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_F32: f32 = TABLE_LENGTH_USIZE as f32;
63
64pub(crate) fn precomputed_sine_table() -> &'static [f32] {
66 static INSTANCE: OnceLock<Vec<f32>> = OnceLock::new();
67 INSTANCE.get_or_init(|| {
68 (0..TABLE_LENGTH_USIZE)
70 .map(|x| ((x as f32) * 2.0 * PI * (1. / (TABLE_LENGTH_F32))).sin())
71 .collect()
72 })
73}
74
75struct MediaStreamRenderer<R> {
78 stream: R,
79 finished: bool,
80}
81
82impl<R> MediaStreamRenderer<R> {
83 fn new(stream: R) -> Self {
84 Self {
85 stream,
86 finished: false,
88 }
89 }
90}
91
92impl<R: AudioBufferIter> AudioProcessor for MediaStreamRenderer<R> {
93 fn process(
94 &mut self,
95 _inputs: &[AudioRenderQuantum],
96 outputs: &mut [AudioRenderQuantum],
97 _params: AudioParamValues<'_>,
98 _scope: &AudioWorkletGlobalScope,
99 ) -> bool {
100 let output = &mut outputs[0];
102
103 match self.stream.next() {
105 Some(Ok(buffer)) => {
106 let channels = buffer.number_of_channels();
107 output.set_number_of_channels(channels);
108 output
109 .channels_mut()
110 .iter_mut()
111 .zip(buffer.channels())
112 .for_each(|(o, i)| o.copy_from_slice(i.as_slice()));
113 }
114 Some(Err(e)) => {
115 log::warn!("Error playing audio stream: {}", e);
116 self.finished = true; output.make_silent()
118 }
119 None => {
120 if !self.finished {
121 log::debug!("Stream finished");
122 self.finished = true;
123 }
124 output.make_silent()
125 }
126 }
127
128 !self.finished
129 }
130}