#include #include void connect (snd_seq_t *seq, int port, const char* dest_name) { snd_seq_addr_t addr; snd_seq_parse_address(seq, &addr, dest_name); snd_seq_connect_to(seq, port, addr.client, addr.port); printf("connect to %s: %d:%d\n", dest_name, addr.client, addr.port); } int main () { snd_seq_t *seq; snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0); int port = snd_seq_create_simple_port(seq, "out", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC); connect (seq, port, "aseqdump"); connect (seq, port, "TiMidity"); int control = snd_seq_alloc_queue(seq); int player = snd_seq_alloc_queue(seq); /* start controller queue */ snd_seq_control_queue(seq, control, SND_SEQ_EVENT_START, 0, NULL); snd_seq_drain_output(seq); /* start player queue after one second using controller queue for timing */ const int absolute = 0; snd_seq_real_time_t rtime; rtime.tv_sec = 1; rtime.tv_nsec = 0; snd_seq_ev_schedule_real(&ev, control, absolute, &rtime); snd_seq_control_queue(seq, player, SND_SEQ_EVENT_START, 0, &ev); snd_seq_drain_output(seq); snd_seq_ev_set_source(&ev, port); snd_seq_ev_set_subs(&ev); /* send note-on to player queue with local time 0 */ /* this is played too early, if you increase the time, then the note is not played at all. */ rtime.tv_sec = 0; rtime.tv_nsec = 0; snd_seq_ev_schedule_real(&ev, player, absolute, &rtime); snd_seq_ev_set_noteon(&ev, 0, 60, 64); snd_seq_event_output_direct(seq, &ev); /* send note-off to player queue with local time 1 */ /* this event is dropped */ rtime.tv_sec = 1; rtime.tv_nsec = 0; snd_seq_ev_schedule_real(&ev, player, absolute, &rtime); snd_seq_ev_set_noteoff(&ev, 0, 60, 64); snd_seq_event_output_direct(seq, &ev); snd_seq_sync_output_queue(seq); /* make sure that we do not destroy pending messages */ sleep(3); snd_seq_free_queue(seq, control); snd_seq_free_queue(seq, player); snd_seq_delete_simple_port(seq, port); snd_seq_close(seq); return 0; }