Skip to content

Commit

Permalink
StereoPannerNode DOM (need to implement backend in servo/media)
Browse files Browse the repository at this point in the history
  • Loading branch information
PurpleHairEngineer authored and Manishearth committed Apr 30, 2019
1 parent 549d320 commit e5b7cc7
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 1 deletion.
10 changes: 10 additions & 0 deletions components/script/dom/audionode.rs
Expand Up @@ -236,6 +236,11 @@ impl AudioNodeMethods for AudioNode {
return Err(Error::NotSupported);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::StereoPannerNode) => {
if value > 2 {
return Err(Error::NotSupported);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelMergerNode) => {
return Err(Error::InvalidState);
},
Expand Down Expand Up @@ -280,6 +285,11 @@ impl AudioNodeMethods for AudioNode {
return Err(Error::NotSupported);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::StereoPannerNode) => {
if value == ChannelCountMode::Max {
return Err(Error::NotSupported);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelMergerNode) => {
return Err(Error::InvalidState);
},
Expand Down
12 changes: 12 additions & 0 deletions components/script/dom/baseaudiocontext.rs
Expand Up @@ -22,6 +22,7 @@ use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::BaseAudioC
use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeErrorCallback;
use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeSuccessCallback;
use crate::dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterOptions;
use crate::dom::bindings::codegen::Bindings::StereoPannerNodeBinding::StereoPannerOptions;
use crate::dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::ChannelMergerOptions;
use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::ChannelSplitterOptions;
use crate::dom::bindings::codegen::Bindings::GainNodeBinding::GainOptions;
Expand All @@ -36,6 +37,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::biquadfilternode::BiquadFilterNode;
use crate::dom::channelmergernode::ChannelMergerNode;
use crate::dom::channelsplitternode::ChannelSplitterNode;
use crate::dom::stereopannernode::StereoPannerNode;
use crate::dom::domexception::{DOMErrorName, DOMException};
use crate::dom::eventtarget::EventTarget;
use crate::dom::gainnode::GainNode;
Expand Down Expand Up @@ -361,6 +363,16 @@ impl BaseAudioContextMethods for BaseAudioContext {
)
}


/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createstereopanner
fn CreateStereoPanner(&self) -> Fallible<DomRoot<StereoPannerNode>> {
StereoPannerNode::new(
&self.global().as_window(),
&self,
&StereoPannerOptions::empty(),
)
}

/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createchannelmerger
fn CreateChannelMerger(&self, count: u32) -> Fallible<DomRoot<ChannelMergerNode>> {
let mut opts = ChannelMergerOptions::empty();
Expand Down
1 change: 1 addition & 0 deletions components/script/dom/mod.rs
Expand Up @@ -457,6 +457,7 @@ pub mod serviceworkerglobalscope;
pub mod serviceworkerregistration;
pub mod servoparser;
pub mod shadowroot;
pub mod stereopannernode;
pub mod storage;
pub mod storageevent;
pub mod stylepropertymapreadonly;
Expand Down
109 changes: 109 additions & 0 deletions components/script/dom/stereopannernode.rs
@@ -0,0 +1,109 @@
/* 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 https://mozilla.org/MPL/2.0/. */

use crate::dom::audioparam::AudioParam;
use crate::dom::audioscheduledsourcenode::AudioScheduledSourceNode;
use crate::dom::baseaudiocontext::BaseAudioContext;
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
ChannelCountMode, ChannelInterpretation,
};
use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
use crate::dom::bindings::codegen::Bindings::StereoPannerNodeBinding::StereoPannerNodeMethods;
use crate::dom::bindings::codegen::Bindings::StereoPannerNodeBinding::{
self, StereoPannerOptions,
};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_media::audio::stereo_panner_node::StereoPannerOptions as ServoMediaStereoPannerOptions;
use servo_media::audio::node::AudioNodeInit;
use servo_media::audio::param::ParamType;
use std::f32;

#[dom_struct]
pub struct StereoPannerNode {
source_node: AudioScheduledSourceNode,
offset: Dom<AudioParam>,
}

impl StereoPannerNode {
#[allow(unrooted_must_root)]
pub fn new_inherited(
window: &Window,
context: &BaseAudioContext,
options: &StereoPannerOptions,
) -> Fallible<StereoPannerNode> {
let node_options =
options
.parent
.unwrap_or(2, ChannelCountMode::ClampedMax, ChannelInterpretation::Speakers);
if node_options.mode == ChannelCountMode::Max {
return Err(Error::NotSupported);
}
if node_options.count > 2 || node_options.count == 0 {
return Err(Error::NotSupported);
}
let source_node = AudioScheduledSourceNode::new_inherited(
AudioNodeInit::StereoPannerNode(options.into()),
context,
node_options,
0, /* inputs */
1, /* outputs */
)?;
let node_id = source_node.node().node_id();
let offset = AudioParam::new(
window,
context,
node_id,
ParamType::Offset,
AutomationRate::A_rate,
1.,
f32::MIN,
f32::MAX,
);

Ok(StereoPannerNode {
source_node,
offset: Dom::from_ref(&offset),
})
}

#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &StereoPannerOptions,
) -> Fallible<DomRoot<StereoPannerNode>> {
let node = StereoPannerNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(
Box::new(node),
window,
StereoPannerNodeBinding::Wrap,
))
}

pub fn Constructor(
window: &Window,
context: &BaseAudioContext,
options: &StereoPannerOptions,
) -> Fallible<DomRoot<StereoPannerNode>> {
StereoPannerNode::new(window, context, options)
}
}

impl StereoPannerNodeMethods for StereoPannerNode {
fn Offset(&self) -> DomRoot<AudioParam> {
DomRoot::from_ref(&self.offset)
}
}

impl<'a> From<&'a StereoPannerOptions> for ServoMediaStereoPannerOptions {
fn from(options: &'a StereoPannerOptions) -> Self {
Self {
offset: *options.offset,
}
}
}
2 changes: 1 addition & 1 deletion components/script/dom/webidls/BaseAudioContext.webidl
Expand Up @@ -43,7 +43,7 @@ interface BaseAudioContext : EventTarget {
// sequence<double> feedback);
// WaveShaperNode createWaveShaper();
[Throws] PannerNode createPanner();
// StereoPannerNode createStereoPanner();
[Throws] StereoPannerNode createStereoPanner();
// ConvolverNode createConvolver();
[Throws] ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
[Throws] ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
Expand Down
17 changes: 17 additions & 0 deletions components/script/dom/webidls/StereoPannerNode.webidl
@@ -0,0 +1,17 @@
/* 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 https://mozilla.org/MPL/2.0/. */
/*
* The origin of this IDL file is
* https://webaudio.github.io/web-audio-api/#StereoPannerNode
*/

dictionary StereoPannerOptions: AudioNodeOptions {
float pan = 0;
};

[Exposed=Window,
Constructor (BaseAudioContext context, optional StereoPannerOptions options)]
interface StereoPannerNode : AudioScheduledSourceNode {
readonly attribute AudioParam offset;
};

0 comments on commit e5b7cc7

Please sign in to comment.