@@ -354,7 +354,7 @@ pub fn test_device_channels_in_scope(
354
354
) -> std:: result:: Result < u32 , OSStatus > {
355
355
debug_assert_not_running_serially ( ) ;
356
356
let address = AudioObjectPropertyAddress {
357
- mSelector : kAudioDevicePropertyStreamConfiguration ,
357
+ mSelector : kAudioDevicePropertyStreams ,
358
358
mScope : match scope {
359
359
Scope :: Input => kAudioDevicePropertyScopeInput,
360
360
Scope :: Output => kAudioDevicePropertyScopeOutput,
@@ -377,32 +377,71 @@ pub fn test_device_channels_in_scope(
377
377
if size == 0 {
378
378
return Ok ( 0 ) ;
379
379
}
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 ] ;
382
381
let status = run_serially ( || unsafe {
383
382
AudioObjectGetPropertyData (
384
383
id,
385
384
& address,
386
385
0 ,
387
386
ptr:: null ( ) ,
388
387
& 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 ,
390
389
)
391
390
} ) ;
392
391
if status != NO_ERR {
393
392
return Err ( status) ;
394
393
}
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 ( ) ;
406
445
Ok ( channels)
407
446
}
408
447
0 commit comments