script/dom/audio/
periodicwave.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::gc::HandleObject;
8use script_bindings::codegen::GenericBindings::PeriodicWaveBinding::PeriodicWaveMethods;
9use script_bindings::num::Finite;
10use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
11use servo_media::audio::periodic_wave::{
12 PeriodicWave as ServoMediaPeriodicWave, PeriodicWaveOptions as ServoMediaPeriodicWaveOptions,
13};
14
15use crate::conversions::Convert;
16use crate::dom::audio::baseaudiocontext::BaseAudioContext;
17use crate::dom::bindings::codegen::Bindings::PeriodicWaveBinding::PeriodicWaveOptions;
18use crate::dom::bindings::error::{Error, Fallible};
19use crate::dom::bindings::root::{Dom, DomRoot};
20use crate::dom::window::Window;
21
22#[dom_struct]
23pub(crate) struct PeriodicWave {
24 reflector_: Reflector,
25 context: Dom<BaseAudioContext>,
26 imag: Vec<Finite<f32>>,
28 real: Vec<Finite<f32>>,
30 normalize: bool,
32}
33
34impl PeriodicWaveMethods<crate::DomTypeHolder> for PeriodicWave {
35 fn Constructor(
37 cx: &mut JSContext,
38 window: &Window,
39 proto: Option<HandleObject>,
40 context: &BaseAudioContext,
41 options: &PeriodicWaveOptions,
42 ) -> Fallible<DomRoot<PeriodicWave>> {
43 let (real, imag) = match (options.real.as_ref(), options.imag.as_ref()) {
44 (Some(real), Some(imag)) => {
46 let mut real = real.to_vec();
47 let mut imag = imag.to_vec();
48 if real.len() != imag.len() {
51 return Err(Error::IndexSize(Some(String::from(
52 "real and imag coefficients have different lengths",
53 ))));
54 }
55 if real.len() < 2 || imag.len() < 2 {
56 return Err(Error::IndexSize(Some(String::from(
57 "At least one of real or imag coefficients have length less than 2",
58 ))));
59 }
60 real[0] = Finite::wrap(0.0);
62 imag[0] = Finite::wrap(0.0);
63 (real, imag)
64 },
65 (Some(real), None) => {
67 let mut real = real.to_vec();
68 if real.len() < 2 {
70 return Err(Error::IndexSize(Some(String::from(
71 "real coefficients have length less than 2",
72 ))));
73 }
74 let real_len = real.len();
76 real[0] = Finite::wrap(0.0);
78 (real, vec![Finite::wrap(0.0); real_len])
80 },
81 (None, Some(imag)) => {
83 let mut imag = imag.to_vec();
84 if imag.len() < 2 {
86 return Err(Error::IndexSize(Some(String::from(
87 "imag coefficients have length less than 2",
88 ))));
89 }
90 let imag_len = imag.len();
92 imag[0] = Finite::wrap(0.0);
94 (vec![Finite::wrap(0.0); imag_len], imag)
96 },
97 (None, None) => (
98 vec![Finite::wrap(0.0); 2],
100 vec![Finite::wrap(0.0), Finite::wrap(1.0)],
102 ),
103 };
104 Ok(reflect_dom_object_with_proto(
105 cx,
106 Box::new(PeriodicWave {
107 reflector_: Reflector::new(),
108 context: Dom::from_ref(context),
109 real,
110 imag,
111 normalize: !options.parent.disableNormalization,
114 }),
115 window,
116 proto,
117 ))
118 }
119}
120
121impl Convert<ServoMediaPeriodicWave> for &PeriodicWave {
122 fn convert(self) -> ServoMediaPeriodicWave {
123 ServoMediaPeriodicWave::new(ServoMediaPeriodicWaveOptions::new(
124 self.imag.iter().map(|x| **x).collect(),
125 self.real.iter().map(|x| **x).collect(),
126 !self.normalize,
127 ))
128 }
129}