MIDI clock input responds to all endpoints
catfact opened this issue · 3 comments
thanks to user "2197" on lines for pointing this out:
https://llllllll.co/t/norns-midi-tempo-is-tripled-from-ext-sync/64036/12
apparently there are a significant number of MIDI clock producing devices out there, that enumerate as multiple source endpoints (user-facing software "devices") and send clock messages on more than one endpoint simultaneously.
in device_midi
, it seems to me that we are handling all clock messages equally regardless of the endpoint of origin:
https://github.com/monome/norns/blob/main/matron/src/device/device_midi.c#L284C1-L284C1
so this would explain some reported issues with doubled/tripled tempo and jittery clock when following MIDI.
any solution that i can think of involves some new connections between lua and device_midi
, one way or another.
(1) from a UI design perspective, the easiest solution i can think of is to treat vport assignment as "enabling" input from a device, including clock input. this would require no new UI elements, but would slightly change the UX behavior if a user was relying on a device for clock while explicitly excluding it from vport assignment list.
(2) the other solution that comes to mind is having an explicit clock device selection, including a default "all" setting. this would have the benefit of not changing any user experience by default.
either one requires some new FFI glue. (2) probably a bit easier in that regard, but designing the lua side is more involved. (e.g., should it be a system parameter representing device name with a string? in that case, need to manage the device name list... should it take vport numbers instead? then need to communicate those to C anyways... etc)
and maybe worth saying that passing clock through lua event loop would make things simpler, but is not desirable for performance.
another possibility, sort of combine the two: implement solution 1, and additionally add a toggled "all clock" mode that is exposed as a system PARAM and defaults to true.
minmal impact on UI, doesn't break existing UX, should be pretty easy for affected users.
a bit clunky maybe?
the only use case that is still broken is pretty niche:
- i have a device that always sends clock on both endpoints A and B simultaneously
- i want to follow clock
- i want to simultaneously receive other input from both A and B, so they are both in the vports list
... hm. maybe midi_clock
source param is, like... an integer? where -1
is all devices, 0
is no devices, 1+
is a vport index?
here's a work in progress:
https://github.com/catfact/norns/tree/midi_clock_filter
it doesn't crash, and the lua parameter exists, but i haven't actually tested the C layer functionality (need to dig up multiple clock sender hardwares, or 4x MIDI interfaces, or something.) sharing here just in case anyone wishes to test it before i get a chance.
a minor complaint might be that the clock input selection parameter shows vport indices and not device names for specific device selection. (it's an option type, and i suppose the option table could be made dynamic if it seems important enough that the UI match better between clock input and output.)