- From: Chris Rogers <crogers@google.com>
- Date: Tue, 30 Oct 2012 14:17:45 -0700
- 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
- Message-ID: <CA+EzO0n8CaMaJQm2p_vOb84rcQnQO+9YkqxxeciRAKy+f1uY3g@mail.gmail.com>
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