Change audio output Topic is solved
Change audio output
Is there anyway to make a hotkey to change my audio output? I have multiple connections on my PC and it feels tiresome to change everytime.
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: Change audio output
is that a "I want a AHK script to switch audio output device" question...
It takes 3 clicks to switch audio device in windows 10. no sure what would be advantageous to have a hot key...
Speaker Tray->Device Drop Down above the volume->Device You want
It takes 3 clicks to switch audio device in windows 10. no sure what would be advantageous to have a hot key...
Speaker Tray->Device Drop Down above the volume->Device You want
Re: Change audio output
I rather use a hotkey too, my work laptop has an easily accessible mute button, which on double tap I use to switch output.
Using: https://autohotkey.com/board/topic/2198 ... functions/
and grabbing the device names from: mmsys.cpl
call: VA_CycleDefaultEndPoint(["Speakers","Headset","Beamer"])
Using: https://autohotkey.com/board/topic/2198 ... functions/
and grabbing the device names from: mmsys.cpl
call: VA_CycleDefaultEndPoint(["Speakers","Headset","Beamer"])
Re: Change audio output
Tested on WIN_10
Note: This method is not documented and may not work in future Windows updates.
Code: Select all
; http://www.daveamenta.com/2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/
Devices := {}
IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}")
; IMMDeviceEnumerator::EnumAudioEndpoints
; eRender = 0, eCapture, eAll
; 0x1 = DEVICE_STATE_ACTIVE
DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt")
ObjRelease(IMMDeviceEnumerator)
; IMMDeviceCollection::GetCount
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt")
Loop % (Count)
{
; IMMDeviceCollection::Item
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt")
; IMMDevice::GetId
DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt")
DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer)
; IMMDevice::OpenPropertyStore
; 0x0 = STGM_READ
DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt")
ObjRelease(IMMDevice)
; IPropertyStore::GetValue
VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24)
VarSetCapacity(PROPERTYKEY, 20)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY)
NumPut(14, &PROPERTYKEY + 16, "UInt")
DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt")
DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16") ; LPWSTR PROPVARIANT.pwszVal
DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8)) ; LPWSTR PROPVARIANT.pwszVal
ObjRelease(IPropertyStore)
ObjRawSet(Devices, DeviceName, DeviceID)
}
ObjRelease(IMMDeviceCollection)
Devices2 := {}
For DeviceName, DeviceID in Devices
List .= "(" . A_Index . ") " . DeviceName . "`n", ObjRawSet(Devices2, A_Index, DeviceID)
InputBox n,, % List,,,,,,,, 1
MsgBox % Devices2[n]
;IPolicyConfig::SetDefaultEndpoint
IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}") ;00000102-0000-0000-C000-000000000046 00000000-0000-0000-C000-000000000046
R := DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "Str", Devices2[n], "UInt", 0, "UInt")
ObjRelease(IPolicyConfig)
MsgBox % Format("0x{:08X}", R)
Re: Change audio output
So I just run this as a normal ahk script and it will prompt to change the audio output, right?Flipeador wrote:Tested on WIN_10Code: Select all
; http://www.daveamenta.com/2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/ Devices := {} IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") ; IMMDeviceEnumerator::EnumAudioEndpoints ; eRender = 0, eCapture, eAll ; 0x1 = DEVICE_STATE_ACTIVE DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt") ObjRelease(IMMDeviceEnumerator) ; IMMDeviceCollection::GetCount DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt") Loop % (Count) { ; IMMDeviceCollection::Item DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt") ; IMMDevice::GetId DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt") DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer) ; IMMDevice::OpenPropertyStore ; 0x0 = STGM_READ DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt") ObjRelease(IMMDevice) ; IPropertyStore::GetValue VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24) VarSetCapacity(PROPERTYKEY, 20) DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY) NumPut(14, &PROPERTYKEY + 16, "UInt") DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt") DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16") ; LPWSTR PROPVARIANT.pwszVal DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8)) ; LPWSTR PROPVARIANT.pwszVal ObjRelease(IPropertyStore) ObjRawSet(Devices, DeviceName, DeviceID) } ObjRelease(IMMDeviceCollection) Devices2 := {} For DeviceName, DeviceID in Devices List .= "(" . A_Index . ") " . DeviceName . "`n", ObjRawSet(Devices2, A_Index, DeviceID) InputBox n,, % List,,,,,,,, 1 MsgBox % Devices2[n] ;IPolicyConfig::SetDefaultEndpoint IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}") ;00000102-0000-0000-C000-000000000046 00000000-0000-0000-C000-000000000046 R := DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "Str", Devices2[n], "UInt", 0, "UInt") ObjRelease(IPolicyConfig) MsgBox % Format("0x{:08X}", R)
Re: Change audio output
Yes, a window appears where you have to select the device you want to set as default (you only have to put the number indicated in parentheses). Obviously, this can be adapted to establish a device automatically without asking anything, it is just an example so you can see how it is done.So I just run this as a normal ahk script and it will prompt to change the audio output, right?
If it does not work for you, try running the script as Administrator. If it still does not work for you, please comment with the information that appears on the InputBox and the two MsgBox.
Re: Change audio output
Yes, you can remove/comment them.a little problem I found, is that after entering the value shows up two boxes. i can hide them in the code by commenting them out, is it fine?
Both messages are correct. The first one shows you the identifier of the selected device, and the second one shows you an error code, 0x00000000 is S_OK (success).
You can set it without asking, tell me the name of the device and I'll tell you how to do it.Ahh, this works perfectly.I would prefer it to just change to an specific audio output but this way totally works in my workflow
Re: Change audio output
I have 5 devices connected, and I use primary 3 of them.
- AMD HDMI Output
- Headphones
- Speakers
Re: Change audio output Topic is solved
Use F1, F2 and F3.
⠀
AutoHotkey v2: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=49980&p=387886#p387886.
Code: Select all
; http://www.daveamenta.com/2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/
Devices := {}
IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}")
; IMMDeviceEnumerator::EnumAudioEndpoints
; eRender = 0, eCapture, eAll
; 0x1 = DEVICE_STATE_ACTIVE
DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt")
ObjRelease(IMMDeviceEnumerator)
; IMMDeviceCollection::GetCount
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt")
Loop % (Count)
{
; IMMDeviceCollection::Item
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt")
; IMMDevice::GetId
DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt")
DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer)
; IMMDevice::OpenPropertyStore
; 0x0 = STGM_READ
DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt")
ObjRelease(IMMDevice)
; IPropertyStore::GetValue
VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24)
VarSetCapacity(PROPERTYKEY, 20)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY)
NumPut(14, &PROPERTYKEY + 16, "UInt")
DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt")
DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16") ; LPWSTR PROPVARIANT.pwszVal
DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8)) ; LPWSTR PROPVARIANT.pwszVal
ObjRelease(IPropertyStore)
ObjRawSet(Devices, DeviceName, DeviceID)
}
ObjRelease(IMMDeviceCollection)
Return
F1:: SetDefaultEndpoint( GetDeviceID(Devices, "AMD HDMI") )
F2:: SetDefaultEndpoint( GetDeviceID(Devices, "Headphones") )
F3:: SetDefaultEndpoint( GetDeviceID(Devices, "Speakers") )
SetDefaultEndpoint(DeviceID)
{
IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}")
DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 0, "UInt")
ObjRelease(IPolicyConfig)
}
GetDeviceID(Devices, Name)
{
For DeviceName, DeviceID in Devices
If (InStr(DeviceName, Name))
Return DeviceID
}
⠀
AutoHotkey v2: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=49980&p=387886#p387886.
Re: Change audio output
I know it's been a bit since this thread was active, but I am not a skilled enough programmer to navigate this on my own. I am attempting to make a version of the script that cycles through a specified subset of my computers audio devices, but to do so I (at least in the way I am thinking of) I would need to detect the currently active audio device. Can I retrieve this parameter?
Re: Change audio output
just short , open speakers / mixer ( Win-10 )
Code: Select all
run,sndvol.exe
CB=runDLL32.EXE shell32.dll,Control_RunDLL mmsys.cpl,,0
run,%CB%
Re: Change audio output
Sorry, I meant pragmatically, so that the script itself could use the parameter. is there a way to do that?garry wrote:just short , open speakers / mixer ( Win-10 )Code: Select all
run,sndvol.exe CB=runDLL32.EXE shell32.dll,Control_RunDLL mmsys.cpl,,0 run,%CB%
Re: Change audio output
replying to flipeador 02 Jun 2018, 12:38 (cannot include quotes because of the spammer issue and I'm new to the forums...)
This is FANTASTIC! Working on my Windows 10 box here - thank you so much! All I had to do was change the sound device names on lines 43-45 (and i also changed the hotkeys to something else).
One question, I notice it only changes the default device and not the default communications devices, is there an easy change that can make them both change simultaneously and if so where would I add that code? See below for example.
This is FANTASTIC! Working on my Windows 10 box here - thank you so much! All I had to do was change the sound device names on lines 43-45 (and i also changed the hotkeys to something else).
One question, I notice it only changes the default device and not the default communications devices, is there an easy change that can make them both change simultaneously and if so where would I add that code? See below for example.
Re: Change audio output
Reading through the VA.ahk source code, I found out how to do it.
Put this second line next to the first line. the numbers 0 and 2 are for "Default Device" and "Default Communication Device" respectively.
Put this second line next to the first line. the numbers 0 and 2 are for "Default Device" and "Default Communication Device" respectively.
Code: Select all
DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 0, "UInt")
DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 2, "UInt")
Re: Change audio output
Thanks a lot, that code works perfectly for me too!
Rather than a dialogbox, I would like to press a key several times, and cycle through my different audio outputs. Any idea on how to do that?
Rather than a dialogbox, I would like to press a key several times, and cycle through my different audio outputs. Any idea on how to do that?
Re: Change audio output
thanks Flipeador! It works flawlessly!
You are a genius!!!
Is it possible to select the wanted device just by pressing the number (without pressing OK/Enter)?
Now it still works for me, but if I can press 1 key instead of 2, the whole world will become perfect!
https://imgur.com/ehcX1nC
You are a genius!!!
Is it possible to select the wanted device just by pressing the number (without pressing OK/Enter)?
Now it still works for me, but if I can press 1 key instead of 2, the whole world will become perfect!
https://imgur.com/ehcX1nC
Re: Change audio output
Hey, This works quite nicely. I'm however quite inept at AHK scripting and even though I did a bit of research, am unable to edit this myself - I would like to turn this into a togglable script where instead of F1, F2, F3 it toggles between these options instead when I press [Win]+[F11]. Sorry for reopening this, but It feels like i'd need to open a new topic anyway, and this fits here quite well. Any help would be welcome.Flipeador wrote: ↑02 Jun 2018, 12:38Use F1, F2 and F3.Code: Select all
; http www.daveamenta.com /2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/ Broken Link for safety Devices := {} IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") ; IMMDeviceEnumerator::EnumAudioEndpoints ; eRender = 0, eCapture, eAll ; 0x1 = DEVICE_STATE_ACTIVE DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt") ObjRelease(IMMDeviceEnumerator) ; IMMDeviceCollection::GetCount DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt") Loop % (Count) { ; IMMDeviceCollection::Item DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt") ; IMMDevice::GetId DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt") DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer) ; IMMDevice::OpenPropertyStore ; 0x0 = STGM_READ DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt") ObjRelease(IMMDevice) ; IPropertyStore::GetValue VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24) VarSetCapacity(PROPERTYKEY, 20) DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY) NumPut(14, &PROPERTYKEY + 16, "UInt") DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt") DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16") ; LPWSTR PROPVARIANT.pwszVal DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8)) ; LPWSTR PROPVARIANT.pwszVal ObjRelease(IPropertyStore) ObjRawSet(Devices, DeviceName, DeviceID) } ObjRelease(IMMDeviceCollection) Return F1:: SetDefaultEndpoint( GetDeviceID(Devices, "AMD HDMI") ) F2:: SetDefaultEndpoint( GetDeviceID(Devices, "Headphones") ) F3:: SetDefaultEndpoint( GetDeviceID(Devices, "Speakers") ) SetDefaultEndpoint(DeviceID) { IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}") DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 0, "UInt") ObjRelease(IPolicyConfig) } GetDeviceID(Devices, Name) { For DeviceName, DeviceID in Devices If (InStr(DeviceName, Name)) Return DeviceID }
EDIT: I'm not quite as inept as I thought, Heres what I put down, I replaced this part
Code: Select all
F1:: SetDefaultEndpoint( GetDeviceID(Devices, "AMD HDMI") )
F2:: SetDefaultEndpoint( GetDeviceID(Devices, "Headphones") )
F3:: SetDefaultEndpoint( GetDeviceID(Devices, "Speakers") )
Code: Select all
#F11:: ; Win+F11 Hotkey
t := !t ; Toggle Var (0 or 1)
If (t = "1")
{
SetDefaultEndpoint( GetDeviceID(Devices, "Headphones") )
}
If (t = "0")
{
SetDefaultEndpoint( GetDeviceID(Devices, "Speakers") )
}
Re: Change audio output
The code worked perfectly until last few days since the latest Win10 OS update. Has anyone been able to identify the necessary changes to match the new OS??
Now running Win 10 Home v. 20H2 build 19042.867 ExpPack 120.2212.551.0
Once it's updated I can share my own modifications to it. I have it change the Speakers AND Mic at the same time.
Now running Win 10 Home v. 20H2 build 19042.867 ExpPack 120.2212.551.0
Once it's updated I can share my own modifications to it. I have it change the Speakers AND Mic at the same time.