aboutsummaryrefslogtreecommitdiff
path: root/src/desktop/audio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/desktop/audio.rs')
-rw-r--r--src/desktop/audio.rs45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/desktop/audio.rs b/src/desktop/audio.rs
index 2438d01..486b41c 100644
--- a/src/desktop/audio.rs
+++ b/src/desktop/audio.rs
@@ -1,12 +1,18 @@
use rodio::{OutputStream, Sink, Source};
-use crate::audio::SAMPLE_RATE;
+use crate::audio::{SAMPLE_RATE, MutableWave};
use crate::io::{Wave, Audio};
use std::time::Duration;
+use std::mem;
+
+const BUFFER_SIZE: usize = 1024;
pub struct RodioAudio {
_stream: OutputStream,
- _sink: Sink,
+ sink: Sink,
+ wave: RodioWave<MutableWave>,
+ buffer: Box<[f32; BUFFER_SIZE]>,
+ buffer_i: usize,
}
struct RodioWave<W: Wave + Send + 'static>(W, usize);
@@ -24,7 +30,17 @@ impl<W: Wave + Send + 'static> Iterator for RodioWave<W>
}
}
-impl<W: Wave + Send + 'static> Source for RodioWave<W>
+struct RodioBuffer<I: Iterator<Item = f32>>(I);
+
+impl<I: Iterator<Item = f32>> Iterator for RodioBuffer<I> {
+ type Item = f32;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+impl<I: Iterator<Item = f32>> Source for RodioBuffer<I>
{
fn current_frame_len(&self) -> Option<usize> {
None
@@ -44,15 +60,32 @@ impl<W: Wave + Send + 'static> Source for RodioWave<W>
}
impl Audio for RodioAudio {
- fn new<S: Wave + Send + 'static>(wave: S) -> Self {
+ fn new(wave: MutableWave) -> Self {
let (stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();
- sink.append(RodioWave(wave, 0));
+ let wave = RodioWave(wave, 0);
RodioAudio {
_stream: stream,
- _sink: sink,
+ sink: sink,
+ wave,
+ buffer: Box::new([0.0; BUFFER_SIZE]),
+ buffer_i: 0,
+ }
+ }
+
+ fn next(&mut self) {
+ if let Some(v) = self.wave.next() {
+ self.buffer[self.buffer_i] = v;
+ self.buffer_i += 1;
+
+ if self.buffer_i == BUFFER_SIZE {
+ self.buffer_i = 0;
+ let mut buffer = Box::new([0.0; BUFFER_SIZE]);
+ mem::swap(&mut self.buffer, &mut buffer);
+ self.sink.append(RodioBuffer(buffer.into_iter()));
+ }
}
}
}