2018-02-26 01:50:41 +00:00
|
|
|
#[cfg(feature = "with-tremor")]
|
2021-02-10 22:13:32 +00:00
|
|
|
use librespot_tremor as vorbis;
|
2017-08-03 20:22:08 +00:00
|
|
|
|
2021-01-07 06:42:38 +00:00
|
|
|
use super::{AudioDecoder, AudioError, AudioPacket};
|
2017-08-03 20:22:08 +00:00
|
|
|
use std::error;
|
2018-02-26 01:50:41 +00:00
|
|
|
use std::fmt;
|
|
|
|
use std::io::{Read, Seek};
|
2017-08-03 20:22:08 +00:00
|
|
|
|
|
|
|
pub struct VorbisDecoder<R: Read + Seek>(vorbis::Decoder<R>);
|
|
|
|
pub struct VorbisError(vorbis::VorbisError);
|
|
|
|
|
2018-02-26 01:50:41 +00:00
|
|
|
impl<R> VorbisDecoder<R>
|
|
|
|
where
|
|
|
|
R: Read + Seek,
|
2017-08-03 20:22:08 +00:00
|
|
|
{
|
|
|
|
pub fn new(input: R) -> Result<VorbisDecoder<R>, VorbisError> {
|
|
|
|
Ok(VorbisDecoder(vorbis::Decoder::new(input)?))
|
|
|
|
}
|
2021-01-07 06:42:38 +00:00
|
|
|
}
|
2017-08-03 20:22:08 +00:00
|
|
|
|
2021-01-07 06:42:38 +00:00
|
|
|
impl<R> AudioDecoder for VorbisDecoder<R>
|
|
|
|
where
|
|
|
|
R: Read + Seek,
|
|
|
|
{
|
2017-08-03 20:22:08 +00:00
|
|
|
#[cfg(not(feature = "with-tremor"))]
|
2021-01-07 06:42:38 +00:00
|
|
|
fn seek(&mut self, ms: i64) -> Result<(), AudioError> {
|
2017-08-03 20:22:08 +00:00
|
|
|
self.0.time_seek(ms as f64 / 1000f64)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "with-tremor")]
|
2021-01-07 06:42:38 +00:00
|
|
|
fn seek(&mut self, ms: i64) -> Result<(), AudioError> {
|
2017-08-03 20:22:08 +00:00
|
|
|
self.0.time_seek(ms)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-01-07 06:42:38 +00:00
|
|
|
fn next_packet(&mut self) -> Result<Option<AudioPacket>, AudioError> {
|
2017-08-03 20:22:08 +00:00
|
|
|
loop {
|
|
|
|
match self.0.packets().next() {
|
2021-02-24 20:39:42 +00:00
|
|
|
Some(Ok(packet)) => {
|
|
|
|
// Losslessly represent [-32768, 32767] to [-1.0, 1.0] while maintaining DC linearity.
|
|
|
|
return Ok(Some(AudioPacket::Samples(
|
|
|
|
packet
|
|
|
|
.data
|
|
|
|
.iter()
|
2021-03-27 20:44:01 +00:00
|
|
|
.map(|sample| {
|
|
|
|
((*sample as f64 + 0.5) / (std::i16::MAX as f64 + 0.5)) as f32
|
|
|
|
})
|
2021-02-24 20:39:42 +00:00
|
|
|
.collect(),
|
|
|
|
)));
|
|
|
|
}
|
2017-08-03 20:22:08 +00:00
|
|
|
None => return Ok(None),
|
|
|
|
|
|
|
|
Some(Err(vorbis::VorbisError::Hole)) => (),
|
|
|
|
Some(Err(err)) => return Err(err.into()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<vorbis::VorbisError> for VorbisError {
|
|
|
|
fn from(err: vorbis::VorbisError) -> VorbisError {
|
|
|
|
VorbisError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for VorbisError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
fmt::Debug::fmt(&self.0, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for VorbisError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
fmt::Display::fmt(&self.0, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for VorbisError {
|
2019-10-08 09:31:18 +00:00
|
|
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
|
|
|
error::Error::source(&self.0)
|
2017-08-03 20:22:08 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-07 06:42:38 +00:00
|
|
|
|
|
|
|
impl From<vorbis::VorbisError> for AudioError {
|
|
|
|
fn from(err: vorbis::VorbisError) -> AudioError {
|
|
|
|
AudioError::VorbisError(VorbisError(err))
|
|
|
|
}
|
|
|
|
}
|