Bug 1456271 - Implement new behaviour of PeriodicWave ctor: not passing in any array makes it into a sine wave. r?baku draft
authorPaul Adenot <paul@paul.cx>
Wed, 30 May 2018 18:42:29 +0200
changeset 818708 eb6672aae33e91d3b30d1df82dfebaf3e3731bae
parent 818682 2ed1506d1dc7db3d70a3feed95f1456bce05bbee
child 818709 2a076fc26ef29d6a570a0095644b7d2f1c39df3a
child 818785 7acc2742bd7b84ff4b624695ee52153599237de5
push id116326
push userpaul@paul.cx
push dateMon, 16 Jul 2018 13:16:21 +0000
reviewersbaku
bugs1456271
milestone63.0a1
Bug 1456271 - Implement new behaviour of PeriodicWave ctor: not passing in any array makes it into a sine wave. r?baku MozReview-Commit-ID: AbI62hSxZyS
dom/media/webaudio/PeriodicWave.cpp
dom/webidl/PeriodicWave.webidl
--- a/dom/media/webaudio/PeriodicWave.cpp
+++ b/dom/media/webaudio/PeriodicWave.cpp
@@ -21,17 +21,17 @@ PeriodicWave::PeriodicWave(AudioContext*
                            const float* aImagData,
                            const uint32_t aLength,
                            const bool aDisableNormalization,
                            ErrorResult& aRv)
   : mContext(aContext)
   , mDisableNormalization(aDisableNormalization)
 {
   MOZ_ASSERT(aContext);
-  MOZ_ASSERT(aRealData || aImagData);
+  MOZ_ASSERT((aRealData || aImagData) || aLength == 2);
 
   // Caller should have checked this and thrown.
   MOZ_ASSERT(aLength > 0);
   mCoefficients.mDuration = aLength;
 
   // Copy coefficient data.
   // The SharedBuffer and two arrays share a single allocation.
   RefPtr<SharedBuffer> buffer =
@@ -39,54 +39,67 @@ PeriodicWave::PeriodicWave(AudioContext*
   if (!buffer) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   auto data = static_cast<float*>(buffer->Data());
   mCoefficients.mBuffer = std::move(buffer);
 
-  if (aRealData) {
-    PodCopy(data, aRealData, aLength);
+  if (!aRealData && !aImagData) {
+    PodZero(data, aLength);
+    mCoefficients.mChannelData.AppendElement(data);
+    data += aLength;
+    data[0] = 0.0f;
+    data[1] = 1.0f;
+    mCoefficients.mChannelData.AppendElement(data);
   } else {
-    PodZero(data, aLength);
-  }
-  mCoefficients.mChannelData.AppendElement(data);
+    if (aRealData) {
+      PodCopy(data, aRealData, aLength);
+    } else {
+      PodZero(data, aLength);
+    }
+    mCoefficients.mChannelData.AppendElement(data);
 
-  data += aLength;
-  if (aImagData) {
-    PodCopy(data, aImagData, aLength);
-  } else {
-    PodZero(data, aLength);
+    data += aLength;
+    if (aImagData) {
+      PodCopy(data, aImagData, aLength);
+    } else {
+      PodZero(data, aLength);
+    }
+    mCoefficients.mChannelData.AppendElement(data);
   }
-  mCoefficients.mChannelData.AppendElement(data);
-
   mCoefficients.mVolume = 1.0f;
   mCoefficients.mBufferFormat = AUDIO_FORMAT_FLOAT32;
 }
 
 /* static */ already_AddRefed<PeriodicWave>
 PeriodicWave::Constructor(const GlobalObject& aGlobal,
                           AudioContext& aAudioContext,
                           const PeriodicWaveOptions& aOptions,
                           ErrorResult& aRv)
 {
-  if (!aOptions.mReal.WasPassed() && !aOptions.mImag.WasPassed()) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return nullptr;
-  }
 
   if (aOptions.mReal.WasPassed() && aOptions.mImag.WasPassed() &&
       aOptions.mReal.Value().Length() != aOptions.mImag.Value().Length()) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
-  uint32_t length =
-    aOptions.mReal.WasPassed() ? aOptions.mReal.Value().Length() : aOptions.mImag.Value().Length();
+  uint32_t length = 0;
+  if (aOptions.mReal.WasPassed()) {
+    length = aOptions.mReal.Value().Length();
+  } else if (aOptions.mImag.WasPassed()) {
+    length = aOptions.mImag.Value().Length();
+  } else {
+    // If nothing has been passed, this PeriodicWave will be a sine wave: 2
+    // elements for each array, the second imaginary component set to 1.0.
+    length = 2;
+  }
+
   if (length == 0) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
   const float* realData =
     aOptions.mReal.WasPassed() ? aOptions.mReal.Value().Elements() : nullptr;
   const float* imagData =
--- a/dom/webidl/PeriodicWave.webidl
+++ b/dom/webidl/PeriodicWave.webidl
@@ -15,14 +15,11 @@ dictionary PeriodicWaveConstraints {
 };
 
 dictionary PeriodicWaveOptions : PeriodicWaveConstraints {
              sequence<float> real;
              sequence<float> imag;
 };
 
 [Pref="dom.webaudio.enabled",
- // XXXbz The second arg is not optional in the spec, but that looks
- // like a spec bug to me.  See
- // <https://github.com/WebAudio/web-audio-api/issues/1116>.
  Constructor(BaseAudioContext context, optional PeriodicWaveOptions options)]
 interface PeriodicWave {
 };