servo_media_audio/
decoder.rs

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