Bug 809654 - Implement BiquadFilterNode; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2012-11-07 20:59:14 -05:00
Родитель af06ad4293
Коммит aee7ba06a2
12 изменённых файлов: 284 добавлений и 12 удалений

Просмотреть файл

@ -17,6 +17,7 @@
#include "PannerNode.h"
#include "AudioListener.h"
#include "DynamicsCompressorNode.h"
#include "BiquadFilterNode.h"
namespace mozilla {
namespace dom {
@ -124,6 +125,14 @@ AudioContext::CreateDynamicsCompressor()
return compressorNode.forget();
}
already_AddRefed<BiquadFilterNode>
AudioContext::CreateBiquadFilter()
{
nsRefPtr<BiquadFilterNode> filterNode =
new BiquadFilterNode(this);
return filterNode.forget();
}
AudioListener*
AudioContext::Listener()
{

Просмотреть файл

@ -27,6 +27,7 @@ class AudioBuffer;
class AudioBufferSourceNode;
class AudioDestinationNode;
class AudioListener;
class BiquadFilterNode;
class DelayNode;
class DynamicsCompressorNode;
class GainNode;
@ -80,6 +81,9 @@ public:
already_AddRefed<DynamicsCompressorNode>
CreateDynamicsCompressor();
already_AddRefed<BiquadFilterNode>
CreateBiquadFilter();
private:
nsCOMPtr<nsIDOMWindow> mWindow;
nsRefPtr<AudioDestinationNode> mDestination;

Просмотреть файл

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BiquadFilterNode.h"
#include "mozilla/dom/BiquadFilterNodeBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(BiquadFilterNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFrequency)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQ)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGain)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mFrequency, AudioParam, "frequency value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mQ, AudioParam, "Q value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mGain, AudioParam, "gain value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BiquadFilterNode)
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(BiquadFilterNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(BiquadFilterNode, AudioNode)
static float
Nyquist(AudioContext* aContext)
{
// TODO: Replace the hardcoded 44100 here with AudioContext::SampleRate()
// when we implement that.
return 0.5f * 44100;
}
BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
: AudioNode(aContext)
, mType(BiquadTypeEnum::LOWPASS)
, mFrequency(new AudioParam(aContext, 350.f, 10.f, Nyquist(aContext)))
, mQ(new AudioParam(aContext, 1.f, 0.0001f, 1000.f))
, mGain(new AudioParam(aContext, 0.f, -40.f, 40.f))
{
}
JSObject*
BiquadFilterNode::WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
{
return BiquadFilterNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap);
}
}
}

Просмотреть файл

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BiquadFilterNode_h_
#define BiquadFilterNode_h_
#include "AudioNode.h"
#include "AudioParam.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
class AudioContext;
MOZ_BEGIN_ENUM_CLASS(BiquadTypeEnum, uint16_t)
LOWPASS = 0,
HIGHPASS = 1,
BANDPASS = 2,
LOWSHELF = 3,
HIGHSHELF = 4,
PEAKING = 5,
NOTCH = 6,
ALLPASS = 7,
Max = 7
MOZ_END_ENUM_CLASS(BiquadTypeEnum)
class BiquadFilterNode : public AudioNode
{
public:
explicit BiquadFilterNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap);
virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
{
return 1;
}
virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
{
return 1;
}
uint16_t Type() const
{
return static_cast<uint16_t> (mType);
}
void SetType(uint16_t aType, ErrorResult& aRv)
{
BiquadTypeEnum type = static_cast<BiquadTypeEnum> (aType);
if (type > BiquadTypeEnum::Max) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
} else {
mType = type;
}
}
AudioParam* Frequency() const
{
return mFrequency;
}
AudioParam* Q() const
{
return mQ;
}
AudioParam* Gain() const
{
return mGain;
}
private:
BiquadTypeEnum mType;
nsRefPtr<AudioParam> mFrequency;
nsRefPtr<AudioParam> mQ;
nsRefPtr<AudioParam> mGain;
};
}
}
#endif

Просмотреть файл

@ -23,6 +23,7 @@ CPPSRCS := \
AudioNode.cpp \
AudioParam.cpp \
AudioSourceNode.cpp \
BiquadFilterNode.cpp \
DelayNode.cpp \
DynamicsCompressorNode.cpp \
EnableWebAudioCheck.cpp \
@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \
AudioNode.h \
AudioParam.h \
AudioSourceNode.h \
BiquadFilterNode.h \
DelayNode.h \
DynamicsCompressorNode.h \
GainNode.h \

