Skip to main content

script/dom/audio/
constantsourcenode.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::constant_source_node::ConstantSourceNodeOptions as ServoMediaConstantSourceOptions;
11use servo_media::audio::graph::NodeId;
12use servo_media::audio::param::ParamType;
13
14use crate::conversions::Convert;
15use crate::dom::audio::audionode::AudioNode;
16use crate::dom::audio::audioparam::AudioParam;
17use crate::dom::audio::audioscheduledsourcenode::AudioScheduledSourceNode;
18use crate::dom::audio::baseaudiocontext::BaseAudioContext;
19use crate::dom::audionode::UnwrappedAudioNodeOptions;
20use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
21use crate::dom::bindings::codegen::Bindings::ConstantSourceNodeBinding::{
22    ConstantSourceNodeMethods, ConstantSourceOptions,
23};
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 ConstantSourceNode {
30    source_node: AudioScheduledSourceNode,
31    offset: Dom<AudioParam>,
32}
33
34impl ConstantSourceNode {
35    fn new_inherited(
36        node_id: Option<NodeId>,
37        context: &BaseAudioContext,
38        node_options: UnwrappedAudioNodeOptions,
39        offset: &AudioParam,
40    ) -> Self {
41        ConstantSourceNode {
42            source_node: AudioScheduledSourceNode::new_inherited(
43                node_id,
44                context,
45                node_options, /* 2, MAX, Speakers */
46                0,            /* inputs */
47                1,            /* outputs */
48            ),
49            offset: Dom::from_ref(offset),
50        }
51    }
52}
53
54impl ConstantSourceNodeMethods<crate::DomTypeHolder> for ConstantSourceNode {
55    /// <https://webaudio.github.io/web-audio-api/#dom-constantsourcenode-constantsourcenode>
56    fn Constructor(
57        cx: &mut JSContext,
58        window: &Window,
59        proto: Option<HandleObject>,
60        context: &BaseAudioContext,
61        options: &ConstantSourceOptions,
62    ) -> Fallible<DomRoot<ConstantSourceNode>> {
63        let node_options: UnwrappedAudioNodeOptions = Default::default();
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        let offset = *options.offset;
70        let node_id = AudioNode::generate_audio_node_id(
71            cx,
72            &node_options,
73            AudioNodeInit::ConstantSourceNode(options.convert()),
74            context,
75        );
76        // <https://webaudio.github.io/web-audio-api/#dom-constantsourcenode-offset>
77        let offset = AudioParam::new(
78            cx,
79            window,
80            context,
81            node_id,
82            AudioNodeType::ConstantSourceNode,
83            ParamType::Offset,
84            AutomationRate::A_rate,
85            offset,
86            f32::MIN,
87            f32::MAX,
88        );
89
90        Ok(reflect_dom_object_with_proto(
91            cx,
92            Box::new(ConstantSourceNode::new_inherited(
93                node_id,
94                context,
95                node_options, /* 2, MAX, Speakers */
96                &offset,
97            )),
98            window,
99            proto,
100        ))
101    }
102
103    /// <https://webaudio.github.io/web-audio-api/#dom-constantsourcenode-offset>
104    fn Offset(&self) -> DomRoot<AudioParam> {
105        DomRoot::from_ref(&self.offset)
106    }
107}
108
109impl Convert<ServoMediaConstantSourceOptions> for ConstantSourceOptions {
110    fn convert(self) -> ServoMediaConstantSourceOptions {
111        ServoMediaConstantSourceOptions {
112            offset: *self.offset,
113        }
114    }
115}