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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use std::sync::Mutex;

#[derive(Debug, PartialEq)]
pub enum AudioDecoderError {
    /// Backend specific error.
    Backend(String),
    /// Could not read the audio buffer content.
    BufferReadFailed,
    /// The media trying to be decoded has an invalid format.
    InvalidMediaFormat,
    /// An invalid sample was found while decoding the audio.
    InvalidSample,
    /// Could not move to a different state.
    StateChangeFailed,
}

pub struct AudioDecoderCallbacks {
    pub eos: Mutex<Option<Box<dyn FnOnce() + Send + 'static>>>,
    pub error: Mutex<Option<Box<dyn FnOnce(AudioDecoderError,) + Send + 'static>>>,
    pub progress: Option<Box<dyn Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>>,
    pub ready: Mutex<Option<Box<dyn FnOnce(u32,) + Send + 'static>>>,
}

impl AudioDecoderCallbacks {
    pub fn new() -> AudioDecoderCallbacksBuilder {
        AudioDecoderCallbacksBuilder {
            eos: None,
            error: None,
            progress: None,
            ready: None,
        }
    }

    pub fn eos(&self) {
        let eos = self.eos.lock().unwrap().take();
        match eos {
            None => return,
            Some(callback) => callback(),
        };
    }

    pub fn error(&self, error: AudioDecoderError) {
        let callback = self.error.lock().unwrap().take();
        match callback {
            None => return,
            Some(callback) => callback(error),
        };
    }

    pub fn progress(&self, buffer: Box<dyn AsRef<[f32]>>, channel: u32) {
        match self.progress {
            None => return,
            Some(ref callback) => callback(buffer, channel),
        };
    }

    pub fn ready(&self, channels: u32) {
        let ready = self.ready.lock().unwrap().take();
        match ready {
            None => return,
            Some(callback) => callback(channels),
        };
    }
}

pub struct AudioDecoderCallbacksBuilder {
    eos: Option<Box<dyn FnOnce() + Send + 'static>>,
    error: Option<Box<dyn FnOnce(AudioDecoderError,) + Send + 'static>>,
    progress: Option<Box<dyn Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>>,
    ready: Option<Box<dyn FnOnce(u32,) + Send + 'static>>,
}

impl AudioDecoderCallbacksBuilder {
    pub fn eos<F: FnOnce() + Send + 'static>(self, eos: F) -> Self {
        Self {
            eos: Some(Box::new(eos)),
            ..self
        }
    }

    pub fn error<F: FnOnce(AudioDecoderError) + Send + 'static>(self, error: F) -> Self {
        Self {
            error: Some(Box::new(error)),
            ..self
        }
    }

    pub fn progress<F: Fn(Box<dyn AsRef<[f32]>>, u32) + Send + Sync + 'static>(
        self,
        progress: F,
    ) -> Self {
        Self {
            progress: Some(Box::new(progress)),
            ..self
        }
    }

    pub fn ready<F: FnOnce(u32) + Send + 'static>(self, ready: F) -> Self {
        Self {
            ready: Some(Box::new(ready)),
            ..self
        }
    }

    pub fn build(self) -> AudioDecoderCallbacks {
        AudioDecoderCallbacks {
            eos: Mutex::new(self.eos),
            error: Mutex::new(self.error),
            progress: self.progress,
            ready: Mutex::new(self.ready),
        }
    }
}

pub struct AudioDecoderOptions {
    pub sample_rate: f32,
}

impl Default for AudioDecoderOptions {
    fn default() -> Self {
        AudioDecoderOptions {
            sample_rate: 44100.,
        }
    }
}

pub trait AudioDecoder {
    fn decode(
        &self,
        data: Vec<u8>,
        callbacks: AudioDecoderCallbacks,
        options: Option<AudioDecoderOptions>,
    );
}