From 2028d5907f7f17b246d695337107d21d49abbdc6 Mon Sep 17 00:00:00 2001 From: tomaka Date: Wed, 11 Oct 2017 13:24:49 +0200 Subject: [PATCH] Run rustfmt on the code (#162) --- .rustfmt.toml | 18 +++ examples/beep.rs | 50 ++++-- examples/enumerate.rs | 11 +- src/alsa/enumerate.rs | 19 ++- src/alsa/mod.rs | 324 +++++++++++++++++++++++-------------- src/coreaudio/enumerate.rs | 15 +- src/coreaudio/mod.rs | 72 +++++---- src/lib.rs | 48 +++--- src/null/mod.rs | 19 ++- src/wasapi/com.rs | 6 +- src/wasapi/enumerate.rs | 27 ++-- src/wasapi/mod.rs | 148 +++++++++++------ src/wasapi/voice.rs | 264 +++++++++++++++--------------- 13 files changed, 622 insertions(+), 399 deletions(-) create mode 100644 .rustfmt.toml diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..5d38d1c --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,18 @@ +fn_args_density = "Compressed" +fn_args_layout = "Visual" +fn_brace_style = "SameLineWhere" +fn_call_style = "Visual" +fn_empty_single_line = false +format_strings = true +generics_indent = "Visual" +impl_empty_single_line = false +match_block_trailing_comma = true +reorder_imported_names = true +reorder_imports = true +reorder_imports_in_group = true +spaces_around_ranges = true +use_try_shorthand = true +where_density = "Tall" +where_style = "Legacy" +wrap_match_arms = false +write_mode = "Overwrite" diff --git a/examples/beep.rs b/examples/beep.rs index 3a53263..884316b 100644 --- a/examples/beep.rs +++ b/examples/beep.rs @@ -20,12 +20,17 @@ impl Executor for MyExecutor { fn main() { let endpoint = cpal::default_endpoint().expect("Failed to get default endpoint"); - let format = endpoint.supported_formats().unwrap().next().expect("Failed to get endpoint format"); + let format = endpoint + .supported_formats() + .unwrap() + .next() + .expect("Failed to get endpoint format"); let event_loop = cpal::EventLoop::new(); let executor = Arc::new(MyExecutor); - let (mut voice, stream) = cpal::Voice::new(&endpoint, &format, &event_loop).expect("Failed to create a voice"); + let (mut voice, stream) = cpal::Voice::new(&endpoint, &format, &event_loop) + .expect("Failed to create a voice"); // Produce a sinusoid of maximum amplitude. let samples_rate = format.samples_rate.0 as f32; @@ -36,22 +41,37 @@ fn main() { task::spawn(stream.for_each(move |buffer| -> Result<_, ()> { match buffer { cpal::UnknownTypeBuffer::U16(mut buffer) => { - for (sample, value) in buffer.chunks_mut(format.channels.len()).zip(&mut data_source) { + for (sample, value) in buffer + .chunks_mut(format.channels.len()) + .zip(&mut data_source) + { let value = ((value * 0.5 + 0.5) * std::u16::MAX as f32) as u16; - for out in sample.iter_mut() { *out = value; } + for out in sample.iter_mut() { + *out = value; + } } }, cpal::UnknownTypeBuffer::I16(mut buffer) => { - for (sample, value) in buffer.chunks_mut(format.channels.len()).zip(&mut data_source) { + for (sample, value) in buffer + .chunks_mut(format.channels.len()) + .zip(&mut data_source) + { let value = (value * std::i16::MAX as f32) as i16; - for out in sample.iter_mut() { *out = value; } + for out in sample.iter_mut() { + *out = value; + } } }, cpal::UnknownTypeBuffer::F32(mut buffer) => { - for (sample, value) in buffer.chunks_mut(format.channels.len()).zip(&mut data_source) { - for out in sample.iter_mut() { *out = value; } + for (sample, value) in buffer + .chunks_mut(format.channels.len()) + .zip(&mut data_source) + { + for out in sample.iter_mut() { + *out = value; + } } }, }; @@ -59,14 +79,12 @@ fn main() { Ok(()) })).execute(executor); - thread::spawn(move || { - loop { - thread::sleep(Duration::from_millis(500)); - voice.pause(); - thread::sleep(Duration::from_millis(500)); - voice.play(); - } - }); + thread::spawn(move || loop { + thread::sleep(Duration::from_millis(500)); + voice.pause(); + thread::sleep(Duration::from_millis(500)); + voice.play(); + }); event_loop.run(); } diff --git a/examples/enumerate.rs b/examples/enumerate.rs index 5cd1414..008d6de 100644 --- a/examples/enumerate.rs +++ b/examples/enumerate.rs @@ -2,14 +2,19 @@ extern crate cpal; fn main() { let endpoints = cpal::endpoints(); - + println!("Endpoints: "); for (endpoint_index, endpoint) in endpoints.enumerate() { - println!("{}. Endpoint \"{}\" Audio formats: ", endpoint_index + 1, endpoint.name()); + println!("{}. Endpoint \"{}\" Audio formats: ", + endpoint_index + 1, + endpoint.name()); let formats = match endpoint.supported_formats() { Ok(f) => f, - Err(e) => { println!("Error: {:?}", e); continue; } + Err(e) => { + println!("Error: {:?}", e); + continue; + }, }; for (format_index, format) in formats.enumerate() { diff --git a/src/alsa/enumerate.rs b/src/alsa/enumerate.rs index 18d64c4..c96fcc6 100644 --- a/src/alsa/enumerate.rs +++ b/src/alsa/enumerate.rs @@ -1,6 +1,7 @@ + +use super::Endpoint; use super::alsa; use super::check_errors; -use super::Endpoint; use std::ffi::CStr; use std::ffi::CString; @@ -17,8 +18,10 @@ pub struct EndpointsIterator { next_str: *const *const u8, } -unsafe impl Send for EndpointsIterator {} -unsafe impl Sync for EndpointsIterator {} +unsafe impl Send for EndpointsIterator { +} +unsafe impl Sync for EndpointsIterator { +} impl Drop for EndpointsIterator { #[inline] @@ -34,8 +37,8 @@ impl Default for EndpointsIterator { unsafe { let mut hints = mem::uninitialized(); // TODO: check in which situation this can fail - check_errors(alsa::snd_device_name_hint(-1, b"pcm\0".as_ptr() as *const _, - &mut hints)).unwrap(); + check_errors(alsa::snd_device_name_hint(-1, b"pcm\0".as_ptr() as *const _, &mut hints)) + .unwrap(); let hints = hints as *const *const u8; @@ -95,8 +98,10 @@ impl Iterator for EndpointsIterator { // trying to open the PCM device to see if it can be opened let name_zeroed = CString::new(name.clone()).unwrap(); let mut playback_handle = mem::uninitialized(); - if alsa::snd_pcm_open(&mut playback_handle, name_zeroed.as_ptr() as *const _, - alsa::SND_PCM_STREAM_PLAYBACK, alsa::SND_PCM_NONBLOCK) == 0 + if alsa::snd_pcm_open(&mut playback_handle, + name_zeroed.as_ptr() as *const _, + alsa::SND_PCM_STREAM_PLAYBACK, + alsa::SND_PCM_NONBLOCK) == 0 { alsa::snd_pcm_close(playback_handle); } else { diff --git a/src/alsa/mod.rs b/src/alsa/mod.rs index 3959fe0..22f3cbf 100644 --- a/src/alsa/mod.rs +++ b/src/alsa/mod.rs @@ -11,16 +11,16 @@ use SampleFormat; use SamplesRate; use UnknownTypeBuffer; -use std::{ffi, cmp, iter, mem, ptr}; -use std::vec::IntoIter as VecIntoIter; +use std::{cmp, ffi, iter, mem, ptr}; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; +use std::vec::IntoIter as VecIntoIter; -use futures::Poll; -use futures::task::Task; -use futures::task; -use futures::stream::Stream; use futures::Async; +use futures::Poll; +use futures::stream::Stream; +use futures::task; +use futures::task::Task; pub type SupportedFormatsIterator = VecIntoIter; @@ -34,10 +34,10 @@ struct Trigger { impl Trigger { fn new() -> Self { - let mut fds = [0,0]; + let mut fds = [0, 0]; match unsafe { libc::pipe(fds.as_mut_ptr()) } { 0 => Trigger { fds: fds }, - _ => panic!("Could not create pipe") + _ => panic!("Could not create pipe"), } } fn read_fd(&self) -> libc::c_int { @@ -72,9 +72,9 @@ impl Drop for Trigger { pub struct Endpoint(String); impl Endpoint { - pub fn get_supported_formats_list(&self) - -> Result - { + pub fn get_supported_formats_list( + &self) + -> Result { unsafe { let mut playback_handle = mem::uninitialized(); let device_name = ffi::CString::new(self.0.clone()).expect("Unable to get device name"); @@ -90,17 +90,18 @@ impl Endpoint { let hw_params = HwParams::alloc(); match check_errors(alsa::snd_pcm_hw_params_any(playback_handle, hw_params.0)) { Err(_) => return Ok(Vec::new().into_iter()), - Ok(_) => () + Ok(_) => (), }; // TODO: check endianess - const FORMATS: [(SampleFormat, alsa::snd_pcm_format_t); 3] = [ - //SND_PCM_FORMAT_S8, - //SND_PCM_FORMAT_U8, - (SampleFormat::I16, alsa::SND_PCM_FORMAT_S16_LE), - //SND_PCM_FORMAT_S16_BE, - (SampleFormat::U16, alsa::SND_PCM_FORMAT_U16_LE), - //SND_PCM_FORMAT_U16_BE, + const FORMATS: [(SampleFormat, alsa::snd_pcm_format_t); 3] = + [ + //SND_PCM_FORMAT_S8, + //SND_PCM_FORMAT_U8, + (SampleFormat::I16, alsa::SND_PCM_FORMAT_S16_LE), + //SND_PCM_FORMAT_S16_BE, + (SampleFormat::U16, alsa::SND_PCM_FORMAT_U16_LE), + //SND_PCM_FORMAT_U16_BE, /*SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_BE, SND_PCM_FORMAT_U24_LE, @@ -109,7 +110,7 @@ impl Endpoint { SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE,*/ - (SampleFormat::F32, alsa::SND_PCM_FORMAT_FLOAT_LE), + (SampleFormat::F32, alsa::SND_PCM_FORMAT_FLOAT_LE) /*SND_PCM_FORMAT_FLOAT_BE, SND_PCM_FORMAT_FLOAT64_LE, SND_PCM_FORMAT_FLOAT64_BE, @@ -132,25 +133,35 @@ impl Endpoint { SND_PCM_FORMAT_S18_3LE, SND_PCM_FORMAT_S18_3BE, SND_PCM_FORMAT_U18_3LE, - SND_PCM_FORMAT_U18_3BE,*/ - ]; + SND_PCM_FORMAT_U18_3BE,*/, + ]; let mut supported_formats = Vec::new(); for &(sample_format, alsa_format) in FORMATS.iter() { - if alsa::snd_pcm_hw_params_test_format(playback_handle, hw_params.0, alsa_format) == 0 { + if alsa::snd_pcm_hw_params_test_format(playback_handle, + hw_params.0, + alsa_format) == 0 + { supported_formats.push(sample_format); } } let mut min_rate = mem::uninitialized(); - check_errors(alsa::snd_pcm_hw_params_get_rate_min(hw_params.0, &mut min_rate, ptr::null_mut())).expect("unable to get minimum supported rete"); + check_errors(alsa::snd_pcm_hw_params_get_rate_min(hw_params.0, + &mut min_rate, + ptr::null_mut())) + .expect("unable to get minimum supported rete"); let mut max_rate = mem::uninitialized(); - check_errors(alsa::snd_pcm_hw_params_get_rate_max(hw_params.0, &mut max_rate, ptr::null_mut())).expect("unable to get maximum supported rate"); + check_errors(alsa::snd_pcm_hw_params_get_rate_max(hw_params.0, + &mut max_rate, + ptr::null_mut())) + .expect("unable to get maximum supported rate"); let samples_rates = if min_rate == max_rate { vec![min_rate] /*} else if alsa::snd_pcm_hw_params_test_rate(playback_handle, hw_params.0, min_rate + 1, 0) == 0 { - (min_rate .. max_rate + 1).collect()*/ // TODO: code is correct but returns lots of stuff + (min_rate .. max_rate + 1).collect()*/ + // TODO: code is correct but returns lots of stuff } else { const RATES: [libc::c_uint; 13] = [ 5512, @@ -170,7 +181,11 @@ impl Endpoint { let mut rates = Vec::new(); for &rate in RATES.iter() { - if alsa::snd_pcm_hw_params_test_rate(playback_handle, hw_params.0, rate, 0) == 0 { + if alsa::snd_pcm_hw_params_test_rate(playback_handle, + hw_params.0, + rate, + 0) == 0 + { rates.push(rate); } } @@ -178,36 +193,52 @@ impl Endpoint { /*if rates.len() == 0 { (min_rate .. max_rate + 1).collect() } else {*/ - rates // TODO: code is correct but returns lots of stuff + rates // TODO: code is correct but returns lots of stuff //} }; let mut min_channels = mem::uninitialized(); - check_errors(alsa::snd_pcm_hw_params_get_channels_min(hw_params.0, &mut min_channels)).expect("unable to get minimum supported channel count"); + check_errors(alsa::snd_pcm_hw_params_get_channels_min(hw_params.0, &mut min_channels)) + .expect("unable to get minimum supported channel count"); let mut max_channels = mem::uninitialized(); - check_errors(alsa::snd_pcm_hw_params_get_channels_max(hw_params.0, &mut max_channels)).expect("unable to get maximum supported channel count"); - let max_channels = cmp::min(max_channels, 32); // TODO: limiting to 32 channels or too much stuff is returned - let supported_channels = (min_channels .. max_channels + 1).filter_map(|num| { - if alsa::snd_pcm_hw_params_test_channels(playback_handle, hw_params.0, num) == 0 { - Some([ChannelPosition::FrontLeft, ChannelPosition::FrontRight, - ChannelPosition::BackLeft, ChannelPosition::BackRight, - ChannelPosition::FrontCenter, ChannelPosition::LowFrequency] - .iter().take(num as usize).cloned().collect::>()) + check_errors(alsa::snd_pcm_hw_params_get_channels_max(hw_params.0, &mut max_channels)) + .expect("unable to get maximum supported channel count"); + let max_channels = cmp::min(max_channels, 32); // TODO: limiting to 32 channels or too much stuff is returned + let supported_channels = (min_channels .. max_channels + 1) + .filter_map(|num| if alsa::snd_pcm_hw_params_test_channels( + playback_handle, + hw_params.0, + num, + ) == 0 + { + Some( + [ + ChannelPosition::FrontLeft, + ChannelPosition::FrontRight, + ChannelPosition::BackLeft, + ChannelPosition::BackRight, + ChannelPosition::FrontCenter, + ChannelPosition::LowFrequency, + ].iter() + .take(num as usize) + .cloned() + .collect::>(), + ) } else { None - } - }).collect::>(); + }) + .collect::>(); let mut output = Vec::with_capacity(supported_formats.len() * supported_channels.len() * - samples_rates.len()); + samples_rates.len()); for &data_type in supported_formats.iter() { for channels in supported_channels.iter() { for &rate in samples_rates.iter() { output.push(Format { - channels: channels.clone(), - samples_rate: SamplesRate(rate as u32), - data_type: data_type, - }); + channels: channels.clone(), + samples_rate: SamplesRate(rate as u32), + data_type: data_type, + }); } } } @@ -256,8 +287,10 @@ struct PollDescriptors { voices: Vec>, } -unsafe impl Send for EventLoopInner {} -unsafe impl Sync for EventLoopInner {} +unsafe impl Send for EventLoopInner { +} +unsafe impl Sync for EventLoopInner { +} impl EventLoop { #[inline] @@ -267,11 +300,13 @@ impl EventLoop { EventLoop { inner: Arc::new(EventLoopInner { current_wait: Mutex::new(PollDescriptors { - descriptors: vec![libc::pollfd { - fd: pending_trigger.read_fd(), - events: libc::POLLIN, - revents: 0, - }], + descriptors: vec![ + libc::pollfd { + fd: pending_trigger.read_fd(), + events: libc::POLLIN, + revents: 0, + }, + ], voices: Vec::new(), }), pending_wait: Mutex::new(PollDescriptors { @@ -279,7 +314,7 @@ impl EventLoop { voices: Vec::new(), }), pending_trigger: pending_trigger, - }) + }), } } @@ -331,14 +366,19 @@ impl EventLoop { { let channel = *current_wait.voices[i_voice].channel.lock().unwrap(); - let num_descriptors = current_wait.voices[i_voice].num_descriptors as libc::c_uint; + let num_descriptors = + current_wait.voices[i_voice].num_descriptors as libc::c_uint; check_errors(alsa::snd_pcm_poll_descriptors_revents(channel, current_wait.descriptors .as_mut_ptr().offset(i_descriptor), num_descriptors, &mut revent)).unwrap(); } if (revent as libc::c_short & libc::POLLOUT) != 0 { - let scheduled = current_wait.voices[i_voice].scheduled.lock().unwrap().take(); + let scheduled = current_wait.voices[i_voice] + .scheduled + .lock() + .unwrap() + .take(); scheduled.unwrap().task.unpark(); for _ in 0 .. current_wait.voices[i_voice].num_descriptors { @@ -347,20 +387,27 @@ impl EventLoop { current_wait.voices.remove(i_voice); } else { - i_descriptor += current_wait.voices[i_voice].num_descriptors as isize; + i_descriptor += current_wait.voices[i_voice].num_descriptors as + isize; i_voice += 1; } }, ScheduledKind::WaitResume => { if current_wait.descriptors[i_descriptor as usize].revents != 0 { // Unpark the task - let scheduled = current_wait.voices[i_voice].scheduled.lock().unwrap().take(); + let scheduled = current_wait.voices[i_voice] + .scheduled + .lock() + .unwrap() + .take(); scheduled.unwrap().task.unpark(); // Emptying the signal. let mut out = 0u64; - let ret = libc::read(current_wait.descriptors[i_descriptor as usize].fd, - &mut out as *mut u64 as *mut _, 8); + let ret = + libc::read(current_wait.descriptors[i_descriptor as usize].fd, + &mut out as *mut u64 as *mut _, + 8); assert_eq!(ret, 8); // Remove from current waiting poll descriptors @@ -370,7 +417,7 @@ impl EventLoop { i_descriptor += 1; i_voice += 1; } - } + }, } } } @@ -396,7 +443,7 @@ pub struct Scheduled { kind: ScheduledKind, } -#[derive(Clone,Copy)] +#[derive(Clone, Copy)] pub enum ScheduledKind { WaitResume, WaitPCM, @@ -436,8 +483,10 @@ struct VoiceInner { resume_trigger: Trigger, } -unsafe impl Send for VoiceInner {} -unsafe impl Sync for VoiceInner {} +unsafe impl Send for VoiceInner { +} +unsafe impl Sync for VoiceInner { +} impl SamplesStream { #[inline] @@ -447,9 +496,9 @@ impl SamplesStream { // We start by filling `scheduled`. *self.inner.scheduled.lock().unwrap() = Some(Scheduled { - task: task::park(), - kind: kind, - }); + task: task::park(), + kind: kind, + }); let mut pending_wait = self.inner.event_loop.pending_wait.lock().unwrap(); match kind { @@ -460,21 +509,26 @@ impl SamplesStream { let len = pending_wait.descriptors.len(); let filled = alsa::snd_pcm_poll_descriptors(*channel, - pending_wait.descriptors.as_mut_ptr() - .offset(len as isize), - self.inner.num_descriptors as libc::c_uint); + pending_wait + .descriptors + .as_mut_ptr() + .offset(len as isize), + self.inner.num_descriptors as + libc::c_uint); debug_assert_eq!(filled, self.inner.num_descriptors as libc::c_int); - pending_wait.descriptors.set_len(len + self.inner.num_descriptors); + pending_wait + .descriptors + .set_len(len + self.inner.num_descriptors); }, ScheduledKind::WaitResume => { // And we add the descriptor corresponding to the resume signal // to `event_loop.pending_wait.descriptors`. pending_wait.descriptors.push(libc::pollfd { - fd: self.inner.resume_trigger.read_fd(), - events: libc::POLLIN, - revents: 0, - }); - } + fd: self.inner.resume_trigger.read_fd(), + events: libc::POLLIN, + revents: 0, + }); + }, } // We also fill `voices`. @@ -502,7 +556,7 @@ impl Stream for SamplesStream { // Determine the number of samples that are available to write. let available = { let channel = self.inner.channel.lock().expect("could not lock channel"); - let available = unsafe { alsa::snd_pcm_avail(*channel) }; // TODO: what about snd_pcm_avail_update? + let available = unsafe { alsa::snd_pcm_avail(*channel) }; // TODO: what about snd_pcm_avail_update? if available == -32 { // buffer underrun @@ -525,7 +579,9 @@ impl Stream for SamplesStream { match self.inner.sample_format { SampleFormat::I16 => { let buffer = Buffer { - buffer: iter::repeat(unsafe { mem::uninitialized() }).take(available).collect(), + buffer: iter::repeat(unsafe { mem::uninitialized() }) + .take(available) + .collect(), inner: self.inner.clone(), }; @@ -533,7 +589,9 @@ impl Stream for SamplesStream { }, SampleFormat::U16 => { let buffer = Buffer { - buffer: iter::repeat(unsafe { mem::uninitialized() }).take(available).collect(), + buffer: iter::repeat(unsafe { mem::uninitialized() }) + .take(available) + .collect(), inner: self.inner.clone(), }; @@ -541,7 +599,9 @@ impl Stream for SamplesStream { }, SampleFormat::F32 => { let buffer = Buffer { - buffer: iter::repeat(unsafe { mem::uninitialized() }).take(available).collect(), + buffer: iter::repeat(unsafe { mem::uninitialized() }) + .take(available) + .collect(), inner: self.inner.clone(), }; @@ -558,7 +618,8 @@ impl HwParams { pub fn alloc() -> HwParams { unsafe { let mut hw_params = mem::uninitialized(); - check_errors(alsa::snd_pcm_hw_params_malloc(&mut hw_params)).expect("unable to get hardware parameters"); + check_errors(alsa::snd_pcm_hw_params_malloc(&mut hw_params)) + .expect("unable to get hardware parameters"); HwParams(hw_params) } } @@ -574,8 +635,7 @@ impl Drop for HwParams { impl Voice { pub fn new(endpoint: &Endpoint, format: &Format, event_loop: &EventLoop) - -> Result<(Voice, SamplesStream), CreationError> - { + -> Result<(Voice, SamplesStream), CreationError> { unsafe { let name = ffi::CString::new(endpoint.0.clone()).expect("unable to clone endpoint"); @@ -595,33 +655,62 @@ impl Voice { }; let hw_params = HwParams::alloc(); - check_errors(alsa::snd_pcm_hw_params_any(playback_handle, hw_params.0)).expect("Errors on playback handle"); - check_errors(alsa::snd_pcm_hw_params_set_access(playback_handle, hw_params.0, alsa::SND_PCM_ACCESS_RW_INTERLEAVED)).expect("handle not acessible"); - check_errors(alsa::snd_pcm_hw_params_set_format(playback_handle, hw_params.0, data_type)).expect("format could not be set"); - check_errors(alsa::snd_pcm_hw_params_set_rate(playback_handle, hw_params.0, format.samples_rate.0 as libc::c_uint, 0)).expect("sample rate could not be set"); - check_errors(alsa::snd_pcm_hw_params_set_channels(playback_handle, hw_params.0, format.channels.len() as libc::c_uint)).expect("channel count could not be set"); - let mut max_buffer_size = format.samples_rate.0 as alsa::snd_pcm_uframes_t / format.channels.len() as alsa::snd_pcm_uframes_t / 5; // 200ms of buffer - check_errors(alsa::snd_pcm_hw_params_set_buffer_size_max(playback_handle, hw_params.0, &mut max_buffer_size)).unwrap(); - check_errors(alsa::snd_pcm_hw_params(playback_handle, hw_params.0)).expect("hardware params could not be set"); + check_errors(alsa::snd_pcm_hw_params_any(playback_handle, hw_params.0)) + .expect("Errors on playback handle"); + check_errors(alsa::snd_pcm_hw_params_set_access(playback_handle, + hw_params.0, + alsa::SND_PCM_ACCESS_RW_INTERLEAVED)) + .expect("handle not acessible"); + check_errors(alsa::snd_pcm_hw_params_set_format(playback_handle, + hw_params.0, + data_type)) + .expect("format could not be set"); + check_errors(alsa::snd_pcm_hw_params_set_rate(playback_handle, + hw_params.0, + format.samples_rate.0 as libc::c_uint, + 0)) + .expect("sample rate could not be set"); + check_errors(alsa::snd_pcm_hw_params_set_channels(playback_handle, + hw_params.0, + format.channels.len() as + libc::c_uint)) + .expect("channel count could not be set"); + let mut max_buffer_size = format.samples_rate.0 as alsa::snd_pcm_uframes_t / + format.channels.len() as alsa::snd_pcm_uframes_t / + 5; // 200ms of buffer + check_errors(alsa::snd_pcm_hw_params_set_buffer_size_max(playback_handle, + hw_params.0, + &mut max_buffer_size)) + .unwrap(); + check_errors(alsa::snd_pcm_hw_params(playback_handle, hw_params.0)) + .expect("hardware params could not be set"); - let mut sw_params = mem::uninitialized(); // TODO: RAII + let mut sw_params = mem::uninitialized(); // TODO: RAII check_errors(alsa::snd_pcm_sw_params_malloc(&mut sw_params)).unwrap(); check_errors(alsa::snd_pcm_sw_params_current(playback_handle, sw_params)).unwrap(); - check_errors(alsa::snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params, 0)).unwrap(); + check_errors(alsa::snd_pcm_sw_params_set_start_threshold(playback_handle, + sw_params, + 0)) + .unwrap(); let (buffer_len, period_len) = { let mut buffer = mem::uninitialized(); let mut period = mem::uninitialized(); - check_errors(alsa::snd_pcm_get_params(playback_handle, &mut buffer, &mut period)).expect("could not initialize buffer"); + check_errors(alsa::snd_pcm_get_params(playback_handle, &mut buffer, &mut period)) + .expect("could not initialize buffer"); assert!(buffer != 0); - check_errors(alsa::snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, period)).unwrap(); + check_errors(alsa::snd_pcm_sw_params_set_avail_min(playback_handle, + sw_params, + period)) + .unwrap(); let buffer = buffer as usize * format.channels.len(); let period = period as usize * format.channels.len(); (buffer, period) }; check_errors(alsa::snd_pcm_sw_params(playback_handle, sw_params)).unwrap(); - check_errors(alsa::snd_pcm_prepare(playback_handle)).expect("could not get playback handle"); + check_errors(alsa::snd_pcm_prepare(playback_handle)) + .expect("could not get playback handle"); let num_descriptors = { let num_descriptors = alsa::snd_pcm_poll_descriptors_count(playback_handle); @@ -630,23 +719,20 @@ impl Voice { }; let samples_stream_inner = Arc::new(VoiceInner { - event_loop: event_loop.inner.clone(), - channel: Mutex::new(playback_handle), - sample_format: format.data_type, - num_descriptors: num_descriptors, - num_channels: format.channels.len() as u16, - buffer_len: buffer_len, - period_len: period_len, - scheduled: Mutex::new(None), - is_paused: AtomicBool::new(true), - resume_trigger: Trigger::new(), - }); + event_loop: event_loop.inner.clone(), + channel: Mutex::new(playback_handle), + sample_format: format.data_type, + num_descriptors: num_descriptors, + num_channels: format.channels.len() as u16, + buffer_len: buffer_len, + period_len: period_len, + scheduled: Mutex::new(None), + is_paused: AtomicBool::new(true), + resume_trigger: Trigger::new(), + }); - Ok((Voice { - inner: samples_stream_inner.clone() - }, SamplesStream { - inner: samples_stream_inner - })) + Ok((Voice { inner: samples_stream_inner.clone() }, + SamplesStream { inner: samples_stream_inner })) } } @@ -686,15 +772,17 @@ impl Buffer { } pub fn finish(self) { - let to_write = (self.buffer.len() / self.inner.num_channels as usize) - as alsa::snd_pcm_uframes_t; - let channel = self.inner.channel.lock().expect("Buffer channel lock failed"); + let to_write = (self.buffer.len() / self.inner.num_channels as usize) as + alsa::snd_pcm_uframes_t; + let channel = self.inner + .channel + .lock() + .expect("Buffer channel lock failed"); unsafe { loop { - let result = alsa::snd_pcm_writei(*channel, - self.buffer.as_ptr() as *const _, - to_write); + let result = + alsa::snd_pcm_writei(*channel, self.buffer.as_ptr() as *const _, to_write); if result == -32 { // buffer underrun @@ -716,7 +804,9 @@ fn check_errors(err: libc::c_int) -> Result<(), String> { if err < 0 { unsafe { - let s = ffi::CStr::from_ptr(alsa::snd_strerror(err)).to_bytes().to_vec(); + let s = ffi::CStr::from_ptr(alsa::snd_strerror(err)) + .to_bytes() + .to_vec(); let s = String::from_utf8(s).expect("Streaming error occured"); return Err(s); } diff --git a/src/coreaudio/enumerate.rs b/src/coreaudio/enumerate.rs index a69f998..7abc5b4 100644 --- a/src/coreaudio/enumerate.rs +++ b/src/coreaudio/enumerate.rs @@ -1,13 +1,15 @@ use super::Endpoint; -use ::Format; +use Format; use std::vec::IntoIter as VecIntoIter; pub struct EndpointsIterator(bool); -unsafe impl Send for EndpointsIterator {} -unsafe impl Sync for EndpointsIterator {} +unsafe impl Send for EndpointsIterator { +} +unsafe impl Sync for EndpointsIterator { +} impl Default for EndpointsIterator { fn default() -> Self { @@ -18,7 +20,12 @@ impl Default for EndpointsIterator { impl Iterator for EndpointsIterator { type Item = Endpoint; fn next(&mut self) -> Option { - if self.0 { None } else { self.0 = true; Some(Endpoint) } + if self.0 { + None + } else { + self.0 = true; + Some(Endpoint) + } } } diff --git a/src/coreaudio/mod.rs b/src/coreaudio/mod.rs index 9f3b662..b96dcac 100644 --- a/src/coreaudio/mod.rs +++ b/src/coreaudio/mod.rs @@ -1,20 +1,20 @@ extern crate coreaudio; extern crate libc; +use ChannelPosition; use CreationError; use Format; use FormatsEnumerationError; use Sample; use SampleFormat; use SamplesRate; -use ChannelPosition; use UnknownTypeBuffer; -use futures::Poll; use futures::Async; -use futures::task::Task; -use futures::task; +use futures::Poll; use futures::stream::Stream; +use futures::task; +use futures::task::Task; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; @@ -24,22 +24,24 @@ use self::coreaudio::audio_unit::render_callback::{self, data}; mod enumerate; -pub use self::enumerate::{EndpointsIterator, - SupportedFormatsIterator, - get_default_endpoint}; +pub use self::enumerate::{EndpointsIterator, SupportedFormatsIterator, get_default_endpoint}; #[derive(Clone, PartialEq, Eq)] pub struct Endpoint; impl Endpoint { - pub fn get_supported_formats_list(&self) - -> Result - { - Ok(vec!(Format { - channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], - samples_rate: SamplesRate(44100), - data_type: SampleFormat::F32 - }).into_iter()) + pub fn get_supported_formats_list( + &self) + -> Result { + Ok( + vec![ + Format { + channels: vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], + samples_rate: SamplesRate(44100), + data_type: SampleFormat::F32, + }, + ].into_iter(), + ) } pub fn get_name(&self) -> String { @@ -50,9 +52,11 @@ impl Endpoint { pub struct EventLoop; impl EventLoop { #[inline] - pub fn new() -> EventLoop { EventLoop } + pub fn new() -> EventLoop { + EventLoop + } #[inline] - pub fn run(&self) { + pub fn run(&self) { loop { // So the loop does not get optimised out in --release thread::sleep(Duration::new(1u64, 0u32)); @@ -65,7 +69,9 @@ pub struct Buffer { buffer: Vec, } -impl Buffer where T: Sample { +impl Buffer + where T: Sample +{ #[inline] pub fn get_buffer(&mut self) -> &mut [T] { &mut self.buffer[..] @@ -123,7 +129,7 @@ impl Stream for SamplesStream { None => { inner.scheduled_task = Some(task::park()); return Ok(Async::NotReady); - } + }, }; let buffer_len = current_callback.num_frames * current_callback.data.channels().count(); @@ -139,12 +145,11 @@ impl Stream for SamplesStream { impl Voice { pub fn new(_: &Endpoint, _: &Format, _: &EventLoop) - -> Result<(Voice, SamplesStream), CreationError> - { + -> Result<(Voice, SamplesStream), CreationError> { let inner = Arc::new(Mutex::new(SamplesStreamInner { - scheduled_task: None, - current_callback: None, - })); + scheduled_task: None, + current_callback: None, + })); fn convert_error(err: coreaudio::Error) -> CreationError { match err { @@ -158,14 +163,14 @@ impl Voice { } let au_type = if cfg!(target_os = "ios") { - // The DefaultOutput unit isn't available in iOS unfortunately. RemoteIO is a sensible replacement. - // See - // https://developer.apple.com/library/content/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/UsingSpecificAudioUnits/UsingSpecificAudioUnits.html + // The DefaultOutput unit isn't available in iOS unfortunately. RemoteIO is a sensible replacement. + // See + // https://developer.apple.com/library/content/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/UsingSpecificAudioUnits/UsingSpecificAudioUnits.html coreaudio::audio_unit::IOType::RemoteIO } else { coreaudio::audio_unit::IOType::DefaultOutput }; - let mut audio_unit = try!(AudioUnit::new(au_type).map_err(convert_error)); + let mut audio_unit = AudioUnit::new(au_type).map_err(convert_error)?; // TODO: iOS uses integer and fixed-point data @@ -199,10 +204,10 @@ impl Voice { Ok(()) }); - try!(result.map_err(convert_error)); + result.map_err(convert_error)?; } - try!(audio_unit.start().map_err(convert_error)); + audio_unit.start().map_err(convert_error)?; let au_arc = Arc::new(Mutex::new(audio_unit)); @@ -212,9 +217,10 @@ impl Voice { }; Ok((Voice { - playing: true, - audio_unit: au_arc.clone(), - }, samples_stream)) + playing: true, + audio_unit: au_arc.clone(), + }, + samples_stream)) } #[inline] diff --git a/src/lib.rs b/src/lib.rs index 621ef31..3914096 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,31 +74,32 @@ extern crate futures; extern crate lazy_static; extern crate libc; -pub use samples_formats::{SampleFormat, Sample}; +pub use samples_formats::{Sample, SampleFormat}; -#[cfg(all(not(windows), not(target_os = "linux"), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "ios")))] +#[cfg(all(not(windows), not(target_os = "linux"), not(target_os = "freebsd"), + not(target_os = "macos"), not(target_os = "ios")))] use null as cpal_impl; -use std::fmt; use std::error::Error; +use std::fmt; use std::ops::{Deref, DerefMut}; -use futures::stream::Stream; use futures::Poll; +use futures::stream::Stream; mod null; mod samples_formats; #[cfg(any(target_os = "linux", target_os = "freebsd"))] -#[path="alsa/mod.rs"] +#[path = "alsa/mod.rs"] mod cpal_impl; #[cfg(windows)] -#[path="wasapi/mod.rs"] +#[path = "wasapi/mod.rs"] mod cpal_impl; #[cfg(any(target_os = "macos", target_os = "ios"))] -#[path="coreaudio/mod.rs"] +#[path = "coreaudio/mod.rs"] mod cpal_impl; /// An iterator for the list of formats that are supported by the backend. @@ -151,18 +152,16 @@ pub struct Endpoint(cpal_impl::Endpoint); impl Endpoint { /// Returns an iterator that produces the list of formats that are supported by the backend. #[inline] - pub fn supported_formats(&self) -> Result - { - Ok(SupportedFormatsIterator(try!(self.0.get_supported_formats_list()))) + pub fn supported_formats(&self) -> Result { + Ok(SupportedFormatsIterator(self.0.get_supported_formats_list()?)) } /// Deprecated. Use `supported_formats` instead. #[inline] #[deprecated] - pub fn get_supported_formats_list(&self) -> Result - { + pub fn get_supported_formats_list( + &self) + -> Result { self.supported_formats() } @@ -254,7 +253,9 @@ impl EventLoop { /// You should destroy this object as soon as possible. Data is only committed when it /// is destroyed. #[must_use] -pub struct Buffer where T: Sample { +pub struct Buffer + where T: Sample +{ // also contains something, taken by `Drop` target: Option>, } @@ -363,9 +364,8 @@ impl Voice { /// Builds a new channel. #[inline] pub fn new(endpoint: &Endpoint, format: &Format, event_loop: &EventLoop) - -> Result<(Voice, SamplesStream), CreationError> - { - let (voice, stream) = try!(cpal_impl::Voice::new(&endpoint.0, format, &event_loop.0)); + -> Result<(Voice, SamplesStream), CreationError> { + let (voice, stream) = cpal_impl::Voice::new(&endpoint.0, format, &event_loop.0)?; let voice = Voice { voice: voice, @@ -447,7 +447,9 @@ impl Stream for SamplesStream { } } -impl Deref for Buffer where T: Sample { +impl Deref for Buffer + where T: Sample +{ type Target = [T]; #[inline] @@ -456,14 +458,18 @@ impl Deref for Buffer where T: Sample { } } -impl DerefMut for Buffer where T: Sample { +impl DerefMut for Buffer + where T: Sample +{ #[inline] fn deref_mut(&mut self) -> &mut [T] { self.target.as_mut().unwrap().get_buffer() } } -impl Drop for Buffer where T: Sample { +impl Drop for Buffer + where T: Sample +{ #[inline] fn drop(&mut self) { self.target.take().unwrap().finish(); diff --git a/src/null/mod.rs b/src/null/mod.rs index 5eaca60..df542be 100644 --- a/src/null/mod.rs +++ b/src/null/mod.rs @@ -2,9 +2,9 @@ use std::marker::PhantomData; +use futures::Async; use futures::Poll; use futures::stream::Stream; -use futures::Async; use CreationError; use Format; @@ -14,9 +14,13 @@ use UnknownTypeBuffer; pub struct EventLoop; impl EventLoop { #[inline] - pub fn new() -> EventLoop { EventLoop } + pub fn new() -> EventLoop { + EventLoop + } #[inline] - pub fn run(&self) { loop { /* TODO: don't spin */ } } + pub fn run(&self) { + loop { /* TODO: don't spin */ } + } } #[derive(Default)] @@ -41,9 +45,9 @@ pub struct Endpoint; impl Endpoint { #[inline] - pub fn get_supported_formats_list(&self) - -> Result - { + pub fn get_supported_formats_list( + &self) + -> Result { unreachable!() } @@ -70,8 +74,7 @@ pub struct SamplesStream; impl Voice { #[inline] pub fn new(_: &Endpoint, _: &Format, _: &EventLoop) - -> Result<(Voice, SamplesStream), CreationError> - { + -> Result<(Voice, SamplesStream), CreationError> { Err(CreationError::DeviceNotAvailable) } diff --git a/src/wasapi/com.rs b/src/wasapi/com.rs index 442cd39..bcd61c3 100644 --- a/src/wasapi/com.rs +++ b/src/wasapi/com.rs @@ -1,9 +1,9 @@ //! Handles COM initialization and cleanup. -use std::ptr; -use super::winapi; -use super::ole32; use super::check_result; +use super::ole32; +use super::winapi; +use std::ptr; thread_local!(static COM_INITIALIZED: ComInitialized = { unsafe { diff --git a/src/wasapi/enumerate.rs b/src/wasapi/enumerate.rs index 61bdbc8..cc67330 100644 --- a/src/wasapi/enumerate.rs +++ b/src/wasapi/enumerate.rs @@ -1,8 +1,9 @@ -use super::winapi; -use super::ole32; -use super::com; + use super::Endpoint; use super::check_result; +use super::com; +use super::ole32; +use super::winapi; use std::mem; use std::ptr; @@ -33,8 +34,10 @@ lazy_static! { /// RAII object around `winapi::IMMDeviceEnumerator`. struct Enumerator(*mut winapi::IMMDeviceEnumerator); -unsafe impl Send for Enumerator {} -unsafe impl Sync for Enumerator {} +unsafe impl Send for Enumerator { +} +unsafe impl Sync for Enumerator { +} impl Drop for Enumerator { #[inline] @@ -52,8 +55,10 @@ pub struct EndpointsIterator { next_item: u32, } -unsafe impl Send for EndpointsIterator {} -unsafe impl Sync for EndpointsIterator {} +unsafe impl Send for EndpointsIterator { +} +unsafe impl Sync for EndpointsIterator { +} impl Drop for EndpointsIterator { #[inline] @@ -72,7 +77,7 @@ impl Default for EndpointsIterator { check_result((*ENUMERATOR.0).EnumAudioEndpoints(winapi::eRender, winapi::DEVICE_STATE_ACTIVE, &mut collection)) - .unwrap(); + .unwrap(); let mut count = mem::uninitialized(); // can fail if the parameter is null, which should never happen @@ -116,11 +121,11 @@ impl Iterator for EndpointsIterator { pub fn get_default_endpoint() -> Option { unsafe { let mut device = mem::uninitialized(); - let hres = (*ENUMERATOR.0).GetDefaultAudioEndpoint(winapi::eRender, - winapi::eConsole, &mut device); + let hres = (*ENUMERATOR.0) + .GetDefaultAudioEndpoint(winapi::eRender, winapi::eConsole, &mut device); if let Err(_err) = check_result(hres) { - return None; // TODO: check specifically for `E_NOTFOUND`, and panic otherwise + return None; // TODO: check specifically for `E_NOTFOUND`, and panic otherwise } Some(Endpoint::from_immdevice(device)) diff --git a/src/wasapi/mod.rs b/src/wasapi/mod.rs index d6138d1..64b7634 100644 --- a/src/wasapi/mod.rs +++ b/src/wasapi/mod.rs @@ -2,23 +2,23 @@ extern crate winapi; extern crate ole32; extern crate kernel32; -use std::io::Error as IoError; -use std::os::windows::ffi::OsStringExt; use std::ffi::OsString; -use std::sync::{Arc, Mutex, MutexGuard}; -use std::ptr; +use std::io::Error as IoError; use std::mem; +use std::os::windows::ffi::OsStringExt; +use std::ptr; use std::slice; +use std::sync::{Arc, Mutex, MutexGuard}; +use ChannelPosition; use Format; use FormatsEnumerationError; -use ChannelPosition; -use SamplesRate; use SampleFormat; +use SamplesRate; -pub use std::option::IntoIter as OptionIntoIter; pub use self::enumerate::{EndpointsIterator, get_default_endpoint}; -pub use self::voice::{Voice, Buffer, EventLoop, SamplesStream}; +pub use self::voice::{Buffer, EventLoop, SamplesStream, Voice}; +pub use std::option::IntoIter as OptionIntoIter; pub type SupportedFormatsIterator = OptionIntoIter; @@ -38,8 +38,10 @@ fn check_result(result: winapi::HRESULT) -> Result<(), IoError> { /// Wrapper because of that stupid decision to remove `Send` and `Sync` from raw pointers. #[derive(Copy, Clone)] struct IAudioClientWrapper(*mut winapi::IAudioClient); -unsafe impl Send for IAudioClientWrapper {} -unsafe impl Sync for IAudioClientWrapper {} +unsafe impl Send for IAudioClientWrapper { +} +unsafe impl Sync for IAudioClientWrapper { +} /// An opaque type that identifies an end point. pub struct Endpoint { @@ -47,11 +49,13 @@ pub struct Endpoint { /// We cache an uninitialized `IAudioClient` so that we can call functions from it without /// having to create/destroy audio clients all the time. - future_audio_client: Arc>>, // TODO: add NonZero around the ptr + future_audio_client: Arc>>, // TODO: add NonZero around the ptr } -unsafe impl Send for Endpoint {} -unsafe impl Sync for Endpoint {} +unsafe impl Send for Endpoint { +} +unsafe impl Sync for Endpoint { +} impl Endpoint { // TODO: this function returns a GUID of the endpoin @@ -87,7 +91,8 @@ impl Endpoint { } /// Ensures that `future_audio_client` contains a `Some` and returns a locked mutex to it. - fn ensure_future_audio_client(&self) -> Result>, IoError> { + fn ensure_future_audio_client(&self) + -> Result>, IoError> { let mut lock = self.future_audio_client.lock().unwrap(); if lock.is_some() { return Ok(lock); @@ -95,12 +100,14 @@ impl Endpoint { let audio_client: *mut winapi::IAudioClient = unsafe { let mut audio_client = mem::uninitialized(); - let hresult = (*self.device).Activate(&winapi::IID_IAudioClient, winapi::CLSCTX_ALL, - ptr::null_mut(), &mut audio_client); + let hresult = (*self.device).Activate(&winapi::IID_IAudioClient, + winapi::CLSCTX_ALL, + ptr::null_mut(), + &mut audio_client); // can fail if the device has been disconnected since we enumerated it, or if // the device doesn't support playback for some reason - try!(check_result(hresult)); + check_result(hresult)?; assert!(!audio_client.is_null()); audio_client as *mut _ }; @@ -112,15 +119,15 @@ impl Endpoint { /// Returns an uninitialized `IAudioClient`. #[inline] fn build_audioclient(&self) -> Result<*mut winapi::IAudioClient, IoError> { - let mut lock = try!(self.ensure_future_audio_client()); + let mut lock = self.ensure_future_audio_client()?; let client = lock.unwrap().0; *lock = None; Ok(client) } - pub fn get_supported_formats_list(&self) - -> Result - { + pub fn get_supported_formats_list( + &self) + -> Result { // We always create voices in shared mode, therefore all samples go through an audio // processor to mix them together. // However there is no way to query the list of all formats that are supported by the @@ -150,10 +157,8 @@ impl Endpoint { let format = { let (channels, data_type) = match (*format_ptr).wFormatTag { winapi::WAVE_FORMAT_PCM => { - ( - vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], - SampleFormat::I16 - ) + (vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], + SampleFormat::I16) }, winapi::WAVE_FORMAT_EXTENSIBLE => { let format_ptr = format_ptr as *const winapi::WAVEFORMATEXTENSIBLE; @@ -162,24 +167,60 @@ impl Endpoint { let mut channels = Vec::new(); let mask = (*format_ptr).dwChannelMask; - if (mask & winapi::SPEAKER_FRONT_LEFT) != 0 { channels.push(ChannelPosition::FrontLeft); } - if (mask & winapi::SPEAKER_FRONT_RIGHT) != 0 { channels.push(ChannelPosition::FrontRight); } - if (mask & winapi::SPEAKER_FRONT_CENTER) != 0 { channels.push(ChannelPosition::FrontCenter); } - if (mask & winapi::SPEAKER_LOW_FREQUENCY) != 0 { channels.push(ChannelPosition::LowFrequency); } - if (mask & winapi::SPEAKER_BACK_LEFT) != 0 { channels.push(ChannelPosition::BackLeft); } - if (mask & winapi::SPEAKER_BACK_RIGHT) != 0 { channels.push(ChannelPosition::BackRight); } - if (mask & winapi::SPEAKER_FRONT_LEFT_OF_CENTER) != 0 { channels.push(ChannelPosition::FrontLeftOfCenter); } - if (mask & winapi::SPEAKER_FRONT_RIGHT_OF_CENTER) != 0 { channels.push(ChannelPosition::FrontRightOfCenter); } - if (mask & winapi::SPEAKER_BACK_CENTER) != 0 { channels.push(ChannelPosition::BackCenter); } - if (mask & winapi::SPEAKER_SIDE_LEFT) != 0 { channels.push(ChannelPosition::SideLeft); } - if (mask & winapi::SPEAKER_SIDE_RIGHT) != 0 { channels.push(ChannelPosition::SideRight); } - if (mask & winapi::SPEAKER_TOP_CENTER) != 0 { channels.push(ChannelPosition::TopCenter); } - if (mask & winapi::SPEAKER_TOP_FRONT_LEFT) != 0 { channels.push(ChannelPosition::TopFrontLeft); } - if (mask & winapi::SPEAKER_TOP_FRONT_CENTER) != 0 { channels.push(ChannelPosition::TopFrontCenter); } - if (mask & winapi::SPEAKER_TOP_FRONT_RIGHT) != 0 { channels.push(ChannelPosition::TopFrontRight); } - if (mask & winapi::SPEAKER_TOP_BACK_LEFT) != 0 { channels.push(ChannelPosition::TopBackLeft); } - if (mask & winapi::SPEAKER_TOP_BACK_CENTER) != 0 { channels.push(ChannelPosition::TopBackCenter); } - if (mask & winapi::SPEAKER_TOP_BACK_RIGHT) != 0 { channels.push(ChannelPosition::TopBackRight); } + if (mask & winapi::SPEAKER_FRONT_LEFT) != 0 { + channels.push(ChannelPosition::FrontLeft); + } + if (mask & winapi::SPEAKER_FRONT_RIGHT) != 0 { + channels.push(ChannelPosition::FrontRight); + } + if (mask & winapi::SPEAKER_FRONT_CENTER) != 0 { + channels.push(ChannelPosition::FrontCenter); + } + if (mask & winapi::SPEAKER_LOW_FREQUENCY) != 0 { + channels.push(ChannelPosition::LowFrequency); + } + if (mask & winapi::SPEAKER_BACK_LEFT) != 0 { + channels.push(ChannelPosition::BackLeft); + } + if (mask & winapi::SPEAKER_BACK_RIGHT) != 0 { + channels.push(ChannelPosition::BackRight); + } + if (mask & winapi::SPEAKER_FRONT_LEFT_OF_CENTER) != 0 { + channels.push(ChannelPosition::FrontLeftOfCenter); + } + if (mask & winapi::SPEAKER_FRONT_RIGHT_OF_CENTER) != 0 { + channels.push(ChannelPosition::FrontRightOfCenter); + } + if (mask & winapi::SPEAKER_BACK_CENTER) != 0 { + channels.push(ChannelPosition::BackCenter); + } + if (mask & winapi::SPEAKER_SIDE_LEFT) != 0 { + channels.push(ChannelPosition::SideLeft); + } + if (mask & winapi::SPEAKER_SIDE_RIGHT) != 0 { + channels.push(ChannelPosition::SideRight); + } + if (mask & winapi::SPEAKER_TOP_CENTER) != 0 { + channels.push(ChannelPosition::TopCenter); + } + if (mask & winapi::SPEAKER_TOP_FRONT_LEFT) != 0 { + channels.push(ChannelPosition::TopFrontLeft); + } + if (mask & winapi::SPEAKER_TOP_FRONT_CENTER) != 0 { + channels.push(ChannelPosition::TopFrontCenter); + } + if (mask & winapi::SPEAKER_TOP_FRONT_RIGHT) != 0 { + channels.push(ChannelPosition::TopFrontRight); + } + if (mask & winapi::SPEAKER_TOP_BACK_LEFT) != 0 { + channels.push(ChannelPosition::TopBackLeft); + } + if (mask & winapi::SPEAKER_TOP_BACK_CENTER) != 0 { + channels.push(ChannelPosition::TopBackCenter); + } + if (mask & winapi::SPEAKER_TOP_BACK_RIGHT) != 0 { + channels.push(ChannelPosition::TopBackRight); + } assert_eq!((*format_ptr).Format.nChannels as usize, channels.len()); channels @@ -187,8 +228,8 @@ impl Endpoint { let format = { fn cmp_guid(a: &winapi::GUID, b: &winapi::GUID) -> bool { - a.Data1 == b.Data1 && a.Data2 == b.Data2 && - a.Data3 == b.Data3 && a.Data4 == b.Data4 + a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 && + a.Data4 == b.Data4 } if cmp_guid(&(*format_ptr).SubFormat, &winapi::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) @@ -207,7 +248,7 @@ impl Endpoint { (channels, format) }, - f => panic!("Unknown data format returned by GetMixFormat: {:?}", f) + f => panic!("Unknown data format returned by GetMixFormat: {:?}", f), }; Format { @@ -231,12 +272,15 @@ impl PartialEq for Endpoint { } } -impl Eq for Endpoint {} +impl Eq for Endpoint { +} impl Clone for Endpoint { #[inline] fn clone(&self) -> Endpoint { - unsafe { (*self.device).AddRef(); } + unsafe { + (*self.device).AddRef(); + } Endpoint { device: self.device, @@ -248,10 +292,14 @@ impl Clone for Endpoint { impl Drop for Endpoint { #[inline] fn drop(&mut self) { - unsafe { (*self.device).Release(); } + unsafe { + (*self.device).Release(); + } if let Some(client) = self.future_audio_client.lock().unwrap().take() { - unsafe { (*client.0).Release(); } + unsafe { + (*client.0).Release(); + } } } } diff --git a/src/wasapi/voice.rs b/src/wasapi/voice.rs index f29e3e1..21698ef 100644 --- a/src/wasapi/voice.rs +++ b/src/wasapi/voice.rs @@ -1,26 +1,27 @@ + +use super::Endpoint; +use super::check_result; use super::com; use super::kernel32; use super::ole32; use super::winapi; -use super::Endpoint; -use super::check_result; -use std::slice; use std::mem; use std::ptr; -use std::sync::atomic::AtomicBool; -use std::sync::atomic::Ordering; +use std::slice; use std::sync::Arc; use std::sync::Mutex; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering; -use futures::Poll; -use futures::task::Task; -use futures::task; -use futures::stream::Stream; use futures::Async; +use futures::Poll; +use futures::stream::Stream; +use futures::task; +use futures::task::Task; -use CreationError; use ChannelPosition; +use CreationError; use Format; use SampleFormat; use UnknownTypeBuffer; @@ -29,8 +30,10 @@ pub struct EventLoop { inner: Arc, } -unsafe impl Send for EventLoop {} -unsafe impl Sync for EventLoop {} +unsafe impl Send for EventLoop { +} +unsafe impl Sync for EventLoop { +} struct EventLoopInner { // List of handles that are currently being polled or that are going to be polled. This mutex @@ -67,22 +70,21 @@ struct EventLoopScheduled { impl EventLoop { pub fn new() -> EventLoop { - let pending_scheduled_event = unsafe { - kernel32::CreateEventA(ptr::null_mut(), 0, 0, ptr::null()) - }; + let pending_scheduled_event = + unsafe { kernel32::CreateEventA(ptr::null_mut(), 0, 0, ptr::null()) }; EventLoop { inner: Arc::new(EventLoopInner { - pending_scheduled_event: pending_scheduled_event, - scheduled: Mutex::new(EventLoopScheduled { - handles: vec![pending_scheduled_event], - task_handles: vec![], - }), - pending_scheduled: Mutex::new(EventLoopScheduled { - handles: vec![], - task_handles: vec![], - }) - }) + pending_scheduled_event: pending_scheduled_event, + scheduled: Mutex::new(EventLoopScheduled { + handles: vec![pending_scheduled_event], + task_handles: vec![], + }), + pending_scheduled: Mutex::new(EventLoopScheduled { + handles: vec![], + task_handles: vec![], + }), + }), } } @@ -101,7 +103,8 @@ impl EventLoop { // sound needs a buffer. let result = kernel32::WaitForMultipleObjectsEx(scheduled.handles.len() as u32, scheduled.handles.as_ptr(), - winapi::FALSE, winapi::INFINITE, /* TODO: allow setting a timeout */ + winapi::FALSE, + winapi::INFINITE, /* TODO: allow setting a timeout */ winapi::FALSE /* irrelevant parameter here */); // Notifying the corresponding task handler. @@ -144,27 +147,30 @@ pub struct SamplesStream { event_loop: Arc, inner: Arc>, // The event that is signalled whenever a buffer is ready to be submitted to the voice. - event: winapi::HANDLE, // TODO: not deleted + event: winapi::HANDLE, // TODO: not deleted max_frames_in_buffer: winapi::UINT32, bytes_per_frame: winapi::WORD, ready: Arc, } -unsafe impl Send for SamplesStream {} -unsafe impl Sync for SamplesStream {} +unsafe impl Send for SamplesStream { +} +unsafe impl Sync for SamplesStream { +} struct VoiceInner { audio_client: *mut winapi::IAudioClient, render_client: *mut winapi::IAudioRenderClient, } -unsafe impl Send for Voice {} -unsafe impl Sync for Voice {} +unsafe impl Send for Voice { +} +unsafe impl Sync for Voice { +} impl Voice { pub fn new(end_point: &Endpoint, format: &Format, event_loop: &EventLoop) - -> Result<(Voice, SamplesStream), CreationError> - { + -> Result<(Voice, SamplesStream), CreationError> { unsafe { // Making sure that COM is initialized. // It's not actually sure that this is required, but when in doubt do it. @@ -179,14 +185,15 @@ impl Voice { // Computing the format and initializing the device. let format = { - let format_attempt = try!(format_to_waveformatextensible(format)); + let format_attempt = format_to_waveformatextensible(format)?; let share_mode = winapi::AUDCLNT_SHAREMODE_SHARED; // `IsFormatSupported` checks whether the format is supported and fills // a `WAVEFORMATEX` let mut dummy_fmt_ptr: *mut winapi::WAVEFORMATEX = mem::uninitialized(); - let hresult = (*audio_client).IsFormatSupported(share_mode, &format_attempt.Format, - &mut dummy_fmt_ptr); + let hresult = + (*audio_client) + .IsFormatSupported(share_mode, &format_attempt.Format, &mut dummy_fmt_ptr); // we free that `WAVEFORMATEX` immediately after because we don't need it if !dummy_fmt_ptr.is_null() { ole32::CoTaskMemFree(dummy_fmt_ptr as *mut _); @@ -196,8 +203,7 @@ impl Voice { // has been found) but we also treat this as an error match (hresult, check_result(hresult)) { (_, Err(ref e)) - if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => - { + if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => { (*audio_client).Release(); return Err(CreationError::DeviceNotAvailable); }, @@ -215,10 +221,13 @@ impl Voice { // finally initializing the audio client let hresult = (*audio_client).Initialize(share_mode, winapi::AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - 0, 0, &format_attempt.Format, ptr::null()); + 0, + 0, + &format_attempt.Format, + ptr::null()); match check_result(hresult) { - Err(ref e) if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => - { + Err(ref e) + if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => { (*audio_client).Release(); return Err(CreationError::DeviceNotAvailable); }, @@ -245,7 +254,7 @@ impl Voice { (*audio_client).Release(); panic!("Failed to call SetEventHandle") }, - Ok(_) => () + Ok(_) => (), }; event @@ -257,8 +266,8 @@ impl Voice { let hresult = (*audio_client).GetBufferSize(&mut max_frames_in_buffer); match check_result(hresult) { - Err(ref e) if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => - { + Err(ref e) + if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => { (*audio_client).Release(); return Err(CreationError::DeviceNotAvailable); }, @@ -276,13 +285,13 @@ impl Voice { let render_client = { let mut render_client: *mut winapi::IAudioRenderClient = mem::uninitialized(); let hresult = (*audio_client).GetService(&winapi::IID_IAudioRenderClient, - &mut render_client - as *mut *mut winapi::IAudioRenderClient - as *mut _); + &mut render_client as + *mut *mut winapi::IAudioRenderClient as + *mut _); match check_result(hresult) { - Err(ref e) if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => - { + Err(ref e) + if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => { (*audio_client).Release(); return Err(CreationError::DeviceNotAvailable); }, @@ -298,9 +307,9 @@ impl Voice { // Everything went fine. let inner = Arc::new(Mutex::new(VoiceInner { - audio_client: audio_client, - render_client: render_client, - })); + audio_client: audio_client, + render_client: render_client, + })); let voice = Voice { inner: inner.clone(), @@ -354,7 +363,9 @@ impl SamplesStream { fn schedule(&mut self) { let mut pending = self.event_loop.pending_scheduled.lock().unwrap(); pending.handles.push(self.event); - pending.task_handles.push((task::park(), self.ready.clone())); + pending + .task_handles + .push((task::park(), self.ready.clone())); drop(pending); let result = unsafe { kernel32::SetEvent(self.event_loop.pending_scheduled_event) }; @@ -379,7 +390,7 @@ impl Stream for SamplesStream { self.schedule(); return Ok(Async::NotReady); }, - _ => unreachable!() + _ => unreachable!(), }; } @@ -403,13 +414,14 @@ impl Stream for SamplesStream { // Obtaining a pointer to the buffer. let (buffer_data, buffer_len) = { let mut buffer: *mut winapi::BYTE = mem::uninitialized(); - let hresult = (*inner.render_client).GetBuffer(frames_available, - &mut buffer as *mut *mut _); - check_result(hresult).unwrap(); // FIXME: can return `AUDCLNT_E_DEVICE_INVALIDATED` + let hresult = (*inner.render_client) + .GetBuffer(frames_available, &mut buffer as *mut *mut _); + check_result(hresult).unwrap(); // FIXME: can return `AUDCLNT_E_DEVICE_INVALIDATED` debug_assert!(!buffer.is_null()); (buffer as *mut _, - frames_available as usize * self.bytes_per_frame as usize / mem::size_of::()) // FIXME: correct size + frames_available as usize * self.bytes_per_frame as usize / + mem::size_of::()) // FIXME: correct size }; let buffer = Buffer { @@ -419,7 +431,9 @@ impl Stream for SamplesStream { frames: frames_available, }; - Ok(Async::Ready(Some(UnknownTypeBuffer::F32(::Buffer { target: Some(buffer) })))) // FIXME: not necessarily F32 + Ok(Async::Ready(Some(UnknownTypeBuffer::F32(::Buffer { + target: Some(buffer), + })))) // FIXME: not necessarily F32 } }; @@ -450,14 +464,13 @@ pub struct Buffer { frames: winapi::UINT32, } -unsafe impl Send for Buffer {} +unsafe impl Send for Buffer { +} impl Buffer { #[inline] pub fn get_buffer(&mut self) -> &mut [T] { - unsafe { - slice::from_raw_parts_mut(self.buffer_data, self.buffer_len) - } + unsafe { slice::from_raw_parts_mut(self.buffer_data, self.buffer_len) } } #[inline] @@ -472,8 +485,7 @@ impl Buffer { let hresult = (*inner.render_client).ReleaseBuffer(self.frames as u32, 0); match check_result(hresult) { // ignoring the error that is produced if the device has been disconnected - Err(ref e) - if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => (), + Err(ref e) if e.raw_os_error() == Some(winapi::AUDCLNT_E_DEVICE_INVALIDATED) => (), e => e.unwrap(), }; } @@ -481,69 +493,69 @@ impl Buffer { } fn format_to_waveformatextensible(format: &Format) - -> Result -{ + -> Result { Ok(winapi::WAVEFORMATEXTENSIBLE { - Format: winapi::WAVEFORMATEX { - wFormatTag: match format.data_type { - SampleFormat::I16 => winapi::WAVE_FORMAT_PCM, - SampleFormat::F32 => winapi::WAVE_FORMAT_EXTENSIBLE, - SampleFormat::U16 => return Err(CreationError::FormatNotSupported), - }, - nChannels: format.channels.len() as winapi::WORD, - nSamplesPerSec: format.samples_rate.0 as winapi::DWORD, - nAvgBytesPerSec: format.channels.len() as winapi::DWORD * - format.samples_rate.0 as winapi::DWORD * - format.data_type.get_sample_size() as winapi::DWORD, - nBlockAlign: format.channels.len() as winapi::WORD * - format.data_type.get_sample_size() as winapi::WORD, - wBitsPerSample: 8 * format.data_type.get_sample_size() as winapi::WORD, - cbSize: match format.data_type { - SampleFormat::I16 => 0, - SampleFormat::F32 => (mem::size_of::() - - mem::size_of::()) as winapi::WORD, - SampleFormat::U16 => return Err(CreationError::FormatNotSupported), - }, - }, - Samples: 8 * format.data_type.get_sample_size() as winapi::WORD, - dwChannelMask: { - let mut mask = 0; - for &channel in format.channels.iter() { - let raw_value = match channel { - ChannelPosition::FrontLeft => winapi::SPEAKER_FRONT_LEFT, - ChannelPosition::FrontRight => winapi::SPEAKER_FRONT_RIGHT, - ChannelPosition::FrontCenter => winapi::SPEAKER_FRONT_CENTER, - ChannelPosition::LowFrequency => winapi::SPEAKER_LOW_FREQUENCY, - ChannelPosition::BackLeft => winapi::SPEAKER_BACK_LEFT, - ChannelPosition::BackRight => winapi::SPEAKER_BACK_RIGHT, - ChannelPosition::FrontLeftOfCenter => winapi::SPEAKER_FRONT_LEFT_OF_CENTER, - ChannelPosition::FrontRightOfCenter => winapi::SPEAKER_FRONT_RIGHT_OF_CENTER, - ChannelPosition::BackCenter => winapi::SPEAKER_BACK_CENTER, - ChannelPosition::SideLeft => winapi::SPEAKER_SIDE_LEFT, - ChannelPosition::SideRight => winapi::SPEAKER_SIDE_RIGHT, - ChannelPosition::TopCenter => winapi::SPEAKER_TOP_CENTER, - ChannelPosition::TopFrontLeft => winapi::SPEAKER_TOP_FRONT_LEFT, - ChannelPosition::TopFrontCenter => winapi::SPEAKER_TOP_FRONT_CENTER, - ChannelPosition::TopFrontRight => winapi::SPEAKER_TOP_FRONT_RIGHT, - ChannelPosition::TopBackLeft => winapi::SPEAKER_TOP_BACK_LEFT, - ChannelPosition::TopBackCenter => winapi::SPEAKER_TOP_BACK_CENTER, - ChannelPosition::TopBackRight => winapi::SPEAKER_TOP_BACK_RIGHT, - }; + Format: winapi::WAVEFORMATEX { + wFormatTag: match format.data_type { + SampleFormat::I16 => winapi::WAVE_FORMAT_PCM, + SampleFormat::F32 => winapi::WAVE_FORMAT_EXTENSIBLE, + SampleFormat::U16 => return Err(CreationError::FormatNotSupported), + }, + nChannels: format.channels.len() as winapi::WORD, + nSamplesPerSec: format.samples_rate.0 as winapi::DWORD, + nAvgBytesPerSec: format.channels.len() as winapi::DWORD * + format.samples_rate.0 as winapi::DWORD * + format.data_type.get_sample_size() as winapi::DWORD, + nBlockAlign: format.channels.len() as winapi::WORD * + format.data_type.get_sample_size() as winapi::WORD, + wBitsPerSample: 8 * format.data_type.get_sample_size() as winapi::WORD, + cbSize: match format.data_type { + SampleFormat::I16 => 0, + SampleFormat::F32 => (mem::size_of::() - + mem::size_of::()) as + winapi::WORD, + SampleFormat::U16 => return Err(CreationError::FormatNotSupported), + }, + }, + Samples: 8 * format.data_type.get_sample_size() as winapi::WORD, + dwChannelMask: { + let mut mask = 0; + for &channel in format.channels.iter() { + let raw_value = match channel { + ChannelPosition::FrontLeft => winapi::SPEAKER_FRONT_LEFT, + ChannelPosition::FrontRight => winapi::SPEAKER_FRONT_RIGHT, + ChannelPosition::FrontCenter => winapi::SPEAKER_FRONT_CENTER, + ChannelPosition::LowFrequency => winapi::SPEAKER_LOW_FREQUENCY, + ChannelPosition::BackLeft => winapi::SPEAKER_BACK_LEFT, + ChannelPosition::BackRight => winapi::SPEAKER_BACK_RIGHT, + ChannelPosition::FrontLeftOfCenter => winapi::SPEAKER_FRONT_LEFT_OF_CENTER, + ChannelPosition::FrontRightOfCenter => winapi::SPEAKER_FRONT_RIGHT_OF_CENTER, + ChannelPosition::BackCenter => winapi::SPEAKER_BACK_CENTER, + ChannelPosition::SideLeft => winapi::SPEAKER_SIDE_LEFT, + ChannelPosition::SideRight => winapi::SPEAKER_SIDE_RIGHT, + ChannelPosition::TopCenter => winapi::SPEAKER_TOP_CENTER, + ChannelPosition::TopFrontLeft => winapi::SPEAKER_TOP_FRONT_LEFT, + ChannelPosition::TopFrontCenter => winapi::SPEAKER_TOP_FRONT_CENTER, + ChannelPosition::TopFrontRight => winapi::SPEAKER_TOP_FRONT_RIGHT, + ChannelPosition::TopBackLeft => winapi::SPEAKER_TOP_BACK_LEFT, + ChannelPosition::TopBackCenter => winapi::SPEAKER_TOP_BACK_CENTER, + ChannelPosition::TopBackRight => winapi::SPEAKER_TOP_BACK_RIGHT, + }; - // channels must be in the right order - if raw_value <= mask { - return Err(CreationError::FormatNotSupported); - } + // channels must be in the right order + if raw_value <= mask { + return Err(CreationError::FormatNotSupported); + } - mask = mask | raw_value; - } + mask = mask | raw_value; + } - mask - }, - SubFormat: match format.data_type { - SampleFormat::I16 => winapi::KSDATAFORMAT_SUBTYPE_PCM, - SampleFormat::F32 => winapi::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, - SampleFormat::U16 => return Err(CreationError::FormatNotSupported), - }, - }) + mask + }, + SubFormat: match format.data_type { + SampleFormat::I16 => winapi::KSDATAFORMAT_SUBTYPE_PCM, + SampleFormat::F32 => winapi::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, + SampleFormat::U16 => return Err(CreationError::FormatNotSupported), + }, + }) }