/* * filters out note-off events * * compile with: * gcc -o strip_note_offs strip_note_offs.c -lasound */ #include #include int main(void) { snd_seq_t *seq; int i, o; int err; err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0); if (err < 0) { fprintf(stderr, "cannot open sequencer: %s\n", snd_strerror(err)); return 1; } err = snd_seq_set_client_name(seq, "Note-Off Stripper"); if (err < 0) { fprintf(stderr, "cannot set client name: %s\n", snd_strerror(err)); snd_seq_close(seq); return 1; } i = snd_seq_create_simple_port(seq, "Input", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_PORT); if (i < 0) { fprintf(stderr, "cannot create port: %s\n", snd_strerror(err)); snd_seq_close(seq); return 1; } o = snd_seq_create_simple_port(seq, "Output", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_PORT); if (o < 0) { fprintf(stderr, "cannot create port: %s\n", snd_strerror(err)); snd_seq_close(seq); return 1; } for (;;) { snd_seq_event_t ev; snd_seq_event_t *evp; int err; err = snd_seq_event_input(seq, &evp); if (err == -ENOSPC) continue; if (err < 0) { fprintf(stderr, "cannot read event: %s\n", snd_strerror(err)); snd_seq_close(seq); return 1; } ev = *evp; if (ev.dest.port != i) continue; if (ev.type == SND_SEQ_EVENT_NOTEOFF || (ev.type == SND_SEQ_EVENT_NOTEON && ev.data.note.velocity == 0)) continue; snd_seq_ev_set_subs(&ev); snd_seq_ev_set_source(&ev, o); snd_seq_ev_set_direct(&ev); err = snd_seq_event_output_direct(seq, &ev); if (err < 0) { fprintf(stderr, "cannot send event: %s\n", snd_strerror(err)); snd_seq_close(seq); return 1; } } snd_seq_close(seq); return 0; }