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

Virtual MIDI not usable as clock/pmap source #1744

Closed
dstroud opened this issue Dec 1, 2023 · 7 comments
Closed

Virtual MIDI not usable as clock/pmap source #1744

dstroud opened this issue Dec 1, 2023 · 7 comments

Comments

@dstroud
Copy link
Contributor

dstroud commented Dec 1, 2023

What the issue is:
MIDI system real-time (clock) messages received by the "virtual" RawMidi port are ignored when clock source is set to MIDI. Likewise, control change messages are ignored when mapping MIDI to parameters.

How to reproduce it:
I'm using CyberMIDI (MIDI over OSC) to send clock/cc over IP. These message types are retrievable in LUA via midi.to_msg().

Why it's worth addressing:

  • If the virtual port is available as a MIDI clock out destination, it stands to reason that it should be available as a clock source.
  • Ability to send MIDI clock has some advantages over Link in, e.g. distinct start vs. continue messages for transport.
  • Allowing any script that sends CC to control parameters on-device or over the network via a generic virtual port would be handy.
  • AFAIK, the virtual port was initiated as a path towards rtmidi support but I don't know if that ever came to fruition. I imagine if that work continues, we would want this functionality.
@catfact
Copy link
Collaborator

catfact commented Dec 1, 2023

Probably a simple oversight and shouldn't be too tricky to fix if anyone wants to have a go

@dstroud
Copy link
Contributor Author

dstroud commented Dec 1, 2023

Would be rad if so! I'm way out of my depth here, but one thing I noticed working on the related mod is that the virtual port gets added later in the boot process than physical ports (after the "system_post_startup" mod hook). Probably tangential but I figured it's worth bringing up if anyone is interested in a more general effort to close gaps between virtual and physical ports.

dstroud added a commit to dstroud/cybermidi that referenced this issue Dec 1, 2023
Enabled system real-time messages but Norns system won't recognize this, pending a fix for monome/norns#1744 (comment)
@catfact
Copy link
Collaborator

catfact commented Jan 31, 2024

i looked at this but only very briefly:

  • in particular i did not really look closely at CyberMidi. it wasn't immediately clear to me what this mod does and how it is implemented. my vague impression is that it (1) maps network traffic to MIDI events, and (2) operators entirely in the norns lua interpreter - maybe calling lua MIDI handlers directly?

if (2) is true, then i can see how it would not work to drive MIDI clock. MIDI clock messages from connected devices are handled at a lower level in matron - a device reads a clock byte, immediately informs the clock module (which is another part of matron independent of lua,) then posts an event to the lua interpreter.

https://github.com/monome/norns/blob/main/matron/src/device/device_midi.c#L288

if i understand corretly, it should work fine to read clock messages from the virtual device, but it would have to be driven by an external process.

the next step i had in mind was a proof-of-concept writing a small program to send periodic clock messages to the virtual device through ALSA rawmidi API. like starting from this example:

https://ccrma.stanford.edu/~craig/articles/linuxmidi/alsa-1.0/alsarawmidiout.c

... i have not quite got that going yet but thought i might as well check back first to ensure we are on the same page.

@dstroud
Copy link
Contributor Author

dstroud commented Feb 1, 2024

Thanks Ezra- you are correct about how CyberMIDI works. MIDI is encoded as OSC to send between devices. When it's decoded the midi.vports[n].event callback is called directly.

I was able to successfully send/receive MIDI clock with a shieldXL which uses the virtual port for its TRS MIDI and that works fine which confirms your explanation.

So it sounds like this is just a limitation of my mod's implementation and not an issue with the virtual port in general. I'm OK with closing the issue since everything is working as expected.

@dstroud dstroud closed this as completed Feb 1, 2024
@dstroud dstroud closed this as not planned Won't fix, can't repro, duplicate, stale Feb 1, 2024
@catfact
Copy link
Collaborator

catfact commented Feb 1, 2024

When it's decoded the midi.vports[n].event callback is called directly.

ah ok, that explains why it would not work for parameter mapping either. (which i forgot to address.)

the parameter mapping code also observes MIDI messages at a different stage in the pipeline than vports does. however unlike MIDI clock input, this is still happening entirely in the lua layer:
https://github.com/monome/norns/blob/main/lua/core/midi.lua#L456-L472

.. so basically, i think all you would need to do to make parameter mapping work is to call norns.menu_midi_event(data, d.port) in addition to midi.vports[d.port].event(data), as the main handler does.


however, making the mod able to drive MIDI clock events from lua would require changes to core: namely a dedicated FFI function to do that. we haven't seen a need for such a function before, but i at least would not be opposed to adding it.

@dstroud
Copy link
Contributor Author

dstroud commented Feb 1, 2024

Aha! Thanks for the tip re: parameter mapping! Between this info and the upcoming Link improvements for clocking, feels like the need for any changes is greatly ameliorated on my end.

TBH, it seems like a better solution than my mod is something like RtMidi which I assume would not have this issue as it uses ALSA. I'll leave that up to someone who knows what they are doing 😬

@catfact
Copy link
Collaborator

catfact commented Feb 2, 2024

Yeah if you asked me to implement something like cybemidi, my first thought would be to do it as a daemon process connected to virtual port. Rtmidi or portmidi would be options for that, but for Linux only I don't think it's any less convenient to use alsa apis directly.

But thinking about it, I think it would also work if cybemidi wrote to virtual device output, and then the daemon process did nothing but loopback on the virtual port, and then norns user would just select virtual device for input and everything works normally.

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

2 participants