dagargo / overwitch

JACK client for Overbridge devices

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MIDI buffer overflow

martinsolberg opened this issue · comments

In my setup I use an Octatrack as the main sequencer and the MIDI master clock. It’s sending MIDI to the audio interface. ALSA MIDI is bridged to Jack, which exposes the audio interface’s MIDI Thru, which can then be connected to the various MIDI inputs in Jack.

Connecting MIDI from the audio interface to Overwitch works at first, but after a while, the connection is broken. Overwitch the prints a lot of these messages:
ERROR:jclient.c:508:(jclient_j2o_midi): j2o: Buffer MIDI overflow. Discarding data...

Sound is still working (perfectly I might add). When I'm running two instances of Overwitch (one to Digitone, one to Digitakt), they seem to run in to the problem more or less simultaneously.

I suspect the problem is somewhere here when comparing the events times. This could lead to not reading from the MIDI queue and hence the buffer overflow when the JACK client side of Overwitch is trying to write there.

overwitch/src/overbridge.c

Lines 649 to 675 in a56d7d4

while (jack_ringbuffer_read_space (ob->j2o_rb_midi) >=
sizeof (struct ob_midi_event) && pos < USB_BULK_MIDI_SIZE)
{
jack_ringbuffer_peek (ob->j2o_rb_midi, (void *) &event,
sizeof (struct ob_midi_event));
event_time = jack_frames_to_time (ob->jclient, event.frames);
if (!first_event_time)
{
first_event_time = event_time;
last_time = event_time;
}
else
{
if (first_event_time != event_time)
{
diff = event_time - last_time;
last_time = event_time;
break;
}
}
memcpy (&ob->j2o_midi_data[pos], event.bytes, OB_MIDI_EVENT_SIZE);
pos += OB_MIDI_EVENT_SIZE;
jack_ringbuffer_read_advance (ob->j2o_rb_midi,
sizeof (struct ob_midi_event));
}

Could you try running Overwitch with -vv? Perhaps, this could help.

Not really sure what to look for, so attaching dump: overwitch_output.txt

By looking at the log you provided, the issue is where I suspected.

The problem is in the diff calculation in the loop above and the huge diff value is even printed. From there, I guess, all the following MIDI messages will not be removed from the queue and it will be full eventually, leading to your error.

DEBUG:overbridge.c:680:(run_j2o_midi): Event frames: 61; diff: 1042
DEBUG:overbridge.c:680:(run_j2o_midi): Event frames: 104; diff: 896
DEBUG:overbridge.c:680:(run_j2o_midi): Event frames: 24; diff: 18446744073709549950
DEBUG:jclient.c:347:(jclient_compute_ratios): Max. latencies (ms): 4.0, 4.0; avg. ratios: 1.000001, 0.999999; curr. ratios: 1.000001, 0.999999
�[31mERROR:jclient.c:508:(jclient_j2o_midi): j2o: Buffer MIDI overflow. Discarding data...
�[m�[31mERROR:jclient.c:508:(jclient_j2o_midi): j2o: Buffer MIDI overflow. Discarding data...
�[m�[31mERROR:jclient.c:508:(jclient_j2o_midi): j2o: Buffer MIDI overflow. Discarding data...
�[m�[31mERROR:jclient.c:508:(jclient_j2o_midi): j2o: Buffer MIDI overflow. Discarding data...

Perhaps it's a signess issue but I'll have to take a closer look. But at least we know where the bug is.

I have a question.

Are you sending other events than notes and MIDI system RT (start, stop, clock...)? Program changes maybe?

I've double checked everything and while I don't know what the underlying problem is, I might have fixed your issue and improved the code.

Let me know if the code in branch midi_out_fix improves anything.

The midi_out_fix branch actually made it worse. On the master branch code, I can make the MIDI connection to the Digitakt, and it seems to be working stably until I start the transport from Octatrack, where it will fail after 30 seconds or so. On the fix branch code, it immediately threw buffer overflow as soon as the connection was made.

I'm attaching a MIDI dump from the master branch overflow:
mididump1.txt

Could you try with the master branch again? BTW, I've deleted the midi_out_fix branch.

Notice that I've changed how the priorities are set and chrt is no longer needed as the default JACK RT priority for plugins is used. Besides, it's not needed to run jackd with this either because it runs with RT priorities by default too.

I did a quick test, seems to be working without issues. I'll report back if it occurs again. Thanks a lot!

You're welcome!

I think the problem was more related to messing with the RT priorities than anything else but there was a bug for sure in the first commit that I pushed.

There is still an issue that appears randomly in which I'm working right now. Just in case you want to follow the project.