cpal/src/lib.rs

235 lines
7.8 KiB
Rust
Raw Normal View History

2014-12-11 16:23:33 +00:00
#![feature(unsafe_destructor)]
2014-12-11 13:22:55 +00:00
#[cfg(all(not(windows)))]
use this_platform_is_not_supported;
2014-12-15 10:45:38 +00:00
mod conversions;
2014-12-11 13:22:55 +00:00
#[cfg(windows)]
#[path="wasapi/mod.rs"]
2014-12-11 15:28:26 +00:00
pub mod cpal_impl;
2014-12-11 16:23:33 +00:00
2014-12-11 17:09:48 +00:00
/// A `Channel` represents a sound output.
///
/// A channel must be periodically filled with new data, or the sound will
/// stop playing.
2014-12-11 16:23:33 +00:00
pub struct Channel(cpal_impl::Channel);
2014-12-11 18:02:04 +00:00
/// Number of channels.
pub type ChannelsCount = u16;
2014-12-15 10:45:38 +00:00
///
#[deriving(Show, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct SamplesRate(pub u32);
2014-12-15 10:45:38 +00:00
2014-12-11 17:09:48 +00:00
/// Represents a buffer that must be filled with audio data.
///
/// A `Buffer` object borrows the channel.
2014-12-15 14:29:59 +00:00
pub struct Buffer<'a, T> {
// also contains something, taken by `Drop`
target: Option<cpal_impl::Buffer<'a, T>>,
// if this is non-none, then the data will be written to `conversion.intermediate_buffer`
// instead of `target`, and the conversion will be done in buffer's destructor
conversion: Option<RequiredConversion<T>>,
// number of elements that have been written
elements_written: uint,
}
/// Iterator over the samples of the buffer.
pub struct SamplesIter<'a, 'b, T: 'b>(&'b mut uint, std::iter::Skip<std::slice::MutItems<'b, T>>);
2014-12-15 10:45:38 +00:00
struct RequiredConversion<T> {
intermediate_buffer: Vec<T>,
from_sample_rate: SamplesRate,
to_sample_rate: SamplesRate,
from_format: SampleFormat,
to_format: SampleFormat,
from_channels: ChannelsCount,
to_channels: ChannelsCount,
}
2014-12-11 16:23:33 +00:00
2014-12-11 18:07:58 +00:00
/// Format that each sample has.
2014-12-15 09:16:18 +00:00
#[deriving(Clone, Copy, Show, PartialEq, Eq)]
2014-12-11 18:07:58 +00:00
pub enum SampleFormat {
/// The value 0 corresponds to 0.
I16,
/// The value 0 corresponds to 32768.
U16,
}
2014-12-15 10:45:38 +00:00
/// Trait for containers that contain PCM data.
#[unstable = "Will be rewritten with associated types"]
pub trait Sample: Copy {
fn get_format(Option<Self>) -> SampleFormat;
/// Turns the data into a `Vec<u16>` where each element is a sample.
fn to_vec_u16(&[Self]) -> Vec<u16>;
fn convert_channels_count(&[Self], from: u16, to: u16) -> Vec<Self>;
fn convert_samples_rate(&[Self], from: SamplesRate, to: SamplesRate) -> Vec<Self>;
}
impl Sample for u16 {
fn get_format(_: Option<u16>) -> SampleFormat {
SampleFormat::U16
}
fn to_vec_u16(input: &[u16]) -> Vec<u16> {
input.to_vec()
}
fn convert_channels_count(input: &[u16], from: u16, to: u16) -> Vec<u16> {
unimplemented!()
}
fn convert_samples_rate(input: &[u16], _from: SamplesRate, _to: SamplesRate) -> Vec<u16> {
unimplemented!()
}
}
2014-12-11 16:23:33 +00:00
impl Channel {
pub fn new() -> Channel {
let channel = cpal_impl::Channel::new();
Channel(channel)
}
2014-12-11 17:09:48 +00:00
/// Returns the number of channels.
///
/// 1 for mono, 2 for stereo, etc.
2014-12-11 18:02:04 +00:00
pub fn get_channels(&self) -> ChannelsCount {
2014-12-11 16:23:33 +00:00
self.0.get_channels()
}
2014-12-11 18:07:58 +00:00
/// Returns the number of samples that are played per second.
///
/// Common values are 22050 Hz or 44100 Hz.
2014-12-15 10:45:38 +00:00
pub fn get_samples_rate(&self) -> SamplesRate {
self.0.get_samples_rate()
2014-12-11 18:07:58 +00:00
}
/// Returns the number of samples that are played per second.
///
/// Common values are 22050 Hz or 44100 Hz.
pub fn get_samples_format(&self) -> SampleFormat {
self.0.get_samples_format()
}
2014-12-11 17:09:48 +00:00
/// Adds some PCM data to the channel's buffer.
///
/// This function returns a `Buffer` object that must be filled with the audio data.
/// You can't know in advance the size of the buffer, as it depends on the current state
/// of the backend.
2014-12-15 10:45:38 +00:00
pub fn append_data<'a, T>(&'a mut self, channels: ChannelsCount,
samples_rate: SamplesRate)
-> Buffer<'a, T> where T: Sample + Clone
{
let target_samples_rate = self.0.get_samples_rate();
let target_channels = self.0.get_channels();
let source_samples_format = Sample::get_format(None::<T>);
let target_samples_format = self.0.get_samples_format();
// if we need to convert the incoming data
if samples_rate != target_samples_rate || channels != target_channels ||
source_samples_format != target_samples_format
{
let mut target_buffer = self.0.append_data();
// computing the length of the intermediary buffer
let intermediate_buffer_length = target_buffer.get_buffer().len();
let intermediate_buffer_length = intermediate_buffer_length * channels as uint /
target_channels as uint;
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as uint /
target_samples_rate.0 as uint;
// TODO: adapt size to samples format too
let mut intermediate_buffer = Vec::from_elem(intermediate_buffer_length, unsafe { std::mem::uninitialized() });
2014-12-15 14:29:59 +00:00
Buffer {
target: Some(target_buffer),
conversion: Some(RequiredConversion {
2014-12-15 10:45:38 +00:00
intermediate_buffer: intermediate_buffer,
from_sample_rate: samples_rate,
to_sample_rate: target_samples_rate,
from_format: source_samples_format,
to_format: target_samples_format,
from_channels: channels,
to_channels: target_channels,
2014-12-15 14:29:59 +00:00
}),
elements_written: 0,
}
2014-12-15 10:45:38 +00:00
} else {
2014-12-15 14:29:59 +00:00
Buffer {
target: Some(self.0.append_data()),
conversion: None,
2014-12-15 14:40:30 +00:00
elements_written: 0,
2014-12-15 14:29:59 +00:00
}
2014-12-15 10:45:38 +00:00
}
2014-12-11 16:23:33 +00:00
}
}
2014-12-15 14:29:59 +00:00
impl<'a, T> Buffer<'a, T> {
pub fn samples<'b>(&'b mut self) -> SamplesIter<'a, 'b, T> {
let iter = if let Some(ref mut conversion) = self.conversion {
conversion.intermediate_buffer.as_mut_slice().iter_mut()
} else {
self.target.as_mut().unwrap().get_buffer().iter_mut()
};
let iter = iter.skip(self.elements_written);
2014-12-15 14:29:59 +00:00
SamplesIter(&mut self.elements_written, iter)
2014-12-11 16:23:33 +00:00
}
}
2014-12-15 14:29:59 +00:00
/// Iterator over the samples of the buffer.
impl<'a, 'b, T> Iterator<&'b mut T> for SamplesIter<'a, 'b, T> {
fn next(&mut self) -> Option<&'b mut T> {
*self.0 += 1;
self.1.next()
2014-12-15 10:45:38 +00:00
}
}
#[unsafe_destructor]
impl<'a, T> Drop for Buffer<'a, T> where T: Sample {
fn drop(&mut self) {
2014-12-15 14:29:59 +00:00
if let Some(conversion) = self.conversion.take() {
2014-12-15 10:45:38 +00:00
let buffer = conversion.intermediate_buffer;
let buffer = if conversion.from_channels != conversion.to_channels {
conversions::convert_channels(buffer.as_slice(), conversion.from_channels,
conversion.to_channels)
} else {
buffer
};
let buffer = if conversion.from_sample_rate != conversion.to_sample_rate {
conversions::convert_samples_rate(buffer.as_slice(), conversion.from_sample_rate,
conversion.to_sample_rate)
} else {
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!() }
2014-12-15 14:29:59 +00:00
let output = self.target.as_mut().unwrap().get_buffer();
2014-12-15 10:45:38 +00:00
assert!(buffer.len() == output.len(), "Buffers length mismatch: {} vs {}", buffer.len(), output.len());
2014-12-15 14:29:59 +00:00
self.elements_written += buffer.len();
2014-12-15 10:45:38 +00:00
for (i, o) in buffer.into_iter().zip(output.iter_mut()) {
*o = i;
}
}
2014-12-15 14:29:59 +00:00
self.target.take().unwrap().finish(self.elements_written);
2014-12-11 16:23:33 +00:00
}
}