Skip to content

Commit bb0066a

Browse files
committed
Fix microphone recorder showcase bin
1 parent 6c3417f commit bb0066a

File tree

1 file changed

+49
-54
lines changed

1 file changed

+49
-54
lines changed

showcase/mic_playback/src/main.rs

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
// run in release mode
22
// `cargo run --release --example mic_playback`
33

4-
use web_audio_api::context::{AudioContext, AudioContextRegistration, BaseAudioContext};
4+
use web_audio_api::context::{AudioContext, BaseAudioContext};
55
use web_audio_api::media_devices::{self, MediaStreamConstraints};
66
use web_audio_api::node::BiquadFilterType;
77
use web_audio_api::node::{
88
AnalyserNode, AudioBufferSourceNode, AudioNode, AudioScheduledSourceNode, BiquadFilterNode,
9-
ChannelConfig, GainNode, MediaStreamAudioSourceNode,
9+
GainNode, MediaStreamAudioSourceNode,
10+
};
11+
use web_audio_api::worklet::{
12+
AudioParamValues, AudioWorkletGlobalScope, AudioWorkletNode, AudioWorkletNodeOptions,
13+
AudioWorkletProcessor,
1014
};
11-
use web_audio_api::render::{AudioParamValues, AudioProcessor, AudioRenderQuantum, RenderScope};
1215
use web_audio_api::AudioBuffer;
1316

1417
use std::io::{stdin, stdout, Write};
@@ -30,48 +33,33 @@ const INFO_PANEL_HEIGHT: u16 = 9;
3033
const LOG_LEN: usize = 10;
3134

3235
struct MediaRecorder {
33-
/// handle to the audio context, required for all audio nodes
34-
registration: AudioContextRegistration,
35-
/// channel configuration (for up/down-mixing of inputs), required for all audio nodes
36-
channel_config: ChannelConfig,
36+
/// handle to the audio node
37+
node: AudioWorkletNode,
3738
/// receiving end for the samples recorded in the render thread
3839
receiver: Receiver<Vec<Vec<f32>>>,
3940
}
4041

