Remove unused `ChannelPosition` API (update all backends and examples accordingly) (#198)
* Remove ChannelPosition API This removes the ChannelPosition API from the lib root and updates the ALSA backend and examples accordingly. The other backends have not yet been updated. Related discussion at #187. * Update windows backend to removal of ChannelPosition API The windows backend now assumes the channel position order is equal to the channel position mask order. E.g. channel 0 will always be front left, channel 1 will always be front right, etc. Compiled and ran both examples successfully. * Update coreaudio backend to removal of ChannelPosition API Compiled and ran both examples successfully. * Update emscriptem backend for removal of ChannelPosition API * Update CHANGELOG for ChannelPosition removal
This commit is contained in:
parent
6bf65f589d
commit
f2728f6bdf
|
@ -1,5 +1,6 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- Remove unused ChannelPosition API.
|
||||||
- Implement Endpoint and Format Enumeration for macos.
|
- Implement Endpoint and Format Enumeration for macos.
|
||||||
- Implement format handling for macos `build_voice` method.
|
- Implement format handling for macos `build_voice` method.
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ fn main() {
|
||||||
event_loop.run(move |_, buffer| {
|
event_loop.run(move |_, buffer| {
|
||||||
match buffer {
|
match buffer {
|
||||||
cpal::UnknownTypeBuffer::U16(mut 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;
|
let value = ((next_value() * 0.5 + 0.5) * std::u16::MAX as f32) as u16;
|
||||||
for out in sample.iter_mut() {
|
for out in sample.iter_mut() {
|
||||||
*out = value;
|
*out = value;
|
||||||
|
@ -34,7 +34,7 @@ fn main() {
|
||||||
},
|
},
|
||||||
|
|
||||||
cpal::UnknownTypeBuffer::I16(mut buffer) => {
|
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;
|
let value = (next_value() * std::i16::MAX as f32) as i16;
|
||||||
for out in sample.iter_mut() {
|
for out in sample.iter_mut() {
|
||||||
*out = value;
|
*out = value;
|
||||||
|
@ -43,7 +43,7 @@ fn main() {
|
||||||
},
|
},
|
||||||
|
|
||||||
cpal::UnknownTypeBuffer::F32(mut buffer) => {
|
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();
|
let value = next_value();
|
||||||
for out in sample.iter_mut() {
|
for out in sample.iter_mut() {
|
||||||
*out = value;
|
*out = value;
|
||||||
|
|
|
@ -3,7 +3,7 @@ extern crate libc;
|
||||||
|
|
||||||
pub use self::enumerate::{EndpointsIterator, default_endpoint};
|
pub use self::enumerate::{EndpointsIterator, default_endpoint};
|
||||||
|
|
||||||
use ChannelPosition;
|
use ChannelsCount;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use Format;
|
use Format;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
|
@ -206,19 +206,7 @@ impl Endpoint {
|
||||||
num,
|
num,
|
||||||
) == 0
|
) == 0
|
||||||
{
|
{
|
||||||
Some(
|
Some(num as ChannelsCount)
|
||||||
[
|
|
||||||
ChannelPosition::FrontLeft,
|
|
||||||
ChannelPosition::FrontRight,
|
|
||||||
ChannelPosition::BackLeft,
|
|
||||||
ChannelPosition::BackRight,
|
|
||||||
ChannelPosition::FrontCenter,
|
|
||||||
ChannelPosition::LowFrequency,
|
|
||||||
].iter()
|
|
||||||
.take(num as usize)
|
|
||||||
.cloned()
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
|
@ -569,11 +557,11 @@ impl EventLoop {
|
||||||
.expect("sample rate could not be set");
|
.expect("sample rate could not be set");
|
||||||
check_errors(alsa::snd_pcm_hw_params_set_channels(playback_handle,
|
check_errors(alsa::snd_pcm_hw_params_set_channels(playback_handle,
|
||||||
hw_params.0,
|
hw_params.0,
|
||||||
format.channels.len() as
|
format.channels as
|
||||||
libc::c_uint))
|
libc::c_uint))
|
||||||
.expect("channel count could not be set");
|
.expect("channel count could not be set");
|
||||||
let mut max_buffer_size = format.samples_rate.0 as alsa::snd_pcm_uframes_t /
|
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
|
5; // 200ms of buffer
|
||||||
check_errors(alsa::snd_pcm_hw_params_set_buffer_size_max(playback_handle,
|
check_errors(alsa::snd_pcm_hw_params_set_buffer_size_max(playback_handle,
|
||||||
hw_params.0,
|
hw_params.0,
|
||||||
|
@ -602,8 +590,8 @@ impl EventLoop {
|
||||||
sw_params,
|
sw_params,
|
||||||
period))
|
period))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let buffer = buffer as usize * format.channels.len();
|
let buffer = buffer as usize * format.channels as usize;
|
||||||
let period = period as usize * format.channels.len();
|
let period = period as usize * format.channels as usize;
|
||||||
(buffer, period)
|
(buffer, period)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -625,7 +613,7 @@ impl EventLoop {
|
||||||
channel: playback_handle,
|
channel: playback_handle,
|
||||||
sample_format: format.data_type,
|
sample_format: format.data_type,
|
||||||
num_descriptors: num_descriptors,
|
num_descriptors: num_descriptors,
|
||||||
num_channels: format.channels.len() as u16,
|
num_channels: format.channels as u16,
|
||||||
buffer_len: buffer_len,
|
buffer_len: buffer_len,
|
||||||
period_len: period_len,
|
period_len: period_len,
|
||||||
can_pause: can_pause,
|
can_pause: can_pause,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
extern crate coreaudio;
|
extern crate coreaudio;
|
||||||
extern crate core_foundation_sys;
|
extern crate core_foundation_sys;
|
||||||
|
|
||||||
use ChannelPosition;
|
use ChannelsCount;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use Format;
|
use Format;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
|
@ -108,26 +108,6 @@ impl Endpoint {
|
||||||
for buffer in buffers {
|
for buffer in buffers {
|
||||||
n_channels += buffer.mNumberChannels as usize;
|
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
|
// 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.
|
// fix this if more pcm formats are supported.
|
||||||
|
@ -170,13 +150,8 @@ impl Endpoint {
|
||||||
// Collect the supported formats for the device.
|
// Collect the supported formats for the device.
|
||||||
let mut fmts = vec![];
|
let mut fmts = vec![];
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
let channels = CHANNEL_POSITIONS.iter()
|
|
||||||
.cloned()
|
|
||||||
.cycle()
|
|
||||||
.take(n_channels)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let fmt = SupportedFormat {
|
let fmt = SupportedFormat {
|
||||||
channels: channels.clone(),
|
channels: n_channels as ChannelsCount,
|
||||||
min_samples_rate: SamplesRate(range.mMinimum as _),
|
min_samples_rate: SamplesRate(range.mMinimum as _),
|
||||||
max_samples_rate: SamplesRate(range.mMaximum as _),
|
max_samples_rate: SamplesRate(range.mMaximum as _),
|
||||||
data_type: sample_format,
|
data_type: sample_format,
|
||||||
|
@ -306,7 +281,7 @@ impl EventLoop {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Set the stream in interleaved mode.
|
// 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 sample_rate = format.samples_rate.0;
|
||||||
let bytes_per_channel = format.data_type.sample_size();
|
let bytes_per_channel = format.data_type.sample_size();
|
||||||
let bits_per_channel = bytes_per_channel * 8;
|
let bits_per_channel = bytes_per_channel * 8;
|
||||||
|
|
|
@ -183,7 +183,7 @@ impl Endpoint {
|
||||||
Ok(
|
Ok(
|
||||||
vec![
|
vec![
|
||||||
SupportedFormat {
|
SupportedFormat {
|
||||||
channels: vec![::ChannelPosition::BackLeft, ::ChannelPosition::BackRight],
|
channels: 2,
|
||||||
min_samples_rate: ::SamplesRate(44100),
|
min_samples_rate: ::SamplesRate(44100),
|
||||||
max_samples_rate: ::SamplesRate(44100),
|
max_samples_rate: ::SamplesRate(44100),
|
||||||
data_type: ::SampleFormat::F32,
|
data_type: ::SampleFormat::F32,
|
||||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -240,29 +240,6 @@ impl Endpoint {
|
||||||
/// Number of channels.
|
/// Number of channels.
|
||||||
pub type ChannelsCount = u16;
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct SamplesRate(pub u32);
|
pub struct SamplesRate(pub u32);
|
||||||
|
@ -270,7 +247,7 @@ pub struct SamplesRate(pub u32);
|
||||||
/// Describes a format.
|
/// Describes a format.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Format {
|
pub struct Format {
|
||||||
pub channels: Vec<ChannelPosition>,
|
pub channels: ChannelsCount,
|
||||||
pub samples_rate: SamplesRate,
|
pub samples_rate: SamplesRate,
|
||||||
pub data_type: SampleFormat,
|
pub data_type: SampleFormat,
|
||||||
}
|
}
|
||||||
|
@ -297,7 +274,7 @@ impl Iterator for SupportedFormatsIterator {
|
||||||
/// Describes a range of supported formats.
|
/// Describes a range of supported formats.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct SupportedFormat {
|
pub struct SupportedFormat {
|
||||||
pub channels: Vec<ChannelPosition>,
|
pub channels: ChannelsCount,
|
||||||
/// Minimum value for the samples rate of the supported formats.
|
/// Minimum value for the samples rate of the supported formats.
|
||||||
pub min_samples_rate: SamplesRate,
|
pub min_samples_rate: SamplesRate,
|
||||||
/// Maximum value for the samples rate of the supported formats.
|
/// Maximum value for the samples rate of the supported formats.
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
use ChannelPosition;
|
use ChannelsCount;
|
||||||
use FormatsEnumerationError;
|
use FormatsEnumerationError;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
use SamplesRate;
|
use SamplesRate;
|
||||||
|
@ -140,75 +140,11 @@ impl Endpoint {
|
||||||
let format = {
|
let format = {
|
||||||
let (channels, data_type) = match (*format_ptr).wFormatTag {
|
let (channels, data_type) = match (*format_ptr).wFormatTag {
|
||||||
winapi::WAVE_FORMAT_PCM => {
|
winapi::WAVE_FORMAT_PCM => {
|
||||||
(vec![ChannelPosition::FrontLeft, ChannelPosition::FrontRight],
|
(2, SampleFormat::I16)
|
||||||
SampleFormat::I16)
|
|
||||||
},
|
},
|
||||||
winapi::WAVE_FORMAT_EXTENSIBLE => {
|
winapi::WAVE_FORMAT_EXTENSIBLE => {
|
||||||
let format_ptr = format_ptr as *const winapi::WAVEFORMATEXTENSIBLE;
|
let format_ptr = format_ptr as *const winapi::WAVEFORMATEXTENSIBLE;
|
||||||
|
let channels = (*format_ptr).Format.nChannels as ChannelsCount;
|
||||||
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 format = {
|
let format = {
|
||||||
fn cmp_guid(a: &winapi::GUID, b: &winapi::GUID) -> bool {
|
fn cmp_guid(a: &winapi::GUID, b: &winapi::GUID) -> bool {
|
||||||
a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 &&
|
a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 &&
|
||||||
|
|
|
@ -13,7 +13,6 @@ use std::sync::Mutex;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ChannelPosition;
|
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use Format;
|
use Format;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
|
@ -472,12 +471,12 @@ fn format_to_waveformatextensible(format: &Format)
|
||||||
SampleFormat::F32 => winapi::WAVE_FORMAT_EXTENSIBLE,
|
SampleFormat::F32 => winapi::WAVE_FORMAT_EXTENSIBLE,
|
||||||
SampleFormat::U16 => return Err(CreationError::FormatNotSupported),
|
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,
|
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.samples_rate.0 as winapi::DWORD *
|
||||||
format.data_type.sample_size() 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,
|
format.data_type.sample_size() as winapi::WORD,
|
||||||
wBitsPerSample: 8 * format.data_type.sample_size() as winapi::WORD,
|
wBitsPerSample: 8 * format.data_type.sample_size() as winapi::WORD,
|
||||||
cbSize: match format.data_type {
|
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,
|
Samples: 8 * format.data_type.sample_size() as winapi::WORD,
|
||||||
dwChannelMask: {
|
dwChannelMask: {
|
||||||
let mut mask = 0;
|
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
|
const CHANNEL_POSITIONS: &'static [winapi::DWORD] = &[
|
||||||
if raw_value <= mask {
|
winapi::SPEAKER_FRONT_LEFT,
|
||||||
return Err(CreationError::FormatNotSupported);
|
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;
|
mask = mask | raw_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue