Skip to content

Instantly share code, notes, and snippets.

@lawkaita
Created April 18, 2024 17:38
Show Gist options
  • Save lawkaita/59fb343c654a8c78fff5873c52aa71a0 to your computer and use it in GitHub Desktop.
Save lawkaita/59fb343c654a8c78fff5873c52aa71a0 to your computer and use it in GitHub Desktop.
Get the device index of the default playback or capture device, to be used with ahk Sound Functions.
#Requires AutoHotkey v2
SoundGetDefaultDeviceIndex(desc := 'playback') {
; based on this post in the AutoHotkey discord
; https://discord.com/channels/115993023636176902/1175025590936543283/1175136154132156526
; and this line in the AutoHotkey source code
; https://github.com/AutoHotkey/AutoHotkey/blob/59f219a111a34b21529c7acf5026e11650a06fbc/source/lib/sound.cpp#L96
static CLSID_MMDeviceEnumerator := "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
, IID_IMMDeviceEnumerator := "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
, S_OK := 0
, VT_UNKNOWN := 0xD
, eRender := 0
, eCapture := 1
, eAll := 2
, DEVICE_STATE_ACTIVE := 0x00000001
, DEVICE_STATE_UNPLUGGED := 0x00000008
, VFTI_IMMDeviceEnumerator_GetDefaultAudioEndPoint := 4
, VFTI_IMMDeviceEnumerator_EnumAudioEndPoints := 3
, VFTI_IMMDeviceCollection_GetCount := 3
, VFTI_IMMDeviceCollection_Item := 4
, VFTI_IMMDevice_GetId := 5
if desc = 'playback'
eDataFlow := eRender
else if desc = 'capture'
eDataFlow := eCapture
else
Throw ValueError("Invalid description", -1, desc)
IMMDeviceEnumerator := ComObject(CLSID_MMDeviceEnumerator, IID_IMMDeviceEnumerator)
IMMDeviceCollection := ComValue(VT_UNKNOWN, 0)
IMMDevice := ComValue(VT_UNKNOWN, 0)
result := ComCall(VFTI_IMMDeviceEnumerator_GetDefaultAudioEndPoint
, IMMDeviceEnumerator, "Uint", eDataFlow, "Uint", Role := 0, "Ptr*", IMMDevice)
if (result != S_OK) {
throw Error("IMMDeviceEnumerator::GetDefaultAudioEndPoint()", -1, result)
}
result := ComCall(VFTI_IMMDevice_GetId, IMMDevice, "Str*", &defaultDevId)
if (result != S_OK) {
throw Error("IMMDevice::GetId()", -1, result)
}
result := ComCall(VFTI_IMMDeviceEnumerator_EnumAudioEndPoints
, IMMDeviceEnumerator, "UInt", eAll, "UInt", DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, "Ptr*", IMMDeviceCollection)
if (result != S_OK) {
throw Error("IMMDeviceEnumerator::EnumAudioEndpoints()", -1, result)
}
count := 0
result := ComCall(VFTI_IMMDeviceCollection_GetCount, IMMDeviceCollection, "UInt*", &count)
if (result != S_OK) {
throw Error("IMMDeviceCollection::GetCount()", -1, result)
}
loop (count) {
IMMDevice := ComValue(VT_UNKNOWN, 0)
result := ComCall(VFTI_IMMDeviceCollection_Item, IMMDeviceCollection, "UInt", A_Index - 1, "Ptr*", IMMDevice)
if (result != S_OK) {
throw Error("IMMDeviceCollection::Item()", -1, result)
}
result := ComCall(VFTI_IMMDevice_GetId, IMMDevice, "Str*", &devId)
if (result != S_OK) {
throw Error("IMMDevice::GetId()", -1, result)
}
if (devId == defaultDevId) {
return A_Index
}
}
; should be impossible.
return 0
}
@lawkaita
Copy link
Author

example:

SoundSetMute(-1, "capture", SoundGetDefaultDeviceIndex("capture"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment