1 //! Thin but safe wrappers for [ALSA](http://http://alsa-project.org). 2 //! 3 //! [Github repo](https://github.com/diwic/alsa-rs) 4 //! 5 //! [Crates.io](https://crates.io/crates/alsa) 6 //! 7 //! This ALSA API wrapper/binding is WIP - the ALSA API is huge, and new 8 //! functions and structs might be added as requested. 9 //! 10 //! Most functions map 1-to-1 to alsa-lib functions, e g, `ctl::CardInfo::get_id()` is a wrapper around 11 //! `snd_ctl_card_info_get_id` and the [alsa-lib documentation](http://www.alsa-project.org/alsa-doc/alsa-lib/) 12 //! can be consulted for additional information. 13 //! 14 //! Enjoy! 15 16 extern crate alsa_sys as alsa; 17 extern crate libc; 18 #[macro_use] 19 extern crate bitflags; 20 #[macro_use] 21 extern crate nix; 22 23 macro_rules! alsa_enum { 24 ($(#[$attr:meta])+ $name:ident, $static_name:ident [$count:expr], $( $a:ident = $b:ident),* ,) => 25 { 26 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 27 $(#[$attr])* 28 pub enum $name { 29 $( 30 $a = alsa::$b as isize, 31 )* 32 } 33 34 static $static_name: [$name; $count] = 35 [ $( $name::$a, )* ]; 36 37 impl $name { 38 /// Returns a slice of all possible values; useful for iteration 39 pub fn all() -> &'static [$name] { &$static_name[..] } 40 41 #[allow(dead_code)] 42 fn from_c_int(c: ::libc::c_int, s: &'static str) -> Result<$name> { 43 Self::all().iter().find(|&&x| c == x as ::libc::c_int).map(|&x| x) 44 .ok_or_else(|| Error::unsupported(s)) 45 } 46 } 47 48 } 49 } 50 51 /// Replaces constants ending with PLAYBACK/CAPTURE as well as 52 /// INPUT/OUTPUT 53 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 54 pub enum Direction { 55 Playback, 56 Capture 57 } 58 impl Direction { 59 #[inline] 60 pub fn input() -> Direction { Direction::Capture } 61 #[inline] 62 pub fn output() -> Direction { Direction::Playback } 63 } 64 65 /// Used to restrict hw parameters. In case the submitted 66 /// value is unavailable, in which direction should one search 67 /// for available values? 68 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 69 pub enum ValueOr { 70 /// The value set is the submitted value, or less 71 Less = -1, 72 /// The value set is the submitted value, or the nearest 73 Nearest = 0, 74 /// The value set is the submitted value, or greater 75 Greater = 1, 76 } 77 78 /// Rounding mode (used in some mixer related calls) 79 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 80 pub enum Round { 81 /// Round down (towards negative infinity) 82 Floor = 0, 83 /// Round up (towards positive infinity) 84 Ceil = 1, 85 } 86 87 mod error; 88 pub use error::{Error, Result}; 89 90 pub mod card; 91 pub use card::Card as Card; 92 93 mod ctl_int; 94 pub mod ctl { 95 //! Control device API 96 pub use super::ctl_int::{Ctl, CardInfo, ElemIface, ElemId, ElemType, ElemValue, ElemInfo}; 97 } 98 99 pub use ctl::Ctl as Ctl; 100 101 pub mod hctl; 102 pub use hctl::HCtl as HCtl; 103 104 pub mod pcm; 105 pub use pcm::PCM as PCM; 106 107 pub mod rawmidi; 108 pub use rawmidi::Rawmidi as Rawmidi; 109 110 pub mod device_name; 111 112 pub mod poll; 113 pub use poll::PollDescriptors as PollDescriptors; 114 115 pub mod mixer; 116 pub use mixer::Mixer as Mixer; 117 118 pub mod seq; 119 pub use seq::Seq as Seq; 120 121 mod io; 122 pub use io::Output; 123 124 // Reexported inside PCM module 125 mod chmap; 126 127 mod pcm_direct; 128 129 /// Functions that bypass alsa-lib and talk directly to the kernel. 130 pub mod direct { 131 /// This module bypasses alsa-lib and directly read and write into memory mapped kernel memory. 132 /// 133 /// In case of the sample memory, this is in many cases the DMA buffers that is transferred to the sound card. 134 /// 135 /// The reasons for doing this are: 136 /// 137 /// * Minimum overhead where it matters most: let alsa-lib do the code heavy setup - 138 /// then steal its file descriptor and deal with sample streaming from Rust. 139 /// * RT-safety to the maximum extent possible. Creating/dropping any of these structs causes syscalls, 140 /// but function calls on these are just read and write from memory. No syscalls, no memory allocations, 141 /// not even loops (with the exception of `MmapPlayback::write` that loops over samples to write). 142 /// * Possibility to allow Send + Sync for structs 143 /// * It's a fun experiment and an interesting deep dive into how alsa-lib does things. 144 /// 145 /// Note: Not all sound card drivers support this direct method of communication; although almost all 146 /// modern/common ones do. It only works with hardware devices though (such as "hw:xxx" device strings), 147 /// don't expect it to work with, e g, the PulseAudio plugin or so. 148 /// 149 /// For an example of how to use this mode, look in the "synth-example" directory. 150 pub mod pcm { 151 pub use pcm_direct::{SyncPtrStatus, Status, Control, MmapCapture, MmapPlayback, MmapIO, RawSamples}; 152 153 } 154 } 155