From 93e265e5b64a7cb263c41c7c0561e1d021bf465d Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 7 Sep 2025 20:01:23 +0200 Subject: [PATCH 1/4] style: format code with rustfmt --- examples/ctl_list.rs | 10 +- examples/midi_enumerate.rs | 58 +- examples/pcm_enumerate.rs | 40 +- examples/pcm_record.rs | 9 +- examples/trigger_hstamp.rs | 2 +- src/card.rs | 26 +- src/chmap.rs | 86 ++- src/config.rs | 20 +- src/ctl_int.rs | 461 +++++++++---- src/device_name.rs | 40 +- src/direct/pcm.rs | 328 ++++++--- src/hctl.rs | 101 ++- src/io.rs | 19 +- src/lib.rs | 28 +- src/mixer.rs | 406 ++++++++--- src/pcm.rs | 777 +++++++++++++++++----- src/poll.rs | 73 +- src/rawmidi.rs | 172 +++-- src/seq.rs | 1292 +++++++++++++++++++++++++----------- 19 files changed, 2858 insertions(+), 1090 deletions(-) diff --git a/examples/ctl_list.rs b/examples/ctl_list.rs index 2d842db..5df2bc1 100644 --- a/examples/ctl_list.rs +++ b/examples/ctl_list.rs @@ -1,11 +1,11 @@ //! Example that enumerates controls for a device. -use alsa::Card; use alsa::card::Iter; use alsa::ctl::Ctl; +use alsa::Card; use alsa::Error; -fn list_controls_for_card(card: &Card) -> Result<(), Error>{ +fn list_controls_for_card(card: &Card) -> Result<(), Error> { // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); let ctl = Ctl::new(&ctl_id, false)?; @@ -25,5 +25,9 @@ fn list_controls_for_card(card: &Card) -> Result<(), Error>{ fn main() { let cards = Iter::new(); - cards.for_each(|card| if let Ok(c) = card { list_controls_for_card(&c).unwrap_or_default() }); + cards.for_each(|card| { + if let Ok(c) = card { + list_controls_for_card(&c).unwrap_or_default() + } + }); } diff --git a/examples/midi_enumerate.rs b/examples/midi_enumerate.rs index 23ef825..6d458ea 100644 --- a/examples/midi_enumerate.rs +++ b/examples/midi_enumerate.rs @@ -1,13 +1,13 @@ //! Example that enumerates hardware and PCM devices. -use alsa::Card; use alsa::card::Iter as CardIter; -use alsa::ctl::{Ctl}; -use alsa::{Error}; +use alsa::ctl::Ctl; use alsa::rawmidi::Iter as MidiIter; +use alsa::Card; +use alsa::Error; + +use alsa::seq::{Addr, ClientIter, PortIter, PortSubscribeIter, QuerySubsType, Seq}; -use alsa::seq::{ClientIter, Seq, PortIter, PortSubscribeIter, QuerySubsType, Addr}; - pub fn list_rawmidi_for_card(card: &Card) -> Result<(), Error> { // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); @@ -17,21 +17,29 @@ pub fn list_rawmidi_for_card(card: &Card) -> Result<(), Error> { let cardinfo = ctl.card_info()?; let card_id = cardinfo.get_id()?; let card_name = cardinfo.get_name()?; - let subdevices:Vec<_> = MidiIter::new(&ctl).filter_map(|d| d.ok()).collect(); + let subdevices: Vec<_> = MidiIter::new(&ctl).filter_map(|d| d.ok()).collect(); if !subdevices.is_empty() { println!("card_id: {:?} card_name {:?} ", card_id, card_name); for info in &subdevices { - println!("subdevice: {:?} {:?} {:?}", info.get_subdevice(), info.get_subdevice_name().unwrap(), info.get_stream()); + println!( + "subdevice: {:?} {:?} {:?}", + info.get_subdevice(), + info.get_subdevice_name().unwrap(), + info.get_stream() + ); } println!(); - } Ok(()) } pub fn list_rawmidi_devices() { let cards = CardIter::new(); - cards.for_each(|card| if let Ok(c) = card { list_rawmidi_for_card(&c).unwrap_or_default() }); + cards.for_each(|card| { + if let Ok(c) = card { + list_rawmidi_for_card(&c).unwrap_or_default() + } + }); } pub fn list_sequencer_port() { @@ -41,13 +49,35 @@ pub fn list_sequencer_port() { seq.set_client_name(&c"ALSA_RS_EXAMPLE").unwrap(); for client in ClientIter::new(&seq) { - println!("Client {:?} {:?}", client.get_client(), client.get_name().unwrap()); + println!( + "Client {:?} {:?}", + client.get_client(), + client.get_name().unwrap() + ); for port in PortIter::new(&seq, client.get_client()) { - println!(" Port {:?} {:?}", port.get_port(), port.get_name().unwrap()); - for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::READ) { + println!( + " Port {:?} {:?}", + port.get_port(), + port.get_name().unwrap() + ); + for sub in PortSubscribeIter::new( + &seq, + Addr { + client: client.get_client(), + port: port.get_port(), + }, + QuerySubsType::READ, + ) { println!(" READ {:?}", sub.get_dest()); } - for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::WRITE) { + for sub in PortSubscribeIter::new( + &seq, + Addr { + client: client.get_client(), + port: port.get_port(), + }, + QuerySubsType::WRITE, + ) { println!(" WRITE {:?}", sub.get_dest()); } } @@ -60,4 +90,4 @@ fn main() { list_rawmidi_devices(); println!("\n--- MIDI Sequencer Clients, Ports and Subscribers ---"); list_sequencer_port(); -} \ No newline at end of file +} diff --git a/examples/pcm_enumerate.rs b/examples/pcm_enumerate.rs index aa4f8a8..d4908cf 100644 --- a/examples/pcm_enumerate.rs +++ b/examples/pcm_enumerate.rs @@ -1,13 +1,13 @@ //! Example that enumerates hardware and PCM devices. -use alsa::Card; use alsa::card::Iter; -use alsa::device_name::HintIter; use alsa::ctl::{Ctl, DeviceIter}; +use alsa::device_name::HintIter; +use alsa::Card; use alsa::{Direction, Error}; // Each card can have multiple devices and subdevices, list them all -fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error>{ +fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> { // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); let ctl = Ctl::new(&ctl_id, false)?; @@ -23,12 +23,19 @@ fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> // Read PCM name let pcm_name = pcm_info.get_name()?.to_string(); - println!("card: {:<2} id: {:<10} device: {:<2} card name: '{}' PCM name: '{}'", card.get_index(), card_id, device, card_name, pcm_name); + println!( + "card: {:<2} id: {:<10} device: {:<2} card name: '{}' PCM name: '{}'", + card.get_index(), + card_id, + device, + card_name, + pcm_name + ); // Loop through subdevices and get their names let subdevs = pcm_info.get_subdevices_count(); for subdev in 0..subdevs { - // Get subdevice name + // Get subdevice name let pcm_info = ctl.pcm_info(device as u32, subdev, direction)?; let subdev_name = pcm_info.get_subdevice_name()?; @@ -41,15 +48,30 @@ fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> pub fn list_hw_devices(direction: Direction) { let cards = Iter::new(); - cards.for_each(|card| if let Ok(c) = card { list_devices_for_card(&c, direction).unwrap_or_default() }); + cards.for_each(|card| { + if let Ok(c) = card { + list_devices_for_card(&c, direction).unwrap_or_default() + } + }); } pub fn list_pcm_devices(direction: Direction) { let hints = HintIter::new_str(None, "pcm").unwrap(); for hint in hints { // When Direction is None it means that both the PCM supports both playback and capture - if hint.name.is_some() && hint.desc.is_some() && (hint.direction.is_none() || hint.direction.map(|dir| dir == direction).unwrap_or_default()) { - println!("name: {:<35} desc: {:?}", hint.name.unwrap(), hint.desc.unwrap()); + if hint.name.is_some() + && hint.desc.is_some() + && (hint.direction.is_none() + || hint + .direction + .map(|dir| dir == direction) + .unwrap_or_default()) + { + println!( + "name: {:<35} desc: {:?}", + hint.name.unwrap(), + hint.desc.unwrap() + ); } } } @@ -64,4 +86,4 @@ fn main() { list_pcm_devices(Direction::Playback); println!("\n--- PCM capture devices ---"); list_pcm_devices(Direction::Capture); -} \ No newline at end of file +} diff --git a/examples/pcm_record.rs b/examples/pcm_record.rs index d91fd15..8d9beb6 100644 --- a/examples/pcm_record.rs +++ b/examples/pcm_record.rs @@ -1,7 +1,7 @@ //! Example that continously reads data and displays its RMS volume. use alsa::pcm::*; -use alsa::{Direction, ValueOr, Error}; +use alsa::{Direction, Error, ValueOr}; fn start_capture(device: &str) -> Result { let pcm = PCM::new(device, Direction::Capture, false)?; @@ -20,7 +20,9 @@ fn start_capture(device: &str) -> Result { // Calculates RMS (root mean square) as a way to determine volume fn rms(buf: &[i16]) -> f64 { - if buf.len() == 0 { return 0f64; } + if buf.len() == 0 { + return 0f64; + } let mut sum = 0f64; for &x in buf { sum += (x as f64) * (x as f64); @@ -30,7 +32,6 @@ fn rms(buf: &[i16]) -> f64 { 20.0 * (r / (i16::MAX as f64)).log10() } - fn read_loop(pcm: &PCM) -> Result<(), Error> { let io = pcm.io_i16()?; let mut buf = [0i16; 8192]; @@ -47,4 +48,4 @@ fn main() { // e g PulseAudio or PipeWire. let capture = start_capture("default").unwrap(); read_loop(&capture).unwrap(); -} \ No newline at end of file +} diff --git a/examples/trigger_hstamp.rs b/examples/trigger_hstamp.rs index 84dd5de..ce2ea1e 100644 --- a/examples/trigger_hstamp.rs +++ b/examples/trigger_hstamp.rs @@ -41,7 +41,7 @@ fn main() -> Result<()> { // I've also tried to construct the status object just once outside the loop but nothing changes let status = pcm.status()?; - + dbg!(&status); // The following "htstamp" functions all wrongly return a timespec struct with 0 seconds and 0 nanoseconds diff --git a/src/card.rs b/src/card.rs index 93345f4..1d1da06 100644 --- a/src/card.rs +++ b/src/card.rs @@ -1,7 +1,7 @@ //! Sound card enumeration -use libc::{c_int, c_char}; use super::error::*; use crate::alsa; +use libc::{c_char, c_int}; use std::ffi::CStr; /// An ALSA sound card, uniquely identified by its index. @@ -12,7 +12,9 @@ pub struct Card(c_int); pub struct Iter(c_int); impl Iter { - pub fn new() -> Iter { Iter(-1) } + pub fn new() -> Iter { + Iter(-1) + } } impl Iterator for Iter { @@ -28,27 +30,35 @@ impl Iterator for Iter { } impl Card { - pub fn new(index: c_int) -> Card { Card(index) } + pub fn new(index: c_int) -> Card { + Card(index) + } pub fn from_str(s: &CStr) -> Result { acheck!(snd_card_get_index(s.as_ptr())).map(Card) } pub fn get_name(&self) -> Result { let mut c: *mut c_char = ::std::ptr::null_mut(); - acheck!(snd_card_get_name(self.0, &mut c)) - .and_then(|_| from_alloc("snd_card_get_name", c)) + acheck!(snd_card_get_name(self.0, &mut c)).and_then(|_| from_alloc("snd_card_get_name", c)) } pub fn get_longname(&self) -> Result { let mut c: *mut c_char = ::std::ptr::null_mut(); acheck!(snd_card_get_longname(self.0, &mut c)) - .and_then(|_| from_alloc("snd_card_get_longname", c)) + .and_then(|_| from_alloc("snd_card_get_longname", c)) } - pub fn get_index(&self) -> c_int { self.0 } + pub fn get_index(&self) -> c_int { + self.0 + } } #[test] fn print_cards() { for a in Iter::new().map(|a| a.unwrap()) { - println!("Card #{}: {} ({})", a.get_index(), a.get_name().unwrap(), a.get_longname().unwrap()) + println!( + "Card #{}: {} ({})", + a.get_index(), + a.get_name().unwrap(), + a.get_longname().unwrap() + ) } } diff --git a/src/chmap.rs b/src/chmap.rs index 0ecbeb1..fb66a32 100644 --- a/src/chmap.rs +++ b/src/chmap.rs @@ -1,6 +1,6 @@ +use super::error::*; use crate::alsa; use std::{fmt, mem, slice}; -use super::error::*; alsa_enum!( /// [SND_CHMAP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants @@ -63,18 +63,25 @@ impl fmt::Display for ChmapPosition { } } - /// [snd_pcm_chmap_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper pub struct Chmap(*mut alsa::snd_pcm_chmap_t, bool); impl Drop for Chmap { - fn drop(&mut self) { if self.1 { unsafe { libc::free(self.0 as *mut libc::c_void) }}} + fn drop(&mut self) { + if self.1 { + unsafe { libc::free(self.0 as *mut libc::c_void) } + } + } } impl Chmap { - fn set_channels(&mut self, c: libc::c_uint) { unsafe { (*self.0) .channels = c }} + fn set_channels(&mut self, c: libc::c_uint) { + unsafe { (*self.0).channels = c } + } fn as_slice_mut(&mut self) -> &mut [libc::c_uint] { - unsafe { slice::from_raw_parts_mut((*self.0).pos.as_mut_ptr(), (*self.0).channels as usize) } + unsafe { + slice::from_raw_parts_mut((*self.0).pos.as_mut_ptr(), (*self.0).channels as usize) + } } fn as_slice(&self) -> &[libc::c_uint] { unsafe { slice::from_raw_parts((*self.0).pos.as_ptr(), (*self.0).channels as usize) } @@ -84,7 +91,11 @@ impl Chmap { impl fmt::Display for Chmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut buf: Vec = vec![0; 512]; - acheck!(snd_pcm_chmap_print(self.0, buf.len() as libc::size_t, buf.as_mut_ptr()))?; + acheck!(snd_pcm_chmap_print( + self.0, + buf.len() as libc::size_t, + buf.as_mut_ptr() + ))?; let s = from_const("snd_pcm_chmap_print", buf.as_mut_ptr())?; write!(f, "{}", s) } @@ -92,61 +103,86 @@ impl fmt::Display for Chmap { impl<'a> From<&'a [ChmapPosition]> for Chmap { fn from(a: &'a [ChmapPosition]) -> Chmap { - let p = unsafe { libc::malloc((mem::size_of::() + mem::size_of::() * a.len()) as libc::size_t) }; - if p.is_null() { panic!("Out of memory") } + let p = unsafe { + libc::malloc( + (mem::size_of::() + mem::size_of::() * a.len()) + as libc::size_t, + ) + }; + if p.is_null() { + panic!("Out of memory") + } let mut r = Chmap(p as *mut alsa::snd_pcm_chmap_t, true); r.set_channels(a.len() as libc::c_uint); - for (i,v) in r.as_slice_mut().iter_mut().enumerate() { *v = a[i] as libc::c_uint } + for (i, v) in r.as_slice_mut().iter_mut().enumerate() { + *v = a[i] as libc::c_uint + } r } } impl<'a> From<&'a Chmap> for Vec { fn from(a: &'a Chmap) -> Vec { - a.as_slice().iter().map(|&v| ChmapPosition::from_c_int(v as libc::c_int, "").unwrap()).collect() + a.as_slice() + .iter() + .map(|&v| ChmapPosition::from_c_int(v as libc::c_int, "").unwrap()) + .collect() } } -pub fn chmap_new(a: *mut alsa::snd_pcm_chmap_t) -> Chmap { Chmap(a, true) } -pub fn chmap_handle(a: &Chmap) -> *mut alsa::snd_pcm_chmap_t { a.0 } - +pub fn chmap_new(a: *mut alsa::snd_pcm_chmap_t) -> Chmap { + Chmap(a, true) +} +pub fn chmap_handle(a: &Chmap) -> *mut alsa::snd_pcm_chmap_t { + a.0 +} /// Iterator over available channel maps - see [snd_pcm_chmap_query_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) pub struct ChmapsQuery(*mut *mut alsa::snd_pcm_chmap_query_t, isize); impl Drop for ChmapsQuery { - fn drop(&mut self) { unsafe { alsa::snd_pcm_free_chmaps(self.0) }} + fn drop(&mut self) { + unsafe { alsa::snd_pcm_free_chmaps(self.0) } + } } -pub fn chmaps_query_new(a: *mut *mut alsa::snd_pcm_chmap_query_t) -> ChmapsQuery { ChmapsQuery(a, 0) } +pub fn chmaps_query_new(a: *mut *mut alsa::snd_pcm_chmap_query_t) -> ChmapsQuery { + ChmapsQuery(a, 0) +} impl Iterator for ChmapsQuery { type Item = (ChmapType, Chmap); fn next(&mut self) -> Option { - if self.0.is_null() { return None; } + if self.0.is_null() { + return None; + } let p = unsafe { *self.0.offset(self.1) }; - if p.is_null() { return None; } + if p.is_null() { + return None; + } self.1 += 1; - let t = ChmapType::from_c_int(unsafe { (*p).type_ } as libc::c_int, "snd_pcm_query_chmaps").unwrap(); + let t = ChmapType::from_c_int(unsafe { (*p).type_ } as libc::c_int, "snd_pcm_query_chmaps") + .unwrap(); let m = Chmap(unsafe { &mut (*p).map }, false); Some((t, m)) } } - #[test] fn chmap_for_first_pcm() { use super::*; - use std::ffi::CString; use crate::device_name::HintIter; + use std::ffi::CString; let i = HintIter::new(None, &*CString::new("pcm").unwrap()).unwrap(); for p in i.map(|n| n.name.unwrap()) { println!("Chmaps for {:?}:", p); - match PCM::open(&CString::new(p).unwrap(), Direction::Playback, false) { - Ok(a) => for c in a.query_chmaps() { - println!(" {:?}, {}", c.0, c.1); - }, - Err(a) => println!(" {}", a) // It's okay to have entries in the name hint array that can't be opened + match PCM::open(&CString::new(p).unwrap(), Direction::Playback, false) { + Ok(a) => { + for c in a.query_chmaps() { + println!(" {:?}, {}", c.0, c.1); + } + } + Err(a) => println!(" {}", a), // It's okay to have entries in the name hint array that can't be opened } } } diff --git a/src/config.rs b/src/config.rs index b19d0aa..f8cebda 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,29 +3,31 @@ //! For now, just contains functions regarding the global configuration //! stored as a cache inside alsa-lib. Calling `update_free_global` might help //! against valgrind reporting memory leaks. -use crate::{alsa}; use super::error::*; use super::Output; +use crate::alsa; use std::ptr; pub fn update() -> Result { - acheck!(snd_config_update()).map(|x| x != 0) + acheck!(snd_config_update()).map(|x| x != 0) } pub fn update_free_global() -> Result<()> { - acheck!(snd_config_update_free_global()).map(|_| ()) + acheck!(snd_config_update_free_global()).map(|_| ()) } /// [snd_config_t](https://alsa-project.org/alsa-doc/alsa-lib/group___config.html) wrapper pub struct Config(*mut alsa::snd_config_t); impl Drop for Config { - fn drop(&mut self) { unsafe { alsa::snd_config_unref(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_config_unref(self.0) }; + } } pub fn update_ref() -> Result { - let mut top = ptr::null_mut(); - acheck!(snd_config_update_ref(&mut top)).map(|_| Config(top)) + let mut top = ptr::null_mut(); + acheck!(snd_config_update_ref(&mut top)).map(|_| Config(top)) } impl Config { @@ -36,8 +38,8 @@ impl Config { #[test] fn config_save() { - let c = update_ref().unwrap(); + let c = update_ref().unwrap(); let mut outp = Output::buffer_open().unwrap(); - c.save(&mut outp).unwrap(); + c.save(&mut outp).unwrap(); println!("== Config save ==\n{}", outp); -} \ No newline at end of file +} diff --git a/src/ctl_int.rs b/src/ctl_int.rs index 2bd001a..2b15940 100644 --- a/src/ctl_int.rs +++ b/src/ctl_int.rs @@ -1,15 +1,14 @@ - -use crate::alsa; -use super::pcm::Info; -use std::ffi::{CStr, CString}; -use super::Direction; use super::error::*; use super::mixer::MilliBel; +use super::pcm::Info; +use super::Direction; use super::Round; -use std::{ptr, mem, fmt, cmp}; -use crate::{Card, poll}; +use crate::alsa; +use crate::{poll, Card}; +use libc::{c_int, c_long, c_short, c_uint, c_void, pollfd, size_t}; use std::cell::UnsafeCell; -use libc::{c_uint, c_void, size_t, c_long, c_int, pollfd, c_short}; +use std::ffi::{CStr, CString}; +use std::{cmp, fmt, mem, ptr}; /// We prefer not to allocate for every ElemId, ElemInfo or ElemValue. /// But we don't know if these will increase in the future or on other platforms. @@ -23,7 +22,7 @@ const ELEM_ID_SIZE: usize = 64; /// Iterate over devices of a card. pub struct DeviceIter<'a>(&'a Ctl, c_int); -impl<'a> DeviceIter<'a>{ +impl<'a> DeviceIter<'a> { pub fn new(ctl: &'a Ctl) -> DeviceIter<'a> { DeviceIter(ctl, -1) } @@ -33,7 +32,7 @@ impl<'a> Iterator for DeviceIter<'a> { type Item = c_int; fn next(&mut self) -> Option { - match acheck!(snd_ctl_pcm_next_device(self.0.0, &mut self.1)) { + match acheck!(snd_ctl_pcm_next_device(self.0 .0, &mut self.1)) { Ok(_) if self.1 == -1 => None, Ok(_) => Some(self.1), Err(_) => None, @@ -64,29 +63,51 @@ impl Ctl { Ctl::open(&CString::new(s).unwrap(), nonblock) } - pub fn card_info(&self) -> Result { CardInfo::new().and_then(|c| - acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) } + pub fn card_info(&self) -> Result { + CardInfo::new().and_then(|c| acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) + } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_ctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } + acheck!(snd_ctl_wait( + self.0, + timeout_ms.map(|x| x as c_int).unwrap_or(-1) + )) + .map(|i| i == 1) + } pub fn get_db_range(&self, id: &ElemId) -> Result<(MilliBel, MilliBel)> { let mut min: c_long = 0; let mut max: c_long = 0; - acheck!(snd_ctl_get_dB_range(self.0, elem_id_ptr(id), &mut min, &mut max)) - .map(|_| (MilliBel(min as i64), MilliBel(max as i64))) + acheck!(snd_ctl_get_dB_range( + self.0, + elem_id_ptr(id), + &mut min, + &mut max + )) + .map(|_| (MilliBel(min as i64), MilliBel(max as i64))) } pub fn convert_to_db(&self, id: &ElemId, volume: i64) -> Result { let mut m: c_long = 0; - acheck!(snd_ctl_convert_to_dB(self.0, elem_id_ptr(id), volume as c_long, &mut m)) - .map(|_| (MilliBel(m as i64))) + acheck!(snd_ctl_convert_to_dB( + self.0, + elem_id_ptr(id), + volume as c_long, + &mut m + )) + .map(|_| (MilliBel(m as i64))) } pub fn convert_from_db(&self, id: &ElemId, mb: MilliBel, dir: Round) -> Result { let mut m: c_long = 0; - acheck!(snd_ctl_convert_from_dB(self.0, elem_id_ptr(id), mb.0 as c_long, &mut m, dir as c_int)) - .map(|_| m as i64) + acheck!(snd_ctl_convert_from_dB( + self.0, + elem_id_ptr(id), + mb.0 as c_long, + &mut m, + dir as c_int + )) + .map(|_| m as i64) } pub fn elem_read(&self, val: &mut ElemValue) -> Result<()> { @@ -119,7 +140,11 @@ impl Ctl { /// returning whether or not you are subscribed. This does not work in practice, so I'm not /// including that here. pub fn subscribe_events(&self, subscribe: bool) -> Result<()> { - acheck!(snd_ctl_subscribe_events(self.0, if subscribe { 1 } else { 0 })).map(|_| ()) + acheck!(snd_ctl_subscribe_events( + self.0, + if subscribe { 1 } else { 0 } + )) + .map(|_| ()) } pub fn read(&self) -> Result> { @@ -132,13 +157,15 @@ impl Ctl { info.set_device(device); info.set_subdevice(subdevice); info.set_stream(direction); - acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info ) + acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info) }) } } impl Drop for Ctl { - fn drop(&mut self) { unsafe { alsa::snd_ctl_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_ctl_close(self.0) }; + } } impl poll::Descriptors for Ctl { @@ -146,24 +173,36 @@ impl poll::Descriptors for Ctl { unsafe { alsa::snd_ctl_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = + unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_ctl_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_ctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_ctl_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_ctl_poll_descriptors_revents( + self.0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_ctl_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } - -pub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { a.0 } +pub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { + a.0 +} /// [snd_ctl_card_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct CardInfo(*mut alsa::snd_ctl_card_info_t); impl Drop for CardInfo { - fn drop(&mut self) { unsafe { alsa::snd_ctl_card_info_free(self.0) }} + fn drop(&mut self) { + unsafe { alsa::snd_ctl_card_info_free(self.0) } + } } impl CardInfo { @@ -173,18 +212,38 @@ impl CardInfo { } pub fn get_id(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_id", unsafe { alsa::snd_ctl_card_info_get_id(self.0) })} + from_const("snd_ctl_card_info_get_id", unsafe { + alsa::snd_ctl_card_info_get_id(self.0) + }) + } pub fn get_driver(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_driver", unsafe { alsa::snd_ctl_card_info_get_driver(self.0) })} + from_const("snd_ctl_card_info_get_driver", unsafe { + alsa::snd_ctl_card_info_get_driver(self.0) + }) + } pub fn get_components(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_components", unsafe { alsa::snd_ctl_card_info_get_components(self.0) })} + from_const("snd_ctl_card_info_get_components", unsafe { + alsa::snd_ctl_card_info_get_components(self.0) + }) + } pub fn get_longname(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_longname", unsafe { alsa::snd_ctl_card_info_get_longname(self.0) })} + from_const("snd_ctl_card_info_get_longname", unsafe { + alsa::snd_ctl_card_info_get_longname(self.0) + }) + } pub fn get_name(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_name", unsafe { alsa::snd_ctl_card_info_get_name(self.0) })} + from_const("snd_ctl_card_info_get_name", unsafe { + alsa::snd_ctl_card_info_get_name(self.0) + }) + } pub fn get_mixername(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_mixername", unsafe { alsa::snd_ctl_card_info_get_mixername(self.0) })} - pub fn get_card(&self) -> Card { Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) })} + from_const("snd_ctl_card_info_get_mixername", unsafe { + alsa::snd_ctl_card_info_get_mixername(self.0) + }) + } + pub fn get_card(&self) -> Card { + Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) }) + } } alsa_enum!( @@ -221,19 +280,25 @@ pub struct ElemValue { } impl Drop for ElemValue { - fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; } + fn drop(&mut self) { + unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; + } } -pub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { a.ptr } +pub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { + a.ptr +} pub fn elem_value_new(t: ElemType, count: u32) -> Result { let mut p = ptr::null_mut(); - acheck!(snd_ctl_elem_value_malloc(&mut p)) - .map(|_| ElemValue { ptr: p, etype: t, count }) + acheck!(snd_ctl_elem_value_malloc(&mut p)).map(|_| ElemValue { + ptr: p, + etype: t, + count, + }) } impl ElemValue { - pub fn set_id(&mut self, id: &ElemId) { unsafe { alsa::snd_ctl_elem_value_set_id(self.ptr, elem_id_ptr(id)) } } @@ -243,67 +308,127 @@ impl ElemValue { // from get_bytes has been dropped when calling a set_* function). pub fn get_boolean(&self, idx: u32) -> Option { - if self.etype != ElemType::Boolean || idx >= self.count { None } - else { Some( unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) } + if self.etype != ElemType::Boolean || idx >= self.count { + None + } else { + Some(unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) + } } pub fn set_boolean(&mut self, idx: u32, val: bool) -> Option<()> { - if self.etype != ElemType::Boolean || idx >= self.count { None } - else { unsafe { alsa::snd_ctl_elem_value_set_boolean(self.ptr, idx as c_uint, if val {1} else {0}) }; Some(()) } + if self.etype != ElemType::Boolean || idx >= self.count { + None + } else { + unsafe { + alsa::snd_ctl_elem_value_set_boolean( + self.ptr, + idx as c_uint, + if val { 1 } else { 0 }, + ) + }; + Some(()) + } } pub fn get_integer(&self, idx: u32) -> Option { - if self.etype != ElemType::Integer || idx >= self.count { None } - else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) } + if self.etype != ElemType::Integer || idx >= self.count { + None + } else { + Some(unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) + } } pub fn set_integer(&mut self, idx: u32, val: i32) -> Option<()> { - if self.etype != ElemType::Integer || idx >= self.count { None } - else { unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; Some(()) } + if self.etype != ElemType::Integer || idx >= self.count { + None + } else { + unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; + Some(()) + } } pub fn get_integer64(&self, idx: u32) -> Option { - if self.etype != ElemType::Integer64 || idx >= self.count { None } - else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) } + if self.etype != ElemType::Integer64 || idx >= self.count { + None + } else { + Some(unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) + } } pub fn set_integer64(&mut self, idx: u32, val: i64) -> Option<()> { - if self.etype != ElemType::Integer || idx >= self.count { None } - else { unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; Some(()) } + if self.etype != ElemType::Integer || idx >= self.count { + None + } else { + unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; + Some(()) + } } pub fn get_enumerated(&self, idx: u32) -> Option { - if self.etype != ElemType::Enumerated || idx >= self.count { None } - else { Some( unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) } + if self.etype != ElemType::Enumerated || idx >= self.count { + None + } else { + Some(unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) + } } pub fn set_enumerated(&mut self, idx: u32, val: u32) -> Option<()> { - if self.etype != ElemType::Enumerated || idx >= self.count { None } - else { unsafe { alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) }; Some(()) } + if self.etype != ElemType::Enumerated || idx >= self.count { + None + } else { + unsafe { + alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) + }; + Some(()) + } } pub fn get_byte(&self, idx: u32) -> Option { - if self.etype != ElemType::Bytes || idx >= self.count { None } - else { Some( unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) } + if self.etype != ElemType::Bytes || idx >= self.count { + None + } else { + Some(unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) + } } pub fn set_byte(&mut self, idx: u32, val: u8) -> Option<()> { - if self.etype != ElemType::Bytes || idx >= self.count { None } - else { unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; Some(()) } + if self.etype != ElemType::Bytes || idx >= self.count { + None + } else { + unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; + Some(()) + } } pub fn get_bytes(&self) -> Option<&[u8]> { - if self.etype != ElemType::Bytes { None } - else { Some( unsafe { ::std::slice::from_raw_parts( - alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, self.count as usize) } ) } + if self.etype != ElemType::Bytes { + None + } else { + Some(unsafe { + ::std::slice::from_raw_parts( + alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, + self.count as usize, + ) + }) + } } pub fn set_bytes(&mut self, val: &[u8]) -> Option<()> { - if self.etype != ElemType::Bytes || val.len() != self.count as usize { None } - + if self.etype != ElemType::Bytes || val.len() != self.count as usize { + None + } // Note: the alsa-lib function definition is broken. First, the pointer is declared as mut even // though it's const, and second, there is a "value" missing between "elem" and "set_bytes". - else { unsafe { alsa::snd_ctl_elem_set_bytes(self.ptr, val.as_ptr() as *mut c_void, val.len() as size_t) }; Some(()) } + else { + unsafe { + alsa::snd_ctl_elem_set_bytes( + self.ptr, + val.as_ptr() as *mut c_void, + val.len() as size_t, + ) + }; + Some(()) + } } /// Creates a new ElemValue. @@ -323,21 +448,22 @@ impl ElemValue { unsafe { alsa::snd_ctl_elem_value_clear(elem_value_ptr(&ev)) }; Ok(ev) } - } impl fmt::Debug for ElemValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ElemType::*; write!(f, "ElemValue({:?}", self.etype)?; - for a in 0..self.count { match self.etype { - Boolean => write!(f, ",{:?}", self.get_boolean(a).unwrap()), - Integer => write!(f, ",{:?}", self.get_integer(a).unwrap()), - Integer64 => write!(f, ",{:?}", self.get_integer64(a).unwrap()), - Enumerated => write!(f, ",{:?}", self.get_enumerated(a).unwrap()), - Bytes => write!(f, ",{:?}", self.get_byte(a).unwrap()), - _ => Ok(()), - }?}; + for a in 0..self.count { + match self.etype { + Boolean => write!(f, ",{:?}", self.get_boolean(a).unwrap()), + Integer => write!(f, ",{:?}", self.get_integer(a).unwrap()), + Integer64 => write!(f, ",{:?}", self.get_integer64(a).unwrap()), + Enumerated => write!(f, ",{:?}", self.get_enumerated(a).unwrap()), + Bytes => write!(f, ",{:?}", self.get_byte(a).unwrap()), + _ => Ok(()), + }? + } write!(f, ")") } } @@ -345,10 +471,14 @@ impl fmt::Debug for ElemValue { /// [snd_ctl_elem_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct ElemInfo(*mut alsa::snd_ctl_elem_info_t); -pub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { a.0 } +pub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { + a.0 +} impl Drop for ElemInfo { - fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_info_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_ctl_elem_info_free(self.0) }; + } } pub fn elem_info_new() -> Result { @@ -357,9 +487,16 @@ pub fn elem_info_new() -> Result { } impl ElemInfo { - pub fn get_type(&self) -> ElemType { ElemType::from_c_int( - unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, "snd_ctl_elem_info_get_type").unwrap() } - pub fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } } + pub fn get_type(&self) -> ElemType { + ElemType::from_c_int( + unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, + "snd_ctl_elem_info_get_type", + ) + .unwrap() + } + pub fn get_count(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } + } } // @@ -375,7 +512,9 @@ pub fn elem_id_new() -> Result { } #[inline] -pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t } +pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { + a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t +} unsafe impl Send for ElemId {} @@ -409,20 +548,48 @@ pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0 } impl ElemId { pub fn get_name(&self) -> Result<&str> { - from_const("snd_hctl_elem_id_get_name", unsafe { alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) })} - pub fn get_device(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 }} - pub fn get_subdevice(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 }} - pub fn get_numid(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 }} - pub fn get_index(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 }} - pub fn get_interface(&self) -> ElemIface { ElemIface::from_c_int( - unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, "snd_ctl_elem_id_get_interface").unwrap() } - - pub fn set_device(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) }} - pub fn set_subdevice(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) }} - pub fn set_numid(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) }} - pub fn set_index(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) }} - pub fn set_interface(&mut self, v: ElemIface) { unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) }} - pub fn set_name(&mut self, v: &CStr) { unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) }} + from_const("snd_hctl_elem_id_get_name", unsafe { + alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) + }) + } + pub fn get_device(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 } + } + pub fn get_subdevice(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 } + } + pub fn get_numid(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 } + } + pub fn get_index(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 } + } + pub fn get_interface(&self) -> ElemIface { + ElemIface::from_c_int( + unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, + "snd_ctl_elem_id_get_interface", + ) + .unwrap() + } + + pub fn set_device(&mut self, v: u32) { + unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) } + } + pub fn set_subdevice(&mut self, v: u32) { + unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) } + } + pub fn set_numid(&mut self, v: u32) { + unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) } + } + pub fn set_index(&mut self, v: u32) { + unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) } + } + pub fn set_interface(&mut self, v: ElemIface) { + unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) } + } + pub fn set_name(&mut self, v: &CStr) { + unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) } + } /// Creates a new ElemId. /// @@ -438,9 +605,12 @@ impl cmp::Eq for ElemId {} impl cmp::PartialEq for ElemId { fn eq(&self, a: &ElemId) -> bool { - self.get_numid() == a.get_numid() && self.get_interface() == a.get_interface() && - self.get_index() == a.get_index() && self.get_device() == a.get_device() && - self.get_subdevice() == a.get_subdevice() && self.get_name().ok() == a.get_name().ok() + self.get_numid() == a.get_numid() + && self.get_interface() == a.get_interface() + && self.get_index() == a.get_index() + && self.get_device() == a.get_device() + && self.get_subdevice() == a.get_subdevice() + && self.get_name().ok() == a.get_name().ok() } } @@ -450,10 +620,22 @@ impl fmt::Debug for ElemId { let device = self.get_device(); let subdevice = self.get_subdevice(); - write!(f, "ElemId(#{}, {:?}, {:?}", self.get_numid(), self.get_interface(), self.get_name())?; - if index > 0 { write!(f, ", index={}", index)? }; - if device > 0 || subdevice > 0 { write!(f, ", device={}", device)? }; - if subdevice > 0 { write!(f, ", subdevice={}", device)? }; + write!( + f, + "ElemId(#{}, {:?}, {:?}", + self.get_numid(), + self.get_interface(), + self.get_name() + )?; + if index > 0 { + write!(f, ", index={}", index)? + }; + if device > 0 || subdevice > 0 { + write!(f, ", device={}", device)? + }; + if subdevice > 0 { + write!(f, ", subdevice={}", device)? + }; write!(f, ")") } } @@ -488,33 +670,56 @@ impl ElemList { } } - pub(crate) fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } } - pub fn get_used(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } } + pub(crate) fn get_count(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } + } + pub fn get_used(&self) -> u32 { + unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } + } pub fn get_id(&self, index: u32) -> Result { self.ensure_valid_index(index)?; let elem_id = elem_id_new()?; unsafe { alsa::snd_ctl_elem_list_get_id(self.0, index, elem_id_ptr(&elem_id)) }; Ok(elem_id) } - pub fn get_numid(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) } + pub fn get_numid(&self, index: u32) -> Result { + self.ensure_valid_index(index)?; + Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) + } pub fn get_interface(&self, index: u32) -> Result { self.ensure_valid_index(index)?; - ElemIface::from_c_int(unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, "snd_ctl_elem_list_get_interface") + ElemIface::from_c_int( + unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, + "snd_ctl_elem_list_get_interface", + ) + } + pub fn get_device(&self, index: u32) -> Result { + self.ensure_valid_index(index)?; + Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) + } + pub fn get_subdevice(&self, index: u32) -> Result { + self.ensure_valid_index(index)?; + Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) } - pub fn get_device(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) } - pub fn get_subdevice(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) } pub fn get_name(&self, index: u32) -> Result<&str> { self.ensure_valid_index(index)?; - from_const("snd_ctl_elem_list_get_name", unsafe { alsa::snd_ctl_elem_list_get_name(self.0, index) }) + from_const("snd_ctl_elem_list_get_name", unsafe { + alsa::snd_ctl_elem_list_get_name(self.0, index) + }) + } + pub fn get_index(&self, index: u32) -> Result { + self.ensure_valid_index(index)?; + Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) } - pub fn get_index(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) } } /// [snd_ctl_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct Event(*mut alsa::snd_ctl_event_t); impl Drop for Event { - fn drop(&mut self) { unsafe { alsa::snd_ctl_event_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_ctl_event_free(self.0) }; + } } pub fn event_new() -> Result { @@ -523,7 +728,9 @@ pub fn event_new() -> Result { } impl Event { - pub fn get_mask(&self) -> EventMask { EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 })} + pub fn get_mask(&self) -> EventMask { + EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 }) + } pub fn get_id(&self) -> ElemId { let r = elem_id_new().unwrap(); unsafe { alsa::snd_ctl_event_elem_get_id(self.0, elem_id_ptr(&r)) }; @@ -531,17 +738,26 @@ impl Event { } } - /// [SND_CTL_EVENT_MASK_XXX](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) bitmask #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub struct EventMask(pub u32); impl EventMask { - pub fn remove(&self) -> bool { return self.0 & 0xffffffff == 0xffffffff } - pub fn value(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 0) != 0); } - pub fn info(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 1) != 0); } - pub fn add(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 2) != 0); } - pub fn tlv(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 3) != 0); } + pub fn remove(&self) -> bool { + return self.0 & 0xffffffff == 0xffffffff; + } + pub fn value(&self) -> bool { + return (!self.remove()) && (self.0 & (1 << 0) != 0); + } + pub fn info(&self) -> bool { + return (!self.remove()) && (self.0 & (1 << 1) != 0); + } + pub fn add(&self) -> bool { + return (!self.remove()) && (self.0 & (1 << 2) != 0); + } + pub fn tlv(&self) -> bool { + return (!self.remove()) && (self.0 & (1 << 3) != 0); + } } #[test] @@ -551,8 +767,11 @@ fn print_sizeof() { let eleminfo = unsafe { alsa::snd_ctl_elem_info_sizeof() } as usize; assert!(elemid <= ELEM_ID_SIZE); -// assert!(elemvalue <= ELEM_VALUE_SIZE); -// assert!(eleminfo <= ELEM_INFO_SIZE); + // assert!(elemvalue <= ELEM_VALUE_SIZE); + // assert!(eleminfo <= ELEM_INFO_SIZE); - println!("Elem id: {}, Elem value: {}, Elem info: {}", elemid, elemvalue, eleminfo); + println!( + "Elem id: {}, Elem value: {}, Elem info: {}", + elemid, elemvalue, eleminfo + ); } diff --git a/src/device_name.rs b/src/device_name.rs index 965231e..21bb6d7 100644 --- a/src/device_name.rs +++ b/src/device_name.rs @@ -14,18 +14,22 @@ //! } //! ``` -use std::ptr; -use libc::{c_void, c_int}; -use crate::alsa; -use super::{Card, Direction}; use super::error::*; +use super::{Card, Direction}; +use crate::alsa; +use libc::{c_int, c_void}; use std::ffi::{CStr, CString}; +use std::ptr; /// [snd_device_name_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct HintIter(*mut *mut c_void, isize); impl Drop for HintIter { - fn drop(&mut self) { unsafe { alsa::snd_device_name_free_hint(self.0); }} + fn drop(&mut self) { + unsafe { + alsa::snd_device_name_free_hint(self.0); + } + } } impl HintIter { @@ -33,8 +37,7 @@ impl HintIter { pub fn new(card: Option<&Card>, iface: &CStr) -> Result { let mut p = ptr::null_mut(); let cnr = card.map(|c| c.get_index()).unwrap_or(-1) as c_int; - acheck!(snd_device_name_hint(cnr, iface.as_ptr(), &mut p)) - .map(|_| HintIter(p, 0)) + acheck!(snd_device_name_hint(cnr, iface.as_ptr(), &mut p)).map(|_| HintIter(p, 0)) } /// A constructor variant that takes the interface as a Rust string slice. @@ -46,15 +49,18 @@ impl HintIter { impl Iterator for HintIter { type Item = Hint; fn next(&mut self) -> Option { - if self.0.is_null() { return None; } + if self.0.is_null() { + return None; + } let p = unsafe { *self.0.offset(self.1) }; - if p.is_null() { return None; } + if p.is_null() { + return None; + } self.1 += 1; Some(Hint::new(p)) } } - /// [snd_device_name_get_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper #[derive(Debug, Clone)] pub struct Hint { @@ -71,12 +77,16 @@ impl Hint { } fn new(p: *const c_void) -> Hint { - let d = Hint::get_str(p, "IOID").and_then(|x| match &*x { + let d = Hint::get_str(p, "IOID").and_then(|x| match &*x { "Input" => Some(Direction::Capture), "Output" => Some(Direction::Playback), _ => None, - }); - Hint { name: Hint::get_str(p, "NAME"), desc: Hint::get_str(p, "DESC"), direction: d } + }); + Hint { + name: Hint::get_str(p, "NAME"), + desc: Hint::get_str(p, "DESC"), + direction: d, + } } } @@ -85,6 +95,8 @@ fn print_hints() { for t in &["pcm", "ctl", "rawmidi", "timer", "seq", "hwdep"] { println!("{} devices:", t); let i = HintIter::new(None, &*CString::new(*t).unwrap()).unwrap(); - for a in i { println!(" {:?}", a) } + for a in i { + println!(" {:?}", a) + } } } diff --git a/src/direct/pcm.rs b/src/direct/pcm.rs index 9036da9..191283c 100644 --- a/src/direct/pcm.rs +++ b/src/direct/pcm.rs @@ -19,13 +19,13 @@ don't expect it to work with, e g, the PulseAudio plugin or so. For an example of how to use this mode, look in the "synth-example" directory. */ -use libc; -use std::{mem, ptr, fmt, cmp}; use crate::error::{Error, Result}; -use std::os::unix::io::RawFd; -use crate::{pcm, PollDescriptors, Direction}; use crate::pcm::Frames; +use crate::{pcm, Direction, PollDescriptors}; +use libc; use std::marker::PhantomData; +use std::os::unix::io::RawFd; +use std::{cmp, fmt, mem, ptr}; use super::ffi::*; @@ -40,37 +40,58 @@ impl SyncPtrStatus { /// Unsafe because /// - setting appl_ptr and avail_min might make alsa-lib confused /// - no check that the fd is really a PCM - pub unsafe fn sync_ptr(fd: RawFd, hwsync: bool, appl_ptr: Option, avail_min: Option) -> Result { + pub unsafe fn sync_ptr( + fd: RawFd, + hwsync: bool, + appl_ptr: Option, + avail_min: Option, + ) -> Result { let mut data = snd_pcm_sync_ptr { - flags: (if hwsync { SNDRV_PCM_SYNC_PTR_HWSYNC } else { 0 }) + - (if appl_ptr.is_some() { SNDRV_PCM_SYNC_PTR_APPL } else { 0 }) + - (if avail_min.is_some() { SNDRV_PCM_SYNC_PTR_AVAIL_MIN } else { 0 }), - c: snd_pcm_mmap_control_r { - control: snd_pcm_mmap_control { - appl_ptr: appl_ptr.unwrap_or(0) as snd_pcm_uframes_t, - avail_min: avail_min.unwrap_or(0) as snd_pcm_uframes_t, - } - }, - s: mem::zeroed() - }; + flags: (if hwsync { SNDRV_PCM_SYNC_PTR_HWSYNC } else { 0 }) + + (if appl_ptr.is_some() { + SNDRV_PCM_SYNC_PTR_APPL + } else { + 0 + }) + + (if avail_min.is_some() { + SNDRV_PCM_SYNC_PTR_AVAIL_MIN + } else { + 0 + }), + c: snd_pcm_mmap_control_r { + control: snd_pcm_mmap_control { + appl_ptr: appl_ptr.unwrap_or(0) as snd_pcm_uframes_t, + avail_min: avail_min.unwrap_or(0) as snd_pcm_uframes_t, + }, + }, + s: mem::zeroed(), + }; sndrv_pcm_ioctl_sync_ptr(fd, &mut data)?; let i = data.s.status.state; - if (i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) { + if (i >= (pcm::State::Open as snd_pcm_state_t)) + && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) + { Ok(SyncPtrStatus(data.s.status)) } else { - Err(Error::unsupported("SNDRV_PCM_IOCTL_SYNC_PTR returned broken state")) + Err(Error::unsupported( + "SNDRV_PCM_IOCTL_SYNC_PTR returned broken state", + )) } } - pub fn hw_ptr(&self) -> pcm::Frames { self.0.hw_ptr as pcm::Frames } - pub fn state(&self) -> pcm::State { unsafe { mem::transmute(self.0.state as u8) } /* valid range checked in sync_ptr */ } - pub fn htstamp(&self) -> libc::timespec { self.0.tstamp } + pub fn hw_ptr(&self) -> pcm::Frames { + self.0.hw_ptr as pcm::Frames + } + pub fn state(&self) -> pcm::State { + unsafe { mem::transmute(self.0.state as u8) } /* valid range checked in sync_ptr */ + } + pub fn htstamp(&self) -> libc::timespec { + self.0.tstamp + } } - - /// Read PCM status directly from memory, bypassing alsa-lib. /// /// This means that it's @@ -93,13 +114,17 @@ fn pcm_to_fd(p: &pcm::PCM) -> Result { let mut fds: [libc::pollfd; 1] = unsafe { mem::zeroed() }; let c = PollDescriptors::fill(p, &mut fds)?; if c != 1 { - return Err(Error::unsupported("snd_pcm_poll_descriptors returned wrong number of fds")) + return Err(Error::unsupported( + "snd_pcm_poll_descriptors returned wrong number of fds", + )); } Ok(fds[0].fd) } impl Status { - pub fn new(p: &pcm::PCM) -> Result { Status::from_fd(pcm_to_fd(p)?) } + pub fn new(p: &pcm::PCM) -> Result { + Status::from_fd(pcm_to_fd(p)?) + } pub fn from_fd(fd: RawFd) -> Result { DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_STATUS as libc::off_t, false).map(Status) @@ -109,7 +134,10 @@ impl Status { pub fn state(&self) -> pcm::State { unsafe { let i = ptr::read_volatile(&(*self.0.ptr).state); - assert!((i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t))); + assert!( + (i >= (pcm::State::Open as snd_pcm_state_t)) + && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) + ); mem::transmute(i as u8) } } @@ -122,9 +150,7 @@ impl Status { /// /// This value wraps at "boundary" (a large value you can read from SwParams). pub fn hw_ptr(&self) -> pcm::Frames { - unsafe { - ptr::read_volatile(&(*self.0.ptr).hw_ptr) as pcm::Frames - } + unsafe { ptr::read_volatile(&(*self.0.ptr).hw_ptr) as pcm::Frames } } /// Timestamp - fast version of alsa-lib's Status::get_htstamp @@ -133,9 +159,7 @@ impl Status { /// Unfortunately, the timespec is too big to be read atomically on most archs. /// Therefore, this function can potentially give bogus result at times, at least in theory...? pub fn htstamp(&self) -> libc::timespec { - unsafe { - ptr::read_volatile(&(*self.0.ptr).tstamp) - } + unsafe { ptr::read_volatile(&(*self.0.ptr).tstamp) } } /// Audio timestamp - fast version of alsa-lib's Status::get_audio_htstamp @@ -144,9 +168,7 @@ impl Status { /// Unfortunately, the timespec is too big to be read atomically on most archs. /// Therefore, this function can potentially give bogus result at times, at least in theory...? pub fn audio_htstamp(&self) -> libc::timespec { - unsafe { - ptr::read_volatile(&(*self.0.ptr).audio_tstamp) - } + unsafe { ptr::read_volatile(&(*self.0.ptr).audio_tstamp) } } } @@ -158,7 +180,9 @@ impl Status { pub struct Control(DriverMemory); impl Control { - pub fn new(p: &pcm::PCM) -> Result { Self::from_fd(pcm_to_fd(p)?) } + pub fn new(p: &pcm::PCM) -> Result { + Self::from_fd(pcm_to_fd(p)?) + } pub fn from_fd(fd: RawFd) -> Result { DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_CONTROL as libc::off_t, true).map(Control) @@ -168,9 +192,7 @@ impl Control { /// /// This value wraps at "boundary" (a large value you can read from SwParams). pub fn appl_ptr(&self) -> pcm::Frames { - unsafe { - ptr::read_volatile(&(*self.0.ptr).appl_ptr) as pcm::Frames - } + unsafe { ptr::read_volatile(&(*self.0.ptr).appl_ptr) as pcm::Frames } } /// Set number of frames application has read or written @@ -179,33 +201,29 @@ impl Control { /// be checked by the kernel. An XRUN will happen in case the application /// has not read or written enough data. pub fn set_appl_ptr(&self, value: pcm::Frames) { - unsafe { - ptr::write_volatile(&mut (*self.0.ptr).appl_ptr, value as snd_pcm_uframes_t) - } + unsafe { ptr::write_volatile(&mut (*self.0.ptr).appl_ptr, value as snd_pcm_uframes_t) } } /// Read minimum number of frames in buffer in order to wakeup process pub fn avail_min(&self) -> pcm::Frames { - unsafe { - ptr::read_volatile(&(*self.0.ptr).avail_min) as pcm::Frames - } + unsafe { ptr::read_volatile(&(*self.0.ptr).avail_min) as pcm::Frames } } /// Write minimum number of frames in buffer in order to wakeup process pub fn set_avail_min(&self, value: pcm::Frames) { - unsafe { - ptr::write_volatile(&mut (*self.0.ptr).avail_min, value as snd_pcm_uframes_t) - } + unsafe { ptr::write_volatile(&mut (*self.0.ptr).avail_min, value as snd_pcm_uframes_t) } } } struct DriverMemory { - ptr: *mut S, - size: libc::size_t, + ptr: *mut S, + size: libc::size_t, } impl fmt::Debug for DriverMemory { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "DriverMemory({:?})", self.ptr) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "DriverMemory({:?})", self.ptr) + } } impl DriverMemory { @@ -213,13 +231,31 @@ impl DriverMemory { let mut total = count * mem::size_of::(); let ps = pagesize(); assert!(total > 0); - if total % ps != 0 { total += ps - total % ps }; - let flags = if writable { libc::PROT_WRITE | libc::PROT_READ } else { libc::PROT_READ }; - let p = unsafe { libc::mmap(ptr::null_mut(), total, flags, libc::MAP_FILE | libc::MAP_SHARED, fd, offs) }; + if total % ps != 0 { + total += ps - total % ps + }; + let flags = if writable { + libc::PROT_WRITE | libc::PROT_READ + } else { + libc::PROT_READ + }; + let p = unsafe { + libc::mmap( + ptr::null_mut(), + total, + flags, + libc::MAP_FILE | libc::MAP_SHARED, + fd, + offs, + ) + }; if p.is_null() || p == libc::MAP_FAILED { Err(Error::last("mmap (of driver memory)")) } else { - Ok(DriverMemory { ptr: p as *mut S, size: total }) + Ok(DriverMemory { + ptr: p as *mut S, + size: total, + }) } } } @@ -229,7 +265,11 @@ unsafe impl Sync for DriverMemory {} impl Drop for DriverMemory { fn drop(&mut self) { - unsafe {{ libc::munmap(self.ptr as *mut libc::c_void, self.size); } } + unsafe { + { + libc::munmap(self.ptr as *mut libc::c_void, self.size); + } + } } } @@ -246,7 +286,7 @@ impl SampleData { let bufsize = params.get_buffer_size()?; let channels = params.get_channels()?; if params.get_access()? != pcm::Access::MMapInterleaved { - return Err(Error::unsupported("Not MMAP interleaved data")) + return Err(Error::unsupported("Not MMAP interleaved data")); } let fd = pcm_to_fd(p)?; @@ -257,17 +297,21 @@ impl SampleData { }; // println!("{:?}", info); if (info.step != channels * mem::size_of::() as u32 * 8) || (info.first != 0) { - return Err(Error::unsupported("MMAP data size mismatch")) + return Err(Error::unsupported("MMAP data size mismatch")); } Ok(SampleData { - mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset as libc::off_t, true)?, + mem: DriverMemory::new( + fd, + (bufsize as usize) * (channels as usize), + info.offset as libc::off_t, + true, + )?, frames: bufsize, channels, }) } } - /// Dummy trait for better generics pub trait MmapDir: fmt::Debug { const DIR: Direction; @@ -282,9 +326,13 @@ impl MmapDir for Playback { const DIR: Direction = Direction::Playback; #[inline] fn avail(hwptr: Frames, applptr: Frames, buffersize: Frames, boundary: Frames) -> Frames { - let r = hwptr.wrapping_add(buffersize).wrapping_sub(applptr); - let r = if r < 0 { r.wrapping_add(boundary) } else { r }; - if r as usize >= boundary as usize { r.wrapping_sub(boundary) } else { r } + let r = hwptr.wrapping_add(buffersize).wrapping_sub(applptr); + let r = if r < 0 { r.wrapping_add(boundary) } else { r }; + if r as usize >= boundary as usize { + r.wrapping_sub(boundary) + } else { + r + } } } @@ -296,8 +344,12 @@ impl MmapDir for Capture { const DIR: Direction = Direction::Capture; #[inline] fn avail(hwptr: Frames, applptr: Frames, _buffersize: Frames, boundary: Frames) -> Frames { - let r = hwptr.wrapping_sub(applptr); - if r < 0 { r.wrapping_add(boundary) } else { r } + let r = hwptr.wrapping_sub(applptr); + if r < 0 { + r.wrapping_add(boundary) + } else { + r + } } } @@ -326,23 +378,28 @@ pub struct RawSamples { impl RawSamples { #[inline] /// Returns `frames` * `channels`, i e the amount of samples (of type `S`) that can be read/written. - pub fn samples(&self) -> isize { self.frames as isize * (self.channels as isize) } + pub fn samples(&self) -> isize { + self.frames as isize * (self.channels as isize) + } /// Writes samples from an iterator. /// /// Returns true if iterator was depleted, and the number of samples written. /// This is just raw read/write of memory. - pub unsafe fn write_samples>(&self, i: &mut I) -> (bool, isize) { + pub unsafe fn write_samples>(&self, i: &mut I) -> (bool, isize) { let mut z = 0; let max_samples = self.samples(); while z < max_samples { - let b = if let Some(b) = i.next() { b } else { return (true, z) }; + let b = if let Some(b) = i.next() { + b + } else { + return (true, z); + }; ptr::write_volatile(self.ptr.offset(z), b); z += 1; - }; + } (false, z) } - } impl MmapIO { @@ -361,49 +418,72 @@ impl MmapIO { } } -pub (crate) fn new_mmap(p: &pcm::PCM) -> Result> { MmapIO::new(p) } +pub(crate) fn new_mmap(p: &pcm::PCM) -> Result> { + MmapIO::new(p) +} impl MmapIO { /// Read current status - pub fn status(&self) -> &Status { &self.ss } + pub fn status(&self) -> &Status { + &self.ss + } /// Read current number of frames committed by application /// /// This number wraps at 'boundary'. #[inline] - pub fn appl_ptr(&self) -> Frames { self.c.appl_ptr() } + pub fn appl_ptr(&self) -> Frames { + self.c.appl_ptr() + } /// Read current number of frames read / written by hardware /// /// This number wraps at 'boundary'. #[inline] - pub fn hw_ptr(&self) -> Frames { self.ss.hw_ptr() } + pub fn hw_ptr(&self) -> Frames { + self.ss.hw_ptr() + } /// The number at which hw_ptr and appl_ptr wraps. #[inline] - pub fn boundary(&self) -> Frames { self.bound } + pub fn boundary(&self) -> Frames { + self.bound + } /// Total number of frames in hardware buffer #[inline] - pub fn buffer_size(&self) -> Frames { self.data.frames } + pub fn buffer_size(&self) -> Frames { + self.data.frames + } /// Number of channels in stream #[inline] - pub fn channels(&self) -> u32 { self.data.channels } + pub fn channels(&self) -> u32 { + self.data.channels + } /// Notifies the kernel that frames have now been read / written by the application /// /// This will allow the kernel to write new data into this part of the buffer. pub fn commit(&self, v: Frames) { let mut z = self.appl_ptr() + v; - if z + v >= self.boundary() { z -= self.boundary() }; + if z + v >= self.boundary() { + z -= self.boundary() + }; self.c.set_appl_ptr(z) } /// Number of frames available to read / write. /// /// In case of an underrun, this value might be bigger than the buffer size. - pub fn avail(&self) -> Frames { D::avail(self.hw_ptr(), self.appl_ptr(), self.buffer_size(), self.boundary()) } + pub fn avail(&self) -> Frames { + D::avail( + self.hw_ptr(), + self.appl_ptr(), + self.buffer_size(), + self.boundary(), + ) + } /// Returns raw pointers to data to read / write. /// @@ -427,23 +507,41 @@ impl MmapIO { let more_data = if b < a { let z = a - b; a = b; - Some( RawSamples { ptr: self.data.mem.ptr, frames: z, channels: c }) - } else { None }; + Some(RawSamples { + ptr: self.data.mem.ptr, + frames: z, + channels: c, + }) + } else { + None + }; - let p = unsafe { self.data.mem.ptr.offset(offs as isize * self.data.channels as isize) }; - (RawSamples { ptr: p, frames: a, channels: c }, more_data) + let p = unsafe { + self.data + .mem + .ptr + .offset(offs as isize * self.data.channels as isize) + }; + ( + RawSamples { + ptr: p, + frames: a, + channels: c, + }, + more_data, + ) } } impl MmapPlayback { /// Write samples to the kernel ringbuffer. - pub fn write>(&mut self, i: &mut I) -> Frames { + pub fn write>(&mut self, i: &mut I) -> Frames { let (data, more_data) = self.data_ptr(); let (iter_end, samples) = unsafe { data.write_samples(i) }; let mut z = samples / data.channels as isize; if !iter_end { if let Some(data2) = more_data { - let (_, samples2) = unsafe { data2.write_samples(i) }; + let (_, samples2) = unsafe { data2.write_samples(i) }; z += samples2 / data2.channels as isize; } } @@ -485,7 +583,8 @@ impl<'a, S: 'static + Copy> CaptureIter<'a, S> { if let Some(p2) = self.next_p.take() { self.samples = p2; } else { - self.m.commit((self.read_samples / self.samples.channels as isize) as Frames); + self.m + .commit((self.read_samples / self.samples.channels as isize) as Frames); self.read_samples = 0; self.samples.frames = 0; // Shortcut to "None" in case anyone calls us again } @@ -499,7 +598,9 @@ impl<'a, S: 'static + Copy> Iterator for CaptureIter<'a, S> { fn next(&mut self) -> Option { if self.p_offs >= self.samples.samples() { self.handle_max(); - if self.samples.frames <= 0 { return None; } + if self.samples.frames <= 0 { + return None; + } } let s = unsafe { ptr::read_volatile(self.samples.ptr.offset(self.p_offs)) }; self.p_offs += 1; @@ -510,18 +611,23 @@ impl<'a, S: 'static + Copy> Iterator for CaptureIter<'a, S> { impl<'a, S: 'static> Drop for CaptureIter<'a, S> { fn drop(&mut self) { - self.m.commit((self.read_samples / self.m.data.channels as isize) as Frames); + self.m + .commit((self.read_samples / self.m.data.channels as isize) as Frames); } } - #[test] #[ignore] // Not everyone has a recording device on plughw:1. So let's ignore this test by default. fn record_from_plughw_rw() { use crate::pcm::*; - use crate::{ValueOr, Direction}; + use crate::{Direction, ValueOr}; use std::ffi::CString; - let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Capture, false).unwrap(); + let pcm = PCM::open( + &*CString::new("plughw:1").unwrap(), + Direction::Capture, + false, + ) + .unwrap(); let ss = self::Status::new(&pcm).unwrap(); let c = self::Control::new(&pcm).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); @@ -540,7 +646,7 @@ fn record_from_plughw_rw() { pcm.start().unwrap(); assert_eq!(c.appl_ptr(), 0); println!("{:?}, {:?}", ss, c); - let mut buf = [0i16; 512*2]; + let mut buf = [0i16; 512 * 2]; assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 512); assert_eq!(c.appl_ptr(), 512); @@ -550,16 +656,20 @@ fn record_from_plughw_rw() { assert!(t2.tv_sec > 0 || t2.tv_nsec > 0); } - #[test] #[ignore] // Not everyone has a record device on plughw:1. So let's ignore this test by default. fn record_from_plughw_mmap() { use crate::pcm::*; - use crate::{ValueOr, Direction}; + use crate::{Direction, ValueOr}; use std::ffi::CString; use std::{thread, time}; - let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Capture, false).unwrap(); + let pcm = PCM::open( + &*CString::new("plughw:1").unwrap(), + Direction::Capture, + false, + ) + .unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -567,7 +677,8 @@ fn record_from_plughw_mmap() { hwp.set_access(Access::MMapInterleaved).unwrap(); pcm.hw_params(&hwp).unwrap(); - let ss = unsafe { SyncPtrStatus::sync_ptr(pcm_to_fd(&pcm).unwrap(), false, None, None).unwrap() }; + let ss = + unsafe { SyncPtrStatus::sync_ptr(pcm_to_fd(&pcm).unwrap(), false, None, None).unwrap() }; assert_eq!(ss.state(), State::Prepared); let mut m = pcm.direct_mmap_capture::().unwrap(); @@ -576,18 +687,24 @@ fn record_from_plughw_mmap() { assert_eq!(m.appl_ptr(), 0); assert_eq!(m.hw_ptr(), 0); - println!("{:?}", m); let now = time::Instant::now(); pcm.start().unwrap(); - while m.avail() < 256 { thread::sleep(time::Duration::from_millis(1)) }; + while m.avail() < 256 { + thread::sleep(time::Duration::from_millis(1)) + } assert!(now.elapsed() >= time::Duration::from_millis(256 * 1000 / 44100)); let (ptr1, md) = m.data_ptr(); assert_eq!(ptr1.channels, 2); assert!(ptr1.frames >= 256); assert!(md.is_none()); - println!("Has {:?} frames at {:?} in {:?}", m.avail(), ptr1.ptr, now.elapsed()); + println!( + "Has {:?} frames at {:?} in {:?}", + m.avail(), + ptr1.ptr, + now.elapsed() + ); let samples: Vec = m.iter().collect(); assert!(samples.len() >= ptr1.frames as usize * 2); println!("Collected {} samples", samples.len()); @@ -599,10 +716,15 @@ fn record_from_plughw_mmap() { #[ignore] fn playback_to_plughw_mmap() { use crate::pcm::*; - use crate::{ValueOr, Direction}; + use crate::{Direction, ValueOr}; use std::ffi::CString; - let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Playback, false).unwrap(); + let pcm = PCM::open( + &*CString::new("plughw:1").unwrap(), + Direction::Playback, + false, + ) + .unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -616,8 +738,8 @@ fn playback_to_plughw_mmap() { assert_eq!(m.hw_ptr(), 0); println!("{:?}", m); - let mut i = (0..(m.buffer_size() * 2)).map(|i| - (((i / 2) as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16); + let mut i = (0..(m.buffer_size() * 2)) + .map(|i| (((i / 2) as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16); m.write(&mut i); assert_eq!(m.appl_ptr(), m.buffer_size()); diff --git a/src/hctl.rs b/src/hctl.rs index 225322d..3e6f730 100644 --- a/src/hctl.rs +++ b/src/hctl.rs @@ -32,14 +32,12 @@ I suppose there is a better solution for this but I'm not sure how. */ - +use super::error::*; +use super::{ctl_int, poll}; use crate::{alsa, Card}; +use libc::{c_int, c_short, c_uint, pollfd}; use std::ffi::{CStr, CString}; -use super::error::*; use std::ptr; -use super::{ctl_int, poll}; -use libc::{c_short, c_uint, c_int, pollfd}; - /// [snd_hctl_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper pub struct HCtl(*mut alsa::snd_hctl_t); @@ -47,7 +45,9 @@ pub struct HCtl(*mut alsa::snd_hctl_t); unsafe impl Send for HCtl {} impl Drop for HCtl { - fn drop(&mut self) { unsafe { alsa::snd_hctl_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_hctl_close(self.0) }; + } } impl HCtl { @@ -61,8 +61,7 @@ impl HCtl { pub fn open(c: &CStr, nonblock: bool) -> Result { let mut r = ptr::null_mut(); let flags = if nonblock { 1 } else { 0 }; // FIXME: alsa::SND_CTL_NONBLOCK does not exist in alsa-sys - acheck!(snd_hctl_open(&mut r, c.as_ptr(), flags)) - .map(|_| HCtl(r)) + acheck!(snd_hctl_open(&mut r, c.as_ptr(), flags)).map(|_| HCtl(r)) } /// Wrapper around open. You probably want to call `load` afterwards. @@ -71,13 +70,21 @@ impl HCtl { HCtl::new(&s, nonblock) } - pub fn load(&self) -> Result<()> { acheck!(snd_hctl_load(self.0)).map(|_| ()) } + pub fn load(&self) -> Result<()> { + acheck!(snd_hctl_load(self.0)).map(|_| ()) + } - pub fn elem_iter(&self) -> ElemIter { ElemIter(self, ptr::null_mut()) } + pub fn elem_iter(&self) -> ElemIter { + ElemIter(self, ptr::null_mut()) + } pub fn find_elem(&self, id: &ctl_int::ElemId) -> Option { let p = unsafe { alsa::snd_hctl_find_elem(self.0, ctl_int::elem_id_ptr(id)) }; - if p.is_null() { None } else { Some(Elem(self, p)) } + if p.is_null() { + None + } else { + Some(Elem(self, p)) + } } pub fn handle_events(&self) -> Result { @@ -85,7 +92,12 @@ impl HCtl { } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_hctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } + acheck!(snd_hctl_wait( + self.0, + timeout_ms.map(|x| x as c_int).unwrap_or(-1) + )) + .map(|i| i == 1) + } } impl poll::Descriptors for HCtl { @@ -93,13 +105,22 @@ impl poll::Descriptors for HCtl { unsafe { alsa::snd_hctl_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_hctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = + unsafe { alsa::snd_hctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_hctl_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_hctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_hctl_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_hctl_poll_descriptors_revents( + self.0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_hctl_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -109,14 +130,19 @@ pub struct ElemIter<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t); impl<'a> Iterator for ElemIter<'a> { type Item = Elem<'a>; fn next(&mut self) -> Option> { - self.1 = if self.1.is_null() { unsafe { alsa::snd_hctl_first_elem((self.0).0) }} - else { unsafe { alsa::snd_hctl_elem_next(self.1) }}; - if self.1.is_null() { None } - else { Some(Elem(self.0, self.1)) } + self.1 = if self.1.is_null() { + unsafe { alsa::snd_hctl_first_elem((self.0).0) } + } else { + unsafe { alsa::snd_hctl_elem_next(self.1) } + }; + if self.1.is_null() { + None + } else { + Some(Elem(self.0, self.1)) + } } } - /// [snd_hctl_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper pub struct Elem<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t); @@ -145,7 +171,11 @@ impl<'a> Elem<'a> { fn print_hctls() { for a in super::card::Iter::new().map(|x| x.unwrap()) { use std::ffi::CString; - let h = HCtl::open(&CString::new(format!("hw:{}", a.get_index())).unwrap(), false).unwrap(); + let h = HCtl::open( + &CString::new(format!("hw:{}", a.get_index())).unwrap(), + false, + ) + .unwrap(); h.load().unwrap(); println!("Card {}:", a.get_name().unwrap()); for b in h.elem_iter() { @@ -158,18 +188,33 @@ fn print_hctls() { fn print_jacks() { for a in super::card::Iter::new().map(|x| x.unwrap()) { use std::ffi::CString; - let h = HCtl::open(&CString::new(format!("hw:{}", a.get_index())).unwrap(), false).unwrap(); + let h = HCtl::open( + &CString::new(format!("hw:{}", a.get_index())).unwrap(), + false, + ) + .unwrap(); h.load().unwrap(); for b in h.elem_iter() { let id = b.get_id().unwrap(); - if id.get_interface() != super::ctl_int::ElemIface::Card { continue; } + if id.get_interface() != super::ctl_int::ElemIface::Card { + continue; + } let name = id.get_name().unwrap(); - if !name.ends_with(" Jack") { continue; } - if name.ends_with(" Phantom Jack") { - println!("{} is always present", &name[..name.len()-13]) + if !name.ends_with(" Jack") { + continue; } - else { println!("{} is {}", &name[..name.len()-5], - if b.read().unwrap().get_boolean(0).unwrap() { "plugged in" } else { "unplugged" }) + if name.ends_with(" Phantom Jack") { + println!("{} is always present", &name[..name.len() - 13]) + } else { + println!( + "{} is {}", + &name[..name.len() - 5], + if b.read().unwrap().get_boolean(0).unwrap() { + "plugged in" + } else { + "unplugged" + } + ) } } } diff --git a/src/io.rs b/src/io.rs index de80827..b63f72e 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,6 +1,6 @@ -use crate::alsa; use super::error::*; -use std::{slice, ptr, fmt}; +use crate::alsa; +use std::{fmt, ptr, slice}; /// [snd_output_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___output.html) wrapper pub struct Output(*mut alsa::snd_output_t); @@ -8,11 +8,12 @@ pub struct Output(*mut alsa::snd_output_t); unsafe impl Send for Output {} impl Drop for Output { - fn drop(&mut self) { unsafe { alsa::snd_output_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_output_close(self.0) }; + } } impl Output { - pub fn buffer_open() -> Result { let mut q = ptr::null_mut(); acheck!(snd_output_buffer_open(&mut q)).map(|_| Output(q)) @@ -22,7 +23,11 @@ impl Output { let b = unsafe { let mut q = ptr::null_mut(); let s = alsa::snd_output_buffer_string(self.0, &mut q); - if s == 0 { &[] } else { slice::from_raw_parts(q as *const u8, s as usize) } + if s == 0 { + &[] + } else { + slice::from_raw_parts(q as *const u8, s as usize) + } }; f(b) } @@ -46,4 +51,6 @@ impl fmt::Display for Output { } } -pub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { o.0 } +pub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { + o.0 +} diff --git a/src/lib.rs b/src/lib.rs index 81ca0f0..2243cba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,13 +59,17 @@ impl $name { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Direction { Playback, - Capture + Capture, } impl Direction { #[inline] - pub fn input() -> Direction { Direction::Capture } + pub fn input() -> Direction { + Direction::Capture + } #[inline] - pub fn output() -> Direction { Direction::Playback } + pub fn output() -> Direction { + Direction::Playback + } } /// Used to restrict hw parameters. In case the submitted @@ -94,26 +98,28 @@ mod error; pub use crate::error::{Error, Result}; pub mod card; -pub use crate::card::Card as Card; +pub use crate::card::Card; mod ctl_int; pub mod ctl { //! Control device API - pub use super::ctl_int::{Ctl, CardInfo, DeviceIter, ElemIface, ElemId, ElemList, ElemType, ElemValue, ElemInfo}; + pub use super::ctl_int::{ + CardInfo, Ctl, DeviceIter, ElemId, ElemIface, ElemInfo, ElemList, ElemType, ElemValue, + }; } -pub use crate::ctl::Ctl as Ctl; +pub use crate::ctl::Ctl; pub mod hctl; -pub use crate::hctl::HCtl as HCtl; +pub use crate::hctl::HCtl; pub mod pcm; -pub use crate::pcm::PCM as PCM; +pub use crate::pcm::PCM; pub mod config; pub mod rawmidi; -pub use crate::rawmidi::Rawmidi as Rawmidi; +pub use crate::rawmidi::Rawmidi; pub mod device_name; @@ -121,10 +127,10 @@ pub mod poll; pub use crate::poll::Descriptors as PollDescriptors; pub mod mixer; -pub use crate::mixer::Mixer as Mixer; +pub use crate::mixer::Mixer; pub mod seq; -pub use crate::seq::Seq as Seq; +pub use crate::seq::Seq; mod io; pub use crate::io::Output; diff --git a/src/mixer.rs b/src/mixer.rs index a08ea59..05a0afa 100644 --- a/src/mixer.rs +++ b/src/mixer.rs @@ -1,13 +1,13 @@ //! Mixer API - Simple Mixer API for mixer control //! -use std::ffi::{CStr, CString}; -use std::{ptr, mem, fmt, ops}; -use libc::{c_long, c_int, c_uint, c_short, pollfd}; use crate::poll; +use libc::{c_int, c_long, c_short, c_uint, pollfd}; +use std::ffi::{CStr, CString}; +use std::{fmt, mem, ops, ptr}; -use crate::alsa; -use super::Round; use super::error::*; +use super::Round; +use crate::alsa; const SELEM_ID_SIZE: usize = 64; @@ -32,8 +32,14 @@ impl Mixer { pub fn find_selem(&self, id: &SelemId) -> Option { let selem = unsafe { alsa::snd_mixer_find_selem(self.0, id.as_ptr()) }; - if selem.is_null() { None } - else { Some(Selem(Elem {handle: selem, _mixer: self})) } + if selem.is_null() { + None + } else { + Some(Selem(Elem { + handle: selem, + _mixer: self, + })) + } } pub fn open(nonblock: bool) -> Result { @@ -53,7 +59,7 @@ impl Mixer { pub fn iter(&self) -> Iter { Iter { last_handle: ptr::null_mut(), - mixer: self + mixer: self, } } @@ -62,7 +68,12 @@ impl Mixer { } pub fn wait(&self, timeout_ms: Option) -> Result<()> { - acheck!(snd_mixer_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|_| ()) } + acheck!(snd_mixer_wait( + self.0, + timeout_ms.map(|x| x as c_int).unwrap_or(-1) + )) + .map(|_| ()) + } } /// Closes mixer and frees used resources @@ -72,23 +83,30 @@ impl Drop for Mixer { } } - impl poll::Descriptors for Mixer { fn count(&self) -> usize { unsafe { alsa::snd_mixer_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_mixer_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = + unsafe { alsa::snd_mixer_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_mixer_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_mixer_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_mixer_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_mixer_poll_descriptors_revents( + self.0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_mixer_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } - /// Wrapper for a mB (millibel) value. /// /// Despite some ALSA functions named "dB", they actually take mB values instead. @@ -98,45 +116,59 @@ impl poll::Descriptors for Mixer { pub struct MilliBel(pub i64); impl MilliBel { - pub fn to_db(self) -> f32 { (self.0 as f32) / 100.0 } - pub fn from_db(db: f32) -> Self { MilliBel((db * 100.0) as i64) } + pub fn to_db(self) -> f32 { + (self.0 as f32) / 100.0 + } + pub fn from_db(db: f32) -> Self { + MilliBel((db * 100.0) as i64) + } } impl ops::Deref for MilliBel { type Target = i64; - fn deref(&self) -> &i64 { &self.0 } + fn deref(&self) -> &i64 { + &self.0 + } } impl ops::Add for MilliBel { type Output = MilliBel; - fn add(self, rhs: Self) -> Self { MilliBel(self.0 + rhs.0) } + fn add(self, rhs: Self) -> Self { + MilliBel(self.0 + rhs.0) + } } impl ops::AddAssign for MilliBel { - fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 } + fn add_assign(&mut self, rhs: Self) { + self.0 += rhs.0 + } } impl ops::Sub for MilliBel { type Output = MilliBel; - fn sub(self, rhs: Self) -> Self { MilliBel(self.0 - rhs.0) } + fn sub(self, rhs: Self) -> Self { + MilliBel(self.0 - rhs.0) + } } impl ops::SubAssign for MilliBel { - fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 } + fn sub_assign(&mut self, rhs: Self) { + self.0 -= rhs.0 + } } /// Wraps [snd_mixer_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html) #[derive(Copy, Clone, Debug)] -pub struct Elem<'a>{ +pub struct Elem<'a> { handle: *mut alsa::snd_mixer_elem_t, - _mixer: &'a Mixer + _mixer: &'a Mixer, } /// Iterator for all elements of mixer #[derive(Copy, Clone)] -pub struct Iter<'a>{ +pub struct Iter<'a> { last_handle: *mut alsa::snd_mixer_elem_t, - mixer: &'a Mixer + mixer: &'a Mixer, } impl<'a> Iterator for Iter<'a> { @@ -153,10 +185,12 @@ impl<'a> Iterator for Iter<'a> { None } else { self.last_handle = elem; - Some(Elem { handle: elem, _mixer: self.mixer}) + Some(Elem { + handle: elem, + _mixer: self.mixer, + }) } } - } /// Wrapper for [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html) @@ -165,7 +199,6 @@ impl<'a> Iterator for Iter<'a> { pub struct SelemId([u8; SELEM_ID_SIZE]); impl SelemId { - pub fn new(name: &str, index: u32) -> SelemId { let mut s = SelemId::empty(); s.set_name(&CString::new(name).unwrap()); @@ -204,7 +237,6 @@ impl SelemId { pub fn set_index(&mut self, index: u32) { unsafe { alsa::snd_mixer_selem_id_set_index(self.as_ptr(), index) }; } - } /// Wraps an Elem as a Selem @@ -214,13 +246,21 @@ pub struct Selem<'a>(Elem<'a>); impl<'a> Selem<'a> { /// Creates a Selem by wrapping `elem`. pub fn new(elem: Elem<'a>) -> Option> { - if unsafe { alsa::snd_mixer_elem_get_type(elem.handle) } == alsa::SND_MIXER_ELEM_SIMPLE - { Some(Selem(elem)) } else { None } + if unsafe { alsa::snd_mixer_elem_get_type(elem.handle) } == alsa::SND_MIXER_ELEM_SIMPLE { + Some(Selem(elem)) + } else { + None + } } /// TODO: This function might change to support regopt and to return the mixer class pub fn register(mixer: &mut Mixer) -> Result<()> { - acheck!(snd_mixer_selem_register(mixer.0, ptr::null_mut(), ptr::null_mut())).map(|_| ()) + acheck!(snd_mixer_selem_register( + mixer.0, + ptr::null_mut(), + ptr::null_mut() + )) + .map(|_| ()) } pub fn get_id(&self) -> SelemId { @@ -313,7 +353,12 @@ impl<'a> Selem<'a> { pub fn get_playback_volume(&self, channel: SelemChannelId) -> Result { let mut value: c_long = 0; - acheck!(snd_mixer_selem_get_playback_volume(self.handle, channel as i32, &mut value)).and_then(|_| Ok(value as i64)) + acheck!(snd_mixer_selem_get_playback_volume( + self.handle, + channel as i32, + &mut value + )) + .and_then(|_| Ok(value as i64)) } /// returns volume in millibels. @@ -325,20 +370,34 @@ impl<'a> Selem<'a> { /// Asks alsa to convert playback volume to millibels. pub fn ask_playback_vol_db(&self, volume: i64) -> Result { let mut decibel_value: c_long = 0; - acheck!(snd_mixer_selem_ask_playback_vol_dB(self.handle, volume as c_long, &mut decibel_value)) - .map(|_| MilliBel(decibel_value as i64)) + acheck!(snd_mixer_selem_ask_playback_vol_dB( + self.handle, + volume as c_long, + &mut decibel_value + )) + .map(|_| MilliBel(decibel_value as i64)) } // Asks alsa to convert millibels to playback volume. pub fn ask_playback_db_vol(&self, db: MilliBel, dir: Round) -> Result { let mut raw_volume: c_long = 0; - acheck!(snd_mixer_selem_ask_playback_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume)) - .map(|_| raw_volume as i64) + acheck!(snd_mixer_selem_ask_playback_dB_vol( + self.handle, + db.0 as c_long, + dir as c_int, + &mut raw_volume + )) + .map(|_| raw_volume as i64) } pub fn get_capture_volume(&self, channel: SelemChannelId) -> Result { let mut value: c_long = 0; - acheck!(snd_mixer_selem_get_capture_volume(self.handle, channel as i32, &mut value)).map(|_| value as i64) + acheck!(snd_mixer_selem_get_capture_volume( + self.handle, + channel as i32, + &mut value + )) + .map(|_| value as i64) } /// returns volume in millibels. @@ -350,59 +409,133 @@ impl<'a> Selem<'a> { /// Asks alsa to convert capture volume to millibels pub fn ask_capture_vol_db(&self, volume: i64) -> Result { let mut decibel_value: c_long = 0; - acheck!(snd_mixer_selem_ask_capture_vol_dB (self.handle, volume as c_long, &mut decibel_value)) - .map(|_| MilliBel(decibel_value as i64)) + acheck!(snd_mixer_selem_ask_capture_vol_dB( + self.handle, + volume as c_long, + &mut decibel_value + )) + .map(|_| MilliBel(decibel_value as i64)) } // Asks alsa to convert millibels to capture volume. pub fn ask_capture_db_vol(&self, db: MilliBel, dir: Round) -> Result { let mut raw_volume: c_long = 0; - acheck!(snd_mixer_selem_ask_capture_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume)) - .map(|_| raw_volume as i64) + acheck!(snd_mixer_selem_ask_capture_dB_vol( + self.handle, + db.0 as c_long, + dir as c_int, + &mut raw_volume + )) + .map(|_| raw_volume as i64) } pub fn set_playback_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume(self.handle, channel as i32, value as c_long)).map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume( + self.handle, + channel as i32, + value as c_long + )) + .map(|_| ()) } pub fn set_playback_volume_range(&self, min: i64, max: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume_range( + self.handle, + min as c_long, + max as c_long + )) + .map(|_| ()) } pub fn set_playback_volume_all(&self, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume_all(self.handle, value as c_long)).map(|_| ()) - } - - pub fn set_playback_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ()) - } - - pub fn set_capture_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume_all( + self.handle, + value as c_long + )) + .map(|_| ()) + } + + pub fn set_playback_db( + &self, + channel: SelemChannelId, + value: MilliBel, + dir: Round, + ) -> Result<()> { + acheck!(snd_mixer_selem_set_playback_dB( + self.handle, + channel as i32, + *value as c_long, + dir as c_int + )) + .map(|_| ()) + } + + pub fn set_capture_db( + &self, + channel: SelemChannelId, + value: MilliBel, + dir: Round, + ) -> Result<()> { + acheck!(snd_mixer_selem_set_capture_dB( + self.handle, + channel as i32, + *value as c_long, + dir as c_int + )) + .map(|_| ()) } pub fn set_playback_db_all(&self, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ()) + acheck!(snd_mixer_selem_set_playback_dB_all( + self.handle, + *value as c_long, + dir as c_int + )) + .map(|_| ()) } pub fn set_capture_db_all(&self, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ()) + acheck!(snd_mixer_selem_set_capture_dB_all( + self.handle, + *value as c_long, + dir as c_int + )) + .map(|_| ()) } pub fn set_capture_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume(self.handle, channel as i32, value as c_long)).map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume( + self.handle, + channel as i32, + value as c_long + )) + .map(|_| ()) } pub fn set_capture_volume_range(&self, min: i64, max: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume_range( + self.handle, + min as c_long, + max as c_long + )) + .map(|_| ()) } pub fn set_capture_volume_all(&self, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume_all(self.handle, value as c_long)).map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume_all( + self.handle, + value as c_long + )) + .map(|_| ()) } pub fn set_playback_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_switch(self.handle, channel as i32, value)).map(|_| ()) + acheck!(snd_mixer_selem_set_playback_switch( + self.handle, + channel as i32, + value + )) + .map(|_| ()) } pub fn set_playback_switch_all(&self, value: i32) -> Result<()> { @@ -410,7 +543,12 @@ impl<'a> Selem<'a> { } pub fn set_capture_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_switch(self.handle, channel as i32, value)).map(|_| ()) + acheck!(snd_mixer_selem_set_capture_switch( + self.handle, + channel as i32, + value + )) + .map(|_| ()) } pub fn set_capture_switch_all(&self, value: i32) -> Result<()> { @@ -419,12 +557,22 @@ impl<'a> Selem<'a> { pub fn get_playback_switch(&self, channel: SelemChannelId) -> Result { let mut value: i32 = 0; - acheck!(snd_mixer_selem_get_playback_switch(self.handle, channel as i32, &mut value)).map(|_| value) + acheck!(snd_mixer_selem_get_playback_switch( + self.handle, + channel as i32, + &mut value + )) + .map(|_| value) } pub fn get_capture_switch(&self, channel: SelemChannelId) -> Result { let mut value: i32 = 0; - acheck!(snd_mixer_selem_get_capture_switch(self.handle, channel as i32, &mut value)).map(|_| value) + acheck!(snd_mixer_selem_get_capture_switch( + self.handle, + channel as i32, + &mut value + )) + .map(|_| value) } pub fn is_enumerated(&self) -> bool { @@ -445,9 +593,14 @@ impl<'a> Selem<'a> { pub fn get_enum_item_name(&self, idx: u32) -> Result { let mut temp = [0 as ::libc::c_char; 128]; - acheck!(snd_mixer_selem_get_enum_item_name(self.handle, idx, temp.len()-1, temp.as_mut_ptr())) - .and_then(|_| from_const("snd_mixer_selem_get_enum_item_name", temp.as_ptr())) - .map(|v| v.into()) + acheck!(snd_mixer_selem_get_enum_item_name( + self.handle, + idx, + temp.len() - 1, + temp.as_mut_ptr() + )) + .and_then(|_| from_const("snd_mixer_selem_get_enum_item_name", temp.as_ptr())) + .map(|v| v.into()) } /// Enumerates over valid Enum values @@ -457,13 +610,21 @@ impl<'a> Selem<'a> { pub fn get_enum_item(&self, channel: SelemChannelId) -> Result { let mut temp = 0; - acheck!(snd_mixer_selem_get_enum_item(self.handle, channel as i32, &mut temp)) - .map(|_| temp) + acheck!(snd_mixer_selem_get_enum_item( + self.handle, + channel as i32, + &mut temp + )) + .map(|_| temp) } pub fn set_enum_item(&self, channel: SelemChannelId, idx: u32) -> Result<()> { - acheck!(snd_mixer_selem_set_enum_item(self.handle, channel as i32, idx)) - .map(|_| ()) + acheck!(snd_mixer_selem_set_enum_item( + self.handle, + channel as i32, + idx + )) + .map(|_| ()) } } @@ -481,8 +642,12 @@ pub struct IterEnum<'a>(&'a Selem<'a>, u32, u32); impl<'a> Iterator for IterEnum<'a> { type Item = Result; fn next(&mut self) -> Option { - if self.1 >= self.2 { None } - else { self.1 += 1; Some(self.0.get_enum_item_name(self.1-1)) } + if self.1 >= self.2 { + None + } else { + self.1 += 1; + Some(self.0.get_enum_item_name(self.1 - 1)) + } } } @@ -504,7 +669,9 @@ alsa_enum!( ); impl SelemChannelId { - pub fn mono() -> SelemChannelId { SelemChannelId::FrontLeft } + pub fn mono() -> SelemChannelId { + SelemChannelId::FrontLeft + } } impl fmt::Display for SelemChannelId { @@ -518,13 +685,21 @@ fn print_mixer_of_cards() { use super::card; for card in card::Iter::new().map(|c| c.unwrap()) { - println!("Card #{}: {} ({})", card.get_index(), card.get_name().unwrap(), card.get_longname().unwrap()); + println!( + "Card #{}: {} ({})", + card.get_index(), + card.get_name().unwrap(), + card.get_longname().unwrap() + ); let mixer = Mixer::new(&format!("hw:{}", card.get_index()), false).unwrap(); for selem in mixer.iter().filter_map(|e| Selem::new(e)) { - let sid = selem.get_id(); - println!("\tMixer element {},{}:", sid.get_name().unwrap(), sid.get_index()); + println!( + "\tMixer element {},{}:", + sid.get_name().unwrap(), + sid.get_index() + ); if selem.has_volume() { print!("\t Volume limits: "); @@ -545,9 +720,14 @@ fn print_mixer_of_cards() { if selem.is_enumerated() { print!("\t Valid values: "); - for v in selem.iter_enum().unwrap() { print!("{}, ", v.unwrap()) }; + for v in selem.iter_enum().unwrap() { + print!("{}, ", v.unwrap()) + } print!("\n\t Current values: "); - for v in SelemChannelId::all().iter().filter_map(|&v| selem.get_enum_item(v).ok()) { + for v in SelemChannelId::all() + .iter() + .filter_map(|&v| selem.get_enum_item(v).ok()) + { print!("{}, ", selem.get_enum_item_name(v).unwrap()); } println!(); @@ -559,16 +739,28 @@ fn print_mixer_of_cards() { print!("Mono"); } else { for channel in SelemChannelId::all() { - if selem.has_capture_channel(*channel) { print!("{}, ", channel) }; + if selem.has_capture_channel(*channel) { + print!("{}, ", channel) + }; } } println!(); print!("\t Capture volumes: "); for channel in SelemChannelId::all() { - if selem.has_capture_channel(*channel) { print!("{}: {} ({} dB), ", channel, - match selem.get_capture_volume(*channel) {Ok(v) => format!("{}", v), Err(_) => "n/a".to_string()}, - match selem.get_capture_vol_db(*channel) {Ok(v) => format!("{}", v.to_db()), Err(_) => "n/a".to_string()} - );} + if selem.has_capture_channel(*channel) { + print!( + "{}: {} ({} dB), ", + channel, + match selem.get_capture_volume(*channel) { + Ok(v) => format!("{}", v), + Err(_) => "n/a".to_string(), + }, + match selem.get_capture_vol_db(*channel) { + Ok(v) => format!("{}", v.to_db()), + Err(_) => "n/a".to_string(), + } + ); + } } println!(); } @@ -579,18 +771,29 @@ fn print_mixer_of_cards() { print!("Mono"); } else { for channel in SelemChannelId::all() { - if selem.has_playback_channel(*channel) { print!("{}, ", channel) }; + if selem.has_playback_channel(*channel) { + print!("{}, ", channel) + }; } } println!(); if selem.has_playback_volume() { print!("\t Playback volumes: "); for channel in SelemChannelId::all() { - if selem.has_playback_channel(*channel) { print!("{}: {} / {}dB, ", - channel, - match selem.get_playback_volume(*channel) {Ok(v) => format!("{}", v), Err(_) => "n/a".to_string()}, - match selem.get_playback_vol_db(*channel) {Ok(v) => format!("{}", v.to_db()), Err(_) => "n/a".to_string()} - );} + if selem.has_playback_channel(*channel) { + print!( + "{}: {} / {}dB, ", + channel, + match selem.get_playback_volume(*channel) { + Ok(v) => format!("{}", v), + Err(_) => "n/a".to_string(), + }, + match selem.get_playback_vol_db(*channel) { + Ok(v) => format!("{}", v.to_db()), + Err(_) => "n/a".to_string(), + } + ); + } } println!(); } @@ -608,9 +811,18 @@ fn get_and_set_playback_volume() { let (rmin, rmax) = selem.get_playback_volume_range(); let mut channel = SelemChannelId::mono(); for c in SelemChannelId::all().iter() { - if selem.has_playback_channel(*c) { channel = *c; break } + if selem.has_playback_channel(*c) { + channel = *c; + break; + } } - println!("Testing on {} with limits {}-{} on channel {}", selem.get_id().get_name().unwrap(), rmin, rmax, channel); + println!( + "Testing on {} with limits {}-{} on channel {}", + selem.get_id().get_name().unwrap(), + rmin, + rmax, + channel + ); let old: i64 = selem.get_playback_volume(channel).unwrap(); let new: i64 = rmax / 2; @@ -636,9 +848,18 @@ fn get_and_set_capture_volume() { let (rmin, rmax) = selem.get_capture_volume_range(); let mut channel = SelemChannelId::mono(); for c in SelemChannelId::all().iter() { - if selem.has_playback_channel(*c) { channel = *c; break } + if selem.has_playback_channel(*c) { + channel = *c; + break; + } } - println!("Testing on {} with limits {}-{} on channel {}", selem.get_id().get_name().unwrap(), rmin, rmax, channel); + println!( + "Testing on {} with limits {}-{} on channel {}", + selem.get_id().get_name().unwrap(), + rmin, + rmax, + channel + ); let old: i64 = selem.get_capture_volume(channel).unwrap(); let new: i64 = rmax / 2; @@ -655,7 +876,6 @@ fn get_and_set_capture_volume() { assert_eq!(old, result); } - #[test] fn print_sizeof() { let selemid = unsafe { alsa::snd_mixer_selem_id_sizeof() } as usize; diff --git a/src/pcm.rs b/src/pcm.rs index e50b1c5..ea82346 100644 --- a/src/pcm.rs +++ b/src/pcm.rs @@ -42,17 +42,16 @@ //! pcm.drain().unwrap(); //! ``` - -use libc::{c_int, c_uint, c_void, ssize_t, c_short, timespec, pollfd}; +use super::error::*; +use super::{chmap, poll, Direction, Output, ValueOr}; use crate::alsa; +use libc::{c_int, c_short, c_uint, c_void, pollfd, ssize_t, timespec}; use std::convert::Infallible; +use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::mem::size_of; -use std::ffi::{CStr, CString}; use std::str::FromStr; -use std::{io, fmt, ptr, cell}; -use super::error::*; -use super::{Direction, Output, poll, ValueOr, chmap}; +use std::{cell, fmt, io, ptr}; pub use super::chmap::{Chmap, ChmapPosition, ChmapType, ChmapsQuery}; @@ -129,7 +128,9 @@ impl Info { } impl Drop for Info { - fn drop(&mut self) { unsafe { alsa::snd_pcm_info_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_pcm_info_free(self.0) }; + } } /// [snd_pcm_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper - start here for audio playback and recording @@ -139,7 +140,9 @@ unsafe impl Send for PCM {} impl PCM { fn check_has_io(&self) { - if self.1.get() { panic!("No hw_params call or additional IO objects allowed") } + if self.1.get() { + panic!("No hw_params call or additional IO objects allowed") + } } /// Wrapper around open that takes a &str instead of a &CStr @@ -152,22 +155,37 @@ impl PCM { let mut r = ptr::null_mut(); let stream = match dir { Direction::Capture => alsa::SND_PCM_STREAM_CAPTURE, - Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK + Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK, }; let flags = if nonblock { alsa::SND_PCM_NONBLOCK } else { 0 }; - acheck!(snd_pcm_open(&mut r, name.as_ptr(), stream, flags)).map(|_| PCM(r, cell::Cell::new(false))) + acheck!(snd_pcm_open(&mut r, name.as_ptr(), stream, flags)) + .map(|_| PCM(r, cell::Cell::new(false))) } - pub fn start(&self) -> Result<()> { acheck!(snd_pcm_start(self.0)).map(|_| ()) } - pub fn drop(&self) -> Result<()> { acheck!(snd_pcm_drop(self.0)).map(|_| ()) } + pub fn start(&self) -> Result<()> { + acheck!(snd_pcm_start(self.0)).map(|_| ()) + } + pub fn drop(&self) -> Result<()> { + acheck!(snd_pcm_drop(self.0)).map(|_| ()) + } pub fn pause(&self, pause: bool) -> Result<()> { - acheck!(snd_pcm_pause(self.0, if pause { 1 } else { 0 })).map(|_| ()) } - pub fn resume(&self) -> Result<()> { acheck!(snd_pcm_resume(self.0)).map(|_| ()) } - pub fn drain(&self) -> Result<()> { acheck!(snd_pcm_drain(self.0)).map(|_| ()) } - pub fn prepare(&self) -> Result<()> { acheck!(snd_pcm_prepare(self.0)).map(|_| ()) } - pub fn reset(&self) -> Result<()> { acheck!(snd_pcm_reset(self.0)).map(|_| ()) } + acheck!(snd_pcm_pause(self.0, if pause { 1 } else { 0 })).map(|_| ()) + } + pub fn resume(&self) -> Result<()> { + acheck!(snd_pcm_resume(self.0)).map(|_| ()) + } + pub fn drain(&self) -> Result<()> { + acheck!(snd_pcm_drain(self.0)).map(|_| ()) + } + pub fn prepare(&self) -> Result<()> { + acheck!(snd_pcm_prepare(self.0)).map(|_| ()) + } + pub fn reset(&self) -> Result<()> { + acheck!(snd_pcm_reset(self.0)).map(|_| ()) + } pub fn recover(&self, err: c_int, silent: bool) -> Result<()> { - acheck!(snd_pcm_recover(self.0, err, if silent { 1 } else { 0 })).map(|_| ()) } + acheck!(snd_pcm_recover(self.0, err, if silent { 1 } else { 0 })).map(|_| ()) + } /// Wrapper around snd_pcm_recover. /// @@ -178,26 +196,40 @@ impl PCM { } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_pcm_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } + acheck!(snd_pcm_wait( + self.0, + timeout_ms.map(|x| x as c_int).unwrap_or(-1) + )) + .map(|i| i == 1) + } pub fn state(&self) -> State { let rawstate = self.state_raw(); if let Ok(state) = State::from_c_int(rawstate, "snd_pcm_state") { state - } - else { + } else { panic!("snd_pcm_state returned an invalid value of {}", rawstate); } } /// Only used internally, and for debugging the alsa library. Please use the "state" function instead. - pub fn state_raw(&self) -> c_int { unsafe { alsa::snd_pcm_state(self.0) as c_int } } + pub fn state_raw(&self) -> c_int { + unsafe { alsa::snd_pcm_state(self.0) as c_int } + } - pub fn bytes_to_frames(&self, i: isize) -> Frames { unsafe { alsa::snd_pcm_bytes_to_frames(self.0, i as ssize_t) }} - pub fn frames_to_bytes(&self, i: Frames) -> isize { unsafe { alsa::snd_pcm_frames_to_bytes(self.0, i) as isize }} + pub fn bytes_to_frames(&self, i: isize) -> Frames { + unsafe { alsa::snd_pcm_bytes_to_frames(self.0, i as ssize_t) } + } + pub fn frames_to_bytes(&self, i: Frames) -> isize { + unsafe { alsa::snd_pcm_frames_to_bytes(self.0, i) as isize } + } - pub fn avail_update(&self) -> Result { acheck!(snd_pcm_avail_update(self.0)) } - pub fn avail(&self) -> Result { acheck!(snd_pcm_avail(self.0)) } + pub fn avail_update(&self) -> Result { + acheck!(snd_pcm_avail_update(self.0)) + } + pub fn avail(&self) -> Result { + acheck!(snd_pcm_avail(self.0)) + } pub fn avail_delay(&self) -> Result<(Frames, Frames)> { let (mut a, mut d) = (0, 0); @@ -214,26 +246,47 @@ impl PCM { fn verify_format(&self, f: Format) -> Result<()> { let ff = self.hw_params_current().and_then(|h| h.get_format())?; - if ff == f { Ok(()) } - else { + if ff == f { + Ok(()) + } else { // let s = format!("Invalid sample format ({:?}, expected {:?})", ff, f); Err(Error::unsupported("io_xx")) } } - pub fn io_i8(&self) -> Result> { self.io_checked() } - pub fn io_u8(&self) -> Result> { self.io_checked() } - pub fn io_i16(&self) -> Result> { self.io_checked() } - pub fn io_u16(&self) -> Result> { self.io_checked() } - pub fn io_i32(&self) -> Result> { self.io_checked() } - pub fn io_u32(&self) -> Result> { self.io_checked() } - pub fn io_f32(&self) -> Result> { self.io_checked() } - pub fn io_f64(&self) -> Result> { self.io_checked() } + pub fn io_i8(&self) -> Result> { + self.io_checked() + } + pub fn io_u8(&self) -> Result> { + self.io_checked() + } + pub fn io_i16(&self) -> Result> { + self.io_checked() + } + pub fn io_u16(&self) -> Result> { + self.io_checked() + } + pub fn io_i32(&self) -> Result> { + self.io_checked() + } + pub fn io_u32(&self) -> Result> { + self.io_checked() + } + pub fn io_f32(&self) -> Result> { + self.io_checked() + } + pub fn io_f64(&self) -> Result> { + self.io_checked() + } /// For the `s24` format, represented by i32 - pub fn io_i32_s24(&self) -> Result> { self.verify_format(Format::s24()).map(|_| IO::new(self)) } + pub fn io_i32_s24(&self) -> Result> { + self.verify_format(Format::s24()).map(|_| IO::new(self)) + } /// For the `u24` format, represented by u32 - pub fn io_u32_u24(&self) -> Result> { self.verify_format(Format::u24()).map(|_| IO::new(self)) } + pub fn io_u32_u24(&self) -> Result> { + self.verify_format(Format::u24()).map(|_| IO::new(self)) + } pub fn io_checked(&self) -> Result> { self.verify_format(S::FORMAT).map(|_| IO::new(self)) @@ -249,12 +302,16 @@ impl PCM { } #[deprecated(note = "renamed to io_bytes")] - pub fn io(&self) -> IO { IO::new(self) } + pub fn io(&self) -> IO { + IO::new(self) + } /// Call this if you have an unusual format, not supported by the regular access methods /// (io_i16 etc). It will succeed regardless of the sample format, but conversion to and from /// bytes to your format is up to you. - pub fn io_bytes(&self) -> IO { IO::new(self) } + pub fn io_bytes(&self) -> IO { + IO::new(self) + } /// Read buffers by talking to the kernel directly, bypassing alsa-lib. pub fn direct_mmap_capture(&self) -> Result> { @@ -277,8 +334,7 @@ impl PCM { /// Retreive current PCM hardware configuration. pub fn hw_params_current(&self) -> Result { - HwParams::new(self).and_then(|h| - acheck!(snd_pcm_hw_params_current(self.0, h.0)).map(|_| h)) + HwParams::new(self).and_then(|h| acheck!(snd_pcm_hw_params_current(self.0, h.0)).map(|_| h)) } pub fn sw_params(&self, h: &SwParams) -> Result<()> { @@ -286,22 +342,23 @@ impl PCM { } pub fn sw_params_current(&self) -> Result { - SwParams::new(self).and_then(|h| - acheck!(snd_pcm_sw_params_current(self.0, h.0)).map(|_| h)) + SwParams::new(self).and_then(|h| acheck!(snd_pcm_sw_params_current(self.0, h.0)).map(|_| h)) } /// Wraps `snd_pcm_get_params`, returns `(buffer_size, period_size)`. pub fn get_params(&self) -> Result<(u64, u64)> { let mut buffer_size = 0; let mut period_size = 0; - acheck!(snd_pcm_get_params(self.0, &mut buffer_size, &mut period_size)) - .map(|_| (buffer_size as u64, period_size as u64)) - + acheck!(snd_pcm_get_params( + self.0, + &mut buffer_size, + &mut period_size + )) + .map(|_| (buffer_size as u64, period_size as u64)) } pub fn info(&self) -> Result { - Info::new().and_then(|info| - acheck!(snd_pcm_info(self.0, info.0)).map(|_| info )) + Info::new().and_then(|info| acheck!(snd_pcm_info(self.0, info.0)).map(|_| info)) } pub fn dump(&self, o: &mut Output) -> Result<()> { @@ -326,8 +383,11 @@ impl PCM { pub fn get_chmap(&self) -> Result { let p = unsafe { alsa::snd_pcm_get_chmap(self.0) }; - if p.is_null() { Err(Error::unsupported("snd_pcm_get_chmap")) } - else { Ok(chmap::chmap_new(p)) } + if p.is_null() { + Err(Error::unsupported("snd_pcm_get_chmap")) + } else { + Ok(chmap::chmap_new(p)) + } } pub fn link(&self, other: &PCM) -> Result<()> { @@ -340,22 +400,32 @@ impl PCM { } impl Drop for PCM { - fn drop(&mut self) { unsafe { alsa::snd_pcm_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_pcm_close(self.0) }; + } } - impl poll::Descriptors for PCM { fn count(&self) -> usize { unsafe { alsa::snd_pcm_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_pcm_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = + unsafe { alsa::snd_pcm_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_pcm_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_pcm_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_pcm_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_pcm_poll_descriptors_revents( + self.0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_pcm_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -366,11 +436,12 @@ impl poll::Descriptors for PCM { pub struct IO<'a, S: Copy>(&'a PCM, PhantomData); impl<'a, S: Copy> Drop for IO<'a, S> { - fn drop(&mut self) { (self.0).1.set(false) } + fn drop(&mut self) { + (self.0).1.set(false) + } } impl<'a, S: Copy> IO<'a, S> { - fn new(a: &'a PCM) -> IO<'a, S> { a.check_has_io(); a.1.set(true); @@ -395,13 +466,23 @@ impl<'a, S: Copy> IO<'a, S> { /// On success, returns number of *frames* written. /// (Multiply with number of channels to get number of items in buf successfully written.) pub fn writei(&self, buf: &[S]) -> Result { - acheck!(snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, self.to_frames(buf.len()))).map(|r| r as usize) + acheck!(snd_pcm_writei( + (self.0).0, + buf.as_ptr() as *const c_void, + self.to_frames(buf.len()) + )) + .map(|r| r as usize) } /// On success, returns number of *frames* read. /// (Multiply with number of channels to get number of items in buf successfully read.) pub fn readi(&self, buf: &mut [S]) -> Result { - acheck!(snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, self.to_frames(buf.len()))).map(|r| r as usize) + acheck!(snd_pcm_readi( + (self.0).0, + buf.as_mut_ptr() as *mut c_void, + self.to_frames(buf.len()) + )) + .map(|r| r as usize) } /// Write non-interleaved frames to pcm. On success, returns number of frames written. @@ -413,7 +494,12 @@ impl<'a, S: Copy> IO<'a, S> { /// of at least `frames` length. pub unsafe fn writen(&self, bufs: &[*const S], frames: usize) -> Result { let frames = frames as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_writen((self.0).0, bufs.as_ptr() as *mut *mut c_void, frames)).map(|r| r as usize) + acheck!(snd_pcm_writen( + (self.0).0, + bufs.as_ptr() as *mut *mut c_void, + frames + )) + .map(|r| r as usize) } /// Read non-interleaved frames to pcm. On success, returns number of frames read. @@ -425,7 +511,12 @@ impl<'a, S: Copy> IO<'a, S> { /// of at least `frames` length. pub unsafe fn readn(&self, bufs: &mut [*mut S], frames: usize) -> Result { let frames = frames as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_readn((self.0).0, bufs.as_mut_ptr() as *mut *mut c_void, frames)).map(|r| r as usize) + acheck!(snd_pcm_readn( + (self.0).0, + bufs.as_mut_ptr() as *mut *mut c_void, + frames + )) + .map(|r| r as usize) } /// Wrapper around snd_pcm_mmap_begin and snd_pcm_mmap_commit. @@ -442,7 +533,12 @@ impl<'a, S: Copy> IO<'a, S> { let mut f = frames as alsa::snd_pcm_uframes_t; let mut offs: alsa::snd_pcm_uframes_t = 0; let mut areas = ptr::null(); - acheck!(snd_pcm_mmap_begin((self.0).0, &mut areas, &mut offs, &mut f))?; + acheck!(snd_pcm_mmap_begin( + (self.0).0, + &mut areas, + &mut offs, + &mut f + ))?; let (first, step) = unsafe { ((*areas).first, (*areas).step) }; if first != 0 || step as isize != self.0.frames_to_bytes(1) * 8 { @@ -457,7 +553,12 @@ impl<'a, S: Copy> IO<'a, S> { }; let fres = func(buf); debug_assert!(fres <= f as usize); - acheck!(snd_pcm_mmap_commit((self.0).0, offs, fres as alsa::snd_pcm_uframes_t)).map(|r| r as usize) + acheck!(snd_pcm_mmap_commit( + (self.0).0, + offs, + fres as alsa::snd_pcm_uframes_t + )) + .map(|r| r as usize) } } @@ -465,8 +566,11 @@ impl<'a, S: Copy> io::Read for IO<'a, S> { fn read(&mut self, buf: &mut [u8]) -> io::Result { let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here? let r = unsafe { alsa::snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, size) }; - if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } - else { Ok(self.0.frames_to_bytes(r) as usize) } + if r < 0 { + Err(io::Error::from_raw_os_error(r as i32)) + } else { + Ok(self.0.frames_to_bytes(r) as usize) + } } } @@ -474,13 +578,17 @@ impl<'a, S: Copy> io::Write for IO<'a, S> { fn write(&mut self, buf: &[u8]) -> io::Result { let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here? let r = unsafe { alsa::snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, size) }; - if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } - else { Ok(self.0.frames_to_bytes(r) as usize) } + if r < 0 { + Err(io::Error::from_raw_os_error(r as i32)) + } else { + Ok(self.0.frames_to_bytes(r) as usize) + } + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } } - alsa_enum!( /// [SND_PCM_STATE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants State, ALL_STATES[9], @@ -499,8 +607,8 @@ alsa_enum!( alsa_enum!( #[non_exhaustive] /// [SND_PCM_FORMAT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants - Format, ALL_FORMATS[52], - + Format, + ALL_FORMATS[52], Unknown = SND_PCM_FORMAT_UNKNOWN, S8 = SND_PCM_FORMAT_S8, U8 = SND_PCM_FORMAT_U8, @@ -678,51 +786,141 @@ impl FromStr for Format { } impl Format { - pub const fn s16() -> Format { ::FORMAT } - pub const fn u16() -> Format { ::FORMAT } - pub const fn s32() -> Format { ::FORMAT } - pub const fn u32() -> Format { ::FORMAT } - pub const fn float() -> Format { ::FORMAT } - pub const fn float64() -> Format { ::FORMAT } + pub const fn s16() -> Format { + ::FORMAT + } + pub const fn u16() -> Format { + ::FORMAT + } + pub const fn s32() -> Format { + ::FORMAT + } + pub const fn u32() -> Format { + ::FORMAT + } + pub const fn float() -> Format { + ::FORMAT + } + pub const fn float64() -> Format { + ::FORMAT + } - #[cfg(target_endian = "little")] pub const fn s24() -> Format { Format::S24LE } - #[cfg(target_endian = "big")] pub const fn s24() -> Format { Format::S24BE } + #[cfg(target_endian = "little")] + pub const fn s24() -> Format { + Format::S24LE + } + #[cfg(target_endian = "big")] + pub const fn s24() -> Format { + Format::S24BE + } - #[cfg(target_endian = "little")] pub const fn s24_3() -> Format { Format::S243LE } - #[cfg(target_endian = "big")] pub const fn s24_3() -> Format { Format::S243BE } + #[cfg(target_endian = "little")] + pub const fn s24_3() -> Format { + Format::S243LE + } + #[cfg(target_endian = "big")] + pub const fn s24_3() -> Format { + Format::S243BE + } - #[cfg(target_endian = "little")] pub const fn u24() -> Format { Format::U24LE } - #[cfg(target_endian = "big")] pub const fn u24() -> Format { Format::U24BE } + #[cfg(target_endian = "little")] + pub const fn u24() -> Format { + Format::U24LE + } + #[cfg(target_endian = "big")] + pub const fn u24() -> Format { + Format::U24BE + } - #[cfg(target_endian = "little")] pub const fn u24_3() -> Format { Format::U243LE } - #[cfg(target_endian = "big")] pub const fn u24_3() -> Format { Format::U243BE } + #[cfg(target_endian = "little")] + pub const fn u24_3() -> Format { + Format::U243LE + } + #[cfg(target_endian = "big")] + pub const fn u24_3() -> Format { + Format::U243BE + } - #[cfg(target_endian = "little")] pub const fn s20() -> Format { Format::S20LE } - #[cfg(target_endian = "big")] pub const fn s20() -> Format { Format::S20BE } + #[cfg(target_endian = "little")] + pub const fn s20() -> Format { + Format::S20LE + } + #[cfg(target_endian = "big")] + pub const fn s20() -> Format { + Format::S20BE + } - #[cfg(target_endian = "little")] pub const fn s20_3() -> Format { Format::S203LE } - #[cfg(target_endian = "big")] pub const fn s20_3() -> Format { Format::S203BE } + #[cfg(target_endian = "little")] + pub const fn s20_3() -> Format { + Format::S203LE + } + #[cfg(target_endian = "big")] + pub const fn s20_3() -> Format { + Format::S203BE + } - #[cfg(target_endian = "little")] pub const fn u20() -> Format { Format::U20LE } - #[cfg(target_endian = "big")] pub const fn u20() -> Format { Format::U20BE } + #[cfg(target_endian = "little")] + pub const fn u20() -> Format { + Format::U20LE + } + #[cfg(target_endian = "big")] + pub const fn u20() -> Format { + Format::U20BE + } - #[cfg(target_endian = "little")] pub const fn u20_3() -> Format { Format::U203LE } - #[cfg(target_endian = "big")] pub const fn u20_3() -> Format { Format::U203BE } + #[cfg(target_endian = "little")] + pub const fn u20_3() -> Format { + Format::U203LE + } + #[cfg(target_endian = "big")] + pub const fn u20_3() -> Format { + Format::U203BE + } - #[cfg(target_endian = "little")] pub const fn s18_3() -> Format { Format::S183LE } - #[cfg(target_endian = "big")] pub const fn s18_3() -> Format { Format::S183BE } + #[cfg(target_endian = "little")] + pub const fn s18_3() -> Format { + Format::S183LE + } + #[cfg(target_endian = "big")] + pub const fn s18_3() -> Format { + Format::S183BE + } - #[cfg(target_endian = "little")] pub const fn u18_3() -> Format { Format::U183LE } - #[cfg(target_endian = "big")] pub const fn u18_3() -> Format { Format::U183BE } + #[cfg(target_endian = "little")] + pub const fn u18_3() -> Format { + Format::U183LE + } + #[cfg(target_endian = "big")] + pub const fn u18_3() -> Format { + Format::U183BE + } - #[cfg(target_endian = "little")] pub const fn dsd_u16() -> Format { Format::DSDU16LE } - #[cfg(target_endian = "big")] pub const fn dsd_u16() -> Format { Format::DSDU16BE } + #[cfg(target_endian = "little")] + pub const fn dsd_u16() -> Format { + Format::DSDU16LE + } + #[cfg(target_endian = "big")] + pub const fn dsd_u16() -> Format { + Format::DSDU16BE + } - #[cfg(target_endian = "little")] pub const fn dsd_u32() -> Format { Format::DSDU32LE } - #[cfg(target_endian = "big")] pub const fn dsd_u32() -> Format { Format::DSDU32BE } + #[cfg(target_endian = "little")] + pub const fn dsd_u32() -> Format { + Format::DSDU32LE + } + #[cfg(target_endian = "big")] + pub const fn dsd_u32() -> Format { + Format::DSDU32BE + } - #[cfg(target_endian = "little")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeLE } - #[cfg(target_endian = "big")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeBE } + #[cfg(target_endian = "little")] + pub const fn iec958_subframe() -> Format { + Format::IEC958SubframeLE + } + #[cfg(target_endian = "big")] + pub const fn iec958_subframe() -> Format { + Format::IEC958SubframeBE + } pub fn physical_width(&self) -> Result { acheck!(snd_pcm_format_physical_width(self.to_c_int())) @@ -741,13 +939,16 @@ impl Format { } } - pub trait IoFormat: Copy { const FORMAT: Format; } -impl IoFormat for i8 { const FORMAT: Format = Format::S8; } -impl IoFormat for u8 { const FORMAT: Format = Format::U8; } +impl IoFormat for i8 { + const FORMAT: Format = Format::S8; +} +impl IoFormat for u8 { + const FORMAT: Format = Format::U8; +} impl IoFormat for i16 { #[cfg(target_endian = "little")] @@ -786,7 +987,6 @@ impl IoFormat for f64 { const FORMAT: Format = Format::Float64BE; } - alsa_enum!( /// [SND_PCM_ACCESS_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants Access, ALL_ACCESSES[5], @@ -811,7 +1011,9 @@ alsa_enum!( pub struct HwParams<'a>(*mut alsa::snd_pcm_hw_params_t, &'a PCM); impl<'a> Drop for HwParams<'a> { - fn drop(&mut self) { unsafe { alsa::snd_pcm_hw_params_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_pcm_hw_params_free(self.0) }; + } } impl<'a> HwParams<'a> { @@ -820,26 +1022,46 @@ impl<'a> HwParams<'a> { acheck!(snd_pcm_hw_params_malloc(&mut p)).map(|_| HwParams(p, a)) } - pub fn any(a: &'a PCM) -> Result> { HwParams::new(a).and_then(|p| - acheck!(snd_pcm_hw_params_any(a.0, p.0)).map(|_| p) - )} + pub fn any(a: &'a PCM) -> Result> { + HwParams::new(a).and_then(|p| acheck!(snd_pcm_hw_params_any(a.0, p.0)).map(|_| p)) + } pub fn get_rate_resample(&self) -> Result { let mut v = 0; - acheck!(snd_pcm_hw_params_get_rate_resample((self.1).0, self.0, &mut v)).map(|_| v != 0) + acheck!(snd_pcm_hw_params_get_rate_resample( + (self.1).0, + self.0, + &mut v + )) + .map(|_| v != 0) } pub fn set_rate_resample(&self, resample: bool) -> Result<()> { - acheck!(snd_pcm_hw_params_set_rate_resample((self.1).0, self.0, if resample {1} else {0})).map(|_| ()) + acheck!(snd_pcm_hw_params_set_rate_resample( + (self.1).0, + self.0, + if resample { 1 } else { 0 } + )) + .map(|_| ()) } pub fn set_channels_near(&self, v: u32) -> Result { let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_channels_near((self.1).0, self.0, &mut r)).map(|_| r) + acheck!(snd_pcm_hw_params_set_channels_near( + (self.1).0, + self.0, + &mut r + )) + .map(|_| r) } pub fn set_channels(&self, v: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_set_channels((self.1).0, self.0, v as c_uint)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_channels( + (self.1).0, + self.0, + v as c_uint + )) + .map(|_| ()) } pub fn get_channels(&self) -> Result { @@ -858,21 +1080,38 @@ impl<'a> HwParams<'a> { } pub fn test_channels(&self, v: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_test_channels((self.1).0, self.0, v as c_uint)).map(|_| ()) + acheck!(snd_pcm_hw_params_test_channels( + (self.1).0, + self.0, + v as c_uint + )) + .map(|_| ()) } pub fn set_rate_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_rate_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r) + acheck!(snd_pcm_hw_params_set_rate_near( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r) } pub fn set_rate(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_rate((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_rate( + (self.1).0, + self.0, + v as c_uint, + dir as c_int + )) + .map(|_| ()) } pub fn get_rate(&self) -> Result { - let (mut v, mut d) = (0,0); + let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_rate(self.0, &mut v, &mut d)).map(|_| v as u32) } @@ -882,18 +1121,34 @@ impl<'a> HwParams<'a> { // -1 if the suprenum is not in the set (i.e. it's an open range), 0 otherwise. This could // be returned along with the value, but it's safe to pass a null ptr in, in which case the // pointer is not dereferenced. - acheck!(snd_pcm_hw_params_get_rate_max(self.0, &mut v, ptr::null_mut())).map(|_| v as u32) + acheck!(snd_pcm_hw_params_get_rate_max( + self.0, + &mut v, + ptr::null_mut() + )) + .map(|_| v as u32) } pub fn get_rate_min(&self) -> Result { let mut v = 0; // Note on the null ptr: see get_rate_max but read +1 and infinum instead of -1 and // suprenum. - acheck!(snd_pcm_hw_params_get_rate_min(self.0, &mut v, ptr::null_mut())).map(|_| v as u32) + acheck!(snd_pcm_hw_params_get_rate_min( + self.0, + &mut v, + ptr::null_mut() + )) + .map(|_| v as u32) } pub fn test_rate(&self, rate: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_test_rate((self.1).0, self.0, rate as c_uint, 0)).map(|_| ()) + acheck!(snd_pcm_hw_params_test_rate( + (self.1).0, + self.0, + rate as c_uint, + 0 + )) + .map(|_| ()) } pub fn set_format(&self, v: Format) -> Result<()> { @@ -907,15 +1162,30 @@ impl<'a> HwParams<'a> { } pub fn test_format(&self, v: Format) -> Result<()> { - acheck!(snd_pcm_hw_params_test_format((self.1).0, self.0, v as c_int)).map(|_| ()) + acheck!(snd_pcm_hw_params_test_format( + (self.1).0, + self.0, + v as c_int + )) + .map(|_| ()) } pub fn test_access(&self, v: Access) -> Result<()> { - acheck!(snd_pcm_hw_params_test_access((self.1).0, self.0, v as c_uint)).map(|_| ()) + acheck!(snd_pcm_hw_params_test_access( + (self.1).0, + self.0, + v as c_uint + )) + .map(|_| ()) } pub fn set_access(&self, v: Access) -> Result<()> { - acheck!(snd_pcm_hw_params_set_access((self.1).0, self.0, v as c_uint)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_access( + (self.1).0, + self.0, + v as c_uint + )) + .map(|_| ()) } pub fn get_access(&self) -> Result { @@ -927,66 +1197,122 @@ impl<'a> HwParams<'a> { pub fn set_period_size_near(&self, v: Frames, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_period_size_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_period_size_near( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as Frames) } pub fn set_period_size(&self, v: Frames, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_period_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t, dir as c_int)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_period_size( + (self.1).0, + self.0, + v as alsa::snd_pcm_uframes_t, + dir as c_int + )) + .map(|_| ()) } pub fn set_period_time_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_period_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_period_time_near( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) } pub fn get_period_size(&self) -> Result { - let (mut v, mut d) = (0,0); + let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_period_size(self.0, &mut v, &mut d)).map(|_| v as Frames) } pub fn get_period_size_min(&self) -> Result { - let (mut v, mut d) = (0,0); - acheck!(snd_pcm_hw_params_get_period_size_min(self.0, &mut v, &mut d)).map(|_| v as Frames) + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_period_size_min( + self.0, &mut v, &mut d + )) + .map(|_| v as Frames) } pub fn get_period_size_max(&self) -> Result { - let (mut v, mut d) = (0,0); - acheck!(snd_pcm_hw_params_get_period_size_max(self.0, &mut v, &mut d)).map(|_| v as Frames) + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_period_size_max( + self.0, &mut v, &mut d + )) + .map(|_| v as Frames) } pub fn set_periods(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_periods((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_periods( + (self.1).0, + self.0, + v as c_uint, + dir as c_int + )) + .map(|_| ()) } pub fn get_periods(&self) -> Result { - let (mut v, mut d) = (0,0); + let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_periods(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn set_buffer_size_near(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_near((self.1).0, self.0, &mut r)).map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_near( + (self.1).0, + self.0, + &mut r + )) + .map(|_| r as Frames) } pub fn set_buffer_size_max(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_max((self.1).0, self.0, &mut r)).map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_max( + (self.1).0, + self.0, + &mut r + )) + .map(|_| r as Frames) } pub fn set_buffer_size_min(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_min((self.1).0, self.0, &mut r)).map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_min( + (self.1).0, + self.0, + &mut r + )) + .map(|_| r as Frames) } pub fn set_buffer_size(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_hw_params_set_buffer_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) + acheck!(snd_pcm_hw_params_set_buffer_size( + (self.1).0, + self.0, + v as alsa::snd_pcm_uframes_t + )) + .map(|_| ()) } pub fn set_buffer_time_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_buffer_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_buffer_time_near( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) } pub fn get_buffer_size(&self) -> Result { @@ -1005,13 +1331,19 @@ impl<'a> HwParams<'a> { } pub fn get_buffer_time_min(&self) -> Result { - let (mut v, mut d) = (0,0); - acheck!(snd_pcm_hw_params_get_buffer_time_min(self.0, &mut v, &mut d)).map(|_| v as u32) + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_buffer_time_min( + self.0, &mut v, &mut d + )) + .map(|_| v as u32) } pub fn get_buffer_time_max(&self) -> Result { - let (mut v, mut d) = (0,0); - acheck!(snd_pcm_hw_params_get_buffer_time_max(self.0, &mut v, &mut d)).map(|_| v as u32) + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_buffer_time_max( + self.0, &mut v, &mut d + )) + .map(|_| v as u32) } /// Returns true if the alsa stream can be paused, false if not. @@ -1066,8 +1398,14 @@ impl<'a> fmt::Debug for HwParams<'a> { .field("rate", &format!("{:?} Hz", self.get_rate())) .field("format", &self.get_format()) .field("access", &self.get_access()) - .field("period_size", &format!("{:?} frames", self.get_period_size())) - .field("buffer_size", &format!("{:?} frames", self.get_buffer_size())) + .field( + "period_size", + &format!("{:?} frames", self.get_period_size()), + ) + .field( + "buffer_size", + &format!("{:?} frames", self.get_buffer_size()), + ) .finish() } } @@ -1076,18 +1414,24 @@ impl<'a> fmt::Debug for HwParams<'a> { pub struct SwParams<'a>(*mut alsa::snd_pcm_sw_params_t, &'a PCM); impl<'a> Drop for SwParams<'a> { - fn drop(&mut self) { unsafe { alsa::snd_pcm_sw_params_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_pcm_sw_params_free(self.0) }; + } } impl<'a> SwParams<'a> { - fn new(a: &'a PCM) -> Result> { let mut p = ptr::null_mut(); acheck!(snd_pcm_sw_params_malloc(&mut p)).map(|_| SwParams(p, a)) } pub fn set_avail_min(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_avail_min((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) + acheck!(snd_pcm_sw_params_set_avail_min( + (self.1).0, + self.0, + v as alsa::snd_pcm_uframes_t + )) + .map(|_| ()) } pub fn get_avail_min(&self) -> Result { @@ -1101,7 +1445,12 @@ impl<'a> SwParams<'a> { } pub fn set_start_threshold(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_start_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) + acheck!(snd_pcm_sw_params_set_start_threshold( + (self.1).0, + self.0, + v as alsa::snd_pcm_uframes_t + )) + .map(|_| ()) } pub fn get_start_threshold(&self) -> Result { @@ -1110,7 +1459,12 @@ impl<'a> SwParams<'a> { } pub fn set_stop_threshold(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_stop_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) + acheck!(snd_pcm_sw_params_set_stop_threshold( + (self.1).0, + self.0, + v as alsa::snd_pcm_uframes_t + )) + .map(|_| ()) } pub fn get_stop_threshold(&self) -> Result { @@ -1119,7 +1473,11 @@ impl<'a> SwParams<'a> { } pub fn set_tstamp_mode(&self, v: bool) -> Result<()> { - let z = if v { alsa::SND_PCM_TSTAMP_ENABLE } else { alsa::SND_PCM_TSTAMP_NONE }; + let z = if v { + alsa::SND_PCM_TSTAMP_ENABLE + } else { + alsa::SND_PCM_TSTAMP_NONE + }; acheck!(snd_pcm_sw_params_set_tstamp_mode((self.1).0, self.0, z)).map(|_| ()) } @@ -1129,7 +1487,12 @@ impl<'a> SwParams<'a> { } pub fn set_tstamp_type(&self, v: TstampType) -> Result<()> { - acheck!(snd_pcm_sw_params_set_tstamp_type((self.1).0, self.0, v as u32)).map(|_| ()) + acheck!(snd_pcm_sw_params_set_tstamp_type( + (self.1).0, + self.0, + v as u32 + )) + .map(|_| ()) } pub fn get_tstamp_type(&self) -> Result { @@ -1155,41 +1518,65 @@ const STATUS_SIZE: usize = 152; /// [snd_pcm_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___status.html) wrapper #[derive(Debug)] -pub struct Status([u64; (STATUS_SIZE+7)/8]); +pub struct Status([u64; (STATUS_SIZE + 7) / 8]); impl Status { fn new() -> Status { assert!(unsafe { alsa::snd_pcm_status_sizeof() } as usize <= STATUS_SIZE); - Status([0; (STATUS_SIZE+7)/8]) + Status([0; (STATUS_SIZE + 7) / 8]) } - fn ptr(&self) -> *mut alsa::snd_pcm_status_t { self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t } + fn ptr(&self) -> *mut alsa::snd_pcm_status_t { + self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t + } pub fn get_htstamp(&self) -> timespec { - let mut h = timespec {tv_sec: 0, tv_nsec: 0}; + let mut h = timespec { + tv_sec: 0, + tv_nsec: 0, + }; unsafe { alsa::snd_pcm_status_get_htstamp(self.ptr(), &mut h) }; h } pub fn get_trigger_htstamp(&self) -> timespec { - let mut h = timespec {tv_sec: 0, tv_nsec: 0}; + let mut h = timespec { + tv_sec: 0, + tv_nsec: 0, + }; unsafe { alsa::snd_pcm_status_get_trigger_htstamp(self.ptr(), &mut h) }; h } pub fn get_audio_htstamp(&self) -> timespec { - let mut h = timespec {tv_sec: 0, tv_nsec: 0}; + let mut h = timespec { + tv_sec: 0, + tv_nsec: 0, + }; unsafe { alsa::snd_pcm_status_get_audio_htstamp(self.ptr(), &mut h) }; h } - pub fn get_state(&self) -> State { State::from_c_int( - unsafe { alsa::snd_pcm_status_get_state(self.ptr()) } as c_int, "snd_pcm_status_get_state").unwrap() } + pub fn get_state(&self) -> State { + State::from_c_int( + unsafe { alsa::snd_pcm_status_get_state(self.ptr()) } as c_int, + "snd_pcm_status_get_state", + ) + .unwrap() + } - pub fn get_avail(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail(self.ptr()) as Frames }} - pub fn get_delay(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_delay(self.ptr()) }} - pub fn get_avail_max(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail_max(self.ptr()) as Frames }} - pub fn get_overrange(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_overrange(self.ptr()) as Frames }} + pub fn get_avail(&self) -> Frames { + unsafe { alsa::snd_pcm_status_get_avail(self.ptr()) as Frames } + } + pub fn get_delay(&self) -> Frames { + unsafe { alsa::snd_pcm_status_get_delay(self.ptr()) } + } + pub fn get_avail_max(&self) -> Frames { + unsafe { alsa::snd_pcm_status_get_avail_max(self.ptr()) as Frames } + } + pub fn get_overrange(&self) -> Frames { + unsafe { alsa::snd_pcm_status_get_overrange(self.ptr()) as Frames } + } pub fn dump(&self, o: &mut Output) -> Result<()> { acheck!(snd_pcm_status_dump(self.ptr(), super::io::output_handle(o))).map(|_| ()) @@ -1207,11 +1594,7 @@ impl StatusBuilder { StatusBuilder(Status::new()) } - pub fn audio_htstamp_config( - self, - type_requested: AudioTstampType, - report_delay: bool, - ) -> Self { + pub fn audio_htstamp_config(self, type_requested: AudioTstampType, report_delay: bool) -> Self { let mut cfg: alsa::snd_pcm_audio_tstamp_config_t = unsafe { std::mem::zeroed() }; cfg.set_type_requested(type_requested as _); cfg.set_report_delay(report_delay as _); @@ -1220,7 +1603,7 @@ impl StatusBuilder { } pub fn build(mut self, pcm: &PCM) -> Result { - let p = self.0.0.as_mut_ptr() as *mut alsa::snd_pcm_status_t; + let p = self.0 .0.as_mut_ptr() as *mut alsa::snd_pcm_status_t; acheck!(snd_pcm_status(pcm.0, p)).map(|_| self.0) } } @@ -1228,8 +1611,8 @@ impl StatusBuilder { alsa_enum!( #[non_exhaustive] /// [SND_PCM_AUDIO_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants - AudioTstampType, ALL_AUDIO_TSTAMP_TYPES[6], - + AudioTstampType, + ALL_AUDIO_TSTAMP_TYPES[6], Compat = SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT, Default = SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT, Link = SND_PCM_AUDIO_TSTAMP_TYPE_LINK, @@ -1241,7 +1624,12 @@ alsa_enum!( #[test] fn info_from_default() { use std::ffi::CString; - let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); + let pcm = PCM::open( + &*CString::new("default").unwrap(), + Direction::Capture, + false, + ) + .unwrap(); let info = pcm.info().unwrap(); println!("PCM Info:"); println!("\tCard: {}", info.get_card()); @@ -1255,7 +1643,12 @@ fn info_from_default() { #[test] fn drop() { use std::ffi::CString; - let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); + let pcm = PCM::open( + &*CString::new("default").unwrap(), + Direction::Capture, + false, + ) + .unwrap(); // Verify that this does not cause a naming conflict (issue #14) let _ = pcm.drop(); } @@ -1263,7 +1656,12 @@ fn drop() { #[test] fn record_from_default() { use std::ffi::CString; - let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); + let pcm = PCM::open( + &*CString::new("default").unwrap(), + Direction::Capture, + false, + ) + .unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -1272,7 +1670,7 @@ fn record_from_default() { pcm.hw_params(&hwp).unwrap(); pcm.start().unwrap(); let mut buf = [0i16; 1024]; - assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 1024/2); + assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 1024 / 2); } #[test] @@ -1291,7 +1689,12 @@ fn open_s24() { #[test] fn playback_to_default() { use std::ffi::CString; - let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Playback, false).unwrap(); + let pcm = PCM::open( + &*CString::new("default").unwrap(), + Direction::Playback, + false, + ) + .unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(1).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -1301,10 +1704,15 @@ fn playback_to_default() { let hwp = pcm.hw_params_current().unwrap(); let swp = pcm.sw_params_current().unwrap(); - swp.set_start_threshold(hwp.get_buffer_size().unwrap()).unwrap(); + swp.set_start_threshold(hwp.get_buffer_size().unwrap()) + .unwrap(); pcm.sw_params(&swp).unwrap(); - println!("PCM status: {:?}, {:?}", pcm.state(), pcm.hw_params_current().unwrap()); + println!( + "PCM status: {:?}, {:?}", + pcm.state(), + pcm.hw_params_current().unwrap() + ); let mut outp = Output::buffer_open().unwrap(); pcm.dump(&mut outp).unwrap(); println!("== PCM dump ==\n{}", outp); @@ -1314,11 +1722,14 @@ fn playback_to_default() { *a = ((i as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16 } let io = pcm.io_i16().unwrap(); - for _ in 0..2*44100/1024 { // 2 seconds of playback + for _ in 0..2 * 44100 / 1024 { + // 2 seconds of playback println!("PCM state: {:?}", pcm.state()); assert_eq!(io.writei(&buf[..]).unwrap(), 1024); } - if pcm.state() != State::Running { pcm.start().unwrap() }; + if pcm.state() != State::Running { + pcm.start().unwrap() + }; let mut outp2 = Output::buffer_open().unwrap(); pcm.status().unwrap().dump(&mut outp2).unwrap(); diff --git a/src/poll.rs b/src/poll.rs index 01becf5..361e726 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -2,11 +2,10 @@ //! //! A tiny wrapper around libc's poll system call. -use libc; use super::error::*; -use std::io; +use libc; pub use libc::pollfd; - +use std::io; bitflags! { #[repr(transparent)] @@ -28,43 +27,75 @@ pub trait Descriptors { /// Wrapper around count and fill - returns an array of pollfds fn get(&self) -> Result> { - let mut v = vec![pollfd { fd: 0, events: 0, revents: 0 }; self.count()]; - if self.fill(&mut v)? != v.len() { Err(Error::unsupported("did not fill the poll descriptors array")) } - else { Ok(v) } + let mut v = vec![ + pollfd { + fd: 0, + events: 0, + revents: 0 + }; + self.count() + ]; + if self.fill(&mut v)? != v.len() { + Err(Error::unsupported( + "did not fill the poll descriptors array", + )) + } else { + Ok(v) + } } } impl Descriptors for pollfd { - fn count(&self) -> usize { 1 } - fn fill(&self, a: &mut [pollfd]) -> Result { a[0] = *self; Ok(1) } - fn revents(&self, a: &[pollfd]) -> Result { Ok(Flags::from_bits_truncate(a[0].revents)) } + fn count(&self) -> usize { + 1 + } + fn fill(&self, a: &mut [pollfd]) -> Result { + a[0] = *self; + Ok(1) + } + fn revents(&self, a: &[pollfd]) -> Result { + Ok(Flags::from_bits_truncate(a[0].revents)) + } } /// Wrapper around the libc poll call. -pub fn poll(fds: &mut[pollfd], timeout: i32) -> Result { - let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::nfds_t, timeout as libc::c_int) }; - if r >= 0 { Ok(r as usize) } else { - from_code("poll", -io::Error::last_os_error().raw_os_error().unwrap()).map(|_| unreachable!()) +pub fn poll(fds: &mut [pollfd], timeout: i32) -> Result { + let r = unsafe { + libc::poll( + fds.as_mut_ptr(), + fds.len() as libc::nfds_t, + timeout as libc::c_int, + ) + }; + if r >= 0 { + Ok(r as usize) + } else { + from_code("poll", -io::Error::last_os_error().raw_os_error().unwrap()) + .map(|_| unreachable!()) } } /// Builds a pollfd array, polls it, and returns the poll descriptors which have non-zero revents. -pub fn poll_all<'a>(desc: &[&'a dyn Descriptors], timeout: i32) -> Result> { - - let mut pollfds: Vec = vec!(); - let mut indices = vec!(); +pub fn poll_all<'a>( + desc: &[&'a dyn Descriptors], + timeout: i32, +) -> Result> { + let mut pollfds: Vec = vec![]; + let mut indices = vec![]; for v2 in desc.iter().map(|q| q.get()) { let v = v2?; - indices.push(pollfds.len() .. pollfds.len()+v.len()); + indices.push(pollfds.len()..pollfds.len() + v.len()); pollfds.extend(v); - }; + } poll(&mut pollfds, timeout)?; - let mut res = vec!(); + let mut res = vec![]; for (i, r) in indices.into_iter().enumerate() { let z = desc[i].revents(&pollfds[r])?; - if !z.is_empty() { res.push((desc[i], z)); } + if !z.is_empty() { + res.push((desc[i], z)); + } } Ok(res) } diff --git a/src/rawmidi.rs b/src/rawmidi.rs index 50ef9cc..9e8461f 100644 --- a/src/rawmidi.rs +++ b/src/rawmidi.rs @@ -1,12 +1,12 @@ //! MIDI devices I/O and enumeration -use libc::{c_int, c_uint, c_void, size_t, c_short, pollfd}; use super::ctl_int::{ctl_ptr, Ctl}; -use super::{Direction, poll}; use super::error::*; +use super::{poll, Direction}; use crate::alsa; -use std::{ptr, io}; +use libc::{c_int, c_short, c_uint, c_void, pollfd, size_t}; use std::ffi::{CStr, CString}; +use std::{io, ptr}; /// Iterator over [Rawmidi](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) devices and subdevices pub struct Iter<'a> { @@ -21,7 +21,9 @@ pub struct Iter<'a> { pub struct Info(*mut alsa::snd_rawmidi_info_t); impl Drop for Info { - fn drop(&mut self) { unsafe { alsa::snd_rawmidi_info_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_rawmidi_info_free(self.0) }; + } } impl Info { @@ -45,15 +47,24 @@ impl Info { fn subdev_count(c: &Ctl, device: c_int) -> Result<(i32, i32)> { let i = Info::from_iter(c, device, 0, Direction::Capture)?; let o = Info::from_iter(c, device, 0, Direction::Playback)?; - Ok((unsafe { alsa::snd_rawmidi_info_get_subdevices_count(o.0) as i32 }, - unsafe { alsa::snd_rawmidi_info_get_subdevices_count(i.0) as i32 })) + Ok(( + unsafe { alsa::snd_rawmidi_info_get_subdevices_count(o.0) as i32 }, + unsafe { alsa::snd_rawmidi_info_get_subdevices_count(i.0) as i32 }, + )) } - pub fn get_device(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_device(self.0) as i32 }} - pub fn get_subdevice(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_subdevice(self.0) as i32 }} + pub fn get_device(&self) -> i32 { + unsafe { alsa::snd_rawmidi_info_get_device(self.0) as i32 } + } + pub fn get_subdevice(&self) -> i32 { + unsafe { alsa::snd_rawmidi_info_get_subdevice(self.0) as i32 } + } pub fn get_stream(&self) -> super::Direction { - if unsafe { alsa::snd_rawmidi_info_get_stream(self.0) } == alsa::SND_RAWMIDI_STREAM_OUTPUT { super::Direction::Playback } - else { super::Direction::Capture } + if unsafe { alsa::snd_rawmidi_info_get_stream(self.0) } == alsa::SND_RAWMIDI_STREAM_OUTPUT { + super::Direction::Playback + } else { + super::Direction::Capture + } } pub fn get_subdevice_name(&self) -> Result { @@ -77,17 +88,30 @@ impl Status { } impl Status { - pub fn get_avail(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_avail(self.0 as *const _) } } - pub fn get_xruns(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_xruns(self.0 as *const _) } } + pub fn get_avail(&self) -> usize { + unsafe { alsa::snd_rawmidi_status_get_avail(self.0 as *const _) } + } + pub fn get_xruns(&self) -> usize { + unsafe { alsa::snd_rawmidi_status_get_xruns(self.0 as *const _) } + } } impl Drop for Status { - fn drop(&mut self) { unsafe { alsa::snd_rawmidi_status_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_rawmidi_status_free(self.0) }; + } } - impl<'a> Iter<'a> { - pub fn new(c: &'a Ctl) -> Iter<'a> { Iter { ctl: c, device: -1, in_count: 0, out_count: 0, current: 0 }} + pub fn new(c: &'a Ctl) -> Iter<'a> { + Iter { + ctl: c, + device: -1, + in_count: 0, + out_count: 0, + current: 0, + } + } } impl<'a> Iterator for Iter<'a> { @@ -95,18 +119,31 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option> { if self.current < self.in_count { self.current += 1; - return Some(Info::from_iter(self.ctl, self.device, self.current-1, Direction::Capture)); + return Some(Info::from_iter( + self.ctl, + self.device, + self.current - 1, + Direction::Capture, + )); } if self.current - self.in_count < self.out_count { self.current += 1; - return Some(Info::from_iter(self.ctl, self.device, self.current-1-self.in_count, Direction::Playback)); + return Some(Info::from_iter( + self.ctl, + self.device, + self.current - 1 - self.in_count, + Direction::Playback, + )); } - let r = acheck!(snd_ctl_rawmidi_next_device(ctl_ptr(self.ctl), &mut self.device)); + let r = acheck!(snd_ctl_rawmidi_next_device( + ctl_ptr(self.ctl), + &mut self.device + )); match r { Err(e) => return Some(Err(e)), Ok(_) if self.device == -1 => return None, - _ => {}, + _ => {} } self.current = 0; match Info::subdev_count(self.ctl, self.device) { @@ -126,11 +163,12 @@ pub struct Rawmidi(*mut alsa::snd_rawmidi_t); unsafe impl Send for Rawmidi {} impl Drop for Rawmidi { - fn drop(&mut self) { unsafe { alsa::snd_rawmidi_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_rawmidi_close(self.0) }; + } } impl Rawmidi { - /// Wrapper around open that takes a &str instead of a &CStr pub fn new(name: &str, dir: Direction, nonblock: bool) -> Result { Self::open(&CString::new(name).unwrap(), dir, nonblock) @@ -140,10 +178,20 @@ impl Rawmidi { let mut h = ptr::null_mut(); let flags = if nonblock { 2 } else { 0 }; // FIXME: alsa::SND_RAWMIDI_NONBLOCK does not exist in alsa-sys acheck!(snd_rawmidi_open( - if dir == Direction::Capture { &mut h } else { ptr::null_mut() }, - if dir == Direction::Playback { &mut h } else { ptr::null_mut() }, - name.as_ptr(), flags)) - .map(|_| Rawmidi(h)) + if dir == Direction::Capture { + &mut h + } else { + ptr::null_mut() + }, + if dir == Direction::Playback { + &mut h + } else { + ptr::null_mut() + }, + name.as_ptr(), + flags + )) + .map(|_| Rawmidi(h)) } pub fn info(&self) -> Result { @@ -154,14 +202,20 @@ impl Rawmidi { Status::new().and_then(|i| acheck!(snd_rawmidi_status(self.0, i.0)).map(|_| i)) } - pub fn drop(&self) -> Result<()> { acheck!(snd_rawmidi_drop(self.0)).map(|_| ()) } - pub fn drain(&self) -> Result<()> { acheck!(snd_rawmidi_drain(self.0)).map(|_| ()) } + pub fn drop(&self) -> Result<()> { + acheck!(snd_rawmidi_drop(self.0)).map(|_| ()) + } + pub fn drain(&self) -> Result<()> { + acheck!(snd_rawmidi_drain(self.0)).map(|_| ()) + } pub fn name(&self) -> Result { let c = unsafe { alsa::snd_rawmidi_name(self.0) }; from_const("snd_rawmidi_name", c).map(|s| s.to_string()) } - pub fn io(&self) -> IO { IO(self) } + pub fn io(&self) -> IO { + IO(self) + } } impl poll::Descriptors for Rawmidi { @@ -169,13 +223,23 @@ impl poll::Descriptors for Rawmidi { unsafe { alsa::snd_rawmidi_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_rawmidi_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = unsafe { + alsa::snd_rawmidi_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) + }; from_code("snd_rawmidi_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_rawmidi_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_rawmidi_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_rawmidi_poll_descriptors_revents( + self.0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_rawmidi_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -184,28 +248,54 @@ pub struct IO<'a>(&'a Rawmidi); impl<'a> io::Read for IO<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let r = unsafe { alsa::snd_rawmidi_read((self.0).0, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) }; - if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } - else { Ok(r as usize) } + let r = unsafe { + alsa::snd_rawmidi_read( + (self.0).0, + buf.as_mut_ptr() as *mut c_void, + buf.len() as size_t, + ) + }; + if r < 0 { + Err(io::Error::from_raw_os_error(r as i32)) + } else { + Ok(r as usize) + } } } impl<'a> io::Write for IO<'a> { fn write(&mut self, buf: &[u8]) -> io::Result { - let r = unsafe { alsa::snd_rawmidi_write((self.0).0, buf.as_ptr() as *const c_void, buf.len() as size_t) }; - if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } - else { Ok(r as usize) } + let r = unsafe { + alsa::snd_rawmidi_write( + (self.0).0, + buf.as_ptr() as *const c_void, + buf.len() as size_t, + ) + }; + if r < 0 { + Err(io::Error::from_raw_os_error(r as i32)) + } else { + Ok(r as usize) + } + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } } - #[test] fn print_rawmidis() { for a in super::card::Iter::new().map(|a| a.unwrap()) { for b in Iter::new(&Ctl::from_card(&a, false).unwrap()).map(|b| b.unwrap()) { - println!("Rawmidi {:?} (hw:{},{},{}) {} - {}", b.get_stream(), a.get_index(), b.get_device(), b.get_subdevice(), - a.get_name().unwrap(), b.get_subdevice_name().unwrap()) + println!( + "Rawmidi {:?} (hw:{},{},{}) {} - {}", + b.get_stream(), + a.get_index(), + b.get_device(), + b.get_subdevice(), + a.get_name().unwrap(), + b.get_subdevice_name().unwrap() + ) } } } diff --git a/src/seq.rs b/src/seq.rs index cc4f3fb..1069c1c 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -1,13 +1,13 @@ //! MIDI sequencer I/O and enumeration -use libc::{c_uint, c_int, c_short, c_uchar, c_void, c_long, size_t, pollfd}; use super::error::*; +use super::{poll, Direction}; use crate::alsa; -use super::{Direction, poll}; -use std::{ptr, fmt, mem, slice, time, cell}; -use std::str::{FromStr, Split}; -use std::ffi::CStr; +use libc::{c_int, c_long, c_short, c_uchar, c_uint, c_void, pollfd, size_t}; use std::borrow::Cow; +use std::ffi::CStr; +use std::str::{FromStr, Split}; +use std::{cell, fmt, mem, ptr, slice, time}; // Workaround for improper alignment of snd_seq_ev_ext_t in alsa-sys #[repr(packed)] @@ -26,12 +26,16 @@ pub struct Seq(*mut alsa::snd_seq_t, cell::Cell); unsafe impl Send for Seq {} impl Drop for Seq { - fn drop(&mut self) { unsafe { alsa::snd_seq_close(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_seq_close(self.0) }; + } } impl Seq { fn check_has_input(&self) { - if self.1.get() { panic!("No additional Input object allowed")} + if self.1.get() { + panic!("No additional Input object allowed") + } } /// Opens the sequencer. @@ -85,7 +89,13 @@ impl Seq { pub fn get_any_port_info(&self, a: Addr) -> Result { let c = PortInfo::new()?; - acheck!(snd_seq_get_any_port_info(self.0, a.client as c_int, a.port as c_int, c.0)).map(|_| c) + acheck!(snd_seq_get_any_port_info( + self.0, + a.client as c_int, + a.port as c_int, + c.0 + )) + .map(|_| c) } pub fn create_port(&self, port: &PortInfo) -> Result<()> { @@ -93,7 +103,13 @@ impl Seq { } pub fn create_simple_port(&self, name: &CStr, caps: PortCap, t: PortType) -> Result { - acheck!(snd_seq_create_simple_port(self.0, name.as_ptr(), caps.bits() as c_uint, t.bits() as c_uint)).map(|q| q as i32) + acheck!(snd_seq_create_simple_port( + self.0, + name.as_ptr(), + caps.bits() as c_uint, + t.bits() as c_uint + )) + .map(|q| q as i32) } pub fn set_port_info(&self, port: i32, info: &mut PortInfo) -> Result<()> { @@ -115,10 +131,27 @@ impl Seq { acheck!(snd_seq_unsubscribe_port(self.0, z.0)).map(|_| ()) } - pub fn control_queue(&self, q: i32, t: EventType, value: i32, e: Option<&mut Event>) -> Result<()> { - assert!(EvQueueControl::<()>::has_data(t) || EvQueueControl::::has_data(t) || EvQueueControl::::has_data(t)); + pub fn control_queue( + &self, + q: i32, + t: EventType, + value: i32, + e: Option<&mut Event>, + ) -> Result<()> { + assert!( + EvQueueControl::<()>::has_data(t) + || EvQueueControl::::has_data(t) + || EvQueueControl::::has_data(t) + ); let p = e.map(|e| &mut e.0 as *mut _).unwrap_or(ptr::null_mut()); - acheck!(snd_seq_control_queue(self.0, q as c_int, t as c_int, value as c_int, p)).map(|_| ()) + acheck!(snd_seq_control_queue( + self.0, + q as c_int, + t as c_int, + value as c_int, + p + )) + .map(|_| ()) } pub fn event_output(&self, e: &mut Event) -> Result { @@ -150,8 +183,12 @@ impl Seq { acheck!(snd_seq_get_queue_status(self.0, q as c_int, value.0)).map(|_| value) } - pub fn free_queue(&self, q: i32) -> Result<()> { acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) } - pub fn alloc_queue(&self) -> Result { acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) } + pub fn free_queue(&self, q: i32) -> Result<()> { + acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) + } + pub fn alloc_queue(&self) -> Result { + acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) + } pub fn alloc_named_queue(&self, n: &CStr) -> Result { acheck!(snd_seq_alloc_named_queue(self.0, n.as_ptr())).map(|q| q as i32) } @@ -185,7 +222,9 @@ impl Seq { pub struct Input<'a>(&'a Seq); impl<'a> Drop for Input<'a> { - fn drop(&mut self) { (self.0).1.set(false) } + fn drop(&mut self) { + (self.0).1.set(false) + } } impl<'a> Input<'a> { @@ -202,14 +241,18 @@ impl<'a> Input<'a> { // event is alive. let mut z = ptr::null_mut(); acheck!(snd_seq_event_input((self.0).0, &mut z))?; - unsafe { Event::extract (&mut *z, "snd_seq_event_input") } + unsafe { Event::extract(&mut *z, "snd_seq_event_input") } } pub fn event_input_pending(&self, fetch_sequencer: bool) -> Result { - acheck!(snd_seq_event_input_pending((self.0).0, if fetch_sequencer {1} else {0})).map(|q| q as u32) + acheck!(snd_seq_event_input_pending( + (self.0).0, + if fetch_sequencer { 1 } else { 0 } + )) + .map(|q| q as u32) } - pub fn set_input_buffer_size(&self, size: u32) -> Result<()> { + pub fn set_input_buffer_size(&self, size: u32) -> Result<()> { acheck!(snd_seq_set_input_buffer_size((self.0).0, size as size_t)).map(|_| ()) } @@ -223,24 +266,39 @@ fn polldir(o: Option) -> c_short { None => poll::Flags::IN | poll::Flags::OUT, Some(Direction::Playback) => poll::Flags::OUT, Some(Direction::Capture) => poll::Flags::IN, - }.bits() + } + .bits() } impl<'a> poll::Descriptors for (&'a Seq, Option) { - fn count(&self) -> usize { unsafe { alsa::snd_seq_poll_descriptors_count((self.0).0, polldir(self.1)) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { alsa::snd_seq_poll_descriptors((self.0).0, p.as_mut_ptr(), p.len() as c_uint, polldir(self.1)) }; + let z = unsafe { + alsa::snd_seq_poll_descriptors( + (self.0).0, + p.as_mut_ptr(), + p.len() as c_uint, + polldir(self.1), + ) + }; from_code("snd_seq_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { alsa::snd_seq_poll_descriptors_revents((self.0).0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; - from_code("snd_seq_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { + alsa::snd_seq_poll_descriptors_revents( + (self.0).0, + p.as_ptr() as *mut pollfd, + p.len() as c_uint, + &mut r, + ) + }; + from_code("snd_seq_poll_descriptors_revents", z) + .map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -287,7 +345,9 @@ impl fmt::Debug for ClientInfo { pub struct ClientIter<'a>(&'a Seq, i32); impl<'a> ClientIter<'a> { - pub fn new(seq: &'a Seq) -> Self { ClientIter(seq, -1) } + pub fn new(seq: &'a Seq) -> Self { + ClientIter(seq, -1) + } } impl<'a> Iterator for ClientIter<'a> { @@ -296,7 +356,10 @@ impl<'a> Iterator for ClientIter<'a> { let z = ClientInfo::new().unwrap(); z.set_client(self.1); let r = unsafe { alsa::snd_seq_query_next_client((self.0).0, z.0) }; - if r < 0 { self.1 = -1; return None }; + if r < 0 { + self.1 = -1; + return None; + }; self.1 = z.get_client(); Some(z) } @@ -355,7 +418,9 @@ impl PortInfo { } pub fn get_capability(&self) -> PortCap { - PortCap::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_capability(self.0) as u32 }) + PortCap::from_bits_truncate(unsafe { + alsa::snd_seq_port_info_get_capability(self.0) as u32 + }) } pub fn get_type(&self) -> PortType { @@ -378,28 +443,66 @@ impl PortInfo { } } - pub fn get_midi_channels(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } } - pub fn get_midi_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } } - pub fn get_synth_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } } - pub fn get_read_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } } - pub fn get_write_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } } - pub fn get_port_specified(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } } - pub fn get_timestamping(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } } - pub fn get_timestamp_real(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } } - pub fn get_timestamp_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } } + pub fn get_midi_channels(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } + } + pub fn get_midi_voices(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } + } + pub fn get_synth_voices(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } + } + pub fn get_read_use(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } + } + pub fn get_write_use(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } + } + pub fn get_port_specified(&self) -> bool { + unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } + } + pub fn get_timestamping(&self) -> bool { + unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } + } + pub fn get_timestamp_real(&self) -> bool { + unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } + } + pub fn get_timestamp_queue(&self) -> i32 { + unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } + } - pub fn set_midi_channels(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } } - pub fn set_midi_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } } - pub fn set_synth_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } } - pub fn set_port_specified(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 } ) } } - pub fn set_timestamping(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 } ) } } - pub fn set_timestamp_real(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 } ) } } - pub fn set_timestamp_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } } + pub fn set_midi_channels(&self, value: i32) { + unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } + } + pub fn set_midi_voices(&self, value: i32) { + unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } + } + pub fn set_synth_voices(&self, value: i32) { + unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } + } + pub fn set_port_specified(&self, value: bool) { + unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 }) } + } + pub fn set_timestamping(&self, value: bool) { + unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 }) } + } + pub fn set_timestamp_real(&self, value: bool) { + unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 }) } + } + pub fn set_timestamp_queue(&self, value: i32) { + unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } + } } impl fmt::Debug for PortInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "PortInfo({}:{},{:?})", self.get_client(), self.get_port(), self.get_name()) + write!( + f, + "PortInfo({}:{},{:?})", + self.get_client(), + self.get_port(), + self.get_name() + ) } } @@ -408,7 +511,9 @@ impl fmt::Debug for PortInfo { pub struct PortIter<'a>(&'a Seq, i32, i32); impl<'a> PortIter<'a> { - pub fn new(seq: &'a Seq, client: i32) -> Self { PortIter(seq, client, -1) } + pub fn new(seq: &'a Seq, client: i32) -> Self { + PortIter(seq, client, -1) + } } impl<'a> Iterator for PortIter<'a> { @@ -418,7 +523,10 @@ impl<'a> Iterator for PortIter<'a> { z.set_client(self.1); z.set_port(self.2); let r = unsafe { alsa::snd_seq_query_next_port((self.0).0, z.0) }; - if r < 0 { self.2 = -1; return None }; + if r < 0 { + self.2 = -1; + return None; + }; self.2 = z.get_port(); Some(z) } @@ -481,7 +589,6 @@ bitflags! { } } - /// [snd_seq_addr_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__addr__t.html) wrapper #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] pub struct Addr { @@ -494,27 +601,34 @@ impl FromStr for Addr { fn from_str(s: &str) -> std::result::Result { let mut split: Split<'_, char> = s.trim().split(':'); - let client = split.next() - .ok_or("no client provided")? - .parse::()?; - let port = split.next() - .ok_or("no port provided")? - .parse::()?; + let client = split.next().ok_or("no client provided")?.parse::()?; + let port = split.next().ok_or("no port provided")?.parse::()?; match split.next() { - Some(_) => { - Err("too many arguments".into()) - }, - None => { - Ok(Addr { client, port }) - } + Some(_) => Err("too many arguments".into()), + None => Ok(Addr { client, port }), } } } impl Addr { - pub fn system_timer() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32 } } - pub fn system_announce() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32 } } - pub fn broadcast() -> Addr { Addr { client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32 } } + pub fn system_timer() -> Addr { + Addr { + client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, + port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32, + } + } + pub fn system_announce() -> Addr { + Addr { + client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, + port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32, + } + } + pub fn broadcast() -> Addr { + Addr { + client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, + port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, + } + } } /// [snd_seq_port_subscribe_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper @@ -523,7 +637,9 @@ pub struct PortSubscribe(*mut alsa::snd_seq_port_subscribe_t); unsafe impl Send for PortSubscribe {} impl Drop for PortSubscribe { - fn drop(&mut self) { unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; } + fn drop(&mut self) { + unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; + } } impl PortSubscribe { @@ -539,36 +655,67 @@ impl PortSubscribe { Ok(z) } - pub fn get_sender(&self) -> Addr { unsafe { - let z = alsa::snd_seq_port_subscribe_get_sender(self.0); - Addr { client: (*z).client as i32, port: (*z).port as i32 } - } } + pub fn get_sender(&self) -> Addr { + unsafe { + let z = alsa::snd_seq_port_subscribe_get_sender(self.0); + Addr { + client: (*z).client as i32, + port: (*z).port as i32, + } + } + } - pub fn get_dest(&self) -> Addr { unsafe { - let z = alsa::snd_seq_port_subscribe_get_dest(self.0); - Addr { client: (*z).client as i32, port: (*z).port as i32 } - } } + pub fn get_dest(&self) -> Addr { + unsafe { + let z = alsa::snd_seq_port_subscribe_get_dest(self.0); + Addr { + client: (*z).client as i32, + port: (*z).port as i32, + } + } + } - pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } } - pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } } - pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } } - pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } } + pub fn get_queue(&self) -> i32 { + unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } + } + pub fn get_exclusive(&self) -> bool { + unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } + } + pub fn get_time_update(&self) -> bool { + unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } + } + pub fn get_time_real(&self) -> bool { + unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } + } pub fn set_sender(&self, value: Addr) { - let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar }; + let z = alsa::snd_seq_addr_t { + client: value.client as c_uchar, + port: value.port as c_uchar, + }; unsafe { alsa::snd_seq_port_subscribe_set_sender(self.0, &z) }; } pub fn set_dest(&self, value: Addr) { - let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar }; + let z = alsa::snd_seq_addr_t { + client: value.client as c_uchar, + port: value.port as c_uchar, + }; unsafe { alsa::snd_seq_port_subscribe_set_dest(self.0, &z) }; } - pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } } - pub fn set_exclusive(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 } ) } } - pub fn set_time_update(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 } ) } } - pub fn set_time_real(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 } ) } } - + pub fn set_queue(&self, value: i32) { + unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } + } + pub fn set_exclusive(&self, value: bool) { + unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 }) } + } + pub fn set_time_update(&self, value: bool) { + unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 }) } + } + pub fn set_time_real(&self, value: bool) { + unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 }) } + } } /// [snd_seq_query_subs_type_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper @@ -585,7 +732,9 @@ struct QuerySubscribe(*mut alsa::snd_seq_query_subscribe_t); unsafe impl Send for QuerySubscribe {} impl Drop for QuerySubscribe { - fn drop(&mut self) { unsafe { alsa::snd_seq_query_subscribe_free(self.0) } } + fn drop(&mut self) { + unsafe { alsa::snd_seq_query_subscribe_free(self.0) } + } } impl QuerySubscribe { @@ -594,24 +743,48 @@ impl QuerySubscribe { acheck!(snd_seq_query_subscribe_malloc(&mut q)).map(|_| QuerySubscribe(q)) } - pub fn get_index(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } } - pub fn get_addr(&self) -> Addr { unsafe { - let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0)); - Addr { client: a.client as i32, port: a.port as i32 } - } } - pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } } - pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } } - pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } } - pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } } + pub fn get_index(&self) -> i32 { + unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } + } + pub fn get_addr(&self) -> Addr { + unsafe { + let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0)); + Addr { + client: a.client as i32, + port: a.port as i32, + } + } + } + pub fn get_queue(&self) -> i32 { + unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } + } + pub fn get_exclusive(&self) -> bool { + unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } + } + pub fn get_time_update(&self) -> bool { + unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } + } + pub fn get_time_real(&self) -> bool { + unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } + } - pub fn set_root(&self, value: Addr) { unsafe { - let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar}; - alsa::snd_seq_query_subscribe_set_root(self.0, &a); - } } - pub fn set_type(&self, value: QuerySubsType) { unsafe { - alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t) - } } - pub fn set_index(&self, value: i32) { unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } } + pub fn set_root(&self, value: Addr) { + unsafe { + let a = alsa::snd_seq_addr_t { + client: value.client as c_uchar, + port: value.port as c_uchar, + }; + alsa::snd_seq_query_subscribe_set_root(self.0, &a); + } + } + pub fn set_type(&self, value: QuerySubsType) { + unsafe { + alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t) + } + } + pub fn set_index(&self, value: i32) { + unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } + } } #[derive(Copy, Clone)] @@ -620,12 +793,17 @@ pub struct PortSubscribeIter<'a> { seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType, - index: i32 + index: i32, } impl<'a> PortSubscribeIter<'a> { pub fn new(seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType) -> Self { - PortSubscribeIter {seq, addr, query_subs_type, index: 0 } + PortSubscribeIter { + seq, + addr, + query_subs_type, + index: 0, + } } } @@ -651,8 +829,8 @@ impl<'a> Iterator for PortSubscribeIter<'a> { QuerySubsType::READ => { vtr.set_sender(self.addr); vtr.set_dest(query.get_addr()); - }, - QuerySubsType:: WRITE => { + } + QuerySubsType::WRITE => { vtr.set_sender(query.get_addr()); vtr.set_dest(self.addr); } @@ -680,7 +858,10 @@ unsafe impl<'a> Send for Event<'a> {} impl<'a> Event<'a> { /// Creates a new event. For events that carry variable-length data (e.g. Sysex), `new_ext` has to be used instead. pub fn new(t: EventType, data: &D) -> Event<'static> { - assert!(!Event::has_ext_data(t), "event type must not carry variable-length data"); + assert!( + !Event::has_ext_data(t), + "event type must not carry variable-length data" + ); let mut z = Event(unsafe { mem::zeroed() }, t, None); (z.0).type_ = t as c_uchar; (z.0).flags |= Event::get_length_flag(t); @@ -691,7 +872,10 @@ impl<'a> Event<'a> { /// Creates a new event carrying variable-length data. This is required for event types `Sysex`, `Bounce`, and the `UsrVar` types. pub fn new_ext>>(t: EventType, data: D) -> Event<'a> { - assert!(Event::has_ext_data(t), "event type must carry variable-length data"); + assert!( + Event::has_ext_data(t), + "event type must carry variable-length data" + ); let mut z = Event(unsafe { mem::zeroed() }, t, Some(data.into())); (z.0).type_ = t as c_uchar; (z.0).flags |= Event::get_length_flag(t); @@ -702,7 +886,11 @@ impl<'a> Event<'a> { /// buffer for variable length messages (e.g. SysEx) has been copied into the event. /// The returned event has a static lifetime, i e, it's decoupled from the original buffer. pub fn into_owned(self) -> Event<'static> { - Event(self.0, self.1, self.2.map(|cow| Cow::Owned(cow.into_owned()))) + Event( + self.0, + self.1, + self.2.map(|cow| Cow::Owned(cow.into_owned())), + ) } fn get_length_flag(t: EventType) -> u8 { @@ -714,7 +902,7 @@ impl<'a> Event<'a> { EventType::UsrVar2 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, EventType::UsrVar3 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, EventType::UsrVar4 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, - _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED + _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED, } } @@ -723,12 +911,19 @@ impl<'a> Event<'a> { } /// Extracts event type and data. Produces a result with an arbitrary lifetime, hence the unsafety. - unsafe fn extract<'any>(z: &mut alsa::snd_seq_event_t, func: &'static str) -> Result> { + unsafe fn extract<'any>( + z: &mut alsa::snd_seq_event_t, + func: &'static str, + ) -> Result> { let t = EventType::from_c_int((*z).type_ as c_int, func)?; let ext_data = if Event::has_ext_data(t) { - assert_ne!((*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, alsa::SND_SEQ_EVENT_LENGTH_FIXED); + assert_ne!( + (*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, + alsa::SND_SEQ_EVENT_LENGTH_FIXED + ); Some(Cow::Borrowed({ - let zz: &EvExtPacked = &*(&(*z).data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _); + let zz: &EvExtPacked = + &*(&(*z).data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _); slice::from_raw_parts((*zz).ptr as *mut u8, (*zz).len as usize) })) } else { @@ -740,24 +935,35 @@ impl<'a> Event<'a> { /// Ensures that the ev.ext union element points to the correct resize_buffer for events /// with variable length content fn ensure_buf(&mut self) { - if !Event::has_ext_data(self.1) { return; } + if !Event::has_ext_data(self.1) { + return; + } let slice: &[u8] = match self.2 { Some(Cow::Owned(ref mut vec)) => &vec[..], Some(Cow::Borrowed(buf)) => buf, // The following case is always a logic error in the program, thus panicking is okay. - None => panic!("event type requires variable-length data, but none was provided") + None => panic!("event type requires variable-length data, but none was provided"), }; - let z: &mut EvExtPacked = unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + let z: &mut EvExtPacked = + unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; z.len = slice.len() as c_uint; z.ptr = slice.as_ptr() as *mut c_void; } #[inline] - pub fn get_type(&self) -> EventType { self.1 } + pub fn get_type(&self) -> EventType { + self.1 + } /// Extract the event data from an event. /// Use `get_ext` instead for events carrying variable-length data. - pub fn get_data(&self) -> Option { if D::has_data(self.1) { Some(D::get_data(self)) } else { None } } + pub fn get_data(&self) -> Option { + if D::has_data(self.1) { + Some(D::get_data(self)) + } else { + None + } + } /// Extract the variable-length data carried by events of type `Sysex`, `Bounce`, or the `UsrVar` types. pub fn get_ext(&self) -> Option<&[u8]> { @@ -766,7 +972,7 @@ impl<'a> Event<'a> { Some(Cow::Owned(ref vec)) => Some(&vec[..]), Some(Cow::Borrowed(buf)) => Some(buf), // The following case is always a logic error in the program, thus panicking is okay. - None => panic!("event type requires variable-length data, but none was found") + None => panic!("event type requires variable-length data, but none was found"), } } else { None @@ -778,19 +984,47 @@ impl<'a> Event<'a> { self.0.dest.port = alsa::SND_SEQ_ADDRESS_UNKNOWN; } - pub fn set_source(&mut self, p: i32) { self.0.source.port = p as u8 } - pub fn set_dest(&mut self, d: Addr) { self.0.dest.client = d.client as c_uchar; self.0.dest.port = d.port as c_uchar; } - pub fn set_tag(&mut self, t: u8) { self.0.tag = t as c_uchar; } - pub fn set_queue(&mut self, q: i32) { self.0.queue = q as c_uchar; } + pub fn set_source(&mut self, p: i32) { + self.0.source.port = p as u8 + } + pub fn set_dest(&mut self, d: Addr) { + self.0.dest.client = d.client as c_uchar; + self.0.dest.port = d.port as c_uchar; + } + pub fn set_tag(&mut self, t: u8) { + self.0.tag = t as c_uchar; + } + pub fn set_queue(&mut self, q: i32) { + self.0.queue = q as c_uchar; + } - pub fn get_source(&self) -> Addr { Addr { client: self.0.source.client as i32, port: self.0.source.port as i32 } } - pub fn get_dest(&self) -> Addr { Addr { client: self.0.dest.client as i32, port: self.0.dest.port as i32 } } - pub fn get_tag(&self) -> u8 { self.0.tag as u8 } - pub fn get_queue(&self) -> i32 { self.0.queue as i32 } + pub fn get_source(&self) -> Addr { + Addr { + client: self.0.source.client as i32, + port: self.0.source.port as i32, + } + } + pub fn get_dest(&self) -> Addr { + Addr { + client: self.0.dest.client as i32, + port: self.0.dest.port as i32, + } + } + pub fn get_tag(&self) -> u8 { + self.0.tag as u8 + } + pub fn get_queue(&self) -> i32 { + self.0.queue as i32 + } pub fn schedule_real(&mut self, queue: i32, relative: bool, rtime: time::Duration) { self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK); - self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS }); + self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL + | (if relative { + alsa::SND_SEQ_TIME_MODE_REL + } else { + alsa::SND_SEQ_TIME_MODE_ABS + }); self.0.queue = queue as u8; let t = unsafe { &mut self.0.time.time }; t.tv_sec = rtime.as_secs() as c_uint; @@ -799,22 +1033,33 @@ impl<'a> Event<'a> { pub fn schedule_tick(&mut self, queue: i32, relative: bool, ttime: u32) { self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK); - self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS }); + self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK + | (if relative { + alsa::SND_SEQ_TIME_MODE_REL + } else { + alsa::SND_SEQ_TIME_MODE_ABS + }); self.0.queue = queue as u8; let t = unsafe { &mut self.0.time.tick }; *t = ttime as c_uint; } - pub fn set_direct(&mut self) { self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT } + pub fn set_direct(&mut self) { + self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT + } - pub fn get_relative(&self) -> bool { (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 } + pub fn get_relative(&self) -> bool { + (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 + } pub fn get_time(&self) -> Option { if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) != 0 { let d = self.0.time; let t = unsafe { &d.time }; Some(time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)) - } else { None } + } else { + None + } } pub fn get_tick(&self) -> Option { @@ -822,37 +1067,68 @@ impl<'a> Event<'a> { let d = self.0.time; let t = unsafe { &d.tick }; Some(*t) - } else { None } + } else { + None + } } /// Returns true if the message is high priority. - pub fn get_priority(&self) -> bool { (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 } + pub fn get_priority(&self) -> bool { + (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 + } pub fn set_priority(&mut self, is_high_prio: bool) { - if is_high_prio { self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; } - else { self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; } + if is_high_prio { + self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; + } else { + self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; + } } } impl<'a> Clone for Event<'a> { - fn clone(&self) -> Self { Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) } + fn clone(&self) -> Self { + Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) + } } impl<'a> fmt::Debug for Event<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut x = f.debug_tuple("Event"); x.field(&self.1); - if let Some(z) = self.get_data::() { x.field(&z); } - if let Some(z) = self.get_data::() { x.field(&z); } - if let Some(z) = self.get_data::() { x.field(&z); } - if let Some(z) = self.get_data::() { x.field(&z); } - if let Some(z) = self.get_data::>() { x.field(&z); } - if let Some(z) = self.get_data::>() { x.field(&z); } - if let Some(z) = self.get_data::>() { x.field(&z); } - if let Some(z) = self.get_data::>() { x.field(&z); } - if let Some(z) = self.get_data::() { x.field(&z); } - if let Some(z) = self.get_data::<[u8; 12]>() { x.field(&z); } - if let Some(z) = self.get_ext() { x.field(&z); } + if let Some(z) = self.get_data::() { + x.field(&z); + } + if let Some(z) = self.get_data::() { + x.field(&z); + } + if let Some(z) = self.get_data::() { + x.field(&z); + } + if let Some(z) = self.get_data::() { + x.field(&z); + } + if let Some(z) = self.get_data::>() { + x.field(&z); + } + if let Some(z) = self.get_data::>() { + x.field(&z); + } + if let Some(z) = self.get_data::>() { + x.field(&z); + } + if let Some(z) = self.get_data::>() { + x.field(&z); + } + if let Some(z) = self.get_data::() { + x.field(&z); + } + if let Some(z) = self.get_data::<[u8; 12]>() { + x.field(&z); + } + if let Some(z) = self.get_ext() { + x.field(&z); + } x.finish() } } @@ -872,43 +1148,43 @@ pub trait EventData { impl EventData for () { fn get_data(_: &Event) -> Self {} fn has_data(e: EventType) -> bool { - matches!(e, - EventType::TuneRequest | - EventType::Reset | - EventType::Sensing | - EventType::None) + matches!( + e, + EventType::TuneRequest | EventType::Reset | EventType::Sensing | EventType::None + ) } fn set_data(&self, _: &mut Event) {} } impl EventData for [u8; 12] { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.raw8 }; - z.d + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.raw8 }; + z.d } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::Echo | - EventType::Oss | - EventType::Usr0 | - EventType::Usr1 | - EventType::Usr2 | - EventType::Usr3 | - EventType::Usr4 | - EventType::Usr5 | - EventType::Usr6 | - EventType::Usr7 | - EventType::Usr8 | - EventType::Usr9) + matches!( + e, + EventType::Echo + | EventType::Oss + | EventType::Usr0 + | EventType::Usr1 + | EventType::Usr2 + | EventType::Usr3 + | EventType::Usr4 + | EventType::Usr5 + | EventType::Usr6 + | EventType::Usr7 + | EventType::Usr8 + | EventType::Usr9 + ) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.raw8 }; - z.d = *self; + let z = unsafe { &mut ev.0.data.raw8 }; + z.d = *self; } } - #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)] pub struct EvNote { pub channel: u8, @@ -920,23 +1196,30 @@ pub struct EvNote { impl EventData for EvNote { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_ev_note_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - EvNote { channel: z.channel as u8, note: z.note as u8, velocity: z.velocity as u8, off_velocity: z.off_velocity as u8, duration: z.duration as u32 } + let z: &alsa::snd_seq_ev_note_t = + unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + EvNote { + channel: z.channel as u8, + note: z.note as u8, + velocity: z.velocity as u8, + off_velocity: z.off_velocity as u8, + duration: z.duration as u32, + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::Note | - EventType::Noteon | - EventType::Noteoff | - EventType::Keypress) + matches!( + e, + EventType::Note | EventType::Noteon | EventType::Noteoff | EventType::Keypress + ) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_ev_note_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.channel = self.channel as c_uchar; - z.note = self.note as c_uchar; - z.velocity = self.velocity as c_uchar; - z.off_velocity = self.off_velocity as c_uchar; - z.duration = self.duration as c_uint; + let z: &mut alsa::snd_seq_ev_note_t = + unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.channel = self.channel as c_uchar; + z.note = self.note as c_uchar; + z.velocity = self.velocity as c_uchar; + z.off_velocity = self.off_velocity as c_uchar; + z.duration = self.duration as c_uint; } } @@ -949,50 +1232,65 @@ pub struct EvCtrl { impl EventData for EvCtrl { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_ev_ctrl_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - EvCtrl { channel: z.channel as u8, param: z.param as u32, value: z.value as i32 } + let z: &alsa::snd_seq_ev_ctrl_t = + unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + EvCtrl { + channel: z.channel as u8, + param: z.param as u32, + value: z.value as i32, + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::Controller | - EventType::Pgmchange | - EventType::Chanpress | - EventType::Pitchbend | - EventType::Control14 | - EventType::Nonregparam | - EventType::Regparam | - EventType::Songpos | - EventType::Songsel | - EventType::Qframe | - EventType::Timesign | - EventType::Keysign) + matches!( + e, + EventType::Controller + | EventType::Pgmchange + | EventType::Chanpress + | EventType::Pitchbend + | EventType::Control14 + | EventType::Nonregparam + | EventType::Regparam + | EventType::Songpos + | EventType::Songsel + | EventType::Qframe + | EventType::Timesign + | EventType::Keysign + ) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_ev_ctrl_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.channel = self.channel as c_uchar; - z.param = self.param as c_uint; - z.value = self.value as c_int; + let z: &mut alsa::snd_seq_ev_ctrl_t = + unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.channel = self.channel as c_uchar; + z.param = self.param as c_uint; + z.value = self.value as c_int; } } impl EventData for Addr { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_addr_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - Addr { client: z.client as i32, port: z.port as i32 } + let z: &alsa::snd_seq_addr_t = + unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + Addr { + client: z.client as i32, + port: z.port as i32, + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::ClientStart | - EventType::ClientExit | - EventType::ClientChange | - EventType::PortStart | - EventType::PortExit | - EventType::PortChange) + matches!( + e, + EventType::ClientStart + | EventType::ClientExit + | EventType::ClientChange + | EventType::PortStart + | EventType::PortExit + | EventType::PortChange + ) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_addr_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.client = self.client as c_uchar; - z.port = self.port as c_uchar; + let z: &mut alsa::snd_seq_addr_t = + unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.client = self.client as c_uchar; + z.port = self.port as c_uchar; } } @@ -1005,24 +1303,28 @@ pub struct Connect { impl EventData for Connect { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.connect }; - Connect { - sender: Addr { client: z.sender.client as i32, port: z.sender.port as i32 }, - dest: Addr { client: z.dest.client as i32, port: z.dest.port as i32 } - } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.connect }; + Connect { + sender: Addr { + client: z.sender.client as i32, + port: z.sender.port as i32, + }, + dest: Addr { + client: z.dest.client as i32, + port: z.dest.port as i32, + }, + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::PortSubscribed | - EventType::PortUnsubscribed) + matches!(e, EventType::PortSubscribed | EventType::PortUnsubscribed) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.connect }; - z.sender.client = self.sender.client as c_uchar; - z.sender.port = self.sender.port as c_uchar; - z.dest.client = self.dest.client as c_uchar; - z.dest.port = self.dest.port as c_uchar; + let z = unsafe { &mut ev.0.data.connect }; + z.sender.client = self.sender.client as c_uchar; + z.sender.port = self.sender.port as c_uchar; + z.dest.client = self.dest.client as c_uchar; + z.dest.port = self.dest.port as c_uchar; } } @@ -1039,78 +1341,102 @@ pub struct EvQueueControl { impl EventData for EvQueueControl<()> { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.queue }; - EvQueueControl { queue: z.queue as i32, value: () } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.queue }; + EvQueueControl { + queue: z.queue as i32, + value: (), + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::Start | - EventType::Continue | - EventType::Stop | - EventType::Clock | - EventType::QueueSkew) + matches!( + e, + EventType::Start + | EventType::Continue + | EventType::Stop + | EventType::Clock + | EventType::QueueSkew + ) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.queue }; - z.queue = self.queue as c_uchar; + let z = unsafe { &mut ev.0.data.queue }; + z.queue = self.queue as c_uchar; } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - EvQueueControl { queue: z.queue as i32, value: z.param.value as i32 } - } } + fn get_data(ev: &Event) -> Self { + unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + EvQueueControl { + queue: z.queue as i32, + value: z.param.value as i32, + } + } + } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::Tempo) + matches!(e, EventType::Tempo) + } + fn set_data(&self, ev: &mut Event) { + unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + z.param.value = self.value as c_int; + } } - fn set_data(&self, ev: &mut Event) { unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - z.param.value = self.value as c_int; - } } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - EvQueueControl { queue: z.queue as i32, value: z.param.position as u32 } - } } + fn get_data(ev: &Event) -> Self { + unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + EvQueueControl { + queue: z.queue as i32, + value: z.param.position as u32, + } + } + } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::SyncPos | - EventType::Tick | - EventType::SetposTick) + matches!( + e, + EventType::SyncPos | EventType::Tick | EventType::SetposTick + ) + } + fn set_data(&self, ev: &mut Event) { + unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + z.param.position = self.value as c_uint; + } } - fn set_data(&self, ev: &mut Event) { unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - z.param.position = self.value as c_uint; - } } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - let t = &mut z.param.time.time; - EvQueueControl { queue: z.queue as i32, value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) } - } } + fn get_data(ev: &Event) -> Self { + unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + let t = &mut z.param.time.time; + EvQueueControl { + queue: z.queue as i32, + value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32), + } + } + } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::SetposTime) + matches!(e, EventType::SetposTime) + } + fn set_data(&self, ev: &mut Event) { + unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + let t = &mut z.param.time.time; + t.tv_sec = self.value.as_secs() as c_uint; + t.tv_nsec = self.value.subsec_nanos() as c_uint; + } } - fn set_data(&self, ev: &mut Event) { unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - let t = &mut z.param.time.time; - t.tv_sec = self.value.as_secs() as c_uint; - t.tv_nsec = self.value.subsec_nanos() as c_uint; - } } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)] @@ -1124,24 +1450,23 @@ pub struct EvResult { impl EventData for EvResult { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.result }; - EvResult { event: z.event as i32, result: z.result as i32 } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.result }; + EvResult { + event: z.event as i32, + result: z.result as i32, + } } fn has_data(e: EventType) -> bool { - matches!(e, - EventType::System | - EventType::Result) + matches!(e, EventType::System | EventType::Result) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.result }; - z.event = self.event as c_int; - z.result = self.result as c_int; + let z = unsafe { &mut ev.0.data.result }; + z.event = self.event as c_int; + z.result = self.result as c_int; } } - - alsa_enum!( /// [SND_SEQ_EVENT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_events.html) constants @@ -1214,7 +1539,9 @@ pub struct QueueTempo(*mut alsa::snd_seq_queue_tempo_t); unsafe impl Send for QueueTempo {} impl Drop for QueueTempo { - fn drop(&mut self) { unsafe { alsa::snd_seq_queue_tempo_free(self.0) } } + fn drop(&mut self) { + unsafe { alsa::snd_seq_queue_tempo_free(self.0) } + } } impl QueueTempo { @@ -1230,17 +1557,35 @@ impl QueueTempo { Ok(q) } - pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } } - pub fn get_tempo(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } } - pub fn get_ppq(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } } - pub fn get_skew(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } } - pub fn get_skew_base(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } } + pub fn get_queue(&self) -> i32 { + unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } + } + pub fn get_tempo(&self) -> u32 { + unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } + } + pub fn get_ppq(&self) -> i32 { + unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } + } + pub fn get_skew(&self) -> u32 { + unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } + } + pub fn get_skew_base(&self) -> u32 { + unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } + } -// pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } } - pub fn set_tempo(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } } - pub fn set_ppq(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } } - pub fn set_skew(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } } - pub fn set_skew_base(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } } + // pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } } + pub fn set_tempo(&self, value: u32) { + unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } + } + pub fn set_ppq(&self, value: i32) { + unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } + } + pub fn set_skew(&self, value: u32) { + unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } + } + pub fn set_skew_base(&self, value: u32) { + unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } + } } /// [snd_seq_queue_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper @@ -1249,7 +1594,9 @@ pub struct QueueStatus(*mut alsa::snd_seq_queue_status_t); unsafe impl Send for QueueStatus {} impl Drop for QueueStatus { - fn drop(&mut self) { unsafe { alsa::snd_seq_queue_status_free(self.0) } } + fn drop(&mut self) { + unsafe { alsa::snd_seq_queue_status_free(self.0) } + } } impl QueueStatus { @@ -1265,14 +1612,24 @@ impl QueueStatus { Ok(q) } - pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } } - pub fn get_events(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } } - pub fn get_tick_time(&self) -> u32 { unsafe {alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } } - pub fn get_real_time(&self) -> time::Duration { unsafe { - let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0)); - time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) - } } - pub fn get_status(&self) -> u32 { unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } } + pub fn get_queue(&self) -> i32 { + unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } + } + pub fn get_events(&self) -> i32 { + unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } + } + pub fn get_tick_time(&self) -> u32 { + unsafe { alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } + } + pub fn get_real_time(&self) -> time::Duration { + unsafe { + let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0)); + time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) + } + } + pub fn get_status(&self) -> u32 { + unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } + } } /// [snd_seq_remove_events_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) wrapper @@ -1281,7 +1638,9 @@ pub struct RemoveEvents(*mut alsa::snd_seq_remove_events_t); unsafe impl Send for RemoveEvents {} impl Drop for RemoveEvents { - fn drop(&mut self) { unsafe { alsa::snd_seq_remove_events_free(self.0) } } + fn drop(&mut self) { + unsafe { alsa::snd_seq_remove_events_free(self.0) } + } } impl RemoveEvents { @@ -1290,49 +1649,87 @@ impl RemoveEvents { acheck!(snd_seq_remove_events_malloc(&mut q)).map(|_| RemoveEvents(q)) } - pub fn get_condition(&self) -> Remove { unsafe { - Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32) - } } - pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } } - pub fn get_time(&self) -> time::Duration { unsafe { - let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0)); - let t = &d.time; - - time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) - } } - pub fn get_dest(&self) -> Addr { unsafe { - let a = &(*alsa::snd_seq_remove_events_get_dest(self.0)); + pub fn get_condition(&self) -> Remove { + unsafe { + Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32) + } + } + pub fn get_queue(&self) -> i32 { + unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } + } + pub fn get_time(&self) -> time::Duration { + unsafe { + let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0)); + let t = &d.time; - Addr { client: a.client as i32, port: a.port as i32 } - } } - pub fn get_channel(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } } - pub fn get_event_type(&self) -> Result { unsafe { - EventType::from_c_int(alsa::snd_seq_remove_events_get_event_type(self.0), "snd_seq_remove_events_get_event_type") - } } - pub fn get_tag(&self) -> u8 { unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } } + time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) + } + } + pub fn get_dest(&self) -> Addr { + unsafe { + let a = &(*alsa::snd_seq_remove_events_get_dest(self.0)); + Addr { + client: a.client as i32, + port: a.port as i32, + } + } + } + pub fn get_channel(&self) -> i32 { + unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } + } + pub fn get_event_type(&self) -> Result { + unsafe { + EventType::from_c_int( + alsa::snd_seq_remove_events_get_event_type(self.0), + "snd_seq_remove_events_get_event_type", + ) + } + } + pub fn get_tag(&self) -> u8 { + unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } + } - pub fn set_condition(&self, value: Remove) { unsafe { - alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint); - } } - pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } } - pub fn set_time(&self, value: time::Duration) { unsafe { - let mut d: alsa::snd_seq_timestamp_t = mem::zeroed(); - let t = &mut d.time; + pub fn set_condition(&self, value: Remove) { + unsafe { + alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint); + } + } + pub fn set_queue(&self, value: i32) { + unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } + } + pub fn set_time(&self, value: time::Duration) { + unsafe { + let mut d: alsa::snd_seq_timestamp_t = mem::zeroed(); + let t = &mut d.time; - t.tv_sec = value.as_secs() as c_uint; - t.tv_nsec = value.subsec_nanos() as c_uint; + t.tv_sec = value.as_secs() as c_uint; + t.tv_nsec = value.subsec_nanos() as c_uint; - alsa::snd_seq_remove_events_set_time(self.0, &d); - } } - pub fn set_dest(&self, value: Addr) { unsafe { - let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar}; + alsa::snd_seq_remove_events_set_time(self.0, &d); + } + } + pub fn set_dest(&self, value: Addr) { + unsafe { + let a = alsa::snd_seq_addr_t { + client: value.client as c_uchar, + port: value.port as c_uchar, + }; - alsa::snd_seq_remove_events_set_dest(self.0, &a); - } } - pub fn set_channel(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } } - pub fn set_event_type(&self, value: EventType) { unsafe { alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); } } - pub fn set_tag(&self, value: u8) { unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } } + alsa::snd_seq_remove_events_set_dest(self.0, &a); + } + } + pub fn set_channel(&self, value: i32) { + unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } + } + pub fn set_event_type(&self, value: EventType) { + unsafe { + alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); + } + } + pub fn set_tag(&self, value: u8) { + unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } + } } /// [snd_midi_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___m_i_d_i___event.html) Wrapper @@ -1341,7 +1738,9 @@ impl RemoveEvents { pub struct MidiEvent(*mut alsa::snd_midi_event_t); impl Drop for MidiEvent { - fn drop(&mut self) { unsafe { alsa::snd_midi_event_free(self.0) } } + fn drop(&mut self) { + unsafe { alsa::snd_midi_event_free(self.0) } + } } impl MidiEvent { @@ -1350,23 +1749,39 @@ impl MidiEvent { acheck!(snd_midi_event_new(bufsize as size_t, &mut q)).map(|_| MidiEvent(q)) } - pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) } + pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { + acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) + } /// Note: this corresponds to snd_midi_event_no_status, but on and off are switched. /// /// Alsa-lib is a bit confusing here. Anyhow, set "enable" to true to enable running status. - pub fn enable_running_status(&self, enable: bool) { unsafe { alsa::snd_midi_event_no_status(self.0, if enable {0} else {1}) } } + pub fn enable_running_status(&self, enable: bool) { + unsafe { alsa::snd_midi_event_no_status(self.0, if enable { 0 } else { 1 }) } + } /// Resets both encoder and decoder - pub fn init(&self) { unsafe { alsa::snd_midi_event_init(self.0) } } + pub fn init(&self) { + unsafe { alsa::snd_midi_event_init(self.0) } + } - pub fn reset_encode(&self) { unsafe { alsa::snd_midi_event_reset_encode(self.0) } } + pub fn reset_encode(&self) { + unsafe { alsa::snd_midi_event_reset_encode(self.0) } + } - pub fn reset_decode(&self) { unsafe { alsa::snd_midi_event_reset_decode(self.0) } } + pub fn reset_decode(&self) { + unsafe { alsa::snd_midi_event_reset_decode(self.0) } + } pub fn decode(&self, buf: &mut [u8], ev: &mut Event) -> Result { ev.ensure_buf(); - acheck!(snd_midi_event_decode(self.0, buf.as_mut_ptr() as *mut c_uchar, buf.len() as c_long, &ev.0)).map(|r| r as usize) + acheck!(snd_midi_event_decode( + self.0, + buf.as_mut_ptr() as *mut c_uchar, + buf.len() as c_long, + &ev.0 + )) + .map(|r| r as usize) } /// In case of success, returns a tuple of (bytes consumed from buf, found Event). @@ -1376,12 +1791,17 @@ impl MidiEvent { // buffer). We make this safe by taking self by unique reference and coupling it to // the event's lifetime. let mut ev = unsafe { mem::zeroed() }; - let r = acheck!(snd_midi_event_encode(self.0, buf.as_ptr() as *const c_uchar, buf.len() as c_long, &mut ev))?; + let r = acheck!(snd_midi_event_encode( + self.0, + buf.as_ptr() as *const c_uchar, + buf.len() as c_long, + &mut ev + ))?; let e = if ev.type_ == alsa::SND_SEQ_EVENT_NONE as u8 { - None - } else { - Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?) - }; + None + } else { + Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?) + }; Ok((r as usize, e)) } } @@ -1390,7 +1810,8 @@ impl MidiEvent { fn print_seqs() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()).unwrap(); + s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()) + .unwrap(); let clients: Vec<_> = ClientIter::new(&s).collect(); for a in &clients { let ports: Vec<_> = PortIter::new(&s, a.get_client()).collect(); @@ -1402,14 +1823,18 @@ fn print_seqs() { fn seq_subscribe() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()).unwrap(); + s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()) + .unwrap(); let timer_info = s.get_any_port_info(Addr { client: 0, port: 0 }).unwrap(); assert_eq!(timer_info.get_name().unwrap(), "Timer"); let info = PortInfo::empty().unwrap(); let _port = s.create_port(&info); let subs = PortSubscribe::empty().unwrap(); subs.set_sender(Addr { client: 0, port: 0 }); - subs.set_dest(Addr { client: s.client_id().unwrap(), port: info.get_port() }); + subs.set_dest(Addr { + client: s.client_id().unwrap(), + port: info.get_port(), + }); s.subscribe_port(&subs).unwrap(); } @@ -1417,7 +1842,8 @@ fn seq_subscribe() { fn seq_loopback() { use std::ffi::CString; let s = super::Seq::open(Some(&CString::new("default").unwrap()), None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()).unwrap(); + s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()) + .unwrap(); // Create ports let sinfo = PortInfo::empty().unwrap(); @@ -1433,13 +1859,25 @@ fn seq_loopback() { // Connect them let subs = PortSubscribe::empty().unwrap(); - subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport }); - subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport }); + subs.set_sender(Addr { + client: s.client_id().unwrap(), + port: sport, + }); + subs.set_dest(Addr { + client: s.client_id().unwrap(), + port: dport, + }); s.subscribe_port(&subs).unwrap(); println!("Connected {:?} to {:?}", subs.get_sender(), subs.get_dest()); // Send a note! - let note = EvNote { channel: 0, note: 64, duration: 100, velocity: 100, off_velocity: 64 }; + let note = EvNote { + channel: 0, + note: 64, + duration: 100, + velocity: 100, + off_velocity: 64, + }; let mut e = Event::new(EventType::Noteon, ¬e); e.set_subs(); e.set_direct(); @@ -1482,7 +1920,8 @@ fn seq_decode_sysex() { fn seq_get_input_twice() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()).unwrap(); + s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()) + .unwrap(); let input1 = s.input(); let input2 = s.input(); // this should panic let _ = (input1, input2); @@ -1493,19 +1932,45 @@ fn seq_has_data() { for v in EventType::all() { let v = *v; let mut i = 0; - if <() as EventData>::has_data(v) { i += 1; } - if <[u8; 12] as EventData>::has_data(v) { i += 1; } - if Event::has_ext_data(v) { i += 1; } - if EvNote::has_data(v) { i += 1; } - if EvCtrl::has_data(v) { i += 1; } - if Addr::has_data(v) { i += 1; } - if Connect::has_data(v) { i += 1; } - if EvResult::has_data(v) { i += 1; } - if EvQueueControl::<()>::has_data(v) { i += 1; } - if EvQueueControl::::has_data(v) { i += 1; } - if EvQueueControl::::has_data(v) { i += 1; } - if EvQueueControl::::has_data(v) { i += 1; } - if i != 1 { panic!("{:?}: {} has_data", v, i) } + if <() as EventData>::has_data(v) { + i += 1; + } + if <[u8; 12] as EventData>::has_data(v) { + i += 1; + } + if Event::has_ext_data(v) { + i += 1; + } + if EvNote::has_data(v) { + i += 1; + } + if EvCtrl::has_data(v) { + i += 1; + } + if Addr::has_data(v) { + i += 1; + } + if Connect::has_data(v) { + i += 1; + } + if EvResult::has_data(v) { + i += 1; + } + if EvQueueControl::<()>::has_data(v) { + i += 1; + } + if EvQueueControl::::has_data(v) { + i += 1; + } + if EvQueueControl::::has_data(v) { + i += 1; + } + if EvQueueControl::::has_data(v) { + i += 1; + } + if i != 1 { + panic!("{:?}: {} has_data", v, i) + } } } @@ -1513,19 +1978,30 @@ fn seq_has_data() { fn seq_remove_events() -> std::result::Result<(), Box> { let info = RemoveEvents::new()?; - info.set_condition(Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH); info.set_queue(123); info.set_time(time::Duration::new(456, 789)); - info.set_dest(Addr { client: 212, port: 121 }); + info.set_dest(Addr { + client: 212, + port: 121, + }); info.set_channel(15); info.set_event_type(EventType::Noteon); info.set_tag(213); - assert_eq!(info.get_condition(), Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH); + assert_eq!( + info.get_condition(), + Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH + ); assert_eq!(info.get_queue(), 123); assert_eq!(info.get_time(), time::Duration::new(456, 789)); - assert_eq!(info.get_dest(), Addr { client: 212, port: 121 }); + assert_eq!( + info.get_dest(), + Addr { + client: 212, + port: 121 + } + ); assert_eq!(info.get_channel(), 15); assert_eq!(info.get_event_type()?, EventType::Noteon); assert_eq!(info.get_tag(), 213); @@ -1551,27 +2027,51 @@ fn seq_portsubscribeiter() { // Connect them let subs = PortSubscribe::empty().unwrap(); - subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport }); - subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport }); + subs.set_sender(Addr { + client: s.client_id().unwrap(), + port: sport, + }); + subs.set_dest(Addr { + client: s.client_id().unwrap(), + port: dport, + }); s.subscribe_port(&subs).unwrap(); // Query READ subs from sport's point of view - let read_subs: Vec = PortSubscribeIter::new(&s, - Addr {client: s.client_id().unwrap(), port: sport }, - QuerySubsType::READ).collect(); + let read_subs: Vec = PortSubscribeIter::new( + &s, + Addr { + client: s.client_id().unwrap(), + port: sport, + }, + QuerySubsType::READ, + ) + .collect(); assert_eq!(read_subs.len(), 1); assert_eq!(read_subs[0].get_sender(), subs.get_sender()); assert_eq!(read_subs[0].get_dest(), subs.get_dest()); - let write_subs: Vec = PortSubscribeIter::new(&s, - Addr {client: s.client_id().unwrap(), port: sport }, - QuerySubsType::WRITE).collect(); + let write_subs: Vec = PortSubscribeIter::new( + &s, + Addr { + client: s.client_id().unwrap(), + port: sport, + }, + QuerySubsType::WRITE, + ) + .collect(); assert_eq!(write_subs.len(), 0); // Now query WRITE subs from dport's point of view - let write_subs: Vec = PortSubscribeIter::new(&s, - Addr {client: s.client_id().unwrap(), port: dport }, - QuerySubsType::WRITE).collect(); + let write_subs: Vec = PortSubscribeIter::new( + &s, + Addr { + client: s.client_id().unwrap(), + port: dport, + }, + QuerySubsType::WRITE, + ) + .collect(); assert_eq!(write_subs.len(), 1); assert_eq!(write_subs[0].get_sender(), subs.get_sender()); assert_eq!(write_subs[0].get_dest(), subs.get_dest()); From b4a4a31017cfa25239adf598b9536df2873a653a Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 7 Sep 2025 20:03:39 +0200 Subject: [PATCH 2/4] feat: add get_periods_min and get_periods_max to HwParams --- src/pcm.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/pcm.rs b/src/pcm.rs index ea82346..6360e87 100644 --- a/src/pcm.rs +++ b/src/pcm.rs @@ -1264,6 +1264,16 @@ impl<'a> HwParams<'a> { acheck!(snd_pcm_hw_params_get_periods(self.0, &mut v, &mut d)).map(|_| v as u32) } + pub fn get_periods_min(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_periods_min(self.0, &mut v, &mut d)).map(|_| v as u32) + } + + pub fn get_periods_max(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_periods_max(self.0, &mut v, &mut d)).map(|_| v as u32) + } + pub fn set_buffer_size_near(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; acheck!(snd_pcm_hw_params_set_buffer_size_near( From fbae5d4eab051fa59d167295ff43995c982ab55d Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 7 Sep 2025 21:01:35 +0200 Subject: [PATCH 3/4] feat: add period and buffer time/size min, max, and get/set methods to HwParams --- src/pcm.rs | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/src/pcm.rs b/src/pcm.rs index 6360e87..bcb4ed3 100644 --- a/src/pcm.rs +++ b/src/pcm.rs @@ -1216,6 +1216,30 @@ impl<'a> HwParams<'a> { .map(|_| ()) } + pub fn set_period_size_min(&self, v: Frames, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as alsa::snd_pcm_uframes_t; + acheck!(snd_pcm_hw_params_set_period_size_min( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as Frames) + } + + pub fn set_period_size_max(&self, v: Frames, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as alsa::snd_pcm_uframes_t; + acheck!(snd_pcm_hw_params_set_period_size_max( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as Frames) + } + pub fn set_period_time_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; @@ -1228,6 +1252,61 @@ impl<'a> HwParams<'a> { .map(|_| r as u32) } + pub fn set_period_time(&self, v: u32, dir: ValueOr) -> Result<()> { + acheck!(snd_pcm_hw_params_set_period_time( + (self.1).0, + self.0, + v as c_uint, + dir as c_int + )) + .map(|_| ()) + } + + pub fn set_period_time_min(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_period_time_min( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + + pub fn set_period_time_max(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_period_time_max( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + + pub fn get_period_time(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_period_time(self.0, &mut v, &mut d)).map(|_| v as u32) + } + + pub fn get_period_time_min(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_period_time_min( + self.0, &mut v, &mut d + )) + .map(|_| v as u32) + } + + pub fn get_period_time_max(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_period_time_max( + self.0, &mut v, &mut d + )) + .map(|_| v as u32) + } + pub fn get_period_size(&self) -> Result { let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_period_size(self.0, &mut v, &mut d)).map(|_| v as Frames) @@ -1249,6 +1328,18 @@ impl<'a> HwParams<'a> { .map(|_| v as Frames) } + pub fn set_periods_near(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_periods_near( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + pub fn set_periods(&self, v: u32, dir: ValueOr) -> Result<()> { acheck!(snd_pcm_hw_params_set_periods( (self.1).0, @@ -1259,6 +1350,30 @@ impl<'a> HwParams<'a> { .map(|_| ()) } + pub fn set_periods_min(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_periods_min( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + + pub fn set_periods_max(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_periods_max( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + pub fn get_periods(&self) -> Result { let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_periods(self.0, &mut v, &mut d)).map(|_| v as u32) @@ -1325,6 +1440,40 @@ impl<'a> HwParams<'a> { .map(|_| r as u32) } + pub fn set_buffer_time(&self, v: u32, dir: ValueOr) -> Result<()> { + acheck!(snd_pcm_hw_params_set_buffer_time( + (self.1).0, + self.0, + v as c_uint, + dir as c_int + )) + .map(|_| ()) + } + + pub fn set_buffer_time_min(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_buffer_time_min( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + + pub fn set_buffer_time_max(&self, v: u32, dir: ValueOr) -> Result { + let mut d = dir as c_int; + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_buffer_time_max( + (self.1).0, + self.0, + &mut r, + &mut d + )) + .map(|_| r as u32) + } + pub fn get_buffer_size(&self) -> Result { let mut v = 0; acheck!(snd_pcm_hw_params_get_buffer_size(self.0, &mut v)).map(|_| v as Frames) @@ -1340,6 +1489,11 @@ impl<'a> HwParams<'a> { acheck!(snd_pcm_hw_params_get_buffer_size_max(self.0, &mut v)).map(|_| v as Frames) } + pub fn get_buffer_time(&self) -> Result { + let (mut v, mut d) = (0, 0); + acheck!(snd_pcm_hw_params_get_buffer_time(self.0, &mut v, &mut d)).map(|_| v as u32) + } + pub fn get_buffer_time_min(&self) -> Result { let (mut v, mut d) = (0, 0); acheck!(snd_pcm_hw_params_get_buffer_time_min( From 79c2b249cb931f7fc564d12e657938f71a17dc04 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sat, 20 Sep 2025 11:54:04 +0200 Subject: [PATCH 4/4] style: revert rustfmt --- examples/ctl_list.rs | 10 +- examples/midi_enumerate.rs | 58 +- examples/pcm_enumerate.rs | 40 +- examples/pcm_record.rs | 9 +- examples/trigger_hstamp.rs | 2 +- src/card.rs | 26 +- src/chmap.rs | 86 +-- src/config.rs | 20 +- src/ctl_int.rs | 461 ++++--------- src/device_name.rs | 40 +- src/direct/pcm.rs | 328 +++------ src/hctl.rs | 101 +-- src/io.rs | 19 +- src/lib.rs | 28 +- src/mixer.rs | 406 +++-------- src/pcm.rs | 897 ++++++------------------- src/poll.rs | 73 +- src/rawmidi.rs | 172 ++--- src/seq.rs | 1292 +++++++++++------------------------- 19 files changed, 1114 insertions(+), 2954 deletions(-) diff --git a/examples/ctl_list.rs b/examples/ctl_list.rs index 5df2bc1..2d842db 100644 --- a/examples/ctl_list.rs +++ b/examples/ctl_list.rs @@ -1,11 +1,11 @@ //! Example that enumerates controls for a device. +use alsa::Card; use alsa::card::Iter; use alsa::ctl::Ctl; -use alsa::Card; use alsa::Error; -fn list_controls_for_card(card: &Card) -> Result<(), Error> { +fn list_controls_for_card(card: &Card) -> Result<(), Error>{ // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); let ctl = Ctl::new(&ctl_id, false)?; @@ -25,9 +25,5 @@ fn list_controls_for_card(card: &Card) -> Result<(), Error> { fn main() { let cards = Iter::new(); - cards.for_each(|card| { - if let Ok(c) = card { - list_controls_for_card(&c).unwrap_or_default() - } - }); + cards.for_each(|card| if let Ok(c) = card { list_controls_for_card(&c).unwrap_or_default() }); } diff --git a/examples/midi_enumerate.rs b/examples/midi_enumerate.rs index 6d458ea..23ef825 100644 --- a/examples/midi_enumerate.rs +++ b/examples/midi_enumerate.rs @@ -1,13 +1,13 @@ //! Example that enumerates hardware and PCM devices. +use alsa::Card; use alsa::card::Iter as CardIter; -use alsa::ctl::Ctl; +use alsa::ctl::{Ctl}; +use alsa::{Error}; use alsa::rawmidi::Iter as MidiIter; -use alsa::Card; -use alsa::Error; - -use alsa::seq::{Addr, ClientIter, PortIter, PortSubscribeIter, QuerySubsType, Seq}; +use alsa::seq::{ClientIter, Seq, PortIter, PortSubscribeIter, QuerySubsType, Addr}; + pub fn list_rawmidi_for_card(card: &Card) -> Result<(), Error> { // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); @@ -17,29 +17,21 @@ pub fn list_rawmidi_for_card(card: &Card) -> Result<(), Error> { let cardinfo = ctl.card_info()?; let card_id = cardinfo.get_id()?; let card_name = cardinfo.get_name()?; - let subdevices: Vec<_> = MidiIter::new(&ctl).filter_map(|d| d.ok()).collect(); + let subdevices:Vec<_> = MidiIter::new(&ctl).filter_map(|d| d.ok()).collect(); if !subdevices.is_empty() { println!("card_id: {:?} card_name {:?} ", card_id, card_name); for info in &subdevices { - println!( - "subdevice: {:?} {:?} {:?}", - info.get_subdevice(), - info.get_subdevice_name().unwrap(), - info.get_stream() - ); + println!("subdevice: {:?} {:?} {:?}", info.get_subdevice(), info.get_subdevice_name().unwrap(), info.get_stream()); } println!(); + } Ok(()) } pub fn list_rawmidi_devices() { let cards = CardIter::new(); - cards.for_each(|card| { - if let Ok(c) = card { - list_rawmidi_for_card(&c).unwrap_or_default() - } - }); + cards.for_each(|card| if let Ok(c) = card { list_rawmidi_for_card(&c).unwrap_or_default() }); } pub fn list_sequencer_port() { @@ -49,35 +41,13 @@ pub fn list_sequencer_port() { seq.set_client_name(&c"ALSA_RS_EXAMPLE").unwrap(); for client in ClientIter::new(&seq) { - println!( - "Client {:?} {:?}", - client.get_client(), - client.get_name().unwrap() - ); + println!("Client {:?} {:?}", client.get_client(), client.get_name().unwrap()); for port in PortIter::new(&seq, client.get_client()) { - println!( - " Port {:?} {:?}", - port.get_port(), - port.get_name().unwrap() - ); - for sub in PortSubscribeIter::new( - &seq, - Addr { - client: client.get_client(), - port: port.get_port(), - }, - QuerySubsType::READ, - ) { + println!(" Port {:?} {:?}", port.get_port(), port.get_name().unwrap()); + for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::READ) { println!(" READ {:?}", sub.get_dest()); } - for sub in PortSubscribeIter::new( - &seq, - Addr { - client: client.get_client(), - port: port.get_port(), - }, - QuerySubsType::WRITE, - ) { + for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::WRITE) { println!(" WRITE {:?}", sub.get_dest()); } } @@ -90,4 +60,4 @@ fn main() { list_rawmidi_devices(); println!("\n--- MIDI Sequencer Clients, Ports and Subscribers ---"); list_sequencer_port(); -} +} \ No newline at end of file diff --git a/examples/pcm_enumerate.rs b/examples/pcm_enumerate.rs index d4908cf..aa4f8a8 100644 --- a/examples/pcm_enumerate.rs +++ b/examples/pcm_enumerate.rs @@ -1,13 +1,13 @@ //! Example that enumerates hardware and PCM devices. +use alsa::Card; use alsa::card::Iter; -use alsa::ctl::{Ctl, DeviceIter}; use alsa::device_name::HintIter; -use alsa::Card; +use alsa::ctl::{Ctl, DeviceIter}; use alsa::{Direction, Error}; // Each card can have multiple devices and subdevices, list them all -fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> { +fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error>{ // Get a Ctl for the card let ctl_id = format!("hw:{}", card.get_index()); let ctl = Ctl::new(&ctl_id, false)?; @@ -23,19 +23,12 @@ fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> // Read PCM name let pcm_name = pcm_info.get_name()?.to_string(); - println!( - "card: {:<2} id: {:<10} device: {:<2} card name: '{}' PCM name: '{}'", - card.get_index(), - card_id, - device, - card_name, - pcm_name - ); + println!("card: {:<2} id: {:<10} device: {:<2} card name: '{}' PCM name: '{}'", card.get_index(), card_id, device, card_name, pcm_name); // Loop through subdevices and get their names let subdevs = pcm_info.get_subdevices_count(); for subdev in 0..subdevs { - // Get subdevice name + // Get subdevice name let pcm_info = ctl.pcm_info(device as u32, subdev, direction)?; let subdev_name = pcm_info.get_subdevice_name()?; @@ -48,30 +41,15 @@ fn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error> pub fn list_hw_devices(direction: Direction) { let cards = Iter::new(); - cards.for_each(|card| { - if let Ok(c) = card { - list_devices_for_card(&c, direction).unwrap_or_default() - } - }); + cards.for_each(|card| if let Ok(c) = card { list_devices_for_card(&c, direction).unwrap_or_default() }); } pub fn list_pcm_devices(direction: Direction) { let hints = HintIter::new_str(None, "pcm").unwrap(); for hint in hints { // When Direction is None it means that both the PCM supports both playback and capture - if hint.name.is_some() - && hint.desc.is_some() - && (hint.direction.is_none() - || hint - .direction - .map(|dir| dir == direction) - .unwrap_or_default()) - { - println!( - "name: {:<35} desc: {:?}", - hint.name.unwrap(), - hint.desc.unwrap() - ); + if hint.name.is_some() && hint.desc.is_some() && (hint.direction.is_none() || hint.direction.map(|dir| dir == direction).unwrap_or_default()) { + println!("name: {:<35} desc: {:?}", hint.name.unwrap(), hint.desc.unwrap()); } } } @@ -86,4 +64,4 @@ fn main() { list_pcm_devices(Direction::Playback); println!("\n--- PCM capture devices ---"); list_pcm_devices(Direction::Capture); -} +} \ No newline at end of file diff --git a/examples/pcm_record.rs b/examples/pcm_record.rs index 8d9beb6..d91fd15 100644 --- a/examples/pcm_record.rs +++ b/examples/pcm_record.rs @@ -1,7 +1,7 @@ //! Example that continously reads data and displays its RMS volume. use alsa::pcm::*; -use alsa::{Direction, Error, ValueOr}; +use alsa::{Direction, ValueOr, Error}; fn start_capture(device: &str) -> Result { let pcm = PCM::new(device, Direction::Capture, false)?; @@ -20,9 +20,7 @@ fn start_capture(device: &str) -> Result { // Calculates RMS (root mean square) as a way to determine volume fn rms(buf: &[i16]) -> f64 { - if buf.len() == 0 { - return 0f64; - } + if buf.len() == 0 { return 0f64; } let mut sum = 0f64; for &x in buf { sum += (x as f64) * (x as f64); @@ -32,6 +30,7 @@ fn rms(buf: &[i16]) -> f64 { 20.0 * (r / (i16::MAX as f64)).log10() } + fn read_loop(pcm: &PCM) -> Result<(), Error> { let io = pcm.io_i16()?; let mut buf = [0i16; 8192]; @@ -48,4 +47,4 @@ fn main() { // e g PulseAudio or PipeWire. let capture = start_capture("default").unwrap(); read_loop(&capture).unwrap(); -} +} \ No newline at end of file diff --git a/examples/trigger_hstamp.rs b/examples/trigger_hstamp.rs index ce2ea1e..84dd5de 100644 --- a/examples/trigger_hstamp.rs +++ b/examples/trigger_hstamp.rs @@ -41,7 +41,7 @@ fn main() -> Result<()> { // I've also tried to construct the status object just once outside the loop but nothing changes let status = pcm.status()?; - + dbg!(&status); // The following "htstamp" functions all wrongly return a timespec struct with 0 seconds and 0 nanoseconds diff --git a/src/card.rs b/src/card.rs index 1d1da06..93345f4 100644 --- a/src/card.rs +++ b/src/card.rs @@ -1,7 +1,7 @@ //! Sound card enumeration +use libc::{c_int, c_char}; use super::error::*; use crate::alsa; -use libc::{c_char, c_int}; use std::ffi::CStr; /// An ALSA sound card, uniquely identified by its index. @@ -12,9 +12,7 @@ pub struct Card(c_int); pub struct Iter(c_int); impl Iter { - pub fn new() -> Iter { - Iter(-1) - } + pub fn new() -> Iter { Iter(-1) } } impl Iterator for Iter { @@ -30,35 +28,27 @@ impl Iterator for Iter { } impl Card { - pub fn new(index: c_int) -> Card { - Card(index) - } + pub fn new(index: c_int) -> Card { Card(index) } pub fn from_str(s: &CStr) -> Result { acheck!(snd_card_get_index(s.as_ptr())).map(Card) } pub fn get_name(&self) -> Result { let mut c: *mut c_char = ::std::ptr::null_mut(); - acheck!(snd_card_get_name(self.0, &mut c)).and_then(|_| from_alloc("snd_card_get_name", c)) + acheck!(snd_card_get_name(self.0, &mut c)) + .and_then(|_| from_alloc("snd_card_get_name", c)) } pub fn get_longname(&self) -> Result { let mut c: *mut c_char = ::std::ptr::null_mut(); acheck!(snd_card_get_longname(self.0, &mut c)) - .and_then(|_| from_alloc("snd_card_get_longname", c)) + .and_then(|_| from_alloc("snd_card_get_longname", c)) } - pub fn get_index(&self) -> c_int { - self.0 - } + pub fn get_index(&self) -> c_int { self.0 } } #[test] fn print_cards() { for a in Iter::new().map(|a| a.unwrap()) { - println!( - "Card #{}: {} ({})", - a.get_index(), - a.get_name().unwrap(), - a.get_longname().unwrap() - ) + println!("Card #{}: {} ({})", a.get_index(), a.get_name().unwrap(), a.get_longname().unwrap()) } } diff --git a/src/chmap.rs b/src/chmap.rs index fb66a32..0ecbeb1 100644 --- a/src/chmap.rs +++ b/src/chmap.rs @@ -1,6 +1,6 @@ -use super::error::*; use crate::alsa; use std::{fmt, mem, slice}; +use super::error::*; alsa_enum!( /// [SND_CHMAP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants @@ -63,25 +63,18 @@ impl fmt::Display for ChmapPosition { } } + /// [snd_pcm_chmap_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper pub struct Chmap(*mut alsa::snd_pcm_chmap_t, bool); impl Drop for Chmap { - fn drop(&mut self) { - if self.1 { - unsafe { libc::free(self.0 as *mut libc::c_void) } - } - } + fn drop(&mut self) { if self.1 { unsafe { libc::free(self.0 as *mut libc::c_void) }}} } impl Chmap { - fn set_channels(&mut self, c: libc::c_uint) { - unsafe { (*self.0).channels = c } - } + fn set_channels(&mut self, c: libc::c_uint) { unsafe { (*self.0) .channels = c }} fn as_slice_mut(&mut self) -> &mut [libc::c_uint] { - unsafe { - slice::from_raw_parts_mut((*self.0).pos.as_mut_ptr(), (*self.0).channels as usize) - } + unsafe { slice::from_raw_parts_mut((*self.0).pos.as_mut_ptr(), (*self.0).channels as usize) } } fn as_slice(&self) -> &[libc::c_uint] { unsafe { slice::from_raw_parts((*self.0).pos.as_ptr(), (*self.0).channels as usize) } @@ -91,11 +84,7 @@ impl Chmap { impl fmt::Display for Chmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut buf: Vec = vec![0; 512]; - acheck!(snd_pcm_chmap_print( - self.0, - buf.len() as libc::size_t, - buf.as_mut_ptr() - ))?; + acheck!(snd_pcm_chmap_print(self.0, buf.len() as libc::size_t, buf.as_mut_ptr()))?; let s = from_const("snd_pcm_chmap_print", buf.as_mut_ptr())?; write!(f, "{}", s) } @@ -103,86 +92,61 @@ impl fmt::Display for Chmap { impl<'a> From<&'a [ChmapPosition]> for Chmap { fn from(a: &'a [ChmapPosition]) -> Chmap { - let p = unsafe { - libc::malloc( - (mem::size_of::() + mem::size_of::() * a.len()) - as libc::size_t, - ) - }; - if p.is_null() { - panic!("Out of memory") - } + let p = unsafe { libc::malloc((mem::size_of::() + mem::size_of::() * a.len()) as libc::size_t) }; + if p.is_null() { panic!("Out of memory") } let mut r = Chmap(p as *mut alsa::snd_pcm_chmap_t, true); r.set_channels(a.len() as libc::c_uint); - for (i, v) in r.as_slice_mut().iter_mut().enumerate() { - *v = a[i] as libc::c_uint - } + for (i,v) in r.as_slice_mut().iter_mut().enumerate() { *v = a[i] as libc::c_uint } r } } impl<'a> From<&'a Chmap> for Vec { fn from(a: &'a Chmap) -> Vec { - a.as_slice() - .iter() - .map(|&v| ChmapPosition::from_c_int(v as libc::c_int, "").unwrap()) - .collect() + a.as_slice().iter().map(|&v| ChmapPosition::from_c_int(v as libc::c_int, "").unwrap()).collect() } } -pub fn chmap_new(a: *mut alsa::snd_pcm_chmap_t) -> Chmap { - Chmap(a, true) -} -pub fn chmap_handle(a: &Chmap) -> *mut alsa::snd_pcm_chmap_t { - a.0 -} +pub fn chmap_new(a: *mut alsa::snd_pcm_chmap_t) -> Chmap { Chmap(a, true) } +pub fn chmap_handle(a: &Chmap) -> *mut alsa::snd_pcm_chmap_t { a.0 } + /// Iterator over available channel maps - see [snd_pcm_chmap_query_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) pub struct ChmapsQuery(*mut *mut alsa::snd_pcm_chmap_query_t, isize); impl Drop for ChmapsQuery { - fn drop(&mut self) { - unsafe { alsa::snd_pcm_free_chmaps(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_pcm_free_chmaps(self.0) }} } -pub fn chmaps_query_new(a: *mut *mut alsa::snd_pcm_chmap_query_t) -> ChmapsQuery { - ChmapsQuery(a, 0) -} +pub fn chmaps_query_new(a: *mut *mut alsa::snd_pcm_chmap_query_t) -> ChmapsQuery { ChmapsQuery(a, 0) } impl Iterator for ChmapsQuery { type Item = (ChmapType, Chmap); fn next(&mut self) -> Option { - if self.0.is_null() { - return None; - } + if self.0.is_null() { return None; } let p = unsafe { *self.0.offset(self.1) }; - if p.is_null() { - return None; - } + if p.is_null() { return None; } self.1 += 1; - let t = ChmapType::from_c_int(unsafe { (*p).type_ } as libc::c_int, "snd_pcm_query_chmaps") - .unwrap(); + let t = ChmapType::from_c_int(unsafe { (*p).type_ } as libc::c_int, "snd_pcm_query_chmaps").unwrap(); let m = Chmap(unsafe { &mut (*p).map }, false); Some((t, m)) } } + #[test] fn chmap_for_first_pcm() { use super::*; - use crate::device_name::HintIter; use std::ffi::CString; + use crate::device_name::HintIter; let i = HintIter::new(None, &*CString::new("pcm").unwrap()).unwrap(); for p in i.map(|n| n.name.unwrap()) { println!("Chmaps for {:?}:", p); - match PCM::open(&CString::new(p).unwrap(), Direction::Playback, false) { - Ok(a) => { - for c in a.query_chmaps() { - println!(" {:?}, {}", c.0, c.1); - } - } - Err(a) => println!(" {}", a), // It's okay to have entries in the name hint array that can't be opened + match PCM::open(&CString::new(p).unwrap(), Direction::Playback, false) { + Ok(a) => for c in a.query_chmaps() { + println!(" {:?}, {}", c.0, c.1); + }, + Err(a) => println!(" {}", a) // It's okay to have entries in the name hint array that can't be opened } } } diff --git a/src/config.rs b/src/config.rs index f8cebda..b19d0aa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,31 +3,29 @@ //! For now, just contains functions regarding the global configuration //! stored as a cache inside alsa-lib. Calling `update_free_global` might help //! against valgrind reporting memory leaks. +use crate::{alsa}; use super::error::*; use super::Output; -use crate::alsa; use std::ptr; pub fn update() -> Result { - acheck!(snd_config_update()).map(|x| x != 0) + acheck!(snd_config_update()).map(|x| x != 0) } pub fn update_free_global() -> Result<()> { - acheck!(snd_config_update_free_global()).map(|_| ()) + acheck!(snd_config_update_free_global()).map(|_| ()) } /// [snd_config_t](https://alsa-project.org/alsa-doc/alsa-lib/group___config.html) wrapper pub struct Config(*mut alsa::snd_config_t); impl Drop for Config { - fn drop(&mut self) { - unsafe { alsa::snd_config_unref(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_config_unref(self.0) }; } } pub fn update_ref() -> Result { - let mut top = ptr::null_mut(); - acheck!(snd_config_update_ref(&mut top)).map(|_| Config(top)) + let mut top = ptr::null_mut(); + acheck!(snd_config_update_ref(&mut top)).map(|_| Config(top)) } impl Config { @@ -38,8 +36,8 @@ impl Config { #[test] fn config_save() { - let c = update_ref().unwrap(); + let c = update_ref().unwrap(); let mut outp = Output::buffer_open().unwrap(); - c.save(&mut outp).unwrap(); + c.save(&mut outp).unwrap(); println!("== Config save ==\n{}", outp); -} +} \ No newline at end of file diff --git a/src/ctl_int.rs b/src/ctl_int.rs index 2b15940..2bd001a 100644 --- a/src/ctl_int.rs +++ b/src/ctl_int.rs @@ -1,14 +1,15 @@ -use super::error::*; -use super::mixer::MilliBel; + +use crate::alsa; use super::pcm::Info; +use std::ffi::{CStr, CString}; use super::Direction; +use super::error::*; +use super::mixer::MilliBel; use super::Round; -use crate::alsa; -use crate::{poll, Card}; -use libc::{c_int, c_long, c_short, c_uint, c_void, pollfd, size_t}; +use std::{ptr, mem, fmt, cmp}; +use crate::{Card, poll}; use std::cell::UnsafeCell; -use std::ffi::{CStr, CString}; -use std::{cmp, fmt, mem, ptr}; +use libc::{c_uint, c_void, size_t, c_long, c_int, pollfd, c_short}; /// We prefer not to allocate for every ElemId, ElemInfo or ElemValue. /// But we don't know if these will increase in the future or on other platforms. @@ -22,7 +23,7 @@ const ELEM_ID_SIZE: usize = 64; /// Iterate over devices of a card. pub struct DeviceIter<'a>(&'a Ctl, c_int); -impl<'a> DeviceIter<'a> { +impl<'a> DeviceIter<'a>{ pub fn new(ctl: &'a Ctl) -> DeviceIter<'a> { DeviceIter(ctl, -1) } @@ -32,7 +33,7 @@ impl<'a> Iterator for DeviceIter<'a> { type Item = c_int; fn next(&mut self) -> Option { - match acheck!(snd_ctl_pcm_next_device(self.0 .0, &mut self.1)) { + match acheck!(snd_ctl_pcm_next_device(self.0.0, &mut self.1)) { Ok(_) if self.1 == -1 => None, Ok(_) => Some(self.1), Err(_) => None, @@ -63,51 +64,29 @@ impl Ctl { Ctl::open(&CString::new(s).unwrap(), nonblock) } - pub fn card_info(&self) -> Result { - CardInfo::new().and_then(|c| acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) - } + pub fn card_info(&self) -> Result { CardInfo::new().and_then(|c| + acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_ctl_wait( - self.0, - timeout_ms.map(|x| x as c_int).unwrap_or(-1) - )) - .map(|i| i == 1) - } + acheck!(snd_ctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } pub fn get_db_range(&self, id: &ElemId) -> Result<(MilliBel, MilliBel)> { let mut min: c_long = 0; let mut max: c_long = 0; - acheck!(snd_ctl_get_dB_range( - self.0, - elem_id_ptr(id), - &mut min, - &mut max - )) - .map(|_| (MilliBel(min as i64), MilliBel(max as i64))) + acheck!(snd_ctl_get_dB_range(self.0, elem_id_ptr(id), &mut min, &mut max)) + .map(|_| (MilliBel(min as i64), MilliBel(max as i64))) } pub fn convert_to_db(&self, id: &ElemId, volume: i64) -> Result { let mut m: c_long = 0; - acheck!(snd_ctl_convert_to_dB( - self.0, - elem_id_ptr(id), - volume as c_long, - &mut m - )) - .map(|_| (MilliBel(m as i64))) + acheck!(snd_ctl_convert_to_dB(self.0, elem_id_ptr(id), volume as c_long, &mut m)) + .map(|_| (MilliBel(m as i64))) } pub fn convert_from_db(&self, id: &ElemId, mb: MilliBel, dir: Round) -> Result { let mut m: c_long = 0; - acheck!(snd_ctl_convert_from_dB( - self.0, - elem_id_ptr(id), - mb.0 as c_long, - &mut m, - dir as c_int - )) - .map(|_| m as i64) + acheck!(snd_ctl_convert_from_dB(self.0, elem_id_ptr(id), mb.0 as c_long, &mut m, dir as c_int)) + .map(|_| m as i64) } pub fn elem_read(&self, val: &mut ElemValue) -> Result<()> { @@ -140,11 +119,7 @@ impl Ctl { /// returning whether or not you are subscribed. This does not work in practice, so I'm not /// including that here. pub fn subscribe_events(&self, subscribe: bool) -> Result<()> { - acheck!(snd_ctl_subscribe_events( - self.0, - if subscribe { 1 } else { 0 } - )) - .map(|_| ()) + acheck!(snd_ctl_subscribe_events(self.0, if subscribe { 1 } else { 0 })).map(|_| ()) } pub fn read(&self) -> Result> { @@ -157,15 +132,13 @@ impl Ctl { info.set_device(device); info.set_subdevice(subdevice); info.set_stream(direction); - acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info) + acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info ) }) } } impl Drop for Ctl { - fn drop(&mut self) { - unsafe { alsa::snd_ctl_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_ctl_close(self.0) }; } } impl poll::Descriptors for Ctl { @@ -173,36 +146,24 @@ impl poll::Descriptors for Ctl { unsafe { alsa::snd_ctl_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = - unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_ctl_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_ctl_poll_descriptors_revents( - self.0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_ctl_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_ctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_ctl_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } -pub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { - a.0 -} + +pub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { a.0 } /// [snd_ctl_card_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct CardInfo(*mut alsa::snd_ctl_card_info_t); impl Drop for CardInfo { - fn drop(&mut self) { - unsafe { alsa::snd_ctl_card_info_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_ctl_card_info_free(self.0) }} } impl CardInfo { @@ -212,38 +173,18 @@ impl CardInfo { } pub fn get_id(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_id", unsafe { - alsa::snd_ctl_card_info_get_id(self.0) - }) - } + from_const("snd_ctl_card_info_get_id", unsafe { alsa::snd_ctl_card_info_get_id(self.0) })} pub fn get_driver(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_driver", unsafe { - alsa::snd_ctl_card_info_get_driver(self.0) - }) - } + from_const("snd_ctl_card_info_get_driver", unsafe { alsa::snd_ctl_card_info_get_driver(self.0) })} pub fn get_components(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_components", unsafe { - alsa::snd_ctl_card_info_get_components(self.0) - }) - } + from_const("snd_ctl_card_info_get_components", unsafe { alsa::snd_ctl_card_info_get_components(self.0) })} pub fn get_longname(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_longname", unsafe { - alsa::snd_ctl_card_info_get_longname(self.0) - }) - } + from_const("snd_ctl_card_info_get_longname", unsafe { alsa::snd_ctl_card_info_get_longname(self.0) })} pub fn get_name(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_name", unsafe { - alsa::snd_ctl_card_info_get_name(self.0) - }) - } + from_const("snd_ctl_card_info_get_name", unsafe { alsa::snd_ctl_card_info_get_name(self.0) })} pub fn get_mixername(&self) -> Result<&str> { - from_const("snd_ctl_card_info_get_mixername", unsafe { - alsa::snd_ctl_card_info_get_mixername(self.0) - }) - } - pub fn get_card(&self) -> Card { - Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) }) - } + from_const("snd_ctl_card_info_get_mixername", unsafe { alsa::snd_ctl_card_info_get_mixername(self.0) })} + pub fn get_card(&self) -> Card { Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) })} } alsa_enum!( @@ -280,25 +221,19 @@ pub struct ElemValue { } impl Drop for ElemValue { - fn drop(&mut self) { - unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; - } + fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; } } -pub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { - a.ptr -} +pub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { a.ptr } pub fn elem_value_new(t: ElemType, count: u32) -> Result { let mut p = ptr::null_mut(); - acheck!(snd_ctl_elem_value_malloc(&mut p)).map(|_| ElemValue { - ptr: p, - etype: t, - count, - }) + acheck!(snd_ctl_elem_value_malloc(&mut p)) + .map(|_| ElemValue { ptr: p, etype: t, count }) } impl ElemValue { + pub fn set_id(&mut self, id: &ElemId) { unsafe { alsa::snd_ctl_elem_value_set_id(self.ptr, elem_id_ptr(id)) } } @@ -308,127 +243,67 @@ impl ElemValue { // from get_bytes has been dropped when calling a set_* function). pub fn get_boolean(&self, idx: u32) -> Option { - if self.etype != ElemType::Boolean || idx >= self.count { - None - } else { - Some(unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) - } + if self.etype != ElemType::Boolean || idx >= self.count { None } + else { Some( unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) } } pub fn set_boolean(&mut self, idx: u32, val: bool) -> Option<()> { - if self.etype != ElemType::Boolean || idx >= self.count { - None - } else { - unsafe { - alsa::snd_ctl_elem_value_set_boolean( - self.ptr, - idx as c_uint, - if val { 1 } else { 0 }, - ) - }; - Some(()) - } + if self.etype != ElemType::Boolean || idx >= self.count { None } + else { unsafe { alsa::snd_ctl_elem_value_set_boolean(self.ptr, idx as c_uint, if val {1} else {0}) }; Some(()) } } pub fn get_integer(&self, idx: u32) -> Option { - if self.etype != ElemType::Integer || idx >= self.count { - None - } else { - Some(unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) - } + if self.etype != ElemType::Integer || idx >= self.count { None } + else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) } } pub fn set_integer(&mut self, idx: u32, val: i32) -> Option<()> { - if self.etype != ElemType::Integer || idx >= self.count { - None - } else { - unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; - Some(()) - } + if self.etype != ElemType::Integer || idx >= self.count { None } + else { unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; Some(()) } } pub fn get_integer64(&self, idx: u32) -> Option { - if self.etype != ElemType::Integer64 || idx >= self.count { - None - } else { - Some(unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) - } + if self.etype != ElemType::Integer64 || idx >= self.count { None } + else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) } } pub fn set_integer64(&mut self, idx: u32, val: i64) -> Option<()> { - if self.etype != ElemType::Integer || idx >= self.count { - None - } else { - unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; - Some(()) - } + if self.etype != ElemType::Integer || idx >= self.count { None } + else { unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; Some(()) } } pub fn get_enumerated(&self, idx: u32) -> Option { - if self.etype != ElemType::Enumerated || idx >= self.count { - None - } else { - Some(unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) - } + if self.etype != ElemType::Enumerated || idx >= self.count { None } + else { Some( unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) } } pub fn set_enumerated(&mut self, idx: u32, val: u32) -> Option<()> { - if self.etype != ElemType::Enumerated || idx >= self.count { - None - } else { - unsafe { - alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) - }; - Some(()) - } + if self.etype != ElemType::Enumerated || idx >= self.count { None } + else { unsafe { alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) }; Some(()) } } pub fn get_byte(&self, idx: u32) -> Option { - if self.etype != ElemType::Bytes || idx >= self.count { - None - } else { - Some(unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) - } + if self.etype != ElemType::Bytes || idx >= self.count { None } + else { Some( unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) } } pub fn set_byte(&mut self, idx: u32, val: u8) -> Option<()> { - if self.etype != ElemType::Bytes || idx >= self.count { - None - } else { - unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; - Some(()) - } + if self.etype != ElemType::Bytes || idx >= self.count { None } + else { unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; Some(()) } } pub fn get_bytes(&self) -> Option<&[u8]> { - if self.etype != ElemType::Bytes { - None - } else { - Some(unsafe { - ::std::slice::from_raw_parts( - alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, - self.count as usize, - ) - }) - } + if self.etype != ElemType::Bytes { None } + else { Some( unsafe { ::std::slice::from_raw_parts( + alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, self.count as usize) } ) } } pub fn set_bytes(&mut self, val: &[u8]) -> Option<()> { - if self.etype != ElemType::Bytes || val.len() != self.count as usize { - None - } + if self.etype != ElemType::Bytes || val.len() != self.count as usize { None } + // Note: the alsa-lib function definition is broken. First, the pointer is declared as mut even // though it's const, and second, there is a "value" missing between "elem" and "set_bytes". - else { - unsafe { - alsa::snd_ctl_elem_set_bytes( - self.ptr, - val.as_ptr() as *mut c_void, - val.len() as size_t, - ) - }; - Some(()) - } + else { unsafe { alsa::snd_ctl_elem_set_bytes(self.ptr, val.as_ptr() as *mut c_void, val.len() as size_t) }; Some(()) } } /// Creates a new ElemValue. @@ -448,22 +323,21 @@ impl ElemValue { unsafe { alsa::snd_ctl_elem_value_clear(elem_value_ptr(&ev)) }; Ok(ev) } + } impl fmt::Debug for ElemValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ElemType::*; write!(f, "ElemValue({:?}", self.etype)?; - for a in 0..self.count { - match self.etype { - Boolean => write!(f, ",{:?}", self.get_boolean(a).unwrap()), - Integer => write!(f, ",{:?}", self.get_integer(a).unwrap()), - Integer64 => write!(f, ",{:?}", self.get_integer64(a).unwrap()), - Enumerated => write!(f, ",{:?}", self.get_enumerated(a).unwrap()), - Bytes => write!(f, ",{:?}", self.get_byte(a).unwrap()), - _ => Ok(()), - }? - } + for a in 0..self.count { match self.etype { + Boolean => write!(f, ",{:?}", self.get_boolean(a).unwrap()), + Integer => write!(f, ",{:?}", self.get_integer(a).unwrap()), + Integer64 => write!(f, ",{:?}", self.get_integer64(a).unwrap()), + Enumerated => write!(f, ",{:?}", self.get_enumerated(a).unwrap()), + Bytes => write!(f, ",{:?}", self.get_byte(a).unwrap()), + _ => Ok(()), + }?}; write!(f, ")") } } @@ -471,14 +345,10 @@ impl fmt::Debug for ElemValue { /// [snd_ctl_elem_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct ElemInfo(*mut alsa::snd_ctl_elem_info_t); -pub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { - a.0 -} +pub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { a.0 } impl Drop for ElemInfo { - fn drop(&mut self) { - unsafe { alsa::snd_ctl_elem_info_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_info_free(self.0) }; } } pub fn elem_info_new() -> Result { @@ -487,16 +357,9 @@ pub fn elem_info_new() -> Result { } impl ElemInfo { - pub fn get_type(&self) -> ElemType { - ElemType::from_c_int( - unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, - "snd_ctl_elem_info_get_type", - ) - .unwrap() - } - pub fn get_count(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } - } + pub fn get_type(&self) -> ElemType { ElemType::from_c_int( + unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, "snd_ctl_elem_info_get_type").unwrap() } + pub fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } } } // @@ -512,9 +375,7 @@ pub fn elem_id_new() -> Result { } #[inline] -pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { - a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t -} +pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t } unsafe impl Send for ElemId {} @@ -548,48 +409,20 @@ pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0 } impl ElemId { pub fn get_name(&self) -> Result<&str> { - from_const("snd_hctl_elem_id_get_name", unsafe { - alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) - }) - } - pub fn get_device(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 } - } - pub fn get_subdevice(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 } - } - pub fn get_numid(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 } - } - pub fn get_index(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 } - } - pub fn get_interface(&self) -> ElemIface { - ElemIface::from_c_int( - unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, - "snd_ctl_elem_id_get_interface", - ) - .unwrap() - } - - pub fn set_device(&mut self, v: u32) { - unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) } - } - pub fn set_subdevice(&mut self, v: u32) { - unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) } - } - pub fn set_numid(&mut self, v: u32) { - unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) } - } - pub fn set_index(&mut self, v: u32) { - unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) } - } - pub fn set_interface(&mut self, v: ElemIface) { - unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) } - } - pub fn set_name(&mut self, v: &CStr) { - unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) } - } + from_const("snd_hctl_elem_id_get_name", unsafe { alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) })} + pub fn get_device(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 }} + pub fn get_subdevice(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 }} + pub fn get_numid(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 }} + pub fn get_index(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 }} + pub fn get_interface(&self) -> ElemIface { ElemIface::from_c_int( + unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, "snd_ctl_elem_id_get_interface").unwrap() } + + pub fn set_device(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) }} + pub fn set_subdevice(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) }} + pub fn set_numid(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) }} + pub fn set_index(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) }} + pub fn set_interface(&mut self, v: ElemIface) { unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) }} + pub fn set_name(&mut self, v: &CStr) { unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) }} /// Creates a new ElemId. /// @@ -605,12 +438,9 @@ impl cmp::Eq for ElemId {} impl cmp::PartialEq for ElemId { fn eq(&self, a: &ElemId) -> bool { - self.get_numid() == a.get_numid() - && self.get_interface() == a.get_interface() - && self.get_index() == a.get_index() - && self.get_device() == a.get_device() - && self.get_subdevice() == a.get_subdevice() - && self.get_name().ok() == a.get_name().ok() + self.get_numid() == a.get_numid() && self.get_interface() == a.get_interface() && + self.get_index() == a.get_index() && self.get_device() == a.get_device() && + self.get_subdevice() == a.get_subdevice() && self.get_name().ok() == a.get_name().ok() } } @@ -620,22 +450,10 @@ impl fmt::Debug for ElemId { let device = self.get_device(); let subdevice = self.get_subdevice(); - write!( - f, - "ElemId(#{}, {:?}, {:?}", - self.get_numid(), - self.get_interface(), - self.get_name() - )?; - if index > 0 { - write!(f, ", index={}", index)? - }; - if device > 0 || subdevice > 0 { - write!(f, ", device={}", device)? - }; - if subdevice > 0 { - write!(f, ", subdevice={}", device)? - }; + write!(f, "ElemId(#{}, {:?}, {:?}", self.get_numid(), self.get_interface(), self.get_name())?; + if index > 0 { write!(f, ", index={}", index)? }; + if device > 0 || subdevice > 0 { write!(f, ", device={}", device)? }; + if subdevice > 0 { write!(f, ", subdevice={}", device)? }; write!(f, ")") } } @@ -670,56 +488,33 @@ impl ElemList { } } - pub(crate) fn get_count(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } - } - pub fn get_used(&self) -> u32 { - unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } - } + pub(crate) fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } } + pub fn get_used(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } } pub fn get_id(&self, index: u32) -> Result { self.ensure_valid_index(index)?; let elem_id = elem_id_new()?; unsafe { alsa::snd_ctl_elem_list_get_id(self.0, index, elem_id_ptr(&elem_id)) }; Ok(elem_id) } - pub fn get_numid(&self, index: u32) -> Result { - self.ensure_valid_index(index)?; - Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) - } + pub fn get_numid(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) } pub fn get_interface(&self, index: u32) -> Result { self.ensure_valid_index(index)?; - ElemIface::from_c_int( - unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, - "snd_ctl_elem_list_get_interface", - ) - } - pub fn get_device(&self, index: u32) -> Result { - self.ensure_valid_index(index)?; - Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) - } - pub fn get_subdevice(&self, index: u32) -> Result { - self.ensure_valid_index(index)?; - Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) + ElemIface::from_c_int(unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, "snd_ctl_elem_list_get_interface") } + pub fn get_device(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) } + pub fn get_subdevice(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) } pub fn get_name(&self, index: u32) -> Result<&str> { self.ensure_valid_index(index)?; - from_const("snd_ctl_elem_list_get_name", unsafe { - alsa::snd_ctl_elem_list_get_name(self.0, index) - }) - } - pub fn get_index(&self, index: u32) -> Result { - self.ensure_valid_index(index)?; - Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) + from_const("snd_ctl_elem_list_get_name", unsafe { alsa::snd_ctl_elem_list_get_name(self.0, index) }) } + pub fn get_index(&self, index: u32) -> Result { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) } } /// [snd_ctl_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct Event(*mut alsa::snd_ctl_event_t); impl Drop for Event { - fn drop(&mut self) { - unsafe { alsa::snd_ctl_event_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_ctl_event_free(self.0) }; } } pub fn event_new() -> Result { @@ -728,9 +523,7 @@ pub fn event_new() -> Result { } impl Event { - pub fn get_mask(&self) -> EventMask { - EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 }) - } + pub fn get_mask(&self) -> EventMask { EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 })} pub fn get_id(&self) -> ElemId { let r = elem_id_new().unwrap(); unsafe { alsa::snd_ctl_event_elem_get_id(self.0, elem_id_ptr(&r)) }; @@ -738,26 +531,17 @@ impl Event { } } + /// [SND_CTL_EVENT_MASK_XXX](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) bitmask #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub struct EventMask(pub u32); impl EventMask { - pub fn remove(&self) -> bool { - return self.0 & 0xffffffff == 0xffffffff; - } - pub fn value(&self) -> bool { - return (!self.remove()) && (self.0 & (1 << 0) != 0); - } - pub fn info(&self) -> bool { - return (!self.remove()) && (self.0 & (1 << 1) != 0); - } - pub fn add(&self) -> bool { - return (!self.remove()) && (self.0 & (1 << 2) != 0); - } - pub fn tlv(&self) -> bool { - return (!self.remove()) && (self.0 & (1 << 3) != 0); - } + pub fn remove(&self) -> bool { return self.0 & 0xffffffff == 0xffffffff } + pub fn value(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 0) != 0); } + pub fn info(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 1) != 0); } + pub fn add(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 2) != 0); } + pub fn tlv(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 3) != 0); } } #[test] @@ -767,11 +551,8 @@ fn print_sizeof() { let eleminfo = unsafe { alsa::snd_ctl_elem_info_sizeof() } as usize; assert!(elemid <= ELEM_ID_SIZE); - // assert!(elemvalue <= ELEM_VALUE_SIZE); - // assert!(eleminfo <= ELEM_INFO_SIZE); +// assert!(elemvalue <= ELEM_VALUE_SIZE); +// assert!(eleminfo <= ELEM_INFO_SIZE); - println!( - "Elem id: {}, Elem value: {}, Elem info: {}", - elemid, elemvalue, eleminfo - ); + println!("Elem id: {}, Elem value: {}, Elem info: {}", elemid, elemvalue, eleminfo); } diff --git a/src/device_name.rs b/src/device_name.rs index 21bb6d7..965231e 100644 --- a/src/device_name.rs +++ b/src/device_name.rs @@ -14,22 +14,18 @@ //! } //! ``` -use super::error::*; -use super::{Card, Direction}; +use std::ptr; +use libc::{c_void, c_int}; use crate::alsa; -use libc::{c_int, c_void}; +use super::{Card, Direction}; +use super::error::*; use std::ffi::{CStr, CString}; -use std::ptr; /// [snd_device_name_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper pub struct HintIter(*mut *mut c_void, isize); impl Drop for HintIter { - fn drop(&mut self) { - unsafe { - alsa::snd_device_name_free_hint(self.0); - } - } + fn drop(&mut self) { unsafe { alsa::snd_device_name_free_hint(self.0); }} } impl HintIter { @@ -37,7 +33,8 @@ impl HintIter { pub fn new(card: Option<&Card>, iface: &CStr) -> Result { let mut p = ptr::null_mut(); let cnr = card.map(|c| c.get_index()).unwrap_or(-1) as c_int; - acheck!(snd_device_name_hint(cnr, iface.as_ptr(), &mut p)).map(|_| HintIter(p, 0)) + acheck!(snd_device_name_hint(cnr, iface.as_ptr(), &mut p)) + .map(|_| HintIter(p, 0)) } /// A constructor variant that takes the interface as a Rust string slice. @@ -49,18 +46,15 @@ impl HintIter { impl Iterator for HintIter { type Item = Hint; fn next(&mut self) -> Option { - if self.0.is_null() { - return None; - } + if self.0.is_null() { return None; } let p = unsafe { *self.0.offset(self.1) }; - if p.is_null() { - return None; - } + if p.is_null() { return None; } self.1 += 1; Some(Hint::new(p)) } } + /// [snd_device_name_get_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper #[derive(Debug, Clone)] pub struct Hint { @@ -77,16 +71,12 @@ impl Hint { } fn new(p: *const c_void) -> Hint { - let d = Hint::get_str(p, "IOID").and_then(|x| match &*x { + let d = Hint::get_str(p, "IOID").and_then(|x| match &*x { "Input" => Some(Direction::Capture), "Output" => Some(Direction::Playback), _ => None, - }); - Hint { - name: Hint::get_str(p, "NAME"), - desc: Hint::get_str(p, "DESC"), - direction: d, - } + }); + Hint { name: Hint::get_str(p, "NAME"), desc: Hint::get_str(p, "DESC"), direction: d } } } @@ -95,8 +85,6 @@ fn print_hints() { for t in &["pcm", "ctl", "rawmidi", "timer", "seq", "hwdep"] { println!("{} devices:", t); let i = HintIter::new(None, &*CString::new(*t).unwrap()).unwrap(); - for a in i { - println!(" {:?}", a) - } + for a in i { println!(" {:?}", a) } } } diff --git a/src/direct/pcm.rs b/src/direct/pcm.rs index 191283c..9036da9 100644 --- a/src/direct/pcm.rs +++ b/src/direct/pcm.rs @@ -19,13 +19,13 @@ don't expect it to work with, e g, the PulseAudio plugin or so. For an example of how to use this mode, look in the "synth-example" directory. */ +use libc; +use std::{mem, ptr, fmt, cmp}; use crate::error::{Error, Result}; +use std::os::unix::io::RawFd; +use crate::{pcm, PollDescriptors, Direction}; use crate::pcm::Frames; -use crate::{pcm, Direction, PollDescriptors}; -use libc; use std::marker::PhantomData; -use std::os::unix::io::RawFd; -use std::{cmp, fmt, mem, ptr}; use super::ffi::*; @@ -40,58 +40,37 @@ impl SyncPtrStatus { /// Unsafe because /// - setting appl_ptr and avail_min might make alsa-lib confused /// - no check that the fd is really a PCM - pub unsafe fn sync_ptr( - fd: RawFd, - hwsync: bool, - appl_ptr: Option, - avail_min: Option, - ) -> Result { + pub unsafe fn sync_ptr(fd: RawFd, hwsync: bool, appl_ptr: Option, avail_min: Option) -> Result { let mut data = snd_pcm_sync_ptr { - flags: (if hwsync { SNDRV_PCM_SYNC_PTR_HWSYNC } else { 0 }) - + (if appl_ptr.is_some() { - SNDRV_PCM_SYNC_PTR_APPL - } else { - 0 - }) - + (if avail_min.is_some() { - SNDRV_PCM_SYNC_PTR_AVAIL_MIN - } else { - 0 - }), - c: snd_pcm_mmap_control_r { - control: snd_pcm_mmap_control { - appl_ptr: appl_ptr.unwrap_or(0) as snd_pcm_uframes_t, - avail_min: avail_min.unwrap_or(0) as snd_pcm_uframes_t, - }, - }, - s: mem::zeroed(), - }; + flags: (if hwsync { SNDRV_PCM_SYNC_PTR_HWSYNC } else { 0 }) + + (if appl_ptr.is_some() { SNDRV_PCM_SYNC_PTR_APPL } else { 0 }) + + (if avail_min.is_some() { SNDRV_PCM_SYNC_PTR_AVAIL_MIN } else { 0 }), + c: snd_pcm_mmap_control_r { + control: snd_pcm_mmap_control { + appl_ptr: appl_ptr.unwrap_or(0) as snd_pcm_uframes_t, + avail_min: avail_min.unwrap_or(0) as snd_pcm_uframes_t, + } + }, + s: mem::zeroed() + }; sndrv_pcm_ioctl_sync_ptr(fd, &mut data)?; let i = data.s.status.state; - if (i >= (pcm::State::Open as snd_pcm_state_t)) - && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) - { + if (i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) { Ok(SyncPtrStatus(data.s.status)) } else { - Err(Error::unsupported( - "SNDRV_PCM_IOCTL_SYNC_PTR returned broken state", - )) + Err(Error::unsupported("SNDRV_PCM_IOCTL_SYNC_PTR returned broken state")) } } - pub fn hw_ptr(&self) -> pcm::Frames { - self.0.hw_ptr as pcm::Frames - } - pub fn state(&self) -> pcm::State { - unsafe { mem::transmute(self.0.state as u8) } /* valid range checked in sync_ptr */ - } - pub fn htstamp(&self) -> libc::timespec { - self.0.tstamp - } + pub fn hw_ptr(&self) -> pcm::Frames { self.0.hw_ptr as pcm::Frames } + pub fn state(&self) -> pcm::State { unsafe { mem::transmute(self.0.state as u8) } /* valid range checked in sync_ptr */ } + pub fn htstamp(&self) -> libc::timespec { self.0.tstamp } } + + /// Read PCM status directly from memory, bypassing alsa-lib. /// /// This means that it's @@ -114,17 +93,13 @@ fn pcm_to_fd(p: &pcm::PCM) -> Result { let mut fds: [libc::pollfd; 1] = unsafe { mem::zeroed() }; let c = PollDescriptors::fill(p, &mut fds)?; if c != 1 { - return Err(Error::unsupported( - "snd_pcm_poll_descriptors returned wrong number of fds", - )); + return Err(Error::unsupported("snd_pcm_poll_descriptors returned wrong number of fds")) } Ok(fds[0].fd) } impl Status { - pub fn new(p: &pcm::PCM) -> Result { - Status::from_fd(pcm_to_fd(p)?) - } + pub fn new(p: &pcm::PCM) -> Result { Status::from_fd(pcm_to_fd(p)?) } pub fn from_fd(fd: RawFd) -> Result { DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_STATUS as libc::off_t, false).map(Status) @@ -134,10 +109,7 @@ impl Status { pub fn state(&self) -> pcm::State { unsafe { let i = ptr::read_volatile(&(*self.0.ptr).state); - assert!( - (i >= (pcm::State::Open as snd_pcm_state_t)) - && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) - ); + assert!((i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t))); mem::transmute(i as u8) } } @@ -150,7 +122,9 @@ impl Status { /// /// This value wraps at "boundary" (a large value you can read from SwParams). pub fn hw_ptr(&self) -> pcm::Frames { - unsafe { ptr::read_volatile(&(*self.0.ptr).hw_ptr) as pcm::Frames } + unsafe { + ptr::read_volatile(&(*self.0.ptr).hw_ptr) as pcm::Frames + } } /// Timestamp - fast version of alsa-lib's Status::get_htstamp @@ -159,7 +133,9 @@ impl Status { /// Unfortunately, the timespec is too big to be read atomically on most archs. /// Therefore, this function can potentially give bogus result at times, at least in theory...? pub fn htstamp(&self) -> libc::timespec { - unsafe { ptr::read_volatile(&(*self.0.ptr).tstamp) } + unsafe { + ptr::read_volatile(&(*self.0.ptr).tstamp) + } } /// Audio timestamp - fast version of alsa-lib's Status::get_audio_htstamp @@ -168,7 +144,9 @@ impl Status { /// Unfortunately, the timespec is too big to be read atomically on most archs. /// Therefore, this function can potentially give bogus result at times, at least in theory...? pub fn audio_htstamp(&self) -> libc::timespec { - unsafe { ptr::read_volatile(&(*self.0.ptr).audio_tstamp) } + unsafe { + ptr::read_volatile(&(*self.0.ptr).audio_tstamp) + } } } @@ -180,9 +158,7 @@ impl Status { pub struct Control(DriverMemory); impl Control { - pub fn new(p: &pcm::PCM) -> Result { - Self::from_fd(pcm_to_fd(p)?) - } + pub fn new(p: &pcm::PCM) -> Result { Self::from_fd(pcm_to_fd(p)?) } pub fn from_fd(fd: RawFd) -> Result { DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_CONTROL as libc::off_t, true).map(Control) @@ -192,7 +168,9 @@ impl Control { /// /// This value wraps at "boundary" (a large value you can read from SwParams). pub fn appl_ptr(&self) -> pcm::Frames { - unsafe { ptr::read_volatile(&(*self.0.ptr).appl_ptr) as pcm::Frames } + unsafe { + ptr::read_volatile(&(*self.0.ptr).appl_ptr) as pcm::Frames + } } /// Set number of frames application has read or written @@ -201,29 +179,33 @@ impl Control { /// be checked by the kernel. An XRUN will happen in case the application /// has not read or written enough data. pub fn set_appl_ptr(&self, value: pcm::Frames) { - unsafe { ptr::write_volatile(&mut (*self.0.ptr).appl_ptr, value as snd_pcm_uframes_t) } + unsafe { + ptr::write_volatile(&mut (*self.0.ptr).appl_ptr, value as snd_pcm_uframes_t) + } } /// Read minimum number of frames in buffer in order to wakeup process pub fn avail_min(&self) -> pcm::Frames { - unsafe { ptr::read_volatile(&(*self.0.ptr).avail_min) as pcm::Frames } + unsafe { + ptr::read_volatile(&(*self.0.ptr).avail_min) as pcm::Frames + } } /// Write minimum number of frames in buffer in order to wakeup process pub fn set_avail_min(&self, value: pcm::Frames) { - unsafe { ptr::write_volatile(&mut (*self.0.ptr).avail_min, value as snd_pcm_uframes_t) } + unsafe { + ptr::write_volatile(&mut (*self.0.ptr).avail_min, value as snd_pcm_uframes_t) + } } } struct DriverMemory { - ptr: *mut S, - size: libc::size_t, + ptr: *mut S, + size: libc::size_t, } impl fmt::Debug for DriverMemory { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DriverMemory({:?})", self.ptr) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "DriverMemory({:?})", self.ptr) } } impl DriverMemory { @@ -231,31 +213,13 @@ impl DriverMemory { let mut total = count * mem::size_of::(); let ps = pagesize(); assert!(total > 0); - if total % ps != 0 { - total += ps - total % ps - }; - let flags = if writable { - libc::PROT_WRITE | libc::PROT_READ - } else { - libc::PROT_READ - }; - let p = unsafe { - libc::mmap( - ptr::null_mut(), - total, - flags, - libc::MAP_FILE | libc::MAP_SHARED, - fd, - offs, - ) - }; + if total % ps != 0 { total += ps - total % ps }; + let flags = if writable { libc::PROT_WRITE | libc::PROT_READ } else { libc::PROT_READ }; + let p = unsafe { libc::mmap(ptr::null_mut(), total, flags, libc::MAP_FILE | libc::MAP_SHARED, fd, offs) }; if p.is_null() || p == libc::MAP_FAILED { Err(Error::last("mmap (of driver memory)")) } else { - Ok(DriverMemory { - ptr: p as *mut S, - size: total, - }) + Ok(DriverMemory { ptr: p as *mut S, size: total }) } } } @@ -265,11 +229,7 @@ unsafe impl Sync for DriverMemory {} impl Drop for DriverMemory { fn drop(&mut self) { - unsafe { - { - libc::munmap(self.ptr as *mut libc::c_void, self.size); - } - } + unsafe {{ libc::munmap(self.ptr as *mut libc::c_void, self.size); } } } } @@ -286,7 +246,7 @@ impl SampleData { let bufsize = params.get_buffer_size()?; let channels = params.get_channels()?; if params.get_access()? != pcm::Access::MMapInterleaved { - return Err(Error::unsupported("Not MMAP interleaved data")); + return Err(Error::unsupported("Not MMAP interleaved data")) } let fd = pcm_to_fd(p)?; @@ -297,21 +257,17 @@ impl SampleData { }; // println!("{:?}", info); if (info.step != channels * mem::size_of::() as u32 * 8) || (info.first != 0) { - return Err(Error::unsupported("MMAP data size mismatch")); + return Err(Error::unsupported("MMAP data size mismatch")) } Ok(SampleData { - mem: DriverMemory::new( - fd, - (bufsize as usize) * (channels as usize), - info.offset as libc::off_t, - true, - )?, + mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset as libc::off_t, true)?, frames: bufsize, channels, }) } } + /// Dummy trait for better generics pub trait MmapDir: fmt::Debug { const DIR: Direction; @@ -326,13 +282,9 @@ impl MmapDir for Playback { const DIR: Direction = Direction::Playback; #[inline] fn avail(hwptr: Frames, applptr: Frames, buffersize: Frames, boundary: Frames) -> Frames { - let r = hwptr.wrapping_add(buffersize).wrapping_sub(applptr); - let r = if r < 0 { r.wrapping_add(boundary) } else { r }; - if r as usize >= boundary as usize { - r.wrapping_sub(boundary) - } else { - r - } + let r = hwptr.wrapping_add(buffersize).wrapping_sub(applptr); + let r = if r < 0 { r.wrapping_add(boundary) } else { r }; + if r as usize >= boundary as usize { r.wrapping_sub(boundary) } else { r } } } @@ -344,12 +296,8 @@ impl MmapDir for Capture { const DIR: Direction = Direction::Capture; #[inline] fn avail(hwptr: Frames, applptr: Frames, _buffersize: Frames, boundary: Frames) -> Frames { - let r = hwptr.wrapping_sub(applptr); - if r < 0 { - r.wrapping_add(boundary) - } else { - r - } + let r = hwptr.wrapping_sub(applptr); + if r < 0 { r.wrapping_add(boundary) } else { r } } } @@ -378,28 +326,23 @@ pub struct RawSamples { impl RawSamples { #[inline] /// Returns `frames` * `channels`, i e the amount of samples (of type `S`) that can be read/written. - pub fn samples(&self) -> isize { - self.frames as isize * (self.channels as isize) - } + pub fn samples(&self) -> isize { self.frames as isize * (self.channels as isize) } /// Writes samples from an iterator. /// /// Returns true if iterator was depleted, and the number of samples written. /// This is just raw read/write of memory. - pub unsafe fn write_samples>(&self, i: &mut I) -> (bool, isize) { + pub unsafe fn write_samples>(&self, i: &mut I) -> (bool, isize) { let mut z = 0; let max_samples = self.samples(); while z < max_samples { - let b = if let Some(b) = i.next() { - b - } else { - return (true, z); - }; + let b = if let Some(b) = i.next() { b } else { return (true, z) }; ptr::write_volatile(self.ptr.offset(z), b); z += 1; - } + }; (false, z) } + } impl MmapIO { @@ -418,72 +361,49 @@ impl MmapIO { } } -pub(crate) fn new_mmap(p: &pcm::PCM) -> Result> { - MmapIO::new(p) -} +pub (crate) fn new_mmap(p: &pcm::PCM) -> Result> { MmapIO::new(p) } impl MmapIO { /// Read current status - pub fn status(&self) -> &Status { - &self.ss - } + pub fn status(&self) -> &Status { &self.ss } /// Read current number of frames committed by application /// /// This number wraps at 'boundary'. #[inline] - pub fn appl_ptr(&self) -> Frames { - self.c.appl_ptr() - } + pub fn appl_ptr(&self) -> Frames { self.c.appl_ptr() } /// Read current number of frames read / written by hardware /// /// This number wraps at 'boundary'. #[inline] - pub fn hw_ptr(&self) -> Frames { - self.ss.hw_ptr() - } + pub fn hw_ptr(&self) -> Frames { self.ss.hw_ptr() } /// The number at which hw_ptr and appl_ptr wraps. #[inline] - pub fn boundary(&self) -> Frames { - self.bound - } + pub fn boundary(&self) -> Frames { self.bound } /// Total number of frames in hardware buffer #[inline] - pub fn buffer_size(&self) -> Frames { - self.data.frames - } + pub fn buffer_size(&self) -> Frames { self.data.frames } /// Number of channels in stream #[inline] - pub fn channels(&self) -> u32 { - self.data.channels - } + pub fn channels(&self) -> u32 { self.data.channels } /// Notifies the kernel that frames have now been read / written by the application /// /// This will allow the kernel to write new data into this part of the buffer. pub fn commit(&self, v: Frames) { let mut z = self.appl_ptr() + v; - if z + v >= self.boundary() { - z -= self.boundary() - }; + if z + v >= self.boundary() { z -= self.boundary() }; self.c.set_appl_ptr(z) } /// Number of frames available to read / write. /// /// In case of an underrun, this value might be bigger than the buffer size. - pub fn avail(&self) -> Frames { - D::avail( - self.hw_ptr(), - self.appl_ptr(), - self.buffer_size(), - self.boundary(), - ) - } + pub fn avail(&self) -> Frames { D::avail(self.hw_ptr(), self.appl_ptr(), self.buffer_size(), self.boundary()) } /// Returns raw pointers to data to read / write. /// @@ -507,41 +427,23 @@ impl MmapIO { let more_data = if b < a { let z = a - b; a = b; - Some(RawSamples { - ptr: self.data.mem.ptr, - frames: z, - channels: c, - }) - } else { - None - }; + Some( RawSamples { ptr: self.data.mem.ptr, frames: z, channels: c }) + } else { None }; - let p = unsafe { - self.data - .mem - .ptr - .offset(offs as isize * self.data.channels as isize) - }; - ( - RawSamples { - ptr: p, - frames: a, - channels: c, - }, - more_data, - ) + let p = unsafe { self.data.mem.ptr.offset(offs as isize * self.data.channels as isize) }; + (RawSamples { ptr: p, frames: a, channels: c }, more_data) } } impl MmapPlayback { /// Write samples to the kernel ringbuffer. - pub fn write>(&mut self, i: &mut I) -> Frames { + pub fn write>(&mut self, i: &mut I) -> Frames { let (data, more_data) = self.data_ptr(); let (iter_end, samples) = unsafe { data.write_samples(i) }; let mut z = samples / data.channels as isize; if !iter_end { if let Some(data2) = more_data { - let (_, samples2) = unsafe { data2.write_samples(i) }; + let (_, samples2) = unsafe { data2.write_samples(i) }; z += samples2 / data2.channels as isize; } } @@ -583,8 +485,7 @@ impl<'a, S: 'static + Copy> CaptureIter<'a, S> { if let Some(p2) = self.next_p.take() { self.samples = p2; } else { - self.m - .commit((self.read_samples / self.samples.channels as isize) as Frames); + self.m.commit((self.read_samples / self.samples.channels as isize) as Frames); self.read_samples = 0; self.samples.frames = 0; // Shortcut to "None" in case anyone calls us again } @@ -598,9 +499,7 @@ impl<'a, S: 'static + Copy> Iterator for CaptureIter<'a, S> { fn next(&mut self) -> Option { if self.p_offs >= self.samples.samples() { self.handle_max(); - if self.samples.frames <= 0 { - return None; - } + if self.samples.frames <= 0 { return None; } } let s = unsafe { ptr::read_volatile(self.samples.ptr.offset(self.p_offs)) }; self.p_offs += 1; @@ -611,23 +510,18 @@ impl<'a, S: 'static + Copy> Iterator for CaptureIter<'a, S> { impl<'a, S: 'static> Drop for CaptureIter<'a, S> { fn drop(&mut self) { - self.m - .commit((self.read_samples / self.m.data.channels as isize) as Frames); + self.m.commit((self.read_samples / self.m.data.channels as isize) as Frames); } } + #[test] #[ignore] // Not everyone has a recording device on plughw:1. So let's ignore this test by default. fn record_from_plughw_rw() { use crate::pcm::*; - use crate::{Direction, ValueOr}; + use crate::{ValueOr, Direction}; use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("plughw:1").unwrap(), - Direction::Capture, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Capture, false).unwrap(); let ss = self::Status::new(&pcm).unwrap(); let c = self::Control::new(&pcm).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); @@ -646,7 +540,7 @@ fn record_from_plughw_rw() { pcm.start().unwrap(); assert_eq!(c.appl_ptr(), 0); println!("{:?}, {:?}", ss, c); - let mut buf = [0i16; 512 * 2]; + let mut buf = [0i16; 512*2]; assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 512); assert_eq!(c.appl_ptr(), 512); @@ -656,20 +550,16 @@ fn record_from_plughw_rw() { assert!(t2.tv_sec > 0 || t2.tv_nsec > 0); } + #[test] #[ignore] // Not everyone has a record device on plughw:1. So let's ignore this test by default. fn record_from_plughw_mmap() { use crate::pcm::*; - use crate::{Direction, ValueOr}; + use crate::{ValueOr, Direction}; use std::ffi::CString; use std::{thread, time}; - let pcm = PCM::open( - &*CString::new("plughw:1").unwrap(), - Direction::Capture, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Capture, false).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -677,8 +567,7 @@ fn record_from_plughw_mmap() { hwp.set_access(Access::MMapInterleaved).unwrap(); pcm.hw_params(&hwp).unwrap(); - let ss = - unsafe { SyncPtrStatus::sync_ptr(pcm_to_fd(&pcm).unwrap(), false, None, None).unwrap() }; + let ss = unsafe { SyncPtrStatus::sync_ptr(pcm_to_fd(&pcm).unwrap(), false, None, None).unwrap() }; assert_eq!(ss.state(), State::Prepared); let mut m = pcm.direct_mmap_capture::().unwrap(); @@ -687,24 +576,18 @@ fn record_from_plughw_mmap() { assert_eq!(m.appl_ptr(), 0); assert_eq!(m.hw_ptr(), 0); + println!("{:?}", m); let now = time::Instant::now(); pcm.start().unwrap(); - while m.avail() < 256 { - thread::sleep(time::Duration::from_millis(1)) - } + while m.avail() < 256 { thread::sleep(time::Duration::from_millis(1)) }; assert!(now.elapsed() >= time::Duration::from_millis(256 * 1000 / 44100)); let (ptr1, md) = m.data_ptr(); assert_eq!(ptr1.channels, 2); assert!(ptr1.frames >= 256); assert!(md.is_none()); - println!( - "Has {:?} frames at {:?} in {:?}", - m.avail(), - ptr1.ptr, - now.elapsed() - ); + println!("Has {:?} frames at {:?} in {:?}", m.avail(), ptr1.ptr, now.elapsed()); let samples: Vec = m.iter().collect(); assert!(samples.len() >= ptr1.frames as usize * 2); println!("Collected {} samples", samples.len()); @@ -716,15 +599,10 @@ fn record_from_plughw_mmap() { #[ignore] fn playback_to_plughw_mmap() { use crate::pcm::*; - use crate::{Direction, ValueOr}; + use crate::{ValueOr, Direction}; use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("plughw:1").unwrap(), - Direction::Playback, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("plughw:1").unwrap(), Direction::Playback, false).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -738,8 +616,8 @@ fn playback_to_plughw_mmap() { assert_eq!(m.hw_ptr(), 0); println!("{:?}", m); - let mut i = (0..(m.buffer_size() * 2)) - .map(|i| (((i / 2) as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16); + let mut i = (0..(m.buffer_size() * 2)).map(|i| + (((i / 2) as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16); m.write(&mut i); assert_eq!(m.appl_ptr(), m.buffer_size()); diff --git a/src/hctl.rs b/src/hctl.rs index 3e6f730..225322d 100644 --- a/src/hctl.rs +++ b/src/hctl.rs @@ -32,12 +32,14 @@ I suppose there is a better solution for this but I'm not sure how. */ -use super::error::*; -use super::{ctl_int, poll}; + use crate::{alsa, Card}; -use libc::{c_int, c_short, c_uint, pollfd}; use std::ffi::{CStr, CString}; +use super::error::*; use std::ptr; +use super::{ctl_int, poll}; +use libc::{c_short, c_uint, c_int, pollfd}; + /// [snd_hctl_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper pub struct HCtl(*mut alsa::snd_hctl_t); @@ -45,9 +47,7 @@ pub struct HCtl(*mut alsa::snd_hctl_t); unsafe impl Send for HCtl {} impl Drop for HCtl { - fn drop(&mut self) { - unsafe { alsa::snd_hctl_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_hctl_close(self.0) }; } } impl HCtl { @@ -61,7 +61,8 @@ impl HCtl { pub fn open(c: &CStr, nonblock: bool) -> Result { let mut r = ptr::null_mut(); let flags = if nonblock { 1 } else { 0 }; // FIXME: alsa::SND_CTL_NONBLOCK does not exist in alsa-sys - acheck!(snd_hctl_open(&mut r, c.as_ptr(), flags)).map(|_| HCtl(r)) + acheck!(snd_hctl_open(&mut r, c.as_ptr(), flags)) + .map(|_| HCtl(r)) } /// Wrapper around open. You probably want to call `load` afterwards. @@ -70,21 +71,13 @@ impl HCtl { HCtl::new(&s, nonblock) } - pub fn load(&self) -> Result<()> { - acheck!(snd_hctl_load(self.0)).map(|_| ()) - } + pub fn load(&self) -> Result<()> { acheck!(snd_hctl_load(self.0)).map(|_| ()) } - pub fn elem_iter(&self) -> ElemIter { - ElemIter(self, ptr::null_mut()) - } + pub fn elem_iter(&self) -> ElemIter { ElemIter(self, ptr::null_mut()) } pub fn find_elem(&self, id: &ctl_int::ElemId) -> Option { let p = unsafe { alsa::snd_hctl_find_elem(self.0, ctl_int::elem_id_ptr(id)) }; - if p.is_null() { - None - } else { - Some(Elem(self, p)) - } + if p.is_null() { None } else { Some(Elem(self, p)) } } pub fn handle_events(&self) -> Result { @@ -92,12 +85,7 @@ impl HCtl { } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_hctl_wait( - self.0, - timeout_ms.map(|x| x as c_int).unwrap_or(-1) - )) - .map(|i| i == 1) - } + acheck!(snd_hctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } } impl poll::Descriptors for HCtl { @@ -105,22 +93,13 @@ impl poll::Descriptors for HCtl { unsafe { alsa::snd_hctl_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = - unsafe { alsa::snd_hctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = unsafe { alsa::snd_hctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_hctl_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_hctl_poll_descriptors_revents( - self.0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_hctl_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_hctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_hctl_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -130,19 +109,14 @@ pub struct ElemIter<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t); impl<'a> Iterator for ElemIter<'a> { type Item = Elem<'a>; fn next(&mut self) -> Option> { - self.1 = if self.1.is_null() { - unsafe { alsa::snd_hctl_first_elem((self.0).0) } - } else { - unsafe { alsa::snd_hctl_elem_next(self.1) } - }; - if self.1.is_null() { - None - } else { - Some(Elem(self.0, self.1)) - } + self.1 = if self.1.is_null() { unsafe { alsa::snd_hctl_first_elem((self.0).0) }} + else { unsafe { alsa::snd_hctl_elem_next(self.1) }}; + if self.1.is_null() { None } + else { Some(Elem(self.0, self.1)) } } } + /// [snd_hctl_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper pub struct Elem<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t); @@ -171,11 +145,7 @@ impl<'a> Elem<'a> { fn print_hctls() { for a in super::card::Iter::new().map(|x| x.unwrap()) { use std::ffi::CString; - let h = HCtl::open( - &CString::new(format!("hw:{}", a.get_index())).unwrap(), - false, - ) - .unwrap(); + let h = HCtl::open(&CString::new(format!("hw:{}", a.get_index())).unwrap(), false).unwrap(); h.load().unwrap(); println!("Card {}:", a.get_name().unwrap()); for b in h.elem_iter() { @@ -188,33 +158,18 @@ fn print_hctls() { fn print_jacks() { for a in super::card::Iter::new().map(|x| x.unwrap()) { use std::ffi::CString; - let h = HCtl::open( - &CString::new(format!("hw:{}", a.get_index())).unwrap(), - false, - ) - .unwrap(); + let h = HCtl::open(&CString::new(format!("hw:{}", a.get_index())).unwrap(), false).unwrap(); h.load().unwrap(); for b in h.elem_iter() { let id = b.get_id().unwrap(); - if id.get_interface() != super::ctl_int::ElemIface::Card { - continue; - } + if id.get_interface() != super::ctl_int::ElemIface::Card { continue; } let name = id.get_name().unwrap(); - if !name.ends_with(" Jack") { - continue; - } + if !name.ends_with(" Jack") { continue; } if name.ends_with(" Phantom Jack") { - println!("{} is always present", &name[..name.len() - 13]) - } else { - println!( - "{} is {}", - &name[..name.len() - 5], - if b.read().unwrap().get_boolean(0).unwrap() { - "plugged in" - } else { - "unplugged" - } - ) + println!("{} is always present", &name[..name.len()-13]) + } + else { println!("{} is {}", &name[..name.len()-5], + if b.read().unwrap().get_boolean(0).unwrap() { "plugged in" } else { "unplugged" }) } } } diff --git a/src/io.rs b/src/io.rs index b63f72e..de80827 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,6 +1,6 @@ -use super::error::*; use crate::alsa; -use std::{fmt, ptr, slice}; +use super::error::*; +use std::{slice, ptr, fmt}; /// [snd_output_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___output.html) wrapper pub struct Output(*mut alsa::snd_output_t); @@ -8,12 +8,11 @@ pub struct Output(*mut alsa::snd_output_t); unsafe impl Send for Output {} impl Drop for Output { - fn drop(&mut self) { - unsafe { alsa::snd_output_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_output_close(self.0) }; } } impl Output { + pub fn buffer_open() -> Result { let mut q = ptr::null_mut(); acheck!(snd_output_buffer_open(&mut q)).map(|_| Output(q)) @@ -23,11 +22,7 @@ impl Output { let b = unsafe { let mut q = ptr::null_mut(); let s = alsa::snd_output_buffer_string(self.0, &mut q); - if s == 0 { - &[] - } else { - slice::from_raw_parts(q as *const u8, s as usize) - } + if s == 0 { &[] } else { slice::from_raw_parts(q as *const u8, s as usize) } }; f(b) } @@ -51,6 +46,4 @@ impl fmt::Display for Output { } } -pub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { - o.0 -} +pub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { o.0 } diff --git a/src/lib.rs b/src/lib.rs index 2243cba..81ca0f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,17 +59,13 @@ impl $name { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Direction { Playback, - Capture, + Capture } impl Direction { #[inline] - pub fn input() -> Direction { - Direction::Capture - } + pub fn input() -> Direction { Direction::Capture } #[inline] - pub fn output() -> Direction { - Direction::Playback - } + pub fn output() -> Direction { Direction::Playback } } /// Used to restrict hw parameters. In case the submitted @@ -98,28 +94,26 @@ mod error; pub use crate::error::{Error, Result}; pub mod card; -pub use crate::card::Card; +pub use crate::card::Card as Card; mod ctl_int; pub mod ctl { //! Control device API - pub use super::ctl_int::{ - CardInfo, Ctl, DeviceIter, ElemId, ElemIface, ElemInfo, ElemList, ElemType, ElemValue, - }; + pub use super::ctl_int::{Ctl, CardInfo, DeviceIter, ElemIface, ElemId, ElemList, ElemType, ElemValue, ElemInfo}; } -pub use crate::ctl::Ctl; +pub use crate::ctl::Ctl as Ctl; pub mod hctl; -pub use crate::hctl::HCtl; +pub use crate::hctl::HCtl as HCtl; pub mod pcm; -pub use crate::pcm::PCM; +pub use crate::pcm::PCM as PCM; pub mod config; pub mod rawmidi; -pub use crate::rawmidi::Rawmidi; +pub use crate::rawmidi::Rawmidi as Rawmidi; pub mod device_name; @@ -127,10 +121,10 @@ pub mod poll; pub use crate::poll::Descriptors as PollDescriptors; pub mod mixer; -pub use crate::mixer::Mixer; +pub use crate::mixer::Mixer as Mixer; pub mod seq; -pub use crate::seq::Seq; +pub use crate::seq::Seq as Seq; mod io; pub use crate::io::Output; diff --git a/src/mixer.rs b/src/mixer.rs index 05a0afa..a08ea59 100644 --- a/src/mixer.rs +++ b/src/mixer.rs @@ -1,13 +1,13 @@ //! Mixer API - Simple Mixer API for mixer control //! -use crate::poll; -use libc::{c_int, c_long, c_short, c_uint, pollfd}; use std::ffi::{CStr, CString}; -use std::{fmt, mem, ops, ptr}; +use std::{ptr, mem, fmt, ops}; +use libc::{c_long, c_int, c_uint, c_short, pollfd}; +use crate::poll; -use super::error::*; -use super::Round; use crate::alsa; +use super::Round; +use super::error::*; const SELEM_ID_SIZE: usize = 64; @@ -32,14 +32,8 @@ impl Mixer { pub fn find_selem(&self, id: &SelemId) -> Option { let selem = unsafe { alsa::snd_mixer_find_selem(self.0, id.as_ptr()) }; - if selem.is_null() { - None - } else { - Some(Selem(Elem { - handle: selem, - _mixer: self, - })) - } + if selem.is_null() { None } + else { Some(Selem(Elem {handle: selem, _mixer: self})) } } pub fn open(nonblock: bool) -> Result { @@ -59,7 +53,7 @@ impl Mixer { pub fn iter(&self) -> Iter { Iter { last_handle: ptr::null_mut(), - mixer: self, + mixer: self } } @@ -68,12 +62,7 @@ impl Mixer { } pub fn wait(&self, timeout_ms: Option) -> Result<()> { - acheck!(snd_mixer_wait( - self.0, - timeout_ms.map(|x| x as c_int).unwrap_or(-1) - )) - .map(|_| ()) - } + acheck!(snd_mixer_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|_| ()) } } /// Closes mixer and frees used resources @@ -83,30 +72,23 @@ impl Drop for Mixer { } } + impl poll::Descriptors for Mixer { fn count(&self) -> usize { unsafe { alsa::snd_mixer_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = - unsafe { alsa::snd_mixer_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = unsafe { alsa::snd_mixer_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_mixer_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_mixer_poll_descriptors_revents( - self.0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_mixer_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_mixer_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_mixer_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } + /// Wrapper for a mB (millibel) value. /// /// Despite some ALSA functions named "dB", they actually take mB values instead. @@ -116,59 +98,45 @@ impl poll::Descriptors for Mixer { pub struct MilliBel(pub i64); impl MilliBel { - pub fn to_db(self) -> f32 { - (self.0 as f32) / 100.0 - } - pub fn from_db(db: f32) -> Self { - MilliBel((db * 100.0) as i64) - } + pub fn to_db(self) -> f32 { (self.0 as f32) / 100.0 } + pub fn from_db(db: f32) -> Self { MilliBel((db * 100.0) as i64) } } impl ops::Deref for MilliBel { type Target = i64; - fn deref(&self) -> &i64 { - &self.0 - } + fn deref(&self) -> &i64 { &self.0 } } impl ops::Add for MilliBel { type Output = MilliBel; - fn add(self, rhs: Self) -> Self { - MilliBel(self.0 + rhs.0) - } + fn add(self, rhs: Self) -> Self { MilliBel(self.0 + rhs.0) } } impl ops::AddAssign for MilliBel { - fn add_assign(&mut self, rhs: Self) { - self.0 += rhs.0 - } + fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 } } impl ops::Sub for MilliBel { type Output = MilliBel; - fn sub(self, rhs: Self) -> Self { - MilliBel(self.0 - rhs.0) - } + fn sub(self, rhs: Self) -> Self { MilliBel(self.0 - rhs.0) } } impl ops::SubAssign for MilliBel { - fn sub_assign(&mut self, rhs: Self) { - self.0 -= rhs.0 - } + fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 } } /// Wraps [snd_mixer_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html) #[derive(Copy, Clone, Debug)] -pub struct Elem<'a> { +pub struct Elem<'a>{ handle: *mut alsa::snd_mixer_elem_t, - _mixer: &'a Mixer, + _mixer: &'a Mixer } /// Iterator for all elements of mixer #[derive(Copy, Clone)] -pub struct Iter<'a> { +pub struct Iter<'a>{ last_handle: *mut alsa::snd_mixer_elem_t, - mixer: &'a Mixer, + mixer: &'a Mixer } impl<'a> Iterator for Iter<'a> { @@ -185,12 +153,10 @@ impl<'a> Iterator for Iter<'a> { None } else { self.last_handle = elem; - Some(Elem { - handle: elem, - _mixer: self.mixer, - }) + Some(Elem { handle: elem, _mixer: self.mixer}) } } + } /// Wrapper for [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html) @@ -199,6 +165,7 @@ impl<'a> Iterator for Iter<'a> { pub struct SelemId([u8; SELEM_ID_SIZE]); impl SelemId { + pub fn new(name: &str, index: u32) -> SelemId { let mut s = SelemId::empty(); s.set_name(&CString::new(name).unwrap()); @@ -237,6 +204,7 @@ impl SelemId { pub fn set_index(&mut self, index: u32) { unsafe { alsa::snd_mixer_selem_id_set_index(self.as_ptr(), index) }; } + } /// Wraps an Elem as a Selem @@ -246,21 +214,13 @@ pub struct Selem<'a>(Elem<'a>); impl<'a> Selem<'a> { /// Creates a Selem by wrapping `elem`. pub fn new(elem: Elem<'a>) -> Option> { - if unsafe { alsa::snd_mixer_elem_get_type(elem.handle) } == alsa::SND_MIXER_ELEM_SIMPLE { - Some(Selem(elem)) - } else { - None - } + if unsafe { alsa::snd_mixer_elem_get_type(elem.handle) } == alsa::SND_MIXER_ELEM_SIMPLE + { Some(Selem(elem)) } else { None } } /// TODO: This function might change to support regopt and to return the mixer class pub fn register(mixer: &mut Mixer) -> Result<()> { - acheck!(snd_mixer_selem_register( - mixer.0, - ptr::null_mut(), - ptr::null_mut() - )) - .map(|_| ()) + acheck!(snd_mixer_selem_register(mixer.0, ptr::null_mut(), ptr::null_mut())).map(|_| ()) } pub fn get_id(&self) -> SelemId { @@ -353,12 +313,7 @@ impl<'a> Selem<'a> { pub fn get_playback_volume(&self, channel: SelemChannelId) -> Result { let mut value: c_long = 0; - acheck!(snd_mixer_selem_get_playback_volume( - self.handle, - channel as i32, - &mut value - )) - .and_then(|_| Ok(value as i64)) + acheck!(snd_mixer_selem_get_playback_volume(self.handle, channel as i32, &mut value)).and_then(|_| Ok(value as i64)) } /// returns volume in millibels. @@ -370,34 +325,20 @@ impl<'a> Selem<'a> { /// Asks alsa to convert playback volume to millibels. pub fn ask_playback_vol_db(&self, volume: i64) -> Result { let mut decibel_value: c_long = 0; - acheck!(snd_mixer_selem_ask_playback_vol_dB( - self.handle, - volume as c_long, - &mut decibel_value - )) - .map(|_| MilliBel(decibel_value as i64)) + acheck!(snd_mixer_selem_ask_playback_vol_dB(self.handle, volume as c_long, &mut decibel_value)) + .map(|_| MilliBel(decibel_value as i64)) } // Asks alsa to convert millibels to playback volume. pub fn ask_playback_db_vol(&self, db: MilliBel, dir: Round) -> Result { let mut raw_volume: c_long = 0; - acheck!(snd_mixer_selem_ask_playback_dB_vol( - self.handle, - db.0 as c_long, - dir as c_int, - &mut raw_volume - )) - .map(|_| raw_volume as i64) + acheck!(snd_mixer_selem_ask_playback_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume)) + .map(|_| raw_volume as i64) } pub fn get_capture_volume(&self, channel: SelemChannelId) -> Result { let mut value: c_long = 0; - acheck!(snd_mixer_selem_get_capture_volume( - self.handle, - channel as i32, - &mut value - )) - .map(|_| value as i64) + acheck!(snd_mixer_selem_get_capture_volume(self.handle, channel as i32, &mut value)).map(|_| value as i64) } /// returns volume in millibels. @@ -409,133 +350,59 @@ impl<'a> Selem<'a> { /// Asks alsa to convert capture volume to millibels pub fn ask_capture_vol_db(&self, volume: i64) -> Result { let mut decibel_value: c_long = 0; - acheck!(snd_mixer_selem_ask_capture_vol_dB( - self.handle, - volume as c_long, - &mut decibel_value - )) - .map(|_| MilliBel(decibel_value as i64)) + acheck!(snd_mixer_selem_ask_capture_vol_dB (self.handle, volume as c_long, &mut decibel_value)) + .map(|_| MilliBel(decibel_value as i64)) } // Asks alsa to convert millibels to capture volume. pub fn ask_capture_db_vol(&self, db: MilliBel, dir: Round) -> Result { let mut raw_volume: c_long = 0; - acheck!(snd_mixer_selem_ask_capture_dB_vol( - self.handle, - db.0 as c_long, - dir as c_int, - &mut raw_volume - )) - .map(|_| raw_volume as i64) + acheck!(snd_mixer_selem_ask_capture_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume)) + .map(|_| raw_volume as i64) } pub fn set_playback_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume( - self.handle, - channel as i32, - value as c_long - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume(self.handle, channel as i32, value as c_long)).map(|_| ()) } pub fn set_playback_volume_range(&self, min: i64, max: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume_range( - self.handle, - min as c_long, - max as c_long - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ()) } pub fn set_playback_volume_all(&self, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_volume_all( - self.handle, - value as c_long - )) - .map(|_| ()) - } - - pub fn set_playback_db( - &self, - channel: SelemChannelId, - value: MilliBel, - dir: Round, - ) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_dB( - self.handle, - channel as i32, - *value as c_long, - dir as c_int - )) - .map(|_| ()) - } - - pub fn set_capture_db( - &self, - channel: SelemChannelId, - value: MilliBel, - dir: Round, - ) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_dB( - self.handle, - channel as i32, - *value as c_long, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_playback_volume_all(self.handle, value as c_long)).map(|_| ()) + } + + pub fn set_playback_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> { + acheck!(snd_mixer_selem_set_playback_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ()) + } + + pub fn set_capture_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> { + acheck!(snd_mixer_selem_set_capture_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ()) } pub fn set_playback_db_all(&self, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_dB_all( - self.handle, - *value as c_long, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_playback_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ()) } pub fn set_capture_db_all(&self, value: MilliBel, dir: Round) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_dB_all( - self.handle, - *value as c_long, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_capture_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ()) } pub fn set_capture_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume( - self.handle, - channel as i32, - value as c_long - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume(self.handle, channel as i32, value as c_long)).map(|_| ()) } pub fn set_capture_volume_range(&self, min: i64, max: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume_range( - self.handle, - min as c_long, - max as c_long - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ()) } pub fn set_capture_volume_all(&self, value: i64) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_volume_all( - self.handle, - value as c_long - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_capture_volume_all(self.handle, value as c_long)).map(|_| ()) } pub fn set_playback_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> { - acheck!(snd_mixer_selem_set_playback_switch( - self.handle, - channel as i32, - value - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_playback_switch(self.handle, channel as i32, value)).map(|_| ()) } pub fn set_playback_switch_all(&self, value: i32) -> Result<()> { @@ -543,12 +410,7 @@ impl<'a> Selem<'a> { } pub fn set_capture_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> { - acheck!(snd_mixer_selem_set_capture_switch( - self.handle, - channel as i32, - value - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_capture_switch(self.handle, channel as i32, value)).map(|_| ()) } pub fn set_capture_switch_all(&self, value: i32) -> Result<()> { @@ -557,22 +419,12 @@ impl<'a> Selem<'a> { pub fn get_playback_switch(&self, channel: SelemChannelId) -> Result { let mut value: i32 = 0; - acheck!(snd_mixer_selem_get_playback_switch( - self.handle, - channel as i32, - &mut value - )) - .map(|_| value) + acheck!(snd_mixer_selem_get_playback_switch(self.handle, channel as i32, &mut value)).map(|_| value) } pub fn get_capture_switch(&self, channel: SelemChannelId) -> Result { let mut value: i32 = 0; - acheck!(snd_mixer_selem_get_capture_switch( - self.handle, - channel as i32, - &mut value - )) - .map(|_| value) + acheck!(snd_mixer_selem_get_capture_switch(self.handle, channel as i32, &mut value)).map(|_| value) } pub fn is_enumerated(&self) -> bool { @@ -593,14 +445,9 @@ impl<'a> Selem<'a> { pub fn get_enum_item_name(&self, idx: u32) -> Result { let mut temp = [0 as ::libc::c_char; 128]; - acheck!(snd_mixer_selem_get_enum_item_name( - self.handle, - idx, - temp.len() - 1, - temp.as_mut_ptr() - )) - .and_then(|_| from_const("snd_mixer_selem_get_enum_item_name", temp.as_ptr())) - .map(|v| v.into()) + acheck!(snd_mixer_selem_get_enum_item_name(self.handle, idx, temp.len()-1, temp.as_mut_ptr())) + .and_then(|_| from_const("snd_mixer_selem_get_enum_item_name", temp.as_ptr())) + .map(|v| v.into()) } /// Enumerates over valid Enum values @@ -610,21 +457,13 @@ impl<'a> Selem<'a> { pub fn get_enum_item(&self, channel: SelemChannelId) -> Result { let mut temp = 0; - acheck!(snd_mixer_selem_get_enum_item( - self.handle, - channel as i32, - &mut temp - )) - .map(|_| temp) + acheck!(snd_mixer_selem_get_enum_item(self.handle, channel as i32, &mut temp)) + .map(|_| temp) } pub fn set_enum_item(&self, channel: SelemChannelId, idx: u32) -> Result<()> { - acheck!(snd_mixer_selem_set_enum_item( - self.handle, - channel as i32, - idx - )) - .map(|_| ()) + acheck!(snd_mixer_selem_set_enum_item(self.handle, channel as i32, idx)) + .map(|_| ()) } } @@ -642,12 +481,8 @@ pub struct IterEnum<'a>(&'a Selem<'a>, u32, u32); impl<'a> Iterator for IterEnum<'a> { type Item = Result; fn next(&mut self) -> Option { - if self.1 >= self.2 { - None - } else { - self.1 += 1; - Some(self.0.get_enum_item_name(self.1 - 1)) - } + if self.1 >= self.2 { None } + else { self.1 += 1; Some(self.0.get_enum_item_name(self.1-1)) } } } @@ -669,9 +504,7 @@ alsa_enum!( ); impl SelemChannelId { - pub fn mono() -> SelemChannelId { - SelemChannelId::FrontLeft - } + pub fn mono() -> SelemChannelId { SelemChannelId::FrontLeft } } impl fmt::Display for SelemChannelId { @@ -685,21 +518,13 @@ fn print_mixer_of_cards() { use super::card; for card in card::Iter::new().map(|c| c.unwrap()) { - println!( - "Card #{}: {} ({})", - card.get_index(), - card.get_name().unwrap(), - card.get_longname().unwrap() - ); + println!("Card #{}: {} ({})", card.get_index(), card.get_name().unwrap(), card.get_longname().unwrap()); let mixer = Mixer::new(&format!("hw:{}", card.get_index()), false).unwrap(); for selem in mixer.iter().filter_map(|e| Selem::new(e)) { + let sid = selem.get_id(); - println!( - "\tMixer element {},{}:", - sid.get_name().unwrap(), - sid.get_index() - ); + println!("\tMixer element {},{}:", sid.get_name().unwrap(), sid.get_index()); if selem.has_volume() { print!("\t Volume limits: "); @@ -720,14 +545,9 @@ fn print_mixer_of_cards() { if selem.is_enumerated() { print!("\t Valid values: "); - for v in selem.iter_enum().unwrap() { - print!("{}, ", v.unwrap()) - } + for v in selem.iter_enum().unwrap() { print!("{}, ", v.unwrap()) }; print!("\n\t Current values: "); - for v in SelemChannelId::all() - .iter() - .filter_map(|&v| selem.get_enum_item(v).ok()) - { + for v in SelemChannelId::all().iter().filter_map(|&v| selem.get_enum_item(v).ok()) { print!("{}, ", selem.get_enum_item_name(v).unwrap()); } println!(); @@ -739,28 +559,16 @@ fn print_mixer_of_cards() { print!("Mono"); } else { for channel in SelemChannelId::all() { - if selem.has_capture_channel(*channel) { - print!("{}, ", channel) - }; + if selem.has_capture_channel(*channel) { print!("{}, ", channel) }; } } println!(); print!("\t Capture volumes: "); for channel in SelemChannelId::all() { - if selem.has_capture_channel(*channel) { - print!( - "{}: {} ({} dB), ", - channel, - match selem.get_capture_volume(*channel) { - Ok(v) => format!("{}", v), - Err(_) => "n/a".to_string(), - }, - match selem.get_capture_vol_db(*channel) { - Ok(v) => format!("{}", v.to_db()), - Err(_) => "n/a".to_string(), - } - ); - } + if selem.has_capture_channel(*channel) { print!("{}: {} ({} dB), ", channel, + match selem.get_capture_volume(*channel) {Ok(v) => format!("{}", v), Err(_) => "n/a".to_string()}, + match selem.get_capture_vol_db(*channel) {Ok(v) => format!("{}", v.to_db()), Err(_) => "n/a".to_string()} + );} } println!(); } @@ -771,29 +579,18 @@ fn print_mixer_of_cards() { print!("Mono"); } else { for channel in SelemChannelId::all() { - if selem.has_playback_channel(*channel) { - print!("{}, ", channel) - }; + if selem.has_playback_channel(*channel) { print!("{}, ", channel) }; } } println!(); if selem.has_playback_volume() { print!("\t Playback volumes: "); for channel in SelemChannelId::all() { - if selem.has_playback_channel(*channel) { - print!( - "{}: {} / {}dB, ", - channel, - match selem.get_playback_volume(*channel) { - Ok(v) => format!("{}", v), - Err(_) => "n/a".to_string(), - }, - match selem.get_playback_vol_db(*channel) { - Ok(v) => format!("{}", v.to_db()), - Err(_) => "n/a".to_string(), - } - ); - } + if selem.has_playback_channel(*channel) { print!("{}: {} / {}dB, ", + channel, + match selem.get_playback_volume(*channel) {Ok(v) => format!("{}", v), Err(_) => "n/a".to_string()}, + match selem.get_playback_vol_db(*channel) {Ok(v) => format!("{}", v.to_db()), Err(_) => "n/a".to_string()} + );} } println!(); } @@ -811,18 +608,9 @@ fn get_and_set_playback_volume() { let (rmin, rmax) = selem.get_playback_volume_range(); let mut channel = SelemChannelId::mono(); for c in SelemChannelId::all().iter() { - if selem.has_playback_channel(*c) { - channel = *c; - break; - } + if selem.has_playback_channel(*c) { channel = *c; break } } - println!( - "Testing on {} with limits {}-{} on channel {}", - selem.get_id().get_name().unwrap(), - rmin, - rmax, - channel - ); + println!("Testing on {} with limits {}-{} on channel {}", selem.get_id().get_name().unwrap(), rmin, rmax, channel); let old: i64 = selem.get_playback_volume(channel).unwrap(); let new: i64 = rmax / 2; @@ -848,18 +636,9 @@ fn get_and_set_capture_volume() { let (rmin, rmax) = selem.get_capture_volume_range(); let mut channel = SelemChannelId::mono(); for c in SelemChannelId::all().iter() { - if selem.has_playback_channel(*c) { - channel = *c; - break; - } + if selem.has_playback_channel(*c) { channel = *c; break } } - println!( - "Testing on {} with limits {}-{} on channel {}", - selem.get_id().get_name().unwrap(), - rmin, - rmax, - channel - ); + println!("Testing on {} with limits {}-{} on channel {}", selem.get_id().get_name().unwrap(), rmin, rmax, channel); let old: i64 = selem.get_capture_volume(channel).unwrap(); let new: i64 = rmax / 2; @@ -876,6 +655,7 @@ fn get_and_set_capture_volume() { assert_eq!(old, result); } + #[test] fn print_sizeof() { let selemid = unsafe { alsa::snd_mixer_selem_id_sizeof() } as usize; diff --git a/src/pcm.rs b/src/pcm.rs index bcb4ed3..9d0c22b 100644 --- a/src/pcm.rs +++ b/src/pcm.rs @@ -42,16 +42,17 @@ //! pcm.drain().unwrap(); //! ``` -use super::error::*; -use super::{chmap, poll, Direction, Output, ValueOr}; + +use libc::{c_int, c_uint, c_void, ssize_t, c_short, timespec, pollfd}; use crate::alsa; -use libc::{c_int, c_short, c_uint, c_void, pollfd, ssize_t, timespec}; use std::convert::Infallible; -use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::mem::size_of; +use std::ffi::{CStr, CString}; use std::str::FromStr; -use std::{cell, fmt, io, ptr}; +use std::{io, fmt, ptr, cell}; +use super::error::*; +use super::{Direction, Output, poll, ValueOr, chmap}; pub use super::chmap::{Chmap, ChmapPosition, ChmapType, ChmapsQuery}; @@ -128,9 +129,7 @@ impl Info { } impl Drop for Info { - fn drop(&mut self) { - unsafe { alsa::snd_pcm_info_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_pcm_info_free(self.0) }; } } /// [snd_pcm_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper - start here for audio playback and recording @@ -140,9 +139,7 @@ unsafe impl Send for PCM {} impl PCM { fn check_has_io(&self) { - if self.1.get() { - panic!("No hw_params call or additional IO objects allowed") - } + if self.1.get() { panic!("No hw_params call or additional IO objects allowed") } } /// Wrapper around open that takes a &str instead of a &CStr @@ -155,37 +152,22 @@ impl PCM { let mut r = ptr::null_mut(); let stream = match dir { Direction::Capture => alsa::SND_PCM_STREAM_CAPTURE, - Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK, + Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK }; let flags = if nonblock { alsa::SND_PCM_NONBLOCK } else { 0 }; - acheck!(snd_pcm_open(&mut r, name.as_ptr(), stream, flags)) - .map(|_| PCM(r, cell::Cell::new(false))) + acheck!(snd_pcm_open(&mut r, name.as_ptr(), stream, flags)).map(|_| PCM(r, cell::Cell::new(false))) } - pub fn start(&self) -> Result<()> { - acheck!(snd_pcm_start(self.0)).map(|_| ()) - } - pub fn drop(&self) -> Result<()> { - acheck!(snd_pcm_drop(self.0)).map(|_| ()) - } + pub fn start(&self) -> Result<()> { acheck!(snd_pcm_start(self.0)).map(|_| ()) } + pub fn drop(&self) -> Result<()> { acheck!(snd_pcm_drop(self.0)).map(|_| ()) } pub fn pause(&self, pause: bool) -> Result<()> { - acheck!(snd_pcm_pause(self.0, if pause { 1 } else { 0 })).map(|_| ()) - } - pub fn resume(&self) -> Result<()> { - acheck!(snd_pcm_resume(self.0)).map(|_| ()) - } - pub fn drain(&self) -> Result<()> { - acheck!(snd_pcm_drain(self.0)).map(|_| ()) - } - pub fn prepare(&self) -> Result<()> { - acheck!(snd_pcm_prepare(self.0)).map(|_| ()) - } - pub fn reset(&self) -> Result<()> { - acheck!(snd_pcm_reset(self.0)).map(|_| ()) - } + acheck!(snd_pcm_pause(self.0, if pause { 1 } else { 0 })).map(|_| ()) } + pub fn resume(&self) -> Result<()> { acheck!(snd_pcm_resume(self.0)).map(|_| ()) } + pub fn drain(&self) -> Result<()> { acheck!(snd_pcm_drain(self.0)).map(|_| ()) } + pub fn prepare(&self) -> Result<()> { acheck!(snd_pcm_prepare(self.0)).map(|_| ()) } + pub fn reset(&self) -> Result<()> { acheck!(snd_pcm_reset(self.0)).map(|_| ()) } pub fn recover(&self, err: c_int, silent: bool) -> Result<()> { - acheck!(snd_pcm_recover(self.0, err, if silent { 1 } else { 0 })).map(|_| ()) - } + acheck!(snd_pcm_recover(self.0, err, if silent { 1 } else { 0 })).map(|_| ()) } /// Wrapper around snd_pcm_recover. /// @@ -196,40 +178,26 @@ impl PCM { } pub fn wait(&self, timeout_ms: Option) -> Result { - acheck!(snd_pcm_wait( - self.0, - timeout_ms.map(|x| x as c_int).unwrap_or(-1) - )) - .map(|i| i == 1) - } + acheck!(snd_pcm_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) } pub fn state(&self) -> State { let rawstate = self.state_raw(); if let Ok(state) = State::from_c_int(rawstate, "snd_pcm_state") { state - } else { + } + else { panic!("snd_pcm_state returned an invalid value of {}", rawstate); } } /// Only used internally, and for debugging the alsa library. Please use the "state" function instead. - pub fn state_raw(&self) -> c_int { - unsafe { alsa::snd_pcm_state(self.0) as c_int } - } + pub fn state_raw(&self) -> c_int { unsafe { alsa::snd_pcm_state(self.0) as c_int } } - pub fn bytes_to_frames(&self, i: isize) -> Frames { - unsafe { alsa::snd_pcm_bytes_to_frames(self.0, i as ssize_t) } - } - pub fn frames_to_bytes(&self, i: Frames) -> isize { - unsafe { alsa::snd_pcm_frames_to_bytes(self.0, i) as isize } - } + pub fn bytes_to_frames(&self, i: isize) -> Frames { unsafe { alsa::snd_pcm_bytes_to_frames(self.0, i as ssize_t) }} + pub fn frames_to_bytes(&self, i: Frames) -> isize { unsafe { alsa::snd_pcm_frames_to_bytes(self.0, i) as isize }} - pub fn avail_update(&self) -> Result { - acheck!(snd_pcm_avail_update(self.0)) - } - pub fn avail(&self) -> Result { - acheck!(snd_pcm_avail(self.0)) - } + pub fn avail_update(&self) -> Result { acheck!(snd_pcm_avail_update(self.0)) } + pub fn avail(&self) -> Result { acheck!(snd_pcm_avail(self.0)) } pub fn avail_delay(&self) -> Result<(Frames, Frames)> { let (mut a, mut d) = (0, 0); @@ -246,47 +214,26 @@ impl PCM { fn verify_format(&self, f: Format) -> Result<()> { let ff = self.hw_params_current().and_then(|h| h.get_format())?; - if ff == f { - Ok(()) - } else { + if ff == f { Ok(()) } + else { // let s = format!("Invalid sample format ({:?}, expected {:?})", ff, f); Err(Error::unsupported("io_xx")) } } - pub fn io_i8(&self) -> Result> { - self.io_checked() - } - pub fn io_u8(&self) -> Result> { - self.io_checked() - } - pub fn io_i16(&self) -> Result> { - self.io_checked() - } - pub fn io_u16(&self) -> Result> { - self.io_checked() - } - pub fn io_i32(&self) -> Result> { - self.io_checked() - } - pub fn io_u32(&self) -> Result> { - self.io_checked() - } - pub fn io_f32(&self) -> Result> { - self.io_checked() - } - pub fn io_f64(&self) -> Result> { - self.io_checked() - } + pub fn io_i8(&self) -> Result> { self.io_checked() } + pub fn io_u8(&self) -> Result> { self.io_checked() } + pub fn io_i16(&self) -> Result> { self.io_checked() } + pub fn io_u16(&self) -> Result> { self.io_checked() } + pub fn io_i32(&self) -> Result> { self.io_checked() } + pub fn io_u32(&self) -> Result> { self.io_checked() } + pub fn io_f32(&self) -> Result> { self.io_checked() } + pub fn io_f64(&self) -> Result> { self.io_checked() } /// For the `s24` format, represented by i32 - pub fn io_i32_s24(&self) -> Result> { - self.verify_format(Format::s24()).map(|_| IO::new(self)) - } + pub fn io_i32_s24(&self) -> Result> { self.verify_format(Format::s24()).map(|_| IO::new(self)) } /// For the `u24` format, represented by u32 - pub fn io_u32_u24(&self) -> Result> { - self.verify_format(Format::u24()).map(|_| IO::new(self)) - } + pub fn io_u32_u24(&self) -> Result> { self.verify_format(Format::u24()).map(|_| IO::new(self)) } pub fn io_checked(&self) -> Result> { self.verify_format(S::FORMAT).map(|_| IO::new(self)) @@ -302,16 +249,12 @@ impl PCM { } #[deprecated(note = "renamed to io_bytes")] - pub fn io(&self) -> IO { - IO::new(self) - } + pub fn io(&self) -> IO { IO::new(self) } /// Call this if you have an unusual format, not supported by the regular access methods /// (io_i16 etc). It will succeed regardless of the sample format, but conversion to and from /// bytes to your format is up to you. - pub fn io_bytes(&self) -> IO { - IO::new(self) - } + pub fn io_bytes(&self) -> IO { IO::new(self) } /// Read buffers by talking to the kernel directly, bypassing alsa-lib. pub fn direct_mmap_capture(&self) -> Result> { @@ -334,7 +277,8 @@ impl PCM { /// Retreive current PCM hardware configuration. pub fn hw_params_current(&self) -> Result { - HwParams::new(self).and_then(|h| acheck!(snd_pcm_hw_params_current(self.0, h.0)).map(|_| h)) + HwParams::new(self).and_then(|h| + acheck!(snd_pcm_hw_params_current(self.0, h.0)).map(|_| h)) } pub fn sw_params(&self, h: &SwParams) -> Result<()> { @@ -342,23 +286,22 @@ impl PCM { } pub fn sw_params_current(&self) -> Result { - SwParams::new(self).and_then(|h| acheck!(snd_pcm_sw_params_current(self.0, h.0)).map(|_| h)) + SwParams::new(self).and_then(|h| + acheck!(snd_pcm_sw_params_current(self.0, h.0)).map(|_| h)) } /// Wraps `snd_pcm_get_params`, returns `(buffer_size, period_size)`. pub fn get_params(&self) -> Result<(u64, u64)> { let mut buffer_size = 0; let mut period_size = 0; - acheck!(snd_pcm_get_params( - self.0, - &mut buffer_size, - &mut period_size - )) - .map(|_| (buffer_size as u64, period_size as u64)) + acheck!(snd_pcm_get_params(self.0, &mut buffer_size, &mut period_size)) + .map(|_| (buffer_size as u64, period_size as u64)) + } pub fn info(&self) -> Result { - Info::new().and_then(|info| acheck!(snd_pcm_info(self.0, info.0)).map(|_| info)) + Info::new().and_then(|info| + acheck!(snd_pcm_info(self.0, info.0)).map(|_| info )) } pub fn dump(&self, o: &mut Output) -> Result<()> { @@ -383,11 +326,8 @@ impl PCM { pub fn get_chmap(&self) -> Result { let p = unsafe { alsa::snd_pcm_get_chmap(self.0) }; - if p.is_null() { - Err(Error::unsupported("snd_pcm_get_chmap")) - } else { - Ok(chmap::chmap_new(p)) - } + if p.is_null() { Err(Error::unsupported("snd_pcm_get_chmap")) } + else { Ok(chmap::chmap_new(p)) } } pub fn link(&self, other: &PCM) -> Result<()> { @@ -400,32 +340,22 @@ impl PCM { } impl Drop for PCM { - fn drop(&mut self) { - unsafe { alsa::snd_pcm_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_pcm_close(self.0) }; } } + impl poll::Descriptors for PCM { fn count(&self) -> usize { unsafe { alsa::snd_pcm_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = - unsafe { alsa::snd_pcm_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; + let z = unsafe { alsa::snd_pcm_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_pcm_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_pcm_poll_descriptors_revents( - self.0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_pcm_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_pcm_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_pcm_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -436,12 +366,11 @@ impl poll::Descriptors for PCM { pub struct IO<'a, S: Copy>(&'a PCM, PhantomData); impl<'a, S: Copy> Drop for IO<'a, S> { - fn drop(&mut self) { - (self.0).1.set(false) - } + fn drop(&mut self) { (self.0).1.set(false) } } impl<'a, S: Copy> IO<'a, S> { + fn new(a: &'a PCM) -> IO<'a, S> { a.check_has_io(); a.1.set(true); @@ -466,23 +395,13 @@ impl<'a, S: Copy> IO<'a, S> { /// On success, returns number of *frames* written. /// (Multiply with number of channels to get number of items in buf successfully written.) pub fn writei(&self, buf: &[S]) -> Result { - acheck!(snd_pcm_writei( - (self.0).0, - buf.as_ptr() as *const c_void, - self.to_frames(buf.len()) - )) - .map(|r| r as usize) + acheck!(snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, self.to_frames(buf.len()))).map(|r| r as usize) } /// On success, returns number of *frames* read. /// (Multiply with number of channels to get number of items in buf successfully read.) pub fn readi(&self, buf: &mut [S]) -> Result { - acheck!(snd_pcm_readi( - (self.0).0, - buf.as_mut_ptr() as *mut c_void, - self.to_frames(buf.len()) - )) - .map(|r| r as usize) + acheck!(snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, self.to_frames(buf.len()))).map(|r| r as usize) } /// Write non-interleaved frames to pcm. On success, returns number of frames written. @@ -494,12 +413,7 @@ impl<'a, S: Copy> IO<'a, S> { /// of at least `frames` length. pub unsafe fn writen(&self, bufs: &[*const S], frames: usize) -> Result { let frames = frames as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_writen( - (self.0).0, - bufs.as_ptr() as *mut *mut c_void, - frames - )) - .map(|r| r as usize) + acheck!(snd_pcm_writen((self.0).0, bufs.as_ptr() as *mut *mut c_void, frames)).map(|r| r as usize) } /// Read non-interleaved frames to pcm. On success, returns number of frames read. @@ -511,12 +425,7 @@ impl<'a, S: Copy> IO<'a, S> { /// of at least `frames` length. pub unsafe fn readn(&self, bufs: &mut [*mut S], frames: usize) -> Result { let frames = frames as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_readn( - (self.0).0, - bufs.as_mut_ptr() as *mut *mut c_void, - frames - )) - .map(|r| r as usize) + acheck!(snd_pcm_readn((self.0).0, bufs.as_mut_ptr() as *mut *mut c_void, frames)).map(|r| r as usize) } /// Wrapper around snd_pcm_mmap_begin and snd_pcm_mmap_commit. @@ -533,12 +442,7 @@ impl<'a, S: Copy> IO<'a, S> { let mut f = frames as alsa::snd_pcm_uframes_t; let mut offs: alsa::snd_pcm_uframes_t = 0; let mut areas = ptr::null(); - acheck!(snd_pcm_mmap_begin( - (self.0).0, - &mut areas, - &mut offs, - &mut f - ))?; + acheck!(snd_pcm_mmap_begin((self.0).0, &mut areas, &mut offs, &mut f))?; let (first, step) = unsafe { ((*areas).first, (*areas).step) }; if first != 0 || step as isize != self.0.frames_to_bytes(1) * 8 { @@ -553,12 +457,7 @@ impl<'a, S: Copy> IO<'a, S> { }; let fres = func(buf); debug_assert!(fres <= f as usize); - acheck!(snd_pcm_mmap_commit( - (self.0).0, - offs, - fres as alsa::snd_pcm_uframes_t - )) - .map(|r| r as usize) + acheck!(snd_pcm_mmap_commit((self.0).0, offs, fres as alsa::snd_pcm_uframes_t)).map(|r| r as usize) } } @@ -566,11 +465,8 @@ impl<'a, S: Copy> io::Read for IO<'a, S> { fn read(&mut self, buf: &mut [u8]) -> io::Result { let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here? let r = unsafe { alsa::snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, size) }; - if r < 0 { - Err(io::Error::from_raw_os_error(r as i32)) - } else { - Ok(self.0.frames_to_bytes(r) as usize) - } + if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } + else { Ok(self.0.frames_to_bytes(r) as usize) } } } @@ -578,17 +474,13 @@ impl<'a, S: Copy> io::Write for IO<'a, S> { fn write(&mut self, buf: &[u8]) -> io::Result { let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here? let r = unsafe { alsa::snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, size) }; - if r < 0 { - Err(io::Error::from_raw_os_error(r as i32)) - } else { - Ok(self.0.frames_to_bytes(r) as usize) - } - } - fn flush(&mut self) -> io::Result<()> { - Ok(()) + if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } + else { Ok(self.0.frames_to_bytes(r) as usize) } } + fn flush(&mut self) -> io::Result<()> { Ok(()) } } + alsa_enum!( /// [SND_PCM_STATE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants State, ALL_STATES[9], @@ -607,8 +499,8 @@ alsa_enum!( alsa_enum!( #[non_exhaustive] /// [SND_PCM_FORMAT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants - Format, - ALL_FORMATS[52], + Format, ALL_FORMATS[52], + Unknown = SND_PCM_FORMAT_UNKNOWN, S8 = SND_PCM_FORMAT_S8, U8 = SND_PCM_FORMAT_U8, @@ -786,141 +678,51 @@ impl FromStr for Format { } impl Format { - pub const fn s16() -> Format { - ::FORMAT - } - pub const fn u16() -> Format { - ::FORMAT - } - pub const fn s32() -> Format { - ::FORMAT - } - pub const fn u32() -> Format { - ::FORMAT - } - pub const fn float() -> Format { - ::FORMAT - } - pub const fn float64() -> Format { - ::FORMAT - } + pub const fn s16() -> Format { ::FORMAT } + pub const fn u16() -> Format { ::FORMAT } + pub const fn s32() -> Format { ::FORMAT } + pub const fn u32() -> Format { ::FORMAT } + pub const fn float() -> Format { ::FORMAT } + pub const fn float64() -> Format { ::FORMAT } - #[cfg(target_endian = "little")] - pub const fn s24() -> Format { - Format::S24LE - } - #[cfg(target_endian = "big")] - pub const fn s24() -> Format { - Format::S24BE - } + #[cfg(target_endian = "little")] pub const fn s24() -> Format { Format::S24LE } + #[cfg(target_endian = "big")] pub const fn s24() -> Format { Format::S24BE } - #[cfg(target_endian = "little")] - pub const fn s24_3() -> Format { - Format::S243LE - } - #[cfg(target_endian = "big")] - pub const fn s24_3() -> Format { - Format::S243BE - } + #[cfg(target_endian = "little")] pub const fn s24_3() -> Format { Format::S243LE } + #[cfg(target_endian = "big")] pub const fn s24_3() -> Format { Format::S243BE } - #[cfg(target_endian = "little")] - pub const fn u24() -> Format { - Format::U24LE - } - #[cfg(target_endian = "big")] - pub const fn u24() -> Format { - Format::U24BE - } + #[cfg(target_endian = "little")] pub const fn u24() -> Format { Format::U24LE } + #[cfg(target_endian = "big")] pub const fn u24() -> Format { Format::U24BE } - #[cfg(target_endian = "little")] - pub const fn u24_3() -> Format { - Format::U243LE - } - #[cfg(target_endian = "big")] - pub const fn u24_3() -> Format { - Format::U243BE - } + #[cfg(target_endian = "little")] pub const fn u24_3() -> Format { Format::U243LE } + #[cfg(target_endian = "big")] pub const fn u24_3() -> Format { Format::U243BE } - #[cfg(target_endian = "little")] - pub const fn s20() -> Format { - Format::S20LE - } - #[cfg(target_endian = "big")] - pub const fn s20() -> Format { - Format::S20BE - } + #[cfg(target_endian = "little")] pub const fn s20() -> Format { Format::S20LE } + #[cfg(target_endian = "big")] pub const fn s20() -> Format { Format::S20BE } - #[cfg(target_endian = "little")] - pub const fn s20_3() -> Format { - Format::S203LE - } - #[cfg(target_endian = "big")] - pub const fn s20_3() -> Format { - Format::S203BE - } + #[cfg(target_endian = "little")] pub const fn s20_3() -> Format { Format::S203LE } + #[cfg(target_endian = "big")] pub const fn s20_3() -> Format { Format::S203BE } - #[cfg(target_endian = "little")] - pub const fn u20() -> Format { - Format::U20LE - } - #[cfg(target_endian = "big")] - pub const fn u20() -> Format { - Format::U20BE - } + #[cfg(target_endian = "little")] pub const fn u20() -> Format { Format::U20LE } + #[cfg(target_endian = "big")] pub const fn u20() -> Format { Format::U20BE } - #[cfg(target_endian = "little")] - pub const fn u20_3() -> Format { - Format::U203LE - } - #[cfg(target_endian = "big")] - pub const fn u20_3() -> Format { - Format::U203BE - } + #[cfg(target_endian = "little")] pub const fn u20_3() -> Format { Format::U203LE } + #[cfg(target_endian = "big")] pub const fn u20_3() -> Format { Format::U203BE } - #[cfg(target_endian = "little")] - pub const fn s18_3() -> Format { - Format::S183LE - } - #[cfg(target_endian = "big")] - pub const fn s18_3() -> Format { - Format::S183BE - } + #[cfg(target_endian = "little")] pub const fn s18_3() -> Format { Format::S183LE } + #[cfg(target_endian = "big")] pub const fn s18_3() -> Format { Format::S183BE } - #[cfg(target_endian = "little")] - pub const fn u18_3() -> Format { - Format::U183LE - } - #[cfg(target_endian = "big")] - pub const fn u18_3() -> Format { - Format::U183BE - } + #[cfg(target_endian = "little")] pub const fn u18_3() -> Format { Format::U183LE } + #[cfg(target_endian = "big")] pub const fn u18_3() -> Format { Format::U183BE } - #[cfg(target_endian = "little")] - pub const fn dsd_u16() -> Format { - Format::DSDU16LE - } - #[cfg(target_endian = "big")] - pub const fn dsd_u16() -> Format { - Format::DSDU16BE - } + #[cfg(target_endian = "little")] pub const fn dsd_u16() -> Format { Format::DSDU16LE } + #[cfg(target_endian = "big")] pub const fn dsd_u16() -> Format { Format::DSDU16BE } - #[cfg(target_endian = "little")] - pub const fn dsd_u32() -> Format { - Format::DSDU32LE - } - #[cfg(target_endian = "big")] - pub const fn dsd_u32() -> Format { - Format::DSDU32BE - } + #[cfg(target_endian = "little")] pub const fn dsd_u32() -> Format { Format::DSDU32LE } + #[cfg(target_endian = "big")] pub const fn dsd_u32() -> Format { Format::DSDU32BE } - #[cfg(target_endian = "little")] - pub const fn iec958_subframe() -> Format { - Format::IEC958SubframeLE - } - #[cfg(target_endian = "big")] - pub const fn iec958_subframe() -> Format { - Format::IEC958SubframeBE - } + #[cfg(target_endian = "little")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeLE } + #[cfg(target_endian = "big")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeBE } pub fn physical_width(&self) -> Result { acheck!(snd_pcm_format_physical_width(self.to_c_int())) @@ -939,16 +741,13 @@ impl Format { } } + pub trait IoFormat: Copy { const FORMAT: Format; } -impl IoFormat for i8 { - const FORMAT: Format = Format::S8; -} -impl IoFormat for u8 { - const FORMAT: Format = Format::U8; -} +impl IoFormat for i8 { const FORMAT: Format = Format::S8; } +impl IoFormat for u8 { const FORMAT: Format = Format::U8; } impl IoFormat for i16 { #[cfg(target_endian = "little")] @@ -987,6 +786,7 @@ impl IoFormat for f64 { const FORMAT: Format = Format::Float64BE; } + alsa_enum!( /// [SND_PCM_ACCESS_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants Access, ALL_ACCESSES[5], @@ -1011,9 +811,7 @@ alsa_enum!( pub struct HwParams<'a>(*mut alsa::snd_pcm_hw_params_t, &'a PCM); impl<'a> Drop for HwParams<'a> { - fn drop(&mut self) { - unsafe { alsa::snd_pcm_hw_params_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_pcm_hw_params_free(self.0) }; } } impl<'a> HwParams<'a> { @@ -1022,46 +820,26 @@ impl<'a> HwParams<'a> { acheck!(snd_pcm_hw_params_malloc(&mut p)).map(|_| HwParams(p, a)) } - pub fn any(a: &'a PCM) -> Result> { - HwParams::new(a).and_then(|p| acheck!(snd_pcm_hw_params_any(a.0, p.0)).map(|_| p)) - } + pub fn any(a: &'a PCM) -> Result> { HwParams::new(a).and_then(|p| + acheck!(snd_pcm_hw_params_any(a.0, p.0)).map(|_| p) + )} pub fn get_rate_resample(&self) -> Result { let mut v = 0; - acheck!(snd_pcm_hw_params_get_rate_resample( - (self.1).0, - self.0, - &mut v - )) - .map(|_| v != 0) + acheck!(snd_pcm_hw_params_get_rate_resample((self.1).0, self.0, &mut v)).map(|_| v != 0) } pub fn set_rate_resample(&self, resample: bool) -> Result<()> { - acheck!(snd_pcm_hw_params_set_rate_resample( - (self.1).0, - self.0, - if resample { 1 } else { 0 } - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_rate_resample((self.1).0, self.0, if resample {1} else {0})).map(|_| ()) } pub fn set_channels_near(&self, v: u32) -> Result { let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_channels_near( - (self.1).0, - self.0, - &mut r - )) - .map(|_| r) + acheck!(snd_pcm_hw_params_set_channels_near((self.1).0, self.0, &mut r)).map(|_| r) } pub fn set_channels(&self, v: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_set_channels( - (self.1).0, - self.0, - v as c_uint - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_channels((self.1).0, self.0, v as c_uint)).map(|_| ()) } pub fn get_channels(&self) -> Result { @@ -1080,38 +858,21 @@ impl<'a> HwParams<'a> { } pub fn test_channels(&self, v: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_test_channels( - (self.1).0, - self.0, - v as c_uint - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_test_channels((self.1).0, self.0, v as c_uint)).map(|_| ()) } pub fn set_rate_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_rate_near( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r) + acheck!(snd_pcm_hw_params_set_rate_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r) } pub fn set_rate(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_rate( - (self.1).0, - self.0, - v as c_uint, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_rate((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) } pub fn get_rate(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_rate(self.0, &mut v, &mut d)).map(|_| v as u32) } @@ -1121,34 +882,18 @@ impl<'a> HwParams<'a> { // -1 if the suprenum is not in the set (i.e. it's an open range), 0 otherwise. This could // be returned along with the value, but it's safe to pass a null ptr in, in which case the // pointer is not dereferenced. - acheck!(snd_pcm_hw_params_get_rate_max( - self.0, - &mut v, - ptr::null_mut() - )) - .map(|_| v as u32) + acheck!(snd_pcm_hw_params_get_rate_max(self.0, &mut v, ptr::null_mut())).map(|_| v as u32) } pub fn get_rate_min(&self) -> Result { let mut v = 0; // Note on the null ptr: see get_rate_max but read +1 and infinum instead of -1 and // suprenum. - acheck!(snd_pcm_hw_params_get_rate_min( - self.0, - &mut v, - ptr::null_mut() - )) - .map(|_| v as u32) + acheck!(snd_pcm_hw_params_get_rate_min(self.0, &mut v, ptr::null_mut())).map(|_| v as u32) } pub fn test_rate(&self, rate: u32) -> Result<()> { - acheck!(snd_pcm_hw_params_test_rate( - (self.1).0, - self.0, - rate as c_uint, - 0 - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_test_rate((self.1).0, self.0, rate as c_uint, 0)).map(|_| ()) } pub fn set_format(&self, v: Format) -> Result<()> { @@ -1162,30 +907,15 @@ impl<'a> HwParams<'a> { } pub fn test_format(&self, v: Format) -> Result<()> { - acheck!(snd_pcm_hw_params_test_format( - (self.1).0, - self.0, - v as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_test_format((self.1).0, self.0, v as c_int)).map(|_| ()) } pub fn test_access(&self, v: Access) -> Result<()> { - acheck!(snd_pcm_hw_params_test_access( - (self.1).0, - self.0, - v as c_uint - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_test_access((self.1).0, self.0, v as c_uint)).map(|_| ()) } pub fn set_access(&self, v: Access) -> Result<()> { - acheck!(snd_pcm_hw_params_set_access( - (self.1).0, - self.0, - v as c_uint - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_access((self.1).0, self.0, v as c_uint)).map(|_| ()) } pub fn get_access(&self) -> Result { @@ -1197,281 +927,153 @@ impl<'a> HwParams<'a> { pub fn set_period_size_near(&self, v: Frames, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_period_size_near( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_period_size_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames) } pub fn set_period_size(&self, v: Frames, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_period_size( - (self.1).0, - self.0, - v as alsa::snd_pcm_uframes_t, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_period_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t, dir as c_int)).map(|_| ()) } - pub fn set_period_size_min(&self, v: Frames, dir: ValueOr) -> Result { + pub fn set_period_time_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; - let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_period_size_min( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as Frames) + let mut r = v as c_uint; + acheck!(snd_pcm_hw_params_set_period_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } - pub fn set_period_size_max(&self, v: Frames, dir: ValueOr) -> Result { + pub fn set_period_size_min(&self, v: Frames, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_period_size_max( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_period_size_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames) } - pub fn set_period_time_near(&self, v: u32, dir: ValueOr) -> Result { + pub fn set_period_size_max(&self, v: Frames, dir: ValueOr) -> Result { let mut d = dir as c_int; - let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_period_time_near( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + let mut r = v as alsa::snd_pcm_uframes_t; + acheck!(snd_pcm_hw_params_set_period_size_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames) } pub fn set_period_time(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_period_time( - (self.1).0, - self.0, - v as c_uint, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_period_time((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) } pub fn set_period_time_min(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_period_time_min( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_period_time_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn set_period_time_max(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_period_time_max( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_period_time_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn get_period_time(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_period_time(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_period_time_min(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_period_time_min( - self.0, &mut v, &mut d - )) - .map(|_| v as u32) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_period_time_min(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_period_time_max(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_period_time_max( - self.0, &mut v, &mut d - )) - .map(|_| v as u32) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_period_time_max(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_period_size(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_period_size(self.0, &mut v, &mut d)).map(|_| v as Frames) } pub fn get_period_size_min(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_period_size_min( - self.0, &mut v, &mut d - )) - .map(|_| v as Frames) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_period_size_min(self.0, &mut v, &mut d)).map(|_| v as Frames) } pub fn get_period_size_max(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_period_size_max( - self.0, &mut v, &mut d - )) - .map(|_| v as Frames) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_period_size_max(self.0, &mut v, &mut d)).map(|_| v as Frames) } pub fn set_periods_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_periods_near( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_periods_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn set_periods(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_periods( - (self.1).0, - self.0, - v as c_uint, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_periods((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) } pub fn set_periods_min(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_periods_min( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_periods_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn set_periods_max(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_periods_max( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_periods_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn get_periods(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_periods(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_periods_min(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_periods_min(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_periods_max(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_periods_max(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn set_buffer_size_near(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_near( - (self.1).0, - self.0, - &mut r - )) - .map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_near((self.1).0, self.0, &mut r)).map(|_| r as Frames) } pub fn set_buffer_size_max(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_max( - (self.1).0, - self.0, - &mut r - )) - .map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_max((self.1).0, self.0, &mut r)).map(|_| r as Frames) } pub fn set_buffer_size_min(&self, v: Frames) -> Result { let mut r = v as alsa::snd_pcm_uframes_t; - acheck!(snd_pcm_hw_params_set_buffer_size_min( - (self.1).0, - self.0, - &mut r - )) - .map(|_| r as Frames) + acheck!(snd_pcm_hw_params_set_buffer_size_min((self.1).0, self.0, &mut r)).map(|_| r as Frames) } pub fn set_buffer_size(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_hw_params_set_buffer_size( - (self.1).0, - self.0, - v as alsa::snd_pcm_uframes_t - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_buffer_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) } pub fn set_buffer_time_near(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_buffer_time_near( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_buffer_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn set_buffer_time(&self, v: u32, dir: ValueOr) -> Result<()> { - acheck!(snd_pcm_hw_params_set_buffer_time( - (self.1).0, - self.0, - v as c_uint, - dir as c_int - )) - .map(|_| ()) + acheck!(snd_pcm_hw_params_set_buffer_time((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ()) } pub fn set_buffer_time_min(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_buffer_time_min( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_buffer_time_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn set_buffer_time_max(&self, v: u32, dir: ValueOr) -> Result { let mut d = dir as c_int; let mut r = v as c_uint; - acheck!(snd_pcm_hw_params_set_buffer_time_max( - (self.1).0, - self.0, - &mut r, - &mut d - )) - .map(|_| r as u32) + acheck!(snd_pcm_hw_params_set_buffer_time_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32) } pub fn get_buffer_size(&self) -> Result { @@ -1490,24 +1092,18 @@ impl<'a> HwParams<'a> { } pub fn get_buffer_time(&self) -> Result { - let (mut v, mut d) = (0, 0); + let (mut v, mut d) = (0,0); acheck!(snd_pcm_hw_params_get_buffer_time(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_buffer_time_min(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_buffer_time_min( - self.0, &mut v, &mut d - )) - .map(|_| v as u32) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_buffer_time_min(self.0, &mut v, &mut d)).map(|_| v as u32) } pub fn get_buffer_time_max(&self) -> Result { - let (mut v, mut d) = (0, 0); - acheck!(snd_pcm_hw_params_get_buffer_time_max( - self.0, &mut v, &mut d - )) - .map(|_| v as u32) + let (mut v, mut d) = (0,0); + acheck!(snd_pcm_hw_params_get_buffer_time_max(self.0, &mut v, &mut d)).map(|_| v as u32) } /// Returns true if the alsa stream can be paused, false if not. @@ -1562,14 +1158,8 @@ impl<'a> fmt::Debug for HwParams<'a> { .field("rate", &format!("{:?} Hz", self.get_rate())) .field("format", &self.get_format()) .field("access", &self.get_access()) - .field( - "period_size", - &format!("{:?} frames", self.get_period_size()), - ) - .field( - "buffer_size", - &format!("{:?} frames", self.get_buffer_size()), - ) + .field("period_size", &format!("{:?} frames", self.get_period_size())) + .field("buffer_size", &format!("{:?} frames", self.get_buffer_size())) .finish() } } @@ -1578,24 +1168,18 @@ impl<'a> fmt::Debug for HwParams<'a> { pub struct SwParams<'a>(*mut alsa::snd_pcm_sw_params_t, &'a PCM); impl<'a> Drop for SwParams<'a> { - fn drop(&mut self) { - unsafe { alsa::snd_pcm_sw_params_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_pcm_sw_params_free(self.0) }; } } impl<'a> SwParams<'a> { + fn new(a: &'a PCM) -> Result> { let mut p = ptr::null_mut(); acheck!(snd_pcm_sw_params_malloc(&mut p)).map(|_| SwParams(p, a)) } pub fn set_avail_min(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_avail_min( - (self.1).0, - self.0, - v as alsa::snd_pcm_uframes_t - )) - .map(|_| ()) + acheck!(snd_pcm_sw_params_set_avail_min((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) } pub fn get_avail_min(&self) -> Result { @@ -1609,12 +1193,7 @@ impl<'a> SwParams<'a> { } pub fn set_start_threshold(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_start_threshold( - (self.1).0, - self.0, - v as alsa::snd_pcm_uframes_t - )) - .map(|_| ()) + acheck!(snd_pcm_sw_params_set_start_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) } pub fn get_start_threshold(&self) -> Result { @@ -1623,12 +1202,7 @@ impl<'a> SwParams<'a> { } pub fn set_stop_threshold(&self, v: Frames) -> Result<()> { - acheck!(snd_pcm_sw_params_set_stop_threshold( - (self.1).0, - self.0, - v as alsa::snd_pcm_uframes_t - )) - .map(|_| ()) + acheck!(snd_pcm_sw_params_set_stop_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ()) } pub fn get_stop_threshold(&self) -> Result { @@ -1637,11 +1211,7 @@ impl<'a> SwParams<'a> { } pub fn set_tstamp_mode(&self, v: bool) -> Result<()> { - let z = if v { - alsa::SND_PCM_TSTAMP_ENABLE - } else { - alsa::SND_PCM_TSTAMP_NONE - }; + let z = if v { alsa::SND_PCM_TSTAMP_ENABLE } else { alsa::SND_PCM_TSTAMP_NONE }; acheck!(snd_pcm_sw_params_set_tstamp_mode((self.1).0, self.0, z)).map(|_| ()) } @@ -1651,12 +1221,7 @@ impl<'a> SwParams<'a> { } pub fn set_tstamp_type(&self, v: TstampType) -> Result<()> { - acheck!(snd_pcm_sw_params_set_tstamp_type( - (self.1).0, - self.0, - v as u32 - )) - .map(|_| ()) + acheck!(snd_pcm_sw_params_set_tstamp_type((self.1).0, self.0, v as u32)).map(|_| ()) } pub fn get_tstamp_type(&self) -> Result { @@ -1682,65 +1247,41 @@ const STATUS_SIZE: usize = 152; /// [snd_pcm_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___status.html) wrapper #[derive(Debug)] -pub struct Status([u64; (STATUS_SIZE + 7) / 8]); +pub struct Status([u64; (STATUS_SIZE+7)/8]); impl Status { fn new() -> Status { assert!(unsafe { alsa::snd_pcm_status_sizeof() } as usize <= STATUS_SIZE); - Status([0; (STATUS_SIZE + 7) / 8]) + Status([0; (STATUS_SIZE+7)/8]) } - fn ptr(&self) -> *mut alsa::snd_pcm_status_t { - self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t - } + fn ptr(&self) -> *mut alsa::snd_pcm_status_t { self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t } pub fn get_htstamp(&self) -> timespec { - let mut h = timespec { - tv_sec: 0, - tv_nsec: 0, - }; + let mut h = timespec {tv_sec: 0, tv_nsec: 0}; unsafe { alsa::snd_pcm_status_get_htstamp(self.ptr(), &mut h) }; h } pub fn get_trigger_htstamp(&self) -> timespec { - let mut h = timespec { - tv_sec: 0, - tv_nsec: 0, - }; + let mut h = timespec {tv_sec: 0, tv_nsec: 0}; unsafe { alsa::snd_pcm_status_get_trigger_htstamp(self.ptr(), &mut h) }; h } pub fn get_audio_htstamp(&self) -> timespec { - let mut h = timespec { - tv_sec: 0, - tv_nsec: 0, - }; + let mut h = timespec {tv_sec: 0, tv_nsec: 0}; unsafe { alsa::snd_pcm_status_get_audio_htstamp(self.ptr(), &mut h) }; h } - pub fn get_state(&self) -> State { - State::from_c_int( - unsafe { alsa::snd_pcm_status_get_state(self.ptr()) } as c_int, - "snd_pcm_status_get_state", - ) - .unwrap() - } + pub fn get_state(&self) -> State { State::from_c_int( + unsafe { alsa::snd_pcm_status_get_state(self.ptr()) } as c_int, "snd_pcm_status_get_state").unwrap() } - pub fn get_avail(&self) -> Frames { - unsafe { alsa::snd_pcm_status_get_avail(self.ptr()) as Frames } - } - pub fn get_delay(&self) -> Frames { - unsafe { alsa::snd_pcm_status_get_delay(self.ptr()) } - } - pub fn get_avail_max(&self) -> Frames { - unsafe { alsa::snd_pcm_status_get_avail_max(self.ptr()) as Frames } - } - pub fn get_overrange(&self) -> Frames { - unsafe { alsa::snd_pcm_status_get_overrange(self.ptr()) as Frames } - } + pub fn get_avail(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail(self.ptr()) as Frames }} + pub fn get_delay(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_delay(self.ptr()) }} + pub fn get_avail_max(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail_max(self.ptr()) as Frames }} + pub fn get_overrange(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_overrange(self.ptr()) as Frames }} pub fn dump(&self, o: &mut Output) -> Result<()> { acheck!(snd_pcm_status_dump(self.ptr(), super::io::output_handle(o))).map(|_| ()) @@ -1758,7 +1299,11 @@ impl StatusBuilder { StatusBuilder(Status::new()) } - pub fn audio_htstamp_config(self, type_requested: AudioTstampType, report_delay: bool) -> Self { + pub fn audio_htstamp_config( + self, + type_requested: AudioTstampType, + report_delay: bool, + ) -> Self { let mut cfg: alsa::snd_pcm_audio_tstamp_config_t = unsafe { std::mem::zeroed() }; cfg.set_type_requested(type_requested as _); cfg.set_report_delay(report_delay as _); @@ -1767,7 +1312,7 @@ impl StatusBuilder { } pub fn build(mut self, pcm: &PCM) -> Result { - let p = self.0 .0.as_mut_ptr() as *mut alsa::snd_pcm_status_t; + let p = self.0.0.as_mut_ptr() as *mut alsa::snd_pcm_status_t; acheck!(snd_pcm_status(pcm.0, p)).map(|_| self.0) } } @@ -1775,8 +1320,8 @@ impl StatusBuilder { alsa_enum!( #[non_exhaustive] /// [SND_PCM_AUDIO_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants - AudioTstampType, - ALL_AUDIO_TSTAMP_TYPES[6], + AudioTstampType, ALL_AUDIO_TSTAMP_TYPES[6], + Compat = SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT, Default = SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT, Link = SND_PCM_AUDIO_TSTAMP_TYPE_LINK, @@ -1788,12 +1333,7 @@ alsa_enum!( #[test] fn info_from_default() { use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("default").unwrap(), - Direction::Capture, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); let info = pcm.info().unwrap(); println!("PCM Info:"); println!("\tCard: {}", info.get_card()); @@ -1807,12 +1347,7 @@ fn info_from_default() { #[test] fn drop() { use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("default").unwrap(), - Direction::Capture, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); // Verify that this does not cause a naming conflict (issue #14) let _ = pcm.drop(); } @@ -1820,12 +1355,7 @@ fn drop() { #[test] fn record_from_default() { use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("default").unwrap(), - Direction::Capture, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Capture, false).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(2).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -1834,7 +1364,7 @@ fn record_from_default() { pcm.hw_params(&hwp).unwrap(); pcm.start().unwrap(); let mut buf = [0i16; 1024]; - assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 1024 / 2); + assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 1024/2); } #[test] @@ -1853,12 +1383,7 @@ fn open_s24() { #[test] fn playback_to_default() { use std::ffi::CString; - let pcm = PCM::open( - &*CString::new("default").unwrap(), - Direction::Playback, - false, - ) - .unwrap(); + let pcm = PCM::open(&*CString::new("default").unwrap(), Direction::Playback, false).unwrap(); let hwp = HwParams::any(&pcm).unwrap(); hwp.set_channels(1).unwrap(); hwp.set_rate(44100, ValueOr::Nearest).unwrap(); @@ -1868,15 +1393,10 @@ fn playback_to_default() { let hwp = pcm.hw_params_current().unwrap(); let swp = pcm.sw_params_current().unwrap(); - swp.set_start_threshold(hwp.get_buffer_size().unwrap()) - .unwrap(); + swp.set_start_threshold(hwp.get_buffer_size().unwrap()).unwrap(); pcm.sw_params(&swp).unwrap(); - println!( - "PCM status: {:?}, {:?}", - pcm.state(), - pcm.hw_params_current().unwrap() - ); + println!("PCM status: {:?}, {:?}", pcm.state(), pcm.hw_params_current().unwrap()); let mut outp = Output::buffer_open().unwrap(); pcm.dump(&mut outp).unwrap(); println!("== PCM dump ==\n{}", outp); @@ -1886,14 +1406,11 @@ fn playback_to_default() { *a = ((i as f32 * 2.0 * ::std::f32::consts::PI / 128.0).sin() * 8192.0) as i16 } let io = pcm.io_i16().unwrap(); - for _ in 0..2 * 44100 / 1024 { - // 2 seconds of playback + for _ in 0..2*44100/1024 { // 2 seconds of playback println!("PCM state: {:?}", pcm.state()); assert_eq!(io.writei(&buf[..]).unwrap(), 1024); } - if pcm.state() != State::Running { - pcm.start().unwrap() - }; + if pcm.state() != State::Running { pcm.start().unwrap() }; let mut outp2 = Output::buffer_open().unwrap(); pcm.status().unwrap().dump(&mut outp2).unwrap(); diff --git a/src/poll.rs b/src/poll.rs index 361e726..01becf5 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -2,10 +2,11 @@ //! //! A tiny wrapper around libc's poll system call. -use super::error::*; use libc; -pub use libc::pollfd; +use super::error::*; use std::io; +pub use libc::pollfd; + bitflags! { #[repr(transparent)] @@ -27,75 +28,43 @@ pub trait Descriptors { /// Wrapper around count and fill - returns an array of pollfds fn get(&self) -> Result> { - let mut v = vec![ - pollfd { - fd: 0, - events: 0, - revents: 0 - }; - self.count() - ]; - if self.fill(&mut v)? != v.len() { - Err(Error::unsupported( - "did not fill the poll descriptors array", - )) - } else { - Ok(v) - } + let mut v = vec![pollfd { fd: 0, events: 0, revents: 0 }; self.count()]; + if self.fill(&mut v)? != v.len() { Err(Error::unsupported("did not fill the poll descriptors array")) } + else { Ok(v) } } } impl Descriptors for pollfd { - fn count(&self) -> usize { - 1 - } - fn fill(&self, a: &mut [pollfd]) -> Result { - a[0] = *self; - Ok(1) - } - fn revents(&self, a: &[pollfd]) -> Result { - Ok(Flags::from_bits_truncate(a[0].revents)) - } + fn count(&self) -> usize { 1 } + fn fill(&self, a: &mut [pollfd]) -> Result { a[0] = *self; Ok(1) } + fn revents(&self, a: &[pollfd]) -> Result { Ok(Flags::from_bits_truncate(a[0].revents)) } } /// Wrapper around the libc poll call. -pub fn poll(fds: &mut [pollfd], timeout: i32) -> Result { - let r = unsafe { - libc::poll( - fds.as_mut_ptr(), - fds.len() as libc::nfds_t, - timeout as libc::c_int, - ) - }; - if r >= 0 { - Ok(r as usize) - } else { - from_code("poll", -io::Error::last_os_error().raw_os_error().unwrap()) - .map(|_| unreachable!()) +pub fn poll(fds: &mut[pollfd], timeout: i32) -> Result { + let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::nfds_t, timeout as libc::c_int) }; + if r >= 0 { Ok(r as usize) } else { + from_code("poll", -io::Error::last_os_error().raw_os_error().unwrap()).map(|_| unreachable!()) } } /// Builds a pollfd array, polls it, and returns the poll descriptors which have non-zero revents. -pub fn poll_all<'a>( - desc: &[&'a dyn Descriptors], - timeout: i32, -) -> Result> { - let mut pollfds: Vec = vec![]; - let mut indices = vec![]; +pub fn poll_all<'a>(desc: &[&'a dyn Descriptors], timeout: i32) -> Result> { + + let mut pollfds: Vec = vec!(); + let mut indices = vec!(); for v2 in desc.iter().map(|q| q.get()) { let v = v2?; - indices.push(pollfds.len()..pollfds.len() + v.len()); + indices.push(pollfds.len() .. pollfds.len()+v.len()); pollfds.extend(v); - } + }; poll(&mut pollfds, timeout)?; - let mut res = vec![]; + let mut res = vec!(); for (i, r) in indices.into_iter().enumerate() { let z = desc[i].revents(&pollfds[r])?; - if !z.is_empty() { - res.push((desc[i], z)); - } + if !z.is_empty() { res.push((desc[i], z)); } } Ok(res) } diff --git a/src/rawmidi.rs b/src/rawmidi.rs index 9e8461f..50ef9cc 100644 --- a/src/rawmidi.rs +++ b/src/rawmidi.rs @@ -1,12 +1,12 @@ //! MIDI devices I/O and enumeration +use libc::{c_int, c_uint, c_void, size_t, c_short, pollfd}; use super::ctl_int::{ctl_ptr, Ctl}; +use super::{Direction, poll}; use super::error::*; -use super::{poll, Direction}; use crate::alsa; -use libc::{c_int, c_short, c_uint, c_void, pollfd, size_t}; +use std::{ptr, io}; use std::ffi::{CStr, CString}; -use std::{io, ptr}; /// Iterator over [Rawmidi](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) devices and subdevices pub struct Iter<'a> { @@ -21,9 +21,7 @@ pub struct Iter<'a> { pub struct Info(*mut alsa::snd_rawmidi_info_t); impl Drop for Info { - fn drop(&mut self) { - unsafe { alsa::snd_rawmidi_info_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_rawmidi_info_free(self.0) }; } } impl Info { @@ -47,24 +45,15 @@ impl Info { fn subdev_count(c: &Ctl, device: c_int) -> Result<(i32, i32)> { let i = Info::from_iter(c, device, 0, Direction::Capture)?; let o = Info::from_iter(c, device, 0, Direction::Playback)?; - Ok(( - unsafe { alsa::snd_rawmidi_info_get_subdevices_count(o.0) as i32 }, - unsafe { alsa::snd_rawmidi_info_get_subdevices_count(i.0) as i32 }, - )) + Ok((unsafe { alsa::snd_rawmidi_info_get_subdevices_count(o.0) as i32 }, + unsafe { alsa::snd_rawmidi_info_get_subdevices_count(i.0) as i32 })) } - pub fn get_device(&self) -> i32 { - unsafe { alsa::snd_rawmidi_info_get_device(self.0) as i32 } - } - pub fn get_subdevice(&self) -> i32 { - unsafe { alsa::snd_rawmidi_info_get_subdevice(self.0) as i32 } - } + pub fn get_device(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_device(self.0) as i32 }} + pub fn get_subdevice(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_subdevice(self.0) as i32 }} pub fn get_stream(&self) -> super::Direction { - if unsafe { alsa::snd_rawmidi_info_get_stream(self.0) } == alsa::SND_RAWMIDI_STREAM_OUTPUT { - super::Direction::Playback - } else { - super::Direction::Capture - } + if unsafe { alsa::snd_rawmidi_info_get_stream(self.0) } == alsa::SND_RAWMIDI_STREAM_OUTPUT { super::Direction::Playback } + else { super::Direction::Capture } } pub fn get_subdevice_name(&self) -> Result { @@ -88,30 +77,17 @@ impl Status { } impl Status { - pub fn get_avail(&self) -> usize { - unsafe { alsa::snd_rawmidi_status_get_avail(self.0 as *const _) } - } - pub fn get_xruns(&self) -> usize { - unsafe { alsa::snd_rawmidi_status_get_xruns(self.0 as *const _) } - } + pub fn get_avail(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_avail(self.0 as *const _) } } + pub fn get_xruns(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_xruns(self.0 as *const _) } } } impl Drop for Status { - fn drop(&mut self) { - unsafe { alsa::snd_rawmidi_status_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_rawmidi_status_free(self.0) }; } } + impl<'a> Iter<'a> { - pub fn new(c: &'a Ctl) -> Iter<'a> { - Iter { - ctl: c, - device: -1, - in_count: 0, - out_count: 0, - current: 0, - } - } + pub fn new(c: &'a Ctl) -> Iter<'a> { Iter { ctl: c, device: -1, in_count: 0, out_count: 0, current: 0 }} } impl<'a> Iterator for Iter<'a> { @@ -119,31 +95,18 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option> { if self.current < self.in_count { self.current += 1; - return Some(Info::from_iter( - self.ctl, - self.device, - self.current - 1, - Direction::Capture, - )); + return Some(Info::from_iter(self.ctl, self.device, self.current-1, Direction::Capture)); } if self.current - self.in_count < self.out_count { self.current += 1; - return Some(Info::from_iter( - self.ctl, - self.device, - self.current - 1 - self.in_count, - Direction::Playback, - )); + return Some(Info::from_iter(self.ctl, self.device, self.current-1-self.in_count, Direction::Playback)); } - let r = acheck!(snd_ctl_rawmidi_next_device( - ctl_ptr(self.ctl), - &mut self.device - )); + let r = acheck!(snd_ctl_rawmidi_next_device(ctl_ptr(self.ctl), &mut self.device)); match r { Err(e) => return Some(Err(e)), Ok(_) if self.device == -1 => return None, - _ => {} + _ => {}, } self.current = 0; match Info::subdev_count(self.ctl, self.device) { @@ -163,12 +126,11 @@ pub struct Rawmidi(*mut alsa::snd_rawmidi_t); unsafe impl Send for Rawmidi {} impl Drop for Rawmidi { - fn drop(&mut self) { - unsafe { alsa::snd_rawmidi_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_rawmidi_close(self.0) }; } } impl Rawmidi { + /// Wrapper around open that takes a &str instead of a &CStr pub fn new(name: &str, dir: Direction, nonblock: bool) -> Result { Self::open(&CString::new(name).unwrap(), dir, nonblock) @@ -178,20 +140,10 @@ impl Rawmidi { let mut h = ptr::null_mut(); let flags = if nonblock { 2 } else { 0 }; // FIXME: alsa::SND_RAWMIDI_NONBLOCK does not exist in alsa-sys acheck!(snd_rawmidi_open( - if dir == Direction::Capture { - &mut h - } else { - ptr::null_mut() - }, - if dir == Direction::Playback { - &mut h - } else { - ptr::null_mut() - }, - name.as_ptr(), - flags - )) - .map(|_| Rawmidi(h)) + if dir == Direction::Capture { &mut h } else { ptr::null_mut() }, + if dir == Direction::Playback { &mut h } else { ptr::null_mut() }, + name.as_ptr(), flags)) + .map(|_| Rawmidi(h)) } pub fn info(&self) -> Result { @@ -202,20 +154,14 @@ impl Rawmidi { Status::new().and_then(|i| acheck!(snd_rawmidi_status(self.0, i.0)).map(|_| i)) } - pub fn drop(&self) -> Result<()> { - acheck!(snd_rawmidi_drop(self.0)).map(|_| ()) - } - pub fn drain(&self) -> Result<()> { - acheck!(snd_rawmidi_drain(self.0)).map(|_| ()) - } + pub fn drop(&self) -> Result<()> { acheck!(snd_rawmidi_drop(self.0)).map(|_| ()) } + pub fn drain(&self) -> Result<()> { acheck!(snd_rawmidi_drain(self.0)).map(|_| ()) } pub fn name(&self) -> Result { let c = unsafe { alsa::snd_rawmidi_name(self.0) }; from_const("snd_rawmidi_name", c).map(|s| s.to_string()) } - pub fn io(&self) -> IO { - IO(self) - } + pub fn io(&self) -> IO { IO(self) } } impl poll::Descriptors for Rawmidi { @@ -223,23 +169,13 @@ impl poll::Descriptors for Rawmidi { unsafe { alsa::snd_rawmidi_poll_descriptors_count(self.0) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { - alsa::snd_rawmidi_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) - }; + let z = unsafe { alsa::snd_rawmidi_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) }; from_code("snd_rawmidi_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_rawmidi_poll_descriptors_revents( - self.0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_rawmidi_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_rawmidi_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_rawmidi_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -248,54 +184,28 @@ pub struct IO<'a>(&'a Rawmidi); impl<'a> io::Read for IO<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let r = unsafe { - alsa::snd_rawmidi_read( - (self.0).0, - buf.as_mut_ptr() as *mut c_void, - buf.len() as size_t, - ) - }; - if r < 0 { - Err(io::Error::from_raw_os_error(r as i32)) - } else { - Ok(r as usize) - } + let r = unsafe { alsa::snd_rawmidi_read((self.0).0, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) }; + if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } + else { Ok(r as usize) } } } impl<'a> io::Write for IO<'a> { fn write(&mut self, buf: &[u8]) -> io::Result { - let r = unsafe { - alsa::snd_rawmidi_write( - (self.0).0, - buf.as_ptr() as *const c_void, - buf.len() as size_t, - ) - }; - if r < 0 { - Err(io::Error::from_raw_os_error(r as i32)) - } else { - Ok(r as usize) - } - } - fn flush(&mut self) -> io::Result<()> { - Ok(()) + let r = unsafe { alsa::snd_rawmidi_write((self.0).0, buf.as_ptr() as *const c_void, buf.len() as size_t) }; + if r < 0 { Err(io::Error::from_raw_os_error(r as i32)) } + else { Ok(r as usize) } } + fn flush(&mut self) -> io::Result<()> { Ok(()) } } + #[test] fn print_rawmidis() { for a in super::card::Iter::new().map(|a| a.unwrap()) { for b in Iter::new(&Ctl::from_card(&a, false).unwrap()).map(|b| b.unwrap()) { - println!( - "Rawmidi {:?} (hw:{},{},{}) {} - {}", - b.get_stream(), - a.get_index(), - b.get_device(), - b.get_subdevice(), - a.get_name().unwrap(), - b.get_subdevice_name().unwrap() - ) + println!("Rawmidi {:?} (hw:{},{},{}) {} - {}", b.get_stream(), a.get_index(), b.get_device(), b.get_subdevice(), + a.get_name().unwrap(), b.get_subdevice_name().unwrap()) } } } diff --git a/src/seq.rs b/src/seq.rs index 1069c1c..cc4f3fb 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -1,13 +1,13 @@ //! MIDI sequencer I/O and enumeration +use libc::{c_uint, c_int, c_short, c_uchar, c_void, c_long, size_t, pollfd}; use super::error::*; -use super::{poll, Direction}; use crate::alsa; -use libc::{c_int, c_long, c_short, c_uchar, c_uint, c_void, pollfd, size_t}; -use std::borrow::Cow; -use std::ffi::CStr; +use super::{Direction, poll}; +use std::{ptr, fmt, mem, slice, time, cell}; use std::str::{FromStr, Split}; -use std::{cell, fmt, mem, ptr, slice, time}; +use std::ffi::CStr; +use std::borrow::Cow; // Workaround for improper alignment of snd_seq_ev_ext_t in alsa-sys #[repr(packed)] @@ -26,16 +26,12 @@ pub struct Seq(*mut alsa::snd_seq_t, cell::Cell); unsafe impl Send for Seq {} impl Drop for Seq { - fn drop(&mut self) { - unsafe { alsa::snd_seq_close(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_seq_close(self.0) }; } } impl Seq { fn check_has_input(&self) { - if self.1.get() { - panic!("No additional Input object allowed") - } + if self.1.get() { panic!("No additional Input object allowed")} } /// Opens the sequencer. @@ -89,13 +85,7 @@ impl Seq { pub fn get_any_port_info(&self, a: Addr) -> Result { let c = PortInfo::new()?; - acheck!(snd_seq_get_any_port_info( - self.0, - a.client as c_int, - a.port as c_int, - c.0 - )) - .map(|_| c) + acheck!(snd_seq_get_any_port_info(self.0, a.client as c_int, a.port as c_int, c.0)).map(|_| c) } pub fn create_port(&self, port: &PortInfo) -> Result<()> { @@ -103,13 +93,7 @@ impl Seq { } pub fn create_simple_port(&self, name: &CStr, caps: PortCap, t: PortType) -> Result { - acheck!(snd_seq_create_simple_port( - self.0, - name.as_ptr(), - caps.bits() as c_uint, - t.bits() as c_uint - )) - .map(|q| q as i32) + acheck!(snd_seq_create_simple_port(self.0, name.as_ptr(), caps.bits() as c_uint, t.bits() as c_uint)).map(|q| q as i32) } pub fn set_port_info(&self, port: i32, info: &mut PortInfo) -> Result<()> { @@ -131,27 +115,10 @@ impl Seq { acheck!(snd_seq_unsubscribe_port(self.0, z.0)).map(|_| ()) } - pub fn control_queue( - &self, - q: i32, - t: EventType, - value: i32, - e: Option<&mut Event>, - ) -> Result<()> { - assert!( - EvQueueControl::<()>::has_data(t) - || EvQueueControl::::has_data(t) - || EvQueueControl::::has_data(t) - ); + pub fn control_queue(&self, q: i32, t: EventType, value: i32, e: Option<&mut Event>) -> Result<()> { + assert!(EvQueueControl::<()>::has_data(t) || EvQueueControl::::has_data(t) || EvQueueControl::::has_data(t)); let p = e.map(|e| &mut e.0 as *mut _).unwrap_or(ptr::null_mut()); - acheck!(snd_seq_control_queue( - self.0, - q as c_int, - t as c_int, - value as c_int, - p - )) - .map(|_| ()) + acheck!(snd_seq_control_queue(self.0, q as c_int, t as c_int, value as c_int, p)).map(|_| ()) } pub fn event_output(&self, e: &mut Event) -> Result { @@ -183,12 +150,8 @@ impl Seq { acheck!(snd_seq_get_queue_status(self.0, q as c_int, value.0)).map(|_| value) } - pub fn free_queue(&self, q: i32) -> Result<()> { - acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) - } - pub fn alloc_queue(&self) -> Result { - acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) - } + pub fn free_queue(&self, q: i32) -> Result<()> { acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) } + pub fn alloc_queue(&self) -> Result { acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) } pub fn alloc_named_queue(&self, n: &CStr) -> Result { acheck!(snd_seq_alloc_named_queue(self.0, n.as_ptr())).map(|q| q as i32) } @@ -222,9 +185,7 @@ impl Seq { pub struct Input<'a>(&'a Seq); impl<'a> Drop for Input<'a> { - fn drop(&mut self) { - (self.0).1.set(false) - } + fn drop(&mut self) { (self.0).1.set(false) } } impl<'a> Input<'a> { @@ -241,18 +202,14 @@ impl<'a> Input<'a> { // event is alive. let mut z = ptr::null_mut(); acheck!(snd_seq_event_input((self.0).0, &mut z))?; - unsafe { Event::extract(&mut *z, "snd_seq_event_input") } + unsafe { Event::extract (&mut *z, "snd_seq_event_input") } } pub fn event_input_pending(&self, fetch_sequencer: bool) -> Result { - acheck!(snd_seq_event_input_pending( - (self.0).0, - if fetch_sequencer { 1 } else { 0 } - )) - .map(|q| q as u32) + acheck!(snd_seq_event_input_pending((self.0).0, if fetch_sequencer {1} else {0})).map(|q| q as u32) } - pub fn set_input_buffer_size(&self, size: u32) -> Result<()> { + pub fn set_input_buffer_size(&self, size: u32) -> Result<()> { acheck!(snd_seq_set_input_buffer_size((self.0).0, size as size_t)).map(|_| ()) } @@ -266,39 +223,24 @@ fn polldir(o: Option) -> c_short { None => poll::Flags::IN | poll::Flags::OUT, Some(Direction::Playback) => poll::Flags::OUT, Some(Direction::Capture) => poll::Flags::IN, - } - .bits() + }.bits() } impl<'a> poll::Descriptors for (&'a Seq, Option) { + fn count(&self) -> usize { unsafe { alsa::snd_seq_poll_descriptors_count((self.0).0, polldir(self.1)) as usize } } fn fill(&self, p: &mut [pollfd]) -> Result { - let z = unsafe { - alsa::snd_seq_poll_descriptors( - (self.0).0, - p.as_mut_ptr(), - p.len() as c_uint, - polldir(self.1), - ) - }; + let z = unsafe { alsa::snd_seq_poll_descriptors((self.0).0, p.as_mut_ptr(), p.len() as c_uint, polldir(self.1)) }; from_code("snd_seq_poll_descriptors", z).map(|_| z as usize) } fn revents(&self, p: &[pollfd]) -> Result { let mut r = 0; - let z = unsafe { - alsa::snd_seq_poll_descriptors_revents( - (self.0).0, - p.as_ptr() as *mut pollfd, - p.len() as c_uint, - &mut r, - ) - }; - from_code("snd_seq_poll_descriptors_revents", z) - .map(|_| poll::Flags::from_bits_truncate(r as c_short)) + let z = unsafe { alsa::snd_seq_poll_descriptors_revents((self.0).0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) }; + from_code("snd_seq_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short)) } } @@ -345,9 +287,7 @@ impl fmt::Debug for ClientInfo { pub struct ClientIter<'a>(&'a Seq, i32); impl<'a> ClientIter<'a> { - pub fn new(seq: &'a Seq) -> Self { - ClientIter(seq, -1) - } + pub fn new(seq: &'a Seq) -> Self { ClientIter(seq, -1) } } impl<'a> Iterator for ClientIter<'a> { @@ -356,10 +296,7 @@ impl<'a> Iterator for ClientIter<'a> { let z = ClientInfo::new().unwrap(); z.set_client(self.1); let r = unsafe { alsa::snd_seq_query_next_client((self.0).0, z.0) }; - if r < 0 { - self.1 = -1; - return None; - }; + if r < 0 { self.1 = -1; return None }; self.1 = z.get_client(); Some(z) } @@ -418,9 +355,7 @@ impl PortInfo { } pub fn get_capability(&self) -> PortCap { - PortCap::from_bits_truncate(unsafe { - alsa::snd_seq_port_info_get_capability(self.0) as u32 - }) + PortCap::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_capability(self.0) as u32 }) } pub fn get_type(&self) -> PortType { @@ -443,66 +378,28 @@ impl PortInfo { } } - pub fn get_midi_channels(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } - } - pub fn get_midi_voices(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } - } - pub fn get_synth_voices(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } - } - pub fn get_read_use(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } - } - pub fn get_write_use(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } - } - pub fn get_port_specified(&self) -> bool { - unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } - } - pub fn get_timestamping(&self) -> bool { - unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } - } - pub fn get_timestamp_real(&self) -> bool { - unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } - } - pub fn get_timestamp_queue(&self) -> i32 { - unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } - } + pub fn get_midi_channels(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } } + pub fn get_midi_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } } + pub fn get_synth_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } } + pub fn get_read_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } } + pub fn get_write_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } } + pub fn get_port_specified(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } } + pub fn get_timestamping(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } } + pub fn get_timestamp_real(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } } + pub fn get_timestamp_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } } - pub fn set_midi_channels(&self, value: i32) { - unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } - } - pub fn set_midi_voices(&self, value: i32) { - unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } - } - pub fn set_synth_voices(&self, value: i32) { - unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } - } - pub fn set_port_specified(&self, value: bool) { - unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 }) } - } - pub fn set_timestamping(&self, value: bool) { - unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 }) } - } - pub fn set_timestamp_real(&self, value: bool) { - unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 }) } - } - pub fn set_timestamp_queue(&self, value: i32) { - unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } - } + pub fn set_midi_channels(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } } + pub fn set_midi_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } } + pub fn set_synth_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } } + pub fn set_port_specified(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 } ) } } + pub fn set_timestamping(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 } ) } } + pub fn set_timestamp_real(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 } ) } } + pub fn set_timestamp_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } } } impl fmt::Debug for PortInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "PortInfo({}:{},{:?})", - self.get_client(), - self.get_port(), - self.get_name() - ) + write!(f, "PortInfo({}:{},{:?})", self.get_client(), self.get_port(), self.get_name()) } } @@ -511,9 +408,7 @@ impl fmt::Debug for PortInfo { pub struct PortIter<'a>(&'a Seq, i32, i32); impl<'a> PortIter<'a> { - pub fn new(seq: &'a Seq, client: i32) -> Self { - PortIter(seq, client, -1) - } + pub fn new(seq: &'a Seq, client: i32) -> Self { PortIter(seq, client, -1) } } impl<'a> Iterator for PortIter<'a> { @@ -523,10 +418,7 @@ impl<'a> Iterator for PortIter<'a> { z.set_client(self.1); z.set_port(self.2); let r = unsafe { alsa::snd_seq_query_next_port((self.0).0, z.0) }; - if r < 0 { - self.2 = -1; - return None; - }; + if r < 0 { self.2 = -1; return None }; self.2 = z.get_port(); Some(z) } @@ -589,6 +481,7 @@ bitflags! { } } + /// [snd_seq_addr_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__addr__t.html) wrapper #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] pub struct Addr { @@ -601,34 +494,27 @@ impl FromStr for Addr { fn from_str(s: &str) -> std::result::Result { let mut split: Split<'_, char> = s.trim().split(':'); - let client = split.next().ok_or("no client provided")?.parse::()?; - let port = split.next().ok_or("no port provided")?.parse::()?; + let client = split.next() + .ok_or("no client provided")? + .parse::()?; + let port = split.next() + .ok_or("no port provided")? + .parse::()?; match split.next() { - Some(_) => Err("too many arguments".into()), - None => Ok(Addr { client, port }), + Some(_) => { + Err("too many arguments".into()) + }, + None => { + Ok(Addr { client, port }) + } } } } impl Addr { - pub fn system_timer() -> Addr { - Addr { - client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, - port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32, - } - } - pub fn system_announce() -> Addr { - Addr { - client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, - port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32, - } - } - pub fn broadcast() -> Addr { - Addr { - client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, - port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, - } - } + pub fn system_timer() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32 } } + pub fn system_announce() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32 } } + pub fn broadcast() -> Addr { Addr { client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32 } } } /// [snd_seq_port_subscribe_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper @@ -637,9 +523,7 @@ pub struct PortSubscribe(*mut alsa::snd_seq_port_subscribe_t); unsafe impl Send for PortSubscribe {} impl Drop for PortSubscribe { - fn drop(&mut self) { - unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; - } + fn drop(&mut self) { unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; } } impl PortSubscribe { @@ -655,67 +539,36 @@ impl PortSubscribe { Ok(z) } - pub fn get_sender(&self) -> Addr { - unsafe { - let z = alsa::snd_seq_port_subscribe_get_sender(self.0); - Addr { - client: (*z).client as i32, - port: (*z).port as i32, - } - } - } + pub fn get_sender(&self) -> Addr { unsafe { + let z = alsa::snd_seq_port_subscribe_get_sender(self.0); + Addr { client: (*z).client as i32, port: (*z).port as i32 } + } } - pub fn get_dest(&self) -> Addr { - unsafe { - let z = alsa::snd_seq_port_subscribe_get_dest(self.0); - Addr { - client: (*z).client as i32, - port: (*z).port as i32, - } - } - } + pub fn get_dest(&self) -> Addr { unsafe { + let z = alsa::snd_seq_port_subscribe_get_dest(self.0); + Addr { client: (*z).client as i32, port: (*z).port as i32 } + } } - pub fn get_queue(&self) -> i32 { - unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } - } - pub fn get_exclusive(&self) -> bool { - unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } - } - pub fn get_time_update(&self) -> bool { - unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } - } - pub fn get_time_real(&self) -> bool { - unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } - } + pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } } + pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } } + pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } } + pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } } pub fn set_sender(&self, value: Addr) { - let z = alsa::snd_seq_addr_t { - client: value.client as c_uchar, - port: value.port as c_uchar, - }; + let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar }; unsafe { alsa::snd_seq_port_subscribe_set_sender(self.0, &z) }; } pub fn set_dest(&self, value: Addr) { - let z = alsa::snd_seq_addr_t { - client: value.client as c_uchar, - port: value.port as c_uchar, - }; + let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar }; unsafe { alsa::snd_seq_port_subscribe_set_dest(self.0, &z) }; } - pub fn set_queue(&self, value: i32) { - unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } - } - pub fn set_exclusive(&self, value: bool) { - unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 }) } - } - pub fn set_time_update(&self, value: bool) { - unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 }) } - } - pub fn set_time_real(&self, value: bool) { - unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 }) } - } + pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } } + pub fn set_exclusive(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 } ) } } + pub fn set_time_update(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 } ) } } + pub fn set_time_real(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 } ) } } + } /// [snd_seq_query_subs_type_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper @@ -732,9 +585,7 @@ struct QuerySubscribe(*mut alsa::snd_seq_query_subscribe_t); unsafe impl Send for QuerySubscribe {} impl Drop for QuerySubscribe { - fn drop(&mut self) { - unsafe { alsa::snd_seq_query_subscribe_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_seq_query_subscribe_free(self.0) } } } impl QuerySubscribe { @@ -743,48 +594,24 @@ impl QuerySubscribe { acheck!(snd_seq_query_subscribe_malloc(&mut q)).map(|_| QuerySubscribe(q)) } - pub fn get_index(&self) -> i32 { - unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } - } - pub fn get_addr(&self) -> Addr { - unsafe { - let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0)); - Addr { - client: a.client as i32, - port: a.port as i32, - } - } - } - pub fn get_queue(&self) -> i32 { - unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } - } - pub fn get_exclusive(&self) -> bool { - unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } - } - pub fn get_time_update(&self) -> bool { - unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } - } - pub fn get_time_real(&self) -> bool { - unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } - } + pub fn get_index(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } } + pub fn get_addr(&self) -> Addr { unsafe { + let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0)); + Addr { client: a.client as i32, port: a.port as i32 } + } } + pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } } + pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } } + pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } } + pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } } - pub fn set_root(&self, value: Addr) { - unsafe { - let a = alsa::snd_seq_addr_t { - client: value.client as c_uchar, - port: value.port as c_uchar, - }; - alsa::snd_seq_query_subscribe_set_root(self.0, &a); - } - } - pub fn set_type(&self, value: QuerySubsType) { - unsafe { - alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t) - } - } - pub fn set_index(&self, value: i32) { - unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } - } + pub fn set_root(&self, value: Addr) { unsafe { + let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar}; + alsa::snd_seq_query_subscribe_set_root(self.0, &a); + } } + pub fn set_type(&self, value: QuerySubsType) { unsafe { + alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t) + } } + pub fn set_index(&self, value: i32) { unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } } } #[derive(Copy, Clone)] @@ -793,17 +620,12 @@ pub struct PortSubscribeIter<'a> { seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType, - index: i32, + index: i32 } impl<'a> PortSubscribeIter<'a> { pub fn new(seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType) -> Self { - PortSubscribeIter { - seq, - addr, - query_subs_type, - index: 0, - } + PortSubscribeIter {seq, addr, query_subs_type, index: 0 } } } @@ -829,8 +651,8 @@ impl<'a> Iterator for PortSubscribeIter<'a> { QuerySubsType::READ => { vtr.set_sender(self.addr); vtr.set_dest(query.get_addr()); - } - QuerySubsType::WRITE => { + }, + QuerySubsType:: WRITE => { vtr.set_sender(query.get_addr()); vtr.set_dest(self.addr); } @@ -858,10 +680,7 @@ unsafe impl<'a> Send for Event<'a> {} impl<'a> Event<'a> { /// Creates a new event. For events that carry variable-length data (e.g. Sysex), `new_ext` has to be used instead. pub fn new(t: EventType, data: &D) -> Event<'static> { - assert!( - !Event::has_ext_data(t), - "event type must not carry variable-length data" - ); + assert!(!Event::has_ext_data(t), "event type must not carry variable-length data"); let mut z = Event(unsafe { mem::zeroed() }, t, None); (z.0).type_ = t as c_uchar; (z.0).flags |= Event::get_length_flag(t); @@ -872,10 +691,7 @@ impl<'a> Event<'a> { /// Creates a new event carrying variable-length data. This is required for event types `Sysex`, `Bounce`, and the `UsrVar` types. pub fn new_ext>>(t: EventType, data: D) -> Event<'a> { - assert!( - Event::has_ext_data(t), - "event type must carry variable-length data" - ); + assert!(Event::has_ext_data(t), "event type must carry variable-length data"); let mut z = Event(unsafe { mem::zeroed() }, t, Some(data.into())); (z.0).type_ = t as c_uchar; (z.0).flags |= Event::get_length_flag(t); @@ -886,11 +702,7 @@ impl<'a> Event<'a> { /// buffer for variable length messages (e.g. SysEx) has been copied into the event. /// The returned event has a static lifetime, i e, it's decoupled from the original buffer. pub fn into_owned(self) -> Event<'static> { - Event( - self.0, - self.1, - self.2.map(|cow| Cow::Owned(cow.into_owned())), - ) + Event(self.0, self.1, self.2.map(|cow| Cow::Owned(cow.into_owned()))) } fn get_length_flag(t: EventType) -> u8 { @@ -902,7 +714,7 @@ impl<'a> Event<'a> { EventType::UsrVar2 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, EventType::UsrVar3 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, EventType::UsrVar4 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR, - _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED, + _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED } } @@ -911,19 +723,12 @@ impl<'a> Event<'a> { } /// Extracts event type and data. Produces a result with an arbitrary lifetime, hence the unsafety. - unsafe fn extract<'any>( - z: &mut alsa::snd_seq_event_t, - func: &'static str, - ) -> Result> { + unsafe fn extract<'any>(z: &mut alsa::snd_seq_event_t, func: &'static str) -> Result> { let t = EventType::from_c_int((*z).type_ as c_int, func)?; let ext_data = if Event::has_ext_data(t) { - assert_ne!( - (*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, - alsa::SND_SEQ_EVENT_LENGTH_FIXED - ); + assert_ne!((*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, alsa::SND_SEQ_EVENT_LENGTH_FIXED); Some(Cow::Borrowed({ - let zz: &EvExtPacked = - &*(&(*z).data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _); + let zz: &EvExtPacked = &*(&(*z).data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _); slice::from_raw_parts((*zz).ptr as *mut u8, (*zz).len as usize) })) } else { @@ -935,35 +740,24 @@ impl<'a> Event<'a> { /// Ensures that the ev.ext union element points to the correct resize_buffer for events /// with variable length content fn ensure_buf(&mut self) { - if !Event::has_ext_data(self.1) { - return; - } + if !Event::has_ext_data(self.1) { return; } let slice: &[u8] = match self.2 { Some(Cow::Owned(ref mut vec)) => &vec[..], Some(Cow::Borrowed(buf)) => buf, // The following case is always a logic error in the program, thus panicking is okay. - None => panic!("event type requires variable-length data, but none was provided"), + None => panic!("event type requires variable-length data, but none was provided") }; - let z: &mut EvExtPacked = - unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + let z: &mut EvExtPacked = unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; z.len = slice.len() as c_uint; z.ptr = slice.as_ptr() as *mut c_void; } #[inline] - pub fn get_type(&self) -> EventType { - self.1 - } + pub fn get_type(&self) -> EventType { self.1 } /// Extract the event data from an event. /// Use `get_ext` instead for events carrying variable-length data. - pub fn get_data(&self) -> Option { - if D::has_data(self.1) { - Some(D::get_data(self)) - } else { - None - } - } + pub fn get_data(&self) -> Option { if D::has_data(self.1) { Some(D::get_data(self)) } else { None } } /// Extract the variable-length data carried by events of type `Sysex`, `Bounce`, or the `UsrVar` types. pub fn get_ext(&self) -> Option<&[u8]> { @@ -972,7 +766,7 @@ impl<'a> Event<'a> { Some(Cow::Owned(ref vec)) => Some(&vec[..]), Some(Cow::Borrowed(buf)) => Some(buf), // The following case is always a logic error in the program, thus panicking is okay. - None => panic!("event type requires variable-length data, but none was found"), + None => panic!("event type requires variable-length data, but none was found") } } else { None @@ -984,47 +778,19 @@ impl<'a> Event<'a> { self.0.dest.port = alsa::SND_SEQ_ADDRESS_UNKNOWN; } - pub fn set_source(&mut self, p: i32) { - self.0.source.port = p as u8 - } - pub fn set_dest(&mut self, d: Addr) { - self.0.dest.client = d.client as c_uchar; - self.0.dest.port = d.port as c_uchar; - } - pub fn set_tag(&mut self, t: u8) { - self.0.tag = t as c_uchar; - } - pub fn set_queue(&mut self, q: i32) { - self.0.queue = q as c_uchar; - } + pub fn set_source(&mut self, p: i32) { self.0.source.port = p as u8 } + pub fn set_dest(&mut self, d: Addr) { self.0.dest.client = d.client as c_uchar; self.0.dest.port = d.port as c_uchar; } + pub fn set_tag(&mut self, t: u8) { self.0.tag = t as c_uchar; } + pub fn set_queue(&mut self, q: i32) { self.0.queue = q as c_uchar; } - pub fn get_source(&self) -> Addr { - Addr { - client: self.0.source.client as i32, - port: self.0.source.port as i32, - } - } - pub fn get_dest(&self) -> Addr { - Addr { - client: self.0.dest.client as i32, - port: self.0.dest.port as i32, - } - } - pub fn get_tag(&self) -> u8 { - self.0.tag as u8 - } - pub fn get_queue(&self) -> i32 { - self.0.queue as i32 - } + pub fn get_source(&self) -> Addr { Addr { client: self.0.source.client as i32, port: self.0.source.port as i32 } } + pub fn get_dest(&self) -> Addr { Addr { client: self.0.dest.client as i32, port: self.0.dest.port as i32 } } + pub fn get_tag(&self) -> u8 { self.0.tag as u8 } + pub fn get_queue(&self) -> i32 { self.0.queue as i32 } pub fn schedule_real(&mut self, queue: i32, relative: bool, rtime: time::Duration) { self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK); - self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL - | (if relative { - alsa::SND_SEQ_TIME_MODE_REL - } else { - alsa::SND_SEQ_TIME_MODE_ABS - }); + self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS }); self.0.queue = queue as u8; let t = unsafe { &mut self.0.time.time }; t.tv_sec = rtime.as_secs() as c_uint; @@ -1033,33 +799,22 @@ impl<'a> Event<'a> { pub fn schedule_tick(&mut self, queue: i32, relative: bool, ttime: u32) { self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK); - self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK - | (if relative { - alsa::SND_SEQ_TIME_MODE_REL - } else { - alsa::SND_SEQ_TIME_MODE_ABS - }); + self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS }); self.0.queue = queue as u8; let t = unsafe { &mut self.0.time.tick }; *t = ttime as c_uint; } - pub fn set_direct(&mut self) { - self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT - } + pub fn set_direct(&mut self) { self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT } - pub fn get_relative(&self) -> bool { - (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 - } + pub fn get_relative(&self) -> bool { (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 } pub fn get_time(&self) -> Option { if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) != 0 { let d = self.0.time; let t = unsafe { &d.time }; Some(time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)) - } else { - None - } + } else { None } } pub fn get_tick(&self) -> Option { @@ -1067,68 +822,37 @@ impl<'a> Event<'a> { let d = self.0.time; let t = unsafe { &d.tick }; Some(*t) - } else { - None - } + } else { None } } /// Returns true if the message is high priority. - pub fn get_priority(&self) -> bool { - (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 - } + pub fn get_priority(&self) -> bool { (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 } pub fn set_priority(&mut self, is_high_prio: bool) { - if is_high_prio { - self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; - } else { - self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; - } + if is_high_prio { self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; } + else { self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; } } } impl<'a> Clone for Event<'a> { - fn clone(&self) -> Self { - Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) - } + fn clone(&self) -> Self { Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) } } impl<'a> fmt::Debug for Event<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut x = f.debug_tuple("Event"); x.field(&self.1); - if let Some(z) = self.get_data::() { - x.field(&z); - } - if let Some(z) = self.get_data::() { - x.field(&z); - } - if let Some(z) = self.get_data::() { - x.field(&z); - } - if let Some(z) = self.get_data::() { - x.field(&z); - } - if let Some(z) = self.get_data::>() { - x.field(&z); - } - if let Some(z) = self.get_data::>() { - x.field(&z); - } - if let Some(z) = self.get_data::>() { - x.field(&z); - } - if let Some(z) = self.get_data::>() { - x.field(&z); - } - if let Some(z) = self.get_data::() { - x.field(&z); - } - if let Some(z) = self.get_data::<[u8; 12]>() { - x.field(&z); - } - if let Some(z) = self.get_ext() { - x.field(&z); - } + if let Some(z) = self.get_data::() { x.field(&z); } + if let Some(z) = self.get_data::() { x.field(&z); } + if let Some(z) = self.get_data::() { x.field(&z); } + if let Some(z) = self.get_data::() { x.field(&z); } + if let Some(z) = self.get_data::>() { x.field(&z); } + if let Some(z) = self.get_data::>() { x.field(&z); } + if let Some(z) = self.get_data::>() { x.field(&z); } + if let Some(z) = self.get_data::>() { x.field(&z); } + if let Some(z) = self.get_data::() { x.field(&z); } + if let Some(z) = self.get_data::<[u8; 12]>() { x.field(&z); } + if let Some(z) = self.get_ext() { x.field(&z); } x.finish() } } @@ -1148,43 +872,43 @@ pub trait EventData { impl EventData for () { fn get_data(_: &Event) -> Self {} fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::TuneRequest | EventType::Reset | EventType::Sensing | EventType::None - ) + matches!(e, + EventType::TuneRequest | + EventType::Reset | + EventType::Sensing | + EventType::None) } fn set_data(&self, _: &mut Event) {} } impl EventData for [u8; 12] { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.raw8 }; - z.d + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.raw8 }; + z.d } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::Echo - | EventType::Oss - | EventType::Usr0 - | EventType::Usr1 - | EventType::Usr2 - | EventType::Usr3 - | EventType::Usr4 - | EventType::Usr5 - | EventType::Usr6 - | EventType::Usr7 - | EventType::Usr8 - | EventType::Usr9 - ) + matches!(e, + EventType::Echo | + EventType::Oss | + EventType::Usr0 | + EventType::Usr1 | + EventType::Usr2 | + EventType::Usr3 | + EventType::Usr4 | + EventType::Usr5 | + EventType::Usr6 | + EventType::Usr7 | + EventType::Usr8 | + EventType::Usr9) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.raw8 }; - z.d = *self; + let z = unsafe { &mut ev.0.data.raw8 }; + z.d = *self; } } + #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)] pub struct EvNote { pub channel: u8, @@ -1196,30 +920,23 @@ pub struct EvNote { impl EventData for EvNote { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_ev_note_t = - unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - EvNote { - channel: z.channel as u8, - note: z.note as u8, - velocity: z.velocity as u8, - off_velocity: z.off_velocity as u8, - duration: z.duration as u32, - } + let z: &alsa::snd_seq_ev_note_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + EvNote { channel: z.channel as u8, note: z.note as u8, velocity: z.velocity as u8, off_velocity: z.off_velocity as u8, duration: z.duration as u32 } } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::Note | EventType::Noteon | EventType::Noteoff | EventType::Keypress - ) + matches!(e, + EventType::Note | + EventType::Noteon | + EventType::Noteoff | + EventType::Keypress) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_ev_note_t = - unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.channel = self.channel as c_uchar; - z.note = self.note as c_uchar; - z.velocity = self.velocity as c_uchar; - z.off_velocity = self.off_velocity as c_uchar; - z.duration = self.duration as c_uint; + let z: &mut alsa::snd_seq_ev_note_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.channel = self.channel as c_uchar; + z.note = self.note as c_uchar; + z.velocity = self.velocity as c_uchar; + z.off_velocity = self.off_velocity as c_uchar; + z.duration = self.duration as c_uint; } } @@ -1232,65 +949,50 @@ pub struct EvCtrl { impl EventData for EvCtrl { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_ev_ctrl_t = - unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - EvCtrl { - channel: z.channel as u8, - param: z.param as u32, - value: z.value as i32, - } + let z: &alsa::snd_seq_ev_ctrl_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + EvCtrl { channel: z.channel as u8, param: z.param as u32, value: z.value as i32 } } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::Controller - | EventType::Pgmchange - | EventType::Chanpress - | EventType::Pitchbend - | EventType::Control14 - | EventType::Nonregparam - | EventType::Regparam - | EventType::Songpos - | EventType::Songsel - | EventType::Qframe - | EventType::Timesign - | EventType::Keysign - ) + matches!(e, + EventType::Controller | + EventType::Pgmchange | + EventType::Chanpress | + EventType::Pitchbend | + EventType::Control14 | + EventType::Nonregparam | + EventType::Regparam | + EventType::Songpos | + EventType::Songsel | + EventType::Qframe | + EventType::Timesign | + EventType::Keysign) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_ev_ctrl_t = - unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.channel = self.channel as c_uchar; - z.param = self.param as c_uint; - z.value = self.value as c_int; + let z: &mut alsa::snd_seq_ev_ctrl_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.channel = self.channel as c_uchar; + z.param = self.param as c_uint; + z.value = self.value as c_int; } } impl EventData for Addr { fn get_data(ev: &Event) -> Self { - let z: &alsa::snd_seq_addr_t = - unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; - Addr { - client: z.client as i32, - port: z.port as i32, - } + let z: &alsa::snd_seq_addr_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event__bindgen_ty_1 as *const _) }; + Addr { client: z.client as i32, port: z.port as i32 } } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::ClientStart - | EventType::ClientExit - | EventType::ClientChange - | EventType::PortStart - | EventType::PortExit - | EventType::PortChange - ) + matches!(e, + EventType::ClientStart | + EventType::ClientExit | + EventType::ClientChange | + EventType::PortStart | + EventType::PortExit | + EventType::PortChange) } fn set_data(&self, ev: &mut Event) { - let z: &mut alsa::snd_seq_addr_t = - unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; - z.client = self.client as c_uchar; - z.port = self.port as c_uchar; + let z: &mut alsa::snd_seq_addr_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event__bindgen_ty_1 as *mut _) }; + z.client = self.client as c_uchar; + z.port = self.port as c_uchar; } } @@ -1303,28 +1005,24 @@ pub struct Connect { impl EventData for Connect { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.connect }; - Connect { - sender: Addr { - client: z.sender.client as i32, - port: z.sender.port as i32, - }, - dest: Addr { - client: z.dest.client as i32, - port: z.dest.port as i32, - }, - } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.connect }; + Connect { + sender: Addr { client: z.sender.client as i32, port: z.sender.port as i32 }, + dest: Addr { client: z.dest.client as i32, port: z.dest.port as i32 } + } } fn has_data(e: EventType) -> bool { - matches!(e, EventType::PortSubscribed | EventType::PortUnsubscribed) + matches!(e, + EventType::PortSubscribed | + EventType::PortUnsubscribed) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.connect }; - z.sender.client = self.sender.client as c_uchar; - z.sender.port = self.sender.port as c_uchar; - z.dest.client = self.dest.client as c_uchar; - z.dest.port = self.dest.port as c_uchar; + let z = unsafe { &mut ev.0.data.connect }; + z.sender.client = self.sender.client as c_uchar; + z.sender.port = self.sender.port as c_uchar; + z.dest.client = self.dest.client as c_uchar; + z.dest.port = self.dest.port as c_uchar; } } @@ -1341,102 +1039,78 @@ pub struct EvQueueControl { impl EventData for EvQueueControl<()> { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.queue }; - EvQueueControl { - queue: z.queue as i32, - value: (), - } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.queue }; + EvQueueControl { queue: z.queue as i32, value: () } } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::Start - | EventType::Continue - | EventType::Stop - | EventType::Clock - | EventType::QueueSkew - ) + matches!(e, + EventType::Start | + EventType::Continue | + EventType::Stop | + EventType::Clock | + EventType::QueueSkew) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.queue }; - z.queue = self.queue as c_uchar; + let z = unsafe { &mut ev.0.data.queue }; + z.queue = self.queue as c_uchar; } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { - unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - EvQueueControl { - queue: z.queue as i32, - value: z.param.value as i32, - } - } - } + fn get_data(ev: &Event) -> Self { unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + EvQueueControl { queue: z.queue as i32, value: z.param.value as i32 } + } } fn has_data(e: EventType) -> bool { - matches!(e, EventType::Tempo) - } - fn set_data(&self, ev: &mut Event) { - unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - z.param.value = self.value as c_int; - } + matches!(e, + EventType::Tempo) } + fn set_data(&self, ev: &mut Event) { unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + z.param.value = self.value as c_int; + } } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { - unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - EvQueueControl { - queue: z.queue as i32, - value: z.param.position as u32, - } - } - } + fn get_data(ev: &Event) -> Self { unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + EvQueueControl { queue: z.queue as i32, value: z.param.position as u32 } + } } fn has_data(e: EventType) -> bool { - matches!( - e, - EventType::SyncPos | EventType::Tick | EventType::SetposTick - ) - } - fn set_data(&self, ev: &mut Event) { - unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - z.param.position = self.value as c_uint; - } + matches!(e, + EventType::SyncPos | + EventType::Tick | + EventType::SetposTick) } + fn set_data(&self, ev: &mut Event) { unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + z.param.position = self.value as c_uint; + } } } impl EventData for EvQueueControl { - fn get_data(ev: &Event) -> Self { - unsafe { - let mut d = ptr::read(&ev.0.data); - let z = &mut d.queue; - let t = &mut z.param.time.time; - EvQueueControl { - queue: z.queue as i32, - value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32), - } - } - } + fn get_data(ev: &Event) -> Self { unsafe { + let mut d = ptr::read(&ev.0.data); + let z = &mut d.queue; + let t = &mut z.param.time.time; + EvQueueControl { queue: z.queue as i32, value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) } + } } fn has_data(e: EventType) -> bool { - matches!(e, EventType::SetposTime) - } - fn set_data(&self, ev: &mut Event) { - unsafe { - let z = &mut ev.0.data.queue; - z.queue = self.queue as c_uchar; - let t = &mut z.param.time.time; - t.tv_sec = self.value.as_secs() as c_uint; - t.tv_nsec = self.value.subsec_nanos() as c_uint; - } + matches!(e, + EventType::SetposTime) } + fn set_data(&self, ev: &mut Event) { unsafe { + let z = &mut ev.0.data.queue; + z.queue = self.queue as c_uchar; + let t = &mut z.param.time.time; + t.tv_sec = self.value.as_secs() as c_uint; + t.tv_nsec = self.value.subsec_nanos() as c_uint; + } } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)] @@ -1450,23 +1124,24 @@ pub struct EvResult { impl EventData for EvResult { fn get_data(ev: &Event) -> Self { - let d = unsafe { ptr::read(&ev.0.data) }; - let z = unsafe { &d.result }; - EvResult { - event: z.event as i32, - result: z.result as i32, - } + let d = unsafe { ptr::read(&ev.0.data) }; + let z = unsafe { &d.result }; + EvResult { event: z.event as i32, result: z.result as i32 } } fn has_data(e: EventType) -> bool { - matches!(e, EventType::System | EventType::Result) + matches!(e, + EventType::System | + EventType::Result) } fn set_data(&self, ev: &mut Event) { - let z = unsafe { &mut ev.0.data.result }; - z.event = self.event as c_int; - z.result = self.result as c_int; + let z = unsafe { &mut ev.0.data.result }; + z.event = self.event as c_int; + z.result = self.result as c_int; } } + + alsa_enum!( /// [SND_SEQ_EVENT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_events.html) constants @@ -1539,9 +1214,7 @@ pub struct QueueTempo(*mut alsa::snd_seq_queue_tempo_t); unsafe impl Send for QueueTempo {} impl Drop for QueueTempo { - fn drop(&mut self) { - unsafe { alsa::snd_seq_queue_tempo_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_seq_queue_tempo_free(self.0) } } } impl QueueTempo { @@ -1557,35 +1230,17 @@ impl QueueTempo { Ok(q) } - pub fn get_queue(&self) -> i32 { - unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } - } - pub fn get_tempo(&self) -> u32 { - unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } - } - pub fn get_ppq(&self) -> i32 { - unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } - } - pub fn get_skew(&self) -> u32 { - unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } - } - pub fn get_skew_base(&self) -> u32 { - unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } - } + pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } } + pub fn get_tempo(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } } + pub fn get_ppq(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } } + pub fn get_skew(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } } + pub fn get_skew_base(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } } - // pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } } - pub fn set_tempo(&self, value: u32) { - unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } - } - pub fn set_ppq(&self, value: i32) { - unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } - } - pub fn set_skew(&self, value: u32) { - unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } - } - pub fn set_skew_base(&self, value: u32) { - unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } - } +// pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } } + pub fn set_tempo(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } } + pub fn set_ppq(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } } + pub fn set_skew(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } } + pub fn set_skew_base(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } } } /// [snd_seq_queue_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper @@ -1594,9 +1249,7 @@ pub struct QueueStatus(*mut alsa::snd_seq_queue_status_t); unsafe impl Send for QueueStatus {} impl Drop for QueueStatus { - fn drop(&mut self) { - unsafe { alsa::snd_seq_queue_status_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_seq_queue_status_free(self.0) } } } impl QueueStatus { @@ -1612,24 +1265,14 @@ impl QueueStatus { Ok(q) } - pub fn get_queue(&self) -> i32 { - unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } - } - pub fn get_events(&self) -> i32 { - unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } - } - pub fn get_tick_time(&self) -> u32 { - unsafe { alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } - } - pub fn get_real_time(&self) -> time::Duration { - unsafe { - let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0)); - time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) - } - } - pub fn get_status(&self) -> u32 { - unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } - } + pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } } + pub fn get_events(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } } + pub fn get_tick_time(&self) -> u32 { unsafe {alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } } + pub fn get_real_time(&self) -> time::Duration { unsafe { + let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0)); + time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) + } } + pub fn get_status(&self) -> u32 { unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } } } /// [snd_seq_remove_events_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) wrapper @@ -1638,9 +1281,7 @@ pub struct RemoveEvents(*mut alsa::snd_seq_remove_events_t); unsafe impl Send for RemoveEvents {} impl Drop for RemoveEvents { - fn drop(&mut self) { - unsafe { alsa::snd_seq_remove_events_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_seq_remove_events_free(self.0) } } } impl RemoveEvents { @@ -1649,87 +1290,49 @@ impl RemoveEvents { acheck!(snd_seq_remove_events_malloc(&mut q)).map(|_| RemoveEvents(q)) } - pub fn get_condition(&self) -> Remove { - unsafe { - Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32) - } - } - pub fn get_queue(&self) -> i32 { - unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } - } - pub fn get_time(&self) -> time::Duration { - unsafe { - let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0)); - let t = &d.time; + pub fn get_condition(&self) -> Remove { unsafe { + Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32) + } } + pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } } + pub fn get_time(&self) -> time::Duration { unsafe { + let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0)); + let t = &d.time; - time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) - } - } - pub fn get_dest(&self) -> Addr { - unsafe { - let a = &(*alsa::snd_seq_remove_events_get_dest(self.0)); + time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) + } } + pub fn get_dest(&self) -> Addr { unsafe { + let a = &(*alsa::snd_seq_remove_events_get_dest(self.0)); - Addr { - client: a.client as i32, - port: a.port as i32, - } - } - } - pub fn get_channel(&self) -> i32 { - unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } - } - pub fn get_event_type(&self) -> Result { - unsafe { - EventType::from_c_int( - alsa::snd_seq_remove_events_get_event_type(self.0), - "snd_seq_remove_events_get_event_type", - ) - } - } - pub fn get_tag(&self) -> u8 { - unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } - } + Addr { client: a.client as i32, port: a.port as i32 } + } } + pub fn get_channel(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } } + pub fn get_event_type(&self) -> Result { unsafe { + EventType::from_c_int(alsa::snd_seq_remove_events_get_event_type(self.0), "snd_seq_remove_events_get_event_type") + } } + pub fn get_tag(&self) -> u8 { unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } } - pub fn set_condition(&self, value: Remove) { - unsafe { - alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint); - } - } - pub fn set_queue(&self, value: i32) { - unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } - } - pub fn set_time(&self, value: time::Duration) { - unsafe { - let mut d: alsa::snd_seq_timestamp_t = mem::zeroed(); - let t = &mut d.time; - t.tv_sec = value.as_secs() as c_uint; - t.tv_nsec = value.subsec_nanos() as c_uint; + pub fn set_condition(&self, value: Remove) { unsafe { + alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint); + } } + pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } } + pub fn set_time(&self, value: time::Duration) { unsafe { + let mut d: alsa::snd_seq_timestamp_t = mem::zeroed(); + let t = &mut d.time; - alsa::snd_seq_remove_events_set_time(self.0, &d); - } - } - pub fn set_dest(&self, value: Addr) { - unsafe { - let a = alsa::snd_seq_addr_t { - client: value.client as c_uchar, - port: value.port as c_uchar, - }; + t.tv_sec = value.as_secs() as c_uint; + t.tv_nsec = value.subsec_nanos() as c_uint; - alsa::snd_seq_remove_events_set_dest(self.0, &a); - } - } - pub fn set_channel(&self, value: i32) { - unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } - } - pub fn set_event_type(&self, value: EventType) { - unsafe { - alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); - } - } - pub fn set_tag(&self, value: u8) { - unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } - } + alsa::snd_seq_remove_events_set_time(self.0, &d); + } } + pub fn set_dest(&self, value: Addr) { unsafe { + let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar}; + + alsa::snd_seq_remove_events_set_dest(self.0, &a); + } } + pub fn set_channel(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } } + pub fn set_event_type(&self, value: EventType) { unsafe { alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); } } + pub fn set_tag(&self, value: u8) { unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } } } /// [snd_midi_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___m_i_d_i___event.html) Wrapper @@ -1738,9 +1341,7 @@ impl RemoveEvents { pub struct MidiEvent(*mut alsa::snd_midi_event_t); impl Drop for MidiEvent { - fn drop(&mut self) { - unsafe { alsa::snd_midi_event_free(self.0) } - } + fn drop(&mut self) { unsafe { alsa::snd_midi_event_free(self.0) } } } impl MidiEvent { @@ -1749,39 +1350,23 @@ impl MidiEvent { acheck!(snd_midi_event_new(bufsize as size_t, &mut q)).map(|_| MidiEvent(q)) } - pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { - acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) - } + pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) } /// Note: this corresponds to snd_midi_event_no_status, but on and off are switched. /// /// Alsa-lib is a bit confusing here. Anyhow, set "enable" to true to enable running status. - pub fn enable_running_status(&self, enable: bool) { - unsafe { alsa::snd_midi_event_no_status(self.0, if enable { 0 } else { 1 }) } - } + pub fn enable_running_status(&self, enable: bool) { unsafe { alsa::snd_midi_event_no_status(self.0, if enable {0} else {1}) } } /// Resets both encoder and decoder - pub fn init(&self) { - unsafe { alsa::snd_midi_event_init(self.0) } - } + pub fn init(&self) { unsafe { alsa::snd_midi_event_init(self.0) } } - pub fn reset_encode(&self) { - unsafe { alsa::snd_midi_event_reset_encode(self.0) } - } + pub fn reset_encode(&self) { unsafe { alsa::snd_midi_event_reset_encode(self.0) } } - pub fn reset_decode(&self) { - unsafe { alsa::snd_midi_event_reset_decode(self.0) } - } + pub fn reset_decode(&self) { unsafe { alsa::snd_midi_event_reset_decode(self.0) } } pub fn decode(&self, buf: &mut [u8], ev: &mut Event) -> Result { ev.ensure_buf(); - acheck!(snd_midi_event_decode( - self.0, - buf.as_mut_ptr() as *mut c_uchar, - buf.len() as c_long, - &ev.0 - )) - .map(|r| r as usize) + acheck!(snd_midi_event_decode(self.0, buf.as_mut_ptr() as *mut c_uchar, buf.len() as c_long, &ev.0)).map(|r| r as usize) } /// In case of success, returns a tuple of (bytes consumed from buf, found Event). @@ -1791,17 +1376,12 @@ impl MidiEvent { // buffer). We make this safe by taking self by unique reference and coupling it to // the event's lifetime. let mut ev = unsafe { mem::zeroed() }; - let r = acheck!(snd_midi_event_encode( - self.0, - buf.as_ptr() as *const c_uchar, - buf.len() as c_long, - &mut ev - ))?; + let r = acheck!(snd_midi_event_encode(self.0, buf.as_ptr() as *const c_uchar, buf.len() as c_long, &mut ev))?; let e = if ev.type_ == alsa::SND_SEQ_EVENT_NONE as u8 { - None - } else { - Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?) - }; + None + } else { + Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?) + }; Ok((r as usize, e)) } } @@ -1810,8 +1390,7 @@ impl MidiEvent { fn print_seqs() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()) - .unwrap(); + s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()).unwrap(); let clients: Vec<_> = ClientIter::new(&s).collect(); for a in &clients { let ports: Vec<_> = PortIter::new(&s, a.get_client()).collect(); @@ -1823,18 +1402,14 @@ fn print_seqs() { fn seq_subscribe() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()) - .unwrap(); + s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()).unwrap(); let timer_info = s.get_any_port_info(Addr { client: 0, port: 0 }).unwrap(); assert_eq!(timer_info.get_name().unwrap(), "Timer"); let info = PortInfo::empty().unwrap(); let _port = s.create_port(&info); let subs = PortSubscribe::empty().unwrap(); subs.set_sender(Addr { client: 0, port: 0 }); - subs.set_dest(Addr { - client: s.client_id().unwrap(), - port: info.get_port(), - }); + subs.set_dest(Addr { client: s.client_id().unwrap(), port: info.get_port() }); s.subscribe_port(&subs).unwrap(); } @@ -1842,8 +1417,7 @@ fn seq_subscribe() { fn seq_loopback() { use std::ffi::CString; let s = super::Seq::open(Some(&CString::new("default").unwrap()), None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()) - .unwrap(); + s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()).unwrap(); // Create ports let sinfo = PortInfo::empty().unwrap(); @@ -1859,25 +1433,13 @@ fn seq_loopback() { // Connect them let subs = PortSubscribe::empty().unwrap(); - subs.set_sender(Addr { - client: s.client_id().unwrap(), - port: sport, - }); - subs.set_dest(Addr { - client: s.client_id().unwrap(), - port: dport, - }); + subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport }); + subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport }); s.subscribe_port(&subs).unwrap(); println!("Connected {:?} to {:?}", subs.get_sender(), subs.get_dest()); // Send a note! - let note = EvNote { - channel: 0, - note: 64, - duration: 100, - velocity: 100, - off_velocity: 64, - }; + let note = EvNote { channel: 0, note: 64, duration: 100, velocity: 100, off_velocity: 64 }; let mut e = Event::new(EventType::Noteon, ¬e); e.set_subs(); e.set_direct(); @@ -1920,8 +1482,7 @@ fn seq_decode_sysex() { fn seq_get_input_twice() { use std::ffi::CString; let s = super::Seq::open(None, None, false).unwrap(); - s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()) - .unwrap(); + s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()).unwrap(); let input1 = s.input(); let input2 = s.input(); // this should panic let _ = (input1, input2); @@ -1932,45 +1493,19 @@ fn seq_has_data() { for v in EventType::all() { let v = *v; let mut i = 0; - if <() as EventData>::has_data(v) { - i += 1; - } - if <[u8; 12] as EventData>::has_data(v) { - i += 1; - } - if Event::has_ext_data(v) { - i += 1; - } - if EvNote::has_data(v) { - i += 1; - } - if EvCtrl::has_data(v) { - i += 1; - } - if Addr::has_data(v) { - i += 1; - } - if Connect::has_data(v) { - i += 1; - } - if EvResult::has_data(v) { - i += 1; - } - if EvQueueControl::<()>::has_data(v) { - i += 1; - } - if EvQueueControl::::has_data(v) { - i += 1; - } - if EvQueueControl::::has_data(v) { - i += 1; - } - if EvQueueControl::::has_data(v) { - i += 1; - } - if i != 1 { - panic!("{:?}: {} has_data", v, i) - } + if <() as EventData>::has_data(v) { i += 1; } + if <[u8; 12] as EventData>::has_data(v) { i += 1; } + if Event::has_ext_data(v) { i += 1; } + if EvNote::has_data(v) { i += 1; } + if EvCtrl::has_data(v) { i += 1; } + if Addr::has_data(v) { i += 1; } + if Connect::has_data(v) { i += 1; } + if EvResult::has_data(v) { i += 1; } + if EvQueueControl::<()>::has_data(v) { i += 1; } + if EvQueueControl::::has_data(v) { i += 1; } + if EvQueueControl::::has_data(v) { i += 1; } + if EvQueueControl::::has_data(v) { i += 1; } + if i != 1 { panic!("{:?}: {} has_data", v, i) } } } @@ -1978,30 +1513,19 @@ fn seq_has_data() { fn seq_remove_events() -> std::result::Result<(), Box> { let info = RemoveEvents::new()?; + info.set_condition(Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH); info.set_queue(123); info.set_time(time::Duration::new(456, 789)); - info.set_dest(Addr { - client: 212, - port: 121, - }); + info.set_dest(Addr { client: 212, port: 121 }); info.set_channel(15); info.set_event_type(EventType::Noteon); info.set_tag(213); - assert_eq!( - info.get_condition(), - Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH - ); + assert_eq!(info.get_condition(), Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH); assert_eq!(info.get_queue(), 123); assert_eq!(info.get_time(), time::Duration::new(456, 789)); - assert_eq!( - info.get_dest(), - Addr { - client: 212, - port: 121 - } - ); + assert_eq!(info.get_dest(), Addr { client: 212, port: 121 }); assert_eq!(info.get_channel(), 15); assert_eq!(info.get_event_type()?, EventType::Noteon); assert_eq!(info.get_tag(), 213); @@ -2027,51 +1551,27 @@ fn seq_portsubscribeiter() { // Connect them let subs = PortSubscribe::empty().unwrap(); - subs.set_sender(Addr { - client: s.client_id().unwrap(), - port: sport, - }); - subs.set_dest(Addr { - client: s.client_id().unwrap(), - port: dport, - }); + subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport }); + subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport }); s.subscribe_port(&subs).unwrap(); // Query READ subs from sport's point of view - let read_subs: Vec = PortSubscribeIter::new( - &s, - Addr { - client: s.client_id().unwrap(), - port: sport, - }, - QuerySubsType::READ, - ) - .collect(); + let read_subs: Vec = PortSubscribeIter::new(&s, + Addr {client: s.client_id().unwrap(), port: sport }, + QuerySubsType::READ).collect(); assert_eq!(read_subs.len(), 1); assert_eq!(read_subs[0].get_sender(), subs.get_sender()); assert_eq!(read_subs[0].get_dest(), subs.get_dest()); - let write_subs: Vec = PortSubscribeIter::new( - &s, - Addr { - client: s.client_id().unwrap(), - port: sport, - }, - QuerySubsType::WRITE, - ) - .collect(); + let write_subs: Vec = PortSubscribeIter::new(&s, + Addr {client: s.client_id().unwrap(), port: sport }, + QuerySubsType::WRITE).collect(); assert_eq!(write_subs.len(), 0); // Now query WRITE subs from dport's point of view - let write_subs: Vec = PortSubscribeIter::new( - &s, - Addr { - client: s.client_id().unwrap(), - port: dport, - }, - QuerySubsType::WRITE, - ) - .collect(); + let write_subs: Vec = PortSubscribeIter::new(&s, + Addr {client: s.client_id().unwrap(), port: dport }, + QuerySubsType::WRITE).collect(); assert_eq!(write_subs.len(), 1); assert_eq!(write_subs[0].get_sender(), subs.get_sender()); assert_eq!(write_subs[0].get_dest(), subs.get_dest());