Reputation: 4578
I have two instances of setInterval. Each is triggering a different function ( these two functions are title quarterNoteFunc & eighthNoteFunc ) at repeated intervals. The interval for quarterNoteFunc is 600 milliseconds. The interval for eighthNoteFunc is 300 milliseconds. Both of these functions each trigger a different audio file at repeat intervals hence creating a basic music rhythm. The rhythm between the two function calls eventually "drifts" in Google Chrome making the rhythm between the two sounds dissolve. My question is:
It seems that even though browser based timing is garbage their should be a way to create some kind of "hard" timing reference so that the sounds are locked even if the "global" timing gets offset hence keeping the sounds in sync. I thought assigning the same variable milliseconds (code below) would inhibit this - but I was wrong.
The (abbreviated) code looks like this
milliseconds = 600;
quarterNote = setInterval(quarterNoteFunc, milliseconds);
eighthNote = setInterval(eighthNoteFunc, milliseconds/2);
Upvotes: 2
Views: 510
Reputation: 39560
Probably the best way to do this is to have a single, always active 1/8 note interval, then call the quarter-note every other tick:
// wrapped in a closure to allow for a private tickCount variable
// alternatively, you could use a more advanced object with start/stop methods, etc.
(function() {
var tickCount = 0,
tick = function() {
eighthNoteFunc();
if(tickCount %2 == 0) {
quarterNoteFunc();
}
tickCount++;
};
setInterval(tick, 300);
})();
This ensures that the methods are always called on the same tick. You can also expand this to support half notes (tickCount % 4 == 0
) and whole notes (tickCount % 8 == 0
).
This interested me, so I decided to create a fully-working sample (except, using animated backgrounds instead of audio): http://jsfiddle.net/SycBm/
This allows you to see the eighth-, quarter-, and half- notes ticking in sync, as well as start & stop the timer, and independently enable or disable the notes.
Enjoy!
Upvotes: 1