web_audio_api/node/
mod.rs1use std::f32::consts::PI;
4use std::sync::OnceLock;
5
6use crate::render::{
7 AudioParamValues, AudioProcessor, AudioRenderQuantum, AudioWorkletGlobalScope,
8};
9use crate::AudioBufferIter;
10
11mod audio_node;
13pub use audio_node::*;
14mod scheduled_source;
15pub use scheduled_source::*;
16
17mod analyser;
19pub use analyser::*;
20mod audio_buffer_source;
21pub use audio_buffer_source::*;
22mod biquad_filter;
23pub use biquad_filter::*;
24mod channel_merger;
25pub use channel_merger::*;
26mod channel_splitter;
27pub use channel_splitter::*;
28mod constant_source;
29pub use constant_source::*;
30mod convolver;
31pub use convolver::*;
32mod delay;
33pub use delay::*;
34mod destination;
35pub use destination::*;
36mod dynamics_compressor;
37pub use dynamics_compressor::*;
38mod gain;
39pub use gain::*;
40mod iir_filter;
41pub use iir_filter::*;
42mod media_element_source;
43pub use media_element_source::*;
44mod media_stream_destination;
45pub use media_stream_destination::*;
46mod media_stream_source;
47pub use media_stream_source::*;
48mod media_stream_track_source;
49pub use media_stream_track_source::*;
50mod oscillator;
51pub use oscillator::*;
52mod panner;
53pub use panner::*;
54mod script_processor;
55pub use script_processor::*;
56mod stereo_panner;
57pub use stereo_panner::*;
58mod waveshaper;
59pub use waveshaper::*;
60
61pub(crate) const TABLE_LENGTH_USIZE: usize = 8192;
62pub(crate) const TABLE_LENGTH_BY_4_USIZE: usize = TABLE_LENGTH_USIZE / 4;
63
64pub(crate) const TABLE_LENGTH_F32: f32 = TABLE_LENGTH_USIZE as f32;
65pub(crate) const TABLE_LENGTH_BY_4_F32: f32 = TABLE_LENGTH_BY_4_USIZE as f32;
66
67pub(crate) fn precomputed_sine_table() -> &'static [f32] {
69 static INSTANCE: OnceLock<Vec<f32>> = OnceLock::new();
70 INSTANCE.get_or_init(|| {
71 (0..TABLE_LENGTH_USIZE)
73 .map(|x| ((x as f32) * 2.0 * PI * (1. / (TABLE_LENGTH_F32))).sin())
74 .collect()
75 })
76}
77
78struct MediaStreamRenderer<R> {
81 stream: R,
82 finished: bool,
83}
84
85impl<R> MediaStreamRenderer<R> {
86 fn new(stream: R) -> Self {
87 Self {
88 stream,
89 finished: false,
91 }
92 }
93}
94
95impl<R: AudioBufferIter> AudioProcessor for MediaStreamRenderer<R> {
96 fn process(
97 &mut self,
98 _inputs: &[AudioRenderQuantum],
99 outputs: &mut [AudioRenderQuantum],
100 _params: AudioParamValues<'_>,
101 _scope: &AudioWorkletGlobalScope,
102 ) -> bool {
103 let output = &mut outputs[0];
105
106 match self.stream.next() {
108 Some(Ok(buffer)) => {
109 let channels = buffer.number_of_channels();
110 output.set_number_of_channels(channels);
111 output
112 .channels_mut()
113 .iter_mut()
114 .zip(buffer.channels())
115 .for_each(|(o, i)| o.copy_from_slice(i.as_slice()));
116 }
117 Some(Err(e)) => {
118 log::warn!("Error playing audio stream: {}", e);
119 self.finished = true; output.make_silent()
121 }
122 None => {
123 if !self.finished {
124 log::debug!("Stream finished");
125 self.finished = true;
126 }
127 output.make_silent()
128 }
129 }
130
131 !self.finished
132 }
133}