クライアントを介してLinux Midiに生のMIDIバイトを書き込む方法は?

クライアントを介してLinux Midiに生のMIDIバイトを書き込む方法は?

コマンドラインユーティリティmidiを使用すると、で識別されたすべてのalsa rawmidiポートにMIDI 16進バイトを送信できますamidi -l。私はMidi Throughのすべてのメッセージを監視する音楽ソフトウェア(Organteq)を持っています。私はMidi Throughを書いてこのソフトウェアを書いたいと思います。

残念ながら、ポートがMIDIに表示されないため、書き込めません。ポートはaplaymidiとpmidiに表示され、どちらも生のバイトをサポートせず、midiファイルのみを送信します。

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.

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           '

それでは、1)クライアント14に書き込むか、またはより良い方法で2)クライアント128に直接書き込むにはどうすればよいですか?

ベストアンサー1

私の問い合わせによると、コマンドラインユーティリティはありません。ただし、これはALSA Cインタフェースを使用することで可能です。名前付きオープンハンドルを使用してLinux ALSAシーケンサーを開き、snd_seq_open()そのsnd_seq_set_client_name名前のポートを作成する必要があります(他のALSAクライアントがポートからデータを読み取ることを許可します)。snd_seq_create_simple_port()SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ

この時点で、プログラムが実行されているときにpmidi -lまたはaconnect -lを使用してポートを表示できる必要があります。

次に、選択したALSAポートに書き込むには、snd_seq_event_tMIDIイベントの構造を作成し、関連情報を入力し(手動でフィールドを割り当てるか、以下のマクロ機能を使用して)最後に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

おすすめ記事