Skip to content

Commit 6bef031

Browse files
committed
Make tests terminaltype-aware when counting channels
With vpio priming devices may be queried for channel count with a vpio unit around, where they previously wouldn't. The vpio unit existing means output devices may list an extra (input) tap stream. This patch filters out away streams having anything but the most common input terminal types.
1 parent 8b5e02a commit 6bef031

File tree

1 file changed

+54
-15
lines changed

1 file changed

+54
-15
lines changed

src/backend/tests/utils.rs

+54-15
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ pub fn test_device_channels_in_scope(
354354
) -> std::result::Result<u32, OSStatus> {
355355
debug_assert_not_running_serially();
356356
let address = AudioObjectPropertyAddress {
357-
mSelector: kAudioDevicePropertyStreamConfiguration,
357+
mSelector: kAudioDevicePropertyStreams,
358358
mScope: match scope {
359359
Scope::Input => kAudioDevicePropertyScopeInput,
360360
Scope::Output => kAudioDevicePropertyScopeOutput,
@@ -377,32 +377,71 @@ pub fn test_device_channels_in_scope(
377377
if size == 0 {
378378
return Ok(0);
379379
}
380-
let byte_len = size / mem::size_of::<u8>();
381-
let mut bytes = vec![0u8; byte_len];
380+
let mut stream_list = vec![0, (size / mem::size_of::<AudioObjectID>()) as u32];
382381
let status = run_serially(|| unsafe {
383382
AudioObjectGetPropertyData(
384383
id,
385384
&address,
386385
0,
387386
ptr::null(),
388387
&mut size as *mut usize as *mut u32,
389-
bytes.as_mut_ptr() as *mut c_void,
388+
stream_list.as_mut_ptr() as *mut c_void,
390389
)
391390
});
392391
if status != NO_ERR {
393392
return Err(status);
394393
}
395-
let buf_list = unsafe { &*(bytes.as_mut_ptr() as *mut AudioBufferList) };
396-
let buf_len = buf_list.mNumberBuffers as usize;
397-
if buf_len == 0 {
398-
return Ok(0);
399-
}
400-
let buf_ptr = buf_list.mBuffers.as_ptr() as *const AudioBuffer;
401-
let buffers = unsafe { slice::from_raw_parts(buf_ptr, buf_len) };
402-
let mut channels: u32 = 0;
403-
for buffer in buffers {
404-
channels += buffer.mNumberChannels;
405-
}
394+
let channels = stream_list
395+
.iter()
396+
.filter(|s: &&AudioObjectID| {
397+
if scope != Scope::Input {
398+
return true;
399+
}
400+
let address = AudioObjectPropertyAddress {
401+
mSelector: kAudioStreamPropertyTerminalType,
402+
mScope: kAudioObjectPropertyScopeGlobal,
403+
mElement: kAudioObjectPropertyElementMaster,
404+
};
405+
let mut ttype: u32 = 0;
406+
let status = unsafe {
407+
AudioObjectGetPropertyData(
408+
**s,
409+
&address,
410+
0,
411+
ptr::null(),
412+
&mut mem::size_of::<u32>() as *mut usize as *mut u32,
413+
&mut ttype as *mut u32 as *mut c_void,
414+
)
415+
};
416+
if status != NO_ERR {
417+
return false;
418+
}
419+
ttype == kAudioStreamTerminalTypeMicrophone
420+
|| (INPUT_MICROPHONE..OUTPUT_UNDEFINED).contains(&ttype)
421+
})
422+
.map(|s: &AudioObjectID| {
423+
let address = AudioObjectPropertyAddress {
424+
mSelector: kAudioStreamPropertyVirtualFormat,
425+
mScope: kAudioObjectPropertyScopeGlobal,
426+
mElement: kAudioObjectPropertyElementMaster,
427+
};
428+
let mut format = AudioStreamBasicDescription::default();
429+
let status = unsafe {
430+
AudioObjectGetPropertyData(
431+
*s,
432+
&address,
433+
0,
434+
ptr::null(),
435+
&mut mem::size_of::<AudioStreamBasicDescription>() as *mut usize as *mut u32,
436+
&mut format as *mut AudioStreamBasicDescription as *mut c_void,
437+
)
438+
};
439+
if status != NO_ERR {
440+
return 0;
441+
}
442+
format.mChannelsPerFrame
443+
})
444+
.sum();
406445
Ok(channels)
407446
}
408447

0 commit comments

Comments
 (0)