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