Thread: "Leader Mode"
View Single Post
Old 09-20-2009, 07:59 PM   #3
phNord
Human being with feelings
 
Join Date: Jul 2005
Location: Boston
Posts: 22
Default

AndyMc: I'm afraid you're not following what I wrote carefully enough, nor have an understanding of exactly what is going on regarding delays and what you hear / what other people hear in NINJAM. I'm going to draw it out here a little better.

Let's say you had a song where the chord progression (aka the form of the song) was as follows:

Code:
| C  | Am  | F  | G  | Am  | Dm  | E7  | F  |
The song is in 4/4, at a tempo of 120 bpm. That means a full chord progression takes a total of 32 beats, at 120 bpm.

The goal when you play a song in NINJAM is for everyone to lineup in the same place of the form of the song. NINJAM does this by delaying what you play by a certain number of beats at the bpm specified so that everyone ends up at the same place within the interval, albeit the same place in a different interval.

As an example, lets say you were jamming the following chord progression:

| Gm | C |

In 4/4 at 120bpm, that would need a bpm 120 and a bpi of 8 to line everyone up. If the bassist started that off, then the time-line looks like this:

Code:
      (A)       (B)       (C)
BEATS |....|....|....|....|....|....|
Bass: | Gm | C  | Gm | C  | Gm | C  |
Guit: |    |    | Gm | C  | Gm | C  |
Drum: |    |    | Gm | C  | Gm | C  |
At point A, the bass starts playing. At point B, the guitarist and drummer hear the bass playing and join in. At point C, the bassist can hear everyone else is playing, which syncs up with his third time through the form.

Now lets take a song with a longer form - for instance, a funk song with this 8 measure chord progression:

Code:
      (A)                                     (B)                                     (C)
BEATS |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....| ...
Bass: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Guit: |    |    |    |    |    |    |    |    | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Drum: |    |    |    |    |    |    |    |    | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
As you can see, since it is 8 measures long, the bpi must be 32 now. That's a pretty long time after the bassist starts the music before the guitarist and drummer hear him playing, and double that time until he can hear them / they can hear each other at C. For the bassist, there are 16 full measures of music before he even hears anyone playing along with him.

Additionally, say the jam was already going on, and the drummer wanted to change the beat to a jazz beat:

Code:
           (A)                                     (B)                                     (C)
BEATS |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....| ...
Bass: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Guit: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Drum: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
The drummer makes the change at point A. The bassist and guitarist could not hear the change until point B. Even more upsetting, the drummer wouldn't hear them playing along with the shuffle until point C - he would be stuck playing a jazz beat against a funk bass and guitar in his speakers from point A until point C!


What I propose we do is modify the server script very slightly. Right now, the server works like this:
- It receives audio from everyone slightly after they play it (w/up to .5 seconds latency)
- It streams the audio to the people who didn't play it with instructions to their client programs to delay it's play time to one full interval after it was originally recorded

I suggest that we allow one person to be designated a "leader," and for the server to function as follows:
- It receives audio from everyone slightly after they play it (a few milliseconds)
- It sends audio from the "leader" out to everyone else's client programs with instructions for it to be played 1/2 interval after it was originally recorded
- It sends audio from the everyone else to the leader's client program with instructions for it to be played 1/2 interval after it was originally recorded
- It sends audio from everyone who is not a leader to everyone else who is not a leader with instructions to delay it's play time to one full interval after it was originally recorded

Lets say the bass was the leader. This would result in something that looks like this:

Code:
      (A)                 (B)                 (C)                 (D)
BEATS |....|....|....|....|....|....|....|....|....|....|....|....|....|....| ...
Bass: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | ...
Guit: |    |    |    |    | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Drum: |    |    |    |    | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
At point A, the bassist begins playing. At point B, the guitarist and drummer hear the bassist and drummer begin playing, and start playing along. At point C, the bassist hears what the drummer and guitarist are playing, which syncs up with his second time through the form. Finally, at point D the guitarist and drummer hear start hearing what each other played at point B (which syncs up with what the bassist played at point C - his second time through the form as perviously mentioned).

Now lets say that the drummer wanted to make that change to the jazz feel:

Code:
           (A)                  (B)                (C)                 (D)                 (E)
BEATS |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....| ...
Bass: | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | ...
Guit: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
Drum: | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | F  | G  | Am | Dm | E7 | F  | C  | Am | ...
At point A, the drummer makes the change. At point B, the bassist hears the change and starts playing along with the jazz feel. At pint C, the guitarist hears both the bassist and drummer playing the jazz feel and starts to play along. Also at point C, the drummer hears the bassist playing along with his jazz feel. At point D, the bassist will hear everyone (including the guitarist) playing the jazz feel as well, and at point E the drummer hears everyone playing the jazz feel he started.

--------

The end result of all of this is basically:
- The leader can hear changes made by others in half the amount of time as normal
- Everyone else can hear changes made by the leader in half the amount of time as normal
- Everyone stays synced up to the correct point in the form with each other

In regard to the issue of the people "dropping out," that isn't something that should be a concern here. Leader mode is intended for songs with long forms (aka hi bpi), so that people can play them without having to wait multiple forms for changes propagate and songs to start. For the network (bandwidth / ping time) side of things, the requirements are the same as if everyone had the bpi of the song set to 1/2 - for instance if you were playing a 32 bpi song, the participants would have to have connections that could handle the same song at 16 bpi.

Last edited by phNord; 09-21-2009 at 12:19 AM. Reason: cleared up some phrasing
phNord is offline   Reply With Quote