mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #21591 - Manishearth:channelmergernode, r=ferjm
Implement ChannelMergerNode partial https://github.com/servo/servo/issues/21558 Haven't yet tested, wanted to get this up as an example for https://github.com/servo/servo/issues/21558 <!-- 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/21591) <!-- Reviewable:end -->
This commit is contained in:
commit
81f6ac8f92
61 changed files with 1072 additions and 1352 deletions
|
@ -44,7 +44,7 @@ impl AudioBufferSourceNode {
|
|||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &AudioBufferSourceOptions,
|
||||
) -> AudioBufferSourceNode {
|
||||
) -> Fallible<AudioBufferSourceNode> {
|
||||
let mut node_options = AudioNodeOptions::empty();
|
||||
node_options.channelCount = Some(2);
|
||||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
|
@ -55,7 +55,7 @@ impl AudioBufferSourceNode {
|
|||
&node_options,
|
||||
0, /* inputs */
|
||||
1, /* outputs */
|
||||
);
|
||||
)?;
|
||||
let node_id = source_node.node().node_id();
|
||||
let playback_rate = AudioParam::new(
|
||||
&window,
|
||||
|
@ -77,7 +77,7 @@ impl AudioBufferSourceNode {
|
|||
f32::MIN,
|
||||
f32::MAX,
|
||||
);
|
||||
AudioBufferSourceNode {
|
||||
Ok(AudioBufferSourceNode {
|
||||
source_node,
|
||||
buffer: Default::default(),
|
||||
playback_rate: Dom::from_ref(&playback_rate),
|
||||
|
@ -85,7 +85,7 @@ impl AudioBufferSourceNode {
|
|||
loop_enabled: Cell::new(options.loop_),
|
||||
loop_start: Cell::new(*options.loopStart),
|
||||
loop_end: Cell::new(*options.loopEnd),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
|
@ -93,9 +93,9 @@ impl AudioBufferSourceNode {
|
|||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &AudioBufferSourceOptions,
|
||||
) -> DomRoot<AudioBufferSourceNode> {
|
||||
let node = AudioBufferSourceNode::new_inherited(window, context, options);
|
||||
reflect_dom_object(Box::new(node), window, AudioBufferSourceNodeBinding::Wrap)
|
||||
) -> Fallible<DomRoot<AudioBufferSourceNode>> {
|
||||
let node = AudioBufferSourceNode::new_inherited(window, context, options)?;
|
||||
Ok(reflect_dom_object(Box::new(node), window, AudioBufferSourceNodeBinding::Wrap))
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
|
@ -103,7 +103,7 @@ impl AudioBufferSourceNode {
|
|||
context: &BaseAudioContext,
|
||||
options: &AudioBufferSourceOptions,
|
||||
) -> Fallible<DomRoot<AudioBufferSourceNode>> {
|
||||
Ok(AudioBufferSourceNode::new(window, context, options))
|
||||
AudioBufferSourceNode::new(window, context, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,14 @@ impl AudioNode {
|
|||
options: &AudioNodeOptions,
|
||||
number_of_inputs: u32,
|
||||
number_of_outputs: u32,
|
||||
) -> AudioNode {
|
||||
) -> Fallible<AudioNode> {
|
||||
if let Some(c) = options.channelCount {
|
||||
if c == 0 || c > MAX_CHANNEL_COUNT {
|
||||
return Err(Error::NotSupported);
|
||||
}
|
||||
}
|
||||
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)
|
||||
Ok(AudioNode::new_inherited_for_id(node_id, context, options, number_of_inputs, number_of_outputs))
|
||||
}
|
||||
|
||||
pub fn new_inherited_for_id(
|
||||
|
@ -218,6 +223,11 @@ impl AudioNodeMethods for AudioNode {
|
|||
return Err(Error::NotSupported)
|
||||
}
|
||||
}
|
||||
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelMergerNode) => {
|
||||
if value != 1 {
|
||||
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.
|
||||
|
@ -256,6 +266,11 @@ impl AudioNodeMethods for AudioNode {
|
|||
return Err(Error::NotSupported)
|
||||
}
|
||||
}
|
||||
EventTargetTypeId::AudioNode(AudioNodeTypeId::ChannelMergerNode) => {
|
||||
if value != ChannelCountMode::Explicit {
|
||||
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.
|
||||
|
|
|
@ -24,24 +24,25 @@ pub struct AudioScheduledSourceNode {
|
|||
}
|
||||
|
||||
impl AudioScheduledSourceNode {
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new_inherited(
|
||||
node_type: AudioNodeInit,
|
||||
context: &BaseAudioContext,
|
||||
options: &AudioNodeOptions,
|
||||
number_of_inputs: u32,
|
||||
number_of_outputs: u32,
|
||||
) -> AudioScheduledSourceNode {
|
||||
AudioScheduledSourceNode {
|
||||
) -> Fallible<AudioScheduledSourceNode> {
|
||||
Ok(AudioScheduledSourceNode {
|
||||
node: AudioNode::new_inherited(
|
||||
node_type,
|
||||
context,
|
||||
options,
|
||||
number_of_inputs,
|
||||
number_of_outputs,
|
||||
),
|
||||
)?,
|
||||
started: Cell::new(false),
|
||||
stopped: Cell::new(false),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn node(&self) -> &AudioNode {
|
||||
|
|
|
@ -16,6 +16,7 @@ use dom::bindings::codegen::Bindings::BaseAudioContextBinding::AudioContextState
|
|||
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::BaseAudioContextMethods;
|
||||
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeErrorCallback;
|
||||
use dom::bindings::codegen::Bindings::BaseAudioContextBinding::DecodeSuccessCallback;
|
||||
use dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::ChannelMergerOptions;
|
||||
use dom::bindings::codegen::Bindings::GainNodeBinding::GainOptions;
|
||||
use dom::bindings::codegen::Bindings::OscillatorNodeBinding::OscillatorOptions;
|
||||
use dom::bindings::codegen::Bindings::PannerNodeBinding::PannerOptions;
|
||||
|
@ -25,6 +26,7 @@ use dom::bindings::num::Finite;
|
|||
use dom::bindings::refcounted::Trusted;
|
||||
use dom::bindings::reflector::DomObject;
|
||||
use dom::bindings::root::{DomRoot, MutNullableDom};
|
||||
use dom::channelmergernode::ChannelMergerNode;
|
||||
use dom::domexception::{DOMErrorName, DOMException};
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::gainnode::GainNode;
|
||||
|
@ -317,7 +319,7 @@ impl BaseAudioContextMethods for BaseAudioContext {
|
|||
event_handler!(statechange, GetOnstatechange, SetOnstatechange);
|
||||
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createoscillator
|
||||
fn CreateOscillator(&self) -> DomRoot<OscillatorNode> {
|
||||
fn CreateOscillator(&self) -> Fallible<DomRoot<OscillatorNode>> {
|
||||
OscillatorNode::new(
|
||||
&self.global().as_window(),
|
||||
&self,
|
||||
|
@ -326,7 +328,7 @@ impl BaseAudioContextMethods for BaseAudioContext {
|
|||
}
|
||||
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-creategain
|
||||
fn CreateGain(&self) -> DomRoot<GainNode> {
|
||||
fn CreateGain(&self) -> Fallible<DomRoot<GainNode>> {
|
||||
GainNode::new(&self.global().as_window(), &self, &GainOptions::empty())
|
||||
}
|
||||
|
||||
|
@ -335,6 +337,12 @@ impl BaseAudioContextMethods for BaseAudioContext {
|
|||
PannerNode::new(&self.global().as_window(), &self, &PannerOptions::empty())
|
||||
}
|
||||
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createchannelmerger
|
||||
fn CreateChannelMerger(&self, count: u32) -> Fallible<DomRoot<ChannelMergerNode>> {
|
||||
let mut opts = ChannelMergerOptions::empty();
|
||||
opts.numberOfInputs = count;
|
||||
ChannelMergerNode::new(&self.global().as_window(), &self, &opts)
|
||||
}
|
||||
|
||||
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer
|
||||
fn CreateBuffer(
|
||||
|
@ -360,7 +368,7 @@ impl BaseAudioContextMethods for BaseAudioContext {
|
|||
}
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffersource
|
||||
fn CreateBufferSource(&self) -> DomRoot<AudioBufferSourceNode> {
|
||||
fn CreateBufferSource(&self) -> Fallible<DomRoot<AudioBufferSourceNode>> {
|
||||
AudioBufferSourceNode::new(
|
||||
&self.global().as_window(),
|
||||
&self,
|
||||
|
|
83
components/script/dom/channelmergernode.rs
Normal file
83
components/script/dom/channelmergernode.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* 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, MAX_CHANNEL_COUNT};
|
||||
use dom::baseaudiocontext::BaseAudioContext;
|
||||
use dom::bindings::codegen::Bindings::AudioNodeBinding::{ChannelCountMode, ChannelInterpretation};
|
||||
use dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions;
|
||||
use dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::{self, ChannelMergerOptions};
|
||||
use dom::bindings::error::{Error, Fallible};
|
||||
use dom::bindings::reflector::reflect_dom_object;
|
||||
use dom::bindings::root::DomRoot;
|
||||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
use servo_media::audio::channel_node::ChannelNodeOptions;
|
||||
use servo_media::audio::node::AudioNodeInit;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct ChannelMergerNode {
|
||||
node: AudioNode,
|
||||
}
|
||||
|
||||
impl ChannelMergerNode {
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new_inherited(
|
||||
_: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &ChannelMergerOptions,
|
||||
) -> Fallible<ChannelMergerNode> {
|
||||
let mut node_options = AudioNodeOptions::empty();
|
||||
let count = options.parent.channelCount.unwrap_or(1);
|
||||
let mode = options.parent.channelCountMode.unwrap_or(ChannelCountMode::Explicit);
|
||||
let interpretation = options.parent.channelInterpretation.unwrap_or(ChannelInterpretation::Speakers);
|
||||
|
||||
if count != 1 || mode != ChannelCountMode::Explicit {
|
||||
return Err(Error::InvalidState)
|
||||
}
|
||||
|
||||
if options.numberOfInputs < 1 || options.numberOfInputs > MAX_CHANNEL_COUNT {
|
||||
return Err(Error::IndexSize)
|
||||
}
|
||||
|
||||
node_options.channelCount = Some(count);
|
||||
node_options.channelCountMode = Some(mode);
|
||||
node_options.channelInterpretation = Some(interpretation);
|
||||
let node = AudioNode::new_inherited(
|
||||
AudioNodeInit::ChannelMergerNode(options.into()),
|
||||
context,
|
||||
&node_options,
|
||||
options.numberOfInputs, // inputs
|
||||
1, // outputs
|
||||
)?;
|
||||
Ok(ChannelMergerNode {
|
||||
node,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &ChannelMergerOptions,
|
||||
) -> Fallible<DomRoot<ChannelMergerNode>> {
|
||||
let node = ChannelMergerNode::new_inherited(window, context, options)?;
|
||||
Ok(reflect_dom_object(Box::new(node), window, ChannelMergerNodeBinding::Wrap))
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &ChannelMergerOptions,
|
||||
) -> Fallible<DomRoot<ChannelMergerNode>> {
|
||||
ChannelMergerNode::new(window, context, options)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ChannelMergerOptions> for ChannelNodeOptions {
|
||||
fn from(options: &'a ChannelMergerOptions) -> Self {
|
||||
Self {
|
||||
channels: options.numberOfInputs as u8,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,19 +30,22 @@ impl GainNode {
|
|||
pub fn new_inherited(
|
||||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
gain_options: &GainOptions,
|
||||
) -> GainNode {
|
||||
options: &GainOptions,
|
||||
) -> Fallible<GainNode> {
|
||||
let mut node_options = AudioNodeOptions::empty();
|
||||
node_options.channelCount = Some(2);
|
||||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
node_options.channelInterpretation = Some(ChannelInterpretation::Speakers);
|
||||
let count = options.parent.channelCount.unwrap_or(2);
|
||||
let mode = options.parent.channelCountMode.unwrap_or(ChannelCountMode::Max);
|
||||
let interpretation = options.parent.channelInterpretation.unwrap_or(ChannelInterpretation::Speakers);
|
||||
node_options.channelCount = Some(count);
|
||||
node_options.channelCountMode = Some(mode);
|
||||
node_options.channelInterpretation = Some(interpretation);
|
||||
let node = AudioNode::new_inherited(
|
||||
AudioNodeInit::GainNode(gain_options.into()),
|
||||
AudioNodeInit::GainNode(options.into()),
|
||||
context,
|
||||
&node_options,
|
||||
1, // inputs
|
||||
1, // outputs
|
||||
);
|
||||
)?;
|
||||
let gain = AudioParam::new(
|
||||
window,
|
||||
context,
|
||||
|
@ -53,10 +56,10 @@ impl GainNode {
|
|||
f32::MIN, // min value
|
||||
f32::MAX, // max value
|
||||
);
|
||||
GainNode {
|
||||
Ok(GainNode {
|
||||
node,
|
||||
gain: Dom::from_ref(&gain),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
|
@ -64,9 +67,9 @@ impl GainNode {
|
|||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &GainOptions,
|
||||
) -> DomRoot<GainNode> {
|
||||
let node = GainNode::new_inherited(window, context, options);
|
||||
reflect_dom_object(Box::new(node), window, GainNodeBinding::Wrap)
|
||||
) -> Fallible<DomRoot<GainNode>> {
|
||||
let node = GainNode::new_inherited(window, context, options)?;
|
||||
Ok(reflect_dom_object(Box::new(node), window, GainNodeBinding::Wrap))
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
|
@ -74,7 +77,7 @@ impl GainNode {
|
|||
context: &BaseAudioContext,
|
||||
options: &GainOptions,
|
||||
) -> Fallible<DomRoot<GainNode>> {
|
||||
Ok(GainNode::new(window, context, options))
|
||||
GainNode::new(window, context, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,7 @@ pub mod bluetoothuuid;
|
|||
pub mod canvasgradient;
|
||||
pub mod canvaspattern;
|
||||
pub mod canvasrenderingcontext2d;
|
||||
pub mod channelmergernode;
|
||||
pub mod characterdata;
|
||||
pub mod client;
|
||||
pub mod closeevent;
|
||||
|
|
|
@ -35,7 +35,7 @@ impl OscillatorNode {
|
|||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
oscillator_options: &OscillatorOptions,
|
||||
) -> OscillatorNode {
|
||||
) -> Fallible<OscillatorNode> {
|
||||
let mut node_options = AudioNodeOptions::empty();
|
||||
node_options.channelCount = Some(2);
|
||||
node_options.channelCountMode = Some(ChannelCountMode::Max);
|
||||
|
@ -46,7 +46,7 @@ impl OscillatorNode {
|
|||
&node_options,
|
||||
0, /* inputs */
|
||||
1, /* outputs */
|
||||
);
|
||||
)?;
|
||||
let node_id = source_node.node().node_id();
|
||||
let frequency = AudioParam::new(
|
||||
window,
|
||||
|
@ -69,12 +69,12 @@ impl OscillatorNode {
|
|||
440. / 2.,
|
||||
);
|
||||
|
||||
OscillatorNode {
|
||||
Ok(OscillatorNode {
|
||||
source_node,
|
||||
oscillator_type: oscillator_options.type_,
|
||||
frequency: Dom::from_ref(&frequency),
|
||||
detune: Dom::from_ref(&detune),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
|
@ -82,9 +82,9 @@ impl OscillatorNode {
|
|||
window: &Window,
|
||||
context: &BaseAudioContext,
|
||||
options: &OscillatorOptions,
|
||||
) -> DomRoot<OscillatorNode> {
|
||||
let node = OscillatorNode::new_inherited(window, context, options);
|
||||
reflect_dom_object(Box::new(node), window, OscillatorNodeBinding::Wrap)
|
||||
) -> Fallible<DomRoot<OscillatorNode>> {
|
||||
let node = OscillatorNode::new_inherited(window, context, options)?;
|
||||
Ok(reflect_dom_object(Box::new(node), window, OscillatorNodeBinding::Wrap))
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
|
@ -92,7 +92,7 @@ impl OscillatorNode {
|
|||
context: &BaseAudioContext,
|
||||
options: &OscillatorOptions,
|
||||
) -> Fallible<DomRoot<OscillatorNode>> {
|
||||
Ok(OscillatorNode::new(window, context, options))
|
||||
OscillatorNode::new(window, context, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ impl PannerNode {
|
|||
&node_options,
|
||||
1, // inputs
|
||||
1, // outputs
|
||||
);
|
||||
)?;
|
||||
let id = node.node_id();
|
||||
let position_x = AudioParam::new(
|
||||
window,
|
||||
|
|
|
@ -30,13 +30,13 @@ interface BaseAudioContext : EventTarget {
|
|||
Promise<AudioBuffer> decodeAudioData(ArrayBuffer audioData,
|
||||
optional DecodeSuccessCallback successCallback,
|
||||
optional DecodeErrorCallback errorCallback);
|
||||
AudioBufferSourceNode createBufferSource();
|
||||
[Throws] AudioBufferSourceNode createBufferSource();
|
||||
// ConstantSourceNode createConstantSource();
|
||||
// ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
|
||||
// optional unsigned long numberOfInputChannels = 2,
|
||||
// optional unsigned long numberOfOutputChannels = 2);
|
||||
// AnalyserNode createAnalyser();
|
||||
GainNode createGain();
|
||||
[Throws] GainNode createGain();
|
||||
// DelayNode createDelay(optional double maxDelayTime = 1);
|
||||
// BiquadFilterNode createBiquadFilter();
|
||||
// IIRFilterNode createIIRFilter(sequence<double> feedforward,
|
||||
|
@ -46,9 +46,9 @@ interface BaseAudioContext : EventTarget {
|
|||
// StereoPannerNode createStereoPanner();
|
||||
// ConvolverNode createConvolver();
|
||||
// ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
|
||||
// ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
|
||||
[Throws] ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
|
||||
// DynamicsCompressorNode createDynamicsCompressor();
|
||||
OscillatorNode createOscillator();
|
||||
[Throws] OscillatorNode createOscillator();
|
||||
// PeriodicWave createPeriodicWave(sequence<float> real,
|
||||
// sequence<float> imag,
|
||||
// optional PeriodicWaveConstraints constraints);
|
||||
|
|
16
components/script/dom/webidls/ChannelMergerNode.webidl
Normal file
16
components/script/dom/webidls/ChannelMergerNode.webidl
Normal file
|
@ -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 http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* The origin of this IDL file is
|
||||
* https://webaudio.github.io/web-audio-api/#channelmergernode
|
||||
*/
|
||||
|
||||
dictionary ChannelMergerOptions : AudioNodeOptions {
|
||||
unsigned long numberOfInputs = 6;
|
||||
};
|
||||
|
||||
[Exposed=Window,
|
||||
Constructor (BaseAudioContext context, optional ChannelMergerOptions options)]
|
||||
interface ChannelMergerNode : AudioNode {
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue