Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback on Lissajous #7

Open
kylestetz opened this issue Dec 1, 2014 · 9 comments
Open

Feedback on Lissajous #7

kylestetz opened this issue Dec 1, 2014 · 9 comments

Comments

@kylestetz
Copy link
Owner

If you've used lissajous and you have any kind of feedback at all, feel free to post it here.

@Shihpin
Copy link

Shihpin commented Dec 1, 2014

Hi

http://qiita.com/Shihpin/items/e8355b167f9cf20117bd

This article is written in Japanese a while ago.

Shihpin 

----- Original Message -----

From: Kyle Stetz notifications@github.com
To: kylestetz/lissajous lissajous@noreply.github.com
Date: 2014/12/2, Tue 01:55
Subject: [lissajous] Feedback on Lissajous (#7)

If you've used lissajous and you have any kind of feedback at all, feel free to post it here.

Reply to this email directly or view it on GitHub.

 
Official blog: http://is.shihp.in

@enedrio
Copy link
Contributor

enedrio commented Jan 12, 2015

Hi Kyle,
thanks for the track.destroy() function.
Here's a little bit I built into the groups prototype:

// apply different beat schemes to all tracks in the group
self.beats = function () {
var args = Array.prototype.slice.call(arguments);
if(args.length > 0) {
var i = 0;
self.tracks.forEach( function (t) {
t.beat(args[i]);
i = (i + 1) % args.length;
});
} else {
self.tracks.forEach( function (t) {
t.beat();
});
}
return self;
}

One can call different beat schemes on the tracks in the group.
If more tracks than schemes are available the schemes will be wrapped around.
That makes synchronous playback of individual tracks possible.
I found it quite useful.

Best
Eric

@kylestetz
Copy link
Owner Author

That's very cool @enedrio! So, just to be clear, you would pass multiple arrays into beats representing the beat pattern for each individual track like this:

t1 = new track(), t2 = new track()
g = new group(t1,t2)
g.beats([4,3,1,2,2,1,3], [4])
// t1 now has the beat pattern [4,3,1,2,2,1,3]
// t2 now has the beat pattern [4]

Is that right? I'm confused by your comment about synchronous playback of individual tracks. Can you elaborate on that?

@enedrio
Copy link
Contributor

enedrio commented Jan 12, 2015

Yes it would be used as you showed.
With synchronous I meant having them all start their patterns at the same time.
Without beats() I had to start a track, then start up the next and shift it 'till its pattern fell in the right place.
But knowing up front which patterns I wanted to combine and how, the beats() function offers me a convenient way to express this in code.
instead of going:

t1.beat(2, 3, 4, 7)
t2.beat(3, 5, 7, 1)
// then shift till it fits 
t2.shift(1)

I can now write:

mygroup = new group()
mygroup.add(t1, t2)
mygroup.beats( [2,3,4,7], [3,5,7,1] )
// and the two tracks will start with their patterns at the same time

If mygroup would contain 3 tracks then the patterns will be wrapped around, like so:

mygroupWith3Tracks.beats( [1,2,3], [4,5,6] )
// t1 --> [ 1, 2, 3 ] 
// t2 --> [ 4, 5, 6 ]  
// t3 --> [ 1, 2, 3 ]

I hope that was somewhat more clear, than my previous post.
I'm a bit out of practice writing in english, sorry. :)

Best
Eric

@kylestetz
Copy link
Owner Author

That's great, I totally get it.

It's worth noting that commas and semicolons allow you to string together several commands to be run at the same time. What you wrote above with t1 and t2 separately can be expressed as:

t1.beat(2, 3, 4, 7), t2.beat(3, 5, 7, 1)

So that you hit enter once and both beats start up in sync.

The syntax of group.beats is interesting and provides another way to do this, so I like it! I would gladly accept a pull request if you want to submit one.

@enedrio
Copy link
Contributor

enedrio commented Jan 12, 2015

Hi,
I just sent the pull request.
And I realized that what the group interface needs,
to make the beats() function even more useful,
would be a synchronize function,
like the one below.

// in group()
self.sync = function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length === 0) {
      self.tracks.forEach( function (t) {
        t._beatPattern.currentStep = 0;
        t._beatPattern.untilNextBeat = 0;
      });  
    } else {
      args.forEach( function (t) {
        t._beatPattern.currentStep = 0;
        t._beatPattern.untilNextBeat = 0;
      });  
    }
    return self;
  }

with such a function one could group tracks together and suddenly bring them in sync playing some crazy beat or whatnot. like so:

// t1 plays something, t2 playing something else
var crazyBeatGroup = new group(t1, t2).sync().beats([2, 3, 4], [4,5,6])

Sounds fun to me.
What do you think?
Maybe a global sync function makes more sense?

The way it's written now it could sync any given tracks even if they're not in the group.
So that's a bit dirty, I guess.

Greets
Eric

EDIT: I just realized, that the code:

t._beatPattern.currentStep = 0;
t._beatPattern.untilNextBeat = 0;

is breaking your model of public and private fields.
So the track.api would need a reset / zero scheduler function
to stay consistent.

@kylestetz
Copy link
Owner Author

Wow. You are blowing my mind right now. I love it! Let's give this decision its own space for discussion: #14

@enedrio
Copy link
Contributor

enedrio commented Jan 24, 2015

Hey Kyle,
I'm still playing around with lissajous.
I had three more ideas, but I'm not sure how to implement them in a good way, yet.

  1. a "seemless" sync Function, that waits until the scheduler of the receiver of the sync call arrives at 0 and only then starts the track that wants to get sync-ed to it.
    Because a hard reset of all running schedulers is a bit unmusical in some situations.
    some sample code:
t1 = new track();
t2 = new track();
t1.beat(1,2,3);
t2.beat(2,3,4);
// t2 keeps running and receives the reset call when t1's scheduler hits zero
t1.sync(t2); 
  1. delete samples from track
  2. list all samples asigned to a track

I know 3) is available by calling track._samples, but that's not an api function :)
2) is not available as far as I understand.

Greets
Eric

@kylestetz
Copy link
Owner Author

Hey @enedrio, I like your idea to sync to the downbeat of a track. It should be possible!

Deleting samples from a track is a great idea, I will add that.

A far as listing the samples assigned to a track... I could add a function to log this, but the issue is that it will log AudioBuffer objects— at the moment we don't keep track of the name of the variable, and in fact that is not exactly a straightforward task.r

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants