In this example code I set up an ALSA client, create a sequencer queue and output port. Then I output a scheduled note on and note off event to this port and wait for a keystroke. At this point I set up midisnoop to read from the port.
When keystroke arrives I start the queue and read the realtime ticks. I am expecting the note to show on the output port which I am monitoring. Nothing appears.
#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;
}
Starting a queue clears it.
You must send the queue start event before the actual events. (You do not need to drain it separately.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.