Execute “live” JavaScript without suspending the browser
I'm trying to write a simple music sequencer in JavaScript
The sound will play soundmanager2
I soon realized that setTimeout and setinterval were useless for this timing Their accuracy is simply not good enough
So what I'm trying is this:
Create a sound event queue (a two-dimensional array [note, time])
Processing queues in a while loop
In pseudo code, it might 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 found that this method looks accurate enough (the playnote call is made at the exact time it should be)
However, when the 'sequence' is playing, all other JavaScript (including the bits that actually sound) is paused, which is hardly a surprise
This means that I have been silent for a long time to run the sequence and then execute all calls to playnote
I have tried to isolate the while loop in its own function and call it through setTimeout, hoping that this will create a background thread to execute its own thing (i.e. playback sequence) without stopping all other JS execution It doesn't work
I also tried to call the playnote function using setTimeout, hoping that although the UI did at least freeze the sequence and was playing, it didn't work
I also tried a combination, but as you might have guessed, it didn't work
So my question is:
How to process the event queue with precise timing instead of turning off all other code execution during runtime
Solution
I don't know if there is a solution for older browsers, but web workers are used for parallel execution in JavaScript
The latest versions of chrome and Firefox support them. I don't know other browsers