bug 1391482 accept int16_t-sample initialization of AudioBuffer r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 17 Aug 2017 17:23:27 +1200
changeset 377740 c949d19c37d0da4071b31b934e9ede21cbd5c0cf
parent 377739 b643a1847ffdfc43e979d1d31aa6a77f751c77a0
child 377741 480d761a45ae40b175502e9769a1f5a3838446b1
push id94338
push userkwierso@gmail.com
push dateThu, 31 Aug 2017 02:58:58 +0000
treeherdermozilla-inbound@9ca18987dabb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1391482
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();