Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Script by [email protected] / p2codes
- #Persistent ; This keeps the script running permanently.
- #SingleInstance ; Only allows one instance of the script to run.
- ; ===============================================================================================
- ; Global Variables
- ; ===============================================================================================
- global curText := "Output 404" ; Text on GUI (Updated later)
- global selectionIndex := 1 ; Currently selected output device
- global arrNames := Object() ; Output devices data (device names)
- ; Registry Keys & Values used in x64 Win 10 (WARNING: MAY DIFFER ON OTHER VERSIONS OF WINDOWS)
- ; ===============================================================================================
- ; This is the value that contains the user customisable name (eg Headphones or TV) of the playback device
- ; The root path to the audio devices section of the registry
- global rootPath = % "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"
- ; This value is found in %rootPath%\%deviceSubKey%\Properties, and always has this same name across devices
- global nameValue = % "{a45c254e-df1c-4efd-8020-67d146a850e0},2"
- ; ===============================================================================================
- ; Script Start-up Instructions (Note: This must run before to the hotkey section)
- ; ===============================================================================================
- createGui() ; Create GUI (but hidden) so it is ready for use (showing)
- ; ===============================================================================================
- ; Windows HotKey (Win + K by default)
- ; ===============================================================================================
- #k::
- {
- currentEnabledDeviceIndex = % getDeviceInfo() ; Get device data from registry
- devName = % getNextSelectionName(currentEnabledDeviceIndex) ; Get name of next device to use
- Run nircmd setdefaultsounddevice "%devName%" 1 ; Use name & nircmd to set default playback device
- Run nircmd setdefaultsounddevice "%devName%" 2 ; Use name & nircmd to set default communication device
- showGui(devName) ; Unhide the GUI with text to match device name
- Return ; Finished
- }
- ; ===============================================================================================
- ; Script Functions
- ; ===============================================================================================
- ; Function: createGui
- ; Description: Creates a small hidden GUI, named soundToggleWin, suitable for re-use and
- ; modification of it's text property, called curText.
- ; ===============================================================================================
- createGui()
- {
- Gui, soundToggleWin:destroy ; Destroy Any Existing Window with name soundToggleWin
- Gui, soundToggleWin: New, -Caption +AlwaysOnTop -SysMenu -Theme ; Create new UI with name soundToggleWin and set appearance propertiess
- Gui, soundToggleWin: Add, text, x15 y8 vcurText, OutputSample ; Add text property to UI, named curText, and place it appropriately
- Return ; Exit
- }
- ; Function: showGui
- ; Description: Applies properties to and shows the soundToggleWin GUI element,
- ; the properties being it's appearance and the text (curText)
- ; Input Data: The text to apply to the GUI's curText text element
- ; ===============================================================================================
- showGui(guiText)
- {
- SysGet, screenx, 0 ; Get ScreenX & Y position values
- SysGet, screeny, 1 ; Same as above
- xpos:=screenx-150 ; Set-up location to place window using screenX/Y values
- ypos:=screeny-62 ; Same as above
- GuiControl, soundToggleWin:, curText, %guiText% ; Set curText text objects text to the input text
- Gui, soundToggleWin:Show, NoActivate x%xpos% y%ypos% h30 w150, soundToggleWin ; Show the UI with specified size and location
- SetTimer, hideGui, 2000 ; Set timer to run hideGui function in 2000ms (2seconds)
- Return ; Exit
- }
- ; Function: hideGui
- ; Description: Hides the soundToggleWin GUI and disables / deletes the hideGui timer
- ; ===============================================================================================
- hideGui()
- {
- SetTimer, hideGui, Delete ; Disable & Delete the timer we started
- Gui, soundToggleWin:hide ; Hide the GUI window
- Return ; Exit
- }
- ; Function: getDeviceInfo
- ; Description: Retrieves registry data about all output devices that are enabled as a device,
- ; in 'Playback Devices', and retrieves which device is the current default output device. It
- ; places this data in the arrNames object/array.
- ; Return Data: The Index of the current default playback device relative to the arrNames array
- ; ===============================================================================================
- getDeviceInfo()
- {
- arrNames := Object() ; Empty array of device names
- largestValue = 0 ; Used to compare device status codes (level:0 values)
- ; Loop through all keys in the root path
- Loop, Reg, %rootPath%, K
- {
- curKeyPath = %rootPath%\%a_LoopRegName% ; Save current audio devices key path to re-use
- RegRead, deviceStateValue, %curKeyPath%, DeviceState ; Read device state (enabled/disabled in playback devices)
- ; If device is useable as a playback device (enabled)
- if (deviceStateValue = 1) {
- RegRead, deviceName, %curKeyPath%\Properties, %nameValue% ; Read device name (user customisable in playback devices)
- arrNames.Insert(deviceName) ; Insert device name into array
- deviceStatusCode = % readRegQW(curKeyPath,"Level:0") ; Get hex code that determines if the device is the current playback device
- ; Check which device is the current playback device using hex code retrieved
- ; Currently enabled device has largest hex code value for key "Level:0"
- if (deviceStatusCode > largestValue) {
- largestValue := deviceStatusCode ; Update largest value for next iteration
- currentDeviceIndex := arrNames.MaxIndex() ; Store index of currently used device so we can avoid it during selection
- }
- }
- }
- Return currentDeviceIndex ; Return the default playback device index (index is for the arrNames array)
- }
- ; Function: getNextSelectionName
- ; Description: Uses the retrieved default playback device index from getDeviceInfo and the
- ; global selectionIndex value to select the next default playback device without conflict and
- ; in a sequential manor.
- ; Input Data: The index (reletive to arrNames) of the current default playback device
- ; Return Data: The device name of the next audio device to set as the default playback device
- ; ===============================================================================================
- getNextSelectionName(deviceIndex)
- {
- ; If selected device is the one already enabled, then skip to next device selection
- if (deviceIndex = selectionIndex) {
- ; If we reach the max index, reset to 1, otherwise add 1 to move on to the next selection
- if (selectionIndex < arrNames.MaxIndex()) {
- selectionIndex := selectionIndex + 1
- } else {
- selectionIndex = 1
- }
- }
- deviceName := arrNames[selectionIndex] ; Store the device name
- Return deviceName ; Return the device name for the next playback device to use
- }
- ; Function: readRegQW
- ; Description: Uses given key & value input to read REG_QWORD values from registry via shell
- ; Input Data: Key - The reg key to search in, Value - The reg value to retrieve the data of
- ; Return Data: The data retrieved from the registry query
- ; ===============================================================================================
- readRegQW(Key,Value)
- {
- shellObj := ComObjCreate("WScript.Shell") ; Create shell object to use
- ; Use shell object to run CMD with flag /q for quiet mode, /c to run a command
- ; We're using it to query the specified key and retrieve all data
- shellExec := shellObj.Exec("cmd.exe /q /c reg query " Key " /v " Value)
- shellOut := "" ; Set the shellOut variable to empty
- while, !shellExec.StdOut.AtEndOfStream ; While the shell hasn't finished outputting
- shellOut := shellExec.StdOut.ReadAll() ; Keep reading the shells contents into shellOut
- StringReplace, shellOut, shellOut, REG_QWORD, FINDMENOW ; Replace "REG_QWORD" with "FINDMENOW" (Console text length may vary user to user, this garantuees a position)
- StringGetPos, findPos, shellOut, FINDMENOW ; Get position of FINDMENOW in string
- shellOut := SubStr(shellOut, findPos+14) ; Use position of FINDMENOW to cut the string down into just the data we need
- shellOut := RTrim(shellOut,"`n`r ") ; Trim off the excess whitespace (newlines) on the right hand side
- shellOut := shellOut + 0 ; Convert to decimal by adding 0
- return shellOut ; Return decimal registry data
- }
Advertisement
Add Comment
Please, Sign In to add comment