Quantising input to BomeBox

CreepyPants

2020-04-13 00:51:55

I press buttons on a box that makes MTPro decide on a bunch of CCs to send out.

>>>I need to create a routine to 'quantise' the output so if several buttons are pressed within a short amount of time, the Timers which create the output all run closer to the same time than they are currently running. (I think)<<<

I'm running into an issue and please understand it is one hellacious rabbit hole to wander down if we want to get into the why/what/how bits, but basically I'm getting timing issues from the receiving device in that part of the CC's are arriving before the beat and some just enough after that the sequencer (receiving device) is affecting some Tracks one beat late (my options on the quantise on the device are Instant, Beat, and then coarser resolution from there).

I'm thinking about MTPro holding onto the output for a short time to sort of 'quantise' the output, but I'm at a loss as to how to approach the logic on this. I'm also not sure that this will resolve what issues I'm having, but really this is difficult for me to explain (as Steve knows because this is still that same project, Steve!  LOL - BTW - It's almost done. I'm actually jamming with it (had a few bad setbacks) and it's runnig the lights and everything)

Sordid Details:
When a button is pressed, MTPro decides which tracks this is going to turn on/off and sets up an output mask, which is 16 bits of a variable representing 16 Tracks with 1 being On and 0 being Off. There are roughly 3 groups of these (it gets more complex, but I think this is the salient part).

Once it has decided what the output mask is going to be, it triggers the Output Timers which just cycles through the 16 bits, checks the status (On/Off;1/0) and compares it to the previous status. If the status changes, it forms the MIDI CC msg and sends it.

There are 3 groups and several output timers for each group: One updates lights on a button box, one decides lighting cues and sends that data out via MIDI over ethernet, both of which are not an issue. The two in each of the 3 groups that are an issue are sending info to my sequencer, one each for two different applications/techniques of muting or playing Tracks.

The Initial Delay on these timers is 0ms.
They run 16x.
They compare the previous run state for each bit, so if there is no change, the script bounces out and doesn't send data (to cut down on MIDI Traffic).
The Repeat Delay is currently 2ms.

So...up to 6 Timers are sending out and take roughly 32ms (just spitballing) to get the data out.

I'm wondering how to approach this, whether I'd want MTPro to hold the incoming Note Data while a Timer cycles until it doesn't receive an input and then process it? Or would it be better on the back end where the output would be subject to a Timer waiting for a pause in input?

As in:
Data comes in
Data is processed and Output Timers are ready to be triggered
Countdown Timer is Started
Output is held until Countdown Timer finishes
Countdown Timer is reset every time an Output Timer is triggered (so, if new data comes in during this window, the Timer is reset and Output effectively held)

Curious bit is that I have roughly 3 systems working independently on these Input/Process/Output routines so I think I'd have to connect them all.

Does that make sense?
No need to write a script - I just don't know the best way or the Bome way to approach this.
I also don't know if this is going to resolve my issues.

I know this will not definitively solve timing issues since the Output Timers happen over a period of time, but I'm wondering if my pressing of multiple buttons is a greater range of time than 32ms.

Also, timing wise:

Whattya think?
Did I get the question in there?

I want to Quantise the Triggering of several Timers.
Generalities & pseudocode perfectly fine

Steve-Bome Forum Moderator

2020-04-13 05:07:42

Wow, Jim,

This is a tall order for MT Pro to pull it off. Essentially you would have to queue up several incoming events (notes or CC) and then release them after count X incoming syncs assuming that you are sending MIDI clock. The outgoing timer would need an incoming clock signal with a counter to count how many came in, then the outgoing timer to send quantized notes would need to very quickly send them out one at a time.  Or if you know how many notes to send, I guess you could use a raw MIDI stream to send them all out with one swoop.

This type of quantizing is probably better handled with a DAW where you send data from several sources and set delays on some of the sources along with clock messages to keep them in sync. If you did it this way, you would send the different streams out a different virtual MIDI port to the DAW and then set up the DAW to handle the necessary delays for quantizing.

The other question arises is if you are playing an instrument, how long of a delay is tolerable to the player?  I know I've tried to play instruments through regular audio bluetooth and the delay is totally intolerable.

 

I'm not sure if this helps much but maybe gives you a few ideas.

 

Steve

 

 

 

CreepyPants

2020-04-13 21:16:56

Thanks for the response, Steve.
Hrmm.

The issue that I'm getting is that I press several keys at once on my control surface (a Prophet12) which triggers the process which triggers the output timers.

One key for drum patterns, one key for bass, one key for melody.

Somewhere in there things get 'off'. Or rather, I think I'm too close to the actual beat. The Pyramid reads part of incoming data before the beat, and some after. I was trying to troubleshoot a way to ensure that all the data happened closer to the same amount of time.

-OR-

Figure out if the problem isn't what I'm imagining it is and perhaps something different. Like I think I posted, the salient timers, if I'm changing all 3 (Drums, Bass, Melody) that send to the Pyramid might be 6 total running at 16 iterations each with a 2ms Delay.  However, note that there is only output if the individual Track status changes (Because some Tracks belong to multiple Groups or Layers).

And no DAW in my system, alas.

I was kind of thinking:

Incoming Note On/Off Event
Translator determines that output is necessary
Starts a timer
If after X ms there is no other input to process, it finishes the output routine
if it receives an input to process, the timer gets reset.

I think i saw something like this in the old forum perhaps, but I haven't been able to find it doing searches.

Generally I'm not pressing two different "Drum Group" buttons in rapid succession. I may press two Drum Layer buttons tho. But then I wonder what is a reasonable amount of time for this delay- 30ms? 10ms?

Okay, I think this is outside the scope of standard MTPro troubleshooting.  :)
I appreciate your input, Steve!
I think I'm going to try to resolve this by technique (play technique) first and assume it's not a problem with my script. If it continues to be a problem, I may have to hire you again for brainstorm, but there will be significantly more background - at least there is video now!  Muahahhahahha

