From aa74d06bb72560c5581ad927509207eab97821f9 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 10 Sep 2015 17:52:02 +0200 Subject: [PATCH] Reenable vorbis --- Cargo.toml | 2 +- examples/basic.rs | 4 +- src/decoder/mod.rs | 6 +-- src/decoder/vorbis.rs | 90 ++++++++++++++++++++----------------------- 4 files changed, 47 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ab89201..8c8c5b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ cpal = "0.2.1" #hound = "1.0.0" hound = { git = "https://github.com/tomaka/hound", branch = "wavreader-ownership" } lazy_static = "0.1.12" -vorbis = "0.0.12" +vorbis = "0.0.13" diff --git a/examples/basic.rs b/examples/basic.rs index 1d5968f..c342322 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -14,8 +14,8 @@ fn main() { rodio::play_once(&endpoint, BufReader::new(file)); std::thread::sleep_ms(1000); - /*let file = std::fs::File::open("examples/beep3.ogg").unwrap(); - rodio::play_once(&endpoint, file);*/ + let file = std::fs::File::open("examples/beep3.ogg").unwrap(); + rodio::play_once(&endpoint, file); std::thread::sleep_ms(1000); beep1.stop(); diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 941b3ff..44f89b0 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -4,7 +4,7 @@ use cpal::Endpoint; use cpal::Voice; mod conversions; -//mod vorbis; +mod vorbis; mod wav; /// Trait for objects that produce an audio stream. @@ -24,9 +24,9 @@ pub fn decode(endpoint: &Endpoint, data: R) -> Box } }; - /*if let Ok(decoder) = vorbis::VorbisDecoder::new(data) { + if let Ok(decoder) = vorbis::VorbisDecoder::new(endpoint, data) { return Box::new(decoder); - }*/ + } panic!("Invalid format"); } diff --git a/src/decoder/vorbis.rs b/src/decoder/vorbis.rs index 6e61b29..853b7c9 100644 --- a/src/decoder/vorbis.rs +++ b/src/decoder/vorbis.rs @@ -3,68 +3,60 @@ use std::mem; use super::Decoder; use super::conversions; -use cpal::{self, Voice}; +use cpal::{self, Endpoint, Voice}; use vorbis; -pub struct VorbisDecoder where R: Read + Seek { - decoder: vorbis::Decoder, - current_packet: Option, +pub struct VorbisDecoder { + reader: Box + Send>, + voice: Voice, } -impl VorbisDecoder where R: Read + Seek { - pub fn new(data: R) -> Result, ()> { +impl VorbisDecoder { + pub fn new(endpoint: &Endpoint, data: R) -> Result + where R: Read + Seek + Send + 'static + { let decoder = match vorbis::Decoder::new(data) { Err(_) => return Err(()), Ok(r) => r }; - Ok(VorbisDecoder { - decoder: decoder, - current_packet: None, - }) - } -} - -impl Decoder for VorbisDecoder where R: Read + Seek { - fn write(&mut self, voice: &mut Voice) { - // setting the current packet to `None` if there is no data left in it - match &mut self.current_packet { - packet @ &mut Some(_) => { - if packet.as_ref().unwrap().data.len() == 0 { - *packet = None; - } - }, - _ => () - }; - - // getting the next packet - let packet = if let Some(ref mut packet) = self.current_packet { - packet - } else { - let next = match self.decoder.packets().next().and_then(|r| r.ok()) { - Some(p) => p, - None => return, // TODO: handle - }; - - self.current_packet = Some(next); - self.current_packet.as_mut().unwrap() - }; + // building the voice + let voice_format = endpoint.get_supported_formats_list().unwrap().next().unwrap(); + let voice = Voice::new(endpoint, &voice_format).unwrap(); let to_channels = voice.get_channels(); let to_samples_rate = voice.get_samples_rate(); - let mut buffer = voice.append_data(packet.data.len()); - let src = mem::replace(&mut packet.data, Vec::new()); + let reader = decoder.into_packets().filter_map(|p| p.ok()).flat_map(move |packet| { + let reader = packet.data.into_iter(); + let reader = conversions::ChannelsCountConverter::new(reader, packet.channels, + to_channels); + let reader = conversions::SamplesRateConverter::new(reader, cpal::SamplesRate(packet.rate as u32), + to_samples_rate); + reader + }); - conversions::convert_and_write(&src, packet.channels, to_channels, - cpal::SamplesRate(packet.rate as u32), to_samples_rate, - &mut buffer); - - /* - let mut src = src.into_iter(); - for (dest, src) in buffer.iter_mut().zip(src.by_ref()) { - *dest = src; - } - packet.data = src.collect();*/ + Ok(VorbisDecoder { + reader: Box::new(reader), + voice: voice, + }) + } +} + +impl Decoder for VorbisDecoder { + fn write(&mut self) { + let (min, _) = self.reader.size_hint(); + + if min == 0 { + // finished + return; + } + + { + let mut buffer = self.voice.append_data(min); + conversions::convert_and_write(self.reader.by_ref(), &mut buffer); + } + + self.voice.play(); } }