Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Persistent
- ; change this
- ; ===============================================================
- ; monitor number of PC
- global PC_Monitor := 1
- ; audio device name of PC
- global PC_Audio := "Headphones (F16-R)"
- ; monitor number of TV
- global TV_Monitor := 2
- ; audio device name of TV
- global TV_Audio := "Speakers (Realtek High Definition Audio)"
- ; ===============================================================
- ; set up a winevent hook to watch for window change events to window move events
- ActiveWindowAudioChange() {
- static hook := DllCall("SetWinEventHook"
- , "UInt", 0x0003 ; EVENT_SYSTEM_FOREGROUND
- , "UInt", 0x000B ; EVENT_SYSTEM_MOVESIZEEND
- , "Ptr", 0
- , "Ptr", RegisterCallback("ActiveWindowAudioChangeCB", "F")
- , "Int", 0
- , "Int", 0
- , "Int", 0x2)
- }
- Return
- ; End of Auto-Execute section
- ; Press F1 to check audio device names
- F1::
- devices := Audio_EnumEndpoints()
- out := "Devices:`n"
- for DeviceName, DeviceID in devices {
- out .= "[" A_Index "] " DeviceName "`n"
- }
- msgbox % out
- Return
- ActiveWindowAudioChangeCB(hWinEventHook, event, hwnd, idObject, idChild) {
- static CurrentAudioDevice := "" ; remember current audio device
- if (idObject|idChild != 0)
- return
- MonitorNumber := GetMonitorNumber()
- if !Audio_GetProgramPeakVolume(hwnd)
- return
- ; change to PC_Audio if window is active in PC_Monitor
- if (MonitorNumber = PC_Monitor && CurrentAudioDevice != PC_Audio) {
- DevID := Audio_GetDeviceID(Audio_EnumEndpoints(), PC_Audio)
- Audio_SetDefaultEndpoint(DevID)
- CurrentAudioDevice := PC_Audio
- }
- ; change to TV_Audio if window is active in TV_Monitor
- if (MonitorNumber = TV_Monitor && CurrentAudioDevice != TV_Audio) {
- DevID := Audio_GetDeviceID(Audio_EnumEndpoints(), TV_Audio)
- Audio_SetDefaultEndpoint(DevID)
- CurrentAudioDevice := TV_Audio
- }
- }
- ; some code borrowed from here: https://www.autohotkey.com/boards/viewtopic.php?p=46349#p46349
- GetMonitorNumber() {
- static MONITOR_DEFAULTTONEAREST := 0x00000002
- hMonitor := DllCall("User32\MonitorFromWindow", "Ptr", WinExist("A"), "UInt", MONITOR_DEFAULTTONEAREST)
- NumPut(VarSetCapacity(MONITORINFOEX, 40 + (32 << !!A_IsUnicode)), MONITORINFOEX, 0, "uint")
- if (DllCall("user32\GetMonitorInfo", "ptr", hMonitor, "ptr", &MONITORINFOEX))
- {
- MonitorName := StrGet(&MONITORINFOEX + 40, 32)
- MonitorNumber := RegExReplace(MonitorName, ".*(\d+)$", "$1")
- return MonitorNumber
- }
- return false
- }
- ; https://www.autohotkey.com/boards/viewtopic.php?p=388086#p388086
- Audio_EnumEndpoints() {
- ; 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 Devices
- }
- Audio_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)
- }
- Audio_GetDeviceID(Devices, Name)
- {
- For DeviceName, DeviceID in Devices
- If (InStr(DeviceName, Name))
- Return DeviceID
- }
- Audio_GetProgramPeakVolume(hwnd:="") {
- WinGet, PID, PID, % "ahk_id " hwnd
- ProcessName := ProcessGetName(PID)
- ISAVs := []
- static IID_IASM2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"
- , IID_IASC2 := "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}"
- , IID_ISAV := "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
- , IID_IAudioMeterInformation := "{C02216F6-8C67-4B5B-9D00-D008E73E0064}"
- ; Activate the session manager of the given device
- pIMMD := VA_GetDevice()
- VA_IMMDevice_Activate(pIMMD, IID_IASM2, 0, 0, pIASM2)
- ObjRelease(pIMMD)
- ; Enumerate sessions for on this device
- VA_IAudioSessionManager2_GetSessionEnumerator(pIASM2, pIASE)
- ObjRelease(pIASM2)
- ; Search for audio sessions with a matching process ID or Name
- VA_IAudioSessionEnumerator_GetCount(pIASE, Count)
- Loop, % Count
- {
- ; Get this session's IAudioSessionControl2 via its IAudioSessionControl
- VA_IAudioSessionEnumerator_GetSession(pIASE, A_Index-1, pIASC)
- pIASC2 := ComObjQuery(pIASC, IID_IASC2)
- ObjRelease(pIASC)
- VA_IAudioSessionControl2_GetProcessID(pIASC2, PID)
- if (ProcessGetName(PID) = ProcessName) {
- ; get IAudioMeterInformation from IAudioSessionControl
- ; AudioMeterInformation = {C02216F6-8C67-4B5B-9D00-D008E73E0064}
- AudioMeter := ComObjQuery(pIASC2, IID_IAudioMeterInformation)
- VA_IAudioMeterInformation_GetPeakValue(AudioMeter, vPeakValue)
- ObjRelease(AudioMeter)
- }
- ObjRelease(pIASC2)
- }
- ; Release the IAudioSessionEnumerator
- ObjRelease(pIASE)
- return vPeakValue
- }
- ProcessGetName(PID) {
- hProcess := DllCall("OpenProcess"
- , "UInt", 0x1000 ; DWORD dwDesiredAccess (PROCESS_QUERY_LIMITED_INFORMATION)
- , "UInt", False ; BOOL bInheritHandle
- , "UInt", PID ; DWORD dwProcessId
- , "UPtr")
- dwSize := VarSetCapacity(strExeName, 512 * A_IsUnicode, 0) // A_IsUnicode
- DllCall("QueryFullProcessImageName"
- , "UPtr", hProcess ; HANDLE hProcess
- , "UInt", 0 ; DWORD dwFlags
- , "Str", strExeName ; LPSTR lpExeName
- , "UInt*", dwSize ; PDWORD lpdwSize
- , "UInt")
- DllCall("CloseHandle", "UPtr", hProcess, "UInt")
- SplitPath, strExeName, strExeName
- return strExeName
- }
- ; =====================================================================================
- ; functions used from VA.ahk
- ; remove functions below if you already have VA.ahk
- ; =====================================================================================
- ; device_desc = device_id
- ; | ( friendly_name | 'playback' | 'capture' ) [ ':' index ]
- VA_GetDevice(device_desc="playback")
- {
- static CLSID_MMDeviceEnumerator := "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
- , IID_IMMDeviceEnumerator := "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
- if !(deviceEnumerator := ComObjCreate(CLSID_MMDeviceEnumerator, IID_IMMDeviceEnumerator))
- return 0
- device := 0
- if VA_IMMDeviceEnumerator_GetDevice(deviceEnumerator, device_desc, device) = 0
- goto VA_GetDevice_Return
- if device_desc is integer
- {
- m2 := device_desc
- if m2 >= 4096 ; Probably a device pointer, passed here indirectly via VA_GetAudioMeter or such.
- {
- ObjAddRef(device := m2)
- goto VA_GetDevice_Return
- }
- }
- else
- RegExMatch(device_desc, "(.*?)\s*(?::(\d+))?$", m)
- if m1 in playback,p
- m1 := "", flow := 0 ; eRender
- else if m1 in capture,c
- m1 := "", flow := 1 ; eCapture
- else if (m1 . m2) = "" ; no name or number specified
- m1 := "", flow := 0 ; eRender (default)
- else
- flow := 2 ; eAll
- if (m1 . m2) = "" ; no name or number (maybe "playback" or "capture")
- {
- VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(deviceEnumerator, flow, 0, device)
- goto VA_GetDevice_Return
- }
- VA_IMMDeviceEnumerator_EnumAudioEndpoints(deviceEnumerator, flow, 1, devices)
- if m1 =
- {
- VA_IMMDeviceCollection_Item(devices, m2-1, device)
- goto VA_GetDevice_Return
- }
- VA_IMMDeviceCollection_GetCount(devices, count)
- index := 0
- Loop % count
- if VA_IMMDeviceCollection_Item(devices, A_Index-1, device) = 0
- if InStr(VA_GetDeviceName(device), m1) && (m2 = "" || ++index = m2)
- goto VA_GetDevice_Return
- else
- ObjRelease(device), device:=0
- VA_GetDevice_Return:
- ObjRelease(deviceEnumerator)
- if devices
- ObjRelease(devices)
- return device ; may be 0
- }
- VA_IMMDevice_Activate(this, iid, ClsCtx, ActivationParams, ByRef Interface) {
- return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", VA_GUID(iid), "uint", ClsCtx, "uint", ActivationParams, "ptr*", Interface)
- }
- VA_IAudioSessionManager2_GetSessionEnumerator(this, ByRef SessionEnum) {
- return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr*", SessionEnum)
- }
- VA_IAudioSessionEnumerator_GetCount(this, ByRef SessionCount) {
- return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "int*", SessionCount)
- }
- VA_IAudioSessionEnumerator_GetSession(this, SessionCount, ByRef Session) {
- return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "int", SessionCount, "ptr*", Session)
- }
- VA_IAudioSessionControl2_GetProcessId(this, ByRef pid) {
- return DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "uint*", pid)
- }
- VA_IAudioMeterInformation_GetPeakValue(this, ByRef Peak) {
- return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "float*", Peak)
- }
- VA_IMMDeviceEnumerator_GetDevice(this, id, ByRef Device) {
- return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "wstr", id, "ptr*", Device)
- }
- VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(this, DataFlow, Role, ByRef Endpoint) {
- return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "int", DataFlow, "int", Role, "ptr*", Endpoint)
- }
- VA_IMMDeviceEnumerator_EnumAudioEndpoints(this, DataFlow, StateMask, ByRef Devices) {
- return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "int", DataFlow, "uint", StateMask, "ptr*", Devices)
- }
- VA_IMMDeviceCollection_Item(this, Index, ByRef Device) {
- return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Index, "ptr*", Device)
- }
- VA_IMMDeviceCollection_GetCount(this, ByRef Count) {
- return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "uint*", Count)
- }
- VA_GetDeviceName(device)
- {
- static PKEY_Device_FriendlyName
- if !VarSetCapacity(PKEY_Device_FriendlyName)
- VarSetCapacity(PKEY_Device_FriendlyName, 20)
- ,VA_GUID(PKEY_Device_FriendlyName :="{A45C254E-DF1C-4EFD-8020-67D146A850E0}")
- ,NumPut(14, PKEY_Device_FriendlyName, 16)
- VarSetCapacity(prop, 16)
- VA_IMMDevice_OpenPropertyStore(device, 0, store)
- ; store->GetValue(.., [out] prop)
- DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_Device_FriendlyName, "ptr", &prop)
- ObjRelease(store)
- VA_WStrOut(deviceName := NumGet(prop,8))
- return deviceName
- }
- VA_GUID(ByRef guid_out, guid_in="%guid_out%") {
- if (guid_in == "%guid_out%")
- guid_in := guid_out
- if guid_in is integer
- return guid_in
- VarSetCapacity(guid_out, 16, 0)
- DllCall("ole32\CLSIDFromString", "wstr", guid_in, "ptr", &guid_out)
- return &guid_out
- }
- VA_IMMDevice_OpenPropertyStore(this, Access, ByRef Properties) {
- return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Access, "ptr*", Properties)
- }
- VA_WStrOut(ByRef str) {
- str := StrGet(ptr := str, "UTF-16")
- DllCall("ole32\CoTaskMemFree", "ptr", ptr)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement