ReSet_Lib/audio/
audio.rs

1use dbus::{
2    arg::{self, Append, Arg, ArgType, Get},
3    Signature,
4};
5use pulse::context::introspect::{
6    CardInfo, CardProfileInfo, SinkInfo, SinkInputInfo, SourceInfo, SourceOutputInfo,
7};
8
9use crate::network::connection::Enum;
10
11#[derive(Debug)]
12pub struct PulseError(pub &'static str);
13
14#[derive(Debug, Clone, Default)]
15pub enum DeviceState {
16    #[default]
17    Idle,
18    Invalid,
19    Suspended,
20    Running,
21}
22
23impl Enum for DeviceState {
24    fn from_i32(num: i32) -> Self {
25        match num {
26            0 => DeviceState::Idle,
27            1 => DeviceState::Invalid,
28            2 => DeviceState::Suspended,
29            _ => DeviceState::Running,
30        }
31    }
32
33    fn to_i32(&self) -> i32 {
34        match self {
35            DeviceState::Idle => 0,
36            DeviceState::Invalid => 1,
37            DeviceState::Suspended => 2,
38            DeviceState::Running => 3,
39        }
40    }
41}
42
43#[derive(Debug, Clone, Default)]
44pub struct Source {
45    pub index: u32,
46    pub name: String,
47    pub alias: String,
48    pub channels: u16,
49    pub volume: Vec<u32>,
50    pub muted: bool,
51    pub active: i32,
52}
53
54unsafe impl Send for Source {}
55unsafe impl Sync for Source {}
56
57impl Append for Source {
58    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
59        iter.append_struct(|i| {
60            i.append(self.index);
61            i.append(&self.name);
62            i.append(&self.alias);
63            i.append(self.channels);
64            i.append(&self.volume);
65            i.append(self.muted);
66            i.append(self.active);
67        });
68    }
69}
70
71impl<'a> Get<'a> for Source {
72    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
73        let (index, name, alias, channels, volume, muted, active) =
74            <(u32, String, String, u16, Vec<u32>, bool, i32)>::get(i)?;
75        Some(Self {
76            index,
77            name,
78            alias,
79            channels,
80            volume,
81            muted,
82            active,
83        })
84    }
85}
86
87impl Arg for Source {
88    const ARG_TYPE: arg::ArgType = ArgType::Struct;
89    fn signature() -> Signature<'static> {
90        unsafe { Signature::from_slice_unchecked("(ussqaubi)\0") }
91    }
92}
93
94impl From<&SourceInfo<'_>> for Source {
95    fn from(value: &SourceInfo<'_>) -> Self {
96        let name_opt = &value.name;
97        let alias_opt = &value.description;
98        let name: String;
99        let alias: String;
100        if name_opt.is_none() {
101            name = String::from("");
102        } else {
103            name = String::from(name_opt.clone().unwrap());
104        }
105        if alias_opt.is_none() {
106            alias = String::from("");
107        } else {
108            alias = String::from(alias_opt.clone().unwrap());
109        }
110        let index = value.index;
111        let channels = value.channel_map.len() as u16;
112        let mut volume = vec![0; channels as usize];
113        for i in 0..channels as usize {
114            unsafe { *volume.get_unchecked_mut(i) = value.volume.get()[i].0 };
115        }
116        let muted = value.mute;
117        let active = value.state as i32;
118        Self {
119            index,
120            name,
121            alias,
122            channels,
123            volume,
124            muted,
125            active,
126        }
127    }
128}
129
130#[derive(Debug, Clone, Default)]
131pub struct Sink {
132    pub index: u32,
133    pub name: String,
134    pub alias: String,
135    pub channels: u16,
136    pub volume: Vec<u32>,
137    pub muted: bool,
138    pub active: i32,
139}
140
141unsafe impl Send for Sink {}
142unsafe impl Sync for Sink {}
143
144impl Append for Sink {
145    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
146        iter.append_struct(|i| {
147            i.append(self.index);
148            i.append(&self.name);
149            i.append(&self.alias);
150            i.append(self.channels);
151            i.append(&self.volume);
152            i.append(self.muted);
153            i.append(self.active);
154        });
155    }
156}
157
158impl<'a> Get<'a> for Sink {
159    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
160        let (index, name, alias, channels, volume, muted, active) =
161            <(u32, String, String, u16, Vec<u32>, bool, i32)>::get(i)?;
162        Some(Self {
163            index,
164            name,
165            alias,
166            channels,
167            volume,
168            muted,
169            active,
170        })
171    }
172}
173
174impl Arg for Sink {
175    const ARG_TYPE: arg::ArgType = ArgType::Struct;
176    fn signature() -> Signature<'static> {
177        unsafe { Signature::from_slice_unchecked("(ussqaubi)\0") }
178    }
179}
180
181impl From<&SinkInfo<'_>> for Sink {
182    fn from(value: &SinkInfo<'_>) -> Self {
183        let name_opt = &value.name;
184        let alias_opt = &value.description;
185        let name: String;
186        let alias: String;
187        if name_opt.is_none() {
188            name = String::from("");
189        } else {
190            name = String::from(name_opt.clone().unwrap());
191        }
192        if alias_opt.is_none() {
193            alias = String::from("");
194        } else {
195            alias = String::from(alias_opt.clone().unwrap());
196        }
197        let index = value.index;
198        let channels = value.channel_map.len() as u16;
199        let mut volume = vec![0; channels as usize];
200        for i in 0..channels as usize {
201            unsafe { *volume.get_unchecked_mut(i) = value.volume.get()[i].0 };
202        }
203        let muted = value.mute;
204        let active = value.mute as i32;
205        Self {
206            index,
207            name,
208            alias,
209            channels,
210            volume,
211            muted,
212            active,
213        }
214    }
215}
216
217#[derive(Debug, Clone, Default)]
218pub struct InputStream {
219    pub index: u32,
220    pub name: String,
221    pub application_name: String,
222    pub sink_index: u32,
223    pub channels: u16,
224    pub volume: Vec<u32>,
225    pub muted: bool,
226    pub corked: bool,
227}
228
229impl Append for InputStream {
230    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
231        iter.append_struct(|i| {
232            i.append(self.index);
233            i.append(&self.name);
234            i.append(&self.application_name);
235            i.append(self.sink_index);
236            i.append(self.channels);
237            i.append(&self.volume);
238            i.append(self.muted);
239            i.append(self.corked);
240        });
241    }
242}
243
244impl<'a> Get<'a> for InputStream {
245    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
246        let (index, name, application_name, sink_index, channels, volume, muted, corked) =
247            <(u32, String, String, u32, u16, Vec<u32>, bool, bool)>::get(i)?;
248        Some(Self {
249            index,
250            name,
251            application_name,
252            sink_index,
253            channels,
254            volume,
255            muted,
256            corked,
257        })
258    }
259}
260
261impl Arg for InputStream {
262    const ARG_TYPE: arg::ArgType = ArgType::Struct;
263    fn signature() -> Signature<'static> {
264        unsafe { Signature::from_slice_unchecked("(ussuqaubb)\0") }
265    }
266}
267
268impl From<&SinkInputInfo<'_>> for InputStream {
269    fn from(value: &SinkInputInfo<'_>) -> Self {
270        let name_opt = &value.name;
271        let name: String;
272        if name_opt.is_none() {
273            name = String::from("");
274        } else {
275            name = String::from(name_opt.clone().unwrap());
276        }
277        let application_name = value
278            .proplist
279            .get_str("application.name")
280            .unwrap_or_default();
281        let sink_index = value.sink;
282        let index = value.index;
283        let channels = value.channel_map.len() as u16;
284        let mut volume = vec![0; channels as usize];
285        for i in 0..channels as usize {
286            unsafe { *volume.get_unchecked_mut(i) = value.volume.get()[i].0 };
287        }
288        let muted = value.mute;
289        let corked = value.corked;
290        Self {
291            index,
292            name,
293            application_name,
294            sink_index,
295            channels,
296            volume,
297            muted,
298            corked,
299        }
300    }
301}
302
303#[derive(Debug, Clone, Default)]
304pub struct OutputStream {
305    pub index: u32,
306    pub name: String,
307    pub application_name: String,
308    pub source_index: u32,
309    pub channels: u16,
310    pub volume: Vec<u32>,
311    pub muted: bool,
312    pub corked: bool,
313}
314
315impl Append for OutputStream {
316    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
317        iter.append_struct(|i| {
318            i.append(self.index);
319            i.append(&self.name);
320            i.append(&self.application_name);
321            i.append(self.source_index);
322            i.append(self.channels);
323            i.append(&self.volume);
324            i.append(self.muted);
325            i.append(self.corked);
326        });
327    }
328}
329
330impl<'a> Get<'a> for OutputStream {
331    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
332        let (index, name, application_name, source_index, channels, volume, muted, corked) =
333            <(u32, String, String, u32, u16, Vec<u32>, bool, bool)>::get(i)?;
334        Some(Self {
335            index,
336            name,
337            application_name,
338            source_index,
339            channels,
340            volume,
341            muted,
342            corked,
343        })
344    }
345}
346
347impl Arg for OutputStream {
348    const ARG_TYPE: arg::ArgType = ArgType::Struct;
349    fn signature() -> Signature<'static> {
350        unsafe { Signature::from_slice_unchecked("(ussuqaubb)\0") }
351    }
352}
353
354impl From<&SourceOutputInfo<'_>> for OutputStream {
355    fn from(value: &SourceOutputInfo<'_>) -> Self {
356        let name_opt = &value.name;
357        let name: String;
358        if name_opt.is_none() {
359            name = String::from("");
360        } else {
361            name = String::from(name_opt.clone().unwrap());
362        }
363        let application_name = value
364            .proplist
365            .get_str("application.name")
366            .unwrap_or_default();
367        let source_index = value.source;
368        let index = value.index;
369        let channels = value.channel_map.len() as u16;
370        let mut volume = vec![0; channels as usize];
371        for i in 0..channels as usize {
372            unsafe { *volume.get_unchecked_mut(i) = value.volume.get()[i].0 };
373        }
374        let muted = value.mute;
375        let corked = value.corked;
376        Self {
377            index,
378            name,
379            application_name,
380            source_index,
381            channels,
382            volume,
383            muted,
384            corked,
385        }
386    }
387}
388
389#[derive(Debug, Clone, Default)]
390pub struct Card {
391    pub index: u32,
392    pub name: String,
393    pub profiles: Vec<CardProfile>,
394    pub active_profile: String,
395}
396
397impl Append for Card {
398    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
399        iter.append_struct(|i| {
400            i.append(self.index);
401            i.append(&self.name);
402            i.append(&self.profiles);
403            i.append(&self.active_profile);
404        });
405    }
406}
407
408impl<'a> Get<'a> for Card {
409    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
410        let (index, name, profiles, active_profile) =
411            <(u32, String, Vec<CardProfile>, String)>::get(i)?;
412        Some(Self {
413            index,
414            name,
415            profiles,
416            active_profile,
417        })
418    }
419}
420
421impl Arg for Card {
422    const ARG_TYPE: arg::ArgType = ArgType::Struct;
423    fn signature() -> Signature<'static> {
424        unsafe { Signature::from_slice_unchecked("(usa(ssb)s)\0") }
425    }
426}
427
428impl From<&CardInfo<'_>> for Card {
429    fn from(value: &CardInfo<'_>) -> Self {
430        let name_opt = &value.proplist.get_str("alsa.card_name");
431        let name: String;
432        if name_opt.is_none() {
433            name = String::from("Unnamed");
434        } else {
435            name = name_opt.clone().unwrap();
436        }
437        let index = value.index;
438        let mut profiles = Vec::new();
439        for profile in value.profiles.iter() {
440            profiles.push(CardProfile::from(profile));
441        }
442        let profile_opt = value.active_profile.as_ref();
443        let active_profile: String;
444        if profile_opt.is_none() {
445            active_profile = String::from("Off");
446        } else {
447            active_profile = profile_opt.unwrap().name.clone().unwrap().to_string();
448        }
449        Self {
450            index,
451            name,
452            profiles,
453            active_profile,
454        }
455    }
456}
457
458#[derive(Debug, Clone, Default)]
459pub struct CardProfile {
460    pub name: String,
461    pub description: String,
462    pub available: bool,
463}
464
465impl Append for CardProfile {
466    fn append_by_ref(&self, iter: &mut arg::IterAppend) {
467        iter.append_struct(|i| {
468            i.append(&self.name);
469            i.append(&self.description);
470            i.append(self.available);
471        });
472    }
473}
474
475impl<'a> Get<'a> for CardProfile {
476    fn get(i: &mut arg::Iter<'a>) -> Option<Self> {
477        let (name, description, available) = <(String, String, bool)>::get(i)?;
478        Some(Self {
479            name,
480            description,
481            available,
482        })
483    }
484}
485
486impl Arg for CardProfile {
487    const ARG_TYPE: arg::ArgType = ArgType::Struct;
488    fn signature() -> Signature<'static> {
489        unsafe { Signature::from_slice_unchecked("(ssb)\0") }
490    }
491}
492
493impl From<&CardProfileInfo<'_>> for CardProfile {
494    fn from(value: &CardProfileInfo<'_>) -> Self {
495        let name_opt = &value.name;
496        let name: String;
497        if name_opt.is_none() {
498            name = String::from("");
499        } else {
500            name = String::from(name_opt.clone().unwrap());
501        }
502        let description_opt = &value.description;
503        let description: String;
504        if description_opt.is_none() {
505            description = String::from("");
506        } else {
507            description = String::from(description_opt.clone().unwrap());
508        }
509        let available = value.available;
510        Self {
511            name,
512            description,
513            available,
514        }
515    }
516}