W3C home > Mailing lists > Public > public-audio@w3.org > October to December 2012

Re: AudioBuffer mutability

From: Chris Rogers <crogers@google.com>
Date: Tue, 30 Oct 2012 14:17:45 -0700
Message-ID: <CA+EzO0n8CaMaJQm2p_vOb84rcQnQO+9YkqxxeciRAKy+f1uY3g@mail.gmail.com>
To: robert@ocallahan.org
Cc: Srikumar Karaikudi Subramanian <srikumarks@gmail.com>, Joseph Berkovitz <joe@noteflight.com>, Ehsan Akhgari <ehsan.akhgari@gmail.com>, public-audio@w3.org
On Tue, Oct 30, 2012 at 1:39 PM, Robert O'Callahan <robert@ocallahan.org>wrote:

> On Wed, Oct 31, 2012 at 5:11 AM, Srikumar Karaikudi Subramanian <
> srikumarks@gmail.com> wrote:
>
>> Although that's true, the getChannelData() API suggests a symmetry of
>> buffer access between the JS side and the audio system. If the buffer were
>> to be read+write locked upon binding to a source node, we'd end up with a
>> reference to a typed array on the JS side that can neither be written to
>> nor read from ... which is a very unusual state to leave a common JS object
>> in.
>>
>
> I wouldn't say that, since typed arrays being transferred to Web Workers
> --- the closest analogue the Web platform currently has to the situation
> we're talking about --- work exactly like this.
>
> To isolate the two sides, the AudioBuffer API has to change to something
>> like this -
>>
>> var f32 = new Float32Array([...]);
>> var buf = context.createBuffer(numChannels, numFrames, sampleRate);
>> buf.writeChannelData(chan, f32, offset);
>> buf.readChannelData(chan, f32, offset);
>>
>> If a buffer is "in use", then the write can be specd to complete after a
>> render quantum and the read can be specd to block during the current render
>> quantum (or perhaps take a callback argument for async read). The "f32"
>> then remains exclusive to JS land.
>>
>
> Something like that would work.
>
> I've got another suggestion though, which I think is simpler and more
> compatible with existing usage:
> -- Neuter ArrayBuffers on first start() using the buffer, as I proposed
> before
> -- If getChannelData() is called on the AudioBuffer after its ArrayBuffers
> have been neutered, make a copy of the underlying data and return it in a
> fresh ArrayBuffer.
>

But we're talking about copying potentially megabytes of data.  This is
inefficient, especially on resource-constrained mobile devices.

Once again, my position is that this "concurrency" issue is not a
real-world problem, and is only a theoretical one.  And we have pretty good
evidence that this is the case.  Any proposed solutions involving copying
of megabytes of data are creating even worse problems.




> This provides applications with read and write access to the AudioBuffer's
> data at all times, providing that after any start() call, getChannelData()
> is called again to acquire a new ArrayBuffer.
>
> This should be implementable efficiently in any system that permits
> *read-only* shared memory between threads, which is reasonable I think. It
> does sometimes require data copying, but it only needs to copy when you
> actually access data after a start(). An implementation could potentially
> do something fancy with copy-on-write to avoid copying when the result of
> getChannelData() is not modified. And note that if getChannelData() is
> called after all nodes have stopped playing the AudioBuffer, then the
> user-agent can transfer ownership of the data back to the main thread to
> avoid copying.
>
> Rob
> --
> Jesus called them together and said, “You know that the rulers of the
> Gentiles lord it over them, and their high officials exercise authority
> over them. Not so with you. Instead, whoever wants to become great among
> you must be your servant, and whoever wants to be first must be your
> slave — just as the Son of Man did not come to be served, but to serve,
> and to give his life as a ransom for many.” [Matthew 20:25-28]
>
>
Received on Tuesday, 30 October 2012 21:18:17 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:50:03 UTC