2 finger metronome set up

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:

Var
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
var
exponent, quantValue : double
    exponent = ScaleRange(kVal, 0.0, 4.0)
    quantValue = Power (2.0 , exponent)
result = Round(quantValue)
SetWidgetLabel(knbQuant, result)
End
   
//user function to handle the MIDI-Stepping
function MidiStep()
var
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
        MidiSequence_ResetToStart(cs)
    end
        
    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)
    end                                  
End

initialization
    //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
   Print(trackCount)
   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))
end


// 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
        MidiStep()
    end            
End

//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
            MidiStep()
        end
    else //all other note will be played
        SendNow(MidiStepIn, m) //just send out note event
    end
End

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

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

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

//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)))
End

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

8 Likes

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

X

2 Likes

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!

2 Likes

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
MidiStep()"
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 !!

Hi.

I have downloaded, opened and inspected the .gig file from this thread.

It is not clear to me what are the further steps necessary to have a working setup for this. Is there a script already in the .gig file? If so, I apologize, but I don’t see it. Where is it found?

What more does one need to know and do to get it all operational?

Thanks!

The script is under the Window menu in Current Rackspace Script Editor.

2 Likes

Thanks!

I have provided a file in the code, and it compiles and reports 1 track available, as expected. However, when I click on the Step Forward widget I get an error, like so:

MIDI Stepper (Rackspace) - GPScript System Function Exception: MidiSequence_GetCurrentEvents. Invalid track number: 3
No source information available - check GPScript options

Where should I be looking to fix this?

My Init block looks like this:

initialization
//load the midi file (!!! use a a"/" instead of "" for path separator !!!)
MidiSequence_LoadStandardMidiFile(cs, “C:/Users/Steve/Desktop/ALL OF ME-ChordMarkers.mid”)
//MidiSequence_LoadStandardMidiFile(cs, “C:/Users/Steve/Desktop/Ripchord.mid”)

trackCount = MidiSequence_GetTrackCount(cs) //get number of tracks of midi file
Print(trackCount)
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)

MidiSequence_MapOutputChannel(cs, 1, 1) // sj

UStepKey = ParamToMidi(GetWidgetValue (knbUStepKey))
end

Finger tap resources

See the Short from here.

You can use the MIDI File Player now.

2 Likes

Thanks!

Using the MIDI File Player is clearly the way to go, it has multiple advantages.

However, I am observing a problem.

Working essentially from the example of SingleStep.gig, I have sometimes been able to step forward correctly thru a MIDI file, but most times the 2nd step jumps immediately to the end of the file.

There is very little to the setup, just two buttons mapped to p534 StepForward and p535 StepReset. I don’t see anything in front of me that looks like it could be causing such a jump.

Is there possibly a bug here?

OK, I think I found the problem. Quantization was set to None.

After setting Quantization to 1, things seem to have stabilized.

If I am stepping thru block chords, I find that each chord sounds until I advance to the next step, at which time the next chord sounds.

Suppose I am “done for the moment” and want to silence a sounding chord.

How can I accomplish that? Is there a parameter in the MIDI File Player to the effect of “silence open notes”? Some other way?