1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use crate::core::{AudioFormat, AudioSource, StreamState}; use std::sync::{Arc, Mutex}; pub struct Echo { source: Arc<Mutex<dyn AudioSource + Send>>, delay: usize, decay: f32, buffer: Vec<f32>, position: usize, } impl Echo { pub fn new(source: Arc<Mutex<dyn AudioSource + Send>>, delay: usize, decay: f32) -> Self { let mut buffer = Vec::new(); buffer.resize(delay, 0.0); Echo { source, delay, decay, buffer, position: 0, } } } impl AudioSource for Echo { fn format(&mut self) -> AudioFormat { self.source.lock().unwrap().format() } fn read(&mut self, samples: &mut [f32]) -> StreamState { let status = self.source.lock().unwrap().read(samples); let written = match status { StreamState::Good => samples.len(), StreamState::Finished(n) => n, StreamState::Underrun(n) => n, }; echo( &mut self.buffer, samples, written, &mut self.position, self.delay, self.decay, ); status } } fn echo( buffer: &mut Vec<f32>, samples: &mut [f32], written: usize, position: &mut usize, delay: usize, decay: f32, ) { let mut i = 0; while i < written { let count = std::cmp::min(delay - *position, written - i); (&mut buffer[*position..delay]) .iter_mut() .zip((&mut samples[i..written]).iter_mut()) .for_each(|(b, s)| { *b = *b * decay + *s; *s = *b; }); i += count; *position = (*position + count) % delay; } }