Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numerous crashes on OSX. #35

Open
MrJoy opened this issue Sep 10, 2015 · 0 comments
Open

Numerous crashes on OSX. #35

MrJoy opened this issue Sep 10, 2015 · 0 comments

Comments

@MrJoy
Copy link

MrJoy commented Sep 10, 2015

Versions

  • OSX: Yosemite 10.10.5
  • Ruby: MRI 2.2.3
  • UniMIDI: 0.4.6
  • ffi-coremidi: 0.3.8
  • ffi: 1.9.10

Problem

In short, it appears to be the case that if I send messages 'too fast', I get a segfault in a subsequent transition between native code and Ruby (commonly Thread.sleep, but I've seen it happen in other very random places too suggesting that the VM is pre-empting plain Ruby code to service another thread and kaboom).

My current working hypothesis is that the CoreMIDI buffer fills up, and error handling is not a thing that is being done in such a scenario. Looking at the CoreMIDI API, it looks like it's the callers' responsibility to gate themselves using a completion callback, etc.

The problem here is that in some cases I know with absolute certainty that I can robustly send MIDI messages to the particular device much more quickly than I can apparently manage with UniMIDI. For example, using portmidi, I can update every LED on the grid of a Novation Launchpad Mark 2 in RGB mode (sysex payloads are much longer for this; I wind up sending two sysex messages to do a full-board update*) at a rate of about 45hz. Using UniMIDI, things seem generally stable only if I gate it to about 12hz or less.

Proposed Solution

  1. Is there a way to tell CoreMIDI to push messages more quickly? If so, that would be helpful.
    • Note that while it schedules messages based on timestamp, merely setting timestamp to 0 does not appear to help at all. Perhaps setting the message to be slightly in the past would, but I haven't tried that yet.
  2. Implement completion callbacks, and block on sending new messages until the last one is completed. Alternatively if there's some known buffer size behind the scenes that can be controlled or whose size can be queried, block only when it fills up and only until there's room for the next message.

Reproduction

I don't have a great isolated test case, at the moment, but the code I'm working on is here:

https://github.com/MrJoy/surface_master/tree/unimidi_experiment

Specifically, see the examples directory and commit history for those files. The Numark Orbit ones are a bit misleading as I have both the problem of CoreMIDI backlogging and causing a segfault but also a 'soft' issue of the Orbit getting stuck and going into la-la land if I send things too quickly -- but not quickly enough to trigger the fault.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant