75 lines · 3.4 KB
Raw Download
1
; toggle audio out between "Speakers" and "Headphones"
2
; http www.daveamenta.com /2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/  Broken Link for safety
3
Devices := {}
4
IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}")
5
6
; IMMDeviceEnumerator::EnumAudioEndpoints
7
; eRender = 0, eCapture, eAll
8
; 0x1 = DEVICE_STATE_ACTIVE
9
DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt")
10
ObjRelease(IMMDeviceEnumerator)
11
12
; IMMDeviceCollection::GetCount
13
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt")
14
Loop % (Count)
15
{
16
    ; IMMDeviceCollection::Item
17
    DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt")
18
19
    ; IMMDevice::GetId
20
    DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt")
21
    DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer)
22
23
    ; IMMDevice::OpenPropertyStore
24
    ; 0x0 = STGM_READ
25
    DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt")
26
    ObjRelease(IMMDevice)
27
28
    ; IPropertyStore::GetValue
29
    VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24)
30
    VarSetCapacity(PROPERTYKEY, 20)
31
    DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY)
32
    NumPut(14, &PROPERTYKEY + 16, "UInt")
33
    DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt")
34
    DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16")    ; LPWSTR PROPVARIANT.pwszVal
35
    DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8))    ; LPWSTR PROPVARIANT.pwszVal
36
    ObjRelease(IPropertyStore)
37
38
    ObjRawSet(Devices, DeviceName, DeviceID)
39
}
40
ObjRelease(IMMDeviceCollection)
41
42
; Check the current default device and toggle it
43
currentDevice := GetCurrentDefaultEndpoint()
44
if (currentDevice = GetDeviceID(Devices, "Speakers")) {
45
    SetDefaultEndpoint(GetDeviceID(Devices, "Headphones"))
46
} else {
47
    SetDefaultEndpoint(GetDeviceID(Devices, "Speakers"))
48
}
49
50
SetDefaultEndpoint(DeviceID)
51
{
52
    IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}")
53
    DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 0, "UInt")
54
    ObjRelease(IPolicyConfig)
55
}
56
57
GetDeviceID(Devices, Name)
58
{
59
    For DeviceName, DeviceID in Devices
60
        If (InStr(DeviceName, Name))
61
            Return DeviceID
62
}
63
64
GetCurrentDefaultEndpoint()
65
{
66
    ; Get the current default audio endpoint
67
    IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}")
68
    DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+4*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDevice, "UInt")
69
    DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt")
70
    DeviceID := StrGet(pBuffer, "UTF-16")
71
    DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer)
72
    ObjRelease(IMMDevice)
73
    ObjRelease(IMMDeviceEnumerator)
74
    Return DeviceID
75
}