Switch back to using buffers

This commit is contained in:
Pierre Krieger 2014-12-15 16:32:13 +01:00
parent 1a556514b0
commit 49636365d8
4 changed files with 11 additions and 38 deletions

View File

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

View File

@ -21,7 +21,7 @@ fn main() {
} }
let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32), data.len()); let mut buffer = channel.append_data(channels, cpal::SamplesRate(rate as u32), data.len());
let mut buffer = buffer.samples(); let mut buffer = buffer.iter_mut();
loop { loop {
let next_sample = match data.get(0) { let next_sample = match data.get(0) {

View File

@ -31,13 +31,8 @@ pub struct Buffer<'a, T> {
// if this is non-none, then the data will be written to `conversion.intermediate_buffer` // if this is non-none, then the data will be written to `conversion.intermediate_buffer`
// instead of `target`, and the conversion will be done in buffer's destructor // instead of `target`, and the conversion will be done in buffer's destructor
conversion: Option<RequiredConversion<T>>, conversion: Option<RequiredConversion<T>>,
// number of elements that have been written
elements_written: uint,
} }
/// Iterator over the samples of the buffer.
pub struct SamplesIter<'a, 'b, T: 'b>(&'b mut uint, std::iter::Skip<std::slice::MutItems<'b, T>>);
struct RequiredConversion<T> { struct RequiredConversion<T> {
intermediate_buffer: Vec<T>, intermediate_buffer: Vec<T>,
from_sample_rate: SamplesRate, from_sample_rate: SamplesRate,
@ -164,43 +159,26 @@ impl Channel {
from_channels: channels, from_channels: channels,
to_channels: target_channels, to_channels: target_channels,
}), }),
elements_written: 0,
} }
} else { } else {
Buffer { Buffer {
target: Some(self.0.append_data(max_elements)), target: Some(self.0.append_data(max_elements)),
conversion: None, conversion: None,
elements_written: 0,
} }
} }
} }
} }
impl<'a, T> Buffer<'a, T> { impl<'a, T> Deref<[T]> for Buffer<'a, T> {
pub fn samples<'b>(&'b mut self) -> SamplesIter<'a, 'b, T> { fn deref(&self) -> &[T] {
let iter = if let Some(ref mut conversion) = self.conversion { panic!("It is forbidden to read from the audio buffer");
conversion.intermediate_buffer.as_mut_slice().iter_mut()
} else {
self.target.as_mut().unwrap().get_buffer().iter_mut()
};
let iter = iter.skip(self.elements_written);
SamplesIter(&mut self.elements_written, iter)
} }
} }
/// Iterator over the samples of the buffer. impl<'a, T> DerefMut<[T]> for Buffer<'a, T> {
impl<'a, 'b, T> Iterator<&'b mut T> for SamplesIter<'a, 'b, T> { fn deref_mut(&mut self) -> &mut [T] {
fn next(&mut self) -> Option<&'b mut T> { self.target.as_mut().unwrap().get_buffer()
match self.1.next() {
Some(v) => {
*self.0 += 1;
Some(v)
},
None => None
}
} }
} }
@ -236,12 +214,11 @@ impl<'a, T> Drop for Buffer<'a, T> where T: Sample {
let output = self.target.as_mut().unwrap().get_buffer(); let output = self.target.as_mut().unwrap().get_buffer();
assert!(buffer.len() == output.len(), "Buffers length mismatch: {} vs {}", buffer.len(), output.len()); assert!(buffer.len() == output.len(), "Buffers length mismatch: {} vs {}", buffer.len(), output.len());
self.elements_written += buffer.len();
for (i, o) in buffer.into_iter().zip(output.iter_mut()) { for (i, o) in buffer.into_iter().zip(output.iter_mut()) {
*o = i; *o = i;
} }
} }
self.target.take().unwrap().finish(self.elements_written); self.target.take().unwrap().finish();
} }
} }

View File

@ -21,7 +21,6 @@ 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,
} }
@ -87,7 +86,6 @@ 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,
}; };
@ -120,13 +118,11 @@ impl<'a, T> Buffer<'a, T> {
self.buffer.as_mut_slice() self.buffer.as_mut_slice()
} }
pub fn finish(self, elements_written: uint) { pub fn finish(self) {
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;
let hresult = f(self.render_client, elements_written as u32, 0); let hresult = f(self.render_client, self.frames as u32, 0);
check_result(hresult).unwrap(); check_result(hresult).unwrap();
if self.start_on_drop { if self.start_on_drop {