Bug 1322883 - AudioNode constructors - part 5 - IIRFilterNode, r=padenot

This commit is contained in:
Andrea Marchesini 2016-12-15 19:24:41 +01:00
parent d00453d527
commit a85230b0c3
4 changed files with 72 additions and 44 deletions

View File

@ -14,10 +14,11 @@
#include "mozilla/dom/AnalyserNode.h"
#include "mozilla/dom/AnalyserNodeBinding.h"
#include "mozilla/dom/AudioBufferSourceNodeBinding.h"
#include "mozilla/dom/AudioContextBinding.h"
#include "mozilla/dom/BiquadFilterNodeBinding.h"
#include "mozilla/dom/DelayNodeBinding.h"
#include "mozilla/dom/GainNodeBinding.h"
#include "mozilla/dom/AudioContextBinding.h"
#include "mozilla/dom/IIRFilterNodeBinding.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/OfflineAudioContextBinding.h"
#include "mozilla/dom/Promise.h"
@ -504,35 +505,10 @@ AudioContext::CreateIIRFilter(const mozilla::dom::binding_detail::AutoSequence<d
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback,
mozilla::ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
if (aFeedforward.Length() == 0 || aFeedforward.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aFeedback.Length() == 0 || aFeedback.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
bool feedforwardAllZeros = true;
for (size_t i = 0; i < aFeedforward.Length(); ++i) {
if (aFeedforward.Elements()[i] != 0.0) {
feedforwardAllZeros = false;
}
}
if (feedforwardAllZeros || aFeedback.Elements()[0] == 0.0) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
RefPtr<IIRFilterNode> filterNode =
new IIRFilterNode(this, aFeedforward, aFeedback);
return filterNode.forget();
IIRFilterOptions options;
options.mFeedforward = aFeedforward;
options.mFeedback = aFeedback;
return IIRFilterNode::Create(*this, options, aRv);
}
already_AddRefed<OscillatorNode>

View File

@ -133,8 +133,8 @@ private:
};
IIRFilterNode::IIRFilterNode(AudioContext* aContext,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback)
const Sequence<double>& aFeedforward,
const Sequence<double>& aFeedback)
: AudioNode(aContext,
2,
ChannelCountMode::Max,
@ -168,8 +168,46 @@ IIRFilterNode::IIRFilterNode(AudioContext* aContext,
aContext->Graph());
}
IIRFilterNode::~IIRFilterNode()
/* static */ already_AddRefed<IIRFilterNode>
IIRFilterNode::Create(AudioContext& aAudioContext,
const IIRFilterOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mFeedforward.Length() == 0 || aOptions.mFeedforward.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aOptions.mFeedback.Length() == 0 || aOptions.mFeedback.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
bool feedforwardAllZeros = true;
for (size_t i = 0; i < aOptions.mFeedforward.Length(); ++i) {
if (aOptions.mFeedforward.Elements()[i] != 0.0) {
feedforwardAllZeros = false;
}
}
if (feedforwardAllZeros || aOptions.mFeedback.Elements()[0] == 0.0) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
RefPtr<IIRFilterNode> audioNode =
new IIRFilterNode(&aAudioContext, aOptions.mFeedforward, aOptions.mFeedback);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
size_t

View File

@ -15,18 +15,25 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct IIRFilterOptions;
class IIRFilterNode final : public AudioNode
{
public:
explicit IIRFilterNode(AudioContext* aContext,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback);
static already_AddRefed<IIRFilterNode>
Create(AudioContext& aAudioContext, const IIRFilterOptions& aOptions,
ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<IIRFilterNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const IIRFilterOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void GetFrequencyResponse(const Float32Array& aFrequencyHz,
const Float32Array& aMagResponse,
@ -40,16 +47,17 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
virtual ~IIRFilterNode();
private:
nsTArray<double> mFeedback;
nsTArray<double> mFeedforward;
IIRFilterNode(AudioContext* aContext,
const Sequence<double>& aFeedforward,
const Sequence<double>& aFeedback);
~IIRFilterNode() = default;
nsTArray<double> mFeedback;
nsTArray<double> mFeedforward;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -9,7 +9,13 @@
* liability, trademark and document use rules apply.
*/
[Pref="dom.webaudio.enabled"]
dictionary IIRFilterOptions : AudioNodeOptions {
required sequence<double> feedforward;
required sequence<double> feedback;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, IIRFilterOptions options)]
interface IIRFilterNode : AudioNode {
void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
};