103 lines
1.9 KiB
C
103 lines
1.9 KiB
C
/* midi.c */
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <err.h>
|
|
#include <sys/midiio.h>
|
|
#include <errno.h>
|
|
#include <sys/ioctl.h>
|
|
#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];
|
|
}
|