14-bit MIDI latency when using Patterns

I’m writing a class to send 14-bit midi to a digital guitar amp (a Kemper) and running into a latency issues when using custom Event types in patterns. Here’s an example of one of the types, used for switching built-in effects on the pedalboard/amplifier:

Event.addEventType(\kemperFxType,{
            if(~kemperMIDI == -1,{
                "no KemperMIDI instance specified ".error;
            },{
                var kMIDI = ~kemperMIDI;       // an instance of KemperMIDI, basically MIDIOut with a coat of paint
                var page = kMIDI.prPageCheck( ~addrPg ); // can be a symbol, returns integer
                var fxBits = KemperMIDI.fxKeys[ ~fxKey ]; // can be a symbol, returns integer
                var chn = kMIDI.chan - 1 + 0xB0;
                var onOff = case
                { ~switchOn == false }{ 0x00 }
                { ~switchOn == true }{ 0x01 }
                { "switchOn must be a boolean".error };
                var pkt = [
                    // these bits assign the effect to the correct effect slot
                    chn, 0x63, page,
                    chn, 0x62, 0x00,
                    chn, 0x06, fxBits[0],
                    chn, 0x26, fxBits[1],
                    // the effects are off by default, must turn them on...
                    chn, 0x63, page, 
                    chn, 0x62, 0x03,
                    chn, 0x06, 0x00, 
                    chn, 0x26, onOff,            
                ];

                thisThread.clock.sched(~latency, kMIDI.midiOut.sysex( pkt.as( Int8Array ) ) )
            }); 
        },(
            kemperMIDI: -1,
            addrPg: 50,
            fxKey: 'empty',
            switchOn: true,
        ))

This “works,” but the timing is very inconsistent - if I’m sending a whole buncha MIDI messages at once (the amp has 8 effects slots, I also have an Event for sending 14-bit control messages, sometimes there’s a lot of traffic…) the switching of effects can be delayed by several seconds, while the control messages don’t seem to be interrupted.

I feel like I’m missing something about 1) event scheduling 2) MIDI latency / bandwidth limitations and/or 3) something else I haven’t considered? I guess hardware latency could be an issue as well…I’ll admit I don’t know so much about MIDI and timing, so any/all tips are appreciated - thanks in advance!

(running on macOS 13.6, for what it’s worth)

Are you using USB MIDI or a MIDI cable?

Anyway, this sounds very similar to an issue with portaudio on macOS that we had in Pd: MIDI out regression. large amount of data can't be send in real time on OSX. · Issue #581 · pure-data/pure-data · GitHub

Here’s the relevant PR: Disable macOS Portmidi rate limit by danomatika · Pull Request #641 · pure-data/pure-data · GitHub

DISCLAIMER: I didn’t have time to check whether the portmidi version used by SC is affected by this issue.

As a side note: it seems like MIDI transmission is generally not reliable on macOS – at least it used to be – and the OS will drop messages if they’d overflow the internal buffer. From the portmidi developer: MIDI out regression. large amount of data can't be send in real time on OSX. · Issue #581 · pure-data/pure-data · GitHub

I thought SC on Mac uses CoreMIDI. PortMIDI would be Windows IIRC.

hjh

You are of course right! @Mike_McCormick disregard my previous post.

Thanks for the replies! Generally speaking, is there some sort of limitation on MIDI data that can be sent from sclang?

This issue seems to suggest it’s a macOS thing, but I wonder if there are any clever ways I can package data better? I might be able to make some of the 14-bit packages 7-bit, for example, though I’m not sure how much of an impact that will make…I also have a linux machine I can try to test with, wouldn’t have expected such a difference between OSes.

I’m using a USB MIDI interface - would you expect using a MIDI cable (from a sound card, for example) yield better results?

No, on the contrary!

1 Like