1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! Ogg vorbis decoder.

// Future work: permit compile-time selection of the default vorbis plugin:
// Xiph.org libvorbisfile, or rust-vorbis.
// #[cfg(libvorbis = "xiph")]
// use xiph_vorbis;
// #[cfg(libvorbis = "rust")]
// use rust_vorbis;

extern crate vorbisfile;

use super::{Source, SourceResult};
use super::SourceResult::{Buffer, StreamError, EndOfStream};
use self::vorbisfile::OVResult;

/// Ogg Vorbis decoder.
pub struct VorbisStream<R> {
    src: vorbisfile::VorbisFile<R>,
}

impl<R: Reader> VorbisStream<R> {
    /// Open a new decoder.
    pub fn open(reader: R) -> OVResult<VorbisStream<R>> {
        Ok(VorbisStream {
            src: try!(vorbisfile::VorbisFile::new(reader))
        })
    }
}

// The native result type for vorbis is a C float. ov_read() postprocesses into
// integer samples, which we're equally capable of doing.
impl<R: Reader> Source for VorbisStream<R> {
    type Output = f32;

    fn next<'a>(&'a mut self) -> SourceResult<'a, f32> {
        // TODO report sample rate
        match self.src.decode() {
            Ok(b) => Buffer(b),
            // ??? => SampleRate(...),
            Err(vorbisfile::OVError::EndOfStream) => EndOfStream,
            Err(e) => StreamError(format!("vorbisfile decoder: {}", e))
        }
    }
}