Fix the hack in the WASAPI implementation

This commit is contained in:
Pierre Krieger 2015-09-22 10:26:11 +02:00
parent d3e610a614
commit de0236b3b0
1 changed files with 54 additions and 51 deletions

View File

@ -232,7 +232,6 @@ impl Voice {
pub fn append_data<'a, T>(&'a mut self, max_elements: usize) -> Buffer<'a, T> { pub fn append_data<'a, T>(&'a mut self, max_elements: usize) -> Buffer<'a, T> {
unsafe { unsafe {
loop {
// //
let frames_available = { let frames_available = {
let mut padding = mem::uninitialized(); let mut padding = mem::uninitialized();
@ -241,16 +240,13 @@ impl Voice {
self.max_frames_in_buffer - padding self.max_frames_in_buffer - padding
}; };
if frames_available == 0 {
// TODO:
::std::thread::sleep_ms(1);
continue;
}
let frames_available = cmp::min(frames_available, let frames_available = cmp::min(frames_available,
max_elements as u32 * mem::size_of::<T>() as u32 / max_elements as u32 * mem::size_of::<T>() as u32 /
self.bytes_per_frame as u32); self.bytes_per_frame as u32);
assert!(frames_available != 0);
if frames_available == 0 {
return Buffer::Empty;
}
// loading buffer // loading buffer
let (buffer_data, buffer_len) = { let (buffer_data, buffer_len) = {
@ -265,15 +261,12 @@ impl Voice {
/ mem::size_of::<T>()) / mem::size_of::<T>())
}; };
let buffer = Buffer { Buffer::Buffer {
render_client: self.render_client, render_client: self.render_client,
buffer_data: buffer_data, buffer_data: buffer_data,
buffer_len: buffer_len, buffer_len: buffer_len,
frames: frames_available, frames: frames_available,
marker: PhantomData, marker: PhantomData,
};
return buffer;
} }
} }
} }
@ -323,33 +316,43 @@ impl Drop for Voice {
} }
} }
pub struct Buffer<'a, T: 'a> { pub enum Buffer<'a, T: 'a> {
Empty,
Buffer {
render_client: *mut winapi::IAudioRenderClient, render_client: *mut winapi::IAudioRenderClient,
buffer_data: *mut T, buffer_data: *mut T,
buffer_len: usize, buffer_len: usize,
frames: winapi::UINT32, frames: winapi::UINT32,
marker: PhantomData<&'a mut T>, marker: PhantomData<&'a mut T>,
},
} }
impl<'a, T> Buffer<'a, T> { impl<'a, T> Buffer<'a, T> {
#[inline] #[inline]
pub fn get_buffer<'b>(&'b mut self) -> &'b mut [T] { pub fn get_buffer<'b>(&'b mut self) -> &'b mut [T] {
unsafe { match self {
slice::from_raw_parts_mut(self.buffer_data, self.buffer_len) &mut Buffer::Empty => &mut [],
&mut Buffer::Buffer { buffer_data, buffer_len, .. } => unsafe {
slice::from_raw_parts_mut(buffer_data, buffer_len)
},
} }
} }
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.buffer_len match self {
&Buffer::Empty => 0,
&Buffer::Buffer { buffer_len, .. } => buffer_len,
}
} }
#[inline] #[inline]
pub fn finish(self) { pub fn finish(self) {
// releasing buffer if let Buffer::Buffer { render_client, frames, .. } = self {
unsafe { unsafe {
let hresult = (*self.render_client).ReleaseBuffer(self.frames as u32, 0); let hresult = (*render_client).ReleaseBuffer(frames as u32, 0);
check_result(hresult).unwrap(); check_result(hresult).unwrap();
}; }
}
} }
} }