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:
parent
54fb5b03cc
commit
bdef4fb3fe
|
@ -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 {
|
||||
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::<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(()) => (),
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue