从 C++ 发送 midi 消息
我使用的是树莓派,所以它有点像 Debian (Raspbian)
I'm using a raspberry pi, so it is sort of Debian (Raspbian)
我有一个正在运行的合成器 (Zynaddsubfx),我想通过代码向他发送 MIDI 消息并让它为我播放音乐.为此,我将使用 ALSA.
I have a synthesizer running (Zynaddsubfx) and I want to send him midi messages from code and have it playing the music for me. I will use ALSA for that.
我通过执行以下操作设法在我的程序中创建了一个发射端口":
I managed to create a "emitting port" in my program by doing:
snd_seq_create_simple_port(seq_handle, "My own sequencer",
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_APPLICATION)
现在我可以在 aconnect -ol
中看到 ZynSubAddFX,在 aconnect -il
中看到我自己的音序器.我可以连接它们:
now I can see ZynSubAddFX in aconnect -ol
and my own sequencer in aconnect -il
. And I'm able to connect them:
pi@cacharro:~/projects/tests$ aconnect 129:0 128:0
pi@cacharro:~/projects/tests$ Info, alsa midi port connected
为此,正如 CL 所建议的那样,我使用打开的 snd_seq_open,存储序列,然后使用 snd_seq_create_simple_port .. 但是:
for doing that, as sugested by CL I used opened snd_seq_open, stored the sequence and then used snd_seq_create_simple_port.. BUT :
正如之前所评论的,我只想在用户交互下向 zynsubaddfx 发送命令,因此创建队列、添加节奏等不是要走的路.
As commented before I just wanna send commands to zynsubaddfx under user interaction so creating queues, adding tempo and so on is not the way to go.
有没有办法通过我打开的端口发送简单的midi命令,比如note on/note off???
Is there a way to send simple midi comands like note on/note off through my opened port ???
推荐答案
在特定时间发送一些事件:
To send some events at a specific time:
- 打开音序器;
- 创建您自己的(源)端口;
- 构建并发送一些事件.
要打开音序器,请调用 snd_seq_open
.(您可以通过 snd_seq_client_id
获取您的客户编号.)
To open the sequencer, call snd_seq_open
.
(You can get your client number with snd_seq_client_id
.)
snd_seq_t seq;
snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
要创建一个端口,分配一个端口信息对象snd_seq_port_info_alloca
,设置端口参数snd_seq_port_info_set_
xxx,并调用snd_seq_create_port
.或者直接调用 snd_seq_create_simple_port
.
To create a port, allocate a port info object with
snd_seq_port_info_alloca
, set port parameters with
snd_seq_port_info_set_
xxx, and call snd_seq_create_port
.
Or simply call snd_seq_create_simple_port
.
int port;
port = snd_seq_create_simple_port(seq, "my port",
SND_SEQ_PORT_CAP_READ | SND_SEQ_POR_CAP_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION);
要发送一个事件,分配一个事件结构(只需对于更改,您可以使用本地 snd_seq_event_t
变量),并调用各种snd_seq_ev_
xxx 函数来设置其属性.然后在发送完所有内容后调用 snd_seq_event_output
和 snd_seq_drain_output
事件.
To send an event, allocate an event structure (just
for a change, you can use a local snd_seq_event_t
variable),
and call various snd_seq_ev_
xxx functions to set its properties.
Then call snd_seq_event_output
, and snd_seq_drain_output
after you've sent all
events.
snd_seq_event_t ev;
snd_seq_ev_clear(&ev);
snd_seq_ev_set_direct(&ev);
/* either */
snd_seq_ev_set_dest(&ev, 64, 0); /* send to 64:0 */
/* or */
snd_seq_ev_set_subs(&ev); /* send to subscribers of source port */
snd_seq_ev_set_noteon(&ev, 0, 60, 127);
snd_seq_event_output(seq, &ev);
snd_seq_ev_set_noteon(&ev, 0, 67, 127);
snd_seq_event_output(seq, &ev);
snd_seq_drain_output(seq);
相关文章