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