coreaudio: Add support for U16/I16 PCM formats.

The conversion is done Rust-side instead of using AUHAL's
automatic conversion because I haven't gotten around generics
issues yet.
This commit is contained in:
Ronald Kinard 2015-09-23 23:19:29 -05:00
parent 54fb5b03cc
commit bdef4fb3fe
2 changed files with 26 additions and 7 deletions

View File

@ -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<SupportedFormatsIterator, FormatsEnumerationError>
{
Ok(vec!(Format {
// 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: SampleFormat::F32
}).into_iter())
data_type: *f
}
})
.collect::<Vec<_>>();
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<T> is a Vec<f32>.
// 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(()) => (),

View File

@ -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 }
}