servo_media_audio/
decoder.rs

1use std::sync::Mutex;
2
3#[derive(Debug, PartialEq)]
4pub enum AudioDecoderError {
5    /// Backend specific error.
6    Backend(String),
7    /// Could not read the audio buffer content.
8    BufferReadFailed,
9    /// The media trying to be decoded has an invalid format.
10    InvalidMediaFormat,
11    /// An invalid sample was found while decoding the audio.
12    InvalidSample,
13    /// Could not move to a different state.
14    StateChangeFailed,
15}
16
17pub struct AudioDecoderCallbacks {
18    pub eos: Mutex<Option<Box<dyn FnOnce() + Send + 'static>>>,
19    pub error: Mutex<Option<Box<dyn FnOnce(AudioDecoderError,) + Send + 'static>>>,
20    pub progress: Option<Box<dyn Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>>,
21    pub ready: Mutex<Option<Box<dyn FnOnce(u32,) + Send + 'static>>>,
22}
23
24impl AudioDecoderCallbacks {
25    pub fn new() -> AudioDecoderCallbacksBuilder {
26        AudioDecoderCallbacksBuilder {
27            eos: None,
28            error: None,
29            progress: None,
30            ready: None,
31        }
32    }
33
34    pub fn eos(&self) {
35        let eos = self.eos.lock().unwrap().take();
36        match eos {
37            None => return,
38            Some(callback) => callback(),
39        };
40    }
41
42    pub fn error(&self, error: AudioDecoderError) {
43        let callback = self.error.lock().unwrap().take();
44        match callback {
45            None => return,
46            Some(callback) => callback(error),
47        };
48    }
49
50    pub fn progress(&self, buffer: Box<dyn AsRef<[f32]>>, channel: u32) {
51        match self.progress {
52            None => return,
53            Some(ref callback) => callback(buffer, channel),
54        };
55    }
56
57    pub fn ready(&self, channels: u32) {
58        let ready = self.ready.lock().unwrap().take();
59        match ready {
60            None => return,
61            Some(callback) => callback(channels),
62        };
63    }
64}
65
66pub struct AudioDecoderCallbacksBuilder {
67    eos: Option<Box<dyn FnOnce() + Send + 'static>>,
68    error: Option<Box<dyn FnOnce(AudioDecoderError,) + Send + 'static>>,
69    progress: Option<Box<dyn Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>>,
70    ready: Option<Box<dyn FnOnce(u32,) + Send + 'static>>,
71}
72
73impl AudioDecoderCallbacksBuilder {
74    pub fn eos<F: FnOnce() + Send + 'static>(self, eos: F) -> Self {
75        Self {
76            eos: Some(Box::new(eos)),
77            ..self
78        }
79    }
80
81    pub fn error<F: FnOnce(AudioDecoderError) + Send + 'static>(self, error: F) -> Self {
82        Self {
83            error: Some(Box::new(error)),
84            ..self
85        }
86    }
87
88    pub fn progress<F: Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>(
89        self,
90        progress: F,
91    ) -> Self {
92        Self {
93            progress: Some(Box::new(progress)),
94            ..self
95        }
96    }
97
98    pub fn ready<F: FnOnce(u32) + Send + 'static>(self, ready: F) -> Self {
99        Self {
100            ready: Some(Box::new(ready)),
101            ..self
102        }
103    }
104
105    pub fn build(self) -> AudioDecoderCallbacks {
106        AudioDecoderCallbacks {
107            eos: Mutex::new(self.eos),
108            error: Mutex::new(self.error),
109            progress: self.progress,
110            ready: Mutex::new(self.ready),
111        }
112    }
113}
114
115pub struct AudioDecoderOptions {
116    pub sample_rate: f32,
117}
118
119impl Default for AudioDecoderOptions {
120    fn default() -> Self {
121        AudioDecoderOptions {
122            sample_rate: 44100.,
123        }
124    }
125}
126
127pub trait AudioDecoder {
128    fn decode(
129        &self,
130        data: Vec<u8>,
131        callbacks: AudioDecoderCallbacks,
132        options: Option<AudioDecoderOptions>,
133    );
134}