Cleaned a bit, lights stopped working

This commit is contained in:
Neale Pickett 2014-12-14 20:29:21 -07:00
parent fe5f5ff21b
commit 879aa06038
3 changed files with 99 additions and 46 deletions

98
alsa.c
View File

@ -4,11 +4,15 @@
#include <alsa/asoundlib.h>
#include "alsa.h"
#include "usb.h"
#include "log.h"
#include "dump.h"
static snd_seq_t *snd_handle;
static int seq_port;
static snd_seq_event_t *ev;
static snd_midi_event_t *midi_event_parser;
#define ALSA_BUFSIZE 4096
int
alsa_setup(const char *name)
@ -24,9 +28,21 @@ alsa_setup(const char *name)
SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_READ |
SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC);
// Allocate parser object for converting to and from MIDI
if (snd_midi_event_new(ALSA_BUFSIZE, &midi_event_parser) < 0) {
fatal("ALSA cannot allocate MIDI event parser");
}
return 0;
}
void
alsa_close()
{
snd_midi_event_free(midi_event_parser);
}
#define MAX_PFDS 20
int npfd;
struct pollfd pfd[MAX_PFDS];
@ -38,8 +54,7 @@ alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds)
int i;
if (npfd > MAX_PFDS) {
fprintf(stderr, "ALSA wants too many file descriptors\n");
abort();
fatal("ALSA wants too many file descriptors");
}
snd_seq_poll_descriptors(snd_handle, pfd, npfd, POLLIN);
@ -55,34 +70,33 @@ alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds)
}
#define ALSA_BUFSIZE 4096
void
alsa_read_ready()
{
static snd_midi_event_t *midi_event_parser;
if (snd_midi_event_new(ALSA_BUFSIZE, &midi_event_parser) < 0) {
fprintf(stderr, "ALSA cannot allocate MIDI event parser\n");
abort();
}
static snd_seq_event_t *ev;
for (;;) {
unsigned char buf[ALSA_BUFSIZE];
long converted;
int r;
if (snd_seq_event_input(snd_handle, &ev) < 0) {
r = snd_seq_event_input(snd_handle, &ev);
if (r == -EAGAIN) {
break;
}
if (r == -ENOSPC) {
warn("Out of space on input queue");
}
converted = snd_midi_event_decode(midi_event_parser, buf, ALSA_BUFSIZE, ev);
if (converted < 0) {
fprintf(stderr, "Can't decode MIDI event type %d\n", ev->type);
warn("Can't decode MIDI event type %d", ev->type);
} else {
DUMP_d(converted);
usb_write(buf, converted);
}
}
snd_midi_event_free(midi_event_parser);
}
void
@ -103,28 +117,40 @@ alsa_check_fds(fd_set *rfds, fd_set *wfds)
void
alsa_write(uint8_t *data, size_t datalen)
{
static snd_midi_event_t *midi_event_parser;
snd_seq_event_t ev;
long r;
size_t offset = 0;
if (snd_midi_event_new(ALSA_BUFSIZE, &midi_event_parser) < 0) {
fprintf(stderr, "ALSA cannot allocate MIDI event parser\n");
abort();
for (; datalen > offset;) {
snd_seq_event_t ev;
long encoded;
int r;
encoded = snd_midi_event_encode(midi_event_parser, data + offset, datalen - offset, &ev);
if (encoded <= 1) {
int i;
warn("Unable to encode MIDI message (%ld < %ld)", encoded, datalen);
fprintf(stderr, " ");
for (i = offset; i < datalen; i += 1) {
fprintf(stderr, "%02x ", data[i]);
}
fprintf(stderr, "\n");
return;
}
snd_seq_ev_set_direct(&ev);
snd_seq_ev_set_source(&ev, seq_port);
snd_seq_ev_set_subs(&ev);
r = snd_seq_event_output(snd_handle, &ev);
if (r < 0) {
warn("Couldn't write an output event");
}
if (r > 200) {
warn("Output buffer size %d", r);
}
offset += encoded;
}
r = snd_midi_event_encode(midi_event_parser, data, datalen, &ev);
if (r < datalen) {
fprintf(stderr, "ALSA didn't parse that message\n");
abort();
}
snd_seq_ev_set_direct(&ev);
snd_seq_ev_set_source(&ev, seq_port);
snd_seq_ev_set_subs(&ev);
if ((r = snd_seq_event_output_direct(snd_handle, &ev)) < 0) {
fprintf(stderr, "ALSA couldn't write an event: %ld\n", r);
abort();
}
snd_midi_event_free(midi_event_parser);
snd_seq_drain_output(snd_handle);
}

13
log.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __LOG_H__
#define __LOG_H__
#include <stdio.h>
#include <stdlib.h>
#define __log__(fmt, args...) fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##args)
#define warn(fmt, args...) __log__("Warning: %s:%d " fmt, __FILE__, __LINE__, ##args)
#define fatal(fmt, args...) do { __log__("Fatal: " fmt, ##args); abort(); } while (0)
#endif

30
usb.c
View File

@ -6,6 +6,7 @@
#include <sys/select.h>
#include "usb.h"
#include "alsa.h"
#include "log.h"
#include "dump.h"
static struct libusb_device_handle *usb_dev;
@ -16,14 +17,15 @@ static int reads_pending = 0;
struct device {
uint16_t product_id;
uint8_t interface_number;
uint8_t ep_in;
uint8_t ep_out;
};
const struct device devices[] = {
{ 0xb102, 0x83, 0x04 }, // Steel
{ 0xb105, 0x82, 0x03 }, // MP3e2
{ 0, 0, 0 }
{ 0xb102, 1, 0x83, 0x04 }, // Steel
{ 0xb105, 1, 0x82, 0x03 }, // MP3e2
{ 0, 0, 0, 0 }
};
void usb_xfer_done(struct libusb_transfer *transfer);
@ -64,7 +66,7 @@ usb_setup(char *name, size_t namelen)
}
if (libusb_pollfds_handle_timeouts(NULL) == 0) {
printf("I'm too dumb to handle events on such an old system.\n");
fatal("I'm too dumb to handle events on such an old system.");
return -1;
}
@ -75,8 +77,7 @@ usb_setup(char *name, size_t namelen)
}
}
if (! usb_dev) {
printf("Couldn't find a controller.\n");
return -1;
fatal("Couldn't find a controller.");
}
// Figure out what it's called
@ -94,11 +95,16 @@ usb_setup(char *name, size_t namelen)
ret = libusb_get_string_descriptor_ascii(usb_dev, ddesc.iProduct, (unsigned char *)p, namelen - ret - 1);
}
if (ret < 0) {
printf("Warning: I can't figure out what to call this thing.\n");
warn("I can't figure out what to call this thing.");
}
printf("Opened [%s]\n", name);
}
if (0 != libusb_claim_interface(usb_dev, d->interface_number)) {
fatal("Couldn't claim interface %d", d->interface_number);
}
usb_initiate_transfer();
return 0;
@ -125,7 +131,7 @@ usb_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds)
}
if (reads_pending + writes_pending > 10) {
fprintf(stderr, "Warning: %d+%d = %d outstanding USB transactions!\n", reads_pending, writes_pending, reads_pending + writes_pending);
warn("%d(r)+%d(w) = %d outstanding USB transactions!", reads_pending, writes_pending, reads_pending + writes_pending);
}
}
@ -150,6 +156,7 @@ usb_check_fds(fd_set *rfds, fd_set *wfds)
void
usb_write_done(struct libusb_transfer *xfer)
{
DUMP_d(xfer->status);
writes_pending -= 1;
free(xfer->buffer);
libusb_free_transfer(xfer);
@ -160,6 +167,13 @@ usb_write(uint8_t *data, size_t datalen)
{
struct libusb_transfer *xfer;
unsigned char *buf;
int i;
DUMP_d(datalen);
for (i = 0; i < datalen; i += 1) {
fprintf(stderr, " %02x", data[i]);
}
fprintf(stderr, "\n");
writes_pending += 1;
xfer = libusb_alloc_transfer(0);