在此示例代码中,我设置了ALSA客户端,创建了一个sequencer队列和输出端口。然后我输出一个预定的音符并注意事件到这个端口并等待击键。此时我设置midisnoop从端口读取。
当按键到达时,我启动队列并读取实时滴答声。我期待在我正在监控的输出端口上显示该注释。什么也没出现。
#include <stdio.h>
#include <alsa/asoundlib.h>
int queue, out_port;
snd_seq_t *seq_handle;
snd_seq_tick_time_t current_tick;
snd_seq_queue_status_t *status;
int main (int argc, char **argv) {
// open sequencer and create queue
snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT | SND_SEQ_OPEN_OUTPUT, 0);
queue = snd_seq_alloc_queue( seq_handle );
fprintf(stderr,"queue id=%d\n", queue);
// create an output port
out_port = snd_seq_create_simple_port(seq_handle, "test:out",
SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_APPLICATION);
if( out_port < 0 ) return 1;
// set up a midi event for scheduling noteon and noteoff
snd_seq_event_t event;
snd_seq_ev_clear( &event );
// set up source address
snd_seq_addr_t addr;
addr.client = snd_seq_client_id( seq_handle);
addr.port = out_port;
event.source = addr;
// set destination addressing to all subscribers
snd_seq_ev_set_subs( &event );
// note specifics
int chan = 0;
int note = 64;
int veloc = 127;
int tick = 0;
// note on at zero
snd_seq_ev_set_noteon( &event, chan, note, veloc);
snd_seq_ev_schedule_tick( &event, queue, 0, tick );
snd_seq_event_output( seq_handle, &event );
// note off at 96
tick = 96;
snd_seq_ev_set_noteoff( &event, chan, note, veloc);
snd_seq_ev_schedule_tick( &event, queue, 0, tick );
snd_seq_event_output( seq_handle, &event );
// drain output
snd_seq_drain_output( seq_handle );
// wait here for keystroke, so we can set up midisnoop
fgetc( stdin );
// start queue and read ticks
snd_seq_start_queue( seq_handle, queue, NULL );
snd_seq_drain_output( seq_handle );
for(int i=0;i<4;i++) {
snd_seq_queue_status_malloc(&status);
snd_seq_get_queue_status(seq_handle, queue, status);
current_tick = snd_seq_queue_status_get_tick_time(status);
snd_seq_queue_status_free(status);
fprintf(stderr,"tick=%d\n", current_tick );
sleep(1);
}
snd_seq_stop_queue( seq_handle, queue, NULL );
snd_seq_free_queue( seq_handle, queue );
return 0;
}
答案 0 :(得分:0)
启动队列会清除它。
您必须在实际事件之前发送队列启动事件。 (您不需要单独排水。)