Skip to content

Commit

Permalink
Merge pull request #254 from orottier/feature/analyser-node-mutable-s…
Browse files Browse the repository at this point in the history
…lice

Change AnalyserNode API, take mutable reference for time/freq data
  • Loading branch information
orottier authored Jan 19, 2023
2 parents aaf9180 + c0bfc66 commit c5294e2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 25 deletions.
10 changes: 3 additions & 7 deletions examples/mic_playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,17 @@ fn poll_frequency_graph(
height: u16,
) -> ! {
let bin_count = analyser.frequency_bin_count();
let mut freq_buffer = Some(vec![0.; bin_count]);
let mut freq_buffer = vec![0.; bin_count];

loop {
// 5 frames per second
std::thread::sleep(std::time::Duration::from_millis(200));

// todo, check BaseAudioContext.state if it is still running

let tmp_buf = freq_buffer.take().unwrap();
let tmp_buf = analyser.get_float_frequency_data(tmp_buf);
analyser.get_float_frequency_data(&mut freq_buffer);

let points: Vec<_> = tmp_buf
let points: Vec<_> = freq_buffer
.iter()
.enumerate()
.map(|(i, &f)| (i as f32, f))
Expand All @@ -259,9 +258,6 @@ fn poll_frequency_graph(

let event = UiEvent::GraphUpdate(plot);
let _ = plot_send.send(event); // allowed to fail if the main thread is shutting down

// restore Vec
freq_buffer = Some(tmp_buf);
}
}

Expand Down
60 changes: 42 additions & 18 deletions src/node/analyser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ impl Default for AnalyserOptions {

enum AnalyserRequest {
FloatTime {
sender: Sender<Vec<f32>>,
buffer: Vec<f32>,
send_done_signal: Sender<()>,
buffer: &'static mut [f32],
},
FloatFrequency {
sender: Sender<Vec<f32>>,
buffer: Vec<f32>,
send_done_signal: Sender<()>,
buffer: &'static mut [f32],
},
}

Expand Down Expand Up @@ -137,21 +137,39 @@ impl AnalyserNode {
/// Copies the current time domain data (waveform data) into the provided buffer
// we can fix this panic cf issue #101
#[allow(clippy::missing_panics_doc)]
pub fn get_float_time_domain_data(&self, buffer: Vec<f32>) -> Vec<f32> {
let (sender, receiver) = crossbeam_channel::bounded(0);
let request = AnalyserRequest::FloatTime { sender, buffer };
pub fn get_float_time_domain_data(&self, buffer: &mut [f32]) {
// SAFETY:
// We transmute to a static reference so we can ship it to the render thread.
// The render thread will only write to the reference, and will send back a signal when it
// is done writing. This function will block until the signal is received.
let buffer: &'static mut [f32] = unsafe { std::mem::transmute(buffer) };

let (send_done_signal, recv_done_signal) = crossbeam_channel::bounded(0);
let request = AnalyserRequest::FloatTime {
send_done_signal,
buffer,
};
self.sender.send(request).unwrap();
receiver.recv().unwrap()
recv_done_signal.recv().unwrap()
}

/// Copies the current frequency data into the provided buffer
// we can fix this panic cf issue #101
#[allow(clippy::missing_panics_doc)]
pub fn get_float_frequency_data(&self, buffer: Vec<f32>) -> Vec<f32> {
let (sender, receiver) = crossbeam_channel::bounded(0);
let request = AnalyserRequest::FloatFrequency { sender, buffer };
pub fn get_float_frequency_data(&self, buffer: &mut [f32]) {
// SAFETY:
// We transmute to a static reference so we can ship it to the render thread.
// The render thread will only write to the reference, and will send back a signal when it
// is done writing. This function will block until the signal is received.
let buffer: &'static mut [f32] = unsafe { std::mem::transmute(buffer) };

let (send_done_signal, recv_done_signal) = crossbeam_channel::bounded(0);
let request = AnalyserRequest::FloatFrequency {
send_done_signal,
buffer,
};
self.sender.send(request).unwrap();
receiver.recv().unwrap()
recv_done_signal.recv().unwrap()
}
}

Expand Down Expand Up @@ -202,17 +220,23 @@ impl AudioProcessor for AnalyserRenderer {
// check if any information was requested from the control thread
if let Ok(request) = self.receiver.try_recv() {
match request {
AnalyserRequest::FloatTime { sender, mut buffer } => {
self.analyser.get_float_time(&mut buffer[..], fft_size);
AnalyserRequest::FloatTime {
send_done_signal: sender,
buffer,
} => {
self.analyser.get_float_time(buffer, fft_size);

// allow to fail when receiver is disconnected
let _ = sender.send(buffer);
let _ = sender.send(());
}
AnalyserRequest::FloatFrequency { sender, mut buffer } => {
self.analyser.get_float_frequency(&mut buffer[..]);
AnalyserRequest::FloatFrequency {
send_done_signal: sender,
buffer,
} => {
self.analyser.get_float_frequency(buffer);

// allow to fail when receiver is disconnected
let _ = sender.send(buffer);
let _ = sender.send(());
}
}
}
Expand Down

0 comments on commit c5294e2

Please sign in to comment.