diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e31b9..9052bff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Remove unused ChannelPosition API. - Implement Endpoint and Format Enumeration for macos. - Implement format handling for macos `build_voice` method. diff --git a/examples/beep.rs b/examples/beep.rs index 579a92a..37b04cf 100644 --- a/examples/beep.rs +++ b/examples/beep.rs @@ -25,7 +25,7 @@ fn main() { event_loop.run(move |_, buffer| { match buffer { cpal::UnknownTypeBuffer::U16(mut buffer) => { - for sample in buffer.chunks_mut(format.channels.len()) { + for sample in buffer.chunks_mut(format.channels as usize) { let value = ((next_value() * 0.5 + 0.5) * std::u16::MAX as f32) as u16; for out in sample.iter_mut() { *out = value; @@ -34,7 +34,7 @@ fn main() { }, cpal::UnknownTypeBuffer::I16(mut buffer) => { - for sample in buffer.chunks_mut(format.channels.len()) { + for sample in buffer.chunks_mut(format.channels as usize) { let value = (next_value() * std::i16::MAX as f32) as i16; for out in sample.iter_mut() { *out = value; @@ -43,7 +43,7 @@ fn main() { }, cpal::UnknownTypeBuffer::F32(mut buffer) => { - for sample in buffer.chunks_mut(format.channels.len()) { + for sample in buffer.chunks_mut(format.channels as usize) { let value = next_value(); for out in sample.iter_mut() { *out = value; diff --git a/src/alsa/mod.rs b/src/alsa/mod.rs index 5251d55..6c852d0 100644 --- a/src/alsa/mod.rs +++ b/src/alsa/mod.rs @@ -3,7 +3,7 @@ extern crate libc; pub use self::enumerate::{EndpointsIterator, default_endpoint}; -use ChannelPosition; +use ChannelsCount; use CreationError; use Format; use FormatsEnumerationError; @@ -206,19 +206,7 @@ impl Endpoint { num, ) == 0 { - Some( - [ - ChannelPosition::FrontLeft, - ChannelPosition::FrontRight, - ChannelPosition::BackLeft, - ChannelPosition::BackRight, - ChannelPosition::FrontCenter, - ChannelPosition::LowFrequency, - ].iter() - .take(num as usize) - .cloned() - .collect::>(), - ) + Some(num as ChannelsCount) } else { None }) @@ -569,11 +557,11 @@ impl EventLoop { .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 + format.channels 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 / + format.channels 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, @@ -602,8 +590,8 @@ impl EventLoop { sw_params, period)) .unwrap(); - let buffer = buffer as usize * format.channels.len(); - let period = period as usize * format.channels.len(); + let buffer = buffer as usize * format.channels as usize; + let period = period as usize * format.channels as usize; (buffer, period) }; @@ -625,7 +613,7 @@ impl EventLoop { channel: playback_handle, sample_format: format.data_type, num_descriptors: num_descriptors, - num_channels: format.channels.len() as u16, + num_channels: format.channels as u16, buffer_len: buffer_len, period_len: period_len, can_pause: can_pause, diff --git a/src/coreaudio/mod.rs b/src/coreaudio/mod.rs index aa11b10..a4e8819 100644 --- a/src/coreaudio/mod.rs +++ b/src/coreaudio/mod.rs @@ -1,7 +1,7 @@ extern crate coreaudio; extern crate core_foundation_sys; -use ChannelPosition; +use ChannelsCount; use CreationError; use Format; use FormatsEnumerationError; @@ -108,26 +108,6 @@ impl Endpoint { for buffer in buffers { n_channels += buffer.mNumberChannels as usize; } - const CHANNEL_POSITIONS: &'static [ChannelPosition] = &[ - ChannelPosition::FrontLeft, - ChannelPosition::FrontRight, - ChannelPosition::FrontCenter, - ChannelPosition::LowFrequency, - ChannelPosition::BackLeft, - ChannelPosition::BackRight, - ChannelPosition::FrontLeftOfCenter, - ChannelPosition::FrontRightOfCenter, - ChannelPosition::BackCenter, - ChannelPosition::SideLeft, - ChannelPosition::SideRight, - ChannelPosition::TopCenter, - ChannelPosition::TopFrontLeft, - ChannelPosition::TopFrontCenter, - ChannelPosition::TopFrontRight, - ChannelPosition::TopBackLeft, - ChannelPosition::TopBackCenter, - ChannelPosition::TopBackRight, - ]; // AFAIK the sample format should always be f32 on macos and i16 on iOS? Feel free to // fix this if more pcm formats are supported. @@ -170,13 +150,8 @@ impl Endpoint { // Collect the supported formats for the device. let mut fmts = vec![]; for range in ranges { - let channels = CHANNEL_POSITIONS.iter() - .cloned() - .cycle() - .take(n_channels) - .collect::>(); let fmt = SupportedFormat { - channels: channels.clone(), + channels: n_channels as ChannelsCount, min_samples_rate: SamplesRate(range.mMinimum as _), max_samples_rate: SamplesRate(range.mMaximum as _), data_type: sample_format, @@ -306,7 +281,7 @@ impl EventLoop { )?; // Set the stream in interleaved mode. - let n_channels = format.channels.len(); + let n_channels = format.channels as usize; let sample_rate = format.samples_rate.0; let bytes_per_channel = format.data_type.sample_size(); let bits_per_channel = bytes_per_channel * 8; diff --git a/src/emscripten/mod.rs b/src/emscripten/mod.rs index 258b6df..26bd5ff 100644 --- a/src/emscripten/mod.rs +++ b/src/emscripten/mod.rs @@ -183,7 +183,7 @@ impl Endpoint { Ok( vec![ SupportedFormat { - channels: vec![::ChannelPosition::BackLeft, ::ChannelPosition::BackRight], + channels: 2, min_samples_rate: ::SamplesRate(44100), max_samples_rate: ::SamplesRate(44100), data_type: ::SampleFormat::F32, diff --git a/src/lib.rs b/src/lib.rs index c134e96..59a103d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -240,29 +240,6 @@ impl Endpoint { /// Number of channels. pub type ChannelsCount = u16; -/// Possible position of a channel. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum ChannelPosition { - FrontLeft, - FrontRight, - FrontCenter, - LowFrequency, - BackLeft, - BackRight, - FrontLeftOfCenter, - FrontRightOfCenter, - BackCenter, - SideLeft, - SideRight, - TopCenter, - TopFrontLeft, - TopFrontCenter, - TopFrontRight, - TopBackLeft, - TopBackCenter, - TopBackRight, -} - /// #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct SamplesRate(pub u32); @@ -270,7 +247,7 @@ pub struct SamplesRate(pub u32); /// Describes a format. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Format { - pub channels: Vec, + pub channels: ChannelsCount, pub samples_rate: SamplesRate, pub data_type: SampleFormat, } @@ -297,7 +274,7 @@ impl Iterator for SupportedFormatsIterator { /// Describes a range of supported formats. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SupportedFormat { - pub channels: Vec, + pub channels: ChannelsCount, /// Minimum value for the samples rate of the supported formats. pub min_samples_rate: SamplesRate, /// Maximum value for the samples rate of the supported formats. diff --git a/src/wasapi/endpoint.rs b/src/wasapi/endpoint.rs index 52e1f76..5d11b5c 100644 --- a/src/wasapi/endpoint.rs +++ b/src/wasapi/endpoint.rs @@ -7,7 +7,7 @@ use std::ptr; use std::slice; use std::sync::{Arc, Mutex, MutexGuard}; -use ChannelPosition; +use ChannelsCount; use FormatsEnumerationError; use SampleFormat; use SamplesRate; @@ -140,75 +140,11 @@ impl Endpoint { let format = { let (channels, data_type) = match (*format_ptr).wFormatTag { winapi::WAVE_FORMAT_PCM => { - (vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight], - SampleFormat::I16) + (2, SampleFormat::I16) }, winapi::WAVE_FORMAT_EXTENSIBLE => { let format_ptr = format_ptr as *const winapi::WAVEFORMATEXTENSIBLE; - - let channels = { - 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); - } - - assert_eq!((*format_ptr).Format.nChannels as usize, channels.len()); - channels - }; - + let channels = (*format_ptr).Format.nChannels as ChannelsCount; let format = { fn cmp_guid(a: &winapi::GUID, b: &winapi::GUID) -> bool { a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 && diff --git a/src/wasapi/voice.rs b/src/wasapi/voice.rs index b547784..0ebb0a3 100644 --- a/src/wasapi/voice.rs +++ b/src/wasapi/voice.rs @@ -13,7 +13,6 @@ use std::sync::Mutex; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; -use ChannelPosition; use CreationError; use Format; use SampleFormat; @@ -472,12 +471,12 @@ fn format_to_waveformatextensible(format: &Format) SampleFormat::F32 => winapi::WAVE_FORMAT_EXTENSIBLE, SampleFormat::U16 => return Err(CreationError::FormatNotSupported), }, - nChannels: format.channels.len() as winapi::WORD, + nChannels: format.channels as winapi::WORD, nSamplesPerSec: format.samples_rate.0 as winapi::DWORD, - nAvgBytesPerSec: format.channels.len() as winapi::DWORD * + nAvgBytesPerSec: format.channels as winapi::DWORD * format.samples_rate.0 as winapi::DWORD * format.data_type.sample_size() as winapi::DWORD, - nBlockAlign: format.channels.len() as winapi::WORD * + nBlockAlign: format.channels as winapi::WORD * format.data_type.sample_size() as winapi::WORD, wBitsPerSample: 8 * format.data_type.sample_size() as winapi::WORD, cbSize: match format.data_type { @@ -491,33 +490,30 @@ fn format_to_waveformatextensible(format: &Format) Samples: 8 * format.data_type.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); - } + const CHANNEL_POSITIONS: &'static [winapi::DWORD] = &[ + winapi::SPEAKER_FRONT_LEFT, + winapi::SPEAKER_FRONT_RIGHT, + winapi::SPEAKER_FRONT_CENTER, + winapi::SPEAKER_LOW_FREQUENCY, + winapi::SPEAKER_BACK_LEFT, + winapi::SPEAKER_BACK_RIGHT, + winapi::SPEAKER_FRONT_LEFT_OF_CENTER, + winapi::SPEAKER_FRONT_RIGHT_OF_CENTER, + winapi::SPEAKER_BACK_CENTER, + winapi::SPEAKER_SIDE_LEFT, + winapi::SPEAKER_SIDE_RIGHT, + winapi::SPEAKER_TOP_CENTER, + winapi::SPEAKER_TOP_FRONT_LEFT, + winapi::SPEAKER_TOP_FRONT_CENTER, + winapi::SPEAKER_TOP_FRONT_RIGHT, + winapi::SPEAKER_TOP_BACK_LEFT, + winapi::SPEAKER_TOP_BACK_CENTER, + winapi::SPEAKER_TOP_BACK_RIGHT, + ]; + for i in 0..format.channels { + let raw_value = CHANNEL_POSITIONS[i as usize]; mask = mask | raw_value; }