script/dom/audio/
channelmergernode.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use js::rust::HandleObject;
7use servo_media::audio::channel_node::ChannelNodeOptions;
8use servo_media::audio::node::AudioNodeInit;
9
10use crate::conversions::Convert;
11use crate::dom::audio::audionode::{AudioNode, AudioNodeOptionsHelper, MAX_CHANNEL_COUNT};
12use crate::dom::audio::baseaudiocontext::BaseAudioContext;
13use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
14    ChannelCountMode, ChannelInterpretation,
15};
16use crate::dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::{
17    ChannelMergerNodeMethods, ChannelMergerOptions,
18};
19use crate::dom::bindings::error::{Error, Fallible};
20use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
21use crate::dom::bindings::root::DomRoot;
22use crate::dom::window::Window;
23use crate::script_runtime::CanGc;
24
25#[dom_struct]
26pub(crate) struct ChannelMergerNode {
27    node: AudioNode,
28}
29
30impl ChannelMergerNode {
31    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
32    pub(crate) fn new_inherited(
33        _: &Window,
34        context: &BaseAudioContext,
35        options: &ChannelMergerOptions,
36    ) -> Fallible<ChannelMergerNode> {
37        let node_options = options.parent.unwrap_or(
38            1,
39            ChannelCountMode::Explicit,
40            ChannelInterpretation::Speakers,
41        );
42
43        if node_options.count != 1 || node_options.mode != ChannelCountMode::Explicit {
44            return Err(Error::InvalidState);
45        }
46
47        if options.numberOfInputs < 1 || options.numberOfInputs > MAX_CHANNEL_COUNT {
48            return Err(Error::IndexSize);
49        }
50
51        let num_inputs = options.numberOfInputs;
52        let node = AudioNode::new_inherited(
53            AudioNodeInit::ChannelMergerNode(options.convert()),
54            context,
55            node_options,
56            num_inputs, // inputs
57            1,          // outputs
58        )?;
59        Ok(ChannelMergerNode { node })
60    }
61
62    pub(crate) fn new(
63        window: &Window,
64        context: &BaseAudioContext,
65        options: &ChannelMergerOptions,
66        can_gc: CanGc,
67    ) -> Fallible<DomRoot<ChannelMergerNode>> {
68        Self::new_with_proto(window, None, context, options, can_gc)
69    }
70
71    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
72    fn new_with_proto(
73        window: &Window,
74        proto: Option<HandleObject>,
75        context: &BaseAudioContext,
76        options: &ChannelMergerOptions,
77        can_gc: CanGc,
78    ) -> Fallible<DomRoot<ChannelMergerNode>> {
79        let node = ChannelMergerNode::new_inherited(window, context, options)?;
80        Ok(reflect_dom_object_with_proto(
81            Box::new(node),
82            window,
83            proto,
84            can_gc,
85        ))
86    }
87}
88
89impl ChannelMergerNodeMethods<crate::DomTypeHolder> for ChannelMergerNode {
90    /// <https://webaudio.github.io/web-audio-api/#dom-channelmergernode-channelmergernode>
91    fn Constructor(
92        window: &Window,
93        proto: Option<HandleObject>,
94        can_gc: CanGc,
95        context: &BaseAudioContext,
96        options: &ChannelMergerOptions,
97    ) -> Fallible<DomRoot<ChannelMergerNode>> {
98        ChannelMergerNode::new_with_proto(window, proto, context, options, can_gc)
99    }
100}
101
102impl Convert<ChannelNodeOptions> for ChannelMergerOptions {
103    fn convert(self) -> ChannelNodeOptions {
104        ChannelNodeOptions {
105            channels: self.numberOfInputs as u8,
106        }
107    }
108}