List all audio devices

Mac OSX specific forum
Wolfram
Enthusiast
Enthusiast
Posts: 567
Joined: Thu May 30, 2013 4:39 pm

List all audio devices

Post by Wolfram »

List all audio devices:

Edit: version 1.1
AudioBufferList had a wrong structure.

Edit: version 1.11
AudioBufferList needs Align #PB_Structure_AlignC

Code: Select all

;Version 1.11

ImportC "-framework CoreAudio"
  AudioObjectGetPropertyDataSize(kAudioObjectSystemObject.i, *propertyAddress, inQualifierDataSize.l, *inQualifierData, *dataSize)
  AudioObjectGetPropertyData(kAudioObjectSystemObject.i, *propertyAddress, inQualifierDataSize.l, *inQualifierData, *dataSize, *outData)
EndImport

ImportC "-framework CoreServices"
  CFStringCreateWithCString(alloc, cStr.p-utf8, encoding = $8000100)  
  MDItemCopyAttribute(item, name)
  MDItemCreate(allocator, path)
  CFRelease(cf)
EndImport


Procedure.s getCFString(CFStringRef.i)
  If CFStringRef
    ProcedureReturn PeekS(CocoaMessage(0, CFStringRef, "UTF8String"), -1, #PB_UTF8)
  Else
    ProcedureReturn ""
  EndIf
EndProcedure


#kAudioHardwarePropertyDevices = $64657623 ;'dev#' 64657623
#kAudioObjectPropertyScopeGlobal = $676C6F62 ;'glob'
#kAudioObjectPropertyScopeInput = $696E7074 ;'inpt'
#kAudioDevicePropertyScopeInput = #kAudioObjectPropertyScopeInput
#kAudioObjectPropertyScopeOutput = $6F757470 ;'outp'
#kAudioDevicePropertyScopeOutput = #kAudioObjectPropertyScopeOutput
#kAudioObjectPropertyElementMaster = 0

#kAudioDevicePropertyDeviceName = $6E616D65 ;'name'
#kAudioDevicePropertyDeviceManufacturer = $6D616B72 ;'makr'
#kAudioDevicePropertyDeviceUID = $75696420 ;'uid '
#kAudioObjectPropertyName = $6C6E616D ;'lnam'
#kAudioDevicePropertyDeviceNameCFString = #kAudioObjectPropertyName
#kAudioDevicePropertyStreamConfiguration = $736C6179 ;'slay'

#kAudioObjectSystemObject = 1

#noError =0


Structure AudioObjectPropertyAddress ;Align #PB_Structure_AlignC
  mSelector.l
  mScope.l
  mElement.l
EndStructure

Structure AudioBuffer
  mNumberChannels.l
  mDataByteSize.l
  mData.i
EndStructure

Structure AudioBufferList Align #PB_Structure_AlignC
  mNumberBuffers.l
  mBuffers.AudioBuffer[0]
EndStructure

Structure audioDeviceStruc
  deviceName.s{64}
  channelCount.l
  deviceID.l
EndStructure


Procedure getAudioPorts(type.l, List deviceList.audioDeviceStruc())
  deviceAddress.AudioObjectPropertyAddress
  deviceAddress\mSelector =#kAudioHardwarePropertyDevices
  deviceAddress\mScope = #kAudioObjectPropertyScopeGlobal
  deviceAddress\mElement = #kAudioObjectPropertyElementMaster
  
  Protected dataSize.l = 0
  Protected AudioDeviceID.l
  
  AudioObjectGetPropertyDataSize(#kAudioObjectSystemObject, @deviceAddress, 0, #Null, @dataSize)
  
  deviceCount.l = dataSize / SizeOf(AudioDeviceID)
  Dim deviceIDs.l(deviceCount)
  
  AudioObjectGetPropertyData(#kAudioObjectSystemObject, @deviceAddress, 0, #Null, @dataSize, @deviceIDs())
  
  
  Dim deviceName.a(63)
  Dim manufacturerName.a(63)
  

  deviceCount -1
  For i =0 To deviceCount
    
    dataSize = 0
    deviceAddress\mSelector = #kAudioDevicePropertyStreamConfiguration
    deviceAddress\mScope = type
    
    AudioObjectGetPropertyDataSize(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize)
    
    If dataSize > 4
      Dim audioBufferList.a(dataSize)
      *ABL.AudioBufferList = @audioBufferList()
      AudioObjectGetPropertyData(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize, *ABL)
      
      
      Protected channelCount =0
      Protected id =0
      Repeat 
        
        channelCount +*ABL\mBuffers[id]\mNumberChannels
        id +1
      Until id >= *ABL\mNumberBuffers
      
      
      dataSize = ArraySize(deviceName())
      deviceAddress\mSelector = #kAudioDevicePropertyDeviceName
      deviceAddress\mScope = #kAudioObjectPropertyScopeGlobal
      
      If AudioObjectGetPropertyData(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize, @deviceName()) = #noError
        Debug PeekS(@deviceName(), -1, #PB_UTF8)
        
        dataSize = ArraySize(manufacturerName())
        deviceAddress\mSelector = #kAudioDevicePropertyDeviceManufacturer
        
        If AudioObjectGetPropertyData(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize, @manufacturerName()) = #noError
          
          
          Protected uidString.i
          dataSize = SizeOf(uidString)
          deviceAddress\mSelector = #kAudioDevicePropertyDeviceUID
          
          If AudioObjectGetPropertyData(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize, @uidString) = #noError
            
            Debug getCFString(uidString)
            CFRelease(uidString)
            
            
            Protected name.i
            dataSize = SizeOf(name)
            deviceAddress\mSelector = #kAudioDevicePropertyDeviceNameCFString
            
            If AudioObjectGetPropertyData(deviceIDs(i), @deviceAddress, 0, #Null, @dataSize, @name)  = #noError
              
              AddElement(deviceList())
              deviceList()\channelCount = channelCount
              deviceList()\deviceName =""
              deviceList()\deviceName = getCFString(name)
              deviceList()\deviceID = deviceIDs(i)
              
              CFRelease(name)
            EndIf
            
          EndIf
          
        EndIf
        
      EndIf
      
    EndIf
  Next
EndProcedure


;-Test
NewList audioInDevices.audioDeviceStruc()

getAudioPorts(#kAudioDevicePropertyScopeInput, audioInDevices())

NewList audioOutDevices.audioDeviceStruc()

getAudioPorts(#kAudioDevicePropertyScopeOutput, audioOutDevices())

Debug "->Inputs:"
ForEach audioInDevices()
  Debug "Device: " +audioInDevices()\deviceName +" - " +Str(audioInDevices()\channelCount) +"Ch - ID-" +Str(audioInDevices()\deviceID)
Next

Debug "<-Outpouts:"
ForEach audioOutDevices()
  Debug "Device: " +audioOutDevices()\deviceName +" - " +Str(audioOutDevices()\channelCount) +"Ch - ID-" +Str(audioOutDevices()\deviceID)
Next
macOS Catalina 10.15.7