bug 1186779 use ChannelFloatsForWrite() instead of const_cast r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 22 Jul 2015 17:59:21 +1200
changeset 286526 44b77af83570ab3e0f98fcf8041b62664135b2c8
parent 286525 eb35e246091350ef010da8a9ac42dc2efcf83757
child 286527 08180ddf47e55c18fb03301a914663c431d22b31
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1186779
milestone42.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 1186779 use ChannelFloatsForWrite() instead of const_cast r=padenot
dom/media/webaudio/AudioBufferSourceNode.cpp
dom/media/webaudio/AudioNodeEngine.cpp
dom/media/webaudio/AudioNodeExternalInputStream.cpp
dom/media/webaudio/AudioNodeStream.cpp
dom/media/webaudio/BiquadFilterNode.cpp
dom/media/webaudio/ChannelMergerNode.cpp
dom/media/webaudio/ChannelSplitterNode.cpp
dom/media/webaudio/ConvolverNode.cpp
dom/media/webaudio/DelayBuffer.cpp
dom/media/webaudio/DelayBuffer.h
dom/media/webaudio/GainNode.cpp
dom/media/webaudio/OscillatorNode.cpp
dom/media/webaudio/PanningUtils.h
dom/media/webaudio/StereoPannerNode.cpp
dom/media/webaudio/WaveShaperNode.cpp
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -202,17 +202,17 @@ public:
 
   // Copy aNumberOfFrames frames from the source buffer at offset aSourceOffset
   // and put it at offset aBufferOffset in the destination buffer.
   void CopyFromInputBuffer(AudioChunk* aOutput,
                            uint32_t aChannels,
                            uintptr_t aOffsetWithinBlock,
                            uint32_t aNumberOfFrames) {
     for (uint32_t i = 0; i < aChannels; ++i) {
-      float* baseChannelData = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i]));
+      float* baseChannelData = aOutput->ChannelFloatsForWrite(i);
       memcpy(baseChannelData + aOffsetWithinBlock,
              mBuffer->GetData(i) + mBufferPosition,
              aNumberOfFrames * sizeof(float));
     }
   }
 
   // Resamples input data to an output buffer, according to |mBufferSampleRate| and
   // the playbackRate/detune.
