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