audio_device/alsa/
access_mask.rs

1use crate::alsa::{Access, Result};
2use crate::libc as c;
3use alsa_sys as alsa;
4use std::mem;
5use std::ptr;
6
7/// Access 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::AccessMask::new()?;
16/// assert!(!mask.test(alsa::Access::MmapInterleaved));
17/// assert!(mask.is_empty());
18///
19/// mask.set(alsa::Access::MmapInterleaved);
20/// assert!(!mask.is_empty());
21/// assert!(mask.test(alsa::Access::MmapInterleaved));
22///
23/// mask.reset(alsa::Access::MmapInterleaved);
24/// assert!(!mask.test(alsa::Access::MmapInterleaved));
25/// assert!(mask.is_empty());
26/// # Ok(()) }
27/// ```
28pub struct AccessMask {
29    pub(super) handle: ptr::NonNull<alsa::snd_pcm_access_mask_t>,
30}
31
32impl AccessMask {
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::AccessMask::new()?;
42    /// assert!(!mask.test(alsa::Access::MmapInterleaved));
43    /// # Ok(()) }
44    /// ```
45    pub fn new() -> Result<Self> {
46        unsafe {
47            let mut mask = Self::allocate()?;
48            alsa::snd_pcm_access_mask_none(mask.handle.as_mut());
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_access_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 [AccessMask] documentation.
64    pub fn is_empty(&self) -> bool {
65        unsafe { alsa::snd_pcm_access_mask_empty(self.handle.as_ptr()) == 1 }
66    }
67
68    /// Set all bits.
69    ///
70    /// See [AccessMask] documentation.
71    pub fn any(&mut self) {
72        unsafe {
73            alsa::snd_pcm_access_mask_any(self.handle.as_mut());
74        }
75    }
76
77    /// Reset all bits.
78    ///
79    /// See [AccessMask] documentation.
80    pub fn none(&mut self) {
81        unsafe {
82            alsa::snd_pcm_access_mask_none(self.handle.as_mut());
83        }
84    }
85
86    /// Make an access type present.
87    ///
88    /// See [AccessMask] documentation.
89    pub fn set(&mut self, access: Access) {
90        unsafe {
91            alsa::snd_pcm_access_mask_set(self.handle.as_mut(), access as c::c_uint);
92        }
93    }
94
95    /// Make an access type missing.
96    ///
97    /// See [AccessMask] documentation.
98    pub fn reset(&mut self, access: Access) {
99        unsafe {
100            alsa::snd_pcm_access_mask_reset(self.handle.as_mut(), access as c::c_uint);
101        }
102    }
103
104    /// Test the presence of an access type.
105    ///
106    /// See [AccessMask] documentation.
107    pub fn test(&mut self, access: Access) -> bool {
108        unsafe { alsa::snd_pcm_access_mask_test(self.handle.as_mut(), access as c::c_uint) == 1 }
109    }
110
111    /// Copy one mask to another.
112    pub fn copy(&mut self, other: &Self) {
113        unsafe {
114            alsa::snd_pcm_access_mask_copy(self.handle.as_mut(), other.handle.as_ptr());
115        }
116    }
117}
118
119impl Drop for AccessMask {
120    fn drop(&mut self) {
121        unsafe {
122            let _ = alsa::snd_pcm_access_mask_free(self.handle.as_mut());
123        }
124    }
125}