use {
crate::{
audio::*,
},
std::sync::{Arc, Mutex},
std::sync::mpsc::{
channel,
Sender,
Receiver,
SendError
}
};
#[derive(Clone)]
pub struct AudioStreamSender {
stream_send: Sender<(u64, AudioBuffer)>,
}
unsafe impl Send for AudioStreamSender {}
#[derive(Clone)]
pub struct AudioStreamReceiver(Arc<Mutex<ReceiverInner>>);
pub struct ReceiverInner {
pub routes: Vec<AudioRoute>,
min_buf: usize,
max_buf: usize,
stream_recv: Receiver<(u64, AudioBuffer)>,
}
unsafe impl Send for AudioStreamReceiver {}
pub struct AudioRoute {
id: u64,
start_offset: usize,
buffers: Vec<AudioBuffer>
}
impl AudioStreamSender {
pub fn create_pair(min_buf:usize, max_buf: usize) -> (AudioStreamSender, AudioStreamReceiver) {
let (stream_send, stream_recv) = channel::<(u64, AudioBuffer)>();
(AudioStreamSender {
stream_send,
}, AudioStreamReceiver(Arc::new(Mutex::new(ReceiverInner {
stream_recv,
min_buf,
max_buf,
routes: Vec::new()
}))))
}
pub fn send(&self, route_id: u64, buffer: AudioBuffer) -> Result<(), SendError<(u64, AudioBuffer) >> {
self.stream_send.send((route_id, buffer))
}
}
impl AudioStreamReceiver {
pub fn num_routes(&self) -> usize {
let iself = self.0.lock().unwrap();
iself.routes.len()
}
pub fn route_id(&self, route_num: usize) -> u64 {
let iself = self.0.lock().unwrap();
iself.routes[route_num].id
}
pub fn try_recv_stream(&mut self) {
let mut iself = self.0.lock().unwrap();
while let Ok((route_id, buf)) = iself.stream_recv.try_recv() {
if let Some(route) = iself.routes.iter_mut().find( | v | v.id == route_id) {
route.buffers.push(buf);
}
else {
iself.routes.push(AudioRoute {
id: route_id,
buffers: vec![buf],
start_offset: 0
});
}
}
}
pub fn recv_stream(&mut self) {
{
let mut iself = self.0.lock().unwrap();
if let Ok((route_id, buf)) = iself.stream_recv.recv() {
if let Some(route) = iself.routes.iter_mut().find( | v | v.id == route_id) {
route.buffers.push(buf);
}
else {
iself.routes.push(AudioRoute {
id: route_id,
buffers: vec![buf],
start_offset: 0
});
}
}
}
self.try_recv_stream();
}
pub fn read_buffer(&mut self, route_num: usize, output: &mut AudioBuffer) -> usize {
let mut iself = self.0.lock().unwrap();
let min_buf = iself.min_buf;
let max_buf = iself.max_buf;
let route = if let Some(route) = iself.routes.get_mut(route_num) {
route
}
else {
return 0;
};
let mut total = 0;
for buf in route.buffers.iter() {
total += buf.frame_count();
}
if total - route.start_offset < output.frame_count() * min_buf {
return 0
}
while total - route.buffers.first().unwrap().frame_count() > output.frame_count() * max_buf{
let buf = route.buffers.remove(0);
total -= buf.frame_count();
route.start_offset = 0;
}
let mut frames_read = 0;
let out_channel_count = output.channel_count();
let out_frame_count = output.frame_count();
while let Some(input) = route.buffers.first() {
let mut start_offset = None;
let start_frames_read = frames_read;
for chan in 0..out_channel_count {
frames_read = start_frames_read;
let inp = input.channel(chan.min(input.channel_count() - 1));
let out = output.channel_mut(chan);
for i in route.start_offset..inp.len() {
if frames_read >= out_frame_count {
start_offset = Some(i);
break;
}
out[frames_read] = inp[i];
frames_read += 1;
}
}
if let Some(start_offset) = start_offset {
route.start_offset = start_offset;
break
}
else { route.start_offset = 0;
route.buffers.remove(0);
}
}
frames_read
}
}