use std::io::Cursor;
use rodio::{Decoder, Sink};
use crate::{output::Output, source::Source, DecoderError};
#[allow(missing_debug_implementations)]
pub struct AudioSink {
sink: Sink,
}
impl AudioSink {
pub fn new(output: &Output) -> AudioSink {
AudioSink {
sink: Sink::new(&output.device),
}
}
pub fn append(&self, source: &Source) -> Result<(), DecoderError> {
self.sink
.append(Decoder::new(Cursor::new(source.clone())).map_err(|_| DecoderError)?);
Ok(())
}
pub fn empty(&self) -> bool {
self.sink.empty()
}
pub fn volume(&self) -> f32 {
self.sink.volume()
}
pub fn set_volume(&mut self, volume: f32) {
self.sink.set_volume(volume);
}
pub fn play(&self) {
self.sink.play();
}
pub fn pause(&self) {
self.sink.pause()
}
pub fn is_paused(&self) -> bool {
self.sink.is_paused()
}
pub fn stop(&self) {
self.sink.stop();
}
}
#[cfg(test)]
mod tests {
#[cfg(target_os = "linux")]
use {
crate::{output::Output, source::Source, AudioSink},
amethyst_utils::app_root_dir::application_root_dir,
std::{fs::File, io::Read, vec::Vec},
};
#[cfg(target_os = "linux")]
fn test_append(file_name: &str, should_pass: bool) {
let app_root = application_root_dir().unwrap();
let audio_path = app_root.join(file_name);
let mut f = File::open(audio_path).unwrap();
let mut buffer = Vec::new();
f.read_to_end(&mut buffer).unwrap();
let src = Source { bytes: buffer };
let output = Output::default();
let sink = AudioSink::new(&output);
match sink.append(&src) {
Ok(_pass) => assert!(
should_pass,
"Expected `append` result to be Err(..), but was Ok(..)"
),
Err(fail) => assert!(
!should_pass,
"Expected `append` result to be `Ok(..)`, but was {:?}",
fail
),
};
}
#[test]
#[cfg(target_os = "linux")]
fn test_append_wav() {
test_append("tests/sound_test.wav", true);
}
#[test]
#[cfg(target_os = "linux")]
fn test_append_mp3() {
test_append("tests/sound_test.mp3", true);
}
#[test]
#[cfg(target_os = "linux")]
fn test_append_flac() {
test_append("tests/sound_test.flac", true);
}
#[test]
#[cfg(target_os = "linux")]
fn test_play_ogg() {
test_append("tests/sound_test.ogg", true);
}
#[test]
#[cfg(target_os = "linux")]
fn test_append_fake() {
test_append("tests/sound_test.fake", false);
}
}