Sound output now works correctly

This commit is contained in:
Pierre Krieger 2014-12-15 16:26:55 +01:00
parent 9598f68d3c
commit 1a556514b0
4 changed files with 34 additions and 19 deletions

View File

@ -18,7 +18,7 @@ fn main() {
}); });
loop { loop {
let mut buffer = channel.append_data(1, cpal::SamplesRate(44100)); let mut buffer = channel.append_data(1, cpal::SamplesRate(44100), 32768);
for sample in buffer.samples() { for sample in buffer.samples() {
let value = data_source.next().unwrap(); let value = data_source.next().unwrap();

View File

@ -13,27 +13,25 @@ fn main() {
let packet = packet.unwrap(); let packet = packet.unwrap();
let vorbis::Packet { channels, rate, data, .. } = packet; let vorbis::Packet { channels, rate, data, .. } = packet;
let mut data = data.iter(); let mut data = data.as_slice();
let mut next_sample = None;
loop { loop {
let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32)); if data.len() == 0 {
continue 'main;
}
let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32), data.len());
let mut buffer = buffer.samples(); let mut buffer = buffer.samples();
loop { loop {
if next_sample.is_none() { let next_sample = match data.get(0) {
match data.next() { Some(s) => *s,
Some(sample) => { None => continue 'main
next_sample = Some(*sample as u16) };
},
None => {
continue 'main;
}
}
}
if let Some(output) = buffer.next() { if let Some(output) = buffer.next() {
*output = next_sample.take().unwrap(); *output = next_sample as u16;
data = data.slice_from(1);
} else { } else {
break; break;
} }

View File

@ -120,10 +120,18 @@ impl Channel {
/// This function returns a `Buffer` object that must be filled with the audio data. /// 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 /// You can't know in advance the size of the buffer, as it depends on the current state
/// of the backend. /// of the backend.
///
/// ## Panic
///
/// Panics if `max_elements` is 0 or is not a multiple of `channels`.
///
pub fn append_data<'a, T>(&'a mut self, channels: ChannelsCount, pub fn append_data<'a, T>(&'a mut self, channels: ChannelsCount,
samples_rate: SamplesRate) samples_rate: SamplesRate, max_elements: uint)
-> Buffer<'a, T> where T: Sample + Clone -> Buffer<'a, T> where T: Sample + Clone
{ {
assert!(max_elements != 0);
assert!(max_elements % channels as uint == 0);
let target_samples_rate = self.0.get_samples_rate(); let target_samples_rate = self.0.get_samples_rate();
let target_channels = self.0.get_channels(); let target_channels = self.0.get_channels();
@ -134,7 +142,7 @@ impl Channel {
if samples_rate != target_samples_rate || channels != target_channels || if samples_rate != target_samples_rate || channels != target_channels ||
source_samples_format != target_samples_format source_samples_format != target_samples_format
{ {
let mut target_buffer = self.0.append_data(); let mut target_buffer = self.0.append_data(max_elements);
// computing the length of the intermediary buffer // computing the length of the intermediary buffer
let intermediate_buffer_length = target_buffer.get_buffer().len(); let intermediate_buffer_length = target_buffer.get_buffer().len();
@ -161,7 +169,7 @@ impl Channel {
} else { } else {
Buffer { Buffer {
target: Some(self.0.append_data()), target: Some(self.0.append_data(max_elements)),
conversion: None, conversion: None,
elements_written: 0, elements_written: 0,
} }

View File

@ -21,6 +21,7 @@ pub struct Buffer<'a, T> {
render_client: *mut winapi::IAudioRenderClient, render_client: *mut winapi::IAudioRenderClient,
buffer: CVec<T>, buffer: CVec<T>,
frames: winapi::UINT32, frames: winapi::UINT32,
channels: winapi::WORD,
start_on_drop: bool, start_on_drop: bool,
} }
@ -44,7 +45,7 @@ impl Channel {
} }
} }
pub fn append_data<'a, T>(&'a mut self) -> Buffer<'a, T> { pub fn append_data<'a, T>(&'a mut self, max_elements: uint) -> Buffer<'a, T> {
unsafe { unsafe {
loop { loop {
// //
@ -63,6 +64,11 @@ impl Channel {
continue; continue;
} }
let frames_available = ::std::cmp::min(frames_available,
max_elements as u32 * mem::size_of::<T>() as u32 /
self.bytes_per_frame as u32);
assert!(frames_available != 0);
// loading buffer // loading buffer
let buffer: CVec<T> = { let buffer: CVec<T> = {
let mut buffer: *mut winapi::BYTE = mem::uninitialized(); let mut buffer: *mut winapi::BYTE = mem::uninitialized();
@ -81,6 +87,7 @@ impl Channel {
audio_client: self.audio_client, audio_client: self.audio_client,
render_client: self.render_client, render_client: self.render_client,
buffer: buffer, buffer: buffer,
channels: self.num_channels,
frames: frames_available, frames: frames_available,
start_on_drop: !self.started, start_on_drop: !self.started,
}; };
@ -114,6 +121,8 @@ impl<'a, T> Buffer<'a, T> {
} }
pub fn finish(self, elements_written: uint) { pub fn finish(self, elements_written: uint) {
let elements_written = elements_written / self.channels as uint;
// releasing buffer // releasing buffer
unsafe { unsafe {
let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().ReleaseBuffer; let f = self.render_client.as_mut().unwrap().lpVtbl.as_ref().unwrap().ReleaseBuffer;