45 lines
1.4 KiB
Rust
45 lines
1.4 KiB
Rust
use crate::*;
|
|
|
|
pub struct Allocator {
|
|
channel: kanal::Receiver<Arc<AudioChunk>>,
|
|
}
|
|
|
|
impl Allocator {
|
|
pub fn spawn(buffer_size: usize, pool_size: usize) -> (Self, tokio::task::JoinHandle<()>) {
|
|
let (allocated_buffer_sender, allocated_buffer_receiver) = kanal::bounded(pool_size);
|
|
|
|
// Pre-fill the channel with initial buffers
|
|
while let Ok(true) = allocated_buffer_sender
|
|
.try_send(AudioChunk::allocate(buffer_size))
|
|
{}
|
|
|
|
let allocator = Allocator {
|
|
channel: allocated_buffer_receiver,
|
|
};
|
|
|
|
let allocated_buffer_sender = allocated_buffer_sender.to_async();
|
|
|
|
// Spawn the background task that continuously allocates buffers
|
|
let join_handle = tokio::runtime::Handle::current().spawn(async move {
|
|
loop {
|
|
let chunk = AudioChunk::allocate(buffer_size);
|
|
if allocated_buffer_sender.send(chunk).await.is_err() {
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
(allocator, join_handle)
|
|
}
|
|
}
|
|
|
|
impl ChunkFactory for Allocator {
|
|
fn create_chunk(&mut self) -> Result<std::sync::Arc<AudioChunk>> {
|
|
//match self.channel.try_recv_realtime() {
|
|
match self.channel.try_recv() {
|
|
Ok(Some(chunk)) => Ok(chunk),
|
|
_ => Err(LooperError::ChunkAllocation(std::panic::Location::caller())),
|
|
}
|
|
}
|
|
}
|