use rodio::{OutputStream, Sink, Source}; 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, wave: RodioWave, buffer: Box<[f32; BUFFER_SIZE]>, buffer_i: usize, } struct RodioWave(W, usize); impl Iterator for RodioWave { type Item = f32; fn next(&mut self) -> Option { self.1 += 1; let left = self.1 % 2 == 0; let result = self.0.next(left); result } } struct RodioBuffer>(I); impl> Iterator for RodioBuffer { type Item = f32; fn next(&mut self) -> Option { self.0.next() } } impl> Source for RodioBuffer { fn current_frame_len(&self) -> Option { None } fn channels(&self) -> u16 { 2 } fn sample_rate(&self) -> u32 { SAMPLE_RATE } fn total_duration(&self) -> Option { None } } impl Audio for RodioAudio { fn new(wave: MutableWave) -> Self { let (stream, stream_handle) = OutputStream::try_default().unwrap(); let sink = Sink::try_new(&stream_handle).unwrap(); let wave = RodioWave(wave, 0); RodioAudio { _stream: stream, 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())); } } } }