Skip to main content

script/dom/audio/
gainnode.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::context::JSContext;
7use js::rust::HandleObject;
8use script_bindings::reflector::reflect_dom_object_with_proto;
9use servo_media::audio::audio_node::{AudioNodeInit, AudioNodeType};
10use servo_media::audio::gain_node::GainNodeOptions;
11use servo_media::audio::graph::NodeId;
12use servo_media::audio::param::ParamType;
13
14use crate::conversions::Convert;
15use crate::dom::audio::audionode::{AudioNode, AudioNodeOptionsHelper};
16use crate::dom::audio::audioparam::AudioParam;
17use crate::dom::audio::baseaudiocontext::BaseAudioContext;
18use crate::dom::audionode::UnwrappedAudioNodeOptions;
19use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
20    ChannelCountMode, ChannelInterpretation,
21};
22use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
23use crate::dom::bindings::codegen::Bindings::GainNodeBinding::{GainNodeMethods, GainOptions};
24use crate::dom::bindings::error::{Error, Fallible};
25use crate::dom::bindings::root::{Dom, DomRoot};
26use crate::dom::window::Window;
27
28#[dom_struct]
29pub(crate) struct GainNode {
30    node: AudioNode,
31    gain: Dom<AudioParam>,
32}
33
34impl GainNode {
35    fn new_inherited(
36        node_id: Option<NodeId>,
37        context: &BaseAudioContext,
38        node_options: UnwrappedAudioNodeOptions,
39        gain: &AudioParam,
40    ) -> Self {
41        GainNode {
42            node: AudioNode::new_inherited(
43                node_id,
44                context,
45                node_options,
46                1, // inputs
47                1, // outputs
48            ),
49            gain: Dom::from_ref(gain),
50        }
51    }
52}
53
54impl GainNodeMethods<crate::DomTypeHolder> for GainNode {
55    /// <https://webaudio.github.io/web-audio-api/#dom-gainnode-gainnode>
56    fn Constructor(
57        cx: &mut JSContext,
58        window: &Window,
59        proto: Option<HandleObject>,
60        context: &BaseAudioContext,
61        options: &GainOptions,
62    ) -> Fallible<DomRoot<GainNode>> {
63        let node_options =
64            options
65                .parent
66                .unwrap_or(2, ChannelCountMode::Max, ChannelInterpretation::Speakers);
67        if AudioNode::channel_count_check(node_options.count) {
68            return Err(Error::NotSupported(Some(String::from(
69                "Channel count not supported",
70            ))));
71        }
72
73        let gain = *options.gain;
74        let gain_init = AudioNodeInit::GainNode(options.convert());
75        let node_id = AudioNode::generate_audio_node_id(cx, &node_options, gain_init, context);
76
77        // <https://webaudio.github.io/web-audio-api/#dom-gainnode-gain>
78        let gain = AudioParam::new(
79            cx,
80            window,
81            context,
82            node_id,
83            AudioNodeType::GainNode,
84            ParamType::Gain,
85            AutomationRate::A_rate,
86            gain,     // default value
87            f32::MIN, // min value
88            f32::MAX, // max value
89        );
90        Ok(reflect_dom_object_with_proto(
91            cx,
92            Box::new(GainNode::new_inherited(
93                node_id,
94                context,
95                node_options,
96                &gain,
97            )),
98            window,
99            proto,
100        ))
101    }
102
103    /// <https://webaudio.github.io/web-audio-api/#dom-gainnode-gain>
104    fn Gain(&self) -> DomRoot<AudioParam> {
105        DomRoot::from_ref(&self.gain)
106    }
107}
108
109impl Convert<GainNodeOptions> for GainOptions {
110    fn convert(self) -> GainNodeOptions {
111        GainNodeOptions { gain: *self.gain }
112    }
113}