зеркало из https://github.com/mozilla/gecko-dev.git
Bug 809654 - Implement BiquadFilterNode; r=bzbarsky
This commit is contained in:
Родитель
af06ad4293
Коммит
aee7ba06a2
|
@ -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 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче