diff --git a/content/media/webaudio/BiquadFilterNode.cpp b/content/media/webaudio/BiquadFilterNode.cpp index 061be834d39b..b494081ce6f8 100644 --- a/content/media/webaudio/BiquadFilterNode.cpp +++ b/content/media/webaudio/BiquadFilterNode.cpp @@ -6,6 +6,10 @@ #include "BiquadFilterNode.h" #include "mozilla/dom/BiquadFilterNodeBinding.h" +#include "AudioNodeEngine.h" +#include "AudioNodeStream.h" +#include "AudioDestinationNode.h" +#include "WebAudioUtils.h" namespace mozilla { namespace dom { @@ -19,6 +23,79 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode) NS_IMPL_ADDREF_INHERITED(BiquadFilterNode, AudioNode) NS_IMPL_RELEASE_INHERITED(BiquadFilterNode, AudioNode) +class BiquadFilterNodeEngine : public AudioNodeEngine +{ +public: + explicit BiquadFilterNodeEngine(AudioDestinationNode* aDestination) + : mSource(nullptr) + , mDestination(static_cast (aDestination->Stream())) + // Keep the default values in sync with the default values in + // BiquadFilterNode::BiquadFilterNode + , mType(BiquadTypeEnum::LOWPASS) + , mFrequency(350.f) + , mQ(1.f) + , mGain(0.f) + { + } + + void SetSourceStream(AudioNodeStream* aSource) + { + mSource = aSource; + } + + enum Parameteres { + TYPE, + FREQUENCY, + Q, + GAIN + }; + void SetInt32Parameter(uint32_t aIndex, int32_t aValue) MOZ_OVERRIDE + { + switch (aIndex) { + case TYPE: mType = static_cast(aValue); break; + default: + NS_ERROR("Bad BiquadFilterNode Int32Parameter"); + } + } + void SetTimelineParameter(uint32_t aIndex, const AudioParamTimeline& aValue) MOZ_OVERRIDE + { + MOZ_ASSERT(mSource && mDestination); + switch (aIndex) { + case FREQUENCY: + mFrequency = aValue; + WebAudioUtils::ConvertAudioParamToTicks(mFrequency, mSource, mDestination); + break; + case Q: + mQ = aValue; + WebAudioUtils::ConvertAudioParamToTicks(mQ, mSource, mDestination); + break; + case GAIN: + mGain = aValue; + WebAudioUtils::ConvertAudioParamToTicks(mGain, mSource, mDestination); + break; + default: + NS_ERROR("Bad BiquadFilterNodeEngine TimelineParameter"); + } + } + + virtual void ProduceAudioBlock(AudioNodeStream* aStream, + const AudioChunk& aInput, + AudioChunk* aOutput, + bool* aFinished) MOZ_OVERRIDE + { + // TODO: do the necessary computation here + *aOutput = aInput; + } + +private: + AudioNodeStream* mSource; + AudioNodeStream* mDestination; + BiquadTypeEnum mType; + AudioParamTimeline mFrequency; + AudioParamTimeline mQ; + AudioParamTimeline mGain; +}; + static float Nyquist(AudioContext* aContext) { @@ -28,10 +105,18 @@ Nyquist(AudioContext* aContext) BiquadFilterNode::BiquadFilterNode(AudioContext* aContext) : AudioNode(aContext) , mType(BiquadTypeEnum::LOWPASS) - , mFrequency(new AudioParam(this, Callback, 350.f, 10.f, Nyquist(aContext))) - , mQ(new AudioParam(this, Callback, 1.f, 0.0001f, 1000.f)) - , mGain(new AudioParam(this, Callback, 0.f, -40.f, 40.f)) + , mFrequency(new AudioParam(this, SendFrequencyToStream, 350.f, 10.f, Nyquist(aContext))) + , mQ(new AudioParam(this, SendQToStream, 1.f, 0.0001f, 1000.f)) + , mGain(new AudioParam(this, SendGainToStream, 0.f, -40.f, 40.f)) { + BiquadFilterNodeEngine* engine = new BiquadFilterNodeEngine(aContext->Destination()); + mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM); + engine->SetSourceStream(static_cast (mStream.get())); +} + +BiquadFilterNode::~BiquadFilterNode() +{ + DestroyMediaStream(); } JSObject* @@ -40,6 +125,39 @@ BiquadFilterNode::WrapObject(JSContext* aCx, JSObject* aScope) return BiquadFilterNodeBinding::Wrap(aCx, aScope, this); } +void +BiquadFilterNode::SetType(uint16_t aType, ErrorResult& aRv) +{ + BiquadTypeEnum type = static_cast (aType); + if (type > BiquadTypeEnum::Max) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + } else { + mType = type; + SendInt32ParameterToStream(BiquadFilterNodeEngine::TYPE, aType); + } +} + +void +BiquadFilterNode::SendFrequencyToStream(AudioNode* aNode) +{ + BiquadFilterNode* This = static_cast(aNode); + SendTimelineParameterToStream(This, BiquadFilterNodeEngine::FREQUENCY, *This->mFrequency); +} + +void +BiquadFilterNode::SendQToStream(AudioNode* aNode) +{ + BiquadFilterNode* This = static_cast(aNode); + SendTimelineParameterToStream(This, BiquadFilterNodeEngine::Q, *This->mQ); +} + +void +BiquadFilterNode::SendGainToStream(AudioNode* aNode) +{ + BiquadFilterNode* This = static_cast(aNode); + SendTimelineParameterToStream(This, BiquadFilterNodeEngine::GAIN, *This->mGain); +} + } } diff --git a/content/media/webaudio/BiquadFilterNode.h b/content/media/webaudio/BiquadFilterNode.h index fa4ef74e941c..e56ff89a9576 100644 --- a/content/media/webaudio/BiquadFilterNode.h +++ b/content/media/webaudio/BiquadFilterNode.h @@ -33,25 +33,23 @@ class BiquadFilterNode : public AudioNode { public: explicit BiquadFilterNode(AudioContext* aContext); + ~BiquadFilterNode(); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode) virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope); + virtual bool SupportsMediaStreams() const MOZ_OVERRIDE + { + return true; + } + uint16_t Type() const { return static_cast (mType); } - void SetType(uint16_t aType, ErrorResult& aRv) - { - BiquadTypeEnum type = static_cast (aType); - if (type > BiquadTypeEnum::Max) { - aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); - } else { - mType = type; - } - } + void SetType(uint16_t aType, ErrorResult& aRv); AudioParam* Frequency() const { @@ -68,6 +66,11 @@ public: return mGain; } +private: + static void SendFrequencyToStream(AudioNode* aNode); + static void SendQToStream(AudioNode* aNode); + static void SendGainToStream(AudioNode* aNode); + private: BiquadTypeEnum mType; nsRefPtr mFrequency;