monome / norns

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

MIDI #28

Closed catfact closed 6 years ago

catfact commented 7 years ago

we want to get MIDI input and maybe output to/from matron/lua.

in the old days, you could just use /dev/sequencer directly, hopefully this is still the case since it would fit nicely alongside the existing device types

tehn commented 7 years ago

yes indeed.

by default it seems reasonable to send/receive MIDI from "all ports" (as max/msp does) which would mean being able to plug in any MIDI USB thing and having it work right away.

a second level would be to be able to specify devices, perhaps similar to the HID work you just did? for example, being able to map a particular knob box to a set of controls, and a keyboard to some other controls, and have those route correctly on hotswapping.

catfact commented 7 years ago

yes i will make device_midi , &c.

i hope and believe that midi controllers will be accessible by their individual entries in /dev/whatever. in that case, hotswapping and notification would be supported by existing device_monitor and device_list, requiring only an additional device type / node pattern.

i don't actually have midi HW on hand to test this theory; i do have it back in CA so this might just wait until then instead of buying more plastic junk

as a fallback, the 'all ports' behavior is obtainable by reading /dev/sequencer as mentioned above (i think)

artfwo commented 6 years ago

Is that still an issue? /dev/sequencer is currently non-existent on Linux unless you use the unstable OSS emulation layer. ALSA recommends using their MIDI libraries. Other option could be JACK midi.

catfact commented 6 years ago

indeed, still unimplemented. thanks for the correction, alsamidi is the thing to use then. looks simple enough, here's some sample code of unknown vintage: http://fundamental-code.com/midi/midi-listen.c

artfwo commented 6 years ago

@catfact, do you think midi devices should be implemented using matron devices? On the application level ALSA sequencer deals with ports, and a device (or application) can provide more than 1 port, e.g.:

client 24: 'Impulse' [type=kernel,card=2]
    0 'Impulse MIDI 1  '
    1 'Impulse MIDI 2  '

To read events from the keyboard, you have to open an output (write-to) port and connect it to 24:0 or 24:1. To send midi, matron would also need an input (read-from) port. With that said, it might make sense to implement an entirely different subsystem for MIDI I/O or do you think that's possible with the current device subsystem?

catfact commented 6 years ago

apologies for lag, i totally missed the notification for this.

um.. yeah i'm not sure, hence the question mark. device_monitor module watches for specific patterns of things to show up in /dev. if that's a sensible way of finding out about new midi devices, then i think makes sense to add them as a new category there.

if that's the case then device_midi could be a new "subclass" of device_common. we already use different APIs for reading from HID and monome. (libevdev and libmonome.) the "superclass" just assigns arbitrary IDs for input devices and starts input threads with arbitrary function pointers.

if there's some better way of getting notified about hotplugged usb midi devices, through alsa, then it should be totally separate i guess.

as far as input/ouput, device stuff only cares about input. its assumed that output will happen on the main (lua) thread via weaver (the c/lua glue layer) which direclty calls e.g. grid update functions decalred in device_monome.

catfact commented 6 years ago

some comments from slack

the current codebase allows you to track as /dev/midi1, dev/midi2, etc. appear in the system and use the path to open the device, but in ALSA it's different

if those sysfs entries do appear for midi devices, then it seems fine - device_monitor will find them and hand them off to device_midi or whatever, which presumably will call into the alsa midi APIs.

if midi doesn't show up in sysfs at all, then yeah we have to do something different. i don't know how hotplugging notifications work in alsa midi (if at all)

(sorry i can't actually try this stuff because i have literally no midi devices at home! waiting for one in the mail right now)

midi is well supported by SC3, so we can use that too

it's certainly an option, though a little baroque. we absolutely want midi events to be usable in lua scripts so this is some pretty weird OSC round-tripping.

not sure if we want matron to depend on jack

would be much better if it didn't. we may want to eliminate the jack dependency for SC3 even.

artfwo commented 6 years ago

midi out is also important, because then you can use norns to build algorithmic sequencers and stuff like that.

in lua, each midi device could be an individual object with a callback for receiving events and a method for sending events. in that case there also could be an observer to notify the scripts about adding and removing devices. then it's possible to use the midi peripherals like this:

function midi:device_added(device)
  if device.name == 'foo_controller' then
    -- map foo controller to the engine
  end
end
tehn commented 6 years ago

thank you @artfwo !