monome / norns

norns is many sound instruments.
http://monome.org
GNU General Public License v3.0
614 stars 144 forks source link

MIDI clock input responds to all endpoints #1754

Closed catfact closed 4 months ago

catfact commented 5 months ago

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.

catfact commented 5 months ago

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.

catfact commented 5 months ago

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:


... hm. maybe midi_clock source param is, like... an integer? where -1 is all devices, 0 is no devices, 1+ is a vport index?

catfact commented 5 months ago

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.)