Detect Single, Double and Long" pressed Keys/MIDI-Event

Hello together,

yesterday I wrote a simple preset to detect how a midi pad on my Arturia BeatSept will be triggered once, twice or hold long. Because of using timers I have to create thees translator-sequence for every pad I woul handle this way - in my case around 20.

This routine has the ability to be enhanced for tripple presses … an so on. You can also modify the time vor the pad time recognition by changing the value of xa (currently set to 200ms).
At the beginning you have to start once the init-translation I placed on a different pad, because this is just an example.

So my questions are:

  • Is this a good implementation for this task?
  • Is there a limitation related to the number of used timers?
  • What about the performance when using timers?

Thans and best regards

StefDoublePressedPad.bmtp (5.1 KB)

Unfortunately, I cannot get your project file to load since you are using the global variables starting with x. There is a bug in version 1.9.0 that has problem reading global variables starting with x. We just discovered this recently. Here is the post.

Your project file may actually be more elegant then the one I did last year. It is hard to tell right now because, my version of MT Pro is not loading your project file correctly. If you can re-post with different global variables. I can dig in deeper.

In my project file I use a single timer “Gesture Dispatcher” to handle gesture management of all buttons.

I set up the global variables staring with g0 for the buttons I want for gestures in this example, in the “Initialize Global Variables” translator. If you go beyond g9, then probably use h0 for the next so not to collide with other global variables.

For any new gesture I copy and paste the set of rules into a new group and then change the global variable for the button (CC or Note) for that gesture. There is a possibility of 9 separate gestures for each button.

It is a bit of a pain to go through and modify the rules which define:

Comparison of the target incoming note or cc number
if gc==g0
the target incoming MIDI Channe
if gb!=0
and the type (Note or CC)
if ga!=1
where 1 is note and 2 is CC

But once it is set up for the 9 new translators, it can be scaled quite nicely and really only requires the one timer.

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

Hi, I was able to make some changes to your methodology which I think is rather nice.

Beyond the x global variable but (I changed to g0,and g1), I noticed that you had rules that would not work

If g0==1 then g0=2
if g0==2 then exit rules skip outgoing action.

Since the first rule modifies g0, the second rule would always execute

You should do this
if pp==1 then g0=2
if pp==2 then exit rules, skip outgoing action

With that I simplified a bit further by just using a counter to increment on press and or release

Then you look at the count of g0 to determine the gesture

if g1!=1 then skip next rule
if g0==0 then Log “Pressed and Held”
if g0==1 then Log “Pressed and released”
if g0==2 then Log “Pressed, twice and held”
if g0==3 then Log “Pressed and released twice”
if g0==4 then Log “Pressed 3 times and held”
if g0==5 then Log “Pressed and released 3 times”

Attached is the modified file.

StefDoublePressedPad–sjc.bmtp (4.7 KB)

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

I really like your methodology. It is much less complex than mine to maintain.
Here I added a mechanism to use any note and calculations to determine which output program number and channel to send on. With just 4 translators, you can handle up to 25 note gestures of

  1. press and hold
  2. single press and release
  3. release after single press and hold
  4. double press and hold
  5. double press and release
  6. release after double press and hold
  7. triple press and hold
  8. triple press and release
  9. release after triple press and hold

So essentially 9 gestures over 25 buttons or 225 messages

Enjoy and thanks for sharing your methodology as I’m sure I will be using it in the future.

StefDoublePressedPad-sjc-multi.bmtp (5.3 KB)

Edit, although the release after press and hold is not yet 100% worked out. It is always the same message for each button no matter how many presses.

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

Hello Steve,

I converted my routine to work with g0, g1 and g9, but I still get somme errors when starting BMT. So I didn’t take a look at you modified versions.
You commended …

If g0==1 then g0=2
if g0==2 then exit rules skip outgoing action.

Well this situation should normaly not occur, because g0 should be set to 2 by releasing the MIDI note. But why should this work? I thought that the varaible will be update immediately so I can use it in the next line.

If you use this routine to capture different note values it will not work if you use more then one pad/note at the same time. I think that should occur if you use one pad as a kind of “shift key” … but I have to think about this, maybe the counter shoulb be free … I’m not shure.

The basic idea bheind my routine, or you call it methodology is a simple FSM (finite state machine) and the only termination criteria, the timeout if the next step do not occur.

But, back to a question of mine … is there a limitation or “best practice” regarding the amount of timers used in one project?

Thanks and best regards

I tried this version StefDoublePressedPad–sjc.bmtp (4.7 KB) and it still runs in an infinit loop after pressing the first key. It is a self triggering routine, because the outgoing action retriggers the routine again …

But maybe it’s a problem of my external MIDI loopback … :wink:

This file will initialize your global variables on project open so should work. The last one I posted, you would have to press the ESC key to initialize them. I use the timer Init to handle this with two translators that trigger it.

