2020-04-24 22:22:48 -05:00
#NoEnv
#SingleInstance force
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
#UseHook
2020-05-11 22:34:22 -05:00
#Persistent
2020-04-24 22:22:48 -05:00
ListLines Off
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetTitleMatchMode RegEx
StringCaseSense Off
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
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
}
2020-05-11 22:34:22 -05:00
; == 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 Out
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[0].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 1 :
Lvl := dial_to_pan ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[0].Pan_x " , Lvl )
2020-05-11 22:34:22 -05:00
Case 2 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[0].Solo " , val )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[0].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Case 4 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[0].B2 " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 2 : ; The second fader: Work Laptop In
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Bus[2].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[2].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 3 : ; The third fader: Desktop Audio
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[3].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 1 :
Lvl := dial_to_pan ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[3].Pan_x " , Lvl )
2020-05-11 22:34:22 -05:00
Case 2 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[3].Solo " , val )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[3].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Case 4 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[3].B2 " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 4 : ; The third fader: Comms In
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Bus[3].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[3].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 5 : ; The fifth fader: Comms Out
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[4].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 1 :
Lvl := dial_to_pan ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[4].Pan_x " , Lvl )
2020-05-11 22:34:22 -05:00
Case 2 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[4].Solo " , val )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[4].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Case 4 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[4].B2 " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 6 : ; The sixth fader: Speakers
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Bus[0].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[0].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 7 : ; The seventh fader: Mic
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Bus[1].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[1].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 8 : ; The eighth fader: Music
Switch cc
{
Case 0 :
Lvl := fader_to_fader ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[2].Gain " , Lvl )
2020-05-11 22:34:22 -05:00
Return
Case 1 :
Lvl := dial_to_pan ( val )
2020-05-12 22:59:34 -05:00
adjustVolLvl ( " Strip[2].Pan_x " , Lvl )
2020-05-11 22:34:22 -05:00
Case 2 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[2].Solo " , val )
2020-05-11 22:34:22 -05:00
Return
Case 3 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[2].Mute " , val )
2020-05-11 22:34:22 -05:00
Return
Case 4 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Strip[2].B1 " , val )
adjustToggle ( " Strip[2].B2 " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Case 10 : ; VoiceMeeter recorder controls
Switch cc
{
Case 7 : ; Rewind
2020-05-12 22:59:34 -05:00
adjustToggle ( " Recorder.REW " , val )
2020-05-11 22:34:22 -05:00
Return
Case 8 : ; Fast Forward
2020-05-12 22:59:34 -05:00
adjustToggle ( " Recorder.FF " , val )
2020-05-11 22:34:22 -05:00
Return
Case 9 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Recorder.Stop " , val )
2020-05-11 22:34:22 -05:00
Return
Case 10 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Recorder.Play " , val )
2020-05-11 22:34:22 -05:00
Return
Case 11 :
2020-05-12 22:59:34 -05:00
adjustToggle ( " Recorder.Record " , val )
2020-05-11 22:34:22 -05:00
Return
Default:
Return
}
Default:
Return
}
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
2020-05-18 16:13:20 -05:00
nval := Round ( ( ( val / 127 ) * 72 ) - 60 )
2020-05-11 22:34:22 -05:00
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
}
2020-04-24 22:22:48 -05:00
; == HOTKEYS ==
; =============
Volume_Mute::
2020-05-12 22:59:34 -05:00
b0M := Round ( readParam ( " Bus[0].Mute " ) ) ; Speakers
b1M := Round ( readParam ( " Bus[1].Mute " ) ) ; Headphones
2020-05-11 22:34:22 -05:00
cM := b0M + b1M
if ( cM = " 2 " )
{ ; Unmute the ones that were unmuted before
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[0].Mute " , b0Ms ) ; Speakers
adjustToggle ( " Bus[1].Mute " , b1Ms ) ; Headphones
2020-05-11 22:34:22 -05:00
} else {
if ! ( b0M ) ; Speakers
{
b0Ms := True
} else {
b0Ms := False
}
if ! ( b1M ) ; Headphones
{
b1Ms := True
} else {
b1Ms := False
}
; Mute
2020-05-12 22:59:34 -05:00
adjustToggle ( " Bus[0].Mute " , " 0 " ) ; Speakers
adjustToggle ( " Bus[1].Mute " , " 0 " ) ; Headphones
2020-04-24 22:22:48 -05:00
}
2020-05-11 22:34:22 -05:00
Return
2020-04-24 22:22:48 -05:00
; == 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 )
2020-04-29 20:39:18 -05:00
tVol := 12.0
2020-04-24 22:22:48 -05:00
else if ( tVol < - 60.0 )
2020-04-29 20:39:18 -05:00
tVol := - 60.0
2020-04-24 22:22:48 -05:00
DllCall ( VMR_FUNCTIONS [ " SetParameterFloat " ] , " AStr " , loc , " Float " , tVol , " Int " )
}
2020-05-12 22:59:34 -05:00
adjustToggle ( func , togg ) {
DllCall ( VMR_FUNCTIONS [ " SetParameterFloat " ] , " AStr " , func , " Float " , togg , " Int " )
}
adjustString ( func , str ) {
DllCall ( VMR_FUNCTIONS [ " SetParameterFloat " ] , " AStr " , func , " Float " , str , " Str " )
2020-04-24 22:22:48 -05:00
}
2020-05-11 22:34:22 -05:00
2020-04-24 22:22:48 -05:00
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
}
2020-05-18 16:13:20 -05:00