Add AudioListener DOM interface

This commit is contained in:
Manish Goregaokar 2018-08-23 14:33:29 -07:00
parent 4b48cfa3ec
commit 9228ca3a02
5 changed files with 230 additions and 1 deletions

View 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)
}
}

View file

@ -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<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)>>,
@ -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<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);

View file

@ -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;

View 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);
};

View file

@ -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;