script/dom/audio/
channelsplitternode.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::rust::HandleObject;
8use script_bindings::reflector::reflect_dom_object_with_proto;
9use servo_media::audio::audio_node::AudioNodeInit;
10use servo_media::audio::graph::NodeId;
11
12use crate::dom::audio::audionode::{AudioNode, AudioNodeOptionsHelper, MAX_CHANNEL_COUNT};
13use crate::dom::audio::baseaudiocontext::BaseAudioContext;
14use crate::dom::audionode::UnwrappedAudioNodeOptions;
15use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
16 ChannelCountMode, ChannelInterpretation,
17};
18use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::{
19 ChannelSplitterNodeMethods, ChannelSplitterOptions,
20};
21use crate::dom::bindings::error::{Error, Fallible};
22use crate::dom::bindings::root::DomRoot;
23use crate::dom::window::Window;
24
25#[dom_struct]
26pub(crate) struct ChannelSplitterNode {
27 node: AudioNode,
28}
29
30impl ChannelSplitterNode {
31 fn new_inherited(
32 node_id: Option<NodeId>,
33 context: &BaseAudioContext,
34 node_options: UnwrappedAudioNodeOptions,
35 number_of_outputs: u32,
36 ) -> Self {
37 ChannelSplitterNode {
38 node: AudioNode::new_inherited(
39 node_id,
40 context,
41 node_options,
42 1, number_of_outputs, ),
45 }
46 }
47}
48
49impl ChannelSplitterNodeMethods<crate::DomTypeHolder> for ChannelSplitterNode {
50 fn Constructor(
52 cx: &mut JSContext,
53 window: &Window,
54 proto: Option<HandleObject>,
55 context: &BaseAudioContext,
56 options: &ChannelSplitterOptions,
57 ) -> Fallible<DomRoot<ChannelSplitterNode>> {
58 if options.numberOfOutputs < 1 || options.numberOfOutputs > MAX_CHANNEL_COUNT {
59 return Err(Error::IndexSize(Some(
60 "numberOfOutputs is out of range".into(),
61 )));
62 }
63
64 let node_options = options.parent.unwrap_or(
65 options.numberOfOutputs,
66 ChannelCountMode::Explicit,
67 ChannelInterpretation::Discrete,
68 );
69
70 if AudioNode::channel_count_check(node_options.count) {
71 return Err(Error::NotSupported(Some(String::from(
72 "Channel count not supported",
73 ))));
74 }
75
76 if node_options.count != options.numberOfOutputs ||
77 node_options.mode != ChannelCountMode::Explicit ||
78 node_options.interpretation != ChannelInterpretation::Discrete
79 {
80 return Err(Error::InvalidState(Some(
81 "Invalid channel options for ChannelSplitterNode".into(),
82 )));
83 }
84
85 let audio_node_init = AudioNodeInit::ChannelSplitterNode;
86 let node_id =
87 AudioNode::generate_audio_node_id(cx, &node_options, audio_node_init, context);
88
89 Ok(reflect_dom_object_with_proto(
90 cx,
91 Box::new(ChannelSplitterNode::new_inherited(
92 node_id,
93 context,
94 node_options,
95 options.numberOfOutputs, )),
97 window,
98 proto,
99 ))
100 }
101}