Switch back to using buffers
This commit is contained in:
parent
1a556514b0
commit
49636365d8
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
37
src/lib.rs
37
src/lib.rs
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue