PureBasic Forum
https://www.purebasic.fr/english/

List all audio devices
https://www.purebasic.fr/english/viewtopic.php?f=19&t=73363
Page 1 of 1

Author:  Wolfram [ Sat Aug 10, 2019 1:49 pm ]
Post subject:  List all audio devices

List all audio devices:

Edit: version 1.1
AudioBufferList had a wrong structure.

Edit: version 1.11
AudioBufferList needs Align #PB_Structure_AlignC

Code:
;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

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/