1

The command line utility amidi may be used to send MIDI hexadecimal bytes to any alsa rawmidi port identified in amidi -l. I have a piece of music software (Organteq) which monitors Midi Through for any messages. I would like to write to this software by writing to Midi Through.

Unfortunately, the port does not show up on amidi and thus I cannot write to it. The port does show up on aplaymidi and pmidi, both of which do not support raw bytes, only sending midi files:

aplaymidi -l
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 20:0    CLASSIC ORGAN CMK3               CLASSIC ORGAN CMK3 CLASSIC ORGA.

It is also visible on aconnect:

aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
        Connecting To: 144:0
    1 'Announce        '
        Connecting To: 144:0, 128:0
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
        Connecting To: 128:1
client 20: 'CLASSIC ORGAN CMK3' [type=kernel,card=1]
    0 'CLASSIC ORGAN CMK3 CLASSIC ORGA'
        Connecting To: 128:2
client 128: 'Organteq' [type=user,pid=2372]
    0 'announcements   '
        Connected From: 0:1
    1 'Midi Through Port-0'
        Connected From: 14:0
    2 'CLASSIC ORGAN CMK3 CLASSIC ORGA'
        Connected From: 20:0
client 144: 'PipeWire-System' [type=user,pid=1100]
    0 'input           '
        Connected From: 0:1, 0:0
client 145: 'PipeWire-RT-Event' [type=user,pid=1100]
    0 'input           '

So, how may I write 1) to client 14, or perhaps even better, 2) write directly to client 128?

2 Answers 2

3

From my inquiries there is no command-line utility. However, using the ALSA C interface this is possible. One must open the Linux ALSA sequencer using snd_seq_open(), and name the opened handle with snd_seq_set_client_name, then create a port using snd_seq_create_simple_port() with the designation SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ (to allow other ALSA clients to read from the port).

At this point your port should be visible using pmidi -l or aconnect -l while your program is running.

Then to write to your chosen ALSA port, simply create a snd_seq_event_t struct for your MIDI event and fill in the relevant information (whether by manually assigning fields or by using macro functions like below), and finally send with snd_seq_event_output().

snd_seq_event_t ev;
int err;
snd_seq_ev_clear(&ev); snd_seq_ev_set_direct(&ev); //direct passing mode (i.e. no queue)

snd_seq_ev_set_dest(&ev, 128, 1); //id and port number of destination. could also subscribe to this port and then use snd_seq_ev_set_subs to send to subscribers
snd_seq_ev_set_noteon(&ev, 0, 45, 127);  //channel, key number, velocity
if ((err = snd_seq_event_output(seq_handle, &ev)) < 0) {
    printf("send to sequencer failed \n"); return -1; }
snd_seq_drain_output(seq_handle); //call when nothing further to send
2

Load the snd-virmidi module (modprobe snd-virmidi). This creates a virtual sound card with several raw MIDI devices that you can also access from Organteq.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .