diff options
| -rw-r--r-- | lib/room.js | 26 | ||||
| -rw-r--r-- | public/js/grid.js | 179 |
2 files changed, 98 insertions, 107 deletions
diff --git a/lib/room.js b/lib/room.js index 2a8f5fe..abb1314 100644 --- a/lib/room.js +++ b/lib/room.js @@ -22,22 +22,14 @@ function Grid(){ var base = this; var tempo = 125; var pattern = [ - [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + [1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0], + [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0] ]; function init(){ bind(); @@ -53,7 +45,7 @@ function Grid(){ base.setNote = function(data){ if (data.step < pattern.length && data.channel < pattern[data.step].length) { var state = data.state == 1 ? 1 : 0; - pattern[data.step][data.channel] = state; + pattern[data.channel][data.step] = state; } } init(); diff --git a/public/js/grid.js b/public/js/grid.js index 0a4aece..3691adf 100644 --- a/public/js/grid.js +++ b/public/js/grid.js @@ -7,7 +7,7 @@ var audioletReady = false; var samples = [ 'KickDrum0001.wav', - // 'Closed Hihat0001.wav', 'Open Hihat0001.wav', 'Clap.wav' + 'Closed Hihat0001.wav', 'Open Hihat0001.wav', 'Clap.wav' // 'Clav.wav', 'Mid Tom0001.wav', 'Rimshot.wav', 'SnareDrum0001.wav' ]; @@ -20,9 +20,9 @@ function Sampler (audiolet, url) { buffer.load(url, false); // connect the buffer to a player and set up the objects we need - this.trigger = new TriggerControl(this.audiolet); + this.trigger = new TriggerControl(this.audiolet, 0); this.player = new BufferPlayer(this.audiolet, buffer, 1, 0, 0); - this.gain = new Gain(this.audiolet, 0.80); + this.gain = new Gain(this.audiolet, 0.50); // trigger -> player -> gain -> OUTPUT this.trigger.connect(this.player, 0, 1); @@ -52,7 +52,7 @@ function Sequencer (audiolet, instrument) { function trigger (note, duration) { if (note == 1) { - this.instrument.trigger.setValue(1); + base.instrument.trigger.trigger.setValue(1); } } } @@ -69,127 +69,129 @@ function AudioletApp () { this.sequencers.push(sequencer); } } - -var Audio = new AudioletApp(); function Grid (app){ var base = this; function setNote (data) { - pattern[data.step][data.channel] = data.state; + Audio.sequencers[data.channel].pattern[data.step] = data.state; drawNote(data.step, data.channel); }; + base.setBeat = function(beatId) { beat = beatId; }; - base.setTempo = function(tempo) { - tick = tempo; - } + base.toggle = toggle; - - var tog = 0; var playing = false; var playingInterval = false; var tick = 125; - var pattern = undefined; - var channels = []; - var channelsOn = []; var activecoloron = 'rgb(255,255,255)'; var activecoloroff = 'rgb(202,202,202)'; var inactivecoloron = 'rgb(152,152,152)'; var inactivecoloroff = 'rgb(28,28,28)'; var gridSize = Math.floor(600/16); var lastStep = 16; - var channelCount = 8; + var channelCount = 4; var beat = lastStep-1; var inset = 5; + var Audio = new AudioletApp(); + var canvas = document.getElementById('canvas'); //.offset(); var ctx = canvas.getContext('2d'); init(); function init(){ bind(); - load(); + makeGrid(); } + // Bind events function bind(){ + + // Server events app.receive("event-grid", loadGrid); app.receive("event-note", setNote); + // UI events $('#start').click(start); $('#stop').click(stop); $('#tempo').change(function() { - resetTempo( document.getElementById('tempo').value ) + setTempo( $('#tempo').val() ) }); - $('#canvas').click(function(e){ - var x = e.pageX-canvas.offsetLeft-10; - var y = e.pageY-canvas.offsetTop-10; + + // Clicking the canvas + $('#canvas').click(canvasClick); + } + + // Click a square on the canvas to toggle it. + function canvasClick (e){ + var x = e.pageX-canvas.offsetLeft-10; + var y = e.pageY-canvas.offsetTop-10; - x = Math.floor(x / gridSize); - y = Math.floor(y / gridSize); + var step = Math.floor(x / gridSize); + var channel = Math.floor(y / gridSize); - toggleNote(x, y); - - app.send("event-note", { - 'step': x, - 'channel': y, - 'state': pattern[x][y] - }); - }); + toggleNote(channel, step); + + // Let the other clients know the new state + app.send("event-note", { + 'step': step, + 'channel': channel, + 'state': Audio.sequencers[channel].pattern[step] + }); } + // Load the pattern from the server function loadGrid(data){ - pattern = data.pattern; + + for (var channel = 0; channel < channelCount; channel++) { + for (var step = 0; step < lastStep; step++) { + Audio.sequencers[channel].pattern[step] = data.pattern[channel][step]; + } + } + tempo = data.tempo; stop(); start(); } - function load(){ - if (playing) { - playingInterval = setInterval(make, tick); - } - makeGrid(); - } - + // Toggle on/off function toggle(){ playing ? stop() : start(); } + // Start playing function start() { reset(); playing = true; - load(); + makeGrid(); document.body.bgColor = "#000000"; - for (var i = 0; i < channelCount; i++) { - channels[i] = document.getElementById('sound' + i); - channelsOn[i] = false; - } - for (var i = 0; i < channelCount; i++) { - channels[i+8] = document.getElementById('sound' + i + 'a'); - } + playingInterval = setInterval(make, tick); } + + // Stop playing function stop() { + reset(); playing = false; document.body.bgColor = "#444444"; - for (var i = 0; i < channelCount; i++) { - document.getElementById('sound' + i).pause(); - document.getElementById('sound' + i + 'a').pause(); - } - reset(); } + + // Clear the canvas, reset everything to zero, stop the event loop function reset() { clearInterval(playingInterval); ctx.clearRect(0,0, canvas.width, canvas.height); beat = lastStep-1; } - function resetTempo(tempo) { + + // Change the tempo + function setTempo(tempo) { if (tempo <= 1 || tempo >= 800) { tempo = 120; } - tick = (1000 / (tempo / 60))/4; + tick = (1000 / (tempo / 60)) / 4; $("#alertDisp").html( "Set tempo to " + tempo ); if (playing) { clearInterval(playingInterval); @@ -197,77 +199,74 @@ function Grid (app){ } } + // Paint the current step that's playing, and reset the previous stamp + // This is the old event loop function make() { beat += 1; if (beat == lastStep) { - makeColumn(beat-1,activecoloroff,inactivecoloroff,false); + makeColumn(beat-1, activecoloroff, inactivecoloroff, false); + makeColumn(0, activecoloron, inactivecoloron, true); beat = 0; - makeColumn(beat,activecoloron,inactivecoloron,true); } else { - makeColumn(beat,activecoloron,inactivecoloron,true); - makeColumn(beat-1,activecoloroff,inactivecoloroff,false); + makeColumn(beat, activecoloron, inactivecoloron, true); + makeColumn(beat-1, activecoloroff, inactivecoloroff, false); } } - function makeColumn(x,active,inactive,goplaysample) { - for (var y = 0; y < channelCount; y += 1) { - if (pattern[x][y] == 1) { - if (goplaysample === true) { - // ctx.fillStyle = active; + + // Paint the rectangles in a column, if any of them are playing. + function makeColumn(step, active, inactive, playing) { + for (var channel = 0; channel < channelCount; channel += 1) { + if (Audio.sequencers[channel].pattern[step] == 1) { + if (playing === true) { ctx.fillStyle = random_color(); - var tmpAudio; - if (channelsOn[y] == true) { - channelsOn[y] = false; - tmpAudio = channels[y+8]; - } - else { - tmpAudio = channels[y]; - } - tmpAudio.currentTime = 0; - if (tmpAudio.paused) - tmpAudio.play(); } else { ctx.fillStyle = active; } - ctx.fillRect((x*gridSize) + inset, (y*gridSize) + inset, gridSize - 2*inset, gridSize - 2*inset); - } - else { - ctx.fillStyle = inactive; + ctx.fillRect( (step*gridSize) + inset, (channel*gridSize) + inset, + gridSize - 2*inset, gridSize - 2*inset ); } } } + + // Paint all the squares on the grid function makeGrid() { - for (var x = 0; x < lastStep; x += 1) { - for (var y = 0; y < channelCount; y += 1) { - if (pattern && pattern[x][y] == 1) { + for (var step = 0; step < lastStep; step += 1) { + for (var channel = 0; channel < channelCount; channel += 1) { + if (Audio.sequencers[channel].pattern[step] == 1) { ctx.fillStyle = activecoloroff; } else { ctx.fillStyle = inactivecoloroff; } - ctx.fillRect((x*gridSize) + inset, (y*gridSize) + inset, gridSize - 2*inset, gridSize - 2*inset); + ctx.fillRect((step*gridSize) + inset, (channel*gridSize) + inset, gridSize - 2*inset, gridSize - 2*inset); } } } - function drawNote(x,y) { - if (pattern[x][y] == 1) { + + // Repaint a square to toggle it + function drawNote(channel, step) { + if (Audio.sequencers[channel].pattern[step] == 1) { ctx.fillStyle = activecoloroff; } else { ctx.fillStyle = inactivecoloroff; } - ctx.fillRect((x*gridSize) + inset, (y*gridSize) + inset, gridSize - 2*inset, gridSize - 2*inset); + ctx.fillRect((step*gridSize) + inset, (channel*gridSize) + inset, gridSize - 2*inset, gridSize - 2*inset); } - function toggleNote(x,y) { - if (pattern[x][y] == 1) { - pattern[x][y] = 0; + + // Actually toggle a note, and then redraw it + function toggleNote(channel, step) { + if (Audio.sequencers[channel].pattern[step] == 1) { + Audio.sequencers[channel].pattern[step] = 0; } else { - pattern[x][y] = 1; + Audio.sequencers[channel].pattern[step] = 1; } - drawNote(x,y); + drawNote(channel, step); } + // Generate a random color function random_color() { var rint = Math.round(0xffffff * Math.random()); return 'rgb(' + (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255) + ')'; |
