--- a/dom/media/webaudio/AudioBuffer.cpp
+++ b/dom/media/webaudio/AudioBuffer.cpp
@@ -266,16 +266,32 @@ AudioBuffer::Create(nsPIDOMWindowInner*
}
JSObject*
AudioBuffer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return AudioBufferBinding::Wrap(aCx, this, aGivenProto);
}
+static void
+CopyChannelDataToFloat(const AudioChunk& aChunk, uint32_t aChannel,
+ uint32_t aSrcOffset, float* aOutput, uint32_t aLength)
+{
+ MOZ_ASSERT(aChunk.mVolume == 1.0f);
+ if (aChunk.mBufferFormat == AUDIO_FORMAT_FLOAT32) {
+ mozilla::PodCopy(aOutput,
+ aChunk.ChannelData<float>()[aChannel] + aSrcOffset,
+ aLength);
+ } else {
+ MOZ_ASSERT(aChunk.mBufferFormat == AUDIO_FORMAT_S16);
+ ConvertAudioSamples(aChunk.ChannelData<int16_t>()[aChannel] + aSrcOffset,
+ aOutput, aLength);
+ }
+}
+
bool
AudioBuffer::RestoreJSChannelData(JSContext* aJSContext)
{
for (uint32_t i = 0; i < mJSChannels.Length(); ++i) {
if (mJSChannels[i]) {
// Already have data in JS array.
continue;
}
@@ -286,23 +302,21 @@ AudioBuffer::RestoreJSChannelData(JSCont
JS::Rooted<JSObject*> array(aJSContext,
JS_NewFloat32Array(aJSContext, Length()));
if (!array) {
return false;
}
if (!mSharedChannels.IsNull()) {
// "4. Attach ArrayBuffers containing copies of the data to the
// AudioBuffer, to be returned by the next call to getChannelData."
- MOZ_ASSERT(mSharedChannels.mVolume == 1.0f);
- const float* data = mSharedChannels.ChannelData<float>()[i];
JS::AutoCheckCannotGC nogc;
bool isShared;
- mozilla::PodCopy(JS_GetFloat32ArrayData(array, &isShared, nogc),
- data, Length());
+ float* jsData = JS_GetFloat32ArrayData(array, &isShared, nogc);
MOZ_ASSERT(!isShared); // Was created as unshared above
+ CopyChannelDataToFloat(mSharedChannels, i, 0, jsData, Length());
}
mJSChannels[i] = array;
}
mSharedChannels.mBuffer = nullptr;
mSharedChannels.mChannelData.Clear();
return true;
@@ -320,39 +334,40 @@ AudioBuffer::CopyFromChannel(const Float
if (aChannelNumber >= NumberOfChannels() ||
!end.isValid() || end.value() > Length()) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
JS::AutoCheckCannotGC nogc;
JSObject* channelArray = mJSChannels[aChannelNumber];
- const float* sourceData = nullptr;
if (channelArray) {
if (JS_GetTypedArrayLength(channelArray) != Length()) {
// The array's buffer was detached.
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
bool isShared = false;
- sourceData = JS_GetFloat32ArrayData(channelArray, &isShared, nogc);
+ const float* sourceData =
+ JS_GetFloat32ArrayData(channelArray, &isShared, nogc);
// The sourceData arrays should all have originated in
// RestoreJSChannelData, where they are created unshared.
MOZ_ASSERT(!isShared);
- } else if (!mSharedChannels.IsNull()) {
- MOZ_ASSERT(mSharedChannels.mVolume == 1.0f);
- sourceData = mSharedChannels.ChannelData<float>()[aChannelNumber];
+ PodMove(aDestination.Data(), sourceData + aStartInChannel, length);
+ return;
}
- if (sourceData) {
- PodMove(aDestination.Data(), sourceData + aStartInChannel, length);
- } else {
- PodZero(aDestination.Data(), length);
+ if (!mSharedChannels.IsNull()) {
+ CopyChannelDataToFloat(mSharedChannels, aChannelNumber, aStartInChannel,
+ aDestination.Data(), length);
+ return;
}
+
+ PodZero(aDestination.Data(), length);
}
void
AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
uint32_t aChannelNumber, uint32_t aStartInChannel,
ErrorResult& aRv)
{
aSource.ComputeLengthAndData();