Compare commits

..
Author SHA1 Message Date
Moonchild 77f8cae06e Issue #2978 - Avoid empty replacements in macro expansion.
If the replacements array is empty, don't attempt to do any work on the
existing macro, and return. This should prevent infinite recursion in
some cases.
Order matters here: we're relying on the `if` statement shortcut so
`collectMacroArgs()` doesn't get called.
2026-03-09 16:04:57 +01:00
78 changed files with 395 additions and 1185 deletions

No files matched your search

-39
View File
@@ -100,45 +100,6 @@ public:
uint32_t mChunksToProcess = 0;
};
/* static */ already_AddRefed<AnalyserNode>
AnalyserNode::Create(AudioContext& aAudioContext,
const AnalyserOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(&aAudioContext);
analyserNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetFftSize(aOptions.mFftSize, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetMinDecibels(aOptions.mMinDecibels, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetMaxDecibels(aOptions.mMaxDecibels, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetSmoothingTimeConstant(aOptions.mSmoothingTimeConstant, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return analyserNode.forget();
}
AnalyserNode::AnalyserNode(AudioContext* aContext)
: AudioNode(aContext,
1,
+4 -15
View File
@@ -14,26 +14,16 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct AnalyserOptions;
class AnalyserNode final : public AudioNode
{
public:
static already_AddRefed<AnalyserNode>
Create(AudioContext& aAudioContext, const AnalyserOptions& aOptions,
ErrorResult& aRv);
explicit AnalyserNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<AnalyserNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AnalyserOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
void GetFloatFrequencyData(const Float32Array& aArray);
void GetByteFrequencyData(const Uint8Array& aArray);
void GetFloatTimeDomainData(const Float32Array& aArray);
@@ -71,9 +61,10 @@ public:
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
~AnalyserNode() = default;
protected:
~AnalyserNode() {}
private:
friend class AnalyserNodeEngine;
void AppendChunk(const AudioChunk& aChunk);
bool AllocateBuffer();
@@ -82,8 +73,6 @@ private:
void GetTimeDomainData(float* aData, size_t aLength);
private:
explicit AnalyserNode(AudioContext* aContext);
FFTBlock mAnalysisBlock;
nsTArray<AudioChunk> mChunks;
double mMinDecibels;
-18
View File
@@ -178,24 +178,6 @@ AudioBuffer::~AudioBuffer()
mozilla::DropJSObjects(this);
}
/* static */ already_AddRefed<AudioBuffer>
AudioBuffer::Constructor(const GlobalObject& aGlobal,
AudioContext& aAudioContext,
const AudioBufferOptions& aOptions,
ErrorResult& aRv)
{
if (!aOptions.mNumberOfChannels) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
float sampleRate = aOptions.mSampleRate.WasPassed()
? aOptions.mSampleRate.Value()
: aAudioContext.SampleRate();
return Create(&aAudioContext, aOptions.mNumberOfChannels, aOptions.mLength,
sampleRate, aRv);
}
void
AudioBuffer::ClearJSChannels()
{
+1 -5
View File
@@ -24,7 +24,6 @@ class ThreadSharedFloatArrayBufferList;
namespace dom {
struct AudioBufferOptions;
class AudioContext;
/**
@@ -57,10 +56,6 @@ public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioBuffer)
static already_AddRefed<AudioBuffer>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AudioBufferOptions& aOptions, ErrorResult& aRv);
nsPIDOMWindowInner* GetParentObject() const
{
nsCOMPtr<nsPIDOMWindowInner> parentObject = do_QueryReferent(mOwnerWindow);
@@ -139,3 +134,4 @@ protected:
} // namespace mozilla
#endif
+2 -22
View File
@@ -607,30 +607,10 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
mStream->AddMainThreadListener(this);
}
/* static */ already_AddRefed<AudioBufferSourceNode>
AudioBufferSourceNode::Create(JSContext* aCx, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions,
ErrorResult& aRv)
AudioBufferSourceNode::~AudioBufferSourceNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AudioBufferSourceNode> audioNode = new AudioBufferSourceNode(&aAudioContext);
if (aOptions.mBuffer.WasPassed()) {
MOZ_ASSERT(aCx);
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value());
}
audioNode->Detune()->SetValue(aOptions.mDetune);
audioNode->SetLoop(aOptions.mLoop);
audioNode->SetLoopEnd(aOptions.mLoopEnd);
audioNode->SetLoopStart(aOptions.mLoopStart);
audioNode->PlaybackRate()->SetValue(aOptions.mPlaybackRate);
return audioNode.forget();
}
void
AudioBufferSourceNode::DestroyMediaStream()
{
+8 -16
View File
@@ -12,16 +12,13 @@
namespace mozilla {
namespace dom {
struct AudioBufferSourceOptions;
class AudioParam;
class AudioBufferSourceNode final : public AudioNode
, public MainThreadMediaStreamListener
class AudioBufferSourceNode final : public AudioNode,
public MainThreadMediaStreamListener
{
public:
static already_AddRefed<AudioBufferSourceNode>
Create(JSContext* aCx, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv);
explicit AudioBufferSourceNode(AudioContext* aContext);
void DestroyMediaStream() override;
@@ -36,13 +33,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode, AudioNode)
static already_AddRefed<AudioBufferSourceNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv)
{
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void Start(double aWhen, double aOffset,
@@ -108,10 +98,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit AudioBufferSourceNode(AudioContext* aContext);
~AudioBufferSourceNode() = default;
protected:
virtual ~AudioBufferSourceNode();
private:
friend class AudioBufferSourceNodeEngine;
// START is sent during Start().
// STOP is sent during Stop().
@@ -139,6 +129,7 @@ private:
void SendBufferParameterToStream(JSContext* aCx);
void SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream);
private:
double mLoopStart;
double mLoopEnd;
double mOffset;
@@ -154,3 +145,4 @@ private:
} // namespace mozilla
#endif
+166 -49
View File
@@ -11,26 +11,10 @@
#include "mozilla/OwningNonNull.h"
#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/ChannelMergerNodeBinding.h"
#include "mozilla/dom/ChannelSplitterNodeBinding.h"
#include "mozilla/dom/ConvolverNodeBinding.h"
#include "mozilla/dom/DelayNodeBinding.h"
#include "mozilla/dom/DynamicsCompressorNodeBinding.h"
#include "mozilla/dom/GainNodeBinding.h"
#include "mozilla/dom/IIRFilterNodeBinding.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/MediaElementAudioSourceNodeBinding.h"
#include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
#include "mozilla/dom/OfflineAudioContextBinding.h"
#include "mozilla/dom/OscillatorNodeBinding.h"
#include "mozilla/dom/PannerNodeBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/StereoPannerNodeBinding.h"
#include "mozilla/dom/WaveShaperNodeBinding.h"
#include "AudioBuffer.h"
#include "AudioBufferSourceNode.h"
@@ -261,9 +245,13 @@ bool AudioContext::CheckClosed(ErrorResult& aRv)
already_AddRefed<AudioBufferSourceNode>
AudioContext::CreateBufferSource(ErrorResult& aRv)
{
return AudioBufferSourceNode::Create(nullptr, *this,
AudioBufferSourceOptions(),
aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AudioBufferSourceNode> bufferNode =
new AudioBufferSourceNode(this);
return bufferNode.forget();
}
already_AddRefed<ConstantSourceNode>
@@ -315,8 +303,18 @@ bool IsValidBufferSize(uint32_t aBufferSize) {
already_AddRefed<MediaStreamAudioDestinationNode>
AudioContext::CreateMediaStreamDestination(ErrorResult& aRv)
{
return MediaStreamAudioDestinationNode::Create(*this, AudioNodeOptions(),
aRv);
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<MediaStreamAudioDestinationNode> node =
new MediaStreamAudioDestinationNode(this);
return node.forget();
}
already_AddRefed<ScriptProcessorNode>
@@ -346,93 +344,181 @@ AudioContext::CreateScriptProcessor(uint32_t aBufferSize,
already_AddRefed<AnalyserNode>
AudioContext::CreateAnalyser(ErrorResult& aRv)
{
return AnalyserNode::Create(*this, AnalyserOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(this);
return analyserNode.forget();
}
already_AddRefed<StereoPannerNode>
AudioContext::CreateStereoPanner(ErrorResult& aRv)
{
return StereoPannerNode::Create(*this, StereoPannerOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<StereoPannerNode> stereoPannerNode = new StereoPannerNode(this);
return stereoPannerNode.forget();
}
already_AddRefed<MediaElementAudioSourceNode>
AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement,
ErrorResult& aRv)
{
MediaElementAudioSourceOptions options;
options.mMediaElement = aMediaElement;
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
return MediaElementAudioSourceNode::Create(*this, options, aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<DOMMediaStream> stream =
aMediaElement.CaptureAudio(aRv, mDestination->Stream()->Graph());
if (aRv.Failed()) {
return nullptr;
}
return MediaElementAudioSourceNode::Create(this, stream, aRv);
}
already_AddRefed<MediaStreamAudioSourceNode>
AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream,
ErrorResult& aRv)
{
MediaStreamAudioSourceOptions options;
options.mMediaStream = aMediaStream;
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
return MediaStreamAudioSourceNode::Create(*this, options, aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
return MediaStreamAudioSourceNode::Create(this, &aMediaStream, aRv);
}
already_AddRefed<GainNode>
AudioContext::CreateGain(ErrorResult& aRv)
{
return GainNode::Create(*this, GainOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<GainNode> gainNode = new GainNode(this);
return gainNode.forget();
}
already_AddRefed<WaveShaperNode>
AudioContext::CreateWaveShaper(ErrorResult& aRv)
{
return WaveShaperNode::Create(*this, WaveShaperOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<WaveShaperNode> waveShaperNode = new WaveShaperNode(this);
return waveShaperNode.forget();
}
already_AddRefed<DelayNode>
AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv)
{
DelayOptions options;
options.mMaxDelayTime = aMaxDelayTime;
return DelayNode::Create(*this, options, aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
if (aMaxDelayTime > 0. && aMaxDelayTime < 180.) {
RefPtr<DelayNode> delayNode = new DelayNode(this, aMaxDelayTime);
return delayNode.forget();
}
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
already_AddRefed<PannerNode>
AudioContext::CreatePanner(ErrorResult& aRv)
{
return PannerNode::Create(*this, PannerOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<PannerNode> pannerNode = new PannerNode(this);
mPannerNodes.PutEntry(pannerNode);
return pannerNode.forget();
}
already_AddRefed<ConvolverNode>
AudioContext::CreateConvolver(ErrorResult& aRv)
{
return ConvolverNode::Create(nullptr, *this, ConvolverOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ConvolverNode> convolverNode = new ConvolverNode(this);
return convolverNode.forget();
}
already_AddRefed<ChannelSplitterNode>
AudioContext::CreateChannelSplitter(uint32_t aNumberOfOutputs, ErrorResult& aRv)
{
ChannelSplitterOptions options;
options.mNumberOfOutputs = aNumberOfOutputs;
return ChannelSplitterNode::Create(*this, options, aRv);
if (aNumberOfOutputs == 0 ||
aNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ChannelSplitterNode> splitterNode =
new ChannelSplitterNode(this, aNumberOfOutputs);
return splitterNode.forget();
}
already_AddRefed<ChannelMergerNode>
AudioContext::CreateChannelMerger(uint32_t aNumberOfInputs, ErrorResult& aRv)
{
ChannelMergerOptions options;
options.mNumberOfInputs = aNumberOfInputs;
return ChannelMergerNode::Create(*this, options, aRv);
if (aNumberOfInputs == 0 ||
aNumberOfInputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ChannelMergerNode> mergerNode =
new ChannelMergerNode(this, aNumberOfInputs);
return mergerNode.forget();
}
already_AddRefed<DynamicsCompressorNode>
AudioContext::CreateDynamicsCompressor(ErrorResult& aRv)
{
return DynamicsCompressorNode::Create(*this, DynamicsCompressorOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<DynamicsCompressorNode> compressorNode =
new DynamicsCompressorNode(this);
return compressorNode.forget();
}
already_AddRefed<BiquadFilterNode>
AudioContext::CreateBiquadFilter(ErrorResult& aRv)
{
return BiquadFilterNode::Create(*this, BiquadFilterOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<BiquadFilterNode> filterNode =
new BiquadFilterNode(this);
return filterNode.forget();
}
already_AddRefed<IIRFilterNode>
@@ -440,16 +526,47 @@ AudioContext::CreateIIRFilter(const mozilla::dom::binding_detail::AutoSequence<d
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback,
mozilla::ErrorResult& aRv)
{
IIRFilterOptions options;
options.mFeedforward = aFeedforward;
options.mFeedback = aFeedback;
return IIRFilterNode::Create(*this, options, 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();
}
already_AddRefed<OscillatorNode>
AudioContext::CreateOscillator(ErrorResult& aRv)
{
return OscillatorNode::Create(*this, OscillatorOptions(), aRv);
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<OscillatorNode> oscillatorNode =
new OscillatorNode(this);
return oscillatorNode.forget();
}
already_AddRefed<PeriodicWave>
+2 -2
View File
@@ -316,8 +316,6 @@ public:
IMPL_EVENT_HANDLER(mozinterruptbegin)
IMPL_EVENT_HANDLER(mozinterruptend)
bool CheckClosed(ErrorResult& aRv);
private:
void DisconnectFromWindow();
void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob);
@@ -328,6 +326,8 @@ private:
friend struct ::mozilla::WebAudioDecodeJob;
bool CheckClosed(ErrorResult& aRv);
nsTArray<MediaStream*> GetAllStreams() const;
private:
-22
View File
@@ -71,28 +71,6 @@ AudioNode::~AudioNode()
}
}
void
AudioNode::Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv)
{
if (aOptions.mChannelCount.WasPassed()) {
SetChannelCount(aOptions.mChannelCount.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (aOptions.mChannelCountMode.WasPassed()) {
SetChannelCountModeValue(aOptions.mChannelCountMode.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (aOptions.mChannelInterpretation.WasPassed()) {
SetChannelInterpretationValue(aOptions.mChannelInterpretation.Value());
}
}
size_t
AudioNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
-3
View File
@@ -250,9 +250,6 @@ private:
bool DisconnectFromOutputIfConnected(uint32_t aOutputIndex, uint32_t aInputIndex);
protected:
// Helper for the Constructors for nodes.
void Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv);
// Helpers for sending different value types to streams
void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
void SendInt32ParameterToStream(uint32_t aIndex, int32_t aValue);
+1 -22
View File
@@ -262,29 +262,8 @@ BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
aContext->Graph());
}
/* static */ already_AddRefed<BiquadFilterNode>
BiquadFilterNode::Create(AudioContext& aAudioContext,
const BiquadFilterOptions& aOptions,
ErrorResult& aRv)
BiquadFilterNode::~BiquadFilterNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<BiquadFilterNode> audioNode = new BiquadFilterNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->SetType(aOptions.mType);
audioNode->Q()->SetValue(aOptions.mQ);
audioNode->Detune()->SetValue(aOptions.mDetune);
audioNode->Frequency()->SetValue(aOptions.mFrequency);
audioNode->Gain()->SetValue(aOptions.mGain);
return audioNode.forget();
}
size_t
+5 -14
View File
@@ -14,25 +14,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct BiquadFilterOptions;
class BiquadFilterNode final : public AudioNode
{
public:
static already_AddRefed<BiquadFilterNode>
Create(AudioContext& aAudioContext, const BiquadFilterOptions& aOptions,
ErrorResult& aRv);
explicit BiquadFilterNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
static already_AddRefed<BiquadFilterNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const BiquadFilterOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
BiquadFilterType Type() const
@@ -73,10 +63,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit BiquadFilterNode(AudioContext* aContext);
~BiquadFilterNode() = default;
protected:
virtual ~BiquadFilterNode();
private:
BiquadFilterType mType;
RefPtr<AudioParam> mFrequency;
RefPtr<AudioParam> mDetune;
@@ -88,3 +78,4 @@ private:
} // namespace mozilla
#endif
+2 -23
View File
@@ -74,30 +74,8 @@ ChannelMergerNode::ChannelMergerNode(AudioContext* aContext,
aContext->Graph());
}
/* static */ already_AddRefed<ChannelMergerNode>
ChannelMergerNode::Create(AudioContext& aAudioContext,
const ChannelMergerOptions& aOptions,
ErrorResult& aRv)
ChannelMergerNode::~ChannelMergerNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mNumberOfInputs == 0 ||
aOptions.mNumberOfInputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
RefPtr<ChannelMergerNode> audioNode =
new ChannelMergerNode(&aAudioContext, aOptions.mNumberOfInputs);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
JSObject*
@@ -108,3 +86,4 @@ ChannelMergerNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
} // namespace dom
} // namespace mozilla
+6 -15
View File
@@ -12,24 +12,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct ChannelMergerOptions;
class ChannelMergerNode final : public AudioNode
{
public:
static already_AddRefed<ChannelMergerNode>
Create(AudioContext& aAudioContext, const ChannelMergerOptions& aOptions,
ErrorResult& aRv);
ChannelMergerNode(AudioContext* aContext,
uint16_t aInputCount);
NS_DECL_ISUPPORTS_INHERITED
static already_AddRefed<ChannelMergerNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ChannelMergerOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t NumberOfInputs() const override { return mInputCount; }
@@ -44,11 +35,10 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
ChannelMergerNode(AudioContext* aContext,
uint16_t aInputCount);
~ChannelMergerNode() = default;
protected:
virtual ~ChannelMergerNode();
private:
const uint16_t mInputCount;
};
@@ -56,3 +46,4 @@ private:
} // namespace mozilla
#endif
+2 -23
View File
@@ -65,30 +65,8 @@ ChannelSplitterNode::ChannelSplitterNode(AudioContext* aContext,
aContext->Graph());
}
/* static */ already_AddRefed<ChannelSplitterNode>
ChannelSplitterNode::Create(AudioContext& aAudioContext,
const ChannelSplitterOptions& aOptions,
ErrorResult& aRv)
ChannelSplitterNode::~ChannelSplitterNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mNumberOfOutputs == 0 ||
aOptions.mNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
RefPtr<ChannelSplitterNode> audioNode =
new ChannelSplitterNode(&aAudioContext, aOptions.mNumberOfOutputs);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
JSObject*
@@ -99,3 +77,4 @@ ChannelSplitterNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProt
} // namespace dom
} // namespace mozilla
+6 -15
View File
@@ -12,24 +12,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct ChannelSplitterOptions;
class ChannelSplitterNode final : public AudioNode
{
public:
static already_AddRefed<ChannelSplitterNode>
Create(AudioContext& aAudioContext, const ChannelSplitterOptions& aOptions,
ErrorResult& aRv);
ChannelSplitterNode(AudioContext* aContext,
uint16_t aOutputCount);
NS_DECL_ISUPPORTS_INHERITED
static already_AddRefed<ChannelSplitterNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ChannelSplitterOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t NumberOfOutputs() const override { return mOutputCount; }
@@ -44,11 +35,10 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
ChannelSplitterNode(AudioContext* aContext,
uint16_t aOutputCount);
~ChannelSplitterNode() = default;
protected:
virtual ~ChannelSplitterNode();
private:
const uint16_t mOutputCount;
};
@@ -56,3 +46,4 @@ private:
} // namespace mozilla
#endif
+2 -27
View File
@@ -203,34 +203,8 @@ ConvolverNode::ConvolverNode(AudioContext* aContext)
aContext->Graph());
}
/* static */ already_AddRefed<ConvolverNode>
ConvolverNode::Create(JSContext* aCx, AudioContext& aAudioContext,
const ConvolverOptions& aOptions,
ErrorResult& aRv)
ConvolverNode::~ConvolverNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ConvolverNode> audioNode = new ConvolverNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// This must be done before setting the buffer.
audioNode->SetNormalize(!aOptions.mDisableNormalization);
if (aOptions.mBuffer.WasPassed()) {
MOZ_ASSERT(aCx);
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
return audioNode.forget();
}
size_t
@@ -317,3 +291,4 @@ ConvolverNode::SetNormalize(bool aNormalize)
} // namespace dom
} // namespace mozilla
+6 -17
View File
@@ -12,26 +12,14 @@
namespace mozilla {
namespace dom {
class AudioContext;
struct ConvolverOptions;
class ConvolverNode final : public AudioNode
{
public:
static already_AddRefed<ConvolverNode>
Create(JSContext* aCx, AudioContext& aAudioContext,
const ConvolverOptions& aOptions, ErrorResult& aRv);
explicit ConvolverNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConvolverNode, AudioNode);
static already_AddRefed<ConvolverNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ConvolverOptions& aOptions, ErrorResult& aRv)
{
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
AudioBuffer* GetBuffer(JSContext* aCx) const
@@ -39,7 +27,7 @@ public:
return mBuffer;
}
void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv);
void SetBuffer(JSContext* aCx, AudioBuffer* aBufferi, ErrorResult& aRv);
bool Normalize() const
{
@@ -73,10 +61,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit ConvolverNode(AudioContext* aContext);
~ConvolverNode() = default;
protected:
virtual ~ConvolverNode();
private:
RefPtr<AudioBuffer> mBuffer;
bool mNormalize;
};
@@ -86,3 +74,4 @@ private:
} //end namespace mozilla
#endif
+1 -23
View File
@@ -205,30 +205,8 @@ DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
aContext->Graph());
}
/* static */ already_AddRefed<DelayNode>
DelayNode::Create(AudioContext& aAudioContext,
const DelayOptions& aOptions,
ErrorResult& aRv)
DelayNode::~DelayNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mMaxDelayTime <= 0. || aOptions.mMaxDelayTime >= 180.) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
RefPtr<DelayNode> audioNode = new DelayNode(&aAudioContext,
aOptions.mMaxDelayTime);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->DelayTime()->SetValue(aOptions.mDelayTime);
return audioNode.forget();
}
size_t
+6 -14
View File
@@ -13,25 +13,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct DelayOptions;
class DelayNode final : public AudioNode
{
public:
static already_AddRefed<DelayNode>
Create(AudioContext& aAudioContext, const DelayOptions& aOptions,
ErrorResult& aRv);
DelayNode(AudioContext* aContext, double aMaxDelay);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode)
static already_AddRefed<DelayNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const DelayOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
AudioParam* DelayTime() const
@@ -47,12 +37,13 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
DelayNode(AudioContext* aContext, double aMaxDelay);
~DelayNode() = default;
protected:
virtual ~DelayNode();
private:
friend class DelayNodeEngine;
private:
RefPtr<AudioParam> mDelay;
};
@@ -60,3 +51,4 @@ private:
} // namespace mozilla
#endif
+1 -23
View File
@@ -204,30 +204,8 @@ DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
aContext->Graph());
}
/* static */ already_AddRefed<DynamicsCompressorNode>
DynamicsCompressorNode::Create(AudioContext& aAudioContext,
const DynamicsCompressorOptions& aOptions,
ErrorResult& aRv)
DynamicsCompressorNode::~DynamicsCompressorNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<DynamicsCompressorNode> audioNode =
new DynamicsCompressorNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->Attack()->SetValue(aOptions.mAttack);
audioNode->Knee()->SetValue(aOptions.mKnee);
audioNode->Ratio()->SetValue(aOptions.mRatio);
audioNode->GetRelease()->SetValue(aOptions.mRelease);
audioNode->Threshold()->SetValue(aOptions.mThreshold);
return audioNode.forget();
}
size_t
+5 -14
View File
@@ -13,25 +13,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct DynamicsCompressorOptions;
class DynamicsCompressorNode final : public AudioNode
{
public:
static already_AddRefed<DynamicsCompressorNode>
Create(AudioContext& aAudioContext, const DynamicsCompressorOptions& aOptions,
ErrorResult& aRv);
explicit DynamicsCompressorNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DynamicsCompressorNode, AudioNode)
static already_AddRefed<DynamicsCompressorNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const DynamicsCompressorOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
AudioParam* Threshold() const
@@ -79,10 +69,10 @@ public:
mReduction = aReduction;
}
private:
explicit DynamicsCompressorNode(AudioContext* aContext);
~DynamicsCompressorNode() = default;
protected:
virtual ~DynamicsCompressorNode();
private:
RefPtr<AudioParam> mThreshold;
RefPtr<AudioParam> mKnee;
RefPtr<AudioParam> mRatio;
@@ -95,3 +85,4 @@ private:
} // namespace mozilla
#endif
+1 -17
View File
@@ -128,24 +128,8 @@ GainNode::GainNode(AudioContext* aContext)
aContext->Graph());
}
/* static */ already_AddRefed<GainNode>
GainNode::Create(AudioContext& aAudioContext,
const GainOptions& aOptions,
ErrorResult& aRv)
GainNode::~GainNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<GainNode> audioNode = new GainNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->Gain()->SetValue(aOptions.mGain);
return audioNode.forget();
}
size_t
+5 -14
View File
@@ -13,25 +13,15 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct GainOptions;
class GainNode final : public AudioNode
{
public:
static already_AddRefed<GainNode>
Create(AudioContext& aAudioContext, const GainOptions& aOptions,
ErrorResult& aRv);
explicit GainNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GainNode, AudioNode)
static already_AddRefed<GainNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const GainOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
AudioParam* Gain() const
@@ -47,10 +37,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit GainNode(AudioContext* aContext);
~GainNode() = default;
protected:
virtual ~GainNode();
private:
RefPtr<AudioParam> mGain;
};
@@ -58,3 +48,4 @@ private:
} // namespace mozilla
#endif
+3 -41
View File
@@ -138,8 +138,8 @@ private:
};
IIRFilterNode::IIRFilterNode(AudioContext* aContext,
const Sequence<double>& aFeedforward,
const Sequence<double>& aFeedback)
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback)
: AudioNode(aContext,
2,
ChannelCountMode::Max,
@@ -173,46 +173,8 @@ IIRFilterNode::IIRFilterNode(AudioContext* aContext,
aContext->Graph());
}
/* static */ already_AddRefed<IIRFilterNode>
IIRFilterNode::Create(AudioContext& aAudioContext,
const IIRFilterOptions& aOptions,
ErrorResult& aRv)
IIRFilterNode::~IIRFilterNode()
{
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
+10 -18
View File
@@ -14,26 +14,19 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct IIRFilterOptions;
class IIRFilterNode final : public AudioNode
{
public:
static already_AddRefed<IIRFilterNode>
Create(AudioContext& aAudioContext, const IIRFilterOptions& aOptions,
ErrorResult& aRv);
explicit IIRFilterNode(AudioContext* aContext,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback);
NS_DECL_ISUPPORTS_INHERITED
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,
const Float32Array& aPhaseResponse);
@@ -46,17 +39,16 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
IIRFilterNode(AudioContext* aContext,
const Sequence<double>& aFeedforward,
const Sequence<double>& aFeedback);
~IIRFilterNode() = default;
protected:
virtual ~IIRFilterNode();
nsTArray<double> mFeedback;
nsTArray<double> mFeedforward;
private:
nsTArray<double> mFeedback;
nsTArray<double> mFeedforward;
};
} // namespace dom
} // namespace mozilla
#endif
@@ -15,29 +15,13 @@ MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext)
}
/* static */ already_AddRefed<MediaElementAudioSourceNode>
MediaElementAudioSourceNode::Create(AudioContext& aAudioContext,
const MediaElementAudioSourceOptions& aOptions,
ErrorResult& aRv)
MediaElementAudioSourceNode::Create(AudioContext* aContext,
DOMMediaStream* aStream, ErrorResult& aRv)
{
if (aAudioContext.IsOffline()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<MediaElementAudioSourceNode> node =
new MediaElementAudioSourceNode(&aAudioContext);
new MediaElementAudioSourceNode(aContext);
RefPtr<DOMMediaStream> stream =
aOptions.mMediaElement->CaptureAudio(aRv, aAudioContext.Destination()->Stream()->Graph());
if (aRv.Failed()) {
return nullptr;
}
node->Init(stream, aRv);
node->Init(aStream, aRv);
if (aRv.Failed()) {
return nullptr;
}
@@ -11,23 +11,11 @@
namespace mozilla {
namespace dom {
class AudioContext;
struct MediaElementAudioSourceOptions;
class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode
{
public:
static already_AddRefed<MediaElementAudioSourceNode>
Create(AudioContext& aAudioContext,
const MediaElementAudioSourceOptions& aOptions,
ErrorResult& aRv);
static already_AddRefed<MediaElementAudioSourceNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const MediaElementAudioSourceOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -15,7 +15,7 @@
namespace mozilla {
namespace dom {
class AudioDestinationTrackSource final :
class AudioDestinationTrackSource :
public MediaStreamTrackSource
{
public:
@@ -49,7 +49,7 @@ public:
}
private:
~AudioDestinationTrackSource() = default;
virtual ~AudioDestinationTrackSource() {}
RefPtr<MediaStreamAudioDestinationNode> mNode;
};
@@ -101,29 +101,8 @@ MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* a
mPort = outputStream->AllocateInputPort(mStream, AudioNodeStream::AUDIO_TRACK);
}
/* static */ already_AddRefed<MediaStreamAudioDestinationNode>
MediaStreamAudioDestinationNode::Create(AudioContext& aAudioContext,
const AudioNodeOptions& aOptions,
ErrorResult& aRv)
MediaStreamAudioDestinationNode::~MediaStreamAudioDestinationNode()
{
if (aAudioContext.IsOffline()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<MediaStreamAudioDestinationNode> audioNode =
new MediaStreamAudioDestinationNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
size_t
@@ -11,26 +11,14 @@
namespace mozilla {
namespace dom {
class AudioContext;
struct AudioNodeOptions;
class MediaStreamAudioDestinationNode final : public AudioNode
{
public:
static already_AddRefed<MediaStreamAudioDestinationNode>
Create(AudioContext& aAudioContext, const AudioNodeOptions& aOptions,
ErrorResult& aRv);
explicit MediaStreamAudioDestinationNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
static already_AddRefed<MediaStreamAudioDestinationNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AudioNodeOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t NumberOfOutputs() const final override
@@ -53,10 +41,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit MediaStreamAudioDestinationNode(AudioContext* aContext);
~MediaStreamAudioDestinationNode() = default;
protected:
virtual ~MediaStreamAudioDestinationNode();
private:
RefPtr<DOMMediaStream> mDOMStream;
RefPtr<MediaInputPort> mPort;
};
@@ -44,23 +44,13 @@ MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext)
}
/* static */ already_AddRefed<MediaStreamAudioSourceNode>
MediaStreamAudioSourceNode::Create(AudioContext& aAudioContext,
const MediaStreamAudioSourceOptions& aOptions,
ErrorResult& aRv)
MediaStreamAudioSourceNode::Create(AudioContext* aContext,
DOMMediaStream* aStream, ErrorResult& aRv)
{
if (aAudioContext.IsOffline()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<MediaStreamAudioSourceNode> node =
new MediaStreamAudioSourceNode(&aAudioContext);
new MediaStreamAudioSourceNode(aContext);
node->Init(aOptions.mMediaStream, aRv);
node->Init(aStream, aRv);
if (aRv.Failed()) {
return nullptr;
}
@@ -14,9 +14,6 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct MediaStreamAudioSourceOptions;
class MediaStreamAudioSourceNodeEngine final : public AudioNodeEngine
{
public:
@@ -48,19 +45,11 @@ class MediaStreamAudioSourceNode : public AudioNode,
{
public:
static already_AddRefed<MediaStreamAudioSourceNode>
Create(AudioContext& aContext, const MediaStreamAudioSourceOptions& aOptions,
ErrorResult& aRv);
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioSourceNode, AudioNode)
static already_AddRefed<MediaStreamAudioSourceNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const MediaStreamAudioSourceOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void DestroyMediaStream() override;
+1 -28
View File
@@ -425,35 +425,8 @@ OscillatorNode::OscillatorNode(AudioContext* aContext)
mStream->AddMainThreadListener(this);
}
/* static */ already_AddRefed<OscillatorNode>
OscillatorNode::Create(AudioContext& aAudioContext,
const OscillatorOptions& aOptions,
ErrorResult& aRv)
OscillatorNode::~OscillatorNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<OscillatorNode> audioNode = new OscillatorNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->SetType(aOptions.mType, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->Frequency()->SetValue(aOptions.mFrequency);
audioNode->Detune()->SetValue(aOptions.mDetune);
if (aOptions.mPeriodicWave.WasPassed()) {
audioNode->SetPeriodicWave(aOptions.mPeriodicWave.Value());
}
return audioNode.forget();
}
size_t
+6 -14
View File
@@ -15,26 +15,16 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct OscillatorOptions;
class OscillatorNode final : public AudioNode,
public MainThreadMediaStreamListener
{
public:
static already_AddRefed<OscillatorNode>
Create(AudioContext& aAudioContext, const OscillatorOptions& aOptions,
ErrorResult& aRv);
explicit OscillatorNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OscillatorNode, AudioNode)
static already_AddRefed<OscillatorNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const OscillatorOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void DestroyMediaStream() override;
@@ -91,13 +81,14 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit OscillatorNode(AudioContext* aContext);
~OscillatorNode() = default;
protected:
virtual ~OscillatorNode();
private:
void SendTypeToStream();
void SendPeriodicWaveToStream();
private:
OscillatorType mType;
RefPtr<PeriodicWave> mPeriodicWave;
RefPtr<AudioParam> mFrequency;
@@ -109,3 +100,4 @@ private:
} // namespace mozilla
#endif
+1 -32
View File
@@ -329,38 +329,6 @@ PannerNode::~PannerNode()
}
}
/* static */ already_AddRefed<PannerNode>
PannerNode::Create(AudioContext& aAudioContext,
const PannerOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<PannerNode> audioNode = new PannerNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->SetPanningModel(aOptions.mPanningModel);
audioNode->SetDistanceModel(aOptions.mDistanceModel);
audioNode->SetPosition(aOptions.mPositionX, aOptions.mPositionY,
aOptions.mPositionZ);
audioNode->SetOrientation(aOptions.mOrientationX, aOptions.mOrientationY,
aOptions.mOrientationZ);
audioNode->SetRefDistance(aOptions.mRefDistance);
audioNode->SetMaxDistance(aOptions.mMaxDistance);
audioNode->SetRolloffFactor(aOptions.mRolloffFactor);
audioNode->SetConeInnerAngle(aOptions.mConeInnerAngle);
audioNode->SetConeOuterAngle(aOptions.mConeOuterAngle);
audioNode->SetConeOuterGain(aOptions.mConeOuterGain);
return audioNode.forget();
}
void PannerNode::SetPanningModel(PanningModelType aPanningModel)
{
mPanningModel = aPanningModel;
@@ -816,3 +784,4 @@ PannerNode::SendDopplerToSourcesIfNeeded()
} // namespace dom
} // namespace mozilla
+5 -15
View File
@@ -19,24 +19,13 @@ namespace dom {
class AudioContext;
class AudioBufferSourceNode;
struct PannerOptions;
class PannerNode final : public AudioNode,
public SupportsWeakPtr<PannerNode>
{
public:
static already_AddRefed<PannerNode>
Create(AudioContext& aAudioContext, const PannerOptions& aOptions,
ErrorResult& aRv);
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PannerNode)
static already_AddRefed<PannerNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const PannerOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
explicit PannerNode(AudioContext* aContext);
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -240,10 +229,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit PannerNode(AudioContext* aContext);
~PannerNode();
protected:
virtual ~PannerNode();
private:
friend class AudioListener;
friend class PannerNodeEngine;
enum EngineParameters {
@@ -303,3 +292,4 @@ private:
} // namespace mozilla
#endif
+1 -26
View File
@@ -43,32 +43,6 @@ PeriodicWave::PeriodicWave(AudioContext* aContext,
mCoefficients->SetData(1, nullptr, free, buffer+aLength);
}
/* static */ already_AddRefed<PeriodicWave>
PeriodicWave::Constructor(const GlobalObject& aGlobal,
AudioContext& aAudioContext,
const PeriodicWaveOptions& aOptions,
ErrorResult& aRv)
{
if (!aOptions.mReal.WasPassed() || !aOptions.mImag.WasPassed() ||
aOptions.mReal.Value().Length() != aOptions.mImag.Value().Length() ||
aOptions.mReal.Value().Length() == 0) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
RefPtr<PeriodicWave> wave =
new PeriodicWave(&aAudioContext, aOptions.mReal.Value().Elements(),
aOptions.mImag.Value().Elements(),
aOptions.mReal.Value().Length(),
aOptions.mDisableNormalization,
aRv);
if (aRv.Failed()) {
return nullptr;
}
return wave.forget();
}
size_t
PeriodicWave::SizeOfExcludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
{
@@ -96,3 +70,4 @@ PeriodicWave::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
} // namespace dom
} // namespace mozilla
+1 -8
View File
@@ -16,9 +16,6 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct PeriodicWaveOptions;
class PeriodicWave final : public nsWrapperCache
{
public:
@@ -32,10 +29,6 @@ public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PeriodicWave)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PeriodicWave)
static already_AddRefed<PeriodicWave>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const PeriodicWaveOptions& aOptions, ErrorResult& aRv);
AudioContext* GetParentObject() const
{
return mContext;
@@ -62,7 +55,7 @@ public:
size_t SizeOfIncludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const;
private:
~PeriodicWave() = default;
~PeriodicWave() {}
RefPtr<AudioContext> mContext;
RefPtr<ThreadSharedFloatArrayBufferList> mCoefficients;
+1 -17
View File
@@ -182,24 +182,8 @@ StereoPannerNode::StereoPannerNode(AudioContext* aContext)
aContext->Graph());
}
/* static */ already_AddRefed<StereoPannerNode>
StereoPannerNode::Create(AudioContext& aAudioContext,
const StereoPannerOptions& aOptions,
ErrorResult& aRv)
StereoPannerNode::~StereoPannerNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<StereoPannerNode> audioNode = new StereoPannerNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->Pan()->SetValue(aOptions.mPan);
return audioNode.forget();
}
size_t
+5 -15
View File
@@ -13,23 +13,12 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct StereoPannerOptions;
class StereoPannerNode final : public AudioNode
{
public:
static already_AddRefed<StereoPannerNode>
Create(AudioContext& aAudioContext, const StereoPannerOptions& aOptions,
ErrorResult& aRv);
MOZ_DECLARE_REFCOUNTED_TYPENAME(StereoPannerNode)
static already_AddRefed<StereoPannerNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const StereoPannerOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
explicit StereoPannerNode(AudioContext* aContext);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -66,10 +55,10 @@ public:
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
private:
explicit StereoPannerNode(AudioContext* aContext);
~StereoPannerNode() = default;
protected:
virtual ~StereoPannerNode();
private:
RefPtr<AudioParam> mPan;
};
@@ -77,3 +66,4 @@ private:
} // namespace mozilla
#endif
+41 -91
View File
@@ -18,6 +18,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(WaveShaperNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WaveShaperNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
tmp->ClearCurve();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WaveShaperNode, AudioNode)
@@ -25,6 +26,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WaveShaperNode)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCurve)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WaveShaperNode)
@@ -311,39 +313,27 @@ WaveShaperNode::WaveShaperNode(AudioContext* aContext)
2,
ChannelCountMode::Max,
ChannelInterpretation::Speakers)
, mCurve(nullptr)
, mType(OverSampleType::None)
{
mozilla::HoldJSObjects(this);
WaveShaperNodeEngine* engine = new WaveShaperNodeEngine(this);
mStream = AudioNodeStream::Create(aContext, engine,
AudioNodeStream::NO_STREAM_FLAGS,
aContext->Graph());
}
/* static */ already_AddRefed<WaveShaperNode>
WaveShaperNode::Create(AudioContext& aAudioContext,
const WaveShaperOptions& aOptions,
ErrorResult& aRv)
WaveShaperNode::~WaveShaperNode()
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
ClearCurve();
}
RefPtr<WaveShaperNode> audioNode = new WaveShaperNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
if (aOptions.mCurve.WasPassed()) {
audioNode->SetCurveInternal(aOptions.mCurve.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
audioNode->SetOversample(aOptions.mOversample);
return audioNode.forget();
void
WaveShaperNode::ClearCurve()
{
mCurve = nullptr;
mozilla::DropJSObjects(this);
}
JSObject*
@@ -355,85 +345,45 @@ WaveShaperNode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
void
WaveShaperNode::SetCurve(const Nullable<Float32Array>& aCurve, ErrorResult& aRv)
{
// Let's purge the cached value for the curve attribute.
WaveShaperNodeBinding::ClearCachedCurveValue(this);
if (aCurve.IsNull()) {
CleanCurveInternal();
return;
}
const Float32Array& floats = aCurve.Value();
floats.ComputeLengthAndData();
if (floats.IsShared()) {
// Throw if the object is mapping shared memory (must opt in).
aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of WaveShaperNode.setCurve"));
return;
}
nsTArray<float> curve;
uint32_t argLength = floats.Length();
if (!curve.SetLength(argLength, fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
if (!aCurve.IsNull()) {
const Float32Array& floats = aCurve.Value();
floats.ComputeLengthAndData();
if (floats.IsShared()) {
// Throw if the object is mapping shared memory (must opt in).
aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of WaveShaperNode.setCurve"));
return;
}
uint32_t argLength = floats.Length();
if (argLength < 2) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (!curve.SetLength(argLength, fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
PodCopy(curve.Elements(), floats.Data(), floats.Length());
mCurve = floats.Obj();
} else {
mCurve = nullptr;
}
PodCopy(curve.Elements(), floats.Data(), argLength);
SetCurveInternal(curve, aRv);
}
void
WaveShaperNode::SetCurveInternal(const nsTArray<float>& aCurve,
ErrorResult& aRv)
{
if (aCurve.Length() < 2) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mCurve = aCurve;
SendCurveToStream();
}
void
WaveShaperNode::CleanCurveInternal()
{
mCurve.Clear();
SendCurveToStream();
}
void
WaveShaperNode::SendCurveToStream()
{
AudioNodeStream* ns = mStream;
MOZ_ASSERT(ns, "Why don't we have a stream here?");
nsTArray<float> copyCurve(mCurve);
ns->SetRawArrayData(copyCurve);
}
void
WaveShaperNode::GetCurve(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval)
{
// Let's return a null value if the list is empty.
if (mCurve.IsEmpty()) {
aRetval.set(nullptr);
return;
}
MOZ_ASSERT(mCurve.Length() >= 2);
aRetval.set(Float32Array::Create(aCx, this, mCurve.Length(),
mCurve.Elements()));
ns->SetRawArrayData(curve);
}
void
WaveShaperNode::SetOversample(OverSampleType aType)
{
mType = aType;
SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE,
static_cast<int32_t>(aType));
SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE, static_cast<int32_t>(aType));
}
} // namespace dom
+11 -21
View File
@@ -14,28 +14,21 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct WaveShaperOptions;
class WaveShaperNode final : public AudioNode
{
public:
static already_AddRefed<WaveShaperNode>
Create(AudioContext& aAudioContext, const WaveShaperOptions& aOptions,
ErrorResult& aRv);
explicit WaveShaperNode(AudioContext *aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WaveShaperNode, AudioNode)
static already_AddRefed<WaveShaperNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const WaveShaperOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval);
void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval) const
{
aRetval.set(mCurve);
}
void SetCurve(const Nullable<Float32Array>& aData, ErrorResult& aRv);
OverSampleType Oversample() const
@@ -61,17 +54,14 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
virtual ~WaveShaperNode();
private:
explicit WaveShaperNode(AudioContext *aContext);
~WaveShaperNode() = default;
void ClearCurve();
void SetCurveInternal(const nsTArray<float>& aCurve,
ErrorResult& aRv);
void CleanCurveInternal();
void SendCurveToStream();
nsTArray<float> mCurve;
private:
JS::Heap<JSObject*> mCurve;
OverSampleType mType;
};
+4 -79
View File
@@ -10,7 +10,9 @@
<pre id="test">
<script class="testbody" type="text/javascript">
function testNode() {
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var context = new AudioContext();
var buffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
@@ -82,7 +84,7 @@ function testNode() {
analyser.maxDecibels = -101;
}, DOMException.INDEX_SIZE_ERR);
ok(Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001, "Correct default value for smoothingTimeConstant");
is(analyser.smoothingTimeConstant, 0.8, "Correct default value for smoothingTimeConstant");
expectException(function() {
analyser.smoothingTimeConstant = -0.1;
}, DOMException.INDEX_SIZE_ERR);
@@ -91,83 +93,6 @@ function testNode() {
}, DOMException.INDEX_SIZE_ERR);
analyser.smoothingTimeConstant = 0;
analyser.smoothingTimeConstant = 1;
}
function testConstructor() {
var context = new AudioContext();
var analyser = new AnalyserNode(context);
is(analyser.channelCount, 1, "analyser node has 1 input channels by default");
is(analyser.channelCountMode, "max", "Correct channelCountMode for the analyser node");
is(analyser.channelInterpretation, "speakers", "Correct channelCountInterpretation for the analyser node");
is(analyser.fftSize, 2048, "Correct default value for fftSize");
is(analyser.frequencyBinCount, 1024, "Correct default value for frequencyBinCount");
is(analyser.minDecibels, -100, "Correct default value for minDecibels");
is(analyser.maxDecibels, -30, "Correct default value for maxDecibels");
ok(Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001, "Correct default value for smoothingTimeConstant");
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 0 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 1 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 8 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 100 }); // non-power of two
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 2049 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 4097 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 8193 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 16385 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 32769 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { fftSize: 65536 });
}, DOMException.INDEX_SIZE_ERR);
analyser = new AnalyserNode(context, { fftSize: 1024 });
is(analyser.frequencyBinCount, 512, "Correct new value for frequencyBinCount");
expectException(function() {
analyser = new AnalyserNode(context, { minDecibels: -30 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { minDecibels: -29 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { maxDecibels: -100 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { maxDecibels: -101 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { smoothingTimeConstant: -0.1 });
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser = new AnalyserNode(context, { smoothingTimeConstant: -1.1 });
}, DOMException.INDEX_SIZE_ERR);
analyser = new AnalyserNode(context, { smoothingTimeConstant: 0 });
analyser = new AnalyserNode(context, { smoothingTimeConstant: 1 });
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
testNode();
testConstructor();
SimpleTest.finish();
});
@@ -19,8 +19,12 @@ var gTest = {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
}
var source = new AudioBufferSourceNode(context, {buffer: buffer, loop: true, loopStart: buffer.duration * 0.25, loopEnd: buffer.duration * 0.75 });
var source = context.createBufferSource();
source.buffer = buffer;
source.start(0);
source.loop = true;
source.loopStart = buffer.duration * 0.25;
source.loopEnd = buffer.duration * 0.75;
return source;
},
createExpectedBuffers: function(context) {
@@ -24,7 +24,7 @@ var gTest = {
buffers.push(buffer);
}
var merger = new ChannelMergerNode(context);
var merger = context.createChannelMerger();
is(merger.channelCount, 1, "merger node has 1 input channels");
is(merger.channelCountMode, "explicit", "Correct channelCountMode for the merger node");
is(merger.channelInterpretation, "speakers", "Correct channelCountInterpretation for the merger node");
@@ -29,7 +29,7 @@ addLoadEvent(function() {
var source = context.createBufferSource();
var splitter = new ChannelSplitterNode(context);
var splitter = context.createChannelSplitter();
is(splitter.channelCount, 2, "splitter node has 2 input channels by default");
is(splitter.channelCountMode, "max", "Correct channelCountMode for the splitter node");
is(splitter.channelInterpretation, "speakers", "Correct channelCountInterpretation for the splitter node");
@@ -13,7 +13,7 @@
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var context = new AudioContext();
var conv = new ConvolverNode(context);
var conv = context.createConvolver();
is(conv.channelCount, 2, "Convolver node has 2 input channels by default");
is(conv.channelCountMode, "clamped-max", "Correct channelCountMode for the Convolver node");
+1 -28
View File
@@ -14,19 +14,6 @@ var gTest = {
length: 4096,
numberOfChannels: 1,
createGraph: function(context) {
var delay = new DelayNode(context);
ok(delay.delayTime, "The audioparam member must exist");
is(delay.delayTime.value, 0, "Correct initial value");
is(delay.delayTime.defaultValue, 0, "Correct default value");
delay.delayTime.value = 0.5;
is(delay.delayTime.value, 0.5, "Correct initial value");
is(delay.delayTime.defaultValue, 0, "Correct default value");
delay = new DelayNode(context, { delayTime: 0.5 });
ok(delay.delayTime, "The audioparam member must exist");
is(delay.delayTime.value, 0.5, "Correct initial value");
is(delay.delayTime.defaultValue, 0, "Correct default value");
var buffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
@@ -34,7 +21,7 @@ var gTest = {
var source = context.createBufferSource();
delay = context.createDelay();
var delay = context.createDelay();
source.buffer = buffer;
@@ -62,20 +49,6 @@ var gTest = {
expectException(function() {
context.createDelay(-1);
}, DOMException.NOT_SUPPORTED_ERR);
expectException(function() {
new DelayNode(context, { maxDelayTime: 0 });
}, DOMException.NOT_SUPPORTED_ERR);
expectException(function() {
new DelayNode(context, { maxDelayTime: 180 });
}, DOMException.NOT_SUPPORTED_ERR);
expectTypeError(function() {
new DelayNode(context, { maxDelayTime: NaN });
}, DOMException.NOT_SUPPORTED_ERR);
expectException(function() {
new DelayNode(context, { maxDelayTime: -1 });
}, DOMException.NOT_SUPPORTED_ERR);
context.createDelay(1); // should not throw
// Delay the source stream by 2048 frames
@@ -20,7 +20,7 @@ addLoadEvent(function() {
var osc = context.createOscillator();
var sp = context.createScriptProcessor();
var compressor = new DynamicsCompressorNode(context);
var compressor = context.createDynamicsCompressor();
osc.connect(compressor);
osc.connect(sp);
+3 -18
View File
@@ -14,32 +14,17 @@ var gTest = {
length: 2048,
numberOfChannels: 1,
createGraph: function(context) {
var gain = new GainNode(context);
ok(gain.gain, "The audioparam member must exist");
is(gain.gain.value, 1.0, "Correct initial value");
is(gain.gain.defaultValue, 1.0, "Correct default value");
gain.gain.value = 0.5;
is(gain.gain.value, 0.5, "Correct initial value");
is(gain.gain.defaultValue, 1.0, "Correct default value");
gain = new GainNode(context, { gain: 0.5 });
ok(gain.gain, "The audioparam member must exist");
is(gain.gain.value, 0.5, "Correct initial value");
is(gain.gain.defaultValue, 1.0, "Correct default value");
gain.gain.value = 0.5;
is(gain.gain.value, 0.5, "Correct initial value");
is(gain.gain.defaultValue, 1.0, "Correct default value");
var buffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
}
var source = context.createBufferSource();
var gain = context.createGain();
source.buffer = buffer;
gain = context.createGain();
source.connect(gain);
ok(gain.gain, "The audioparam member must exist");
@@ -56,7 +56,7 @@ function test() {
}
audio.onloadedmetadata = function() {
var node = new MediaElementAudioSourceNode(context, { mediaElement: audio });
var node = context.createMediaElementSource(audio);
var sp = context.createScriptProcessor(2048, 1);
node.connect(sp);
// Use a fuzz factor of 100 to account for samples that just happen to be zero
@@ -23,7 +23,7 @@ addLoadEvent(function() {
var source = context.createBufferSource();
source.buffer = buffer;
var dest = new MediaStreamAudioDestinationNode(context);
var dest = context.createMediaStreamDestination();
source.connect(dest);
var elem = document.getElementById('audioelem');
@@ -31,7 +31,7 @@ var gTest = {
source.connect(dest);
source.start(0);
var mediaStreamSource = new MediaStreamAudioSourceNode(context, { mediaStream: dest.stream });
var mediaStreamSource = context.createMediaStreamSource(dest.stream);
// channelCount and channelCountMode should have no effect
mediaStreamSource.channelCount = 1;
mediaStreamSource.channelCountMode = "explicit";
@@ -14,7 +14,7 @@ SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var context = new AudioContext();
var osc = new OscillatorNode(context);
var osc = context.createOscillator();
is(osc.channelCount, 2, "Oscillator node has 2 input channels by default");
is(osc.channelCountMode, "max", "Correct channelCountMode for the Oscillator node");
+1 -1
View File
@@ -25,7 +25,7 @@ addLoadEvent(function() {
var source = context.createBufferSource();
var panner = new PannerNode(context);
var panner = context.createPanner();
source.buffer = buffer;
@@ -49,7 +49,7 @@ function applyMonoToStereoPanning(c, panning) {
// Test the DOM interface
var context = new OfflineAudioContext(1, 1, SR);
var stereoPanner = new StereoPannerNode(context);
var stereoPanner = context.createStereoPanner();
ok(stereoPanner.pan, "The AudioParam member must exist");
is(stereoPanner.pan.value, 0.0, "Correct initial value");
is(stereoPanner.pan.defaultValue, 0.0, "Correct default value");
@@ -70,11 +70,8 @@ function sine(t) {
// A couple mono and stereo buffers: the StereoPannerNode equation is different
// if the input is mono or stereo
var stereoBuffer = new AudioBuffer(context, { numberOfChannels: 2,
length: BUF_SIZE });
var monoBuffer = new AudioBuffer(context, { numberOfChannels: 1,
length: BUF_SIZE,
sampleRate: context.sampleRate });
var stereoBuffer = context.createBuffer(2, BUF_SIZE, context.sampleRate);
var monoBuffer = context.createBuffer(1, BUF_SIZE, context.sampleRate);
for (var i = 0; i < BUF_SIZE; ++i) {
monoBuffer.getChannelData(0)[i] =
stereoBuffer.getChannelData(0)[i] =
@@ -84,9 +81,7 @@ for (var i = 0; i < BUF_SIZE; ++i) {
// Expected test vectors
function expectedBufferNoop(gain) {
gain = gain || 1.0;
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
length: BUF_SIZE,
sampleRate: SR });
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
for (var i = 0; i < BUF_SIZE; i++) {
expectedBuffer.getChannelData(0)[i] = gain * sine(i);
expectedBuffer.getChannelData(1)[i] = gain * sine(i);
@@ -96,9 +91,7 @@ function expectedBufferNoop(gain) {
function expectedBufferForStereo(gain) {
gain = gain || 1.0;
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
length: BUF_SIZE,
sampleRate: SR });
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
var gainPanning = gainForPanningStereoToStereo(PANNING);
gainPanning[0] *= gain;
gainPanning[1] *= gain;
@@ -113,9 +106,7 @@ function expectedBufferForStereo(gain) {
function expectedBufferForMono(gain) {
gain = gain || 1.0;
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
length: BUF_SIZE,
sampleRate: SR });
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
var gainPanning = gainForPanningMonoToStereo(PANNING);
gainPanning[0] *= gain;
gainPanning[1] *= gain;
+1 -1
View File
@@ -17,7 +17,7 @@ var gTest = {
var source = context.createBufferSource();
source.buffer = this.buffer;
var shaper = new WaveShaperNode(context);
var shaper = context.createWaveShaper();
shaper.curve = this.curve;
source.connect(shaper);
+2 -9
View File
@@ -10,15 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary AnalyserOptions : AudioNodeOptions {
unsigned long fftSize = 2048;
float maxDecibels = -30;
float minDecibels = -100;
float smoothingTimeConstant = 0.8;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional AnalyserOptions options)]
[Pref="dom.webaudio.enabled"]
interface AnalyserNode : AudioNode {
// Real-time frequency-domain data
@@ -46,3 +38,4 @@ interface AnalyserNode : AudioNode {
// Mozilla extension
AnalyserNode implements AudioNodePassThrough;
+2 -8
View File
@@ -10,14 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary AudioBufferOptions {
unsigned long numberOfChannels = 1;
required unsigned long length;
float sampleRate;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, AudioBufferOptions options)]
[Pref="dom.webaudio.enabled"]
interface AudioBuffer {
readonly attribute float sampleRate;
@@ -36,3 +29,4 @@ interface AudioBuffer {
[Throws]
void copyToChannel(Float32Array source, long channelNumber, optional unsigned long startInChannel = 0);
};
+1 -11
View File
@@ -10,17 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary AudioBufferSourceOptions {
AudioBuffer? buffer;
float detune = 0;
boolean loop = false;
double loopEnd = 0;
double loopStart = 0;
float playbackRate = 1;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional AudioBufferSourceOptions options)]
[Pref="dom.webaudio.enabled"]
interface AudioBufferSourceNode : AudioNode {
attribute AudioBuffer? buffer;
-6
View File
@@ -21,12 +21,6 @@ enum ChannelInterpretation {
"discrete"
};
dictionary AudioNodeOptions {
unsigned long channelCount;
ChannelCountMode channelCountMode;
ChannelInterpretation channelInterpretation;
};
[Pref="dom.webaudio.enabled"]
interface AudioNode : EventTarget {
+1 -10
View File
@@ -21,16 +21,7 @@ enum BiquadFilterType {
"allpass"
};
dictionary BiquadFilterOptions : AudioNodeOptions {
BiquadFilterType type = "lowpass";
float Q = 1;
float detune = 0;
float frequency = 350;
float gain = 0;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional BiquadFilterOptions options)]
[Pref="dom.webaudio.enabled"]
interface BiquadFilterNode : AudioNode {
attribute BiquadFilterType type;
+3 -6
View File
@@ -10,11 +10,8 @@
* liability, trademark and document use rules apply.
*/
dictionary ChannelMergerOptions : AudioNodeOptions {
unsigned long numberOfInputs = 6;
[Pref="dom.webaudio.enabled"]
interface ChannelMergerNode : AudioNode {
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional ChannelMergerOptions options)]
interface ChannelMergerNode : AudioNode {
};
+1 -6
View File
@@ -10,12 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary ChannelSplitterOptions : AudioNodeOptions {
unsigned long numberOfOutputs = 6;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional ChannelSplitterOptions options)]
[Pref="dom.webaudio.enabled"]
interface ChannelSplitterNode : AudioNode {
};
+1 -7
View File
@@ -10,13 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary ConvolverOptions : AudioNodeOptions {
AudioBuffer? buffer;
boolean disableNormalization = false;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional ConvolverOptions options)]
[Pref="dom.webaudio.enabled"]
interface ConvolverNode : AudioNode {
[SetterThrows]
+1 -7
View File
@@ -10,13 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary DelayOptions : AudioNodeOptions {
double maxDelayTime = 1;
double delayTime = 0;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional DelayOptions options)]
[Pref="dom.webaudio.enabled"]
interface DelayNode : AudioNode {
readonly attribute AudioParam delayTime;
+1 -10
View File
@@ -10,16 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary DynamicsCompressorOptions : AudioNodeOptions {
float attack = 0.003;
float knee = 30;
float ratio = 12;
float release = 0.25;
float threshold = -24;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional DynamicsCompressorOptions options)]
[Pref="dom.webaudio.enabled"]
interface DynamicsCompressorNode : AudioNode {
readonly attribute AudioParam threshold; // in Decibels
+1 -6
View File
@@ -10,12 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary GainOptions : AudioNodeOptions {
float gain = 1.0;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional GainOptions options)]
[Pref="dom.webaudio.enabled"]
interface GainNode : AudioNode {
readonly attribute AudioParam gain;
+1 -7
View File
@@ -9,13 +9,7 @@
* liability, trademark and document use rules apply.
*/
dictionary IIRFilterOptions : AudioNodeOptions {
required sequence<double> feedforward;
required sequence<double> feedback;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, IIRFilterOptions options)]
[Pref="dom.webaudio.enabled"]
interface IIRFilterNode : AudioNode {
void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
};
@@ -10,12 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary MediaElementAudioSourceOptions {
required HTMLMediaElement mediaElement;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, MediaElementAudioSourceOptions options)]
[Pref="dom.webaudio.enabled"]
interface MediaElementAudioSourceNode : AudioNode {
};
@@ -10,8 +10,9 @@
* liability, trademark and document use rules apply.
*/
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional AudioNodeOptions options)]
[Pref="dom.webaudio.enabled"]
interface MediaStreamAudioDestinationNode : AudioNode {
readonly attribute MediaStream stream;
};
+1 -6
View File
@@ -10,12 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary MediaStreamAudioSourceOptions {
required MediaStream mediaStream;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, MediaStreamAudioSourceOptions options)]
[Pref="dom.webaudio.enabled"]
interface MediaStreamAudioSourceNode : AudioNode {
};
+2 -9
View File
@@ -18,15 +18,7 @@ enum OscillatorType {
"custom"
};
dictionary OscillatorOptions : AudioNodeOptions {
OscillatorType type = "sine";
float frequency = 440;
float detune = 0;
PeriodicWave periodicWave;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional OscillatorOptions options)]
[Pref="dom.webaudio.enabled"]
interface OscillatorNode : AudioNode {
[SetterThrows]
@@ -47,3 +39,4 @@ interface OscillatorNode : AudioNode {
// Mozilla extensions
OscillatorNode implements AudioNodePassThrough;
+1 -19
View File
@@ -21,25 +21,7 @@ enum DistanceModelType {
"exponential"
};
dictionary PannerOptions : AudioNodeOptions {
PanningModelType panningModel = "equalpower";
DistanceModelType distanceModel = "inverse";
float positionX = 0;
float positionY = 0;
float positionZ = 0;
float orientationX = 1;
float orientationY = 0;
float orientationZ = 0;
double refDistance = 1;
double maxDistance = 10000;
double rolloffFactor = 1;
double coneInnerAngle = 360;
double coneOuterAngle = 360;
double coneOuterGain = 0;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional PannerOptions options)]
[Pref="dom.webaudio.enabled"]
interface PannerNode : AudioNode {
// Default for stereo is equalpower
+3 -7
View File
@@ -10,12 +10,8 @@
* liability, trademark and document use rules apply.
*/
dictionary PeriodicWaveOptions : PeriodicWaveConstraints {
sequence<float> real;
sequence<float> imag;
[Pref="dom.webaudio.enabled"]
interface PeriodicWave {
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, PeriodicWaveOptions options)]
interface PeriodicWave {
};
+1 -6
View File
@@ -10,12 +10,7 @@
* liability, trademark and document use rules apply.
*/
dictionary StereoPannerOptions : AudioNodeOptions {
float pan = 0;
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional StereoPannerOptions options)]
[Pref="dom.webaudio.enabled"]
interface StereoPannerNode : AudioNode {
readonly attribute AudioParam pan;
};
+2 -8
View File
@@ -16,16 +16,10 @@ enum OverSampleType {
"4x"
};
dictionary WaveShaperOptions : AudioNodeOptions {
sequence<float> curve;
OverSampleType oversample = "none";
};
[Pref="dom.webaudio.enabled",
Constructor(AudioContext context, optional WaveShaperOptions options)]
[Pref="dom.webaudio.enabled"]
interface WaveShaperNode : AudioNode {
[Cached, Pure, SetterThrows]
[SetterThrows]
attribute Float32Array? curve;
attribute OverSampleType oversample;
@@ -220,7 +220,8 @@ bool MacroExpander::expandMacro(const Macro &macro,
assert(macro.type == Macro::kTypeFunc);
std::vector<MacroArg> args;
args.reserve(macro.parameters.size());
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
if (replacements->size() == 0 ||
!collectMacroArgs(macro, identifier, &args, &replacementLocation))
return false;
replaceMacroParams(macro, args, replacements);