librespot_playback/decoder/
mod.rs

1use std::ops::Deref;
2
3use thiserror::Error;
4
5#[cfg(feature = "passthrough-decoder")]
6mod passthrough_decoder;
7#[cfg(feature = "passthrough-decoder")]
8pub use passthrough_decoder::PassthroughDecoder;
9
10mod symphonia_decoder;
11pub use symphonia_decoder::SymphoniaDecoder;
12
13#[derive(Error, Debug)]
14pub enum DecoderError {
15    #[error("Passthrough Decoder Error: {0}")]
16    PassthroughDecoder(String),
17    #[error("Symphonia Decoder Error: {0}")]
18    SymphoniaDecoder(String),
19}
20
21pub type DecoderResult<T> = Result<T, DecoderError>;
22
23#[derive(Error, Debug)]
24pub enum AudioPacketError {
25    #[error("Decoder Raw Error: Can't return Raw on Samples")]
26    Raw,
27    #[error("Decoder Samples Error: Can't return Samples on Raw")]
28    Samples,
29}
30
31pub type AudioPacketResult<T> = Result<T, AudioPacketError>;
32
33pub enum AudioPacket {
34    Samples(Vec<f64>),
35    Raw(Vec<u8>),
36}
37
38impl AudioPacket {
39    #[inline]
40    pub fn samples(&self) -> AudioPacketResult<&[f64]> {
41        match self {
42            AudioPacket::Samples(s) => Ok(s),
43            AudioPacket::Raw(_) => Err(AudioPacketError::Raw),
44        }
45    }
46
47    #[inline]
48    pub fn raw(&self) -> AudioPacketResult<&[u8]> {
49        match self {
50            AudioPacket::Raw(d) => Ok(d),
51            AudioPacket::Samples(_) => Err(AudioPacketError::Samples),
52        }
53    }
54
55    #[inline]
56    pub fn is_empty(&self) -> bool {
57        match self {
58            AudioPacket::Samples(s) => s.is_empty(),
59            AudioPacket::Raw(d) => d.is_empty(),
60        }
61    }
62}
63
64#[derive(Debug, Clone)]
65pub struct AudioPacketPosition {
66    pub position_ms: u32,
67    pub skipped: bool,
68}
69
70impl Deref for AudioPacketPosition {
71    type Target = u32;
72    fn deref(&self) -> &Self::Target {
73        &self.position_ms
74    }
75}
76
77pub trait AudioDecoder {
78    fn seek(&mut self, position_ms: u32) -> Result<u32, DecoderError>;
79    fn next_packet(&mut self) -> DecoderResult<Option<(AudioPacketPosition, AudioPacket)>>;
80}
81
82impl From<DecoderError> for librespot_core::error::Error {
83    fn from(err: DecoderError) -> Self {
84        librespot_core::error::Error::aborted(err)
85    }
86}
87
88impl From<symphonia::core::errors::Error> for DecoderError {
89    fn from(err: symphonia::core::errors::Error) -> Self {
90        Self::SymphoniaDecoder(err.to_string())
91    }
92}