@@ -263,18 +263,17 @@ public:
       inputLimit = std::min(inputLimit, availableInInputBuffer);
 
       for (uint32_t i = 0; true; ) {
         uint32_t inSamples = inputLimit;
         const float* inputData = mBuffer->GetData(i) + mBufferPosition;
 
         uint32_t outSamples = availableInOutputBuffer;
         float* outputData =
-          static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])) +
-          *aOffsetWithinBlock;
+          aOutput->ChannelFloatsForWrite(i) + *aOffsetWithinBlock;
 
         WebAudioUtils::SpeexResamplerProcess(resampler, i,
                                              inputData, &inSamples,
                                              outputData, &outSamples);
         if (++i == aChannels) {
           mBufferPosition += inSamples;
           MOZ_ASSERT(mBufferPosition <= mBufferEnd || mLoop);
           *aOffsetWithinBlock += outSamples;
@@ -289,18 +288,17 @@ public:
           return;
         }
       }
     } else {
       for (uint32_t i = 0; true; ) {
         uint32_t inSamples = mRemainingResamplerTail;
         uint32_t outSamples = availableInOutputBuffer;
         float* outputData =
-          static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])) +
-          *aOffsetWithinBlock;
+          aOutput->ChannelFloatsForWrite(i) + *aOffsetWithinBlock;
 
         // AudioDataValue* for aIn selects the function that does not try to
         // copy and format-convert input data.
         WebAudioUtils::SpeexResamplerProcess(resampler, i,
                          static_cast<AudioDataValue*>(nullptr), &inSamples,
                          outputData, &outSamples);
         if (++i == aChannels) {
           mRemainingResamplerTail -= inSamples;
--- a/dom/media/webaudio/AudioNodeEngine.cpp
+++ b/dom/media/webaudio/AudioNodeEngine.cpp
@@ -37,19 +37,19 @@ AllocateAudioBlock(uint32_t aChannelCoun
 
 void
 WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength)
 {
   MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE);
   MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk");
   if (aLength == 0)
     return;
+
   for (uint32_t i = 0; i < aChunk->mChannelData.Length(); ++i) {
-    memset(static_cast<float*>(const_cast<void*>(aChunk->mChannelData[i])) + aStart,
-           0, aLength*sizeof(float));
+    PodZero(aChunk->ChannelFloatsForWrite(i) + aStart, aLength);
   }
 }
 
 void AudioBufferCopyWithScale(const float* aInput,
                               float aScale,
                               float* aOutput,
                               uint32_t aSize)
 {
--- a/dom/media/webaudio/AudioNodeExternalInputStream.cpp
+++ b/dom/media/webaudio/AudioNodeExternalInputStream.cpp
@@ -44,18 +44,17 @@ CopyChunkToBlock(const AudioChunk& aInpu
       // We only need to upmix here because aBlock's channel count has been
       // chosen to be a superset of the channel count of every chunk.
       AudioChannelsUpMix(&channels, blockChannels, nullptr);
     }
   }
 
   uint32_t duration = aInput.GetDuration();
   for (uint32_t c = 0; c < blockChannels; ++c) {
-    float* outputData =
-      static_cast<float*>(const_cast<void*>(aBlock->mChannelData[c])) + aOffsetInBlock;
+    float* outputData = aBlock->ChannelFloatsForWrite(c) + aOffsetInBlock;
     if (channels[c]) {
       switch (aInput.mBufferFormat) {
       case AUDIO_FORMAT_FLOAT32:
         ConvertAudioSamplesWithScale(
             static_cast<const float*>(channels[c]), outputData, duration,
             aInput.mVolume);
         break;
       case AUDIO_FORMAT_S16:
--- a/dom/media/webaudio/AudioNodeStream.cpp
+++ b/dom/media/webaudio/AudioNodeStream.cpp
@@ -406,17 +406,17 @@ AudioNodeStream::AccumulateInputChunk(ui
                                       AudioChunk* aBlock,
                                       nsTArray<float>* aDownmixBuffer)
 {
   nsAutoTArray<const void*,GUESS_AUDIO_CHANNELS> channels;
   UpMixDownMixChunk(&aChunk, aBlock->mChannelData.Length(), channels, *aDownmixBuffer);
 
   for (uint32_t c = 0; c < channels.Length(); ++c) {
     const float* inputData = static_cast<const float*>(channels[c]);
-    float* outputData = static_cast<float*>(const_cast<void*>(aBlock->mChannelData[c]));
+    float* outputData = aBlock->ChannelFloatsForWrite(c);
     if (inputData) {
       if (aInputIndex == 0) {
         AudioBlockCopyChannelWithScale(inputData, aChunk.mVolume, outputData);
       } else {
         AudioBlockAddChannelWithScale(inputData, aChunk.mVolume, outputData);
       }
     } else {
       if (aInputIndex == 0) {
--- a/dom/media/webaudio/BiquadFilterNode.cpp
+++ b/dom/media/webaudio/BiquadFilterNode.cpp
@@ -201,17 +201,17 @@ public:
         if (aInput.mVolume != 1.0) {
           AudioBlockCopyChannelWithScale(input, aInput.mVolume, inputBuffer);
           input = inputBuffer;
         }
       }
       SetParamsOnBiquad(mBiquads[i], aStream->SampleRate(), mType, freq, q, gain, detune);
 
       mBiquads[i].process(input,
-                          static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])),
+                          aOutput->ChannelFloatsForWrite(i),
                           aInput.GetDuration());
     }
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     // Not owned:
     // - mSource - probably not owned
--- a/dom/media/webaudio/ChannelMergerNode.cpp
+++ b/dom/media/webaudio/ChannelMergerNode.cpp
@@ -45,17 +45,17 @@ public:
     // Append each channel in each input to the output
     size_t channelIndex = 0;
     for (uint16_t i = 0; true; ++i) {
       MOZ_ASSERT(i < InputCount());
       for (size_t j = 0; j < aInput[i].mChannelData.Length(); ++j) {
         AudioBlockCopyChannelWithScale(
             static_cast<const float*>(aInput[i].mChannelData[j]),
             aInput[i].mVolume,
-            static_cast<float*>(const_cast<void*>(aOutput[0].mChannelData[channelIndex])));
+            aOutput[0].ChannelFloatsForWrite(channelIndex));
         ++channelIndex;
         if (channelIndex >= channelCount) {
           return;
         }
       }
     }
   }
 
