makepad_platform/
audio.rs

1use {
2    crate::{
3        makepad_live_id::{LiveId, FromLiveId},
4    }
5};
6
7pub const MAX_AUDIO_DEVICE_INDEX: usize = 32;
8
9pub type AudioOutputFn = Box<dyn FnMut(AudioInfo, &mut AudioBuffer) + Send + 'static >;
10pub type AudioInputFn = Box<dyn FnMut(AudioInfo, &AudioBuffer) + Send + 'static >;
11
12#[derive(Clone, Debug, Default, Eq, Hash, Copy, PartialEq, FromLiveId)]
13pub struct AudioDeviceId(pub LiveId);
14
15#[derive(Clone, Copy, Debug)]
16pub struct AudioInfo{
17    pub device_id: AudioDeviceId,
18    pub time: Option<AudioTime>
19}
20
21#[derive(Clone, Debug)]
22pub struct AudioDeviceDesc {
23    pub device_id: AudioDeviceId,
24    pub device_type: AudioDeviceType,
25    pub is_default: bool,
26    pub has_failed: bool,
27    pub channel_count: usize,
28    pub name: String,
29}
30
31impl std::fmt::Display for AudioDeviceDesc {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        if self.is_default{
34            write!(f, "[Default ")?;
35        }
36        else{
37            write!(f, "[")?;
38        }
39        if self.device_type.is_input(){
40            write!(f, "Input]")?;
41        }
42        else{
43            write!(f, "Output]")?;
44        }
45        write!(f, " {}", self.name)?;
46        Ok(())
47    }
48}
49
50
51#[derive(Clone, Debug)]
52pub struct AudioDevicesEvent{
53    pub descs: Vec<AudioDeviceDesc>,
54}
55
56impl AudioDevicesEvent{
57    pub fn default_input(&self)->Vec<AudioDeviceId>{
58        for d in &self.descs{
59            if d.is_default && d.device_type.is_input() && !d.has_failed{
60                return vec![d.device_id]
61            }
62        }
63        for d in &self.descs{
64            if d.is_default && d.device_type.is_input(){
65                return vec![d.device_id]
66            }
67        }
68        Vec::new()
69    } 
70    pub fn default_output(&self)->Vec<AudioDeviceId>{
71        for d in &self.descs{
72            if d.is_default && d.device_type.is_output() && !d.has_failed{
73                return vec![d.device_id]
74            }
75        }
76        for d in &self.descs{
77            if d.is_default && d.device_type.is_output(){
78                return vec![d.device_id]
79            }
80        }
81        Vec::new()
82    }
83    
84    pub fn match_outputs(&self, outputs: &[&str])->Vec<AudioDeviceId>{
85        let mut results = Vec::new();
86        for d in &self.descs{
87            if d.device_type.is_output(){
88                for output in outputs{
89                    if d.name.find(output).is_some(){
90                        results.push(d.device_id);
91                        break;
92                    }
93                }
94            }
95        }
96        if results.len() == 0{
97            return self.default_output()
98        }
99        results
100    }
101    
102    pub fn match_inputs(&self, inputs: &[&str])->Vec<AudioDeviceId>{
103        let mut results = Vec::new();
104        for d in &self.descs{
105            if d.device_type.is_input(){
106                for input in inputs{
107                    if d.name.find(input).is_some(){
108                        results.push(d.device_id);
109                    }
110                }
111            }
112        }
113        return results
114    }
115    
116}
117
118impl std::fmt::Display for AudioDevicesEvent {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        let _ = write!(f,"Audio Devices:\n");
121        for d in &self.descs{
122           let _ = write!(f, "{}\n", d);
123        }
124        Ok(())
125    }
126}
127
128
129#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
130pub enum AudioDeviceType {
131    Input,
132    Output,
133}
134
135impl AudioDeviceType{
136    pub fn is_input(&self)->bool{
137        match self{
138            AudioDeviceType::Input=>true,
139            _=>false
140        }
141    }
142    pub fn is_output(&self)->bool{
143        match self{
144            AudioDeviceType::Output=>true,
145            _=>false
146        }
147    }
148}
149
150#[derive(Copy, Clone, Debug)]
151pub struct AudioTime {
152    pub sample_time: f64,
153    pub host_time: u64,
154    pub rate_scalar: f64,
155}
156
157#[derive(Clone, Default)]
158pub struct AudioBuffer {
159    pub data: Vec<f32>,
160    pub final_size: bool,
161    pub frame_count: usize,
162    pub channel_count: usize
163}
164
165impl AudioBuffer {
166    pub fn from_data(data: Vec<f32>, channel_count: usize) -> Self {
167        let frame_count = data.len() / channel_count;
168        Self {
169            data,
170            final_size: false,
171            frame_count,
172            channel_count
173        }
174    }
175    
176    pub fn from_i16(inp: &[i16], channel_count: usize) -> Self {
177        let mut data = Vec::new();
178        data.resize(inp.len(), 0.0);
179        let frame_count = data.len() / channel_count;
180        for i in 0..data.len() {
181            data[i] = (inp[i] as f32) / 32767.0;
182        }
183        Self {
184            data,
185            final_size: false,
186            frame_count,
187            channel_count
188        }
189    }
190    
191    pub fn make_single_channel(&mut self) {
192        self.data.resize(self.frame_count, 0.0);
193        self.channel_count = 1;
194    }
195    
196    pub fn into_data(self) -> Vec<f32> {
197        self.data
198    }
199    
200    pub fn to_i16(&self) -> Vec<i16> {
201        let mut out = Vec::new();
202        out.resize(self.data.len(), 0);
203        for i in 0..self.data.len() {
204            let f = (self.data[i] * 32767.0).max(std::i16::MIN as f32).min(std::i16::MAX as f32);
205            out[i] = f as i16;
206        }
207        out
208    }
209    
210    pub fn new_with_size(frame_count: usize, channel_count: usize) -> Self {
211        let mut ret = Self::default();
212        ret.resize(frame_count, channel_count);
213        ret
214    }
215    
216    pub fn new_like(like: &AudioBuffer) -> Self {
217        let mut ret = Self::default();
218        ret.resize_like(like);
219        ret
220    }
221    
222    pub fn frame_count(&self) -> usize {self.frame_count}
223    pub fn channel_count(&self) -> usize {self.channel_count}
224    
225    
226    pub fn copy_from(&mut self, like: &AudioBuffer) -> &mut Self {
227        self.resize(like.frame_count(), like.channel_count());
228        self.data.copy_from_slice(&like.data);
229        self
230    }
231    
232    pub fn resize_like(&mut self, like: &AudioBuffer) -> &mut Self {
233        self.resize(like.frame_count(), like.channel_count());
234        self
235    }
236    
237    pub fn resize(&mut self, frame_count: usize, channel_count: usize) {
238        if self.frame_count != frame_count || self.channel_count != channel_count {
239            if self.final_size {
240                panic!("Audiobuffer is set to 'final size' and resize is different");
241            }
242            self.frame_count = frame_count;
243            self.channel_count = channel_count;
244            self.data.resize(frame_count * channel_count as usize, 0.0);
245        }
246    }
247    
248    pub fn clear_final_size(&mut self) {
249        self.final_size = false;
250    }
251    
252    pub fn set_final_size(&mut self) {
253        self.final_size = true;
254    }
255    
256    pub fn stereo_mut(&mut self) -> (&mut [f32], &mut [f32]) {
257        if self.channel_count != 2 {panic!()}
258        self.data.split_at_mut(self.frame_count)
259    }
260    
261    pub fn stereo(&self) -> (&[f32], &[f32]) {
262        if self.channel_count != 2 {panic!()}
263        self.data.split_at(self.frame_count)
264    }
265    
266    pub fn channel_mut(&mut self, channel: usize) -> &mut [f32] {
267        &mut self.data[channel * self.frame_count..(channel + 1) * self.frame_count]
268    }
269    
270    pub fn channel(&self, channel: usize) -> &[f32] {
271        &self.data[channel * self.frame_count..(channel + 1) * self.frame_count]
272    }
273    
274    pub fn zero(&mut self) {
275        for i in 0..self.data.len() {
276            self.data[i] = 0.0;
277        }
278    }
279    
280    pub fn copy_from_interleaved(&mut self, channel_count:usize, interleaved:&[f32]){
281        let frame_count = interleaved.len() / channel_count;
282        self.resize(frame_count, channel_count);
283        for i in 0..frame_count {
284            for j in 0..channel_count{
285                self.data[i + j * frame_count] = interleaved[i * channel_count + j];
286            }
287        }
288    }
289
290    pub fn copy_to_interleaved(&self, interleaved:&mut [f32]){
291        if interleaved.len() != self.frame_count * self.channel_count{
292            panic!()
293        }
294        for i in 0..self.frame_count {
295            for j in 0..self.channel_count{
296                interleaved[i * self.channel_count + j] = self.data[i + j * self.frame_count];
297            }
298        }
299    }
300}
301