- From: Robert O'Callahan <robert@ocallahan.org>
- Date: Wed, 31 Oct 2012 09:39:08 +1300
- To: Srikumar Karaikudi Subramanian <srikumarks@gmail.com>
- Cc: Chris Rogers <crogers@google.com>, Joseph Berkovitz <joe@noteflight.com>, Ehsan Akhgari <ehsan.akhgari@gmail.com>, public-audio@w3.org
- Message-ID: <CAOp6jLZo8gXp0Ms7sBo0TSWoEWbkczaBxHNncMiZigUYCrk+8w@mail.gmail.com>
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. 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 20:39:37 UTC