16 April 2011
Central to the API is the
mozWriteAudio() method. This method adds an array of samples to the browser’s output buffer. It’s possible to fill this buffer completely, in which case some samples won’t be added and the return value will indicate the number of samples that actually were added. When this happens, it’s up to you to keep track of the remaining samples and make sure that they’re written eventually.
The Typed Array specification provides an easy way to do this with its
subarray() method. This method works a lot like the regular
Array.slice() method, but instead of creating a copy of the array elements, it simply creates a new window into the underlying region of memory which is what you want if you’re trying to write a low-latency audio application.
Ideally, we’d just take the return value from
mozWriteAudio() and slice that many samples off the front of the sample array:
This is exactly what I tried, and then spent the better part of an hour trying to figure out why samples were being repeated, producing a stuttering effect. As it turns out,
subarray() is just broken in Firefox 4.
The bug is simple to illustrate.
When run, the first value should be removed each time, giving
1, 2, 3, 4 2, 3, 4 3, 4 4
This is exactly what happens in recent WebKit. Firefox 4, however, gives
1, 2, 3, 4 1, 2, 3 1, 2 1
This makes it look like Firefox is slicing off the end, but what is actually happening is that the byte offset for the new array is always relative to the beginning of the underlying buffer, but the length is being calculated correctly.
With this in place, Firefox behaves correctly and produces the same output as WebKit. You can write code that uses
subarray() without worrying about the effects of the bug and when Mozilla ships a fix, this patch won’t be applied.0>