From 87d828f979cb7a36e66e84cc0a5df4ecb3ba3fe6 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Wed, 17 Jul 2019 06:36:43 +0000 Subject: [PATCH] Bug 1558123 copy audio samples to/from JS arrays r=padenot Direct use of aInput buffers for ArrayBuffer elements is not possible in general. aInput buffers are const because they may be used elsewhere but ArrayBuffer elements may be modified by script. If necessary, it would be possible to later add a mechanism to mix inputs directly into the ArrayBuffer, but often no mixing is required. Direct use of output ArrayBuffer elements would require DetachArrayBuffer to ensure the elements are not modified by script, but that would require creation of a new ArrayBuffer JS object on each call. https://github.com/WebAudio/web-audio-api/issues/1932 tracks specification of making output data available for reading (for downstream node input). Differential Revision: https://phabricator.services.mozilla.com/D34837 --HG-- extra : moz-landing-system : lando --- dom/media/webaudio/AudioWorkletNode.cpp | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/dom/media/webaudio/AudioWorkletNode.cpp b/dom/media/webaudio/AudioWorkletNode.cpp index 96c38aaeb28a..6c5cd1887b87 100644 --- a/dom/media/webaudio/AudioWorkletNode.cpp +++ b/dom/media/webaudio/AudioWorkletNode.cpp @@ -269,6 +269,44 @@ void WorkletNodeEngine::ProcessBlocksOnPorts(AudioNodeStream* aStream, ProduceSilence(aOutput); return; } + + // Copy input values to JS objects. + for (size_t i = 0; i < aInput.Length(); ++i) { + const AudioBlock& input = aInput[i]; + size_t channelCount = input.ChannelCount(); + if (channelCount == 0) { + // Null blocks have AUDIO_FORMAT_SILENCE. + // Don't call ChannelData(). + continue; + } + float volume = input.mVolume; + const auto& channelData = input.ChannelData(); + const auto& float32Arrays = mInputs.mPorts[i].mFloat32Arrays; + JS::AutoCheckCannotGC nogc; + for (size_t c = 0; c < channelCount; ++c) { + bool isShared; + float* dest = JS_GetFloat32ArrayData(float32Arrays[c], &isShared, nogc); + MOZ_ASSERT(!isShared); // Was created as unshared + AudioBlockCopyChannelWithScale(channelData[c], volume, dest); + } + } + + // TODO call process() - bug 1558123 + + // Copy output values from JS objects. + for (size_t o = 0; o < aOutput.Length(); ++o) { + AudioBlock* output = &aOutput[o]; + size_t channelCount = output->ChannelCount(); + const auto& float32Arrays = mOutputs.mPorts[o].mFloat32Arrays; + JS::AutoCheckCannotGC nogc; + for (size_t c = 0; c < channelCount; ++c) { + bool isShared; + const float* src = + JS_GetFloat32ArrayData(float32Arrays[c], &isShared, nogc); + MOZ_ASSERT(!isShared); // Was created as unshared + PodCopy(output->ChannelFloatsForWrite(c), src, WEBAUDIO_BLOCK_SIZE); + } + } } AudioWorkletNode::AudioWorkletNode(AudioContext* aAudioContext,