SendSysexExternal - later

Hi,
I trying to:

  1. Send a sysex to my keyboard (Motif XS) to change the mode (e.g. performance mode or voice mode)
  2. Immediately followed by a program change message

So, I’ve written the script for those two steps into two separate functions. It works well if I run step 1 above first, WAIT, then do step 2.
But, if the two steps are called one after the other (from a “On Variation” event handler), it appears that step 2 jumps ahead of step 1, which won’t work because step 2 by its nature has to execute after step 1 is completed.

I’ve looked through the documentation at length but can’t find a suitable delay function or a “SendSysexExternalLater()” function (although there is a SendSysexInternalLater() function). Any ideas? :thinking:

...
// === start - sysex
function SetMode(mode : integer)
    var msg : SysexMessage = # F0 43 10 7F 03 0A 00 01 00 F7
    
    SM_ChangeValue(msg, 8, mode)
    SendSysexExternal(midiOutToXSPlugin, msg)
end

function SetPreset(preset : integer)
    var msg : ProgramChangeMessage = MakeProgramChangeMessageEx(preset, 1) // to channel 1

    SendNowExternal(midiOutToXSPlugin, msg)
end
// -- end
...
on Variation(oldVariation : integer, newVariation : integer)
    var mode : integer = GetModeValue()
        preset : integer = GetPresetValue()
    
    SetMode(mode)
    SetPreset(preset)
end
...

Maybe this can give some ideas?

…sorry out of the studio.

Try an used midi in block (e.g. the Midi In OSC) and then route that to your midi out block. That way you can use the SendSysexInternalLater sent to this Midi In block.

Perhaps you could try a combined function SetModeAndPreset(midiOut : MidiOutBlock, mode : Integer, preset : Integer), such that it could perhaps keep the correct send order.

I’m confused. Are you saying that the second message is being sent out before the first one?

Or is it the case that they are being sent in order but your external device is responding to the second message before it has finished dealing with the first one?

@dhj is right, how did you check this?

Thanks for the suggestions everyone. Some interesting ideas there.

@dhj Are you saying that the second message is being sent out before the first one?
No, whether the second message is completely before or too close to the first I can’t precisely tell. The keyboard takes longer processing a Mode change request than it does processing a Preset change request. It appears as though the second is processed by the keyboard before fully completing the first request. Is that even possible in Midi messaging? I don’t know enough about Midi, but if midi messages are serial messages and the keyboard completes processing one message before processing the next, then my lack of midi knowledge would think the second one jumps ahead of the first. I don’t know enough about it.

Tests using button widgets
This test is done by pressing button widgets.
Separate Mode change (Mx) and Preset change (Py).
Starting with keyboard state of (M1,P1)
After {M2} → keyboard state is (M2,P1)
After {P4} → keyboard state is (M2,P4)
After {M1} → keyboard state is (M1,P4)
Result: all passed

Tests using Rackspace Variations
This test is done using the Variations on change event handler.
Mode change (Mx) and Preset change (Py) change sets
Assuming keyboard mode is already (M1,P1) at the start,
After {M1,P2} → keyboard state is (M1,P2)
After {M1,P3} → keyboard state is (M1,P3)
After {M2,P4} → keyboard state is (M2,P4) for a second then changed to (M2,P3) !
After {M2,P5} → keyboard state is (M2,P5)
After {M2,P6} → keyboard state is (M2,P6)
After {M1,P7} → keyboard state is (M1,P7) for a second then changed to (M1,P6) !
Result seems to suggest everytime the Mode is changed to something different the keyboard gets busy, accepts the Preset change momentarily then reverts back to previous Preset value of the previous Mode.

Given the two test methods above, it seems probable that adding a delay between the Mode and the Preset changes might solve the problem? :slight_smile:
I’ll try the suggestions from the other guys as well. Thanks… :slight_smile:

Well, you could, using an external MIDI Monitor

Perhaps just throw in a for loop, perhaps a nested one, to just waste a bit of time.

I think, that’s indeed the next step.

Just an update. Using an external MIDI monitor we can confirm that the first message send and second message are sent out in the right order everytime, but the timestamps are on the same millisecond (except the first run), see picture below :point_down:.

I added a Wait() function between the two message calls. Then the problem is now resolved. After a little tests, it seems for my use-case it needs a minimum of 300 milliseconds between the Mode change message and the following Program change message. I’ll use 500 milliseconds to have a buffer.

Btw, just to be clear, the title of this thread is wrong. If anything it should be SendLaterExternal because SendNowExternal is the one that needs a delay, not SendSysexExternal.

Anyway… I’m having a good time with GP 4. Great community support, great software. Thanks everyone… :slight_smile:

1 Like

You are right, you succeed to make me look into the wrong direction too. So, it could be nice to add SendSysexExternalLater, but you solved your problem using SendLaterExternal, right? (which is probably better than blocking a callback with a waiting loop inside)

By the way, interesting multiplatform analysis tool:
https://hexler.net/protokol
I need to test this ASAP… :wink:

Oh yeah, that’s a much better OSC monitor than what I was using!

Unless my glasses are playing up again, SendLaterExternal is not available yet as of now :slight_smile: . But yes, if it becomes available in future I’d definitely mod my code with it. For now, I’m using a While Do loop monitoring elapsed time on each cycle. Also agree, a blocking loop is not great practice. Ok… enough coding… time to… gig :slight_smile:.

OK, one more missing :wink: :innocent:

Good plan! :sunglasses:

Just to be clear — that would not have helped your problem — in fact it would have made it worse because your program change would get sent out first.

The underlying problem here, as I understand it, is that your synth cannot respond quickly enough and so the only correct solution is to wait for a while, which is what you did.

The concept of a SendLater was really intended for doing such things as scheduling Note On events and automatic NoteOff events in the future, i.e, to implement the concept of a note with a duration.

So it doesn’t send any other MIDI message later? :thinking:

You can certainly send other non-sysex messages later but remember that sysex messages have a different “type” than regular MIDI messages

It certainly wouldn’t be a big deal to add this functionally for sysex but what’s the use case?

My quastion was for any “SendLater” MIDI GPScript function. Here we have a use case where it could be interesting to send a non-sysex MIDI message later. Does these SendLater function only send note messages later?

Per the documentation, that function will work with any MidiMessage

However, a SysEx message is not considered to be a MidiMessage (from GPScript’s perspective) because it has to be handled completely differently, i.e, arbitrary length vs a single 32 bit integer. That is why they have different types.

Agreed. Could be interesting to be able to send anything later even if we only faced the use case for a delayed version of SendNowExternal here: