Files
lightscript/src/lsi/midi.c
2007-04-29 11:50:00 +00:00

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];
}