Implement samples formats conversions
This commit is contained in:
parent
fbc0bad46f
commit
d3d6dd94db
68
src/lib.rs
68
src/lib.rs
|
@ -1,3 +1,4 @@
|
||||||
|
#![feature(macro_rules)]
|
||||||
#![feature(unsafe_destructor)]
|
#![feature(unsafe_destructor)]
|
||||||
|
|
||||||
#[cfg(all(not(windows), not(unix)))]
|
#[cfg(all(not(windows), not(unix)))]
|
||||||
|
@ -40,7 +41,6 @@ struct RequiredConversion<T> {
|
||||||
intermediate_buffer: Vec<T>,
|
intermediate_buffer: Vec<T>,
|
||||||
from_sample_rate: SamplesRate,
|
from_sample_rate: SamplesRate,
|
||||||
to_sample_rate: SamplesRate,
|
to_sample_rate: SamplesRate,
|
||||||
from_format: SampleFormat,
|
|
||||||
to_format: SampleFormat,
|
to_format: SampleFormat,
|
||||||
from_channels: ChannelsCount,
|
from_channels: ChannelsCount,
|
||||||
to_channels: ChannelsCount,
|
to_channels: ChannelsCount,
|
||||||
|
@ -55,6 +55,15 @@ pub enum SampleFormat {
|
||||||
U16,
|
U16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SampleFormat {
|
||||||
|
fn get_sample_size(&self) -> uint {
|
||||||
|
match self {
|
||||||
|
&SampleFormat::I16 => std::mem::size_of::<i16>(),
|
||||||
|
&SampleFormat::U16 => std::mem::size_of::<u16>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Trait for containers that contain PCM data.
|
/// Trait for containers that contain PCM data.
|
||||||
#[unstable = "Will be rewritten with associated types"]
|
#[unstable = "Will be rewritten with associated types"]
|
||||||
pub trait Sample: Copy {
|
pub trait Sample: Copy {
|
||||||
|
@ -74,6 +83,22 @@ impl Sample for u16 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sample for i16 {
|
||||||
|
fn get_format(_: Option<i16>) -> SampleFormat {
|
||||||
|
SampleFormat::I16
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_vec_u16(input: &[i16]) -> Vec<u16> {
|
||||||
|
input.iter().map(|&value| {
|
||||||
|
if value < 0 {
|
||||||
|
(value + 32767) as u16
|
||||||
|
} else {
|
||||||
|
(value as u16) + 32768
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Channel {
|
impl Channel {
|
||||||
pub fn new() -> Channel {
|
pub fn new() -> Channel {
|
||||||
let channel = cpal_impl::Channel::new();
|
let channel = cpal_impl::Channel::new();
|
||||||
|
@ -129,8 +154,10 @@ impl Channel {
|
||||||
source_samples_format != target_samples_format
|
source_samples_format != target_samples_format
|
||||||
{
|
{
|
||||||
let max_elements = max_elements * target_channels as uint / channels as uint;
|
let max_elements = max_elements * target_channels as uint / channels as uint;
|
||||||
let max_elements = max_elements * target_samples_rate.0 as uint / samples_rate.0 as uint;
|
let max_elements = max_elements * target_samples_rate.0 as uint /
|
||||||
// TODO: samples format
|
samples_rate.0 as uint;
|
||||||
|
let max_elements = max_elements * target_samples_format.get_sample_size() /
|
||||||
|
source_samples_format.get_sample_size();
|
||||||
|
|
||||||
let mut target_buffer = self.0.append_data(max_elements);
|
let mut target_buffer = self.0.append_data(max_elements);
|
||||||
|
|
||||||
|
@ -140,7 +167,9 @@ impl Channel {
|
||||||
target_channels as uint;
|
target_channels as uint;
|
||||||
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as uint /
|
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as uint /
|
||||||
target_samples_rate.0 as uint;
|
target_samples_rate.0 as uint;
|
||||||
// TODO: adapt size to samples format too
|
let intermediate_buffer_length = intermediate_buffer_length *
|
||||||
|
source_samples_format.get_sample_size() /
|
||||||
|
target_samples_format.get_sample_size();
|
||||||
let intermediate_buffer = Vec::from_elem(intermediate_buffer_length, unsafe { std::mem::uninitialized() });
|
let intermediate_buffer = Vec::from_elem(intermediate_buffer_length, unsafe { std::mem::uninitialized() });
|
||||||
|
|
||||||
Buffer {
|
Buffer {
|
||||||
|
@ -149,7 +178,6 @@ impl Channel {
|
||||||
intermediate_buffer: intermediate_buffer,
|
intermediate_buffer: intermediate_buffer,
|
||||||
from_sample_rate: samples_rate,
|
from_sample_rate: samples_rate,
|
||||||
to_sample_rate: target_samples_rate,
|
to_sample_rate: target_samples_rate,
|
||||||
from_format: source_samples_format,
|
|
||||||
to_format: target_samples_format,
|
to_format: target_samples_format,
|
||||||
from_channels: channels,
|
from_channels: channels,
|
||||||
to_channels: target_channels,
|
to_channels: target_channels,
|
||||||
|
@ -201,20 +229,26 @@ impl<'a, T> Drop for Buffer<'a, T> where T: Sample {
|
||||||
buffer
|
buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
/*let buffer = if conversion.from_format != conversion.to_format {
|
|
||||||
match conversion.to_format {
|
|
||||||
SampleFormat::U16 => Sample::to_vec_u16(buffer.as_slice()),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buffer
|
|
||||||
};*/
|
|
||||||
if conversion.from_format != conversion.to_format { unimplemented!() }
|
|
||||||
|
|
||||||
let output = self.target.as_mut().unwrap().get_buffer();
|
let output = self.target.as_mut().unwrap().get_buffer();
|
||||||
assert!(buffer.len() == output.len(), "Buffers length mismatch: {} vs {}", buffer.len(), output.len());
|
assert!(buffer.len() == output.len(), "Buffers length mismatch: {} vs {}", buffer.len(), output.len());
|
||||||
for (i, o) in buffer.into_iter().zip(output.iter_mut()) {
|
|
||||||
*o = i;
|
macro_rules! write_to_buf(
|
||||||
|
($buf:expr, $output:expr, $ty:ty) => ({
|
||||||
|
let output: &mut [$ty] = unsafe { std::mem::transmute($output) };
|
||||||
|
for (i, o) in $buf.into_iter().zip(output.iter_mut()) {
|
||||||
|
*o = i;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
match conversion.to_format {
|
||||||
|
SampleFormat::I16 => {
|
||||||
|
unimplemented!()
|
||||||
|
},
|
||||||
|
SampleFormat::U16 => {
|
||||||
|
let buffer = Sample::to_vec_u16(buffer.as_slice());
|
||||||
|
write_to_buf!(buffer, output, u16);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue