mirror of https://github.com/nealey/hdjd.git
Cleaned a bit, lights stopped working
This commit is contained in:
parent
fe5f5ff21b
commit
879aa06038
102
alsa.c
102
alsa.c
|
@ -4,11 +4,15 @@
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include "alsa.h"
|
#include "alsa.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "log.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
|
|
||||||
static snd_seq_t *snd_handle;
|
static snd_seq_t *snd_handle;
|
||||||
static int seq_port;
|
static int seq_port;
|
||||||
static snd_seq_event_t *ev;
|
static snd_midi_event_t *midi_event_parser;
|
||||||
|
|
||||||
|
#define ALSA_BUFSIZE 4096
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
alsa_setup(const char *name)
|
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_READ | SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_READ |
|
||||||
SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
alsa_close()
|
||||||
|
{
|
||||||
|
snd_midi_event_free(midi_event_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define MAX_PFDS 20
|
#define MAX_PFDS 20
|
||||||
int npfd;
|
int npfd;
|
||||||
struct pollfd pfd[MAX_PFDS];
|
struct pollfd pfd[MAX_PFDS];
|
||||||
|
@ -38,8 +54,7 @@ alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (npfd > MAX_PFDS) {
|
if (npfd > MAX_PFDS) {
|
||||||
fprintf(stderr, "ALSA wants too many file descriptors\n");
|
fatal("ALSA wants too many file descriptors");
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_seq_poll_descriptors(snd_handle, pfd, npfd, POLLIN);
|
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
|
void
|
||||||
alsa_read_ready()
|
alsa_read_ready()
|
||||||
{
|
{
|
||||||
static snd_midi_event_t *midi_event_parser;
|
static snd_seq_event_t *ev;
|
||||||
|
|
||||||
if (snd_midi_event_new(ALSA_BUFSIZE, &midi_event_parser) < 0) {
|
|
||||||
fprintf(stderr, "ALSA cannot allocate MIDI event parser\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned char buf[ALSA_BUFSIZE];
|
unsigned char buf[ALSA_BUFSIZE];
|
||||||
long converted;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
if (r == -ENOSPC) {
|
||||||
|
warn("Out of space on input queue");
|
||||||
|
}
|
||||||
|
|
||||||
converted = snd_midi_event_decode(midi_event_parser, buf, ALSA_BUFSIZE, ev);
|
converted = snd_midi_event_decode(midi_event_parser, buf, ALSA_BUFSIZE, ev);
|
||||||
if (converted < 0) {
|
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 {
|
} else {
|
||||||
|
DUMP_d(converted);
|
||||||
usb_write(buf, converted);
|
usb_write(buf, converted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snd_midi_event_free(midi_event_parser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -103,28 +117,40 @@ alsa_check_fds(fd_set *rfds, fd_set *wfds)
|
||||||
void
|
void
|
||||||
alsa_write(uint8_t *data, size_t datalen)
|
alsa_write(uint8_t *data, size_t datalen)
|
||||||
{
|
{
|
||||||
static snd_midi_event_t *midi_event_parser;
|
size_t offset = 0;
|
||||||
snd_seq_event_t ev;
|
|
||||||
long r;
|
|
||||||
|
|
||||||
if (snd_midi_event_new(ALSA_BUFSIZE, &midi_event_parser) < 0) {
|
|
||||||
fprintf(stderr, "ALSA cannot allocate MIDI event parser\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
r = snd_midi_event_encode(midi_event_parser, data, datalen, &ev);
|
for (; datalen > offset;) {
|
||||||
if (r < datalen) {
|
snd_seq_event_t ev;
|
||||||
fprintf(stderr, "ALSA didn't parse that message\n");
|
long encoded;
|
||||||
abort();
|
int r;
|
||||||
}
|
|
||||||
|
encoded = snd_midi_event_encode(midi_event_parser, data + offset, datalen - offset, &ev);
|
||||||
snd_seq_ev_set_direct(&ev);
|
if (encoded <= 1) {
|
||||||
snd_seq_ev_set_source(&ev, seq_port);
|
int i;
|
||||||
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);
|
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;
|
||||||
|
}
|
||||||
|
snd_seq_drain_output(snd_handle);
|
||||||
|
}
|
||||||
|
|
|
@ -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
30
usb.c
|
@ -6,6 +6,7 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "alsa.h"
|
#include "alsa.h"
|
||||||
|
#include "log.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
|
|
||||||
static struct libusb_device_handle *usb_dev;
|
static struct libusb_device_handle *usb_dev;
|
||||||
|
@ -16,14 +17,15 @@ static int reads_pending = 0;
|
||||||
|
|
||||||
struct device {
|
struct device {
|
||||||
uint16_t product_id;
|
uint16_t product_id;
|
||||||
|
uint8_t interface_number;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct device devices[] = {
|
const struct device devices[] = {
|
||||||
{ 0xb102, 0x83, 0x04 }, // Steel
|
{ 0xb102, 1, 0x83, 0x04 }, // Steel
|
||||||
{ 0xb105, 0x82, 0x03 }, // MP3e2
|
{ 0xb105, 1, 0x82, 0x03 }, // MP3e2
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void usb_xfer_done(struct libusb_transfer *transfer);
|
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) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +77,7 @@ usb_setup(char *name, size_t namelen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! usb_dev) {
|
if (! usb_dev) {
|
||||||
printf("Couldn't find a controller.\n");
|
fatal("Couldn't find a controller.");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out what it's called
|
// Figure out what it's called
|
||||||
|
@ -94,10 +95,15 @@ usb_setup(char *name, size_t namelen)
|
||||||
ret = libusb_get_string_descriptor_ascii(usb_dev, ddesc.iProduct, (unsigned char *)p, namelen - ret - 1);
|
ret = libusb_get_string_descriptor_ascii(usb_dev, ddesc.iProduct, (unsigned char *)p, namelen - ret - 1);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
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);
|
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();
|
usb_initiate_transfer();
|
||||||
|
|
||||||
|
@ -125,7 +131,7 @@ usb_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reads_pending + writes_pending > 10) {
|
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
|
void
|
||||||
usb_write_done(struct libusb_transfer *xfer)
|
usb_write_done(struct libusb_transfer *xfer)
|
||||||
{
|
{
|
||||||
|
DUMP_d(xfer->status);
|
||||||
writes_pending -= 1;
|
writes_pending -= 1;
|
||||||
free(xfer->buffer);
|
free(xfer->buffer);
|
||||||
libusb_free_transfer(xfer);
|
libusb_free_transfer(xfer);
|
||||||
|
@ -160,6 +167,13 @@ usb_write(uint8_t *data, size_t datalen)
|
||||||
{
|
{
|
||||||
struct libusb_transfer *xfer;
|
struct libusb_transfer *xfer;
|
||||||
unsigned char *buf;
|
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;
|
writes_pending += 1;
|
||||||
xfer = libusb_alloc_transfer(0);
|
xfer = libusb_alloc_transfer(0);
|
||||||
|
|
Loading…
Reference in New Issue