From 4b48cfa3ecd95298428a2d1d377a5a16020cc65b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 13:33:40 -0700 Subject: [PATCH 01/12] Upgrade to latest servo-media --- Cargo.lock | 18 ++++++++++++------ components/script/dom/audiodestinationnode.rs | 6 ++---- components/script/dom/audionode.rs | 15 ++++++++++++--- .../script/dom/audioscheduledsourcenode.rs | 1 - components/script/dom/gainnode.rs | 1 - 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04057be5ec1..17f87a0fdb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3197,7 +3197,7 @@ dependencies = [ [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#7a5c334698aa1e8a9cf95c5bd761e4a31489b6db" +source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" dependencies = [ "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)", @@ -3207,9 +3207,10 @@ dependencies = [ [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#7a5c334698aa1e8a9cf95c5bd761e4a31489b6db" +source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "servo_media_derive 0.1.0 (git+https://github.com/servo/media)", @@ -3219,7 +3220,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#7a5c334698aa1e8a9cf95c5bd761e4a31489b6db" +source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3227,7 +3228,7 @@ dependencies = [ "gstreamer-app 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-audio 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-player 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-player 0.1.0 (git+https://github.com/servo/media)", @@ -3237,7 +3238,12 @@ dependencies = [ [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#7a5c334698aa1e8a9cf95c5bd761e4a31489b6db" +source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +dependencies = [ + "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "servo-skia" @@ -3318,7 +3324,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#7a5c334698aa1e8a9cf95c5bd761e4a31489b6db" +source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" dependencies = [ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/script/dom/audiodestinationnode.rs b/components/script/dom/audiodestinationnode.rs index 06a871edc5a..f3c0190e193 100644 --- a/components/script/dom/audiodestinationnode.rs +++ b/components/script/dom/audiodestinationnode.rs @@ -10,7 +10,6 @@ use dom::bindings::reflector::reflect_dom_object; use dom::bindings::root::DomRoot; use dom::globalscope::GlobalScope; use dom_struct::dom_struct; -use servo_media::audio::node::AudioNodeInit; #[dom_struct] pub struct AudioDestinationNode { @@ -23,9 +22,8 @@ impl AudioDestinationNode { options: &AudioNodeOptions, ) -> AudioDestinationNode { AudioDestinationNode { - node: AudioNode::new_inherited( - AudioNodeInit::DestinationNode, - Some(context.destination_node()), + node: AudioNode::new_inherited_for_id( + context.destination_node(), context, options, 1, diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs index d193c9d77d9..88d2314f20f 100644 --- a/components/script/dom/audionode.rs +++ b/components/script/dom/audionode.rs @@ -36,17 +36,26 @@ pub struct AudioNode { channel_interpretation: Cell, } + impl AudioNode { pub fn new_inherited( node_type: AudioNodeInit, - node_id: Option, context: &BaseAudioContext, options: &AudioNodeOptions, number_of_inputs: u32, number_of_outputs: u32, ) -> AudioNode { - let node_id = - node_id.unwrap_or_else(|| context.audio_context_impl().create_node(node_type)); + let node_id = context.audio_context_impl().create_node(node_type); + AudioNode::new_inherited_for_id(node_id, context, options, number_of_inputs, number_of_outputs) + } + + pub fn new_inherited_for_id( + node_id: NodeId, + context: &BaseAudioContext, + options: &AudioNodeOptions, + number_of_inputs: u32, + number_of_outputs: u32, + ) -> AudioNode { AudioNode { eventtarget: EventTarget::new_inherited(), node_id, diff --git a/components/script/dom/audioscheduledsourcenode.rs b/components/script/dom/audioscheduledsourcenode.rs index c8ecf9a8fda..03f1f952102 100644 --- a/components/script/dom/audioscheduledsourcenode.rs +++ b/components/script/dom/audioscheduledsourcenode.rs @@ -34,7 +34,6 @@ impl AudioScheduledSourceNode { AudioScheduledSourceNode { node: AudioNode::new_inherited( node_type, - None, /* node_id */ context, options, number_of_inputs, diff --git a/components/script/dom/gainnode.rs b/components/script/dom/gainnode.rs index fe7ac041bf9..5cdbd8a89c9 100644 --- a/components/script/dom/gainnode.rs +++ b/components/script/dom/gainnode.rs @@ -38,7 +38,6 @@ impl GainNode { node_options.channelInterpretation = Some(ChannelInterpretation::Speakers); let node = AudioNode::new_inherited( AudioNodeInit::GainNode(gain_options.into()), - None, context, &node_options, 1, // inputs From 9228ca3a02078508f605ad8df9371df87f2339f2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 14:33:29 -0700 Subject: [PATCH 02/12] Add AudioListener DOM interface --- components/script/dom/audiolistener.rs | 190 ++++++++++++++++++ components/script/dom/baseaudiocontext.rs | 16 ++ components/script/dom/mod.rs | 1 + .../script/dom/webidls/AudioListener.webidl | 22 ++ .../dom/webidls/BaseAudioContext.webidl | 2 +- 5 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 components/script/dom/audiolistener.rs create mode 100644 components/script/dom/webidls/AudioListener.webidl diff --git a/components/script/dom/audiolistener.rs b/components/script/dom/audiolistener.rs new file mode 100644 index 00000000000..bf6c9b20d44 --- /dev/null +++ b/components/script/dom/audiolistener.rs @@ -0,0 +1,190 @@ +/* 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::audioparam::AudioParam; +use dom::baseaudiocontext::BaseAudioContext; +use dom::bindings::codegen::Bindings::AudioListenerBinding::{self, AudioListenerMethods}; +use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate; +use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::bindings::root::{Dom, DomRoot}; +use dom::window::Window; +use dom_struct::dom_struct; +use servo_media::audio::param::{ParamType, ParamDir}; +use std::f32; + +#[dom_struct] +pub struct AudioListener { + reflector_: Reflector, + position_x: Dom, + position_y: Dom, + position_z: Dom, + forward_x: Dom, + forward_y: Dom, + forward_z: Dom, + up_x: Dom, + up_y: Dom, + up_z: Dom, +} + +impl AudioListener { + fn new_inherited( + window: &Window, + context: &BaseAudioContext, + ) -> AudioListener { + let node = context.listener(); + + let position_x = AudioParam::new( + window, + context, + node, + ParamType::Position(ParamDir::X), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let position_y = AudioParam::new( + window, + context, + node, + ParamType::Position(ParamDir::Y), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let position_z = AudioParam::new( + window, + context, + node, + ParamType::Position(ParamDir::Z), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let forward_x = AudioParam::new( + window, + context, + node, + ParamType::Forward(ParamDir::X), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let forward_y = AudioParam::new( + window, + context, + node, + ParamType::Forward(ParamDir::Y), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let forward_z = AudioParam::new( + window, + context, + node, + ParamType::Forward(ParamDir::Z), + AutomationRate::A_rate, + -1., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let up_x = AudioParam::new( + window, + context, + node, + ParamType::Up(ParamDir::X), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let up_y = AudioParam::new( + window, + context, + node, + ParamType::Up(ParamDir::Y), + AutomationRate::A_rate, + 1., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let up_z = AudioParam::new( + window, + context, + node, + ParamType::Up(ParamDir::Z), + AutomationRate::A_rate, + 0., // default value + f32::MIN, // min value + f32::MAX, // max value + ); + AudioListener { + reflector_: Reflector::new(), + position_x: Dom::from_ref(&position_x), + position_y: Dom::from_ref(&position_y), + position_z: Dom::from_ref(&position_z), + forward_x: Dom::from_ref(&forward_x), + forward_y: Dom::from_ref(&forward_y), + forward_z: Dom::from_ref(&forward_z), + up_x: Dom::from_ref(&up_x), + up_y: Dom::from_ref(&up_y), + up_z: Dom::from_ref(&up_z), + } + } + + #[allow(unrooted_must_root)] + pub fn new( + window: &Window, + context: &BaseAudioContext, + ) -> DomRoot { + let node = AudioListener::new_inherited(window, context); + reflect_dom_object(Box::new(node), window, AudioListenerBinding::Wrap) + } +} + +impl AudioListenerMethods for AudioListener { + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionx + fn PositionX(&self) -> DomRoot { + DomRoot::from_ref(&self.position_x) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-positiony + fn PositionY(&self) -> DomRoot { + DomRoot::from_ref(&self.position_y) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionz + fn PositionZ(&self) -> DomRoot { + DomRoot::from_ref(&self.position_z) + } + + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardx + fn ForwardX(&self) -> DomRoot { + DomRoot::from_ref(&self.forward_x) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardy + fn ForwardY(&self) -> DomRoot { + DomRoot::from_ref(&self.forward_y) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardz + fn ForwardZ(&self) -> DomRoot { + DomRoot::from_ref(&self.forward_z) + } + + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-upx + fn UpX(&self) -> DomRoot { + DomRoot::from_ref(&self.up_x) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-upy + fn UpY(&self) -> DomRoot { + DomRoot::from_ref(&self.up_y) + } + // https://webaudio.github.io/web-audio-api/#dom-audiolistener-upz + fn UpZ(&self) -> DomRoot { + DomRoot::from_ref(&self.up_z) + } +} diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 583b1690048..c32f3fdcc3d 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -5,6 +5,7 @@ use dom::audiobuffer::AudioBuffer; use dom::audiobuffersourcenode::AudioBufferSourceNode; use dom::audiodestinationnode::AudioDestinationNode; +use dom::audiolistener::AudioListener; use dom::audionode::MAX_CHANNEL_COUNT; use dom::bindings::callback::ExceptionHandling; use dom::bindings::cell::DomRefCell; @@ -66,6 +67,7 @@ pub struct BaseAudioContext { audio_context_impl: Rc>, /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination destination: MutNullableDom, + listener: MutNullableDom, /// Resume promises which are soon to be fulfilled by a queued task. #[ignore_malloc_size_of = "promises are hard"] in_flight_resume_promises_queue: DomRefCell]>, ErrorResult)>>, @@ -101,6 +103,7 @@ impl BaseAudioContext { .create_audio_context(options.into()), ), destination: Default::default(), + listener: Default::default(), in_flight_resume_promises_queue: Default::default(), pending_resume_promises: Default::default(), decode_resolvers: Default::default(), @@ -125,6 +128,10 @@ impl BaseAudioContext { self.audio_context_impl.dest_node() } + pub fn listener(&self) -> NodeId { + self.audio_context_impl.listener() + } + // https://webaudio.github.io/web-audio-api/#allowed-to-start pub fn is_allowed_to_start(&self) -> bool { self.state.get() == AudioContextState::Suspended @@ -297,6 +304,15 @@ impl BaseAudioContextMethods for BaseAudioContext { }) } + /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-listener + fn Listener(&self) -> DomRoot { + let global = self.global(); + let window = global.as_window(); + self.listener.or_init(|| { + AudioListener::new(&window, self) + }) + } + /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-onstatechange event_handler!(statechange, GetOnstatechange, SetOnstatechange); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index ba1668e9f43..efc36131e77 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -220,6 +220,7 @@ pub mod audiobuffer; pub mod audiobuffersourcenode; pub mod audiocontext; pub mod audiodestinationnode; +pub mod audiolistener; pub mod audionode; pub mod audioparam; pub mod audioscheduledsourcenode; diff --git a/components/script/dom/webidls/AudioListener.webidl b/components/script/dom/webidls/AudioListener.webidl new file mode 100644 index 00000000000..a98fecdd565 --- /dev/null +++ b/components/script/dom/webidls/AudioListener.webidl @@ -0,0 +1,22 @@ +/* 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/#audiolistener + */ + +[Exposed=Window] +interface AudioListener { + readonly attribute AudioParam positionX; + readonly attribute AudioParam positionY; + readonly attribute AudioParam positionZ; + readonly attribute AudioParam forwardX; + readonly attribute AudioParam forwardY; + readonly attribute AudioParam forwardZ; + readonly attribute AudioParam upX; + readonly attribute AudioParam upY; + readonly attribute AudioParam upZ; + // void setPosition (float x, float y, float z); + // void setOrientation (float x, float y, float z, float xUp, float yUp, float zUp); +}; diff --git a/components/script/dom/webidls/BaseAudioContext.webidl b/components/script/dom/webidls/BaseAudioContext.webidl index 197ef3f357b..af0bc28a8be 100644 --- a/components/script/dom/webidls/BaseAudioContext.webidl +++ b/components/script/dom/webidls/BaseAudioContext.webidl @@ -20,7 +20,7 @@ interface BaseAudioContext : EventTarget { readonly attribute AudioDestinationNode destination; readonly attribute float sampleRate; readonly attribute double currentTime; - // readonly attribute AudioListener listener; + readonly attribute AudioListener listener; readonly attribute AudioContextState state; Promise resume(); attribute EventHandler onstatechange; From e4e01a64523f98b5f18fd86c6e7ef02096ad7ac2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 15:01:55 -0700 Subject: [PATCH 03/12] Add PannerNode DOM interface --- components/script/dom/mod.rs | 1 + components/script/dom/pannernode.rs | 210 ++++++++++++++++++ .../script/dom/webidls/PannerNode.webidl | 56 +++++ 3 files changed, 267 insertions(+) create mode 100644 components/script/dom/pannernode.rs create mode 100644 components/script/dom/webidls/PannerNode.webidl diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index efc36131e77..758c4284979 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -409,6 +409,7 @@ pub mod pagetransitionevent; pub mod paintrenderingcontext2d; pub mod paintsize; pub mod paintworkletglobalscope; +pub mod pannernode; pub mod performance; pub mod performanceentry; pub mod performancemark; diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs new file mode 100644 index 00000000000..cfb59578f31 --- /dev/null +++ b/components/script/dom/pannernode.rs @@ -0,0 +1,210 @@ +/* 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::AudioNodeBinding::AudioNodeOptions; +use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate; +use dom::bindings::codegen::Bindings::PannerNodeBinding::{self, PannerNodeMethods, PannerOptions}; +use dom::bindings::codegen::Bindings::PannerNodeBinding::{DistanceModelType, PanningModelType}; +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::panner_node::{DistanceModel, PannerNodeOptions, PanningModel}; +use servo_media::audio::node::AudioNodeInit; +use servo_media::audio::param::{ParamDir, ParamType}; +use std::f32; + +#[dom_struct] +pub struct PannerNode { + node: AudioNode, + position_x: Dom, + position_y: Dom, + position_z: Dom, + orientation_x: Dom, + orientation_y: Dom, + orientation_z: Dom, +} + +impl PannerNode { + #[allow(unrooted_must_root)] + pub fn new_inherited( + window: &Window, + context: &BaseAudioContext, + options: &PannerOptions, + ) -> PannerNode { + let mut node_options = AudioNodeOptions::empty(); + node_options.channelCount = Some(2); + node_options.channelCountMode = Some(ChannelCountMode::Clamped_max); + node_options.channelInterpretation = Some(ChannelInterpretation::Speakers); + let options = options.into(); + let node = AudioNode::new_inherited( + AudioNodeInit::PannerNode(options), + context, + &node_options, + 1, // inputs + 1, // outputs + ); + let id = node.node_id(); + let position_x = AudioParam::new( + window, + context, + id, + ParamType::Position(ParamDir::X), + AutomationRate::A_rate, + options.position_x, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let position_y = AudioParam::new( + window, + context, + id, + ParamType::Position(ParamDir::Y), + AutomationRate::A_rate, + options.position_y, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let position_z = AudioParam::new( + window, + context, + id, + ParamType::Position(ParamDir::Z), + AutomationRate::A_rate, + options.position_z, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let orientation_x = AudioParam::new( + window, + context, + id, + ParamType::Orientation(ParamDir::X), + AutomationRate::A_rate, + options.orientation_x, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let orientation_y = AudioParam::new( + window, + context, + id, + ParamType::Orientation(ParamDir::Y), + AutomationRate::A_rate, + options.orientation_y, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + let orientation_z = AudioParam::new( + window, + context, + id, + ParamType::Orientation(ParamDir::Z), + AutomationRate::A_rate, + options.orientation_z, // default value + f32::MIN, // min value + f32::MAX, // max value + ); + PannerNode { + node, + position_x: Dom::from_ref(&position_x), + position_y: Dom::from_ref(&position_y), + position_z: Dom::from_ref(&position_z), + orientation_x: Dom::from_ref(&orientation_x), + orientation_y: Dom::from_ref(&orientation_y), + orientation_z: Dom::from_ref(&orientation_z), + } + } + + #[allow(unrooted_must_root)] + pub fn new( + window: &Window, + context: &BaseAudioContext, + options: &PannerOptions, + ) -> DomRoot { + let node = PannerNode::new_inherited(window, context, options); + reflect_dom_object(Box::new(node), window, PannerNodeBinding::Wrap) + } + + pub fn Constructor( + window: &Window, + context: &BaseAudioContext, + options: &PannerOptions, + ) -> Fallible> { + Ok(PannerNode::new(window, context, options)) + } +} + +impl PannerNodeMethods for PannerNode { + // https://webaudio.github.io/web-audio-api/#dom-pannernode-positionx + fn PositionX(&self) -> DomRoot { + DomRoot::from_ref(&self.position_x) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-positiony + fn PositionY(&self) -> DomRoot { + DomRoot::from_ref(&self.position_y) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-positionz + fn PositionZ(&self) -> DomRoot { + DomRoot::from_ref(&self.position_z) + } + + // https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationx + fn OrientationX(&self) -> DomRoot { + DomRoot::from_ref(&self.orientation_x) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationy + fn OrientationY(&self) -> DomRoot { + DomRoot::from_ref(&self.orientation_y) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationz + fn OrientationZ(&self) -> DomRoot { + DomRoot::from_ref(&self.orientation_z) + } +} + +impl<'a> From<&'a PannerOptions> for PannerNodeOptions { + fn from(options: &'a PannerOptions) -> Self { + Self { + panning_model: options.panningModel.into(), + distance_model: options.distanceModel.into(), + position_x: *options.positionX, + position_y: *options.positionY, + position_z: *options.positionZ, + orientation_x: *options.orientationX, + orientation_y: *options.orientationY, + orientation_z: *options.orientationZ, + ref_distance: *options.refDistance, + max_distance: *options.maxDistance, + rolloff_factor: *options.rolloffFactor, + cone_inner_angle: *options.coneInnerAngle, + cone_outer_angle: *options.coneOuterAngle, + cone_outer_gain: *options.coneOuterGain, + } + } +} + +impl From for DistanceModel { + fn from(model: DistanceModelType) -> Self { + match model { + DistanceModelType::Linear => DistanceModel::Linear, + DistanceModelType::Inverse => DistanceModel::Inverse, + DistanceModelType::Exponential => DistanceModel::Exponential, + } + } +} + +impl From for PanningModel { + fn from(model: PanningModelType) -> Self { + match model { + PanningModelType::Equalpower => PanningModel::EqualPower, + PanningModelType::HRTF => PanningModel::HRTF, + } + } +} diff --git a/components/script/dom/webidls/PannerNode.webidl b/components/script/dom/webidls/PannerNode.webidl new file mode 100644 index 00000000000..625f6172409 --- /dev/null +++ b/components/script/dom/webidls/PannerNode.webidl @@ -0,0 +1,56 @@ +/* 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/#pannernode + */ + +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; +}; + +enum DistanceModelType { + "linear", + "inverse", + "exponential" +}; + +enum PanningModelType { + "equalpower", + "HRTF" +}; + +[Exposed=Window, + Constructor (BaseAudioContext context, optional PannerOptions options)] +interface PannerNode : AudioNode { + // attribute PanningModelType panningModel; + readonly attribute AudioParam positionX; + readonly attribute AudioParam positionY; + readonly attribute AudioParam positionZ; + readonly attribute AudioParam orientationX; + readonly attribute AudioParam orientationY; + readonly attribute AudioParam orientationZ; + // attribute DistanceModelType distanceModel; + // attribute double refDistance; + // attribute double maxDistance; + // attribute double rolloffFactor; + // attribute double coneInnerAngle; + // attribute double coneOuterAngle; + // attribute double coneOuterGain; + // void setPosition (float x, float y, float z); + // void setOrientation (float x, float y, float z); +}; \ No newline at end of file From 43ea9e0e4a0d2fc5366f770a3c1f64f344268558 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 15:03:53 -0700 Subject: [PATCH 04/12] cleanup: Remove Rc from BaseAudioContext --- components/script/dom/baseaudiocontext.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index c32f3fdcc3d..f9487b17c7d 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -64,7 +64,7 @@ struct DecodeResolver { pub struct BaseAudioContext { eventtarget: EventTarget, #[ignore_malloc_size_of = "servo_media"] - audio_context_impl: Rc>, + audio_context_impl: AudioContext, /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination destination: MutNullableDom, listener: MutNullableDom, @@ -97,11 +97,9 @@ impl BaseAudioContext { let context = BaseAudioContext { eventtarget: EventTarget::new_inherited(), - audio_context_impl: Rc::new( - ServoMedia::get() - .unwrap() - .create_audio_context(options.into()), - ), + audio_context_impl: ServoMedia::get() + .unwrap() + .create_audio_context(options.into()), destination: Default::default(), listener: Default::default(), in_flight_resume_promises_queue: Default::default(), @@ -120,8 +118,8 @@ impl BaseAudioContext { false } - pub fn audio_context_impl(&self) -> Rc> { - self.audio_context_impl.clone() + pub fn audio_context_impl(&self) -> &AudioContext { + &self.audio_context_impl } pub fn destination_node(&self) -> NodeId { From 062c1d607157028594f4133e997c8cdb6738ed7e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 15:31:13 -0700 Subject: [PATCH 05/12] Add BaseAudioContext.createPanner() --- components/script/dom/baseaudiocontext.rs | 8 ++++++++ components/script/dom/webidls/BaseAudioContext.webidl | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index f9487b17c7d..915f60a8e33 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -18,6 +18,7 @@ use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeErrorCallba use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeSuccessCallback; use dom::bindings::codegen::Bindings::GainNodeBinding::GainOptions; use dom::bindings::codegen::Bindings::OscillatorNodeBinding::OscillatorOptions; +use dom::bindings::codegen::Bindings::PannerNodeBinding::PannerOptions; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::num::Finite; @@ -28,6 +29,7 @@ use dom::domexception::{DOMErrorName, DOMException}; use dom::eventtarget::EventTarget; use dom::gainnode::GainNode; use dom::oscillatornode::OscillatorNode; +use dom::pannernode::PannerNode; use dom::promise::Promise; use dom::window::Window; use dom_struct::dom_struct; @@ -328,6 +330,12 @@ impl BaseAudioContextMethods for BaseAudioContext { GainNode::new(&self.global().as_window(), &self, &GainOptions::empty()) } + /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createpanner + fn CreatePanner(&self) -> DomRoot { + PannerNode::new(&self.global().as_window(), &self, &PannerOptions::empty()) + } + + /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer fn CreateBuffer( &self, diff --git a/components/script/dom/webidls/BaseAudioContext.webidl b/components/script/dom/webidls/BaseAudioContext.webidl index af0bc28a8be..4669d81c6e1 100644 --- a/components/script/dom/webidls/BaseAudioContext.webidl +++ b/components/script/dom/webidls/BaseAudioContext.webidl @@ -42,7 +42,7 @@ interface BaseAudioContext : EventTarget { // IIRFilterNode createIIRFilter(sequence feedforward, // sequence feedback); // WaveShaperNode createWaveShaper(); - // PannerNode createPanner(); + PannerNode createPanner(); // StereoPannerNode createStereoPanner(); // ConvolverNode createConvolver(); // ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6); From 0f66f170010381dcf782580f243b96171e9c301b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 23 Aug 2018 15:33:01 -0700 Subject: [PATCH 06/12] Add HTML test --- tests/html/webaudio/test_panner_listener.html | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/html/webaudio/test_panner_listener.html diff --git a/tests/html/webaudio/test_panner_listener.html b/tests/html/webaudio/test_panner_listener.html new file mode 100644 index 00000000000..11e031378ec --- /dev/null +++ b/tests/html/webaudio/test_panner_listener.html @@ -0,0 +1,32 @@ + From 7d5b4b204ccbbe2933d2af3fd1a7ce448d9fd369 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 08:31:45 -0700 Subject: [PATCH 07/12] Add constraints for PannerNode --- components/script/dom/audionode.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs index 88d2314f20f..4690f74245e 100644 --- a/components/script/dom/audionode.rs +++ b/components/script/dom/audionode.rs @@ -213,6 +213,11 @@ impl AudioNodeMethods for AudioNode { return Err(Error::IndexSize); } }, + EventTargetTypeId::AudioNode(AudioNodeTypeId::PannerNode) => { + if value > 2 { + return Err(Error::NotSupported) + } + } // XXX We do not support any of the other AudioNodes with // constraints yet. Add more cases here as we add support // for new AudioNodes. @@ -246,6 +251,11 @@ impl AudioNodeMethods for AudioNode { return Err(Error::InvalidState); } }, + EventTargetTypeId::AudioNode(AudioNodeTypeId::PannerNode) => { + if value == ChannelCountMode::Max { + return Err(Error::NotSupported) + } + } // XXX We do not support any of the other AudioNodes with // constraints yet. Add more cases here as we add support // for new AudioNodes. From 7daec55010e9877294475a1f01570d15375ee44b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 09:26:34 -0700 Subject: [PATCH 08/12] Add accessors for PannerNode --- Cargo.lock | 10 +- components/script/dom/bindings/trace.rs | 3 +- components/script/dom/pannernode.rs | 111 +++++++++++++++++- .../script/dom/webidls/PannerNode.webidl | 16 +-- 4 files changed, 125 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17f87a0fdb8..34893fb3da8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3197,7 +3197,7 @@ dependencies = [ [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" dependencies = [ "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)", @@ -3207,7 +3207,7 @@ dependencies = [ [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3220,7 +3220,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3238,7 +3238,7 @@ dependencies = [ [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" dependencies = [ "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#a3d25355acac0fe6f7f8b7af18e6fe1f910431ab" +source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" dependencies = [ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index fd0d346414c..41d1231a580 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -92,6 +92,7 @@ use servo_media::Backend; use servo_media::audio::buffer_source_node::AudioBuffer; use servo_media::audio::context::AudioContext; use servo_media::audio::graph::NodeId; +use servo_media::audio::panner_node::{DistanceModel, PanningModel}; use servo_media::audio::param::ParamType; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; @@ -434,7 +435,7 @@ unsafe_no_jsmanaged_fields!(SourceSet); unsafe_no_jsmanaged_fields!(AudioBuffer); unsafe_no_jsmanaged_fields!(AudioContext); unsafe_no_jsmanaged_fields!(NodeId); -unsafe_no_jsmanaged_fields!(ParamType); +unsafe_no_jsmanaged_fields!(DistanceModel, PanningModel, ParamType); unsafe impl<'a> JSTraceable for &'a str { #[inline] diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index cfb59578f31..558b5a005de 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -11,13 +11,17 @@ use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate; use dom::bindings::codegen::Bindings::PannerNodeBinding::{self, PannerNodeMethods, PannerOptions}; use dom::bindings::codegen::Bindings::PannerNodeBinding::{DistanceModelType, PanningModelType}; use dom::bindings::error::Fallible; +use dom::bindings::inheritance::Castable; +use dom::bindings::num::Finite; 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::panner_node::{DistanceModel, PannerNodeOptions, PanningModel}; -use servo_media::audio::node::AudioNodeInit; +use servo_media::audio::panner_node::PannerNodeMessage; +use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::param::{ParamDir, ParamType}; +use std::cell::Cell; use std::f32; #[dom_struct] @@ -29,6 +33,16 @@ pub struct PannerNode { orientation_x: Dom, orientation_y: Dom, orientation_z: Dom, + #[ignore_malloc_size_of = "servo_media"] + panning_model: Cell, + #[ignore_malloc_size_of = "servo_media"] + distance_model: Cell, + ref_distance: Cell, + max_distance: Cell, + rolloff_factor: Cell, + cone_inner_angle: Cell, + cone_outer_angle: Cell, + cone_outer_gain: Cell, } impl PannerNode { @@ -119,6 +133,14 @@ impl PannerNode { orientation_x: Dom::from_ref(&orientation_x), orientation_y: Dom::from_ref(&orientation_y), orientation_z: Dom::from_ref(&orientation_z), + panning_model: Cell::new(options.panning_model), + distance_model: Cell::new(options.distance_model), + ref_distance: Cell::new(options.ref_distance), + max_distance: Cell::new(options.max_distance), + rolloff_factor: Cell::new(options.rolloff_factor), + cone_inner_angle: Cell::new(options.cone_inner_angle), + cone_outer_angle: Cell::new(options.cone_outer_angle), + cone_outer_gain: Cell::new(options.cone_outer_gain), } } @@ -167,6 +189,93 @@ impl PannerNodeMethods for PannerNode { fn OrientationZ(&self) -> DomRoot { DomRoot::from_ref(&self.orientation_z) } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-distancemodel + fn DistanceModel(&self) -> DistanceModelType { + match self.distance_model.get() { + DistanceModel::Linear => DistanceModelType::Linear, + DistanceModel::Inverse => DistanceModelType::Inverse, + DistanceModel::Exponential => DistanceModelType::Exponential, + } + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-distancemodel + fn SetDistanceModel(&self, model: DistanceModelType) { + self.distance_model.set(model.into()); + let msg = PannerNodeMessage::SetDistanceModel(self.distance_model.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-panningmodel + fn PanningModel(&self) -> PanningModelType { + match self.panning_model.get() { + PanningModel::EqualPower => PanningModelType::Equalpower, + PanningModel::HRTF => PanningModelType::HRTF, + } + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-panningmodel + fn SetPanningModel(&self, model: PanningModelType) { + self.panning_model.set(model.into()); + let msg = PannerNodeMessage::SetPanningModel(self.panning_model.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-refdistance + fn RefDistance(&self) -> Finite { + Finite::wrap(self.ref_distance.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-refdistance + fn SetRefDistance(&self, val: Finite) { + self.ref_distance.set(*val); + let msg = PannerNodeMessage::SetRefDistance(self.ref_distance.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance + fn MaxDistance(&self) -> Finite { + Finite::wrap(self.max_distance.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance + fn SetMaxDistance(&self, val: Finite) { + self.max_distance.set(*val); + let msg = PannerNodeMessage::SetMaxDistance(self.max_distance.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor + fn RolloffFactor(&self) -> Finite { + Finite::wrap(self.rolloff_factor.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor + fn SetRolloffFactor(&self, val: Finite) { + self.rolloff_factor.set(*val); + let msg = PannerNodeMessage::SetRolloff(self.rolloff_factor.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneinnerangle + fn ConeInnerAngle(&self) -> Finite { + Finite::wrap(self.cone_inner_angle.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneinnerangle + fn SetConeInnerAngle(&self, val: Finite) { + self.cone_inner_angle.set(*val); + let msg = PannerNodeMessage::SetConeInner(self.cone_inner_angle.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneouterangle + fn ConeOuterAngle(&self) -> Finite { + Finite::wrap(self.cone_outer_angle.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneouterangle + fn SetConeOuterAngle(&self, val: Finite) { + self.cone_outer_angle.set(*val); + let msg = PannerNodeMessage::SetConeOuter(self.cone_outer_angle.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain + fn ConeOuterGain(&self) -> Finite { + Finite::wrap(self.cone_outer_gain.get()) + } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain + fn SetConeOuterGain(&self, val: Finite) { + self.cone_outer_gain.set(*val); + let msg = PannerNodeMessage::SetConeGain(self.cone_outer_gain.get()); + self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + } } impl<'a> From<&'a PannerOptions> for PannerNodeOptions { diff --git a/components/script/dom/webidls/PannerNode.webidl b/components/script/dom/webidls/PannerNode.webidl index 625f6172409..8429005887e 100644 --- a/components/script/dom/webidls/PannerNode.webidl +++ b/components/script/dom/webidls/PannerNode.webidl @@ -37,20 +37,20 @@ enum PanningModelType { [Exposed=Window, Constructor (BaseAudioContext context, optional PannerOptions options)] interface PannerNode : AudioNode { - // attribute PanningModelType panningModel; + attribute PanningModelType panningModel; readonly attribute AudioParam positionX; readonly attribute AudioParam positionY; readonly attribute AudioParam positionZ; readonly attribute AudioParam orientationX; readonly attribute AudioParam orientationY; readonly attribute AudioParam orientationZ; - // attribute DistanceModelType distanceModel; - // attribute double refDistance; - // attribute double maxDistance; - // attribute double rolloffFactor; - // attribute double coneInnerAngle; - // attribute double coneOuterAngle; - // attribute double coneOuterGain; + attribute DistanceModelType distanceModel; + attribute double refDistance; + attribute double maxDistance; + attribute double rolloffFactor; + attribute double coneInnerAngle; + attribute double coneOuterAngle; + attribute double coneOuterGain; // void setPosition (float x, float y, float z); // void setOrientation (float x, float y, float z); }; \ No newline at end of file From 18960b6c947453a3cf38794f5b70f8393dde3c6c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 09:48:22 -0700 Subject: [PATCH 09/12] Add PannerNode.setPosition(), setOrientation() --- components/script/dom/pannernode.rs | 19 +++++++++++++++++-- .../script/dom/webidls/PannerNode.webidl | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index 558b5a005de..9a596ab91b5 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -7,7 +7,7 @@ use dom::audioparam::AudioParam; use dom::baseaudiocontext::BaseAudioContext; use dom::bindings::codegen::Bindings::AudioNodeBinding::{ChannelCountMode, ChannelInterpretation}; use dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions; -use dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate; +use dom::bindings::codegen::Bindings::AudioParamBinding::{AudioParamMethods, AutomationRate}; use dom::bindings::codegen::Bindings::PannerNodeBinding::{self, PannerNodeMethods, PannerOptions}; use dom::bindings::codegen::Bindings::PannerNodeBinding::{DistanceModelType, PanningModelType}; use dom::bindings::error::Fallible; @@ -17,9 +17,9 @@ 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::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::panner_node::{DistanceModel, PannerNodeOptions, PanningModel}; use servo_media::audio::panner_node::PannerNodeMessage; -use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage}; use servo_media::audio::param::{ParamDir, ParamType}; use std::cell::Cell; use std::f32; @@ -189,6 +189,7 @@ impl PannerNodeMethods for PannerNode { fn OrientationZ(&self) -> DomRoot { DomRoot::from_ref(&self.orientation_z) } + // https://webaudio.github.io/web-audio-api/#dom-pannernode-distancemodel fn DistanceModel(&self) -> DistanceModelType { match self.distance_model.get() { @@ -276,6 +277,20 @@ impl PannerNodeMethods for PannerNode { let msg = PannerNodeMessage::SetConeGain(self.cone_outer_gain.get()); self.upcast::().message(AudioNodeMessage::PannerNode(msg)); } + + // https://webaudio.github.io/web-audio-api/#dom-pannernode-setposition + fn SetPosition(&self, x: Finite, y: Finite, z: Finite) { + self.position_x.SetValue(x); + self.position_y.SetValue(y); + self.position_z.SetValue(z); + } + + // https://webaudio.github.io/web-audio-api/#dom-pannernode-setorientation + fn SetOrientation(&self, x: Finite, y: Finite, z: Finite) { + self.orientation_x.SetValue(x); + self.orientation_y.SetValue(y); + self.orientation_z.SetValue(z); + } } impl<'a> From<&'a PannerOptions> for PannerNodeOptions { diff --git a/components/script/dom/webidls/PannerNode.webidl b/components/script/dom/webidls/PannerNode.webidl index 8429005887e..e762d9dd110 100644 --- a/components/script/dom/webidls/PannerNode.webidl +++ b/components/script/dom/webidls/PannerNode.webidl @@ -51,6 +51,6 @@ interface PannerNode : AudioNode { attribute double coneInnerAngle; attribute double coneOuterAngle; attribute double coneOuterGain; - // void setPosition (float x, float y, float z); - // void setOrientation (float x, float y, float z); -}; \ No newline at end of file + void setPosition (float x, float y, float z); + void setOrientation (float x, float y, float z); +}; From 58176c414817d48d019bb7bf5643623c556c4f71 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 12:17:26 -0700 Subject: [PATCH 10/12] Add some checks in PannerNode accessors --- components/script/dom/pannernode.rs | 20 +++++++++++++++---- .../script/dom/webidls/PannerNode.webidl | 6 +++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index 9a596ab91b5..089de7c1ec4 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions; use dom::bindings::codegen::Bindings::AudioParamBinding::{AudioParamMethods, AutomationRate}; use dom::bindings::codegen::Bindings::PannerNodeBinding::{self, PannerNodeMethods, PannerOptions}; use dom::bindings::codegen::Bindings::PannerNodeBinding::{DistanceModelType, PanningModelType}; -use dom::bindings::error::Fallible; +use dom::bindings::error::{Error, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::num::Finite; use dom::bindings::reflector::reflect_dom_object; @@ -232,20 +232,28 @@ impl PannerNodeMethods for PannerNode { Finite::wrap(self.max_distance.get()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance - fn SetMaxDistance(&self, val: Finite) { + fn SetMaxDistance(&self, val: Finite) -> Fallible<()> { + if *val < 0. { + return Err(Error::NotSupported) + } self.max_distance.set(*val); let msg = PannerNodeMessage::SetMaxDistance(self.max_distance.get()); self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + Ok(()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor fn RolloffFactor(&self) -> Finite { Finite::wrap(self.rolloff_factor.get()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor - fn SetRolloffFactor(&self, val: Finite) { + fn SetRolloffFactor(&self, val: Finite) -> Fallible<()> { + if *val < 0. { + return Err(Error::Range("value should be positive".into())) + } self.rolloff_factor.set(*val); let msg = PannerNodeMessage::SetRolloff(self.rolloff_factor.get()); self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + Ok(()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneinnerangle fn ConeInnerAngle(&self) -> Finite { @@ -272,10 +280,14 @@ impl PannerNodeMethods for PannerNode { Finite::wrap(self.cone_outer_gain.get()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain - fn SetConeOuterGain(&self, val: Finite) { + fn SetConeOuterGain(&self, val: Finite) -> Fallible<()> { + if *val < 0. || *val > 360. { + return Err(Error::InvalidState) + } self.cone_outer_gain.set(*val); let msg = PannerNodeMessage::SetConeGain(self.cone_outer_gain.get()); self.upcast::().message(AudioNodeMessage::PannerNode(msg)); + Ok(()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-setposition diff --git a/components/script/dom/webidls/PannerNode.webidl b/components/script/dom/webidls/PannerNode.webidl index e762d9dd110..18d01f52b11 100644 --- a/components/script/dom/webidls/PannerNode.webidl +++ b/components/script/dom/webidls/PannerNode.webidl @@ -46,11 +46,11 @@ interface PannerNode : AudioNode { readonly attribute AudioParam orientationZ; attribute DistanceModelType distanceModel; attribute double refDistance; - attribute double maxDistance; - attribute double rolloffFactor; + [SetterThrows] attribute double maxDistance; + [SetterThrows] attribute double rolloffFactor; attribute double coneInnerAngle; attribute double coneOuterAngle; - attribute double coneOuterGain; + [SetterThrows] attribute double coneOuterGain; void setPosition (float x, float y, float z); void setOrientation (float x, float y, float z); }; From 5dd830344b047633749413c29b330f4d4b4e2ba3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 12:42:50 -0700 Subject: [PATCH 11/12] Handle channel count constraints in panner constructor --- components/script/dom/baseaudiocontext.rs | 2 +- components/script/dom/pannernode.rs | 26 ++++++++++++------- .../dom/webidls/BaseAudioContext.webidl | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 915f60a8e33..9513a0b22d1 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -331,7 +331,7 @@ impl BaseAudioContextMethods for BaseAudioContext { } /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createpanner - fn CreatePanner(&self) -> DomRoot { + fn CreatePanner(&self) -> Fallible> { PannerNode::new(&self.global().as_window(), &self, &PannerOptions::empty()) } diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index 089de7c1ec4..7f1909cdb50 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -51,10 +51,18 @@ impl PannerNode { window: &Window, context: &BaseAudioContext, options: &PannerOptions, - ) -> PannerNode { + ) -> Fallible { + let count = options.parent.channelCount.unwrap_or(2); + let mode = options.parent.channelCountMode.unwrap_or(ChannelCountMode::Clamped_max); + if mode == ChannelCountMode::Max { + return Err(Error::NotSupported) + } + if count > 2 { + return Err(Error::NotSupported) + } let mut node_options = AudioNodeOptions::empty(); - node_options.channelCount = Some(2); - node_options.channelCountMode = Some(ChannelCountMode::Clamped_max); + node_options.channelCount = Some(count); + node_options.channelCountMode = Some(mode); node_options.channelInterpretation = Some(ChannelInterpretation::Speakers); let options = options.into(); let node = AudioNode::new_inherited( @@ -125,7 +133,7 @@ impl PannerNode { f32::MIN, // min value f32::MAX, // max value ); - PannerNode { + Ok(PannerNode { node, position_x: Dom::from_ref(&position_x), position_y: Dom::from_ref(&position_y), @@ -141,7 +149,7 @@ impl PannerNode { cone_inner_angle: Cell::new(options.cone_inner_angle), cone_outer_angle: Cell::new(options.cone_outer_angle), cone_outer_gain: Cell::new(options.cone_outer_gain), - } + }) } #[allow(unrooted_must_root)] @@ -149,9 +157,9 @@ impl PannerNode { window: &Window, context: &BaseAudioContext, options: &PannerOptions, - ) -> DomRoot { - let node = PannerNode::new_inherited(window, context, options); - reflect_dom_object(Box::new(node), window, PannerNodeBinding::Wrap) + ) -> Fallible> { + let node = PannerNode::new_inherited(window, context, options)?; + Ok(reflect_dom_object(Box::new(node), window, PannerNodeBinding::Wrap)) } pub fn Constructor( @@ -159,7 +167,7 @@ impl PannerNode { context: &BaseAudioContext, options: &PannerOptions, ) -> Fallible> { - Ok(PannerNode::new(window, context, options)) + PannerNode::new(window, context, options) } } diff --git a/components/script/dom/webidls/BaseAudioContext.webidl b/components/script/dom/webidls/BaseAudioContext.webidl index 4669d81c6e1..f00ec373667 100644 --- a/components/script/dom/webidls/BaseAudioContext.webidl +++ b/components/script/dom/webidls/BaseAudioContext.webidl @@ -42,7 +42,7 @@ interface BaseAudioContext : EventTarget { // IIRFilterNode createIIRFilter(sequence feedforward, // sequence feedback); // WaveShaperNode createWaveShaper(); - PannerNode createPanner(); + [Throws] PannerNode createPanner(); // StereoPannerNode createStereoPanner(); // ConvolverNode createConvolver(); // ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6); From 04e60e683a3307ee28e6b97730353cf23f4691c5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Aug 2018 12:52:24 -0700 Subject: [PATCH 12/12] Update WPT expectations --- .../wpt/metadata/webaudio/historical.html.ini | 13 - .../webaudio/idlharness.https.window.js.ini | 291 ------------------ .../audiobuffersource-multi-channels.html.ini | 5 +- .../ctor-panner.html.ini | 13 +- .../distance-exponential.html.ini | 10 +- .../distance-inverse.html.ini | 10 +- .../distance-linear.html.ini | 10 +- ...nner-automation-equalpower-stereo.html.ini | 10 +- .../panner-distance-clamping.html.ini | 25 ++ .../panner-equalpower-stereo.html.ini | 10 +- .../panner-equalpower.html.ini | 8 +- .../pannernode-basic.html.ini | 1 - tests/wpt/mozilla/meta/MANIFEST.json | 2 +- .../wpt/mozilla/tests/mozilla/interfaces.html | 2 + 14 files changed, 96 insertions(+), 314 deletions(-) delete mode 100644 tests/wpt/metadata/webaudio/historical.html.ini diff --git a/tests/wpt/metadata/webaudio/historical.html.ini b/tests/wpt/metadata/webaudio/historical.html.ini deleted file mode 100644 index 3279a2dc99f..00000000000 --- a/tests/wpt/metadata/webaudio/historical.html.ini +++ /dev/null @@ -1,13 +0,0 @@ -[historical.html] - [dopplerFactor member should not exist on the AudioListener.] - expected: FAIL - - [speedOfSound member should not exist on the AudioListener.] - expected: FAIL - - [setVelocity member should not exist on the AudioListener.] - expected: FAIL - - [setVelocity should not exist on PannerNodes.] - expected: FAIL - diff --git a/tests/wpt/metadata/webaudio/idlharness.https.window.js.ini b/tests/wpt/metadata/webaudio/idlharness.https.window.js.ini index a2dd21e21e6..d95bb14fe01 100644 --- a/tests/wpt/metadata/webaudio/idlharness.https.window.js.ini +++ b/tests/wpt/metadata/webaudio/idlharness.https.window.js.ini @@ -5,9 +5,6 @@ [Test driver] expected: FAIL - [BaseAudioContext interface: attribute listener] - expected: FAIL - [BaseAudioContext interface: attribute audioWorklet] expected: FAIL @@ -38,9 +35,6 @@ [BaseAudioContext interface: operation createIIRFilter([object Object\], [object Object\])] expected: FAIL - [BaseAudioContext interface: operation createPanner()] - expected: FAIL - [BaseAudioContext interface: operation createPeriodicWave([object Object\], [object Object\], PeriodicWaveConstraints)] expected: FAIL @@ -98,9 +92,6 @@ [AudioContext interface: context must inherit property "createMediaStreamDestination()" with the proper type] expected: FAIL - [BaseAudioContext interface: context must inherit property "listener" with the proper type] - expected: FAIL - [BaseAudioContext interface: context must inherit property "audioWorklet" with the proper type] expected: FAIL @@ -143,9 +134,6 @@ [BaseAudioContext interface: calling createIIRFilter([object Object\], [object Object\]) on context with too few arguments must throw TypeError] expected: FAIL - [BaseAudioContext interface: context must inherit property "createPanner()" with the proper type] - expected: FAIL - [BaseAudioContext interface: context must inherit property "createPeriodicWave([object Object\], [object Object\], PeriodicWaveConstraints)" with the proper type] expected: FAIL @@ -179,9 +167,6 @@ [OfflineAudioContext interface: calling suspend(double) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError] expected: FAIL - [BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "listener" with the proper type] - expected: FAIL - [BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "audioWorklet" with the proper type] expected: FAIL @@ -224,9 +209,6 @@ [BaseAudioContext interface: calling createIIRFilter([object Object\], [object Object\]) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError] expected: FAIL - [BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPanner()" with the proper type] - expected: FAIL - [BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPeriodicWave([object Object\], [object Object\], PeriodicWaveConstraints)" with the proper type] expected: FAIL @@ -416,90 +398,12 @@ [AudioNode interface: new AnalyserNode(context) must inherit property "channelInterpretation" with the proper type] expected: FAIL - [AudioListener interface: existence and properties of interface object] - expected: FAIL - - [AudioListener interface object length] - expected: FAIL - - [AudioListener interface object name] - expected: FAIL - - [AudioListener interface: existence and properties of interface prototype object] - expected: FAIL - - [AudioListener interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [AudioListener interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [AudioListener interface: attribute positionX] - expected: FAIL - - [AudioListener interface: attribute positionY] - expected: FAIL - - [AudioListener interface: attribute positionZ] - expected: FAIL - - [AudioListener interface: attribute forwardX] - expected: FAIL - - [AudioListener interface: attribute forwardY] - expected: FAIL - - [AudioListener interface: attribute forwardZ] - expected: FAIL - - [AudioListener interface: attribute upX] - expected: FAIL - - [AudioListener interface: attribute upY] - expected: FAIL - - [AudioListener interface: attribute upZ] - expected: FAIL - [AudioListener interface: operation setPosition(float, float, float)] expected: FAIL [AudioListener interface: operation setOrientation(float, float, float, float, float, float)] expected: FAIL - [AudioListener must be primary interface of context.listener] - expected: FAIL - - [Stringification of context.listener] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "positionX" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "positionY" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "positionZ" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "forwardX" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "forwardY" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "forwardZ" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "upX" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "upY" with the proper type] - expected: FAIL - - [AudioListener interface: context.listener must inherit property "upZ" with the proper type] - expected: FAIL - [AudioListener interface: context.listener must inherit property "setPosition(float, float, float)" with the proper type] expected: FAIL @@ -1673,201 +1577,6 @@ [OscillatorNode interface: calling setPeriodicWave(PeriodicWave) on new OscillatorNode(context) with too few arguments must throw TypeError] expected: FAIL - [PannerNode interface: existence and properties of interface object] - expected: FAIL - - [PannerNode interface object length] - expected: FAIL - - [PannerNode interface object name] - expected: FAIL - - [PannerNode interface: existence and properties of interface prototype object] - expected: FAIL - - [PannerNode interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [PannerNode interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [PannerNode interface: attribute panningModel] - expected: FAIL - - [PannerNode interface: attribute positionX] - expected: FAIL - - [PannerNode interface: attribute positionY] - expected: FAIL - - [PannerNode interface: attribute positionZ] - expected: FAIL - - [PannerNode interface: attribute orientationX] - expected: FAIL - - [PannerNode interface: attribute orientationY] - expected: FAIL - - [PannerNode interface: attribute orientationZ] - expected: FAIL - - [PannerNode interface: attribute distanceModel] - expected: FAIL - - [PannerNode interface: attribute refDistance] - expected: FAIL - - [PannerNode interface: attribute maxDistance] - expected: FAIL - - [PannerNode interface: attribute rolloffFactor] - expected: FAIL - - [PannerNode interface: attribute coneInnerAngle] - expected: FAIL - - [PannerNode interface: attribute coneOuterAngle] - expected: FAIL - - [PannerNode interface: attribute coneOuterGain] - expected: FAIL - - [PannerNode interface: operation setPosition(float, float, float)] - expected: FAIL - - [PannerNode interface: operation setOrientation(float, float, float)] - expected: FAIL - - [PannerNode must be primary interface of new PannerNode(context)] - expected: FAIL - - [Stringification of new PannerNode(context)] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "panningModel" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "positionX" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "positionY" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "positionZ" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "orientationX" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "orientationY" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "orientationZ" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "distanceModel" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "refDistance" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "maxDistance" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "rolloffFactor" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "coneInnerAngle" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "coneOuterAngle" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "coneOuterGain" with the proper type] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "setPosition(float, float, float)" with the proper type] - expected: FAIL - - [PannerNode interface: calling setPosition(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [PannerNode interface: new PannerNode(context) must inherit property "setOrientation(float, float, float)" with the proper type] - expected: FAIL - - [PannerNode interface: calling setOrientation(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling connect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect()" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(AudioNode) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(AudioNode, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(AudioParam) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type] - expected: FAIL - - [AudioNode interface: calling disconnect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "context" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "numberOfInputs" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "numberOfOutputs" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "channelCount" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "channelCountMode" with the proper type] - expected: FAIL - - [AudioNode interface: new PannerNode(context) must inherit property "channelInterpretation" with the proper type] - expected: FAIL - [PeriodicWave interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-multi-channels.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-multi-channels.html.ini index d60992b5d9f..69be473f09a 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-multi-channels.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-multi-channels.html.ini @@ -1,2 +1,5 @@ [audiobuffersource-multi-channels.html] - expected: CRASH + expected: TIMEOUT + [X Rendered audio for channel 0 does not equal [0,0.19242584705352783,0.3714718818664551,0.5250332355499268,0.6435103416442871,0.7207010388374329,0.7542802691459656,0.7458723187446594,0.7007185816764832,0.6269197463989258,0.5344454050064087,0.4339446425437927,0.33560463786125183,0.24808235466480255,0.17771567404270172,0.12810270488262177...\] with an element-wise tolerance of {"absoluteThreshold":0.000030517578125,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t6.2648326158523560e-2\t1.9242584705352783e-1\t1.2977752089500427e-1\t6.7442873648311685e-1\t3.0517578125000000e-5\n\t[2\]\t1.2505052983760834e-1\t3.7147188186645508e-1\t2.4642135202884674e-1\t6.6336474995282613e-1\t3.0517578125000000e-5\n\t[3\]\t1.8696144223213196e-1\t5.2503323554992676e-1\t3.3807179331779480e-1\t6.4390551002679652e-1\t3.0517578125000000e-5\n\t[4\]\t2.4813784658908844e-1\t6.4351034164428711e-1\t3.9537249505519867e-1\t6.1439959775152853e-1\t3.0517578125000000e-5\n\t[5\]\t3.0833941698074341e-1\t7.2070103883743286e-1\t4.1236162185668945e-1\t5.7216737542361873e-1\t3.0517578125000000e-5\n\t...and 44074 more errors.\n\tMax AbsError of 8.6889546364545822e-1 at index of 129.\n\t[129\]\t9.7299009561538696e-1\t1.0409463196992874e-1\t8.6889546364545822e-1\t8.3471687944145678e+0\t3.0517578125000000e-5\n\tMax RelError of 1.2424206265621037e+5 at index of 1363.\n\t[1363\]\t-5.8316510915756226e-1\t4.6938193918322213e-6\t5.8316980297695409e-1\t1.2424206265621037e+5\t3.0517578125000000e-5\n] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html.ini index 669207991d1..60f05981dcb 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html.ini @@ -1,5 +1,4 @@ [ctor-panner.html] - expected: ERROR [X context = new OfflineAudioContext(...) incorrectly threw ReferenceError: "OfflineAudioContext is not defined".] expected: FAIL @@ -9,3 +8,15 @@ [X node0 = new PannerNode(context) incorrectly threw TypeError: "window[name\] is not a constructor".] expected: FAIL + [< [test AudioNodeOptions\] 2 out of 18 assertions were failed.] + expected: FAIL + + [X new PannerNode(c, {"channelCount":0}) did not throw an exception.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 5 tasks were failed.] + expected: FAIL + + [X node6.channelInterpretation is not equal to discrete. Got speakers.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html.ini index 7efbcf583f3..5a441271ab6 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html.ini @@ -1,2 +1,10 @@ [distance-exponential.html] - expected: ERROR + [X Number of impulses is not equal to 100. Got 0.] + expected: FAIL + + [< [test\] 1 out of 2 assertions were failed.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html.ini index b516b89d7eb..aaa56270d45 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html.ini @@ -1,2 +1,10 @@ [distance-inverse.html] - expected: ERROR + [X Number of impulses is not equal to 100. Got 0.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] + expected: FAIL + + [< [test\] 1 out of 2 assertions were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html.ini index a83cbe3becb..f0484230db4 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html.ini @@ -1,2 +1,10 @@ [distance-linear.html] - expected: ERROR + [X Number of impulses is not equal to 100. Got 0.] + expected: FAIL + + [< [test\] 1 out of 2 assertions were failed.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html.ini index 23daa531853..54a00d56336 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html.ini @@ -1,2 +1,10 @@ [panner-automation-equalpower-stereo.html] - expected: ERROR + [X Number of impulses found is not equal to 100. Got 0.] + expected: FAIL + + [< [test\] 1 out of 4 assertions were failed.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html.ini index 6c23696cca2..f5b50f5b8fa 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html.ini @@ -11,3 +11,28 @@ [X new PannerNode(c, {refDistance: -1}) threw "ReferenceError" instead of EcmaScript error RangeError.] expected: FAIL + + [X panner.maxDistance = 0 did not throw an exception.] + expected: FAIL + + [X panner.maxDistance = -1 threw "NotSupportedError" instead of EcmaScript error RangeError.] + expected: FAIL + + [< [max-distance-error\] 4 out of 6 assertions were failed.] + expected: FAIL + + [X new PannerNode(c, {maxDistance: 0}) did not throw an exception.] + expected: FAIL + + [X panner.refDistance = -1 did not throw an exception.] + expected: FAIL + + [X new PannerNode(c, {refDistance: -1}) did not throw an exception.] + expected: FAIL + + [< [ref-distance-error\] 2 out of 6 assertions were failed.] + expected: FAIL + + [X new PannerNode(c, {maxDistance: -1}) did not throw an exception.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html.ini index af6521690b1..0c85b786d24 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html.ini @@ -1,2 +1,10 @@ [panner-equalpower-stereo.html] - expected: ERROR + [X Number of impulses found is not equal to 100. Got 0.] + expected: FAIL + + [< [test\] 1 out of 4 assertions were failed.] + expected: FAIL + + [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html.ini index 2c9651d704f..0a532a498af 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html.ini @@ -1,2 +1,8 @@ [panner-equalpower.html] - expected: ERROR + expected: TIMEOUT + [X Number of impulses found is not equal to 100. Got 0.] + expected: FAIL + + [< [test\] 1 out of 4 assertions were failed.] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html.ini index 9553796f474..f5088fcd792 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html.ini @@ -1,5 +1,4 @@ [pannernode-basic.html] - expected: ERROR [X Initialize context and panner incorrectly threw TypeError: "context.createPanner is not a function".] expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 86cf8a862e2..d4e4e851138 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -65286,7 +65286,7 @@ "testharness" ], "mozilla/interfaces.html": [ - "ad419477302c2f55fd0b0f7b90d4b36ee9700988", + "179f9c6c6928b3a4194c82f85cd1cce81123a5bc", "testharness" ], "mozilla/interfaces.js": [ diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index ad419477302..179f9c6c692 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -16,6 +16,7 @@ test_interfaces([ "AudioBufferSourceNode", "AudioContext", "AudioDestinationNode", + "AudioListener", "AudioNode", "AudioParam", "AudioScheduledSourceNode", @@ -173,6 +174,7 @@ test_interfaces([ "OfflineAudioContext", "OscillatorNode", "PageTransitionEvent", + "PannerNode", "Performance", "PerformanceEntry", "PerformanceMark",