From 04017096ddbbf1f93862f0832594eee4e4197020 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 25 Oct 2013 14:05:43 +1300 Subject: [PATCH] b=898291 skip HRTF panner processing when input has been null long enough for output to be null r=ehsan --HG-- extra : transplant_source : %E4l%83zo%0E%08%14%FF%F7%9D%D6%8C%FD%A2%07a%2A%8Aq --- content/media/webaudio/PannerNode.cpp | 37 ++++++++++++++++++--- content/media/webaudio/blink/HRTFPanner.cpp | 21 +++++------- content/media/webaudio/blink/HRTFPanner.h | 3 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/content/media/webaudio/PannerNode.cpp b/content/media/webaudio/PannerNode.cpp index 40a99e8af29..2d56af0fa4c 100644 --- a/content/media/webaudio/PannerNode.cpp +++ b/content/media/webaudio/PannerNode.cpp @@ -9,6 +9,7 @@ #include "AudioNodeStream.h" #include "AudioListener.h" #include "AudioBufferSourceNode.h" +#include "PlayingRefChangeHandler.h" #include "blink/HRTFPanner.h" #include "blink/HRTFDatabaseLoader.h" @@ -58,6 +59,7 @@ public: // to some dummy values here. , mListenerDopplerFactor(0.) , mListenerSpeedOfSound(0.) + , mLeftOverData(INT_MIN) { // HRTFDatabaseLoader needs to be fetched on the main thread. TemporaryRef loader = @@ -136,6 +138,35 @@ public: AudioChunk* aOutput, bool *aFinished) MOZ_OVERRIDE { + if (aInput.IsNull()) { + // mLeftOverData != INT_MIN means that the panning model was HRTF and a + // tail-time reference was added. Even if the model is now equalpower, + // the reference will need to be removed. + if (mLeftOverData > 0) { + mLeftOverData -= WEBAUDIO_BLOCK_SIZE; + } else { + if (mLeftOverData != INT_MIN) { + mLeftOverData = INT_MIN; + mHRTFPanner->reset(); + + nsRefPtr refchanged = + new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE); + aStream->Graph()-> + DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget()); + } + *aOutput = aInput; + return; + } + } else if (mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) { + if (mLeftOverData == INT_MIN) { + nsRefPtr refchanged = + new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::ADDREF); + aStream->Graph()-> + DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget()); + } + mLeftOverData = mHRTFPanner->maxTailFrames(); + } + (this->*mPanningModelFunction)(aInput, aOutput); } @@ -177,6 +208,7 @@ public: ThreeDPoint mListenerVelocity; double mListenerDopplerFactor; double mListenerSpeedOfSound; + int mLeftOverData; }; PannerNode::PannerNode(AudioContext* aContext) @@ -277,11 +309,6 @@ void PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput) { - if (aInput.IsNull()) { - *aOutput = aInput; - return; - } - float azimuth, elevation, gainL, gainR, normalizedAzimuth, distanceGain, coneGain; int inputChannels = aInput.mChannelData.Length(); diff --git a/content/media/webaudio/blink/HRTFPanner.cpp b/content/media/webaudio/blink/HRTFPanner.cpp index d30e2fff812..8bc86b6ccfd 100644 --- a/content/media/webaudio/blink/HRTFPanner.cpp +++ b/content/media/webaudio/blink/HRTFPanner.cpp @@ -290,19 +290,16 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioChunk* } } -double HRTFPanner::tailTime() const +int HRTFPanner::maxTailFrames() const { - // Because HRTFPanner is implemented with a DelayKernel and a FFTConvolver, the tailTime of the HRTFPanner - // is the sum of the tailTime of the DelayKernel and the tailTime of the FFTConvolver, which is MaxDelayTimeSeconds - // and fftSize() / 2, respectively. - return MaxDelayTimeSeconds + (fftSize() / 2) / static_cast(sampleRate()); -} - -double HRTFPanner::latencyTime() const -{ - // The latency of a FFTConvolver is also fftSize() / 2, and is in addition to its tailTime of the - // same value. - return (fftSize() / 2) / static_cast(sampleRate()); + // Although the ideal tail time would be the length of the impulse + // response, there is additional tail time from the approximations in the + // implementation. Because HRTFPanner is implemented with a DelayKernel + // and a FFTConvolver, the tailTime of the HRTFPanner is the sum of the + // tailTime of the DelayKernel and the tailTime of the FFTConvolver. + // The FFTConvolver has a tail time of fftSize(), including latency of + // fftSize()/2. + return m_delayLineL.MaxDelayFrames() + fftSize(); } } // namespace WebCore diff --git a/content/media/webaudio/blink/HRTFPanner.h b/content/media/webaudio/blink/HRTFPanner.h index b787dd88d2d..6c725a8a521 100644 --- a/content/media/webaudio/blink/HRTFPanner.h +++ b/content/media/webaudio/blink/HRTFPanner.h @@ -51,8 +51,7 @@ public: float sampleRate() const { return m_sampleRate; } - double tailTime() const; - double latencyTime() const; + int maxTailFrames() const; private: // Given an azimuth angle in the range -180 -> +180, returns the corresponding azimuth index for the database,