Просмотреть файл

@ -11,11 +11,13 @@ relativesrcdir := @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES := \
webaudio.js \
test_bug808374.html \
test_AudioBuffer.html \
test_AudioContext.html \
test_AudioListener.html \
test_badConnect.html \
test_biquadFilterNode.html \
test_delayNode.html \
test_dynamicsCompressorNode.html \
test_gainNode.html \

Просмотреть файл

@ -7,20 +7,9 @@
</head>
<body>
<pre id="test">
<script src="webaudio.js" type="text/javascript"></script>
<script class="testbody" type="text/javascript">
function expectException(func, exceptionCode) {
var threw = false;
try {
func();
} catch (ex) {
threw = true;
ok(ex instanceof DOMException, "Expect a DOM exception");
ok(ex.code, exceptionCode, "Expect the correct exception code");
}
ok(threw, "The exception was thrown");
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true);

Просмотреть файл

@ -0,0 +1,73 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test BiquadFilterNode</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script src="webaudio.js" type="text/javascript"></script>
<script class="testbody" type="text/javascript">
function near(a, b, msg) {
ok(Math.abs(a - b) < 1e-3, msg);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
var context = new mozAudioContext();
var buffer = context.createBuffer(1, 2048, 44100);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / 44100);
}
var destination = context.destination;
var source = context.createBufferSource();
var filter = context.createBiquadFilter();
source.buffer = buffer;
source.connect(filter);
filter.connect(destination);
// Verify default values
is(filter.type, 0, "Correct default value for type");
near(filter.frequency.minValue, 10, "Correct min value for filter frequency");
near(filter.frequency.maxValue, 22050, "Correct max value for filter frequency");
near(filter.frequency.defaultValue, 350, "Correct default value for filter frequency");
near(filter.Q.minValue, 0.001, "Correct min value for filter Q");
near(filter.Q.maxValue, 1000, "Correct max value for filter Q");
near(filter.Q.defaultValue, 1, "Correct default value for filter Q");
near(filter.gain.minValue, -40, "Correct min value for filter gain");
near(filter.gain.maxValue, 40, "Correct max value for filter gain");
near(filter.gain.defaultValue, 0, "Correct default value for filter gain");
// Make sure that we can set all of the valid type values
for (var i = 0; i <= 7; ++i) {
filter.type = i;
}
expectException(function() {
filter.type = 8;
}, DOMException.INDEX_SIZE_ERR);
source.start(0);
SimpleTest.executeSoon(function() {
source.stop(0);
source.disconnect();
filter.disconnect();
SpecialPowers.clearUserPref("media.webaudio.enabled");
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -114,6 +114,10 @@ DOMInterfaces = {
'concrete': False,
},
'BiquadFilterNode': {
'resultNotAddRefed': [ 'frequency', 'q', 'gain' ],
},
'Blob': [
{
'headerFile': 'nsIDOMFile.h',

Просмотреть файл

@ -31,6 +31,8 @@ interface mozAudioContext {
[Creator]
DelayNode createDelay(optional float maxDelayTime = 1);
[Creator]
BiquadFilterNode createBiquadFilter();
[Creator]
PannerNode createPanner();
[Creator]

Просмотреть файл

@ -0,0 +1,37 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[PrefControlled]
interface BiquadFilterNode : AudioNode {
// Filter type.
const unsigned short LOWPASS = 0;
const unsigned short HIGHPASS = 1;
const unsigned short BANDPASS = 2;
const unsigned short LOWSHELF = 3;
const unsigned short HIGHSHELF = 4;
const unsigned short PEAKING = 5;
const unsigned short NOTCH = 6;
const unsigned short ALLPASS = 7;
[SetterThrows]
attribute unsigned short type;
readonly attribute AudioParam frequency; // in Hertz
readonly attribute AudioParam Q; // Quality factor
readonly attribute AudioParam gain; // in Decibels
// void getFrequencyResponse(Float32Array frequencyHz,
// Float32Array magResponse,
// Float32Array phaseResponse);
};

Просмотреть файл

@ -17,6 +17,7 @@ webidl_files = \
AudioNode.webidl \
AudioParam.webidl \
AudioSourceNode.webidl \
BiquadFilterNode.webidl \
Blob.webidl \
CanvasRenderingContext2D.webidl \
ClientRectList.webidl \