Skip to content

Commit 9addf9d

Browse files
committed
Format, check channels
1 parent 7de3603 commit 9addf9d

File tree

4 files changed

+42
-32
lines changed

4 files changed

+42
-32
lines changed

examples/feedback_interleaved.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ fn main() -> Result<(), coreaudio::Error> {
3535

3636
let format_flag = match SAMPLE_FORMAT {
3737
SampleFormat::F32 => LinearPcmFlags::IS_FLOAT | LinearPcmFlags::IS_PACKED,
38-
SampleFormat::I32 | SampleFormat::I24_3 | SampleFormat::I16 | SampleFormat::I8 => {
38+
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
3939
LinearPcmFlags::IS_SIGNED_INTEGER | LinearPcmFlags::IS_PACKED
4040
}
41-
SampleFormat::I24_4 => LinearPcmFlags::IS_SIGNED_INTEGER,
41+
_ => {
42+
unimplemented!("Please use one of the packed formats");
43+
}
4244
};
4345

4446
let in_stream_format = StreamFormat {

examples/sine_advanced.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ extern crate coreaudio;
55
use coreaudio::audio_unit::audio_format::LinearPcmFlags;
66
use coreaudio::audio_unit::render_callback::{self, data};
77
use coreaudio::audio_unit::{
8-
audio_unit_from_device_id, get_default_device_id, get_supported_physical_stream_formats,
9-
set_device_physical_stream_format, set_device_sample_rate, AliveListener, RateListener,
10-
find_matching_physical_format,
8+
audio_unit_from_device_id, find_matching_physical_format, get_default_device_id,
9+
get_supported_physical_stream_formats, set_device_physical_stream_format,
10+
set_device_sample_rate, AliveListener, RateListener,
1111
};
1212
use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat};
1313
use coreaudio::sys::kAudioUnitProperty_StreamFormat;
@@ -62,10 +62,12 @@ fn main() -> Result<(), coreaudio::Error> {
6262

6363
let mut format_flag = match SAMPLE_FORMAT {
6464
SampleFormat::F32 => LinearPcmFlags::IS_FLOAT | LinearPcmFlags::IS_PACKED,
65-
SampleFormat::I32 | SampleFormat::I24_3 | SampleFormat::I16 | SampleFormat::I8 => {
65+
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
6666
LinearPcmFlags::IS_SIGNED_INTEGER | LinearPcmFlags::IS_PACKED
6767
}
68-
SampleFormat::I24_4 => LinearPcmFlags::IS_SIGNED_INTEGER,
68+
_ => {
69+
unimplemented!("Please use one of the packed formats");
70+
}
6971
};
7072

7173
if !INTERLEAVED {
@@ -98,12 +100,13 @@ fn main() -> Result<(), coreaudio::Error> {
98100
println!("setting hardware (physical) format");
99101
let hw_stream_format = StreamFormat {
100102
sample_rate: SAMPLE_RATE,
101-
sample_format: SampleFormat::I24_3,
103+
sample_format: SampleFormat::I24,
102104
flags: LinearPcmFlags::empty(),
103105
channels: 2,
104106
};
105107

106-
let hw_asbd = find_matching_physical_format(audio_unit_id, hw_stream_format).unwrap();
108+
let hw_asbd = find_matching_physical_format(audio_unit_id, hw_stream_format)
109+
.ok_or(coreaudio::Error::UnsupportedStreamFormat)?;
107110

108111
println!("asbd: {:?}", hw_asbd);
109112

src/audio_unit/macos_helpers.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ use sys::{
2424
kCFStringEncodingUTF8, AudioDeviceID, AudioObjectAddPropertyListener,
2525
AudioObjectGetPropertyData, AudioObjectGetPropertyDataSize, AudioObjectID,
2626
AudioObjectPropertyAddress, AudioObjectRemovePropertyListener, AudioObjectSetPropertyData,
27-
AudioStreamBasicDescription, AudioValueRange, OSStatus, AudioStreamRangedDescription,
27+
AudioStreamBasicDescription, AudioStreamRangedDescription, AudioValueRange, OSStatus,
2828
};
2929

3030
use crate::audio_unit::audio_format::{AudioFormat, LinearPcmFlags};
31-
use crate::audio_unit::{AudioUnit, Element, IOType, Scope};
32-
use crate::audio_unit::stream_format::StreamFormat;
3331
use crate::audio_unit::sample_format::SampleFormat;
32+
use crate::audio_unit::stream_format::StreamFormat;
33+
use crate::audio_unit::{AudioUnit, Element, IOType, Scope};
3434

3535
/// Helper function to get the device id of the default input or output device
3636
/// Only implemented for macOS, not iOS.
@@ -332,29 +332,39 @@ pub fn find_matching_physical_format(
332332
let wanted_samplerate = stream_format.sample_rate as usize;
333333
let wanted_bits = stream_format.sample_format.size_in_bits();
334334
let wanted_float = stream_format.sample_format == SampleFormat::F32;
335+
let wanted_channels = stream_format.channels;
335336
for fmt in all_formats {
336337
let minrate = fmt.mSampleRateRange.mMinimum as usize;
337338
let maxrate = fmt.mSampleRateRange.mMaximum as usize;
338339
let rate = fmt.mFormat.mSampleRate as usize;
339-
if let Some(AudioFormat::LinearPCM(flags)) = AudioFormat::from_format_and_flag(fmt.mFormat.mFormatID, Some(fmt.mFormat.mFormatFlags)) {
340+
let channels = fmt.mFormat.mChannelsPerFrame;
341+
if let Some(AudioFormat::LinearPCM(flags)) = AudioFormat::from_format_and_flag(
342+
fmt.mFormat.mFormatID,
343+
Some(fmt.mFormat.mFormatFlags),
344+
) {
340345
let floats = flags.contains(LinearPcmFlags::IS_FLOAT);
341-
let ints = flags.contains(LinearPcmFlags::IS_SIGNED_INTEGER);
342-
if wanted_float != floats || wanted_float == ints {
346+
let ints = flags.contains(LinearPcmFlags::IS_SIGNED_INTEGER);
347+
if wanted_float != floats || wanted_float == ints {
343348
// Wrong number type
344349
continue;
345-
}
350+
}
346351
if wanted_bits != fmt.mFormat.mBitsPerChannel {
347352
// Wrong number of bits
348353
continue;
349354
}
350-
if rate == wanted_samplerate || (wanted_samplerate >= minrate && wanted_samplerate <= maxrate) {
355+
if wanted_channels > channels {
356+
// Too few channels
357+
continue;
358+
}
359+
if rate == wanted_samplerate
360+
|| (wanted_samplerate >= minrate && wanted_samplerate <= maxrate)
361+
{
351362
return Some(fmt.mFormat);
352363
}
353-
354364
}
355365
}
356366
}
357-
return None
367+
return None;
358368
}
359369

360370
/// Change the physical stream format (sample rate and format) of a device.

src/audio_unit/sample_format.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ pub enum SampleFormat {
77
F32,
88
/// 32-bit signed integer.
99
I32,
10-
/// 24-bit signed integer, packed in 3 bytes.
11-
I24_3,
12-
/// 24-bit signed integer, stored in 4 bytes where one is padding.
13-
I24_4,
10+
/// 24-bit signed integer. Can be packed or not depending on the flags.
11+
I24,
1412
/// 16-bit signed integer.
1513
I16,
1614
/// 8-bit signed integer.
@@ -25,10 +23,10 @@ impl SampleFormat {
2523
let is_packed = flags.contains(LinearPcmFlags::IS_PACKED);
2624
match *self {
2725
SampleFormat::F32 => is_float && !is_signed_integer && is_packed,
28-
SampleFormat::I32 | SampleFormat::I24_3 | SampleFormat::I16 | SampleFormat::I8 => {
26+
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
2927
is_signed_integer && !is_float && is_packed
3028
}
31-
SampleFormat::I24_4 => is_signed_integer && !is_float && !is_packed,
29+
SampleFormat::I24 => is_signed_integer && !is_float,
3230
}
3331
}
3432

@@ -47,8 +45,7 @@ impl SampleFormat {
4745
match (bits_per_sample, packed) {
4846
(8, true) => SampleFormat::I8,
4947
(16, true) => SampleFormat::I16,
50-
(24, true) => SampleFormat::I24_3,
51-
(24, false) => SampleFormat::I24_4,
48+
(24, _) => SampleFormat::I24,
5249
(32, true) => SampleFormat::I32,
5350
_ => return None,
5451
}
@@ -59,14 +56,13 @@ impl SampleFormat {
5956
Some(sample_format)
6057
}
6158

62-
/// Return the size of one sample in bytes.
59+
/// Return the size of one sample in bytes, assuming that the format is packed.
6360
pub fn size_in_bytes(&self) -> usize {
6461
use std::mem::size_of;
6562
match *self {
6663
SampleFormat::F32 => size_of::<f32>(),
6764
SampleFormat::I32 => size_of::<i32>(),
68-
SampleFormat::I24_3 => 3 * size_of::<u8>(),
69-
SampleFormat::I24_4 => 4 * size_of::<u8>(),
65+
SampleFormat::I24 => 3 * size_of::<u8>(),
7066
SampleFormat::I16 => size_of::<i16>(),
7167
SampleFormat::I8 => size_of::<i8>(),
7268
}
@@ -77,8 +73,7 @@ impl SampleFormat {
7773
match *self {
7874
SampleFormat::F32 => 32,
7975
SampleFormat::I32 => 32,
80-
SampleFormat::I24_3 => 24,
81-
SampleFormat::I24_4 => 24,
76+
SampleFormat::I24 => 24,
8277
SampleFormat::I16 => 16,
8378
SampleFormat::I8 => 8,
8479
}

0 commit comments

Comments
 (0)