Add allocator and switch to tokio bounded channels instead of thingbuf
This commit is contained in:
26
src/allocator.rs
Normal file
26
src/allocator.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use std::sync::Arc;
|
||||
use crate::AudioChunk;
|
||||
|
||||
pub struct Allocator {
|
||||
buffer_size: usize,
|
||||
allocated_buffer_sender: tokio::sync::mpsc::Sender<Arc<AudioChunk>>,
|
||||
}
|
||||
|
||||
impl Allocator {
|
||||
pub fn new(buffer_size: usize, allocated_buffer_sender: tokio::sync::mpsc::Sender<Arc<AudioChunk>>) -> Self {
|
||||
while allocated_buffer_sender.try_send(AudioChunk::allocate(buffer_size)).is_ok() {}
|
||||
Self {
|
||||
buffer_size,
|
||||
allocated_buffer_sender,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(self) {
|
||||
loop {
|
||||
let chunk = AudioChunk::allocate(self.buffer_size);
|
||||
if self.allocated_buffer_sender.send(chunk).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,9 +53,9 @@ impl AudioChunk {
|
||||
|
||||
/// Write samples into this chunk and additional chunks as needed.
|
||||
/// Uses the factory to get pre-allocated chunks when current chunk fills up.
|
||||
pub fn write_samples<F>(this: &mut Arc<Self>, samples: &[f32], chunk_factory: F) -> Result<(), LooperError>
|
||||
pub fn write_samples<F>(this: &mut Arc<Self>, samples: &[f32], mut chunk_factory: F) -> Result<(), LooperError>
|
||||
where
|
||||
F: Fn() -> Result<Arc<AudioChunk>, LooperError>
|
||||
F: FnMut() -> Result<Arc<AudioChunk>, LooperError>
|
||||
{
|
||||
let sample_count = samples.len();
|
||||
|
||||
|
||||
35
src/main.rs
35
src/main.rs
@@ -1,21 +1,30 @@
|
||||
mod audio_chunk;
|
||||
mod looper_error;
|
||||
mod allocator;
|
||||
|
||||
use audio_chunk::AudioChunk;
|
||||
use looper_error::LooperError;
|
||||
use allocator::Allocator;
|
||||
|
||||
fn main() {
|
||||
let mut chunk = AudioChunk::allocate(2);
|
||||
|
||||
use std::cell::RefCell;
|
||||
let available_chunks = RefCell::new(vec![
|
||||
AudioChunk::allocate(2),
|
||||
AudioChunk::allocate(2),
|
||||
]);
|
||||
let factory = || available_chunks.borrow_mut().pop().ok_or(LooperError::ChunkAllocation);
|
||||
|
||||
let samples = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; // 6 samples, each chunk holds 2
|
||||
AudioChunk::write_samples(&mut chunk, &samples, factory).unwrap();
|
||||
AudioChunk::consolidate(&chunk);
|
||||
println!("Audio chunk allocated with size: {}", chunk.samples.len());
|
||||
let (allocated_buffer_sender, mut allocated_buffer_receiver) = tokio::sync::mpsc::channel(1);
|
||||
let allocator = Allocator::new(3, allocated_buffer_sender);
|
||||
let mut factory = move || {
|
||||
match allocated_buffer_receiver.try_recv() {
|
||||
Ok(chunk) => Ok(chunk),
|
||||
Err(_) => Err(LooperError::ChunkAllocation),
|
||||
}
|
||||
};
|
||||
|
||||
let handle = std::thread::spawn(move || {
|
||||
let mut chunk = factory().unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
let samples = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; // 6 samples, each chunk holds 2
|
||||
AudioChunk::write_samples(&mut chunk, &samples, factory).unwrap();
|
||||
AudioChunk::consolidate(&chunk);
|
||||
});
|
||||
|
||||
let tokio_runtime = tokio::runtime::Builder::new_current_thread().build().unwrap();
|
||||
tokio_runtime.block_on(allocator.run());
|
||||
handle.join().unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user