I also fixed it so that upon release it will send PC on MIDI CH 1 the same gesture count as hold.

My guess is that you were not initializing the global variable since I changed the incoming action for that to only ESC key on the last iteration.

Gestures-Steve-2021-06-21.bmtp (5.9 KB)

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

I think best practice would be using the least amount of timers required. With a lot of timers eventually you would run out of either processing power or start creating possible global variable conflicts and collisions.

For instance, ideally only one translator should ever modify a global variable and the rest read them as they are not atomic and could cause a race condition of two translators are trying to change the same global variable at the same time.

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

Hey guys,

Really cool preset - thank you for making it public.

I’ve managed to tweak it to suit my needs which is basically just sending out note on messages rather than program changes however I’d like to follow those note on messages with note off messages some short time after the note ons are sent (as demonstrated in one of the BMT tutorials) but that method doesn’t seem to work in this case…

Any help or ideas here would be much appreciated,


Hi, in general the easiest way to do this is with a timer.

  • Translator to Trigger a one shot timer "Send-Note - capture note number in global variable (ie ga)
  • Translator with in coming timer “Send-Note” outgoing action with note-on note number from global variable - no delay
  • Another Translator incoming timer “Send-Note” outgoing action with note on note number from global variable with whatever delay you want

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

I’m so pleased this thread has resurfaced! I’m looking to implement the very save feature into ARC.

With regards to the ‘x’ vars, has this been rectified yet?



I think there is still a problem with x variables in 1.9.0. Until that is resolved you can use global variables with any other letter.

As of 1.9.0 you can use variables beginning with o-w as global variables as long as their last letter isn’t the same as the first letter.

For example
oa-on, op-oz, o0-09 is global where oo is local
pa-po, pq-pz, p0–9 is global where pp is local

So there are a lot more global variables available in 1.9.0

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

Nice one Steve, thanks for the speedy reply and advice.

I’ve tried to implement your suggestions but it doesn’t seem to be working. Would you mind taking a look at my project and letting me know what I’m doing wrong? Also I don’t quite understand what “release after single/double/triple press and hold” means and I’m wondering if it would be possible to tweak the rules to forgo these three gestures in favour of putting all gestures onto the same channel? Does that make sense?

Let me know,


Gestures-Tony-2021-11-04.bmtp (6.9 KB)

Hi ,

For your requirements, I think you are over complicating things. You said you just wanted to automatically send a note off after a specific interval after the note-on message. The attached project is as I described in my last post. That does just that. If you want the note-off delay to change, simply change that in the last translator outgoing action.
Note-Off with Delay.bmtp (1.5 KB)

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

Hi @SteveC

I’m specifically trying to send a note off that corresponds to the notes on sent by the gestures in the project you shared in this thread. That’s the functionality I’m looking for… maybe it’s because there’s a delay inherent in the notes sent out by the gestures that isn’t being accounted for…?

Perhaps, that is why I went the simpler route with your specific requirements instead of the original Gestures discussion. In gestures, we need to add time to determine the number of taps, where in the latest project file, this is not necessary.

Steve Caldwell
Bome Customer Care

Also available for paid consulting services:

@SteveC I see. So how would you recommend following the gesture note ons with note offs?

What gesture would you use for this? If only single button push I would recommend not using gestures and instead using the last project file I posted.


Hey @SteveC,

I’m making use of single/double/triple press as well as single/double/triple press + hold so 6 gestures. I know how to setup the method you kindly posted previously however my use case is heavily dependent on the gestures which are awesome however the held notes are causing some issues I think. Do you think there might be some other way to capture the output of the last translator in your original gestures project?

Thanks for help so far in any case!

Hi, let me show you another technique that is more complicated but pretty flexible.

In this model we set different note numbers for different buttons. This example shows Note 1 for Button 1 as defined by the global variable g0 and note 2 as defined by g1. You can duplicate whole sections for each incoming note but rules will need to be changed for the note number

Note 1 has this rule in all of the outgoing actions

// Note
if gc!=g0 then exit rules, skip Outgoing Action

Note 2 has this rule in all outgoing actions

// Note
if gc!=g1 then exit rules, skip Outgoing Action

You can enable or disable gestures to stop outgoing actions to happen on those gestures.

Translators 1.8 and 1.9 handle the note-on and note-off with delay as you requested for double press

Translator 1.4 sends a program change for the same button with a single press
All other gestures are disabled.

Translators 1.16-1.26 handle gestures for the second note g1

Again a bit harder to set up as you need to ensure the rules are changed for each translator based on the desired note number, but it is quite more flexible.

I hope this helps.

I set up my alias as shown you will need to change these to the devices that you use.


gesture-example-2021-11-04.bmtp (19.1 KB)

Steve Caldwell
Bome Customer Care

Also available for paid consulting services: