My use case for this idea, is that sometimes I want to add vibrato to a sound, without having to remove my hands (and using that sound one keyboard which does not have keyboard). In that case I can assign a switch of my MIDI pedal board to mimic the vibrato setting of a plugin (IK Multimedia MixBox in my case). But this idea can be used for all cases where a button is needed instead a knob.
However, when pressing the switch the vibrato gets immediately at 100% which sounds unnatural. Also, many other effects causes crackles/distortion when changing too fast.
This script slowly moves the knob towards the correct direction. When the button is pressed, it slowly goes to a set maximum value, and when released iti goes slowly to a set minimum value (even when halfway and changing the switch of course).
See the video for a small demo.
The script is shown below.
var
Switch : Widget
MixBoxPlugin : PluginBlock
MidiIn : MidiInBlock
currentValue : double = 0.0
minValue : double = 0.2
maxValue : double = 0.8
speed : double = 2.0 // sec
lastMs : double = 0.0
direction : integer = 0 // -1 = down, 0 = stay, 1 = up
// nt : NoteTracker
const
PARAMETER_INDEX : integer = 3
Function SetParameterValue()
SetParameter(MixBoxPlugin, PARAMETER_INDEX, currentValue)
end
Initialization
currentValue = minValue
SetParameterValue()
End
On WidgetValueChanged(newValue : double) from Switch
direction = if newValue == 0.0 then -1 else 1 end
lastMs = TimeSinceStartup()
SetTimersRunning(true)
End
On TimerTick(ms : double)
// var notes : integer array
if direction != 0 then
// if NoteTracker_NoteOnCount(nt) == 0 then
// currentValue = if direction == -1 then minValue else maxValue end
// direction = 0
// else
currentValue = currentValue - (((lastMs - ms) / 1000) / speed * ((maxValue - minValue) * direction))
lastMs = ms
if currentValue <= minValue then
currentValue = minValue
direction = 0
elsif currentValue >= maxValue then
currentValue = maxValue
direction = 0
end
// end
if direction == 0 then
SetTimersRunning(false)
end
SetParameterValue()
end
End
// On NoteEvent(m: NoteMessage) from MidiIn
// var notes : integer array
//
// if IsNoteOn(m) then
// NoteTracker_GotNoteOn(nt, GetNoteNumber(m))
// else
// NoteTracker_GotNoteOff(nt, GetNoteNumber(m))
// end
//
// notes = NoteTracker_GetHeldNotes(nt)
// NoteTracker_GotNote(nt, m)
// SendNow(MidiIn, m)
// End
The commented out lines are for the NoteTracker, in case you want to have it immediately to the min/max value when no keys are pressed, but I found out this works too tricky so I commented it.
The variables which can be set are:
Switch : Widget: The name of the switch (needs to be assigned to be accessible by GPScript).
MixBoxPlugin : PluginBlock: The plugin block that contains the plugin parameter to be changed
// MidiIn : MidiInBlock: The MIDI in block where the keys are checked for the note tracker
minValue : double = 0.2: The minimum value of the parameter value (0-1)
maxValue : double = 0.8: The maximum value of the parameter value (0-1)
speed : double = 2.0 // sec: The amount of seconds between moving from minimum to maximum or vice versa
const PARAMETER_INDEX : integer = 3: The parameter index of the plugin (MixBoxPlugin in my case) to be set
Future improvements
- It uses the timer tick function, which is not too precise (when called). Maybe using a generator (ramp) would be better/more precise.
- The upward and downward speed are equal. This could be two different values. See below.
UPDATE
(Below is a version with the note tracker code removed and with separate up/downward speeds, and a few small code improvements.
var
Switch : Widget
MixBoxPlugin : PluginBlock
currentValue : double = 0.0
minValue : double = 0.2
maxValue : double = 0.8
upSpeed : double = 2.0 // sec
downSpeed : double = 0.5 // sec
lastMs : double = 0.0
direction : integer = 0 // -1 = down, 0 = stay, 1 = up
const
PARAMETER_INDEX : integer = 3
Function SetParameterValue()
SetParameter(MixBoxPlugin, PARAMETER_INDEX, currentValue)
end
Initialization
currentValue = minValue
SetParameterValue()
End
On WidgetValueChanged(newValue : double) from Switch
direction = if newValue == 0.0 then -1 else 1 end
lastMs = TimeSinceStartup()
SetTimersRunning(true)
End
On TimerTick(ms : double)
var multiplier : double = 0.0
if direction != 0 then
multiplier = (ms - lastMs) * (maxValue - minValue) / 1000.0
if direction == 1 then
currentValue = currentValue + multiplier / upSpeed
else
currentValue = currentValue - multiplier / downSpeed
end
lastMs = ms
if currentValue <= minValue then
currentValue = minValue
direction = 0
elsif currentValue >= maxValue then
currentValue = maxValue
direction = 0
end
if direction == 0 then
SetTimersRunning(false)
end
SetParameterValue()
end
End