Merge pull request #70 from tomaka/wasapi-sleep

Fix the hack in the WASAPI implementation
This commit is contained in:
tomaka 2015-09-22 11:22:14 +02:00
commit 3e4ced5fba
1 changed files with 54 additions and 51 deletions

View File

@ -232,48 +232,41 @@ 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(); let hresult = (*self.audio_client).GetCurrentPadding(&mut padding);
let hresult = (*self.audio_client).GetCurrentPadding(&mut padding); check_result(hresult).unwrap();
check_result(hresult).unwrap(); self.max_frames_in_buffer - padding
self.max_frames_in_buffer - padding };
};
if frames_available == 0 { let frames_available = cmp::min(frames_available,
// TODO: max_elements as u32 * mem::size_of::<T>() as u32 /
::std::thread::sleep_ms(1); self.bytes_per_frame as u32);
continue;
}
let frames_available = cmp::min(frames_available, if frames_available == 0 {
max_elements as u32 * mem::size_of::<T>() as u32 / return Buffer::Empty;
self.bytes_per_frame as u32); }
assert!(frames_available != 0);
// loading buffer // loading buffer
let (buffer_data, buffer_len) = { let (buffer_data, buffer_len) = {
let mut buffer: *mut winapi::BYTE = mem::uninitialized(); let mut buffer: *mut winapi::BYTE = mem::uninitialized();
let hresult = (*self.render_client).GetBuffer(frames_available, let hresult = (*self.render_client).GetBuffer(frames_available,
&mut buffer as *mut *mut _); &mut buffer as *mut *mut _);
check_result(hresult).unwrap(); check_result(hresult).unwrap();
assert!(!buffer.is_null()); assert!(!buffer.is_null());
(buffer as *mut T, (buffer as *mut T,
frames_available as usize * self.bytes_per_frame as usize frames_available as usize * self.bytes_per_frame as usize
/ 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> {
render_client: *mut winapi::IAudioRenderClient, Empty,
buffer_data: *mut T, Buffer {
buffer_len: usize, render_client: *mut winapi::IAudioRenderClient,
frames: winapi::UINT32, buffer_data: *mut T,
marker: PhantomData<&'a mut T>, buffer_len: usize,
frames: winapi::UINT32,
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();
}; }
}
} }
} }