jackaudio / jack2

jack2 codebase
GNU General Public License v2.0
2.21k stars 373 forks source link

jackd midi raw/seq drivers to handle sysex #712

Open tl072 opened 3 years ago

tl072 commented 3 years ago

Summary

jackd midi raw/seq drivers are able to send, receive, and route sysex midi data between software to/from physical midi ports

Motivation

I have several hardware synthesizers that can be controlled with sysex messages. They can also dump patches to sysex midi data so that a copy of their current patch can be saved to a hard-drive. I will explain more specifically why this would help me and I imagine others (in some cases friends who I have talked about this with) but the general issue is that working with sysex requires stopping jackd, then doing whatever work is needed with sysex, and then restarting jack. This breaks the flow of music creation / working with software using jackaudio. Stated more positively, being able to alter the synthesizers with sysex and receiving sysex while creating music could improve the creative process.

There are two specific use cases where this would improve my musical production and others who I have spoken with about this. Hopefully the below detail is clear but please let me know and I can provide more detail or clarify further.

Use case 1 - synthesizer editing software

There are various pieces of software that enables editing hardware synthesizers using software interfaces (see for example https://github.com/RomanKubiak/ctrlr but also puredata and proprietary software run through wine). Especially for older synthesizers (for example, Yamaha DX7) which have small LCD displays (or features not accessible from physical interface), being able to edit the synthesizer parameters via an more intuitive and graphical interface makes the creative process more enjoyable, quick, and perhaps unlocks new ideas.

My use case is having a Ardour session open where a idea/track is being created and then wanting to be able to modify the synth patch through this editor software. Currently, it is necessary to stop jack (which often requires shutting down ardour because otherwise certain port assignments can otherwise be lost), make the changes, and then start up jack and whatever other software I am using in the session.

The editor software I have used either uses ALSA ports or is editor software run through WINE which uses ALSA. I came across the absence of sysex support while trying to edit my synths and work on music at the same time. The same physical port used to create/arrange a melody for a recording session will be the same port used by the editing software so the editing software complains that another process already has locked the alsa port. I initially thought that I might be able to use a2jmidid but because jack does not pass the sysex data this does not work.

Use case 2 - saving sysex files

This use case is an extension of the above. Many of the editor software acts as librarian software but where a specific library management software doesn't exist, it would be nice to record the midi using amidi. Similarly, in would useful to be able record the sysex dump into a daw like Ardour so that a session file can contain the information necessary to recreate the synth patches used.

Recording with amidi would require a jack port is exposed in alsa. a2jmidid is a bit zealous in providing a jack port for each alsa port so I think it also locks up the ALSA port created by j2amidi_bridge. In short there is no easy low-level way of recording sysex while jack is running.

DarkAyron commented 3 years ago

I can't reconstruct your issue. I am able to both send and receive sysex messages through jack to my hardware midi port in seq and raw mode. I can also pass them from the alsa sequencer to jack and vice versa using a2jmidid. Recording sysex data is possible from alsa and jack. When using jack in raw mode, you need to use a2jmidid, because jack blocks the MPU-401 in that mode.

tl072 commented 3 years ago

@DarkAyron thanks for the response. I believe this may be a difference between jack 1 and jack 2 - maybe. I found a few emails on the listserv discussing midi buffer length and sysex for jack 1.

A friend has the same problem and also other people on the internet: see for example: https://www.spinics.net/lists/linux-audio-users/msg112645.html .

With applications using ALSA sequencer (tested with qtractor and Rosegarden), I can record and play successfully sysex using ALSA. However, I cannot record nor play sysex when connecting jack MIDI ports instead (jack MIDI wrapper ports from a2jmidid)

Related to this jack1 vs jack2 thing, there is also (https://github.com/jackaudio/jackaudio.github.com/wiki/Differences-between-jack1-and-jack2):

JACK2 uses a large, fixed sized buffer for MIDI; JACK1 defaults to a smaller size but allows the size to be set at run time.

In asking about that I was told that JACK2 has a large buffer but does not pass sysex.

The other relevant detail it makes me think of is that I am using a firewire interface although it think I had the problem previously with a usb audio card as well but at that time did not investigate it quite as thoroughly.

I am using jack: 1.9.12 a2jmidid: 8~dfsg0-3

riban-bw commented 3 years ago

Maybe related, I can route sysex to software receivers okay but sending to USB (midiman 2x2) truncates messages at 256 bytes if the send buffer is cleared on each process cycle. I'm not sure how to send larger packets, e.g. clear the buffer when all of message sent.

DarkAyron commented 3 years ago

That's related on how USB works. In contrast to a UART (e.g. the game port on a sound card) USB sends a MIDI message as a whole and not byte by byte. 256 bytes is 4 times the maximum packet size of 64 bytes. Because sysex message can get larger than 64 bytes these can be split into multiple packets, but this can overflow the buffer of the receiving device.

tl072 commented 2 years ago

I am going to give this issue another nudge. It is rather unfortunate that jack does not have sysex capabilities. There are not easy work arounds and lots of use cases. Especially as audio gets even better on linux and more people try it out, I can imagine that it will became a major barrier to more people sticking with linux for audio. If you search Google for jack audio and midi you can see lots of people are interested / confused by this issue.

x37v commented 1 year ago

RE the alsa sequencer driver.. I wonder how things would behave if we just removed this line?

https://github.com/jackaudio/jack2/blob/4f58969432339a250ce87fe855fb962c67d00ddb/linux/alsa/alsa_seqmidi.c#L883

keinstein commented 1 year ago

Once I did a deeper analysis in order to write automated tests for RtMidi. The result was: It is not supported.

Some points:

The question here is not, whether some software does a workaround, but whether JACK supports sending large messages.

For Ctrlr: It is based on JUCE, which supports native MIDI on many operating systems. If you try to avoid JACK, it should work. For Windows you can use Virtual Midi cables in case you need other software to interact with Ctrlr. Other systems have native support for virtual MIDI devices. So you could even connect them to JACK in case you use an application that only supports JACK.

keinstein commented 1 year ago

That's related on how USB works. In contrast to a UART (e.g. the game port on a sound card) USB sends a MIDI message as a whole and not byte by byte. 256 bytes is 4 times the maximum packet size of 64 bytes. Because sysex message can get larger than 64 bytes these can be split into multiple packets, but this can overflow the buffer of the receiving device.

That is totally unrelated for @tl072 as ALSA accesses the devices via its class complient driver. This handles all speed issues. The limit is given by JACK.

Though ALSA is not without problems. This problem can be solved as RTP-MIDI poves: This software sends the whole package directly to each connected port.