Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Audio sync, call function every 1 / 44.1 millisecond

In JavaScript, is it possible to call a function playing 10 different wav sounds at 44.1 kHz and call that same function again in (1/44100)*(128/60)*16 seconds with a 1/44.1 millisecond precision preferably with chrome/safari and in that case how?

I'm looking at making a music loop machine playing a few simultaneous loops. The precision is needed otherwise there will be unwanted hearable issues with the sounds (phasing).

like image 409
K. Kilian Lindberg Avatar asked Jan 06 '14 23:01

K. Kilian Lindberg


3 Answers

Robert,

It's possible to measure time with high accuracy - via performance.now() - but you cannot get a callback with that kind of precision. In fact, in light of layout passes and JavaScript execution in the main thread, and the ever-looming threat of garbage collection happening in the main thread, you can't get anywhere NEAR even millisecond precision; you generally ought to be planning on potential interruptions in the tens of milliseconds for robustness.

The answer to this is to use scheduling, particularly in the Web Audio API - I see that you saw the article I wrote about this a year ago on HTML5Rocks (http://www.html5rocks.com/en/tutorials/audio/scheduling/), but you missed the significant piece - you shouldn't be calling

audioSource2.noteOn(0, 0.1190, 1.875);

you need the time offset to schedule it ahead appropriately:

audioSource2.noteOn(time, 0.1190, 1.875);

If you look at my original code, that's how I'm scheduling the oscillator ahead of time. The scheduler runs in a "slow" callback loop - being called only every 100ms or so - but schedules ahead a few beats. If you truly need to mute notes that may already be scheduled in the next 1/10th of a second, then you can keep a node in the middle to disconnect().

like image 137
cwilso Avatar answered Oct 23 '22 23:10

cwilso


I would take a look at either DOM High Resolution timestamp, which can be accessed with window.performance.now(), or request Animation Frame, with window.requestAnimationFrame

like image 1
scrblnrd3 Avatar answered Oct 23 '22 21:10

scrblnrd3


You can use this library which I have written : https://github.com/sebpiq/WAAClock

It lets you schedule things precisely and easily and also provides useful functionalities such as : cancel event, change tempo, ... everything necessary for a loop machine. Under the hood, it implements the tricks explained in this article (already linked by other people) : http://www.html5rocks.com/en/tutorials/audio/scheduling/

If by loop machine you mean continuously looping a few samples (and not a drum machine, where you just play a sample at a point in time), you might also want to look into this : https://github.com/sebpiq/WAATableNode

like image 1
sebpiq Avatar answered Oct 23 '22 21:10

sebpiq