web_audio_api/node/
media_stream_destination.rs1use std::error::Error;
2
3use crate::buffer::AudioBuffer;
4use crate::context::{AudioContextRegistration, BaseAudioContext};
5use crate::render::{
6 AudioParamValues, AudioProcessor, AudioRenderQuantum, AudioWorkletGlobalScope,
7};
8
9use super::{AudioNode, AudioNodeOptions, ChannelConfig};
10
11use crate::media_streams::{MediaStream, MediaStreamTrack};
12use crossbeam_channel::{self, Receiver, Sender};
13
14#[derive(Debug)]
59pub struct MediaStreamAudioDestinationNode {
60 registration: AudioContextRegistration,
61 channel_config: ChannelConfig,
62 stream: MediaStream,
63}
64
65impl AudioNode for MediaStreamAudioDestinationNode {
66 fn registration(&self) -> &AudioContextRegistration {
67 &self.registration
68 }
69
70 fn channel_config(&self) -> &ChannelConfig {
71 &self.channel_config
72 }
73
74 fn number_of_inputs(&self) -> usize {
75 1
76 }
77
78 fn number_of_outputs(&self) -> usize {
79 0
80 }
81}
82
83impl MediaStreamAudioDestinationNode {
84 pub fn new<C: BaseAudioContext>(context: &C, options: AudioNodeOptions) -> Self {
86 context.base().register(move |registration| {
87 let (send, recv) = crossbeam_channel::bounded(1);
88
89 let iter = AudioDestinationNodeStream {
90 receiver: recv.clone(),
91 };
92 let track = MediaStreamTrack::from_iter(iter);
93 let stream = MediaStream::from_tracks(vec![track]);
94
95 let node = MediaStreamAudioDestinationNode {
96 registration,
97 channel_config: options.into(),
98 stream,
99 };
100
101 let render = DestinationRenderer { send, recv };
102
103 (node, Box::new(render))
104 })
105 }
106
107 pub fn stream(&self) -> &MediaStream {
110 &self.stream
111 }
112}
113
114struct DestinationRenderer {
115 send: Sender<AudioBuffer>,
116 recv: Receiver<AudioBuffer>,
117}
118
119impl AudioProcessor for DestinationRenderer {
120 fn process(
121 &mut self,
122 inputs: &[AudioRenderQuantum],
123 _outputs: &mut [AudioRenderQuantum],
124 _params: AudioParamValues<'_>,
125 scope: &AudioWorkletGlobalScope,
126 ) -> bool {
127 let input = &inputs[0];
129
130 let samples: Vec<_> = input.channels().iter().map(|c| c.to_vec()).collect();
132 let buffer = AudioBuffer::from(samples, scope.sample_rate);
133
134 if self.recv.try_recv().is_ok() {
136 log::warn!("MediaStreamDestination buffer dropped");
137 }
138
139 let _ = self.send.send(buffer);
141
142 false
143 }
144}
145
146struct AudioDestinationNodeStream {
147 receiver: Receiver<AudioBuffer>,
148}
149
150impl Iterator for AudioDestinationNodeStream {
151 type Item = Result<AudioBuffer, Box<dyn Error + Send + Sync>>;
152
153 fn next(&mut self) -> Option<Self::Item> {
154 match self.receiver.recv() {
155 Ok(buf) => Some(Ok(buf)),
156 Err(e) => Some(Err(Box::new(e))),
157 }
158 }
159}