Re: AudioBuffer mutability

On Mon, Oct 29, 2012 at 3:31 AM, Robert O'Callahan <robert@ocallahan.org>wrote:

> If someone attaches an AudioBuffer to an AudioBufferSourceNode, then calls
> start(T) on the node, and then modifies the contents of the AudioBuffer (by
> calling getChannelData() and then modifying the returned array), do the
> changes affect what will be played by the AudioBufferSourceNode?
>
> If they don't, we have to make a copy of the buffer in the start() call,
> in case the buffer is mutated later.
>
> If they do, then we are exposed to race conditions where depending on
> exactly where the playback position is when script modifies the array, how
> much audio is buffered and how everything is implemented, changes to the
> buffer may or may not be played. Even worse, on machines with
> non-sequentially-consistent memory (or very aggressive optimizing JS
> compilers), some subsets of the modifications may be played while others
> are mysteriously ignored.
>
> Both options are undesirable. If AudioBuffer didn't provide direct array
> access to its samples, we'd have better options. Is it too late to change
> that?
>
> Rob


Hi Robert, the answer is that for efficiency the AudioBufferSourceNode is
expected to *directly* read the data stored in the AudioBuffer.  As a
consequence of this, then any changes to the AudioBuffer after start() is
called can affect the result.  As you point out this is an inherently racy
affair, but for all practical purposes is a non-issue because, in general,
it's not useful to modify the data dynamically in this way.  In over two
years of developer use of this API, using it for a great variety of uses
cases, this issue has not been a problem because people know to not modify
the buffer.

So, what I think the specification should say is that the behavior is
undefined if the buffer is modified after start().  It's very important to
*not* require any buffer copies in AudioBufferSourceNode for efficiency.
 Developers are free to make their own copies of the buffers, modify them,
and use them in other calls to start().

Chris

Received on Monday, 29 October 2012 18:20:47 UTC