Here’s a YouTube video I just uploaded showing how GPScript can be used to implement an AutoSustainer to sustain notes automatically until you release all keys AND then start playing a new chord. It’s an approach that I’ve depended on for years with several bands and had previously implemented it using the ‘borax’ objects in MaxMSP. Now it can be done natively.
There’s also an example of a chord recognizer and you can see chord names being displayed as I play the chords on a keyboard.
The script in this video also shows the syntax for writing functions. This stuff is all implemented and will be available in the next beta.
var MasterKeyboard : MidiInBlock
AutoSustain : AutoSustainer
Initialization
AutoSustain.AutoSustainer_SetTarget(MasterKeyboard)
End
On NoteEvent(m : NoteMessage) from MasterKeyboard
AutoSustain.AutoSustainer_Play(m)
End
On PitchBendEvent(m : PitchBendMessage) from MasterKeyboard
AutoSustain.AutoSustainer_Stop()
End
Requires a MidiInBlock with the script name ‘MasterKeyboard’. Routing is just as if there were no scripting involved at all. Touching the PitchBend wheel stops all pending chord. Remove this callback if you don’t need it.
The only problem I see is when using a different MIDI channel than 1. What happens is that NoteOn events will be on channel (say) 5, but the NoteOff events are sent on channel 1. I guess that the AutoSustainer makes use of the NoteTracker internally which does not save the MIDI channel of incoming NoteOn events.
Perfect! Thank you for your quick anwser. I tried to find a way that it works also with all the settings (velocity, key- and velocitysplit) from the MidiInBlock.
Here is my result:
var MasterKeyboard : MidiInBlock
AutoSustain : AutoSustainer
AUTOSUSTAIN_ON_OFF : Widget
Initialization
AutoSustain.AutoSustainer_SetTarget(MasterKeyboard)
End
On NoteEvent (m : NoteMessage) from MasterKeyboard
var blockfilter : boolean
var velo : integer
velo = m.GetVelocity()
blockfilter = false
if (m.IsNoteOn()) then
// Block all notes lower than MIN note from the MidiBlock settings
if (GetNoteNumber(m) < MasterKeyboard.GetMinNoteFromMidiInBlock()) then blockfilter = true end
// Block all notes higher than MAN note from the MidiBlock settings
if (GetNoteNumber(m) > MasterKeyboard.GetMaxNoteFromMidiInBlock()) then blockfilter = true end
// Block all notes lower than Min Velocity from the MidiBlock settings
if (velo < ParamToMidi(MasterKeyboard.GetParameter(150)) && velo > 0) then blockfilter = true end
// Block all notes higher than Man Velocity from the MidiBlock settings
if (velo > ParamToMidi(MasterKeyboard.GetParameter(151))) then blockfilter = true end
end
if (blockfilter == false) then
if (m.IsNoteOn()) then
if (MasterKeyboard.GetParameter(154)==1) then
// Calculate the new veloctiy when the MidiBlock setting is Constrain
if (velo < ParamToMidi(MasterKeyboard.GetParameter(152))) then velo = ParamToMidi(MasterKeyboard.GetParameter(152)) end
if (velo > ParamToMidi(MasterKeyboard.GetParameter(153))) then velo = ParamToMidi(MasterKeyboard.GetParameter(153)) end
else
// Calculate the new veloctiy when the MidiBlock setting is Scale
velo = (Round(Scale (velo, 0, 127, ParamToMidi(MasterKeyboard.GetParameter(152)), ParamToMidi(MasterKeyboard.GetParameter(153)))))
end
end
if (GetWidgetValue(AUTOSUSTAIN_ON_OFF) > 0) then
// Sending out the notes with the new veloctiy and transpose setting from MidiBlock over AutoSustain
AutoSustain.AutoSustainer_Play(Transpose(WithVelocity(m,velo),MasterKeyboard.GetTransposeFromMidiInBlock()))
else
// Sending out the notes with the new veloctiy and transpose setting from MidiBlock without AutoSustain
MasterKeyboard.SendNow(Transpose(WithVelocity(m,velo),MasterKeyboard.GetTransposeFromMidiInBlock()))
end
end
End
AutoSustainer works beautifully! It’s now part of my standard rackspace, merged with my metronome volume script. I can turn the sustain on and off using a button on my Livid DS-1 controller.
Using the Autosustain Script from LeeHarvey which is absolutly great and works very well.
However, in my case when using this script the overall GP tranpose does not work any more, which I would still need.
Another (minor) thing is that after approx 3min holding the key, the sound starts to get deteriorated.
Any idea, especially for the overall transpose?
Well, not much info from you to elaborate some advice (what plugin are you using, what computer, audio interface, it´s settings (sample rate/buffer size)
I’ll have a play with AutoSustainer to remember things…
Hello @keyman,
Thank you for your feedback!
Here the infos on my setup:
Plugins: Chordz, CollaB3
Keys: Studiologic MP-113
Interface: Steinberg UR22C
Dell Inspiron 7580 i7 32GB RAM, Win10
ASIO 44,1kHz, 512 Samples
OK, thank you very much for your feedback. I will try to circle the problem by stepwise changing my setup.
Any idea for the overall GP transpose function?
var MIN : MidiInBlock
AutoSustain : AutoSustainer
tr : Integer
on NoteEvent(m:NoteMessage) from MIN
if IsNoteOn(m) then
tr = GetGlobalTranspose()
AutoSustain.AutoSustainer_Play(Transpose(m, tr))
end
end
initialization
AutoSustainer_SetTarget(AutoSustain, MIN)
end
Hello @pianopaul,
thanks for the feedack and the script. My understanding was to use it instead of the original script from @LeeHarvey. However, the new script seems not to stop any tones, which was a feature of LeeHarveys script and which is mandatory for me.
But maybe there is a misunderstanding: is your script ment only as starting point for my own programming to include the features of LeeHaeveys script? Or should I add your scripting to the orignal script somehow?
Sorry for still being new to GP scripting…
I am heavily/happily using the autosustainer script from @LeeHarvey as shown above. It includes a widget to switch autosustain on or off.
What I am missing would be a second widget which stops the autosustain of the currently sustained note, however does not switch off the autosustain mode (i.e. when next key is pressed, the note is again autosustained).
Is there a way to extend the script with such a widget?
Thanks very much already in advance!
Thanks to the developers of GP for the possibility of scriptlets since version 4.
I have solved this for me more elegantly with a scriptlet.
Maybe one or the other can also use this.
Greetings,
New to GP and with zero programming experience I have successfully, with the help member’s examples, been able to cobble together a couple of scripts to meet my needs. Thanks to all.
Would it be possible to add code to the autosustain script to permit a choice of specific channels?
Example: channel 2 - no sustain, higher channels ‘sustain all’ with the ability to enable/disable via variation, rackspace or widgets.
I have already achieved this by inserting channel constrainers in the path and am wondering if there is possibly a more elegant and flexible solution via programming.