클라이언트를 통해 Linux Midi에 원시 MIDI 바이트를 쓰는 방법은 무엇입니까?

클라이언트를 통해 Linux Midi에 원시 MIDI 바이트를 쓰는 방법은 무엇입니까?

명령줄 유틸리티 midi를 사용하면 에서 식별된 모든 alsa rawmidi 포트에 MIDI 16진수 바이트를 보낼 수 있습니다 amidi -l. 저는 Midi Through의 모든 메시지를 모니터링하는 음악 소프트웨어(Organteq)를 가지고 있습니다. 저는 Midi Through를 작성하여 이 소프트웨어를 작성하고 싶습니다.

불행하게도 포트가 미디에 표시되지 않아 쓸 수 없습니다. 포트는 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

답변2

snd-virmidi 모듈( modprobe snd-virmidi)을 로드합니다. 그러면 Organteq에서도 접근할 수 있는 여러 원시 MIDI 장치가 포함된 가상 사운드 카드가 생성됩니다.

관련 정보