/* midi.c */ #include #include #include #include #include #include #include #include "vm.h" #define PORT "/dev/music" int midi_fd; int midi_bytes; seq_event_rec midi_buf; int midi_initialised = 0; int midi_init(void) { midi_fd = open(PORT, O_NONBLOCK | O_RDONLY, 0); if (midi_fd == -1) { err(1, "failed to open MIDI port"); } midi_bytes = 0; midi_initialised = 1; vm_register_signal_fd(midi_fd, VM_MIDIQ); return 1; } void midi_close(void) { printf("Closing MIDI\n"); ioctl(midi_fd, SEQUENCER_SYNC, NULL); ioctl(midi_fd, SEQUENCER_RESET, NULL); printf("...\n"); close(midi_fd); printf("X.\n"); midi_fd = 0; midi_initialised = 0; } /* * Returns non-zero if we're interested in the packet * received. Zero otherwise. */ int midi_filter(void) { switch (midi_buf.arr[0]) { case SEQ_CHN_COMMON: /* We don't care about the unit number - yet */ /* We don't care about the channel - yet */ if (midi_buf.arr[2] == 0xb0) /* cmd */ return 1; return 0; case SEQ_TIMING: return 0; default: printf("Unknown MIDI message received\n"); return 0; } } int midi_read(void) { if (!midi_initialised) return 0; while (1) { int rv; int left = sizeof(midi_buf) - midi_bytes; rv = read(midi_fd, midi_buf.arr + midi_bytes, left); if (rv == -1) { if (errno == EAGAIN) return 0; printf("Error reading from MIDI\n"); close(midi_fd); midi_initialised = 0; } if (rv == 0) return 0; midi_bytes += rv; if (midi_bytes == sizeof(midi_buf)) { midi_bytes = 0; if (midi_filter()) return 1; } } } /* * Return the interesting bits of the MIDI command. * The contents of this function is likely to change * as we become interested in more types of MIDI device. * Pre-condition: midi_filter() has returned 1 */ void midi_getcmd(int *button, int *value) { *button = midi_buf.arr[4]; *value = midi_buf.arr[6]; }