CreepyPants

2020-04-13 21:19:04

comment

Oh, and "Tall Order" for MTPro? Dude - when I first purchased MTPro I had no idea I could do what I'm doing with it now. I have completely redesigned the way I interact with my gear and I LOVE IT! The day MTPro goes the way of Cakewalk or JLCooper will be the beginning of a decade of mourning for me.

Steve-Bome Forum Moderator

2020-04-14 00:09:36

comment

Well if you are going to delay output using a timer. You will still have to tee up the incoming MIDI events in a queue of sorts so that when the timer trips, it can iterate through the queued up events (hopefully very quickly).

CreepyPants

2020-04-14 18:58:18

comment

Good points. Except I'm not playing notes, I'm playing cues to trigger the sequencer and they will rarely happen less than a half a measure apart, at least the ones to trigger the same Timers. Okay, so if I were programming a double tap on a Note Event. MTPro would listen for a Note Event, then start a Timer to see if that Note Event is repeated and if so, does a thing. I'd swear someone asked this question but I haven't been able to find that thread. I think it was in the old forum. Does that sound familiar? If not, how would you code a doubletap situation like that? I'm drawing a blank, even tho the harder part is applying that to my situation...but I'm learning that I can still learn, which was difficult to learn. heh heh :)

Steve-Bome Forum Moderator

2020-04-14 19:14:55

comment

Yes, see this post on gestures. I use timers and count events to determine how many times I tap or tap and hold. https://www.bomeloft.com/support/kb/multinote-gesture-detector

CreepyPants

2020-04-14 19:19:38

comment

Bingo! That's it! Thanks Steve! :) Be safe - be well - be healthy

jbam21

2020-06-15 02:36:36

Did you resolve this? Just reading out of interest from a forum search... I'm dreaming up a new project for programming a sequencer...

As I understand it, you're trying to have messages quantised irrespective of their accuracy from when they were struck (although I do get a little lost  towards the end of the post with double taps etc. so maybe I'm wrong?!)...

Did you consider using the current layout as code to modify the bit states (as you have it currently), but then using separate triggers to then run a setting change? e.g. 8th beat are the actual trigger point - hit your key combination... then if there's a change, it all dumps on the next 8th beat... if no change, that 8th note trigger exits (no outgoing action). Or perhaps that's part of the problem (data being recieved too late once it's triggerd "on time"?... perhaps having a set delay to force it to the NEXT quantise point on the device could help with that (although you'd have to be savvy in hitting the combination early)... With only one trigger, you could then neatly order the actual final event to be processed in a preset (change this, then that and then do this...) irrespsective of the order of key presses, and that may allow quantising separate to the device quantise setting.

Just some thoughts, as I'm running through similar musings in me head ;)... For all I know, this may be what you're actually doing though haha...

Steve-Bome Forum Moderator

2020-06-15 15:32:16

comment

Thanks for the comments! I think at this point this discussion was all about possible strategies but I haven't developed a solution Maybe CreepyPants did something?

CreepyPants

2020-06-15 23:24:24

I was looking for options to deal with a way things were happening controlling my sequencer, but my options were to force a quantisation via Bome or to adjust my play technique.  I chose the later to start with (because: easier) and that seems to have resolved it.

I think.

I was always worried about having BMT 'counting' the clock bytes. I have a distrust of MIDI that msgs can get overlooked or lost. It hasnt happened lately, but: baggage from the 80s and all.  :)

Ultimately in my system the deciding bit is when the data arrives at the sequencer. Playing slightly ahead of the beat resolves this for me so far, but also creating visual beat counting feedback helps: I have a translator that flashes 4 successive LEDs on a controller to the beat, but I start it a few ticks in, so the lights are technically ahead of the beat anyway - just 3 ticks tho.

I think the problem I keep running into is the amount of data changes. It's all great to count up F8s and release all the data if 'all the data' is a fixed amount.  Cycling through possible variables (which is doable: one variable for the count of MIDI messages, and then others for the actual messages in a predetermined order, count up, hit the peak, unload, etc) is just more headaches.

I've spent a year 'developing' my interface script.
I want to be done and back to making music!  LOL

Note: I don't know how to properly form the suggestion, but I'm hoping BMT 2.0 will allow for varying the amount of data output.  If it doesn't, it's not a big deal. BMT is still SO INCREDIBLY POWERFUL it's now the 'go to' for anything I invest in.

Recently picked up a Squarp Rample (4 voice modular sample playback device) and before I even received it in the mail I was writing a script to interface with it. It now works more like a rompler with a modulation input to select sample layer, but it's more an example how I won't leave well enough alone.  Ever.