attemp at removing buffer

This commit is contained in:
DMSDeveloper 2018-04-26 14:58:36 +10:00 committed by mitchmindtree
parent 9a084347db
commit ab7e17558f
1 changed files with 72 additions and 24 deletions

View File

@ -12,6 +12,7 @@ use UnknownTypeInputBuffer;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::mem; use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use SampleFormat;
pub struct EventLoop { pub struct EventLoop {
asio_stream: Arc<Mutex<Option<sys::AsioStream>>>, asio_stream: Arc<Mutex<Option<sys::AsioStream>>>,
@ -55,13 +56,54 @@ impl EventLoop {
let callbacks = self.callbacks.clone(); let callbacks = self.callbacks.clone();
let bytes_per_channel = format.data_type.sample_size(); let bytes_per_channel = format.data_type.sample_size();
let num_channels = format.channels.clone(); let num_channels = format.channels.clone();
// Create buffers
let cpal_num_samples =
(stream.buffer_size as usize) * num_channels as usize;
let channel_len = cpal_num_samples
/ num_channels as usize;
enum CpalBuffer{
I16(Vec<i16>),
U16(Vec<u16>),
F32(Vec<f32>),
}
enum ChannelBuffer{
I16(Vec<Vec<i16>>),
U16(Vec<Vec<u16>>),
F32(Vec<Vec<f32>>),
}
let (mut cpal_buffer,
mut channels) = match format.data_type{
SampleFormat::I16 => {
let mut cpal_buffer = CpalBuffer::I16(vec![0 as i16; cpal_num_samples]);
let mut channels = ChannelBuffer::I16(
(0..num_channels)
.map(|_| Vec::with_capacity(channel_len))
.collect());
(cpal_buffer, channels)
}
SampleFormat::U16 => {
let mut cpal_buffer = CpalBuffer::U16(vec![0 as u16; cpal_num_samples]);
let mut channels = ChannelBuffer::U16(
(0..num_channels)
.map(|_| Vec::with_capacity(channel_len))
.collect());
(cpal_buffer, channels)
}
SampleFormat::F32 => {
let mut cpal_buffer = CpalBuffer::F32(vec![0 as f32; cpal_num_samples]);
let mut channels = ChannelBuffer::F32(
(0..num_channels)
.map(|_| Vec::with_capacity(channel_len))
.collect());
(cpal_buffer, channels)
}
};
sys::set_callback(move |index| unsafe { sys::set_callback(move |index| unsafe {
if let Some(ref asio_stream) = *asio_stream.lock().unwrap() { if let Some(ref asio_stream) = *asio_stream.lock().unwrap() {
// Number of samples needed total // Number of samples needed total
let cpal_num_samples =
(asio_stream.buffer_size as usize) * num_channels as usize;
let mut callbacks = callbacks.lock().unwrap(); let mut callbacks = callbacks.lock().unwrap();
// Assuming only one callback, probably needs to change // Assuming only one callback, probably needs to change
@ -73,22 +115,18 @@ impl EventLoop {
$SampleTypeIdent:ident, $SampleTypeIdent:ident,
$AsioType:ty, $AsioType:ty,
$AsioTypeIdent:ident) => { $AsioTypeIdent:ident) => {
// Buffer that is filled by cpal.
let mut cpal_buffer: Vec<$SampleType> = vec![0 as $SampleType; cpal_num_samples];
// Function for deinterleaving because // Function for deinterleaving because
// cpal writes to buffer interleaved // cpal writes to buffer interleaved
fn interleave(channels: Vec<Vec<$SampleType>>) -> Vec<$SampleType>{ fn interleave(channels: &[Vec<$SampleType>],
let mut buffer: Vec<$SampleType> = Vec::new(); buffer: &mut Vec<$SampleType>) {
let length = channels[0].len(); let length = channels[0].len();
for i in 0..length{ for i in 0..length{
for channel in &channels{ for channel in channels{
buffer.push(channel[i]); buffer.push(channel[i]);
} }
} }
buffer
} }
let mut channels: Vec<Vec<$SampleType>> = vec![Vec::new(); num_channels as usize];
// For each channel write the cpal data to // For each channel write the cpal data to
// the asio buffer // the asio buffer
// Also need to check for Endian // Also need to check for Endian
@ -111,11 +149,11 @@ impl EventLoop {
// interleave all the channels // interleave all the channels
let mut inter_buffer = interleave(channels); interleave(&channels, &mut cpal_buffer);
let buff = InputBuffer{ let buff = InputBuffer{
buffer: &mut inter_buffer buffer: &mut cpal_buffer
}; };
callback( callback(
StreamId(count), StreamId(count),
@ -130,17 +168,25 @@ impl EventLoop {
}; };
// Generic over types // Generic over types
// TODO check for endianess // TODO check for endianess
match stream_type { match (stream_type, cpal_buffer, channels) {
sys::AsioSampleType::ASIOSTInt32LSB => { (sys::AsioSampleType::ASIOSTInt32LSB,
CpalBuffer::I16(cpal_buffer),
ChannelBuffer::I16(channels))=> {
try_callback!(I16, i16, i16, i32, i32); try_callback!(I16, i16, i16, i32, i32);
} }
sys::AsioSampleType::ASIOSTInt16LSB => { (sys::AsioSampleType::ASIOSTInt16LSB,
CpalBuffer::I16(cpal_buffer),
ChannelBuffer::I16(channels))=> {
try_callback!(I16, i16, i16, i16, i16); try_callback!(I16, i16, i16, i16, i16);
} }
sys::AsioSampleType::ASIOSTFloat32LSB => { (sys::AsioSampleType::ASIOSTFloat32LSB,
CpalBuffer::F32(cpal_buffer),
ChannelBuffer::F32(channels))=> {
try_callback!(F32, f32, f32, f32, f32); try_callback!(F32, f32, f32, f32, f32);
} }
sys::AsioSampleType::ASIOSTFloat64LSB => { (sys::AsioSampleType::ASIOSTFloat64LSB,
CpalBuffer::F32(cpal_buffer),
ChannelBuffer::F32(channels))=> {
try_callback!(F32, f32, f32, f64, f64); try_callback!(F32, f32, f32, f64, f64);
} }
_ => println!("unsupported format {:?}", stream_type), _ => println!("unsupported format {:?}", stream_type),
@ -215,20 +261,22 @@ pub fn build_output_stream(
// Function for deinterleaving because // Function for deinterleaving because
// cpal writes to buffer interleaved // cpal writes to buffer interleaved
fn deinterleave(data_slice: &mut [$SampleType], fn deinterleave(data_slice: &mut [$SampleType],
num_channels: usize) -> Vec<Vec<$SampleType>>{ num_channels: usize,
let channel_len = data_slice.len() / num_channels; channels: &mut [Vec<$SampleType>]) {
let mut channels: Vec<_> = (0..num_channels)
.map(|_| Vec::with_capacity(channel_len))
.collect();
for (i, &sample) in data_slice.iter().enumerate() { for (i, &sample) in data_slice.iter().enumerate() {
let ch = i % num_channels; let ch = i % num_channels;
channels[ch].push(sample); channels[ch].push(sample);
} }
channels
} }
// Deinter all the channels // Deinter all the channels
let deinter_channels = deinterleave(&mut cpal_buffer[..], let channel_len = cpal_buffer.len()
num_channels as usize); / num_channels as usize;
let mut deinter_channels: Vec<_> = (0..num_channels)
.map(|_| Vec::with_capacity(channel_len))
.collect();
deinterleave(&mut cpal_buffer[..],
num_channels as usize,
&mut deinter_channels);
// For each channel write the cpal data to // For each channel write the cpal data to
// the asio buffer // the asio buffer