diff --git a/src/coreaudio/mod.rs b/src/coreaudio/mod.rs index e93e771..2039f14 100644 --- a/src/coreaudio/mod.rs +++ b/src/coreaudio/mod.rs @@ -10,6 +10,7 @@ use FormatsEnumerationError; use SampleFormat; use SamplesRate; use ChannelPosition; +use Sample; mod enumerate; @@ -26,11 +27,21 @@ impl Endpoint { pub fn get_supported_formats_list(&self) -> Result { - Ok(vec!(Format { - channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], - samples_rate: SamplesRate(44100), - data_type: SampleFormat::F32 - }).into_iter()) + // AUHAL converts internally for simple PCM translations. + // However, an additional AudioConverter unit is needed in order to + // change sample rate. + // TODO support other sample rates. + let formats = [SampleFormat::F32, SampleFormat::I16, SampleFormat::U16] + .into_iter() + .map(|f| { + Format { + channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], + samples_rate: SamplesRate(44100), + data_type: *f + } + }) + .collect::>(); + Ok(formats.into_iter()) } pub fn get_name(&self) -> String { @@ -46,7 +57,7 @@ pub struct Buffer<'a, T: 'a> { marker: ::std::marker::PhantomData<&'a T>, } -impl<'a, T> Buffer<'a, T> { +impl<'a, T: Sample> Buffer<'a, T> { #[inline] pub fn get_buffer<'b>(&'b mut self) -> &'b mut [T] { &mut self.samples[..] @@ -62,7 +73,8 @@ impl<'a, T> Buffer<'a, T> { let Buffer { samples_sender, samples, num_channels, .. } = self; // TODO: At the moment this assumes the Vec is a Vec. // Need to add T: Sample and use Sample::to_vec_f32. - let samples = unsafe { mem::transmute(samples) }; + //let samples = unsafe { mem::transmute(samples) }; + let samples = samples.into_iter().map(|x| x.as_f32()).collect(); match samples_sender.send((samples, num_channels)) { Err(_) => panic!("Failed to send samples to audio unit callback."), Ok(()) => (), diff --git a/src/samples_formats.rs b/src/samples_formats.rs index ebf6525..14f88ee 100644 --- a/src/samples_formats.rs +++ b/src/samples_formats.rs @@ -27,6 +27,7 @@ impl SampleFormat { pub unsafe trait Sample: Copy + Clone { /// Returns the `SampleFormat` corresponding to this data type. fn get_format() -> SampleFormat; + fn as_f32(&self) -> f32; } unsafe impl Sample for u16 { @@ -34,6 +35,8 @@ unsafe impl Sample for u16 { fn get_format() -> SampleFormat { SampleFormat::U16 } + + fn as_f32(&self) -> f32 { (*self as f32 - 32768.0) / (32768.0) } } unsafe impl Sample for i16 { @@ -41,6 +44,8 @@ unsafe impl Sample for i16 { fn get_format() -> SampleFormat { SampleFormat::I16 } + + fn as_f32(&self) -> f32 { (*self as f32) / (32768.0) } } unsafe impl Sample for f32 { @@ -48,4 +53,6 @@ unsafe impl Sample for f32 { fn get_format() -> SampleFormat { SampleFormat::F32 } + + fn as_f32(&self) -> f32 { *self } }