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