Merge pull request #70 from tomaka/wasapi-sleep
Fix the hack in the WASAPI implementation
This commit is contained in:
commit
3e4ced5fba
|
@ -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();
|
||||||
};
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue