Merge pull request #31 from mitchmindtree/master
Fixed coreaudio callback to send proper buffersize, removed code in lib where sampleformat affected buffersize
This commit is contained in:
commit
f7c2949549
|
@ -1,3 +1,5 @@
|
||||||
|
#![feature(core, old_io)]
|
||||||
|
|
||||||
extern crate cpal;
|
extern crate cpal;
|
||||||
extern crate vorbis;
|
extern crate vorbis;
|
||||||
|
|
||||||
|
@ -34,7 +36,7 @@ fn main() {
|
||||||
|
|
||||||
if let Some(output) = buffer.next() {
|
if let Some(output) = buffer.next() {
|
||||||
*output = next_sample as u16;
|
*output = next_sample as u16;
|
||||||
data = data.slice_from(1);
|
data = &data[1..];
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,12 @@ use std::mem;
|
||||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||||
|
|
||||||
type NumChannels = usize;
|
type NumChannels = usize;
|
||||||
|
type NumFrames = usize;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Voice {
|
pub struct Voice {
|
||||||
audio_unit: AudioUnit,
|
audio_unit: AudioUnit,
|
||||||
ready_receiver: Receiver<()>,
|
ready_receiver: Receiver<(NumChannels, NumFrames)>,
|
||||||
samples_sender: Sender<(Vec<f32>, NumChannels)>,
|
samples_sender: Sender<(Vec<f32>, NumChannels)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,15 +43,20 @@ impl Voice {
|
||||||
::SampleFormat::F32
|
::SampleFormat::F32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_data<'a, T>(&'a mut self, buffer_size: usize) -> Buffer<'a, T> where T: Clone {
|
pub fn append_data<'a, T>(&'a mut self, max_elements: usize) -> Buffer<'a, T> where T: Clone {
|
||||||
while let None = self.ready_receiver.try_recv().ok() {}
|
// Block until the audio callback is ready for more data.
|
||||||
Buffer {
|
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_sender: self.samples_sender.clone(),
|
||||||
samples: vec![unsafe{ mem::uninitialized() }; buffer_size],
|
samples: vec![unsafe{ mem::uninitialized() }; buffer_size],
|
||||||
num_channels: 2,
|
num_channels: channels as usize,
|
||||||
marker: ::std::marker::PhantomData,
|
marker: ::std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn play(&mut self) {
|
pub fn play(&mut self) {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -88,25 +94,24 @@ fn new_voice() -> Result<Voice, String> {
|
||||||
|
|
||||||
let audio_unit_result = AudioUnit::new(Type::Output, SubType::HalOutput)
|
let audio_unit_result = AudioUnit::new(Type::Output, SubType::HalOutput)
|
||||||
.render_callback(box move |channels, num_frames| {
|
.render_callback(box move |channels, num_frames| {
|
||||||
|
if let Err(_) = ready_sender.send((channels.len(), 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(()) {
|
|
||||||
return Err("Callback failed to send 'ready' message.".to_string());
|
return Err("Callback failed to send 'ready' message.".to_string());
|
||||||
}
|
}
|
||||||
|
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,
|
assert!(num_frames == (samples.len() / num_channels) as usize,
|
||||||
"The number of input frames given differs from the number requested by the AudioUnit");
|
"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 (i, frame) in samples.chunks(num_channels).enumerate() {
|
||||||
for (channel, sample) in channels.iter_mut().zip(frame.iter()) {
|
for (channel, sample) in channels.iter_mut().zip(frame.iter()) {
|
||||||
channel[i] = *sample;
|
channel[i] = *sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -192,8 +192,6 @@ impl Voice {
|
||||||
let max_elements = max_elements * target_channels as usize / channels as usize;
|
let max_elements = max_elements * target_channels as usize / channels as usize;
|
||||||
let max_elements = max_elements * target_samples_rate.0 as usize /
|
let max_elements = max_elements * target_samples_rate.0 as usize /
|
||||||
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);
|
let mut target_buffer = self.0.append_data(max_elements);
|
||||||
|
|
||||||
|
@ -203,9 +201,6 @@ impl Voice {
|
||||||
target_channels as usize;
|
target_channels as usize;
|
||||||
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as usize /
|
let intermediate_buffer_length = intermediate_buffer_length * samples_rate.0 as usize /
|
||||||
target_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() })
|
let intermediate_buffer = std::iter::repeat(unsafe { std::mem::uninitialized() })
|
||||||
.take(intermediate_buffer_length).collect();
|
.take(intermediate_buffer_length).collect();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue