mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Add AudioListener DOM interface
This commit is contained in:
parent
4b48cfa3ec
commit
9228ca3a02
5 changed files with 230 additions and 1 deletions
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
use dom::audiobuffer::AudioBuffer;
|
use dom::audiobuffer::AudioBuffer;
|
||||||
use dom::audiobuffersourcenode::AudioBufferSourceNode;
|
use dom::audiobuffersourcenode::AudioBufferSourceNode;
|
||||||
use dom::audiodestinationnode::AudioDestinationNode;
|
use dom::audiodestinationnode::AudioDestinationNode;
|
||||||
|
use dom::audiolistener::AudioListener;
|
||||||
use dom::audionode::MAX_CHANNEL_COUNT;
|
use dom::audionode::MAX_CHANNEL_COUNT;
|
||||||
use dom::bindings::callback::ExceptionHandling;
|
use dom::bindings::callback::ExceptionHandling;
|
||||||
use dom::bindings::cell::DomRefCell;
|
use dom::bindings::cell::DomRefCell;
|
||||||
|
@ -66,6 +67,7 @@ pub struct BaseAudioContext {
|
||||||
audio_context_impl: Rc<AudioContext<Backend>>,
|
audio_context_impl: Rc<AudioContext<Backend>>,
|
||||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination
|
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination
|
||||||
destination: MutNullableDom<AudioDestinationNode>,
|
destination: MutNullableDom<AudioDestinationNode>,
|
||||||
|
listener: MutNullableDom<AudioListener>,
|
||||||
/// Resume promises which are soon to be fulfilled by a queued task.
|
/// Resume promises which are soon to be fulfilled by a queued task.
|
||||||
#[ignore_malloc_size_of = "promises are hard"]
|
#[ignore_malloc_size_of = "promises are hard"]
|
||||||
in_flight_resume_promises_queue: DomRefCell<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>,
|
in_flight_resume_promises_queue: DomRefCell<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>,
|
||||||
|
@ -101,6 +103,7 @@ impl BaseAudioContext {
|
||||||
.create_audio_context(options.into()),
|
.create_audio_context(options.into()),
|
||||||
),
|
),
|
||||||
destination: Default::default(),
|
destination: Default::default(),
|
||||||
|
listener: Default::default(),
|
||||||
in_flight_resume_promises_queue: Default::default(),
|
in_flight_resume_promises_queue: Default::default(),
|
||||||
pending_resume_promises: Default::default(),
|
pending_resume_promises: Default::default(),
|
||||||
decode_resolvers: Default::default(),
|
decode_resolvers: Default::default(),
|
||||||
|
@ -125,6 +128,10 @@ impl BaseAudioContext {
|
||||||
self.audio_context_impl.dest_node()
|
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
|
// https://webaudio.github.io/web-audio-api/#allowed-to-start
|
||||||
pub fn is_allowed_to_start(&self) -> bool {
|
pub fn is_allowed_to_start(&self) -> bool {
|
||||||
self.state.get() == AudioContextState::Suspended
|
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
|
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-onstatechange
|
||||||
event_handler!(statechange, GetOnstatechange, SetOnstatechange);
|
event_handler!(statechange, GetOnstatechange, SetOnstatechange);
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,7 @@ pub mod audiobuffer;
|
||||||
pub mod audiobuffersourcenode;
|
pub mod audiobuffersourcenode;
|
||||||
pub mod audiocontext;
|
pub mod audiocontext;
|
||||||
pub mod audiodestinationnode;
|
pub mod audiodestinationnode;
|
||||||
|
pub mod audiolistener;
|
||||||
pub mod audionode;
|
pub mod audionode;
|
||||||
pub mod audioparam;
|
pub mod audioparam;
|
||||||
pub mod audioscheduledsourcenode;
|
pub mod audioscheduledsourcenode;
|
||||||
|
|
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 AudioDestinationNode destination;
|
||||||
readonly attribute float sampleRate;
|
readonly attribute float sampleRate;
|
||||||
readonly attribute double currentTime;
|
readonly attribute double currentTime;
|
||||||
// readonly attribute AudioListener listener;
|
readonly attribute AudioListener listener;
|
||||||
readonly attribute AudioContextState state;
|
readonly attribute AudioContextState state;
|
||||||
Promise<void> resume();
|
Promise<void> resume();
|
||||||
attribute EventHandler onstatechange;
|
attribute EventHandler onstatechange;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue