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 SampleFormat;
|
||||||
use SamplesRate;
|
use SamplesRate;
|
||||||
use ChannelPosition;
|
use ChannelPosition;
|
||||||
|
use Sample;
|
||||||
|
|
||||||
mod enumerate;
|
mod enumerate;
|
||||||
|
|
||||||
|
@ -26,11 +27,21 @@ impl Endpoint {
|
||||||
pub fn get_supported_formats_list(&self)
|
pub fn get_supported_formats_list(&self)
|
||||||
-> Result<SupportedFormatsIterator, FormatsEnumerationError>
|
-> 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],
|
channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight],
|
||||||
samples_rate: SamplesRate(44100),
|
samples_rate: SamplesRate(44100),
|
||||||
data_type: SampleFormat::F32
|
data_type: *f
|
||||||
}).into_iter())
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Ok(formats.into_iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_name(&self) -> String {
|
pub fn get_name(&self) -> String {
|
||||||
|
@ -46,7 +57,7 @@ pub struct Buffer<'a, T: 'a> {
|
||||||
marker: ::std::marker::PhantomData<&'a T>,
|
marker: ::std::marker::PhantomData<&'a T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Buffer<'a, T> {
|
impl<'a, T: Sample> Buffer<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_buffer<'b>(&'b mut self) -> &'b mut [T] {
|
pub fn get_buffer<'b>(&'b mut self) -> &'b mut [T] {
|
||||||
&mut self.samples[..]
|
&mut self.samples[..]
|
||||||
|
@ -62,7 +73,8 @@ impl<'a, T> Buffer<'a, T> {
|
||||||
let Buffer { samples_sender, samples, num_channels, .. } = self;
|
let Buffer { samples_sender, samples, num_channels, .. } = self;
|
||||||
// TODO: At the moment this assumes the Vec<T> is a Vec<f32>.
|
// TODO: At the moment this assumes the Vec<T> is a Vec<f32>.
|
||||||
// Need to add T: Sample and use Sample::to_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)) {
|
match samples_sender.send((samples, num_channels)) {
|
||||||
Err(_) => panic!("Failed to send samples to audio unit callback."),
|
Err(_) => panic!("Failed to send samples to audio unit callback."),
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
|
|
|
@ -27,6 +27,7 @@ impl SampleFormat {
|
||||||
pub unsafe trait Sample: Copy + Clone {
|
pub unsafe trait Sample: Copy + Clone {
|
||||||
/// Returns the `SampleFormat` corresponding to this data type.
|
/// Returns the `SampleFormat` corresponding to this data type.
|
||||||
fn get_format() -> SampleFormat;
|
fn get_format() -> SampleFormat;
|
||||||
|
fn as_f32(&self) -> f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sample for u16 {
|
unsafe impl Sample for u16 {
|
||||||
|
@ -34,6 +35,8 @@ unsafe impl Sample for u16 {
|
||||||
fn get_format() -> SampleFormat {
|
fn get_format() -> SampleFormat {
|
||||||
SampleFormat::U16
|
SampleFormat::U16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_f32(&self) -> f32 { (*self as f32 - 32768.0) / (32768.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sample for i16 {
|
unsafe impl Sample for i16 {
|
||||||
|
@ -41,6 +44,8 @@ unsafe impl Sample for i16 {
|
||||||
fn get_format() -> SampleFormat {
|
fn get_format() -> SampleFormat {
|
||||||
SampleFormat::I16
|
SampleFormat::I16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_f32(&self) -> f32 { (*self as f32) / (32768.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sample for f32 {
|
unsafe impl Sample for f32 {
|
||||||
|
@ -48,4 +53,6 @@ unsafe impl Sample for f32 {
|
||||||
fn get_format() -> SampleFormat {
|
fn get_format() -> SampleFormat {
|
||||||
SampleFormat::F32
|
SampleFormat::F32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_f32(&self) -> f32 { *self }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue