script/dom/audio/
channelsplitternode.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::node::AudioNodeInit;
8
9use crate::dom::audio::audionode::{AudioNode, AudioNodeOptionsHelper, MAX_CHANNEL_COUNT};
10use crate::dom::audio::baseaudiocontext::BaseAudioContext;
11use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
12    ChannelCountMode, ChannelInterpretation,
13};
14use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::{
15    ChannelSplitterNodeMethods, ChannelSplitterOptions,
16};
17use crate::dom::bindings::error::{Error, Fallible};
18use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
19use crate::dom::bindings::root::DomRoot;
20use crate::dom::window::Window;
21use crate::script_runtime::CanGc;
22
23#[dom_struct]
24pub(crate) struct ChannelSplitterNode {
25    node: AudioNode,
26}
27
28impl ChannelSplitterNode {
29    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
30    pub(crate) fn new_inherited(
31        _: &Window,
32        context: &BaseAudioContext,
33        options: &ChannelSplitterOptions,
34    ) -> Fallible<ChannelSplitterNode> {
35        if options.numberOfOutputs < 1 || options.numberOfOutputs > MAX_CHANNEL_COUNT {
36            return Err(Error::IndexSize);
37        }
38
39        let node_options = options.parent.unwrap_or(
40            options.numberOfOutputs,
41            ChannelCountMode::Explicit,
42            ChannelInterpretation::Discrete,
43        );
44
45        if node_options.count != options.numberOfOutputs ||
46            node_options.mode != ChannelCountMode::Explicit ||
47            node_options.interpretation != ChannelInterpretation::Discrete
48        {
49            return Err(Error::InvalidState);
50        }
51
52        let node = AudioNode::new_inherited(
53            AudioNodeInit::ChannelSplitterNode,
54            context,
55            node_options,
56            1,                       // inputs
57            options.numberOfOutputs, // outputs
58        )?;
59        Ok(ChannelSplitterNode { node })
60    }
61
62    pub(crate) fn new(
63        window: &Window,
64        context: &BaseAudioContext,
65        options: &ChannelSplitterOptions,
66        can_gc: CanGc,
67    ) -> Fallible<DomRoot<ChannelSplitterNode>> {
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: &ChannelSplitterOptions,
77        can_gc: CanGc,
78    ) -> Fallible<DomRoot<ChannelSplitterNode>> {
79        let node = ChannelSplitterNode::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 ChannelSplitterNodeMethods<crate::DomTypeHolder> for ChannelSplitterNode {
90    /// <https://webaudio.github.io/web-audio-api/#dom-channelsplitternode-channelsplitternode>
91    fn Constructor(
92        window: &Window,
93        proto: Option<HandleObject>,
94        can_gc: CanGc,
95        context: &BaseAudioContext,
96        options: &ChannelSplitterOptions,
97    ) -> Fallible<DomRoot<ChannelSplitterNode>> {
98        ChannelSplitterNode::new_with_proto(window, proto, context, options, can_gc)
99    }
100}