diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-09-20 11:01:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-20 11:01:53 -0400 |
commit | ac331c6663f50300a1b647ecf3fc3df9d46eac97 (patch) | |
tree | dd67770addbc03215a6ac62b0699f91349ca3126 /components/script | |
parent | a6dbfdd29f9b3f0ce0c13adc79fad99538a9a44b (diff) | |
parent | daf85918e39a7fa1c47a69732711a2c35194eba2 (diff) | |
download | servo-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.rs | 7 | ||||
-rw-r--r-- | components/script/dom/biquadfilternode.rs | 184 | ||||
-rw-r--r-- | components/script/dom/gainnode.rs | 2 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/BaseAudioContext.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/BiquadFilterNode.webidl | 39 |
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); +}; |