audio_device/alsa/
mod.rs

1//! An idiomatic Rust ALSA interface.
2
3use crate::libc as c;
4use crate::unix::errno::Errno;
5use std::io;
6use std::ops;
7use thiserror::Error;
8
9/// A string allocated through libc.
10#[repr(transparent)]
11pub struct CString {
12    ptr: *mut c::c_char,
13}
14
15impl CString {
16    /// Construct a new string that was allocated through libc.
17    ///
18    /// This differs from [std::ffi::CString] in that it requires the underlying
19    /// string to have been allocated using libc allocators, and will free the
20    /// underlying string using those as well.
21    pub unsafe fn from_raw(ptr: *mut c::c_char) -> Self {
22        Self { ptr }
23    }
24}
25
26impl Drop for CString {
27    fn drop(&mut self) {
28        unsafe {
29            c::free(self.ptr as *mut _);
30        }
31    }
32}
33
34impl ops::Deref for CString {
35    type Target = std::ffi::CStr;
36
37    fn deref(&self) -> &Self::Target {
38        unsafe { std::ffi::CStr::from_ptr(self.ptr) }
39    }
40}
41
42// Safety: string is allocated with the libc allocator and can be freely shared
43// across threads.
44unsafe impl Send for CString {}
45unsafe impl Sync for CString {}
46
47/// Errors that can be raised by the ALSA layer.
48#[derive(Debug, Error)]
49pub enum Error {
50    /// System error.
51    #[error("system error: {0}")]
52    Sys(#[from] Errno),
53    /// I/O error.
54    #[error("i/o error: {0}")]
55    Io(
56        #[source]
57        #[from]
58        io::Error,
59    ),
60    /// Error raised when there's a format mismatch between an underlying stream
61    /// and the type attempting to be used with it.
62    #[error("type `{ty}` is not appropriate to use with format `{format}`")]
63    FormatMismatch {
64        /// A description of the type expected.
65        ty: &'static str,
66        /// The format that mismatched.
67        format: Format,
68    },
69    /// Error raised when there's a channel count mismatch between an underlying
70    /// stream and the type attempting to be used with it.
71    #[error("mismatch in number of channels in buffer; actual = {actual}, expected = {expected}")]
72    ChannelsMismatch {
73        /// The actual number of channels.
74        actual: usize,
75        /// The expected number of channels.
76        expected: usize,
77    },
78    /// Underlying function call returned an illegal format identifier.
79    #[error("bad format identifier ({0})")]
80    BadFormat(c::c_int),
81    /// Underlying function call returned an illegal access identifier.
82    #[error("bad access identifier ({0})")]
83    BadAccess(c::c_uint),
84    /// Underlying function call returned an illegal timestamp identifier.
85    #[error("bad timestamp mode identifier ({0})")]
86    BadTimestamp(c::c_uint),
87    /// Underlying function call returned an illegal timestamp type identifier.
88    #[error("bad timestamp type identifier ({0})")]
89    BadTimestampType(c::c_uint),
90    /// Underlying PCM was not set up for polling.
91    #[error("pcm device is not pollable")]
92    MissingPollFds,
93}
94
95/// Helper result wrapper.
96pub type Result<T, E = Error> = ::std::result::Result<T, E>;
97
98mod card;
99pub use self::card::{cards, Card};
100
101mod pcm;
102pub use self::pcm::Pcm;
103
104mod hardware_parameters;
105pub use self::hardware_parameters::{HardwareParameters, HardwareParametersMut};
106
107mod software_parameters;
108pub use self::software_parameters::{SoftwareParameters, SoftwareParametersMut};
109
110mod format_mask;
111pub use self::format_mask::FormatMask;
112
113mod access_mask;
114pub use self::access_mask::AccessMask;
115
116mod enums;
117pub use self::enums::{Access, Direction, Format, State, Stream, Timestamp, TimestampType};
118
119mod channel_area;
120#[doc(hidden)]
121pub use self::channel_area::ChannelArea;
122
123mod writer;
124pub use self::writer::Writer;
125
126cfg_poll_driver! {
127    mod async_writer;
128    pub use self::async_writer::AsyncWriter;
129}
130
131mod sample;
132pub use self::sample::Sample;
133
134mod configurator;
135pub use self::configurator::{Config, Configurator};