Hi!
I'm trying to write a simple music-sequencer in Javascript.
Sounds will be played by SoundManager2
I quickly realised that setTimeout and setInterval are useless for this kind of timing. Their accuracy is simply not good enough.
So what I am trying instead is this:
Create a queue of sound-events (a 2d array [ note, time ] )
Process the queue in a while loop
In pseudo code it could look like this:
// The queue of time/note values (millisecs)
var q = [[0, C], [250, D], [500, E]]
var begin = (new Date).getTime()
while(q.length > 0 ){
var now = (new Date).getTime()
var eventTime = q[0][0] + begin
if( now >= eventTime){
playNote(q[0][1]) // Play the note
q.shift() // Now that the note has been played, discard it.
}
}
Through debugging I've found that this method seems precise enough (the playNote call is made at the exact time it's supposed to).
However while the 'sequence' is playing, all other Javascript (including the bit that actually MAKES the sound) is suspended which is hardly a surprise.
This means that I have silence for as long time it takes to run the sequence and then ALL of the calls to playNote are executed.
I've tried isolating the while-loop in it's own function and then call it through setTimeout, in the hopes that this would create a background thread executing it's own thing (namely playing the sequence) without halting all other JS execution. That doesn't work
I've also tried calling the playNote function using setTimeout, in the hopes that while indeed the UI is frozen at least the sequence is playing correctly, but that doesn't work either.
I've also tried a combination, but as you probably already guessed, that doesn't work either.
So my question is:
How can I have a queue of events processed with precise timing, while NOT shutting down all other code-execution during the run