--- a/dom/media/webaudio/ChannelSplitterNode.cpp
+++ b/dom/media/webaudio/ChannelSplitterNode.cpp
@@ -33,17 +33,17 @@ public:
     aOutput.SetLength(OutputCount());
     for (uint16_t i = 0; i < OutputCount(); ++i) {
       if (i < aInput[0].mChannelData.Length()) {
         // Split out existing channels
         AllocateAudioBlock(1, &aOutput[i]);
         AudioBlockCopyChannelWithScale(
             static_cast<const float*>(aInput[0].mChannelData[i]),
             aInput[0].mVolume,
-            static_cast<float*>(const_cast<void*>(aOutput[i].mChannelData[0])));
+            aOutput[i].ChannelFloatsForWrite(0));
       } else {
         // Pad with silent channels if needed
         aOutput[i].SetNull(WEBAUDIO_BLOCK_SIZE);
       }
     }
   }
 
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
--- a/dom/media/webaudio/ConvolverNode.cpp
+++ b/dom/media/webaudio/ConvolverNode.cpp
@@ -130,17 +130,17 @@ public:
       }
     } else {
       if (aInput.mVolume != 1.0f) {
         // Pre-multiply the input's volume
         uint32_t numChannels = aInput.mChannelData.Length();
         AllocateAudioBlock(numChannels, &input);
         for (uint32_t i = 0; i < numChannels; ++i) {
           const float* src = static_cast<const float*>(aInput.mChannelData[i]);
-          float* dest = static_cast<float*>(const_cast<void*>(input.mChannelData[i]));
+          float* dest = input.ChannelFloatsForWrite(i);
           AudioBlockCopyChannelWithScale(src, aInput.mVolume, dest);
         }
       }
 
       if (mLeftOverData <= 0) {
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::ADDREF);
         aStream->Graph()->
--- a/dom/media/webaudio/DelayBuffer.cpp
+++ b/dom/media/webaudio/DelayBuffer.cpp
@@ -92,49 +92,46 @@ DelayBuffer::Read(const double aPerFrame
   }
 
   // Remember currentDelayFrames for the next ProcessBlock call
   mCurrentDelay = aPerFrameDelays[WEBAUDIO_BLOCK_SIZE - 1];
 }
 
 void
 DelayBuffer::ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
-                         const AudioChunk* aOutputChunk, uint32_t aChannel,
+                         AudioChunk* aOutputChunk, uint32_t aChannel,
                          ChannelInterpretation aChannelInterpretation)
 {
   if (!mChunks.Length()) {
-    float* outputChannel = static_cast<float*>
-      (const_cast<void*>(aOutputChunk->mChannelData[aChannel]));
+    float* outputChannel = aOutputChunk->ChannelFloatsForWrite(aChannel);
     PodZero(outputChannel, WEBAUDIO_BLOCK_SIZE);
     return;
   }
 
   ReadChannels(aPerFrameDelays, aOutputChunk,
                aChannel, 1, aChannelInterpretation);
 }
 
 void
 DelayBuffer::ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
-                          const AudioChunk* aOutputChunk,
+                          AudioChunk* aOutputChunk,
                           uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
                           ChannelInterpretation aChannelInterpretation)
 {
   uint32_t totalChannelCount = aOutputChunk->mChannelData.Length();
   uint32_t readChannelsEnd = aFirstChannel + aNumChannelsToRead;
   MOZ_ASSERT(readChannelsEnd <= totalChannelCount);
 
   if (mUpmixChannels.Length() != totalChannelCount) {
     mLastReadChunk = -1; // invalidate cache
   }
 
-  float* const* outputChannels = reinterpret_cast<float* const*>
-    (const_cast<void* const*>(aOutputChunk->mChannelData.Elements()));
   for (uint32_t channel = aFirstChannel;
        channel < readChannelsEnd; ++channel) {
-    PodZero(outputChannels[channel], WEBAUDIO_BLOCK_SIZE);
+    PodZero(aOutputChunk->ChannelFloatsForWrite(channel), WEBAUDIO_BLOCK_SIZE);
   }
 
   for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
     double currentDelay = aPerFrameDelays[i];
     MOZ_ASSERT(currentDelay >= 0.0);
     MOZ_ASSERT(currentDelay <= (mChunks.Length() - 1) * WEBAUDIO_BLOCK_SIZE);
 
     // Interpolate two input frames in case the read position does not match
@@ -153,17 +150,17 @@ DelayBuffer::ReadChannels(const double a
       // chunks specially.
       if (!mChunks[readChunk].IsNull()) {
         int readOffset = OffsetForPosition(positions[tick]);
         UpdateUpmixChannels(readChunk, totalChannelCount,
                             aChannelInterpretation);
         double multiplier = interpolationFactor * mChunks[readChunk].mVolume;
         for (uint32_t channel = aFirstChannel;
              channel < readChannelsEnd; ++channel) {
-          outputChannels[channel][i] += multiplier *
+          aOutputChunk->ChannelFloatsForWrite(channel)[i] += multiplier *
             static_cast<const float*>(mUpmixChannels[channel])[readOffset];
         }
       }
 
       interpolationFactor = 1.0 - interpolationFactor;
     }
   }
 }
