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
This commit is contained in:
Karl Tomlinson 2013-10-25 14:05:43 +13:00
parent 1cb0a5c853
commit 04017096dd
3 changed files with 42 additions and 19 deletions

View File

@ -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<HRTFDatabaseLoader> 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<PlayingRefChangeHandler> refchanged =
new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);
aStream->Graph()->
DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
}
*aOutput = aInput;
return;
}
} else if (mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
if (mLeftOverData == INT_MIN) {
nsRefPtr<PlayingRefChangeHandler> 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();

View File

@ -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<double>(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<double>(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

View File

@ -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,