aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-09-20 11:01:53 -0400
committerGitHub <noreply@github.com>2018-09-20 11:01:53 -0400
commitac331c6663f50300a1b647ecf3fc3df9d46eac97 (patch)
treedd67770addbc03215a6ac62b0699f91349ca3126 /components/script
parenta6dbfdd29f9b3f0ce0c13adc79fad99538a9a44b (diff)
parentdaf85918e39a7fa1c47a69732711a2c35194eba2 (diff)
downloadservo-ac331c6663f50300a1b647ecf3fc3df9d46eac97.tar.gz
servo-ac331c6663f50300a1b647ecf3fc3df9d46eac97.zip
Auto merge of #21750 - Manishearth:biquad, r=ferjm
Implement BiquadFilterNode A bunch of tests still fail but some of it may be a timing issue, looking at it the tests are *at least* affected by https://github.com/servo/servo/issues/21659 (changing how they work to avoid problems from that does not make them pass but does change the exact value of the error), so I feel like I should fix that first before investigating these. r? @ferjm <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21750) <!-- Reviewable:end -->
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/baseaudiocontext.rs7
-rw-r--r--components/script/dom/biquadfilternode.rs184
-rw-r--r--components/script/dom/gainnode.rs2
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/webidls/BaseAudioContext.webidl2
-rw-r--r--components/script/dom/webidls/BiquadFilterNode.webidl39
6 files changed, 233 insertions, 2 deletions
diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs
index f539f81bc4e..b892049a8ec 100644
--- a/components/script/dom/baseaudiocontext.rs
+++ b/components/script/dom/baseaudiocontext.rs
@@ -18,6 +18,7 @@ use dom::bindings::codegen::Bindings::BaseAudioContextBinding::AudioContextState
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::BaseAudioContextMethods;
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeErrorCallback;
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeSuccessCallback;
+use dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterOptions;
use dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::ChannelMergerOptions;
use dom::bindings::codegen::Bindings::GainNodeBinding::GainOptions;
use dom::bindings::codegen::Bindings::OscillatorNodeBinding::OscillatorOptions;
@@ -28,6 +29,7 @@ use dom::bindings::num::Finite;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::root::{DomRoot, MutNullableDom};
+use dom::biquadfilternode::BiquadFilterNode;
use dom::channelmergernode::ChannelMergerNode;
use dom::domexception::{DOMErrorName, DOMException};
use dom::eventtarget::EventTarget;
@@ -344,6 +346,11 @@ impl BaseAudioContextMethods for BaseAudioContext {
AnalyserNode::new(&self.global().as_window(), &self, &AnalyserOptions::empty())
}
+ /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbiquadfilter
+ fn CreateBiquadFilter(&self) -> Fallible<DomRoot<BiquadFilterNode>> {
+ BiquadFilterNode::new(&self.global().as_window(), &self, &BiquadFilterOptions::empty())
+ }
+
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createchannelmerger
fn CreateChannelMerger(&self, count: u32) -> Fallible<DomRoot<ChannelMergerNode>> {
let mut opts = ChannelMergerOptions::empty();
diff --git a/components/script/dom/biquadfilternode.rs b/components/script/dom/biquadfilternode.rs
new file mode 100644
index 00000000000..2ee309498be
--- /dev/null
+++ b/components/script/dom/biquadfilternode.rs
@@ -0,0 +1,184 @@
+/* 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/. */
+
+use dom::audionode::AudioNode;
+use dom::audioparam::AudioParam;
+use dom::baseaudiocontext::BaseAudioContext;
+use dom::bindings::codegen::Bindings::AudioNodeBinding::{ChannelCountMode, ChannelInterpretation};
+use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
+use dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::{self, BiquadFilterNodeMethods};
+use dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterOptions;
+use dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterType;
+use dom::bindings::error::Fallible;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::root::{Dom, DomRoot};
+use dom::window::Window;
+use dom_struct::dom_struct;
+use servo_media::audio::biquad_filter_node::{BiquadFilterNodeOptions, FilterType};
+use servo_media::audio::biquad_filter_node::BiquadFilterNodeMessage;
+use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage};
+use servo_media::audio::param::ParamType;
+use std::cell::Cell;
+use std::f32;
+
+#[dom_struct]
+pub struct BiquadFilterNode {
+ node: AudioNode,
+ gain: Dom<AudioParam>,
+ frequency: Dom<AudioParam>,
+ q: Dom<AudioParam>,
+ detune: Dom<AudioParam>,
+ filter: Cell<BiquadFilterType>,
+}
+
+impl BiquadFilterNode {
+ #[allow(unrooted_must_root)]
+ pub fn new_inherited(
+ window: &Window,
+ context: &BaseAudioContext,
+ options: &BiquadFilterOptions,
+ ) -> Fallible<BiquadFilterNode> {
+ let node_options = options.parent
+ .unwrap_or(2, ChannelCountMode::Max,
+ ChannelInterpretation::Speakers);
+ let filter = Cell::new(options.type_);
+ let options = options.into();
+ let node = AudioNode::new_inherited(
+ AudioNodeInit::BiquadFilterNode(options),
+ context,
+ node_options,
+ 1, // inputs
+ 1, // outputs
+ )?;
+ let gain = AudioParam::new(
+ window,
+ context,
+ node.node_id(),
+ ParamType::Gain,
+ AutomationRate::A_rate,
+ options.gain, // default value
+ f32::MIN, // min value
+ f32::MAX, // max value
+ );
+ let q = AudioParam::new(
+ window,
+ context,
+ node.node_id(),
+ ParamType::Q,
+ AutomationRate::A_rate,
+ options.q, // default value
+ f32::MIN, // min value
+ f32::MAX, // max value
+ );
+ let frequency = AudioParam::new(
+ window,
+ context,
+ node.node_id(),
+ ParamType::Frequency,
+ AutomationRate::A_rate,
+ options.frequency, // default value
+ f32::MIN, // min value
+ f32::MAX, // max value
+ );
+ let detune = AudioParam::new(
+ window,
+ context,
+ node.node_id(),
+ ParamType::Detune,
+ AutomationRate::A_rate,
+ options.detune, // default value
+ f32::MIN, // min value
+ f32::MAX, // max value
+ );
+ Ok(BiquadFilterNode {
+ node,
+ filter,
+ gain: Dom::from_ref(&gain),
+ q: Dom::from_ref(&q),
+ frequency: Dom::from_ref(&frequency),
+ detune: Dom::from_ref(&detune),
+ })
+ }
+
+ #[allow(unrooted_must_root)]
+ pub fn new(
+ window: &Window,
+ context: &BaseAudioContext,
+ options: &BiquadFilterOptions,
+ ) -> Fallible<DomRoot<BiquadFilterNode>> {
+ let node = BiquadFilterNode::new_inherited(window, context, options)?;
+ Ok(reflect_dom_object(Box::new(node), window, BiquadFilterNodeBinding::Wrap))
+ }
+
+ pub fn Constructor(
+ window: &Window,
+ context: &BaseAudioContext,
+ options: &BiquadFilterOptions,
+ ) -> Fallible<DomRoot<BiquadFilterNode>> {
+ BiquadFilterNode::new(window, context, options)
+ }
+}
+
+impl BiquadFilterNodeMethods for BiquadFilterNode {
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-gain
+ fn Gain(&self) -> DomRoot<AudioParam> {
+ DomRoot::from_ref(&self.gain)
+ }
+
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-q
+ fn Q(&self) -> DomRoot<AudioParam> {
+ DomRoot::from_ref(&self.q)
+ }
+
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-detune
+ fn Detune(&self) -> DomRoot<AudioParam> {
+ DomRoot::from_ref(&self.detune)
+ }
+
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-frequency
+ fn Frequency(&self) -> DomRoot<AudioParam> {
+ DomRoot::from_ref(&self.frequency)
+ }
+
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-type
+ fn Type(&self) -> BiquadFilterType {
+ self.filter.get()
+ }
+
+ // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-type
+ fn SetType(&self, filter: BiquadFilterType) {
+ self.filter.set(filter);
+ self.node
+ .message(AudioNodeMessage::BiquadFilterNode(
+ BiquadFilterNodeMessage::SetFilterType(filter.into()),
+ ));
+ }
+}
+
+impl<'a> From<&'a BiquadFilterOptions> for BiquadFilterNodeOptions {
+ fn from(options: &'a BiquadFilterOptions) -> Self {
+ Self {
+ gain: *options.gain,
+ q: *options.Q,
+ frequency: *options.frequency,
+ detune: *options.detune,
+ filter: options.type_.into()
+ }
+ }
+}
+
+impl From<BiquadFilterType> for FilterType {
+ fn from(filter: BiquadFilterType) -> FilterType {
+ match filter {
+ BiquadFilterType::Lowpass => FilterType::LowPass,
+ BiquadFilterType::Highpass => FilterType::HighPass,
+ BiquadFilterType::Bandpass => FilterType::BandPass,
+ BiquadFilterType::Lowshelf => FilterType::LowShelf,
+ BiquadFilterType::Highshelf => FilterType::HighShelf,
+ BiquadFilterType::Peaking => FilterType::Peaking,
+ BiquadFilterType::Allpass => FilterType::AllPass,
+ BiquadFilterType::Notch => FilterType::Notch,
+ }
+ }
+}
diff --git a/components/script/dom/gainnode.rs b/components/script/dom/gainnode.rs
index ea81ac58535..7e2235f5e80 100644
--- a/components/script/dom/gainnode.rs
+++ b/components/script/dom/gainnode.rs
@@ -48,7 +48,7 @@ impl GainNode {
node.node_id(),
ParamType::Gain,
AutomationRate::A_rate,
- 1., // default value
+ *options.gain, // default value
f32::MIN, // min value
f32::MAX, // max value
);
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 54b9adcc422..07425cccae1 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -228,6 +228,7 @@ pub mod audioscheduledsourcenode;
pub mod baseaudiocontext;
pub mod beforeunloadevent;
pub mod bindings;
+pub mod biquadfilternode;
pub mod blob;
pub mod bluetooth;
pub mod bluetoothadvertisingevent;
diff --git a/components/script/dom/webidls/BaseAudioContext.webidl b/components/script/dom/webidls/BaseAudioContext.webidl
index 9b8d8c5efa1..2883e60ffd8 100644
--- a/components/script/dom/webidls/BaseAudioContext.webidl
+++ b/components/script/dom/webidls/BaseAudioContext.webidl
@@ -38,7 +38,7 @@ interface BaseAudioContext : EventTarget {
[Throws] AnalyserNode createAnalyser();
[Throws] GainNode createGain();
// DelayNode createDelay(optional double maxDelayTime = 1);
- // BiquadFilterNode createBiquadFilter();
+ [Throws] BiquadFilterNode createBiquadFilter();
// IIRFilterNode createIIRFilter(sequence<double> feedforward,
// sequence<double> feedback);
// WaveShaperNode createWaveShaper();
diff --git a/components/script/dom/webidls/BiquadFilterNode.webidl b/components/script/dom/webidls/BiquadFilterNode.webidl
new file mode 100644
index 00000000000..24e993f5aa4
--- /dev/null
+++ b/components/script/dom/webidls/BiquadFilterNode.webidl
@@ -0,0 +1,39 @@
+/* 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://webaudio.github.io/web-audio-api/#biquadfilternode
+ */
+
+enum BiquadFilterType {
+ "lowpass",
+ "highpass",
+ "bandpass",
+ "lowshelf",
+ "highshelf",
+ "peaking",
+ "notch",
+ "allpass"
+};
+
+dictionary BiquadFilterOptions : AudioNodeOptions {
+ BiquadFilterType type = "lowpass";
+ float Q = 1;
+ float detune = 0;
+ float frequency = 350;
+ float gain = 0;
+};
+
+[Exposed=Window,
+ Constructor (BaseAudioContext context, optional BiquadFilterOptions options)]
+interface BiquadFilterNode : AudioNode {
+ attribute BiquadFilterType type;
+ readonly attribute AudioParam frequency;
+ readonly attribute AudioParam detune;
+ readonly attribute AudioParam Q;
+ readonly attribute AudioParam gain;
+ // the AudioParam model of https://github.com/servo/servo/issues/21659 needs to
+ // be implemented before we implement this
+ // void getFrequencyResponse (Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
+};