41-
// implement required methods for AudioNode trait
42-
impl AudioNode for MediaRecorder {
43-
fn registration(&self) -> &AudioContextRegistration {
44-
&self.registration
45-
}
46-
fn channel_config(&self) -> &ChannelConfig {
47-
&self.channel_config
48-
}
49-
fn number_of_inputs(&self) -> usize {
50-
1
51-
}
52-
fn number_of_outputs(&self) -> usize {
53-
0
54-
}
55-
}
56-
5742
impl MediaRecorder {
5843
/// Construct a new MediaRecorder
5944
fn new<C: BaseAudioContext>(context: &C) -> Self {
60-
context.register(move |registration| {
61-
let (sender, receiver) = crossbeam_channel::unbounded();
62-
63-
// setup the processor, this will run in the render thread
64-
let render = MediaRecorderProcessor { sender };
45+
let (sender, receiver) = crossbeam_channel::unbounded();
46+
47+
// setup the processor, this will run in the render thread
48+
let options = AudioWorkletNodeOptions {
49+
number_of_inputs: 1,
50+
number_of_outputs: 0,
51+
output_channel_count: Default::default(),
52+
parameter_data: Default::default(),
53+
audio_node_options: Default::default(),
54+
processor_options: sender,
55+
};
56+
let node = AudioWorkletNode::new::<MediaRecorderProcessor>(context, options);
6557

66-
// setup the audio node, this will live in the control thread (user facing)
67-
let node = MediaRecorder {
68-
registration,
69-
channel_config: ChannelConfig::default(),
70-
receiver,
71-
};
58+
MediaRecorder { node, receiver }
59+
}
7260

73-
(node, Box::new(render))
74-
})
61+
fn node(&self) -> &AudioWorkletNode {
62+
&self.node
7563
}
7664

7765
fn get_data(self, sample_rate: f32) -> Option<AudioBuffer> {
@@ -89,17 +77,23 @@ struct MediaRecorderProcessor {
8977
sender: Sender<Vec<Vec<f32>>>,
9078
}
9179

92-
impl AudioProcessor for MediaRecorderProcessor {
93-
fn process(
80+
impl AudioWorkletProcessor for MediaRecorderProcessor {
81+
type ProcessorOptions = Sender<Vec<Vec<f32>>>;
82+
83+
fn constructor(opts: Self::ProcessorOptions) -> Self {
84+
Self { sender: opts }
85+
}
86+
87+
fn process<'a, 'b>(
9488
&mut self,
95-
inputs: &[AudioRenderQuantum],
96-
_outputs: &mut [AudioRenderQuantum],
97-
_params: AudioParamValues<'_>,
98-
_scope: &RenderScope,
89+
inputs: &'b [&'a [&'a [f32]]],
90+
_outputs: &'b mut [&'a mut [&'a mut [f32]]],
91+
_params: AudioParamValues<'b>,
92+
_scope: &'b AudioWorkletGlobalScope,
9993
) -> bool {
10094
// single input node
10195
let input = &inputs[0];
102-
let data = input.channels().iter().map(|c| c.to_vec()).collect();
96+
let data = input.iter().map(|c| c.to_vec()).collect();
10397

10498
let _ = self.sender.send(data);
10599

@@ -248,18 +242,19 @@ fn poll_frequency_graph(
248242
.map(|(i, &f)| (i as f32, f))
249243
.collect();
250244

251-
let plot = Chart::new_with_y_range(
245+
let mut chart = Chart::new_with_y_range(
252246
width as u32 * 2,
253247
(height - 25) as u32 * 4,
254248
0.0,
255249
bin_count as f32,
256-
-80.,
250+
-100.,
257251
20.,
258-
)
259-
.lineplot(&Shape::Bars(&points[..]))
260-
.to_string();
252+
);
253+
let bars = Shape::Bars(&points[..]);
254+
let plot = chart.lineplot(&bars);
255+
plot.figures();
261256

262-
let event = UiEvent::GraphUpdate(plot);
257+
let event = UiEvent::GraphUpdate(plot.to_string());
263258
let _ = plot_send.send(event); // allowed to fail if the main thread is shutting down
264259
}
265260
}
@@ -350,7 +345,7 @@ impl AudioThread {
350345
self.mic_in.disconnect();
351346

352347
if beep {
353-
let osc = self.context.create_oscillator();
348+
let mut osc = self.context.create_oscillator();
354349
osc.connect(&self.context.destination());
355350
osc.start();
356351
osc.stop_at(self.context.current_time() + 0.2);
@@ -365,15 +360,15 @@ impl AudioThread {
365360
.take()
366361
.and_then(|r| r.get_data(self.context.sample_rate()));
367362

368-
let buffer_source = self.context.create_buffer_source();
363+
let mut buffer_source = self.context.create_buffer_source();
369364
let playback_rate = Self::PLAYBACK_STEP.powi(self.playback_rate_factor);
370365
buffer_source.playback_rate().set_value(playback_rate);
371366
buffer_source.set_loop(true);
372367
if let Some(buf) = buf {
373368
buffer_source.set_buffer(buf);
374369
}
375370

376-
let biquad = self.context.create_biquad_filter();
371+
let mut biquad = self.context.create_biquad_filter();
377372
biquad.set_type((self.biquad_filter_type % 8).into());
378373

379374
let gain = self.context.create_gain();
@@ -396,13 +391,13 @@ impl AudioThread {
396391
self.buffer_source.stop();
397392
log::info!("Start recording - press space to stop");
398393

399-
let osc = self.context.create_oscillator();
394+
let mut osc = self.context.create_oscillator();
400395
osc.connect(&self.context.destination());
401396
osc.start();
402397
osc.stop_at(self.context.current_time() + 0.2);
403398

404399
let recorder = MediaRecorder::new(&self.context);
405-
self.mic_in.connect(&recorder);
400+
self.mic_in.connect(recorder.node());
406401
self.mic_in.connect(&*self.analyser.lock().unwrap());
407402

408403
self.recorder = Some(recorder);

0 commit comments

Comments
 (0)