mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Auto merge of #21502 - Manishearth:listener, r=ferjm
Add AudioListener/AudioPanner DOM interfaces Seems to work. I'll need some changes to the servo-media side to support the panner node getters as well as the older `setPosition()`/etc APIs. I'll get to those later. 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/21502) <!-- Reviewable:end -->
This commit is contained in:
commit
d827370804
28 changed files with 822 additions and 340 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -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#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,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#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)",
|
||||
"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#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)",
|
||||
|
@ -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#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)",
|
||||
"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#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)",
|
||||
|
|
|
@ -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,
|
||||
|
|
190
components/script/dom/audiolistener.rs
Normal file
190
components/script/dom/audiolistener.rs
Normal file
|
@ -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<AudioParam>,
|
||||
position_y: Dom<AudioParam>,
|
||||
position_z: Dom<AudioParam>,
|
||||
forward_x: Dom<AudioParam>,
|
||||
forward_y: Dom<AudioParam>,
|
||||
forward_z: Dom<AudioParam>,
|
||||
up_x: Dom<AudioParam>,
|
||||
up_y: Dom<AudioParam>,
|
||||
up_z: Dom<AudioParam>,
|
||||
}
|
||||
|
||||
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<AudioListener> {
|
||||
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<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_x)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-positiony
|
||||
fn PositionY(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_y)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionz
|
||||
fn PositionZ(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_z)
|
||||
}
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardx
|
||||
fn ForwardX(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.forward_x)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardy
|
||||
fn ForwardY(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.forward_y)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardz
|
||||
fn ForwardZ(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.forward_z)
|
||||
}
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-upx
|
||||
fn UpX(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.up_x)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-upy
|
||||
fn UpY(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.up_y)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiolistener-upz
|
||||
fn UpZ(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.up_z)
|
||||
}
|
||||
}
|
|
@ -36,17 +36,26 @@ pub struct AudioNode {
|
|||
channel_interpretation: Cell<ChannelInterpretation>,
|
||||
}
|
||||
|
||||
|
||||
impl AudioNode {
|
||||
pub fn new_inherited(
|
||||
node_type: AudioNodeInit,
|
||||
node_id: Option<NodeId>,
|
||||
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,
|
||||
|
@ -204,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.
|
||||
|
@ -237,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.
|
||||
|
|
|
@ -34,7 +34,6 @@ impl AudioScheduledSourceNode {
|
|||
AudioScheduledSourceNode {
|
||||
node: AudioNode::new_inherited(
|
||||
node_type,
|
||||
None, /* node_id */
|
||||
context,
|
||||
options,
|
||||
number_of_inputs,
|
||||
|
|
|
@ -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;
|
||||
|
@ -17,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;
|
||||
|
@ -27,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;
|
||||
|
@ -63,9 +66,10 @@ struct DecodeResolver {
|
|||
pub struct BaseAudioContext {
|
||||
eventtarget: EventTarget,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
audio_context_impl: Rc<AudioContext<Backend>>,
|
||||
audio_context_impl: AudioContext<Backend>,
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination
|
||||
destination: MutNullableDom<AudioDestinationNode>,
|
||||
listener: MutNullableDom<AudioListener>,
|
||||
/// 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<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>,
|
||||
|
@ -95,12 +99,11 @@ 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(),
|
||||
pending_resume_promises: Default::default(),
|
||||
decode_resolvers: Default::default(),
|
||||
|
@ -117,14 +120,18 @@ impl BaseAudioContext {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn audio_context_impl(&self) -> Rc<AudioContext<Backend>> {
|
||||
self.audio_context_impl.clone()
|
||||
pub fn audio_context_impl(&self) -> &AudioContext<Backend> {
|
||||
&self.audio_context_impl
|
||||
}
|
||||
|
||||
pub fn destination_node(&self) -> NodeId {
|
||||
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<AudioListener> {
|
||||
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);
|
||||
|
||||
|
@ -314,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) -> Fallible<DomRoot<PannerNode>> {
|
||||
PannerNode::new(&self.global().as_window(), &self, &PannerOptions::empty())
|
||||
}
|
||||
|
||||
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer
|
||||
fn CreateBuffer(
|
||||
&self,
|
||||
|
|
|
@ -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<Backend>);
|
||||
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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
@ -408,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;
|
||||
|
|
354
components/script/dom/pannernode.rs
Normal file
354
components/script/dom/pannernode.rs
Normal file
|
@ -0,0 +1,354 @@
|
|||
/* 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::{AudioParamMethods, AutomationRate};
|
||||
use dom::bindings::codegen::Bindings::PannerNodeBinding::{self, PannerNodeMethods, PannerOptions};
|
||||
use dom::bindings::codegen::Bindings::PannerNodeBinding::{DistanceModelType, PanningModelType};
|
||||
use dom::bindings::error::{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::node::{AudioNodeInit, AudioNodeMessage};
|
||||
use servo_media::audio::panner_node::{DistanceModel, PannerNodeOptions, PanningModel};
|
||||
use servo_media::audio::panner_node::PannerNodeMessage;
|
||||
use servo_media::audio::param::{ParamDir, ParamType};
|
||||
use std::cell::Cell;
|
||||
use std::f32;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct PannerNode {
|
||||
node: AudioNode,
|
||||
position_x: Dom<AudioParam>,
|
||||
position_y: Dom<AudioParam>,
|
||||
position_z: Dom<AudioParam>,
|
||||
orientation_x: Dom<AudioParam>,
|
||||
orientation_y: Dom<AudioParam>,
|
||||
orientation_z: Dom<AudioParam>,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
panning_model: Cell<PanningModel>,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
distance_model: Cell<DistanceModel>,
|
||||
ref_distance: Cell<f64>,
|
||||
max_distance: Cell<f64>,
|
||||
rolloff_factor: Cell<f64>,
|
||||
cone_inner_angle: Cell<f64>,
|
||||
cone_outer_angle: Cell<f64>,
|
||||
cone_outer_gain: Cell<f64>,
|
||||
}
|
||||
|
||||
impl PannerNode {
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new_inherited(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &PannerOptions,
|
||||
) -> Fallible<PannerNode> {
|
||||
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(count);
|
||||
node_options.channelCountMode = Some(mode);
|
||||
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
|
||||
);
|
||||
Ok(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),
|
||||
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),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &PannerOptions,
|
||||
) -> Fallible<DomRoot<PannerNode>> {
|
||||
let node = PannerNode::new_inherited(window, context, options)?;
|
||||
Ok(reflect_dom_object(Box::new(node), window, PannerNodeBinding::Wrap))
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &PannerOptions,
|
||||
) -> Fallible<DomRoot<PannerNode>> {
|
||||
PannerNode::new(window, context, options)
|
||||
}
|
||||
}
|
||||
|
||||
impl PannerNodeMethods for PannerNode {
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-positionx
|
||||
fn PositionX(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_x)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-positiony
|
||||
fn PositionY(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_y)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-positionz
|
||||
fn PositionZ(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.position_z)
|
||||
}
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationx
|
||||
fn OrientationX(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.orientation_x)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationy
|
||||
fn OrientationY(&self) -> DomRoot<AudioParam> {
|
||||
DomRoot::from_ref(&self.orientation_y)
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-orientationz
|
||||
fn OrientationZ(&self) -> DomRoot<AudioParam> {
|
||||
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::<AudioNode>().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::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-refdistance
|
||||
fn RefDistance(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.ref_distance.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-refdistance
|
||||
fn SetRefDistance(&self, val: Finite<f64>) {
|
||||
self.ref_distance.set(*val);
|
||||
let msg = PannerNodeMessage::SetRefDistance(self.ref_distance.get());
|
||||
self.upcast::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance
|
||||
fn MaxDistance(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.max_distance.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance
|
||||
fn SetMaxDistance(&self, val: Finite<f64>) -> Fallible<()> {
|
||||
if *val < 0. {
|
||||
return Err(Error::NotSupported)
|
||||
}
|
||||
self.max_distance.set(*val);
|
||||
let msg = PannerNodeMessage::SetMaxDistance(self.max_distance.get());
|
||||
self.upcast::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
Ok(())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor
|
||||
fn RolloffFactor(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.rolloff_factor.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor
|
||||
fn SetRolloffFactor(&self, val: Finite<f64>) -> 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::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
Ok(())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneinnerangle
|
||||
fn ConeInnerAngle(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.cone_inner_angle.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneinnerangle
|
||||
fn SetConeInnerAngle(&self, val: Finite<f64>) {
|
||||
self.cone_inner_angle.set(*val);
|
||||
let msg = PannerNodeMessage::SetConeInner(self.cone_inner_angle.get());
|
||||
self.upcast::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneouterangle
|
||||
fn ConeOuterAngle(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.cone_outer_angle.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneouterangle
|
||||
fn SetConeOuterAngle(&self, val: Finite<f64>) {
|
||||
self.cone_outer_angle.set(*val);
|
||||
let msg = PannerNodeMessage::SetConeOuter(self.cone_outer_angle.get());
|
||||
self.upcast::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain
|
||||
fn ConeOuterGain(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.cone_outer_gain.get())
|
||||
}
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain
|
||||
fn SetConeOuterGain(&self, val: Finite<f64>) -> 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::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-pannernode-setposition
|
||||
fn SetPosition(&self, x: Finite<f32>, y: Finite<f32>, z: Finite<f32>) {
|
||||
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<f32>, y: Finite<f32>, z: Finite<f32>) {
|
||||
self.orientation_x.SetValue(x);
|
||||
self.orientation_y.SetValue(y);
|
||||
self.orientation_z.SetValue(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<DistanceModelType> for DistanceModel {
|
||||
fn from(model: DistanceModelType) -> Self {
|
||||
match model {
|
||||
DistanceModelType::Linear => DistanceModel::Linear,
|
||||
DistanceModelType::Inverse => DistanceModel::Inverse,
|
||||
DistanceModelType::Exponential => DistanceModel::Exponential,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PanningModelType> for PanningModel {
|
||||
fn from(model: PanningModelType) -> Self {
|
||||
match model {
|
||||
PanningModelType::Equalpower => PanningModel::EqualPower,
|
||||
PanningModelType::HRTF => PanningModel::HRTF,
|
||||
}
|
||||
}
|
||||
}
|
22
components/script/dom/webidls/AudioListener.webidl
Normal file
22
components/script/dom/webidls/AudioListener.webidl
Normal file
|
@ -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);
|
||||
};
|
|
@ -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<void> resume();
|
||||
attribute EventHandler onstatechange;
|
||||
|
@ -42,7 +42,7 @@ interface BaseAudioContext : EventTarget {
|
|||
// IIRFilterNode createIIRFilter(sequence<double> feedforward,
|
||||
// sequence<double> feedback);
|
||||
// WaveShaperNode createWaveShaper();
|
||||
// PannerNode createPanner();
|
||||
[Throws] PannerNode createPanner();
|
||||
// StereoPannerNode createStereoPanner();
|
||||
// ConvolverNode createConvolver();
|
||||
// ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
|
||||
|
|
56
components/script/dom/webidls/PannerNode.webidl
Normal file
56
components/script/dom/webidls/PannerNode.webidl
Normal file
|
@ -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;
|
||||
[SetterThrows] attribute double maxDistance;
|
||||
[SetterThrows] attribute double rolloffFactor;
|
||||
attribute double coneInnerAngle;
|
||||
attribute double coneOuterAngle;
|
||||
[SetterThrows] attribute double coneOuterGain;
|
||||
void setPosition (float x, float y, float z);
|
||||
void setOrientation (float x, float y, float z);
|
||||
};
|
32
tests/html/webaudio/test_panner_listener.html
Normal file
32
tests/html/webaudio/test_panner_listener.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script type="text/javascript">
|
||||
let ctx = new AudioContext();
|
||||
let osc = ctx.createOscillator();
|
||||
let options = {
|
||||
"coneOuterAngle": 0,
|
||||
"positionX": 100, "positionY": 0, "positionZ": 100,
|
||||
"refDistance": 100, "rolloffFactor": 0.01
|
||||
};
|
||||
let panner = new PannerNode(ctx, options);
|
||||
osc.connect(panner);
|
||||
panner.connect(ctx.destination);
|
||||
osc.start();
|
||||
panner.positionX.linearRampToValueAtTime(-100, 0.2);
|
||||
panner.positionZ.linearRampToValueAtTime(100, 0.2);
|
||||
panner.positionX.linearRampToValueAtTime(-100, 0.4);
|
||||
panner.positionZ.linearRampToValueAtTime(-100, 0.4);
|
||||
panner.positionX.linearRampToValueAtTime(100, 0.6);
|
||||
panner.positionZ.linearRampToValueAtTime(-100, 0.6);
|
||||
panner.positionX.linearRampToValueAtTime(100, 0.8);
|
||||
panner.positionZ.linearRampToValueAtTime(100, 0.8);
|
||||
panner.positionX.linearRampToValueAtTime(-100, 1.0);
|
||||
panner.positionZ.linearRampToValueAtTime(100, 1.0);
|
||||
panner.positionX.linearRampToValueAtTime(-100, 1.2);
|
||||
panner.positionZ.linearRampToValueAtTime(-100, 1.2);
|
||||
panner.positionX.linearRampToValueAtTime(100, 1.4);
|
||||
panner.positionZ.linearRampToValueAtTime(-100, 1.4);
|
||||
panner.positionX.linearRampToValueAtTime(100, 1.6);
|
||||
panner.positionZ.linearRampToValueAtTime(100, 1.6);
|
||||
panner.positionZ.linearRampToValueAtTime(10000, 3);
|
||||
ctx.listener.positionZ.setValueAtTime(0, 3);
|
||||
ctx.listener.positionZ.linearRampToValueAtTime(10000, 4);
|
||||
</script>
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -65286,7 +65286,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"mozilla/interfaces.html": [
|
||||
"ad419477302c2f55fd0b0f7b90d4b36ee9700988",
|
||||
"179f9c6c6928b3a4194c82f85cd1cce81123a5bc",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/interfaces.js": [
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue