Skip to main content

script/dom/audio/
delaynode.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::codegen::GenericBindings::DelayNodeBinding::{DelayNodeMethods, DelayOptions};
9use script_bindings::reflector::reflect_dom_object_with_proto;
10use servo_media::audio::audio_node::{AudioNodeInit, AudioNodeType};
11use servo_media::audio::delay_node::DelayNodeOptions;
12use servo_media::audio::param::ParamType;
13
14use crate::conversions::Convert;
15use crate::dom::audio::audionode::AudioNodeOptionsHelper;
16use crate::dom::audio::audioparam::AudioParam;
17use crate::dom::audio::baseaudiocontext::BaseAudioContext;
18use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
19    ChannelCountMode, ChannelInterpretation,
20};
21use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
22use crate::dom::bindings::error::Fallible;
23use crate::dom::bindings::root::{Dom, DomRoot};
24use crate::dom::types::AudioNode;
25use crate::dom::window::Window;
26
27#[dom_struct]
28pub(crate) struct DelayNode {
29    source_node: AudioNode,
30    /// <https://webaudio.github.io/web-audio-api/#dom-delaynode-delaytime>
31    delay_time: Dom<AudioParam>,
32}
33
34impl DelayNodeMethods<crate::DomTypeHolder> for DelayNode {
35    /// <https://webaudio.github.io/web-audio-api/#dom-delaynode-delaynode>
36    #[cfg_attr(crown, expect(crown::unrooted_must_root))]
37    fn Constructor(
38        cx: &mut JSContext,
39        window: &Window,
40        proto: Option<HandleObject>,
41        context: &BaseAudioContext,
42        options: &DelayOptions,
43    ) -> Fallible<DomRoot<DelayNode>> {
44        let node_options =
45            options
46                .parent
47                .unwrap_or(2, ChannelCountMode::Max, ChannelInterpretation::Speakers);
48        let delay_time = *options.delayTime;
49        let max_delay_time = *options.maxDelayTime;
50        let delay_options = AudioNodeInit::DelayNode(options.convert());
51        let source_node = AudioNode::new_inherited(cx, delay_options, context, node_options, 1, 1)?;
52        let node_id = source_node.node_id();
53        let delay_time = AudioParam::new(
54            cx,
55            window,
56            context,
57            node_id,
58            AudioNodeType::OscillatorNode,
59            ParamType::DelayTime,
60            AutomationRate::A_rate,
61            delay_time as f32,
62            0.,
63            max_delay_time as f32,
64        );
65        let node = DelayNode {
66            source_node,
67            delay_time: Dom::from_ref(&delay_time),
68        };
69
70        Ok(reflect_dom_object_with_proto(
71            cx,
72            Box::new(node),
73            window,
74            proto,
75        ))
76    }
77
78    /// <https://webaudio.github.io/web-audio-api/#dom-delaynode-delaytime>
79    fn DelayTime(&self) -> DomRoot<AudioParam> {
80        DomRoot::from_ref(&self.delay_time)
81    }
82}
83
84impl Convert<DelayNodeOptions> for DelayOptions {
85    fn convert(self) -> DelayNodeOptions {
86        DelayNodeOptions {
87            max_delay_time: *self.maxDelayTime,
88            delay_time: *self.delayTime,
89        }
90    }
91}