recording v1

This commit is contained in:
DMSDeveloper 2018-04-22 23:24:05 +10:00 committed by mitchmindtree
parent 2cfd60757a
commit c978583863
2 changed files with 208 additions and 207 deletions

View File

@ -182,6 +182,12 @@ impl Iterator for Devices {
// so returning first in list as default
pub fn default_input_device() -> Option<Device> {
let mut driver_list = sys::get_driver_list();
for dn in &driver_list{
if dn == "ASIO4ALL v2"{
println!("Defaulted to ASIO4ALL **remove from production**");
return Some(Device{ driver_name: dn.clone() });
}
}
match driver_list.pop() {
Some(dn) => Some(Device{ driver_name: dn }),
None => None,

View File

@ -9,6 +9,7 @@ use std::marker::PhantomData;
use super::Device;
use std::cell::Cell;
use UnknownTypeOutputBuffer;
use UnknownTypeInputBuffer;
use std::sync::{Arc, Mutex};
use std::mem;
use self::itertools::Itertools;
@ -23,7 +24,7 @@ pub struct EventLoop {
pub struct StreamId(usize);
pub struct InputBuffer<'a, T: 'a> {
marker: PhantomData<&'a T>,
buffer: &'a mut [T],
}
pub struct OutputBuffer<'a, T: 'a> {
buffer: &'a mut [T],
@ -42,8 +43,7 @@ impl EventLoop {
&self,
device: &Device,
format: &Format,
) -> Result<StreamId, CreationError> {
/*
) -> Result<StreamId, CreationError> {
let stream_type = sys::get_data_type(&device.driver_name).expect("Couldn't load data type");
match sys::prepare_stream(&device.driver_name) {
Ok(stream) => {
@ -57,7 +57,6 @@ impl EventLoop {
let bytes_per_channel = format.data_type.sample_size();
let num_channels = format.channels.clone();
// Get stream types
sys::set_callback(move |index| unsafe {
if let Some(ref asio_stream) = *asio_stream.lock().unwrap() {
@ -70,192 +69,67 @@ impl EventLoop {
match callbacks.first_mut() {
Some(callback) => {
macro_rules! try_callback {
($SampleFormat:ident,
$SampleType:ty,
$SampleTypeIdent:ident,
$AsioType:ty,
$AsioTypeIdent:ident) => {
// Buffer that is filled by cpal.
let mut cpal_buffer: Vec<$SampleType> = vec![0 as $SampleType; cpal_num_samples];
// Call in block because of mut borrow
{
}
// Function for deinterleaving because
// cpal writes to buffer interleaved
fn interleave(channels: Vec<Vec<$SampleType>>) -> Vec<$SampleType>{
let mut buffer: Vec<$SampleType> = Vec::new();
let length = channels[0].len();
for i in 0..length{
for channel in channels{
buffer.push(channel[i]);
}
($SampleFormat:ident,
$SampleType:ty,
$SampleTypeIdent:ident,
$AsioType:ty,
$AsioTypeIdent:ident) => {
// Buffer that is filled by cpal.
let mut cpal_buffer: Vec<$SampleType> = vec![0 as $SampleType; cpal_num_samples];
// Call in block because of mut borrow
{
}
// Function for deinterleaving because
// cpal writes to buffer interleaved
fn interleave(channels: Vec<Vec<$SampleType>>) -> Vec<$SampleType>{
let mut buffer: Vec<$SampleType> = Vec::new();
let length = channels[0].len();
for i in 0..length{
for channel in &channels{
buffer.push(channel[i]);
}
buffer
}
// Deinter all the channels
let deinter_channels = deinterleave(&mut cpal_buffer[..],
num_channels as usize);
// For each channel write the cpal data to
// the asio buffer
// Also need to check for Endian
for (i, channel) in deinter_channels.into_iter().enumerate(){
let buff_ptr = (asio_stream
.buffer_infos[i]
.buffers[index as usize] as *mut $AsioType)
.offset(asio_stream.buffer_size as isize * i as isize);
let asio_buffer: &'static mut [$AsioType] =
std::slice::from_raw_parts_mut(
buff_ptr,
asio_stream.buffer_size as usize);
for (asio_s, cpal_s) in asio_buffer.iter_mut()
.zip(&channel){
*asio_s = (*cpal_s as i64 *
::std::$AsioTypeIdent::MAX as i64 /
::std::$SampleTypeIdent::MAX as i64) as $AsioType;
}
buffer
}
let mut channels: Vec<Vec<$SampleType>> = vec![Vec::new(); num_channels as usize];
// For each channel write the cpal data to
// the asio buffer
// Also need to check for Endian
for (i, channel) in channels.iter_mut().enumerate(){
let buff_ptr = (asio_stream
.buffer_infos[i]
.buffers[index as usize] as *mut $AsioType)
.offset(asio_stream.buffer_size as isize * i as isize);
let asio_buffer: &'static mut [$AsioType] =
std::slice::from_raw_parts_mut(
buff_ptr,
asio_stream.buffer_size as usize);
for asio_s in asio_buffer.iter(){
channel.push( (*asio_s as i64 *
::std::$SampleTypeIdent::MAX as i64 /
::std::$AsioTypeIdent::MAX as i64) as $SampleType);
}
}
// interleave all the channels
let inter_buffer = interleave(channels);
let buff = InputBuffer{
buffer: &mut cpal_buffer
};
callback(
StreamId(count),
StreamData::Input{
buffer: UnknownTypeInputBuffer::$SampleFormat(
::InputBuffer{
target: Some(super::super::InputBuffer::Asio(buff))
})
}
);
let buff = InputBuffer{
buffer: &mut cpal_buffer
};
}
// Generic over types
// TODO check for endianess
match stream_type {
sys::AsioSampleType::ASIOSTInt32LSB => {
try_callback!(I16, i16, i16, i32, i32);
}
sys::AsioSampleType::ASIOSTInt16LSB => {
try_callback!(I16, i16, i16, i16, i16);
}
sys::AsioSampleType::ASIOSTFloat32LSB => {
try_callback!(F32, f32, f32, f32, f32);
}
sys::AsioSampleType::ASIOSTFloat32LSB => {
try_callback!(F32, f32, f32, f64, f64);
}
_ => println!("unsupported format {:?}", stream_type),
}
}
None => return (),
}
}
});
Ok(StreamId(count))
}
Err(ref e) => {
println!("Error preparing stream: {}", e);
Err(CreationError::DeviceNotAvailable)
}
}
*/
unimplemented!()
}
pub fn build_output_stream(
&self,
device: &Device,
format: &Format,
) -> Result<StreamId, CreationError> {
let stream_type = sys::get_data_type(&device.driver_name).expect("Couldn't load data type");
match sys::prepare_stream(&device.driver_name) {
Ok(stream) => {
{
*self.asio_stream.lock().unwrap() = Some(stream);
}
let count = self.stream_count.get();
self.stream_count.set(count + 1);
let asio_stream = self.asio_stream.clone();
let callbacks = self.callbacks.clone();
let bytes_per_channel = format.data_type.sample_size();
let num_channels = format.channels.clone();
// Get stream types
sys::set_callback(move |index| unsafe {
if let Some(ref asio_stream) = *asio_stream.lock().unwrap() {
// 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();
// Assuming only one callback, probably needs to change
match callbacks.first_mut() {
Some(callback) => {
macro_rules! try_callback {
($SampleFormat:ident,
$SampleType:ty,
$SampleTypeIdent:ident,
$AsioType:ty,
$AsioTypeIdent:ident) => {
// Buffer that is filled by cpal.
let mut cpal_buffer: Vec<$SampleType> = vec![0 as $SampleType; cpal_num_samples];
// Call in block because of mut borrow
{
let buff = OutputBuffer{
buffer: &mut cpal_buffer
};
callback(
StreamId(count),
StreamData::Output{
buffer: UnknownTypeOutputBuffer::$SampleFormat(
::OutputBuffer{
target: Some(super::super::OutputBuffer::Asio(buff))
})
}
);
callback(
StreamId(count),
StreamData::Input{
buffer: UnknownTypeInputBuffer::$SampleFormat(
::InputBuffer{
buffer: Some(super::super::InputBuffer::Asio(buff))
})
}
// Function for deinterleaving because
// cpal writes to buffer interleaved
fn deinterleave(data_slice: &mut [$SampleType],
num_channels: usize) -> Vec<Vec<$SampleType>>{
let mut channels: Vec<Vec<$SampleType>> = Vec::new();
for i in 0..num_channels{
let mut it = data_slice.iter().skip(i).cloned();
let channel = it.step(num_channels).collect();
channels.push(channel);
}
channels
}
// Deinter all the channels
let deinter_channels = deinterleave(&mut cpal_buffer[..],
num_channels as usize);
// For each channel write the cpal data to
// the asio buffer
// Also need to check for Endian
for (i, channel) in deinter_channels.into_iter().enumerate(){
let buff_ptr = (asio_stream
.buffer_infos[i]
.buffers[index as usize] as *mut $AsioType)
.offset(asio_stream.buffer_size as isize * i as isize);
let asio_buffer: &'static mut [$AsioType] =
std::slice::from_raw_parts_mut(
buff_ptr,
asio_stream.buffer_size as usize);
for (asio_s, cpal_s) in asio_buffer.iter_mut()
.zip(&channel){
*asio_s = (*cpal_s as i64 *
::std::$AsioTypeIdent::MAX as i64 /
::std::$SampleTypeIdent::MAX as i64) as $AsioType;
}
}
};
);
}
};
// Generic over types
// TODO check for endianess
match stream_type {
@ -287,42 +161,163 @@ impl EventLoop {
}
}
pub fn play_stream(&self, stream: StreamId) {
sys::play();
}
pub fn build_output_stream(
&self,
device: &Device,
format: &Format,
) -> Result<StreamId, CreationError> {
let stream_type = sys::get_data_type(&device.driver_name).expect("Couldn't load data type");
match sys::prepare_stream(&device.driver_name) {
Ok(stream) => {
{
*self.asio_stream.lock().unwrap() = Some(stream);
}
let count = self.stream_count.get();
self.stream_count.set(count + 1);
let asio_stream = self.asio_stream.clone();
let callbacks = self.callbacks.clone();
let bytes_per_channel = format.data_type.sample_size();
let num_channels = format.channels.clone();
pub fn pause_stream(&self, stream: StreamId) {
sys::stop();
}
pub fn destroy_stream(&self, stream_id: StreamId) {
let mut asio_stream_lock = self.asio_stream.lock().unwrap();
let old_stream = mem::replace(&mut *asio_stream_lock, None);
if let Some(old_stream) = old_stream {
sys::destroy_stream(old_stream);
// Get stream types
sys::set_callback(move |index| unsafe {
if let Some(ref asio_stream) = *asio_stream.lock().unwrap() {
// 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();
// Assuming only one callback, probably needs to change
match callbacks.first_mut() {
Some(callback) => {
macro_rules! try_callback {
($SampleFormat:ident,
$SampleType:ty,
$SampleTypeIdent:ident,
$AsioType:ty,
$AsioTypeIdent:ident) => {
// Buffer that is filled by cpal.
let mut cpal_buffer: Vec<$SampleType> = vec![0 as $SampleType; cpal_num_samples];
// Call in block because of mut borrow
{
let buff = OutputBuffer{
buffer: &mut cpal_buffer
};
callback(
StreamId(count),
StreamData::Output{
buffer: UnknownTypeOutputBuffer::$SampleFormat(
::OutputBuffer{
target: Some(super::super::OutputBuffer::Asio(buff))
})
}
);
}
// Function for deinterleaving because
// cpal writes to buffer interleaved
fn deinterleave(data_slice: &mut [$SampleType],
num_channels: usize) -> Vec<Vec<$SampleType>>{
let mut channels: Vec<Vec<$SampleType>> = Vec::new();
for i in 0..num_channels{
let mut it = data_slice.iter().skip(i).cloned();
let channel = it.step(num_channels).collect();
channels.push(channel);
}
channels
}
// Deinter all the channels
let deinter_channels = deinterleave(&mut cpal_buffer[..],
num_channels as usize);
// For each channel write the cpal data to
// the asio buffer
// Also need to check for Endian
for (i, channel) in deinter_channels.into_iter().enumerate(){
let buff_ptr = (asio_stream
.buffer_infos[i]
.buffers[index as usize] as *mut $AsioType)
.offset(asio_stream.buffer_size as isize * i as isize);
let asio_buffer: &'static mut [$AsioType] =
std::slice::from_raw_parts_mut(
buff_ptr,
asio_stream.buffer_size as usize);
for (asio_s, cpal_s) in asio_buffer.iter_mut()
.zip(&channel){
*asio_s = (*cpal_s as i64 *
::std::$AsioTypeIdent::MAX as i64 /
::std::$SampleTypeIdent::MAX as i64) as $AsioType;
}
}
};
}
// Generic over types
// TODO check for endianess
match stream_type {
sys::AsioSampleType::ASIOSTInt32LSB => {
try_callback!(I16, i16, i16, i32, i32);
}
sys::AsioSampleType::ASIOSTInt16LSB => {
try_callback!(I16, i16, i16, i16, i16);
}
sys::AsioSampleType::ASIOSTFloat32LSB => {
try_callback!(F32, f32, f32, f32, f32);
}
sys::AsioSampleType::ASIOSTFloat32LSB => {
try_callback!(F32, f32, f32, f64, f64);
}
_ => println!("unsupported format {:?}", stream_type),
}
}
None => return (),
}
}
});
Ok(StreamId(count))
}
}
pub fn run<F>(&self, mut callback: F) -> !
where
F: FnMut(StreamId, StreamData) + Send,
{
let callback: &mut (FnMut(StreamId, StreamData) + Send) = &mut callback;
self.callbacks
.lock()
.unwrap()
.push(unsafe { mem::transmute(callback) });
loop {
// Might need a sleep here to prevent the loop being
// removed in --release
Err(ref e) => {
println!("Error preparing stream: {}", e);
Err(CreationError::DeviceNotAvailable)
}
}
}
pub fn play_stream(&self, stream: StreamId) {
sys::play();
}
pub fn pause_stream(&self, stream: StreamId) {
sys::stop();
}
pub fn destroy_stream(&self, stream_id: StreamId) {
let mut asio_stream_lock = self.asio_stream.lock().unwrap();
let old_stream = mem::replace(&mut *asio_stream_lock, None);
if let Some(old_stream) = old_stream {
sys::destroy_stream(old_stream);
}
}
pub fn run<F>(&self, mut callback: F) -> !
where
F: FnMut(StreamId, StreamData) + Send,
{
let callback: &mut (FnMut(StreamId, StreamData) + Send) = &mut callback;
self.callbacks
.lock()
.unwrap()
.push(unsafe { mem::transmute(callback) });
loop {
// Might need a sleep here to prevent the loop being
// removed in --release
}
}
}
impl<'a, T> InputBuffer<'a, T> {
pub fn buffer(&self) -> &[T] {
unimplemented!()
&self.buffer
}
pub fn finish(self) {
unimplemented!()
}
}