2 finger metronome set up

I am new to GP and I was drawn to the software because of a video where David sets the tempo of a pre-recorded Audio or Midi file using two keys. I am sure most of you have seen it. I can’t however, find a way to do that set up. It seems that I will have to script something for it- which I will NOT be able to do.

Am I missing something? Can someone let me know if they are using this technique and how they set it up?



Was that Steely Dan related?

yes! he was doing Josie and a couple of other tunes that had complex keys and he played a few of those tracks with that set up and did the accents with his right hand, which I thought was great. I forgot to mention that I play with a few guys that hate the idea of ANY backing tracks and this would solve a lot of issues for me.

At around 7:20.

Right this is the one. Looking for the way to set that up.
It’s not in any of the docs that I have found Also, in this forum there has been some discussion about it and I understood that there would be some scripting involved.

[Wrong info: deleted].

It is scripting. It’s not really comfortable to use, but it works.
A midi file is loaded and then, by tapping two notes, the script will step through the midi notes according to the used quantization.
So you don’t do anything with the speed or BPM, it’s just going step by step as fast as you are tapping.
I actually made a rackspcae to play around with this…
I will upload it tomorrow (it’s bed time now), so you will have at least a solid starting point for your own experiments.

1 Like

OK… here we go! :slight_smile:
Since this rackspace still was in an experimental phase i had to do some “cleanup” first, so it took a bit longer…

This rackspace will do the following things:

  • load a specified midi file (has to be done in the script!)
  • do a remapping of particular midi tracks to a specified midi channel (has to be done in the script!)
  • step sequentially through the midi events of that file according to the quantization setting using two diffrent trigger controls

You can

  • set the quantization value with a knob widget
  • see the current position of the midi sequence
  • set the used note/key pair as stepping triggers or
  • use a pad widget as a stepping trigger (could be midi-mapped to a pedal or whatever)
  • use a pad widget to reset the sequence to start (could be midi mapped to a certain note or midi controller)
  • use a widget as “panic-button” (sends all notes off & resets midi)

This is the code of the script:

MidiStepIn : MidiInBlock

cs : MidiSequence
trackCount, quantization, UStepKey : integer
padStep, padReset, lblPosition, knbQuant, btnPanic, knbUStepKey : widget

//user function to calculate the quantization from the knob widget's value
function SetQuantization(kVal : double) returns integer
exponent, quantValue : double
    exponent = ScaleRange(kVal, 0.0, 4.0)
    quantValue = Power (2.0 , exponent)
result = Round(quantValue)
SetWidgetLabel(knbQuant, result)
//user function to handle the MIDI-Stepping
function MidiStep()
notes : MidiMessage Array
aNote : MidiMessage
index : integer
trackIndex : integer
bar, beat, tick : integer

    bar = MidiSequence_GetCurrentBar(cs)
    beat = MidiSequence_GetCurrentBeat(cs)
    tick = MidiSequence_GetCurrentTick(cs)
    if MidiSequence_EndOfSong(cs) then
    SetWidgetLabel (lblPosition, "Pos: " + bar + " / " + beat + " / " + tick)
    MidiSequence_CollectEventsNow(cs); //fetch all events from current position

    notes = MidiSequence_GetCurrentEvents(cs, 3) // Get current events from track #3

    for index = 0; index < Size(notes); index = index + 1 do
        aNote = notes[index]
        SendNow(MidiStepIn, aNote)

    //load the midi file (!!! use a a"/" instead of "\" for path separator !!!)
   MidiSequence_LoadStandardMidiFile(cs, "D:/MIDI-files/The-Model.mid")
   trackCount = MidiSequence_GetTrackCount(cs) //get number of tracks of midi file
   quantization = SetQuantization (GetWidgetValue (knbQuant)) //get quantization value from widget
   MidiSequence_Quantize(cs, quantization ) // Quantization may be 1/2/4/8/16
   //map events coming from track 2 & 3 both to MIDI channel 1
   //change remapping to your needs -> add/remove according code lines
   MidiSequence_MapOutputChannel(cs, 2, 1)
   MidiSequence_MapOutputChannel(cs, 3, 1)
   UStepKey = ParamToMidi(GetWidgetValue (knbUStepKey))

