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}