bug 1391482 accept int16_t-sample initialization of AudioBuffer r?padenot draft
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 17 Aug 2017 17:23:27 +1200
changeset 654568 282bbf97ce3ee98244f9fc16d5c18f24470e1a04
parent 654567 aab2e830e91408b81a4ff079e2ede072696b68ec
child 654569 0c984b92020df877640edbc50483aa381f13022f
push id76601
push userktomlinson@mozilla.com
push dateMon, 28 Aug 2017 23:35:34 +0000
reviewerspadenot
bugs1391482
milestone57.0a1
bug 1391482 accept int16_t-sample initialization of AudioBuffer r?padenot MozReview-Commit-ID: 5UaVZYneN2b
dom/media/webaudio/AudioBuffer.cpp
--- 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();