Syncing your demo is rocket science

mog[trbl,3ln]

Synchronization?

is the coordination of events to operate a system in unison.
--http://en.wikipedia.org/wiki/Synchronisation


Sync

If the tune goes UNZ spin the cube

So, why all the fuzz?

  • Connect visuals with music
  • Connect music with visuals

Loop is all you need

var ctx = document.getElementById("someCanvas").getContext('2d'),
    MAX_WIDTH = ctx.canvas.width,
    START_POINT = 0;

var tune = new Audio();
tune.src = "tune.ogg";
tune.currentTime = START_POINT;

tune.play();
render();
function render() {

    //draw progress of tune as rectangle with 5px height
    //start the bar where the demo starts
    ctx.fillRect(MAX_WIDTH / tune.duration * START_POINT, 0,
                 MAX_WIDTH / tune.duration * tune.currentTime, 5);

    //loop the loop
    if(tune.isPlaying)
        window.requestAnimationFrame(render);
}

Meat the possibilities

  • the tedious beatmatch game
  • the knobtwisting magic
  • the OHMYGAWD it's Excel

That spacebar needs slapping


//get the music to play
var tune = new Audio();
tune.src = "tune.ogg";
tune.play();

//hit key, receive time
document.onkeydown = function(evt) {
    switch(evt.keyCode) {
        case 32: //spacebar
            console.log(tune.currentTime, "UNZ!");
            break;
        case 13: //enter
            console.log(tune.currentTime, "interesting");
            break;
    }
};

The harvest

2.5231668949127197 "UNZ!"
3.5650649070739746 "UNZ!"
4.509472846984863 "UNZ!"
5.5099310874938965 "UNZ!"
6.1040358543396 "UNZ!"
8.1040358543396 "interesting"
12.1040358543396 "interesting"
13.1040358543396 "UNZ!"
19.1040358543396 "interesting"

It's full of syncpoints!

var _tuneInfo = [];
_tuneInfo["2.52"] = {what:"UNZ!"};
//..
_tuneInfo["19.10"] = {what:"interesting"};

function gotSync(tuneTime) {
    for (var pos in _tuneInfo) {
        if (_tuneInfo.hasOwnProperty(pos) &&

            ((pos <= tuneTime) && (!_tuneInfo[pos].ticked)) {
                _tuneInfo[pos].ticked = true;
                return _tuneInfo[pos].what;
            }

        }
    }
}
function render() {

    var syncPoint = gotSync(_tune.currentTime);

    switch(syncPoint) {
        case "UNZ!":
            console.log("could spin cube here");
            break;

        case "interesting":
            console.log("could rotate the cat");
            break;
    }
}

Dance the wave with me


Alpha C - Euh

Dance the wave with me

Rhythm is a dancer

dancerjs

var dancer = new Dancer();

var tune = new Audio();
tune.src = 'tune.ogg';
dancer.load( tune );
var kick = dancer.createKick({
    onKick: function ( mag ) {
        console.log('Kick!');
    }
});;

kick.on();

Oh snap!

Twisting knobs

var dancer = new Dancer();

var tune = new Audio();
tune.src = 'tune.ogg';
dancer.load( tune );
var kick = dancer.createKick({
    onKick: function ( mag ) {
        console.log('Kick!');
    },
    threshold: .3,  //amount of UNZiness
    decay: .02      //the higher the less noise (and beats)
});
}

Grab a coffee, this might take a while

So beatdetection is meh

  • Hearding cats
  • Maybe for a music disk
  • Needs UNTZY tune

Tune Math the hard way

Music is created on a grid, usually 4/4
So we only need fixed distances for syncing
Beats per Minute!
Suddenly we're spot on

So let's use jsRocket

  • Database of syncpoints tied to vars
  • Rocket let's you play with values
  • Remote control for your demo

A spinning cube

var BPM = 120,
    ROWS_PER_BEAT = 4,
    ROW_RATE = BPM / 60 * ROWS_PER_BEAT;

var syncDevice = new JSRocket.SyncDevice();

syncDevice.init(); //syncDevice.init("demo");

syncDevice.on('ready', onSyncReady);
syncDevice.on('update', onSyncUpdate);
syncDevice.on('play', onPlay);
syncDevice.on('pause', onPause);

var rotation = syncDevice.getTrack('rotation');

function render() {
    row = tune.currentTime * ROW_RATE;
    console.log(rotation.getValue(row));
}
                    
<track name="distance">
    <key row="0" value="400.000000" interpolation="0"/>
    <key row="5" value="130.000000" interpolation="0"/>
    <key row="11" value="400.000000" interpolation="3"/>
    <key row="14" value="130.000000" interpolation="0"/>
</track>
<track name="FOV">
    <key row="0" value="35.000000" interpolation="3"/>
    <key row="5" value="90.000000" interpolation="0"/>
</track>