--- a/dom/media/webaudio/DelayBuffer.h
+++ b/dom/media/webaudio/DelayBuffer.h
@@ -51,17 +51,17 @@ public:
   void Read(double aDelayTicks, AudioChunk* aOutputChunk,
             ChannelInterpretation aChannelInterpretation);
 
   // Read into one of the channels of aOutputChunk, given an array of
   // delays in ticks.  This is useful when delays are different on different
   // channels.  aOutputChunk must have already been allocated with at least as
   // many channels as were in any of the blocks passed to Write().
   void ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
-                   const AudioChunk* aOutputChunk, uint32_t aChannel,
+                   AudioChunk* aOutputChunk, uint32_t aChannel,
                    ChannelInterpretation aChannelInterpretation);
 
   // Advance the buffer pointer
   void NextBlock()
   {
     mCurrentChunk = (mCurrentChunk + 1) % mChunks.Length();
 #ifdef DEBUG
     MOZ_ASSERT(mHaveWrittenBlock);
@@ -75,17 +75,17 @@ public:
   };
 
   int MaxDelayTicks() const { return mMaxDelayTicks; }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
 
 private:
   void ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
-                    const AudioChunk* aOutputChunk,
+                    AudioChunk* aOutputChunk,
                     uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
                     ChannelInterpretation aChannelInterpretation);
   bool EnsureBuffer();
   int PositionForDelay(int aDelay);
   int ChunkForPosition(int aPosition);
   int OffsetForPosition(int aPosition);
   int ChunkForDelay(int aDelay);
   void UpdateUpmixChannels(int aNewReadChunk, uint32_t channelCount,
--- a/dom/media/webaudio/GainNode.cpp
+++ b/dom/media/webaudio/GainNode.cpp
@@ -90,18 +90,17 @@ public:
 
       for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
         computedGain[counter] *= aInput.mVolume;
       }
 
       // Apply the gain to the output buffer
       for (size_t channel = 0; channel < aOutput->mChannelData.Length(); ++channel) {
         const float* inputBuffer = static_cast<const float*> (aInput.mChannelData[channel]);
-        float* buffer = static_cast<float*> (const_cast<void*>
-                          (aOutput->mChannelData[channel]));
+        float* buffer = aOutput->ChannelFloatsForWrite(channel);
         AudioBlockCopyChannelWithScale(inputBuffer, computedGain, buffer);
       }
     }
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     // Not owned:
--- a/dom/media/webaudio/OscillatorNode.cpp
+++ b/dom/media/webaudio/OscillatorNode.cpp
@@ -303,18 +303,17 @@ public:
     }
     if (ticks + WEBAUDIO_BLOCK_SIZE <= mStart) {
       // We're not playing yet.
       ComputeSilence(aOutput);
       return;
     }
 
     AllocateAudioBlock(1, aOutput);
