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