Skip to main content

script/dom/audio/
audiolistener.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 script_bindings::reflector::{Reflector, reflect_dom_object};
8use servo_media::audio::audio_node::AudioNodeType;
9use servo_media::audio::param::{ParamDir, ParamType};
10
11use crate::dom::audio::audioparam::AudioParam;
12use crate::dom::audio::baseaudiocontext::BaseAudioContext;
13use crate::dom::bindings::codegen::Bindings::AudioListenerBinding::AudioListenerMethods;
14use crate::dom::bindings::codegen::Bindings::AudioParamBinding::{
15    AudioParamMethods, AutomationRate,
16};
17use crate::dom::bindings::error::Fallible;
18use crate::dom::bindings::num::Finite;
19use crate::dom::bindings::root::{Dom, DomRoot};
20use crate::dom::window::Window;
21
22#[dom_struct]
23pub(crate) struct AudioListener {
24    reflector_: Reflector,
25    position_x: Dom<AudioParam>,
26    position_y: Dom<AudioParam>,
27    position_z: Dom<AudioParam>,
28    forward_x: Dom<AudioParam>,
29    forward_y: Dom<AudioParam>,
30    forward_z: Dom<AudioParam>,
31    up_x: Dom<AudioParam>,
32    up_y: Dom<AudioParam>,
33    up_z: Dom<AudioParam>,
34}
35
36impl AudioListener {
37    fn new_inherited(
38        cx: &mut JSContext,
39        window: &Window,
40        context: &BaseAudioContext,
41    ) -> AudioListener {
42        let node = context.listener();
43
44        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionx>
45        let position_x = AudioParam::new(
46            cx,
47            window,
48            context,
49            Some(node),
50            AudioNodeType::AudioListenerNode,
51            ParamType::Position(ParamDir::X),
52            AutomationRate::A_rate,
53            0.,       // default value
54            f32::MIN, // min value
55            f32::MAX, // max value
56        );
57        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positiony>
58        let position_y = AudioParam::new(
59            cx,
60            window,
61            context,
62            Some(node),
63            AudioNodeType::AudioListenerNode,
64            ParamType::Position(ParamDir::Y),
65            AutomationRate::A_rate,
66            0.,       // default value
67            f32::MIN, // min value
68            f32::MAX, // max value
69        );
70        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionz>
71        let position_z = AudioParam::new(
72            cx,
73            window,
74            context,
75            Some(node),
76            AudioNodeType::AudioListenerNode,
77            ParamType::Position(ParamDir::Z),
78            AutomationRate::A_rate,
79            0.,       // default value
80            f32::MIN, // min value
81            f32::MAX, // max value
82        );
83        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardx>
84        let forward_x = AudioParam::new(
85            cx,
86            window,
87            context,
88            Some(node),
89            AudioNodeType::AudioListenerNode,
90            ParamType::Forward(ParamDir::X),
91            AutomationRate::A_rate,
92            0.,       // default value
93            f32::MIN, // min value
94            f32::MAX, // max value
95        );
96        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardy>
97        let forward_y = AudioParam::new(
98            cx,
99            window,
100            context,
101            Some(node),
102            AudioNodeType::AudioListenerNode,
103            ParamType::Forward(ParamDir::Y),
104            AutomationRate::A_rate,
105            0.,       // default value
106            f32::MIN, // min value
107            f32::MAX, // max value
108        );
109        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardz>
110        let forward_z = AudioParam::new(
111            cx,
112            window,
113            context,
114            Some(node),
115            AudioNodeType::AudioListenerNode,
116            ParamType::Forward(ParamDir::Z),
117            AutomationRate::A_rate,
118            -1.,      // default value
119            f32::MIN, // min value
120            f32::MAX, // max value
121        );
122        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upx>
123        let up_x = AudioParam::new(
124            cx,
125            window,
126            context,
127            Some(node),
128            AudioNodeType::AudioListenerNode,
129            ParamType::Up(ParamDir::X),
130            AutomationRate::A_rate,
131            0.,       // default value
132            f32::MIN, // min value
133            f32::MAX, // max value
134        );
135        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upy>
136        let up_y = AudioParam::new(
137            cx,
138            window,
139            context,
140            Some(node),
141            AudioNodeType::AudioListenerNode,
142            ParamType::Up(ParamDir::Y),
143            AutomationRate::A_rate,
144            1.,       // default value
145            f32::MIN, // min value
146            f32::MAX, // max value
147        );
148        // <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upz>
149        let up_z = AudioParam::new(
150            cx,
151            window,
152            context,
153            Some(node),
154            AudioNodeType::AudioListenerNode,
155            ParamType::Up(ParamDir::Z),
156            AutomationRate::A_rate,
157            0.,       // default value
158            f32::MIN, // min value
159            f32::MAX, // max value
160        );
161
162        AudioListener {
163            reflector_: Reflector::new(),
164            position_x: Dom::from_ref(&position_x),
165            position_y: Dom::from_ref(&position_y),
166            position_z: Dom::from_ref(&position_z),
167            forward_x: Dom::from_ref(&forward_x),
168            forward_y: Dom::from_ref(&forward_y),
169            forward_z: Dom::from_ref(&forward_z),
170            up_x: Dom::from_ref(&up_x),
171            up_y: Dom::from_ref(&up_y),
172            up_z: Dom::from_ref(&up_z),
173        }
174    }
175
176    #[cfg_attr(crown, expect(crown::unrooted_must_root))]
177    pub(crate) fn new(
178        cx: &mut JSContext,
179        window: &Window,
180        context: &BaseAudioContext,
181    ) -> DomRoot<AudioListener> {
182        let node = AudioListener::new_inherited(cx, window, context);
183        reflect_dom_object(cx, Box::new(node), window)
184    }
185}
186
187#[expect(non_snake_case)]
188impl AudioListenerMethods<crate::DomTypeHolder> for AudioListener {
189    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionx>
190    fn PositionX(&self) -> DomRoot<AudioParam> {
191        DomRoot::from_ref(&self.position_x)
192    }
193    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positiony>
194    fn PositionY(&self) -> DomRoot<AudioParam> {
195        DomRoot::from_ref(&self.position_y)
196    }
197    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionz>
198    fn PositionZ(&self) -> DomRoot<AudioParam> {
199        DomRoot::from_ref(&self.position_z)
200    }
201
202    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardx>
203    fn ForwardX(&self) -> DomRoot<AudioParam> {
204        DomRoot::from_ref(&self.forward_x)
205    }
206    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardy>
207    fn ForwardY(&self) -> DomRoot<AudioParam> {
208        DomRoot::from_ref(&self.forward_y)
209    }
210    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-forwardz>
211    fn ForwardZ(&self) -> DomRoot<AudioParam> {
212        DomRoot::from_ref(&self.forward_z)
213    }
214
215    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upx>
216    fn UpX(&self) -> DomRoot<AudioParam> {
217        DomRoot::from_ref(&self.up_x)
218    }
219    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upy>
220    fn UpY(&self) -> DomRoot<AudioParam> {
221        DomRoot::from_ref(&self.up_y)
222    }
223    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-upz>
224    fn UpZ(&self) -> DomRoot<AudioParam> {
225        DomRoot::from_ref(&self.up_z)
226    }
227
228    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-setorientation>
229    fn SetOrientation(
230        &self,
231        x: Finite<f32>,
232        y: Finite<f32>,
233        z: Finite<f32>,
234        xUp: Finite<f32>,
235        yUp: Finite<f32>,
236        zUp: Finite<f32>,
237    ) -> Fallible<DomRoot<AudioListener>> {
238        self.forward_x.SetValue(x);
239        self.forward_y.SetValue(y);
240        self.forward_z.SetValue(z);
241        self.up_x.SetValue(xUp);
242        self.up_y.SetValue(yUp);
243        self.up_z.SetValue(zUp);
244        Ok(DomRoot::from_ref(self))
245    }
246
247    /// <https://webaudio.github.io/web-audio-api/#dom-audiolistener-setposition>
248    fn SetPosition(
249        &self,
250        x: Finite<f32>,
251        y: Finite<f32>,
252        z: Finite<f32>,
253    ) -> Fallible<DomRoot<AudioListener>> {
254        self.position_x.SetValue(x);
255        self.position_y.SetValue(y);
256        self.position_z.SetValue(z);
257        Ok(DomRoot::from_ref(self))
258    }
259}