-    float* output = static_cast<float*>(
-        const_cast<void*>(aOutput->mChannelData[0]));
+    float* output = aOutput->ChannelFloatsForWrite(0);
 
     uint32_t start, end;
     FillBounds(output, ticks, start, end);
 
     // Synthesize the correct waveform.
     switch(mType) {
       case OscillatorType::Sine:
         ComputeSine(output, ticks, start, end);
--- a/dom/media/webaudio/PanningUtils.h
+++ b/dom/media/webaudio/PanningUtils.h
@@ -13,37 +13,37 @@
 namespace mozilla {
 namespace dom {
 
 template<typename T>
 void
 GainMonoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
                  T aGainL, T aGainR)
 {
-  float* outputL = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[0]));
-  float* outputR = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[1]));
-  const float* input = static_cast<float*>(const_cast<void*>(aInput.mChannelData[0]));
+  float* outputL = aOutput->ChannelFloatsForWrite(0);
+  float* outputR = aOutput->ChannelFloatsForWrite(1);
+  const float* input = static_cast<const float*>(aInput.mChannelData[0]);
 
   MOZ_ASSERT(aInput.ChannelCount() == 1);
   MOZ_ASSERT(aOutput->ChannelCount() == 2);
 
   AudioBlockPanMonoToStereo(input, aGainL, aGainR, outputL, outputR);
 }
 
 // T can be float or an array of float, and  U can be bool or an array of bool,
 // depending if the value of the parameters are constant for this block.
 template<typename T, typename U>
 void
 GainStereoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
                    T aGainL, T aGainR, U aOnLeft)
 {
-  float* outputL = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[0]));
-  float* outputR = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[1]));
-  const float* inputL = static_cast<float*>(const_cast<void*>(aInput.mChannelData[0]));
-  const float* inputR = static_cast<float*>(const_cast<void*>(aInput.mChannelData[1]));
+  float* outputL = aOutput->ChannelFloatsForWrite(0);
+  float* outputR = aOutput->ChannelFloatsForWrite(1);
+  const float* inputL = static_cast<const float*>(aInput.mChannelData[0]);
+  const float* inputR = static_cast<const float*>(aInput.mChannelData[1]);
 
   MOZ_ASSERT(aInput.ChannelCount() == 2);
   MOZ_ASSERT(aOutput->ChannelCount() == 2);
 
   AudioBlockPanStereoToStereo(inputL, inputR, aGainL, aGainR, aOnLeft, outputL, outputR);
 }
 
 // T can be float or an array of float, and  U can be bool or an array of bool,
--- a/dom/media/webaudio/StereoPannerNode.cpp
+++ b/dom/media/webaudio/StereoPannerNode.cpp
@@ -81,33 +81,33 @@ public:
 
     aLeftGain  = cos(0.5 * M_PI * aPanning);
     aRightGain = sin(0.5 * M_PI * aPanning);
   }
 
   void SetToSilentStereoBlock(AudioChunk* aChunk)
   {
     for (uint32_t channel = 0; channel < 2; channel++) {
-      float* samples = static_cast<float*>(const_cast<void*>(aChunk->mChannelData[channel]));
+      float* samples = aChunk->ChannelFloatsForWrite(channel);
       for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i++) {
         samples[i] = 0.f;
       }
     }
   }
 
   void UpmixToStereoIfNeeded(const AudioChunk& aInput, AudioChunk* aOutput)
   {
     if (aInput.ChannelCount() == 2) {
       *aOutput = aInput;
     } else {
       MOZ_ASSERT(aInput.ChannelCount() == 1);
       AllocateAudioBlock(2, aOutput);
       const float* input = static_cast<const float*>(aInput.mChannelData[0]);
       for (uint32_t channel = 0; channel < 2; channel++) {
-        float* output = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[channel]));
+        float* output = aOutput->ChannelFloatsForWrite(channel);
         PodCopy(output, input, WEBAUDIO_BLOCK_SIZE);
       }
     }
   }
 
   virtual void ProcessBlock(AudioNodeStream* aStream,
                             const AudioChunk& aInput,
                             AudioChunk* aOutput,
--- a/dom/media/webaudio/WaveShaperNode.cpp
+++ b/dom/media/webaudio/WaveShaperNode.cpp
@@ -227,17 +227,17 @@ public:
       return;
     }
 
     AllocateAudioBlock(channelCount, aOutput);
     for (uint32_t i = 0; i < channelCount; ++i) {
       float* scaledSample = (float *)(aInput.mChannelData[i]);
       AudioBlockInPlaceScale(scaledSample, aInput.mVolume);
       const float* inputBuffer = static_cast<const float*>(scaledSample);
-      float* outputBuffer = const_cast<float*> (static_cast<const float*>(aOutput->mChannelData[i]));
+      float* outputBuffer = aOutput->ChannelFloatsForWrite(i);
       float* sampleBuffer;
 
       switch (mType) {
       case OverSampleType::None:
         mResampler.Reset(channelCount, aStream->SampleRate(), OverSampleType::None);
         ProcessCurve<1>(inputBuffer, outputBuffer);
         break;
       case OverSampleType::_2x: