Mixxx stops receiving data from MIDI controllers when too many messages arrive at once

Bug #1527410 reported by Sean M. Pappalardo
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mixxx
Fix Released
Medium
Sean M. Pappalardo
2.1
Fix Released
Medium
Daniel Schürmann

Bug Description

Testing with a Stanton SCS.1d on Debian 8 Linux where it shows up as a regular but extremely chatty MIDI controller,
if anything happens on my system to cause a slight delay (such as scrolling the library,) and too many MIDI message build up in the receive queue, Mixxx drops the ball and stops responding to the controller at all. It can still send things to the controller and the GUI remains responsive, it just stops getting data from the controller unless I disable and re-enable it.

I'm not sure if this is happening at the PortMIDI or ALSA-MIDI levels instead of Mixxx either. How can I best check?

I just got this, but it was after I stopped execution for a few seconds in gdb then continued:
Expression 'alsa_snd_pcm_prepare( stream->playback.pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2920
Expression 'AlsaStart( stream, 0 )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3246
Expression 'AlsaRestart( self )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3313
Expression 'PaAlsaStream_HandleXrun( self )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3924
Expression 'PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4253
[Thread 0x7fff8e24a700 (LWP 21672) exited]

Revision history for this message
Sean M. Pappalardo (pegasus-renegadetech) wrote :

Found that MIXXX_PORTMIDI_BUFFER_LEN was set too low at 64. After setting it to 1024 and letting Mixxx run for awhile and doing latency-inducing actions (like switching to a text console,) the highest number of queued events was 135, so I'm going to propose setting it to 256.

Changed in mixxx:
assignee: nobody → Sean M. Pappalardo (pegasus-renegadetech)
status: New → In Progress
Revision history for this message
Sean M. Pappalardo (pegasus-renegadetech) wrote :

Actually after some stress-testing, 500 events were queued up at one point, so maybe 1024 is a good number to use.

Revision history for this message
Sean M. Pappalardo (pegasus-renegadetech) wrote :
Changed in mixxx:
status: In Progress → Fix Committed
milestone: none → 2.0.0
Revision history for this message
Owen Williams (ywwg) wrote :

For the record the portmidi header does describe how a caller is supposed to recover from overflow. If we aren't detecting overflow that's a bug as well:

/* Pm_Read() retrieves midi data into a buffer, and returns the number
    of events read. Result is a non-negative number unless an error occurs,
    in which case a PmError value will be returned.

    Buffer Overflow

    The problem: if an input overflow occurs, data will be lost, ultimately
    because there is no flow control all the way back to the data source.
    When data is lost, the receiver should be notified and some sort of
    graceful recovery should take place, e.g. you shouldn't resume receiving
    in the middle of a long sysex message.

    With a lock-free fifo, which is pretty much what we're stuck with to
    enable portability to the Mac, it's tricky for the producer and consumer
    to synchronously reset the buffer and resume normal operation.

    Solution: the buffer managed by PortMidi will be flushed when an overflow
    occurs. The consumer (Pm_Read()) gets an error message (pmBufferOverflow)
    and ordinary processing resumes as soon as a new message arrives. The
    remainder of a partial sysex message is not considered to be a "new
    message" and will be flushed as well. */

Revision history for this message
Sean M. Pappalardo (pegasus-renegadetech) wrote :

Good point, and that starts to answer my question of if this is the best fix. I suspect we're just bailing out, assuming any error is an unrecoverable one. Should we target this to 2.1 then?

Revision history for this message
Owen Williams (ywwg) wrote :

I think upping the buffer size is a good stop-gap fix, but yeah in 2.1 we should try to be able to handle this situation more gracefully.

Revision history for this message
Daniel Schürmann (daschuer) wrote :

I can confirm the issue with my RMX2 when I am reduce the buffer to 2

Revision history for this message
Daniel Schürmann (daschuer) wrote :

We use a redundant Pm_Poll call that prevents that we can recover from an overflow.
In case of overflow the buffer is flushed so Pm_Poll returns 0, but Pm_Read call does the buffer management.
Both calls poll telegrams from the hardware.

If I remove the Pm_Poll call and use a portmidi build without PM_CHECK_ERRORS all works like a charm and overflows are handled gracefully.

Revision history for this message
Daniel Schürmann (daschuer) wrote :
RJ Skerry-Ryan (rryan)
Changed in mixxx:
status: Fix Committed → Fix Released
Revision history for this message
Swiftb0y (swiftb0y) wrote :

Mixxx now uses GitHub for bug tracking. This bug has been migrated to:
https://github.com/mixxxdj/mixxx/issues/8381

lock status: Metadata changes locked and limited to project staff
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.