Fixed coreaudio callback to send proper buffersize, removed code in lib where sampleformat affected buffersize

This commit is contained in:
mitchmindtree 2015-03-03 18:17:21 +11:00
parent 1347c7c99d
commit 1d66e18d7e
3 changed files with 32 additions and 30 deletions

View File

@ -1,3 +1,5 @@
#![feature(core, old_io)]
extern crate cpal;
extern crate vorbis;
@ -34,7 +36,7 @@ fn main() {
if let Some(output) = buffer.next() {
*output = next_sample as u16;
data = data.slice_from(1);
data = &data[1..];
} else {
break;
}

View File

@ -6,11 +6,12 @@ use std::mem;
use std::sync::mpsc::{channel, Sender, Receiver};
type NumChannels = usize;
type NumFrames = usize;
#[allow(dead_code)]
pub struct Voice {
audio_unit: AudioUnit,
ready_receiver: Receiver<()>,
ready_receiver: Receiver<(NumChannels, NumFrames)>,
samples_sender: Sender<(Vec<f32>, NumChannels)>,
}
@ -42,13 +43,18 @@ impl Voice {
::SampleFormat::F32
}
pub fn append_data<'a, T>(&'a mut self, buffer_size: usize) -> Buffer<'a, T> where T: Clone {
while let None = self.ready_receiver.try_recv().ok() {}
Buffer {
samples_sender: self.samples_sender.clone(),
samples: vec![unsafe{ mem::uninitialized() }; buffer_size],
num_channels: 2,
marker: ::std::marker::PhantomData,
pub fn append_data<'a, T>(&'a mut self, max_elements: usize) -> Buffer<'a, T> where T: Clone {
// Block until the audio callback is ready for more data.
loop {
if let Ok((channels, frames)) = self.ready_receiver.try_recv() {
let buffer_size = ::std::cmp::min(channels * frames, max_elements);
return Buffer {
samples_sender: self.samples_sender.clone(),
samples: vec![unsafe{ mem::uninitialized() }; buffer_size],
num_channels: channels as usize,
marker: ::std::marker::PhantomData,
}
}
}
}
@ -88,25 +94,24 @@ fn new_voice() -> Result<Voice, String> {
let audio_unit_result = AudioUnit::new(Type::Output, SubType::HalOutput)
.render_callback(box move |channels, num_frames| {
let (samples, num_channels) = match samples_receiver.try_recv() {
Ok((samples, num_channels)) => (samples, num_channels),
_ => (vec![0.0; num_frames * channels.len()], channels.len()),
};
if let Err(_) = ready_sender.send(()) {
if let Err(_) = ready_sender.send((channels.len(), num_frames)) {
return Err("Callback failed to send 'ready' message.".to_string());
}
assert!(num_frames == (samples.len() / num_channels) as usize,
"The number of input frames given differs from the number requested by the AudioUnit");
for (i, frame) in samples.chunks(num_channels).enumerate() {
for (channel, sample) in channels.iter_mut().zip(frame.iter()) {
channel[i] = *sample;
}
loop {
if let Ok((samples, num_channels)) = samples_receiver.try_recv() {
let samples: Vec<f32> = samples;
assert!(num_frames == (samples.len() / num_channels) as usize,
"The number of input frames given differs from the number \
requested by the AudioUnit: {:?} and {:?} respectively",
(samples.len() / num_channels as usize), num_frames);
for (i, frame) in samples.chunks(num_channels).enumerate() {
for (channel, sample) in channels.iter_mut().zip(frame.iter()) {
channel[i] = *sample;
}
}
break;
};
}
Ok(())
})

View File

@ -192,8 +192,6 @@ impl Voice {
let max_elements = max_elements * target_channels as usize / channels as usize;
let max_elements = max_elements * target_samples_rate.0 as usize /
samples_rate.0 as usize;
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);
@ -203,9 +201,6 @@ impl Voice {
target_channels as usize;
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as usize /
target_samples_rate.0 as usize;
let intermediate_buffer_length = intermediate_buffer_length *
source_samples_format.get_sample_size() /
target_samples_format.get_sample_size();
let intermediate_buffer = std::iter::repeat(unsafe { std::mem::uninitialized() })
.take(intermediate_buffer_length).collect();