audio_device/alsa/
enums.rs

1use crate::alsa::Result;
2use crate::libc as c;
3use alsa_sys as alsa;
4use std::fmt;
5
6macro_rules! decl_enum {
7    (
8        $(#[doc = $doc:literal])*
9        #[repr($ty:ident)]
10        $vis:vis enum $name:ident {
11            $(
12                $(#[$m:meta])*
13                $a:ident = $b:ident
14            ),* $(,)?
15        }
16    ) => {
17        $(#[doc = $doc])*
18        #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19        #[non_exhaustive]
20        #[repr($ty)]
21        $vis enum $name {
22            $(
23                $(#[$m])*
24                #[allow(missing_docs)]
25                $a = alsa::$b,
26            )*
27        }
28
29        impl $name {
30            /// Parse the given enum from a value.
31            $vis fn from_value(value: $ty) -> Option<Self> {
32                Some(match value {
33                    $(alsa::$b => Self::$a,)*
34                    _ => return None,
35                })
36            }
37        }
38
39        impl fmt::Display for $name {
40            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41                let id = match self {
42                    $(Self::$a => stringify!($a),)*
43                };
44
45                f.write_str(id)
46            }
47        }
48    }
49}
50
51/// The direction in which updated hardware parameters is restricted unless the
52/// exact value is available.
53#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
54#[repr(i32)]
55pub enum Direction {
56    /// Accept smaller values.
57    Smaller = -1,
58    /// Accept the nearest value.
59    Nearest = 0,
60    /// Accept greater values.
61    Greater = 1,
62}
63
64impl Direction {
65    pub(super) fn from_value(value: i32) -> Self {
66        match value {
67            -1 => Self::Smaller,
68            0 => Self::Nearest,
69            _ => Self::Greater,
70        }
71    }
72}
73
74decl_enum! {
75    /// The state of the [Pcm][super::Pcm].
76    #[repr(u32)]
77    pub enum State {
78        /// Open.
79        Open = SND_PCM_STATE_OPEN,
80        /// Setup installed.
81        Setup = SND_PCM_STATE_SETUP,
82        /// Ready to start.
83        Prepare = SND_PCM_STATE_PREPARED,
84        /// Running.
85        Running = SND_PCM_STATE_RUNNING,
86        /// Stopped: underrun (playback) or overrun (capture) detected.
87        Xrun = SND_PCM_STATE_XRUN,
88        /// Draining: running (playback) or stopped (capture).
89        Draining = SND_PCM_STATE_DRAINING,
90        /// Paused.
91        Paused = SND_PCM_STATE_PAUSED,
92        /// Hardware is suspended.
93        Suspended = SND_PCM_STATE_SUSPENDED,
94        /// Hardware is disconnected.
95        Disconnected = SND_PCM_STATE_DISCONNECTED,
96        /// Private - used internally in the library - do not use.
97        Private1 = SND_PCM_STATE_PRIVATE1,
98    }
99}
100
101decl_enum! {
102    /// Defines the supported format of a stream.
103    #[repr(i32)]
104    pub enum Format {
105        Unknown = SND_PCM_FORMAT_UNKNOWN,
106        S8 = SND_PCM_FORMAT_S8,
107        U8 = SND_PCM_FORMAT_U8,
108        S16LE = SND_PCM_FORMAT_S16_LE,
109        S16BE = SND_PCM_FORMAT_S16_BE,
110        U16LE = SND_PCM_FORMAT_U16_LE,
111        U16BE = SND_PCM_FORMAT_U16_BE,
112        S24LE = SND_PCM_FORMAT_S24_LE,
113        S24BE = SND_PCM_FORMAT_S24_BE,
114        U24LE = SND_PCM_FORMAT_U24_LE,
115        U24BE = SND_PCM_FORMAT_U24_BE,
116        S32LE = SND_PCM_FORMAT_S32_LE,
117        S32BE = SND_PCM_FORMAT_S32_BE,
118        U32LE = SND_PCM_FORMAT_U32_LE,
119        U32BE = SND_PCM_FORMAT_U32_BE,
120        FloatLE = SND_PCM_FORMAT_FLOAT_LE,
121        FloatBE = SND_PCM_FORMAT_FLOAT_BE,
122        Float64LE = SND_PCM_FORMAT_FLOAT64_LE,
123        Float64BE = SND_PCM_FORMAT_FLOAT64_BE,
124        IEC958SubframeLE = SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
125        IEC958SubframeBE = SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
126        MuLaw = SND_PCM_FORMAT_MU_LAW,
127        ALaw = SND_PCM_FORMAT_A_LAW,
128        ImaAdPCM = SND_PCM_FORMAT_IMA_ADPCM,
129        MPEG = SND_PCM_FORMAT_MPEG,
130        GSM = SND_PCM_FORMAT_GSM,
131        Special = SND_PCM_FORMAT_SPECIAL,
132        S243LE = SND_PCM_FORMAT_S24_3LE,
133        S243BE = SND_PCM_FORMAT_S24_3BE,
134        U243LE = SND_PCM_FORMAT_U24_3LE,
135        U243BE = SND_PCM_FORMAT_U24_3BE,
136        S203LE = SND_PCM_FORMAT_S20_3LE,
137        S203BE = SND_PCM_FORMAT_S20_3BE,
138        U203LE = SND_PCM_FORMAT_U20_3LE,
139        U203BE = SND_PCM_FORMAT_U20_3BE,
140        S183LE = SND_PCM_FORMAT_S18_3LE,
141        S183BE = SND_PCM_FORMAT_S18_3BE,
142        U183LE = SND_PCM_FORMAT_U18_3LE,
143        U183BE = SND_PCM_FORMAT_U18_3BE,
144        G72324 = SND_PCM_FORMAT_G723_24,
145        G723241B = SND_PCM_FORMAT_G723_24_1B,
146        G72340 = SND_PCM_FORMAT_G723_40,
147        G723401B = SND_PCM_FORMAT_G723_40_1B,
148        DSDU8 = SND_PCM_FORMAT_DSD_U8,
149        DSDU16LE = SND_PCM_FORMAT_DSD_U16_LE,
150        DSDU32LE = SND_PCM_FORMAT_DSD_U32_LE,
151        DSDU16BE = SND_PCM_FORMAT_DSD_U16_BE,
152        DSDU32BE = SND_PCM_FORMAT_DSD_U32_BE,
153    }
154}
155
156impl Format {
157    /// Return bits needed to store a PCM sample.
158    ///
159    /// # Examples
160    ///
161    /// ```rust
162    /// use audio_device::alsa;
163    ///
164    /// # fn main() -> anyhow::Result<()> {
165    /// assert_eq!(alsa::Format::U8.physical_width()?, 8);
166    /// assert_eq!(alsa::Format::S16LE.physical_width()?, 16);
167    /// assert_eq!(alsa::Format::S243LE.physical_width()?, 24);
168    /// # Ok(()) }
169    /// ```
170    pub fn physical_width(self) -> Result<usize> {
171        unsafe { Ok(errno!(alsa::snd_pcm_format_physical_width(self as c::c_int))? as usize) }
172    }
173}
174
175decl_enum! {
176    /// Defines the direction of a stream.
177    ///
178    /// See [Pcm::open][super::Pcm::open].
179    #[repr(u32)]
180    pub enum Stream {
181        /// A capture stream. Corresponds to `SND_PCM_STREAM_CAPTURE`.
182        Capture = SND_PCM_STREAM_CAPTURE,
183        /// A playback stream. Corresponds to `SND_PCM_STREAM_PLAYBACK`.
184        Playback = SND_PCM_STREAM_PLAYBACK,
185    }
186}
187
188decl_enum! {
189    /// Defines how the underlying device is accessed.
190    #[repr(u32)]
191    pub enum Access {
192        /// MMAP access with simple interleaved channels
193        MmapInterleaved = SND_PCM_ACCESS_MMAP_INTERLEAVED,
194        /// MMAP access with simple non interleaved channels
195        MmapNoninterleaved = SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
196        /// MMAP access with complex placement
197        MmapComplex = SND_PCM_ACCESS_MMAP_COMPLEX,
198        /// Interleaved read/write access
199        ReadWriteInterleaved = SND_PCM_ACCESS_RW_INTERLEAVED,
200        /// Sequential read/write access
201        ReadWriteNoninterleaved = SND_PCM_ACCESS_RW_NONINTERLEAVED,
202    }
203}
204
205decl_enum! {
206    /// Defines if timestamps are enabled or not.
207    #[repr(u32)]
208    pub enum Timestamp {
209        /// No timestamp.
210        None = SND_PCM_TSTAMP_NONE,
211        //// Update timestamp at every hardware position update.
212        Enable = SND_PCM_TSTAMP_ENABLE,
213    }
214}
215
216decl_enum! {
217    /// Defines the type of timestamp that is available.
218    #[repr(u32)]
219    pub enum TimestampType {
220        /// gettimeofday equivalent
221        GetTimeOfDay = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY,
222        /// posix_clock_monotonic equivalent
223        Monotonic = SND_PCM_TSTAMP_TYPE_MONOTONIC,
224        /// monotonic_raw (no NTP)
225        MonotonicRaw = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
226    }
227}