Skip to content

Commit

Permalink
Implement DOM APIs for ChannelSplitterNode
Browse files Browse the repository at this point in the history
  • Loading branch information
collares committed Jan 10, 2019
1 parent 4ac5b8a commit ff0cf9e
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 133 deletions.
18 changes: 16 additions & 2 deletions components/script/dom/audionode.rs
Expand Up @@ -241,6 +241,9 @@ impl AudioNodeMethods for AudioNode {
return Err(Error::InvalidState);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelSplitterNode) => {
return Err(Error::InvalidState);
},
// XXX We do not support any of the other AudioNodes with
// constraints yet. Add more cases here as we add support
// for new AudioNodes.
Expand Down Expand Up @@ -284,6 +287,9 @@ impl AudioNodeMethods for AudioNode {
return Err(Error::InvalidState);
}
},
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelSplitterNode) => {
return Err(Error::InvalidState);
},
// XXX We do not support any of the other AudioNodes with
// constraints yet. Add more cases here as we add support
// for new AudioNodes.
Expand All @@ -301,14 +307,22 @@ impl AudioNodeMethods for AudioNode {
}

// https://webaudio.github.io/web-audio-api/#dom-audionode-channelinterpretation
fn SetChannelInterpretation(&self, value: ChannelInterpretation) {
fn SetChannelInterpretation(&self, value: ChannelInterpretation) -> ErrorResult {
// Channel interpretation mode has no effect for nodes with no inputs.
if self.number_of_inputs == 0 {
return;
return Ok(());
}

match self.upcast::<EventTarget>().type_id() {
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelSplitterNode) => {
return Err(Error::InvalidState);
},
_ => (),
};

self.channel_interpretation.set(value);
self.message(AudioNodeMessage::SetChannelInterpretation(value.into()));
Ok(())
}
}

Expand Down
9 changes: 9 additions & 0 deletions components/script/dom/baseaudiocontext.rs
Expand Up @@ -22,6 +22,7 @@ use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeErro
use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeSuccessCallback;
use crate::dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterOptions;
use crate::dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::ChannelMergerOptions;
use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::ChannelSplitterOptions;
use crate::dom::bindings::codegen::Bindings::GainNodeBinding::GainOptions;
use crate::dom::bindings::codegen::Bindings::OscillatorNodeBinding::OscillatorOptions;
use crate::dom::bindings::codegen::Bindings::PannerNodeBinding::PannerOptions;
Expand All @@ -33,6 +34,7 @@ use crate::dom::bindings::reflector::DomObject;
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::domexception::{DOMErrorName, DOMException};
use crate::dom::eventtarget::EventTarget;
use crate::dom::gainnode::GainNode;
Expand Down Expand Up @@ -360,6 +362,13 @@ impl BaseAudioContextMethods for BaseAudioContext {
ChannelMergerNode::new(&self.global().as_window(), &self, &opts)
}

/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createchannelsplitter
fn CreateChannelSplitter(&self, count: u32) -> Fallible<DomRoot<ChannelSplitterNode>> {
let mut opts = ChannelSplitterOptions::empty();
opts.numberOfOutputs = count;
ChannelSplitterNode::new(&self.global().as_window(), &self, &opts)
}

/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer
fn CreateBuffer(
&self,
Expand Down
80 changes: 80 additions & 0 deletions components/script/dom/channelsplitternode.rs
@@ -0,0 +1,80 @@
/* 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::audionode::{AudioNode, MAX_CHANNEL_COUNT};
use crate::dom::baseaudiocontext::BaseAudioContext;
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
ChannelCountMode, ChannelInterpretation,
};
use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::{
self, ChannelSplitterOptions,
};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::DomRoot;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_media::audio::node::AudioNodeInit;

#[dom_struct]
pub struct ChannelSplitterNode {
node: AudioNode,
}

impl ChannelSplitterNode {
#[allow(unrooted_must_root)]
pub fn new_inherited(
_: &Window,
context: &BaseAudioContext,
options: &ChannelSplitterOptions,
) -> Fallible<ChannelSplitterNode> {
if options.numberOfOutputs < 1 || options.numberOfOutputs > MAX_CHANNEL_COUNT {
return Err(Error::IndexSize);
}

let node_options = options.parent.unwrap_or(
options.numberOfOutputs,
ChannelCountMode::Explicit,
ChannelInterpretation::Discrete,
);

if node_options.count != options.numberOfOutputs ||
node_options.mode != ChannelCountMode::Explicit ||
node_options.interpretation != ChannelInterpretation::Discrete
{
return Err(Error::InvalidState);
}

let node = AudioNode::new_inherited(
AudioNodeInit::ChannelSplitterNode,
context,
node_options,
1, // inputs
options.numberOfOutputs, // outputs
)?;
Ok(ChannelSplitterNode { node })
}

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

pub fn Constructor(
window: &Window,
context: &BaseAudioContext,
options: &ChannelSplitterOptions,
) -> Fallible<DomRoot<ChannelSplitterNode>> {
ChannelSplitterNode::new(window, context, options)
}
}
1 change: 1 addition & 0 deletions components/script/dom/mod.rs
Expand Up @@ -244,6 +244,7 @@ pub mod canvasgradient;
pub mod canvaspattern;
pub mod canvasrenderingcontext2d;
pub mod channelmergernode;
pub mod channelsplitternode;
pub mod characterdata;
pub mod client;
pub mod closeevent;
Expand Down
1 change: 1 addition & 0 deletions components/script/dom/webidls/AudioNode.webidl
Expand Up @@ -57,5 +57,6 @@ interface AudioNode : EventTarget {
attribute unsigned long channelCount;
[SetterThrows]
attribute ChannelCountMode channelCountMode;
[SetterThrows]
attribute ChannelInterpretation channelInterpretation;
};
2 changes: 1 addition & 1 deletion components/script/dom/webidls/BaseAudioContext.webidl
Expand Up @@ -45,7 +45,7 @@ interface BaseAudioContext : EventTarget {
[Throws] PannerNode createPanner();
// StereoPannerNode createStereoPanner();
// ConvolverNode createConvolver();
// ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
[Throws] ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
[Throws] ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
// DynamicsCompressorNode createDynamicsCompressor();
[Throws] OscillatorNode createOscillator();
Expand Down
16 changes: 16 additions & 0 deletions components/script/dom/webidls/ChannelSplitterNode.webidl
@@ -0,0 +1,16 @@
/* 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/#channelsplitternode
*/

dictionary ChannelSplitterOptions : AudioNodeOptions {
unsigned long numberOfOutputs = 6;
};

[Exposed=Window,
Constructor (BaseAudioContext context, optional ChannelSplitterOptions options)]
interface ChannelSplitterNode : AudioNode {
};

0 comments on commit ff0cf9e

Please sign in to comment.