Skip to content

Commit f30df52

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 those input streams when counting channels.
1 parent 24796b6 commit f30df52

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/backend/tests/utils.rs

+52-15
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ pub fn test_device_channels_in_scope(
338338
scope: Scope,
339339
) -> std::result::Result<u32, OSStatus> {
340340
let address = AudioObjectPropertyAddress {
341-
mSelector: kAudioDevicePropertyStreamConfiguration,
341+
mSelector: kAudioDevicePropertyStreams,
342342
mScope: match scope {
343343
Scope::Input => kAudioDevicePropertyScopeInput,
344344
Scope::Output => kAudioDevicePropertyScopeOutput,
@@ -361,32 +361,69 @@ pub fn test_device_channels_in_scope(
361361
if size == 0 {
362362
return Ok(0);
363363
}
364-
let byte_len = size / mem::size_of::<u8>();
365-
let mut bytes = vec![0u8; byte_len];
364+
let mut stream_list = vec![0, (size / mem::size_of::<AudioObjectID>()) as u32];
366365
let status = unsafe {
367366
AudioObjectGetPropertyData(
368367
id,
369368
&address,
370369
0,
371370
ptr::null(),
372371
&mut size as *mut usize as *mut u32,
373-
bytes.as_mut_ptr() as *mut c_void,
372+
stream_list.as_mut_ptr() as *mut c_void,
374373
)
375374
};
376375
if status != NO_ERR {
377376
return Err(status);
378377
}
379-
let buf_list = unsafe { &*(bytes.as_mut_ptr() as *mut AudioBufferList) };
380-
let buf_len = buf_list.mNumberBuffers as usize;
381-
if buf_len == 0 {
382-
return Ok(0);
383-
}
384-
let buf_ptr = buf_list.mBuffers.as_ptr() as *const AudioBuffer;
385-
let buffers = unsafe { slice::from_raw_parts(buf_ptr, buf_len) };
386-
let mut channels: u32 = 0;
387-
for buffer in buffers {
388-
channels += buffer.mNumberChannels;
389-
}
378+
let channels = stream_list
379+
.iter()
380+
.filter(|s: &&AudioObjectID| {
381+
if scope == Scope::Input {
382+
let address = AudioObjectPropertyAddress {
383+
mSelector: kAudioStreamPropertyTerminalType,
384+
mScope: kAudioObjectPropertyScopeGlobal,
385+
mElement: kAudioObjectPropertyElementMaster,
386+
};
387+
let mut ttype: u32 = 0;
388+
let status = unsafe {
389+
AudioObjectGetPropertyData(
390+
**s,
391+
&address,
392+
0,
393+
ptr::null(),
394+
&mut mem::size_of::<u32>() as *mut usize as *mut u32,
395+
&mut ttype as *mut u32 as *mut c_void,
396+
)
397+
};
398+
return status == NO_ERR
399+
&& ttype != kAudioStreamTerminalTypeUnknown
400+
&& ttype != INPUT_UNDEFINED;
401+
}
402+
true
403+
})
404+
.map(|s: &AudioObjectID| {
405+
let address = AudioObjectPropertyAddress {
406+
mSelector: kAudioStreamPropertyVirtualFormat,
407+
mScope: kAudioObjectPropertyScopeGlobal,
408+
mElement: kAudioObjectPropertyElementMaster,
409+
};
410+
let mut format = AudioStreamBasicDescription::default();
411+
let status = unsafe {
412+
AudioObjectGetPropertyData(
413+
*s,
414+
&address,
415+
0,
416+
ptr::null(),
417+
&mut mem::size_of::<AudioStreamBasicDescription>() as *mut usize as *mut u32,
418+
&mut format as *mut AudioStreamBasicDescription as *mut c_void,
419+
)
420+
};
421+
if status != NO_ERR {
422+
return 0;
423+
}
424+
format.mChannelsPerFrame
425+
})
426+
.sum();
390427
Ok(channels)
391428
}
392429

0 commit comments

Comments
 (0)