script/dom/audio/
channelmergernode.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::rust::HandleObject;
8use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
9use servo_media::audio::channel_node::ChannelNodeOptions;
10use servo_media::audio::node::AudioNodeInit;
11
12use crate::conversions::Convert;
13use crate::dom::audio::audionode::{AudioNode, AudioNodeOptionsHelper, MAX_CHANNEL_COUNT};
14use crate::dom::audio::baseaudiocontext::BaseAudioContext;
15use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
16 ChannelCountMode, ChannelInterpretation,
17};
18use crate::dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::{
19 ChannelMergerNodeMethods, ChannelMergerOptions,
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 ChannelMergerNode {
27 node: AudioNode,
28}
29
30impl ChannelMergerNode {
31 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
32 pub(crate) fn new_inherited(
33 cx: &mut JSContext,
34 _: &Window,
35 context: &BaseAudioContext,
36 options: &ChannelMergerOptions,
37 ) -> Fallible<ChannelMergerNode> {
38 let node_options = options.parent.unwrap_or(
39 1,
40 ChannelCountMode::Explicit,
41 ChannelInterpretation::Speakers,
42 );
43
44 if node_options.count != 1 || node_options.mode != ChannelCountMode::Explicit {
45 return Err(Error::InvalidState(None));
46 }
47
48 if options.numberOfInputs < 1 || options.numberOfInputs > MAX_CHANNEL_COUNT {
49 return Err(Error::IndexSize(None));
50 }
51
52 let num_inputs = options.numberOfInputs;
53 let node = AudioNode::new_inherited(
54 cx,
55 AudioNodeInit::ChannelMergerNode(options.convert()),
56 context,
57 node_options,
58 num_inputs, 1, )?;
61 Ok(ChannelMergerNode { node })
62 }
63
64 pub(crate) fn new(
65 cx: &mut JSContext,
66 window: &Window,
67 context: &BaseAudioContext,
68 options: &ChannelMergerOptions,
69 ) -> Fallible<DomRoot<ChannelMergerNode>> {
70 Self::new_with_proto(cx, window, None, context, options)
71 }
72
73 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
74 fn new_with_proto(
75 cx: &mut JSContext,
76 window: &Window,
77 proto: Option<HandleObject>,
78 context: &BaseAudioContext,
79 options: &ChannelMergerOptions,
80 ) -> Fallible<DomRoot<ChannelMergerNode>> {
81 let node = ChannelMergerNode::new_inherited(cx, window, context, options)?;
82 Ok(reflect_dom_object_with_proto_and_cx(
83 Box::new(node),
84 window,
85 proto,
86 cx,
87 ))
88 }
89}
90
91impl ChannelMergerNodeMethods<crate::DomTypeHolder> for ChannelMergerNode {
92 fn Constructor(
94 cx: &mut JSContext,
95 window: &Window,
96 proto: Option<HandleObject>,
97 context: &BaseAudioContext,
98 options: &ChannelMergerOptions,
99 ) -> Fallible<DomRoot<ChannelMergerNode>> {
100 ChannelMergerNode::new_with_proto(cx, window, proto, context, options)
101 }
102}
103
104impl Convert<ChannelNodeOptions> for ChannelMergerOptions {
105 fn convert(self) -> ChannelNodeOptions {
106 ChannelNodeOptions {
107 channels: self.numberOfInputs as u8,
108 }
109 }
110}