extern crate asio_sys as sys; use std; pub type SupportedInputFormats = std::vec::IntoIter; pub type SupportedOutputFormats = std::vec::IntoIter; use Format; use FormatsEnumerationError; use DefaultFormatError; use SupportedFormat; use SampleFormat; use SampleRate; use std::hash::{Hash, Hasher}; #[derive(Debug, Clone)] pub struct Device{ pub drivers: sys::Drivers, pub name: String, } pub struct Devices{ drivers: std::vec::IntoIter, } impl PartialEq for Device { fn eq(&self, other: &Self) -> bool { self.name == other.name } } impl Eq for Device {} impl Hash for Device { fn hash(&self, state: &mut H) { self.name.hash(state); } } impl Device { pub fn name(&self) -> String { self.name.clone() } // Just supporting default for now pub fn supported_input_formats(&self) -> Result { match self.default_input_format() { Ok(f) => Ok(vec![SupportedFormat::from(f)].into_iter()), Err(_) => Err(FormatsEnumerationError::DeviceNotAvailable), } } pub fn supported_output_formats(&self) -> Result { match self.default_output_format() { Ok(f) => Ok(vec![SupportedFormat::from(f)].into_iter()), Err(_) => Err(FormatsEnumerationError::DeviceNotAvailable), } } pub fn default_input_format(&self) -> Result { let channels = self.drivers.get_channels().ins as u16; let sample_rate = SampleRate(self.drivers.get_sample_rate().rate); match self.drivers.get_data_type() { Ok(sys::AsioSampleType::ASIOSTInt16MSB) => Ok(SampleFormat::I16), Ok(sys::AsioSampleType::ASIOSTFloat32MSB) => Ok(SampleFormat::F32), Ok(sys::AsioSampleType::ASIOSTInt16LSB) => Ok(SampleFormat::I16), // TODO This should not be set to 16bit but is for testing Ok(sys::AsioSampleType::ASIOSTInt32LSB) => Ok(SampleFormat::I16), Ok(sys::AsioSampleType::ASIOSTFloat32LSB) => Ok(SampleFormat::F32), _ => Err(DefaultFormatError::StreamTypeNotSupported), }.map(|dt| { Format{channels, sample_rate, data_type: dt } }) } pub fn default_output_format(&self) -> Result { let channels = self.drivers.get_channels().outs as u16; let sample_rate = SampleRate(self.drivers.get_sample_rate().rate); match self.drivers.get_data_type() { Ok(sys::AsioSampleType::ASIOSTInt16MSB) => Ok(SampleFormat::I16), Ok(sys::AsioSampleType::ASIOSTFloat32MSB) => Ok(SampleFormat::F32), Ok(sys::AsioSampleType::ASIOSTInt16LSB) => Ok(SampleFormat::I16), // TODO This should not be set to 16bit but is for testing Ok(sys::AsioSampleType::ASIOSTInt32LSB) => Ok(SampleFormat::I16), Ok(sys::AsioSampleType::ASIOSTFloat32LSB) => Ok(SampleFormat::F32), _ => Err(DefaultFormatError::StreamTypeNotSupported), }.map(|dt|{ Format{channels, sample_rate, data_type: dt } }) } } impl Default for Devices { fn default() -> Devices { Devices{ drivers: sys::get_driver_list().into_iter() } } } impl Iterator for Devices { type Item = Device; fn next(&mut self) -> Option { match self.drivers.next() { Some(name) => { sys::Drivers::load(&name) .or_else(|e| { eprintln!("{}", e); Err(e) }) .ok() .map(|drivers| Device{drivers, name} ) }, None => None, } } fn size_hint(&self) -> (usize, Option) { unimplemented!() } } // Asio doesn't have a concept of default // so returning first in list as default pub fn default_input_device() -> Option { let mut driver_list = sys::get_driver_list(); match driver_list.pop() { Some(name) => { sys::Drivers::load(&name) .or_else(|e| { eprintln!("{}", e); Err(e) }) .ok() .map(|drivers| Device{drivers, name} ) }, None => None, } } pub fn default_output_device() -> Option { let mut driver_list = sys::get_driver_list(); match driver_list.pop() { Some(name) => { sys::Drivers::load(&name) .or_else(|e| { eprintln!("{}", e); Err(e) }) .ok() .map(|drivers| Device{drivers, name} ) }, None => None, } }