audio_device/alsa/
format_mask.rs

1use crate::alsa::{Format, Result};
2use crate::libc as c;
3use alsa_sys as alsa;
4use std::mem;
5use std::ptr;
6
7/// Format mask used in combination with hardware parameters.
8///
9/// # Examples
10///
11/// ```rust
12/// use audio_device::alsa;
13///
14/// # fn main() -> anyhow::Result<()> {
15/// let mut mask = alsa::FormatMask::new()?;
16/// assert!(!mask.test(alsa::Format::S8));
17/// assert!(mask.is_empty());
18///
19/// mask.set(alsa::Format::S8);
20/// assert!(!mask.is_empty());
21/// assert!(mask.test(alsa::Format::S8));
22///
23/// mask.reset(alsa::Format::S8);
24/// assert!(!mask.test(alsa::Format::S8));
25/// assert!(mask.is_empty());
26/// # Ok(()) }
27/// ```
28pub struct FormatMask {
29    pub(super) handle: ptr::NonNull<alsa::snd_pcm_format_mask_t>,
30}
31
32impl FormatMask {
33    /// Construct a new empty access mask.
34    ///
35    /// # Examples
36    ///
37    /// ```rust
38    /// use audio_device::alsa;
39    ///
40    /// # fn main() -> anyhow::Result<()> {
41    /// let mut mask = alsa::FormatMask::new()?;
42    /// assert!(!mask.test(alsa::Format::S8));
43    /// # Ok(()) }
44    /// ```
45    pub fn new() -> Result<Self> {
46        unsafe {
47            let mut mask = Self::allocate()?;
48            mask.none();
49            Ok(mask)
50        }
51    }
52
53    /// Allocate a new access mask. The state of it will be uninitialized.
54    pub(super) unsafe fn allocate() -> Result<Self> {
55        let mut handle = mem::MaybeUninit::uninit();
56        errno!(alsa::snd_pcm_format_mask_malloc(handle.as_mut_ptr()))?;
57        let handle = ptr::NonNull::new_unchecked(handle.assume_init());
58        Ok(Self { handle })
59    }
60
61    /// Test if mask is empty.
62    ///
63    /// See [FormatMask] documentation.
64    pub fn is_empty(&self) -> bool {
65        unsafe { alsa::snd_pcm_format_mask_empty(self.handle.as_ptr()) == 1 }
66    }
67
68    /// Set all bits.
69    ///
70    /// See [FormatMask] documentation.
71    pub fn any(&mut self) {
72        unsafe {
73            alsa::snd_pcm_format_mask_any(self.handle.as_mut());
74        }
75    }
76
77    /// Reset all bits.
78    ///
79    /// See [FormatMask] documentation.
80    pub fn none(&mut self) {
81        unsafe {
82            alsa::snd_pcm_format_mask_none(self.handle.as_mut());
83        }
84    }
85
86    /// Make a format present.
87    ///
88    /// See [FormatMask] documentation.
89    pub fn set(&mut self, format: Format) {
90        unsafe {
91            alsa::snd_pcm_format_mask_set(self.handle.as_mut(), format as c::c_int);
92        }
93    }
94
95    /// Make a format missing.
96    ///
97    /// See [FormatMask] documentation.
98    pub fn reset(&mut self, format: Format) {
99        unsafe {
100            alsa::snd_pcm_format_mask_reset(self.handle.as_mut(), format as c::c_int);
101        }
102    }
103
104    /// Test the presence of a format.
105    ///
106    /// See [FormatMask] documentation.
107    pub fn test(&mut self, format: Format) -> bool {
108        unsafe { alsa::snd_pcm_format_mask_test(self.handle.as_mut(), format as c::c_int) == 1 }
109    }
110
111    /// Copy one mask to another.
112    pub fn copy(&mut self, other: &Self) {
113        unsafe {
114            alsa::snd_pcm_format_mask_copy(self.handle.as_mut(), other.handle.as_ptr());
115        }
116    }
117}
118
119impl Drop for FormatMask {
120    fn drop(&mut self) {
121        unsafe {
122            let _ = alsa::snd_pcm_format_mask_free(self.handle.as_mut());
123        }
124    }
125}