// Use this as a finger clock -- pressing the trigger control (widget or two notes) behaves 
//like a manual clock to sequence through the MIDI events of the loaded file

//use pad widget as a trigger to step through the MIDI file
On WidgetValueChanged (pVal : double) from padStep
    if pVal > 0.6 then

//use the two trigger notes to step through the MIDI file (use knob widget to set the according notes)
On NoteEvent(m : NoteMessage) from MidiStepIn
    //if the note event is a trigger note, step forward
    if GetNoteNumber(m) == UStepKey or GetNoteNumber(m) == UStepKey-2 then
        if IsNoteOn(m) then
    else //all other note will be played
        SendNow(MidiStepIn, m) //just send out note event

//reset the midi sequence to start
On WidgetValueChanged (pVal : double) from padReset
bar, beat, tick : integer
    bar = MidiSequence_GetCurrentBar(cs)
    beat = MidiSequence_GetCurrentBeat(cs)
    tick = MidiSequence_GetCurrentTick(cs)
    SetWidgetLabel (lblPosition, "Pos: " + bar + " / " + beat + " / " + tick)

//Panic button = all notes off & back to start
On WidgetValueChanged (pVal : double) from btnPanic
    if pVal > 0.6 then
        Panic() // Stop any sounds that were being held

//use knob to set quantization for sequence stepping
On WidgetValueChanged (kVal : double) from knbQuant
    quantization = SetQuantization (kVal)
    MidiSequence_Quantize(cs, quantization )

//use knob widget to set the Upper note/key used to step forward
On WidgetValueChanged (kVal : double) from knbUStepKey
    UStepKey = ParamToMidi(kVal)
    SetWidgetLabel (knbUStepKey, "" + NoteNumberToNoteName(ParamToMidi(kVal)-2) + "/" + NoteNumberToNoteName(ParamToMidi(kVal)))

And here is the gigfile for download:
midistepper.gig (115.8 KB)

I hope this helps somehow…
…and maybe, some day in the future, we might have some better options to do such things?!
However, have fun with it! May it be useful! :vulcan_salute:
Cheers, Erik


@schamass , you da man! I was looking to do this myself, but you beat me to it!



Great stuff! :slight_smile:
Included here, as well.

1 Like

Thanks for the info! I really appreciate it. I am going to try and ill let you know how it goes!
Best Regards!


so this only works if scripted? i’m new to the scripting as i haven’t had a need for it until now. I would like to see this process simplified in an update as i can really make use of it! Thanks for the info & the gigfile!

1 Like

love it , this script is a game changer for me as a guitar player and one finger keyboard guy in a five piece classic rock cover band . Also I enjoy practicing my parts at home to the chord changes , accompaniment if you will without typical playback , this routine is a thousand times more creative and can go off in different tangents compared to triggering a midi file with the midi file player for example , especially when we are typically just referencing chords , or really chord changes . Being a guitar player my hands are tied up so for me utilizing a standard sustain switch pedal like a Roland DP-2 to drive the sequence instead of two midi note on’s works for me . My workaround at the moment is a midi pipe that converts the CC I’m stepping with into subsequent note on’s ; that is a note on for the depress and a note on for the release , that gets the tempo to a reasonable facility , substituting a pedal depress and release for a two note on performance with fingers .
My query is thus :
Can this script be tweaked to incorporate CC events , say 127 and zero in place of the note on events ?

Thanks for this script it’s a guitarists dream game changer for me !

1 Like

Actually, had I been thinking at the time, I would have done the triggers differently.

I would have had the callbacks tied to two widgets (step and reset) rather than directly to notes.

Users could then just map the widgets to whatever messages they want.

Probably wouldn’t be hard to modify the script to do that.

1 Like

I like where you are going with this wink wink nudge say please say more !
I would also add for the guitarists out here , some forethought or facility to include that each , or multiple let’s say CC could …
" if GetNoteNumber(m) == UStepKey or GetNoteNumber(m) == UStepKey-2 then
if IsNoteOn(m) then
could MidiStep , pasted a chunk of code there without really understanding it
but the idea is that either CC127 or CC0 of some CC# could theoretically MidiStep the sequence therefore allowing faster MidiStep than a single CCvalue could .

In essence going up and down , or depress and release action of a pedal could substitute for what two separate midi note messages are doing here …
Just my two cents … thanks !!