From 4eadb236da33326ba592eae2cf470618d14d5143 Mon Sep 17 00:00:00 2001 From: David Daily Date: Fri, 10 Dec 2021 08:38:52 -0600 Subject: [PATCH] Reorganize functions, pause if YT or Netflix are active --- VB.ahk | 497 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 482 insertions(+), 15 deletions(-) diff --git a/VB.ahk b/VB.ahk index d8877a4..936f746 100644 --- a/VB.ahk +++ b/VB.ahk @@ -8,7 +8,7 @@ SetWorkingDir, C:\Users\Leand.000\Documents\D3K #Persistent ListLines Off SendMode Input ; Recommended for new scripts due to its superior speed and reliability. -SetTitleMatchMode RegEx +SetTitleMatchMode, RegEx StringCaseSense Off OnExit("cleanup_before_exit") @@ -255,7 +255,13 @@ midiCCin: } Return Case 3: ; Media Play/Pause - Send, {Media_Play_Pause} + If (WinActive("Netflix|YouTube",, "Music")) + { + Send, {Space} + } Else + { + Send, {Media_Play_Pause} + } Return Case 4: ; Set button / death sound if (val) @@ -318,19 +324,7 @@ midiCCin: } Return -fader_to_fader(val) ; Translates MIDI fader values to the VoiceMeeter software faders -{ - ; The upper limit for faders in VM is 12.0 - ; The lower limit for the faders in VM that I would like is -40.0, how low it should go when the physical fader is all the way at the bottom - nval := Round(((val / 127) * 72) - 60) - Return nval -} -; Formula: ((value / max value) * total range) - negative part of range -dial_to_pan(val) -{ - nval := Round((val / 127) - 0.5, 2) - Return nval -} + ; == HOTKEYS == ; ============= @@ -434,6 +428,479 @@ adjustString(func, str) { DllCall(VMR_FUNCTIONS["SetParameterFloat"], "AStr", func, "AStr", str, "Str") } +fader_to_fader(val) ; Translates MIDI fader values to the VoiceMeeter software faders +{ + ; The upper limit for faders in VM is 12.0 + ; The lower limit for the faders in VM that I would like is -40.0, how low it should go when the physical fader is all the way at the bottom + nval := Round(((val / 127) * 72) - 60) + Return nval +} +; Formula: ((value / max value) * total range) - negative part of range +dial_to_pan(val) +{ + nval := Round((val / 127) - 0.5, 2) + Return nval +} + + +add_vmr_function(func_name) { + VMR_FUNCTIONS[func_name] := DllCall("GetProcAddress", "Ptr", VMR_MODULE, "AStr", "VBVMR_" . func_name, "Ptr") + if (ErrorLevel || VMR_FUNCTIONS[func_name] == 0) + die("Failed to register VMR function " . func_name . ".") +} + +cleanup_before_exit(exit_reason, exit_code) { + DllCall(VMR_FUNCTIONS["Logout"], "Int") + ; OnExit functions must return 0 to allow the app to exit. + return 0 +} + +die(die_string:="UNSPECIFIED FATAL ERROR.", exit_status:=254) { + MsgBox 16, FATAL ERROR, %die_string% + ExitApp exit_status +}#Include, flag.ahk +SetWorkingDir, C:\Users\Leand.000\Documents\D3K +#SingleInstance force +#MaxHotkeysPerInterval 99000000 +#HotkeyInterval 99000000 +#KeyHistory 0 +#UseHook +#Persistent +ListLines Off +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetTitleMatchMode, RegEx +StringCaseSense Off + +OnExit("cleanup_before_exit") +SetFormat, Float, 0.3 +global VMR_FUNCTIONS := {} +global VMR_DLL_DRIVE := "C:" +global VMR_DLL_DIRPATH := "Program Files (x86)\VB\Voicemeeter" +global VMR_DLL_FILENAME_32 := "VoicemeeterRemote.dll" +global VMR_DLL_FILENAME_64 := "VoicemeeterRemote64.dll" +global VMR_DLL_FULL_PATH := VMR_DLL_DRIVE . "\" . VMR_DLL_DIRPATH . "\" +Sleep, 500 +if (A_Is64bitOS) { + VMR_DLL_FULL_PATH .= VMR_DLL_FILENAME_64 +} else { + VMR_DLL_FULL_PATH .= VMR_DLL_FILENAME_32 +} + +; == START OF EXECUTION == +; ======================== + +; Load the VoicemeeterRemote DLL: +; This returns a module handle +global VMR_MODULE := DllCall("LoadLibrary", "Str", VMR_DLL_FULL_PATH, "Ptr") +if (ErrorLevel || VMR_MODULE == 0) + die("Attempt to load VoiceMeeter Remote DLL failed.") + +; Populate VMR_FUNCTIONS +add_vmr_function("Login") +add_vmr_function("Logout") +add_vmr_function("RunVoicemeeter") +add_vmr_function("SetParameterFloat") +add_vmr_function("GetParameterFloat") +add_vmr_function("IsParametersDirty") + +; "Login" to Voicemeeter, by calling the function in the DLL named 'VBVMR_Login()'... +login_result := DllCall(VMR_FUNCTIONS["Login"], "Int") +if (ErrorLevel || login_result < 0) + die("VoiceMeeter Remote login failed.") + +; If the login returns 1, that apparently means that Voicemeeter isn't running, +; so we start it; pass 1 to run Voicemeeter, or 2 for Voicemeeter Banana: +if (login_result == 1) { + DllCall(VMR_FUNCTIONS["RunVoicemeeter"], "Int", 2, "Int") + if (ErrorLevel) + die("Attempt to run VoiceMeeter failed.") + Sleep 2000 +} + +; == MIDI == +; ========== +#Include, MIDI\MidiStart.ahk +#Include, MIDI\Midi_In_and_GuiMonitor.ahk ; this file contains: the function to parse midi message into parts we can work with and a midi monitor. +#Include, MIDI\MidiRules.ahk ; this file contains: Rules for manipulating midi input then sending modified midi output. +#Include, MIDI\Midi_under_the_hood.ahk ; this file contains: (DO NOT EDIT THIS FILE) all the dialogs to set up midi ports and midi message handling. + +midiCCin: + cc := byte1 ; The Control Channel + val := byte2 ; The value (0-127 for faders, 0 or 1 for buttons (that part is set with the software)) + + Switch chan + { + Case 1: ; The first fader: Work Laptop Receive + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Strip[0].Gain", Lvl) + Return + Case 1: + Lvl := dial_to_pan(val) + adjustVolLvl("Strip[0].Pan_x", Lvl) + Case 2: + adjustToggle("Strip[0].Solo", val) + Return + Case 3: + adjustToggle("Strip[0].Mute", val) + Return + Case 4: + adjustToggle("Strip[0].B2", val) + Return + Default: + Return + } + Case 2: ; The second fader: Work Laptop Send + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Bus[2].Gain", Lvl) + Return + Case 2, 3, 4: + adjustToggle("Bus[2].Mute", val) + Return + Default: + Return + } + Case 3: ; The third fader: Desktop Audio + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Strip[3].Gain", Lvl) + Return + Case 1: + Lvl := dial_to_pan(val) + adjustVolLvl("Strip[3].Pan_x", Lvl) + Case 2: + adjustToggle("Strip[3].Solo", val) + Return + Case 3: + adjustToggle("Strip[3].Mute", val) + Return + Case 4: + adjustToggle("Strip[3].B2", val) + Return + Default: + Return + } + Case 4: ; The third fader: Comms Send + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Bus[3].Gain", Lvl) + Return + Case 2: ; PTT + if !(val){ + cSendMute := Round(readParam("Bus[3].Mute")) + adjustToggle("Bus[3].Mute", False) + } else { + adjustToggle("Bus[3].Mute", cSendMute) + } + Return + Case 3: + adjustToggle("Bus[3].Mute", val) + Return + Case 4: ; Push to mute + if !(val){ + cSendMute := Round(readParam("Bus[3].Mute")) + adjustToggle("Bus[3].Mute", True) + } else { + adjustToggle("Bus[3].Mute", cSendMute) + } + Return + Default: + Return + } + Case 5: ; The fifth fader: Comms Receive + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Strip[4].Gain", Lvl) + Return + Case 1: + Lvl := dial_to_pan(val) + adjustVolLvl("Strip[4].Pan_x", Lvl) + Case 2: + adjustToggle("Strip[4].Solo", val) + Return + Case 3: + adjustToggle("Strip[4].Mute", val) + Return + Case 4: + adjustToggle("Strip[4].B2", val) + Return + Default: + Return + } + Case 6: ; The sixth fader: Speakers + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Bus[0].Gain", Lvl) + Return + Case 3: + adjustToggle("Bus[0].Mute", val) + Return + Default: + Return + } + Case 7: ; The seventh fader: Mic + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Bus[1].Gain", Lvl) + Return + Case 3: + adjustToggle("Strip[1].Mute", val) + adjustToggle("Bus[1].Mute", val) + Return + Case 4: + adjustToggle("Strip[1].B2", val) + Return + Default: + Return + } + Case 8: ; The eighth fader: Music + Switch cc + { + Case 0: + Lvl := fader_to_fader(val) + adjustVolLvl("Strip[2].Gain", Lvl) + Return + Case 1: + Lvl := dial_to_pan(val) + adjustVolLvl("Strip[2].Pan_x", Lvl) + Case 2: + adjustToggle("Strip[2].Solo", val) + Return + Case 3: + adjustToggle("Strip[2].Mute", val) + Return + Case 4: ; Send audio to Comms out & record + adjustToggle("Strip[2].B1", val) + adjustToggle("Strip[2].B2", val) + if (val) + { + Send {F22} ; Toggle PTT/Voice Activity (Shows up as UNK133 in discord) + Send {F23 down} ; PTT button (Shows up as UNK134 in discord) + } else { + Send {F23 up} + Send {F22} ; Toggle PTT/Voice Activity + } + Return + Default: + Return + } + Case 10: ; VoiceMeeter recorder controls + Switch cc + { + Case 1: ; Media Previous + if (val) + { + Send, {Media_Prev} + } + Return + Case 2: ; Media Next + if (val) + { + Send, {Media_Next} + } + Return + Case 3: ; Media Play/Pause + If (WinActive("Netflix|YouTube",, "Music")) + { + Send, {Space} + } Else + { + Send, {Media_Play_Pause} + } + Return + Case 4: ; Set button / death sound + if (val) + { + Send {F22} ; Toggle PTT/Voice Activity + Send {F23 down} + adjustToggle("Recorder.Play", True) ; Temp fix until file loading works + } else { + Send {F23 up} + Send {F22} + adjustToggle("Recorder.Stop", True) + Sleep, 250 ; Makes sure the playback is reset to the beginning, temp until loading files is possible + adjustToggle("Recorder.Stop", True) + } + Return + Case 5: ; <- under Marker / dislike song + if !(val) + { + Send {F20} + } + Return + Case 6: ; -> under Marker / like song + if !(val) + { + Send {F21} + } + Return + Case 7: ; Rewind + if (val) + { + adjustToggle("Recorder.REW", True) + } else { + adjustToggle("Recorder.Play", True) + } + Return + Case 8: ; Fast Forward + if (val) + { + adjustToggle("Recorder.FF", True) + } else { + adjustToggle("Recorder.Play", True) + } + Return + Case 9: + adjustToggle("Recorder.Stop", val) + Return + Case 10: + adjustToggle("Recorder.Play", val) + Return + Case 11: + adjustToggle("Recorder.Record", val) + Return + Default: + Gosub, SendCC + Return + } + Default: + Gosub, SendCC + Return + } +Return + + +; == HOTKEYS == +; ============= + +Volume_Mute:: + b0M := Round(readParam("Bus[0].Mute")) ; Speakers + b1M := Round(readParam("Bus[1].Mute")) ; Headphones + b2M := Round(readParam("Bus[2].Mute")) ; Work Laptop Send + b3M := Round(readParam("Bus[3].Mute")) ; Comms Send + b4M := Round(readParam("Bus[4].Mute")) ; Recording + cM := b0M + b1M + b2M + b3M + b4M + + if (cM = "5") + { ; Unmute the ones that were unmuted before + adjustToggle("Bus[0].Mute", b0Ms) ; Speakers + adjustToggle("Bus[1].Mute", b1Ms) ; Headphones + adjustToggle("Bus[2].Mute", b2Ms) ; Work Laptop Send + adjustToggle("Bus[3].Mute", b3Ms) ; Comms Send + adjustToggle("Bus[4].Mute", b4Ms) ; Recording + Run %A_AhkPath% "flag.ahk" "off" + } else { + adjustToggle("Bus[0].Mute", True) ; Speakers + adjustToggle("Bus[1].Mute", True) ; Headphones + adjustToggle("Bus[2].Mute", True) ; Work Laptop Send + adjustToggle("Bus[3].Mute", True) ; Comms Send + adjustToggle("Bus[4].Mute", True) ; Recording + b0Ms := b0M + b1Ms := b1M + b2Ms := b2M + b3Ms := b3M + b4Ms := b4M + Run %A_AhkPath% "flag.ahk" "s" "red" + } +Return + +Volume_Up:: + cM := Round(readParam("Strip[3].Mute")) + + if !(cM) + { + cLvl := readParam("Strip[3].Gain") + if (cLvl != "") + { + cLvl += 1 + adjustVolLvl("Strip[3].Gain", cLvl) + } + } +Return + +Volume_Down:: + cM := Round(readParam("Strip[3].Mute")) + + if !(cM) + { + cLvl := readParam("Strip[3].Gain") + if (cLvl != "") + { + cLvl -= 1 + adjustVolLvl("Strip[3].Gain", cLvl) + } + } +Return + +; == Functions == +; =============== +readParam(loc){ + Loop + { + pDirty := DLLCall(VMR_FUNCTIONS["IsParametersDirty"]) ;Check if parameters have changed. + if (pDirty==0) ;0 = no new paramters. + break + else if (pDirty<0) ;-1 = error, -2 = no server + return "" + else ;1 = New parameters -> update your display. (this only applies if YOU have a display, couldn't find any code to update VM display which can get off sometimes) + if A_Index > 200 + return "" + sleep, 20 + } + tParamVal := 0.0 + NumPut(0.0, tParamVal, 0, "Float") + statusLvl := DllCall(VMR_FUNCTIONS["GetParameterFloat"], "AStr", loc, "Ptr", &tParamVal, "Int") + tParamVal := NumGet(tParamVal, 0, "Float") + if (statusLvl < 0) + return "" + else + return tParamVal +} + +adjustVolLvl(loc, tVol) { + if (tVol > 12.0) + tVol := 12.0 + else if (tVol < -60.0) + tVol := -60.0 + DllCall(VMR_FUNCTIONS["SetParameterFloat"], "AStr", loc, "Float", tVol, "Int") +} + +adjustToggle(func, togg) { + DllCall(VMR_FUNCTIONS["SetParameterFloat"], "AStr", func, "Float", togg, "Int") +} + +adjustString(func, str) { + DllCall(VMR_FUNCTIONS["SetParameterFloat"], "AStr", func, "AStr", str, "Str") +} + +fader_to_fader(val) ; Translates MIDI fader values to the VoiceMeeter software faders +{ + ; The upper limit for faders in VM is 12.0 + ; The lower limit for the faders in VM that I would like is -40.0, how low it should go when the physical fader is all the way at the bottom + nval := Round(((val / 127) * 72) - 60) + Return nval +} +; Formula: ((value / max value) * total range) - negative part of range +dial_to_pan(val) +{ + nval := Round((val / 127) - 0.5, 2) + Return nval +} add_vmr_function(func_name) {