From fbc59832be80ea47ef3c8b205f5fbd36aea6608f Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 27 May 2013 22:11:48 -0600 Subject: [PATCH] modularize --- Makefile | 9 +- alsa.c | 104 ++++++++++++++++++++++ alsa.h | 10 +++ hdjd.c | 266 ++++++------------------------------------------------- usb.c | 121 +++++++++++++++++++++++++ usb.h | 10 +++ 6 files changed, 280 insertions(+), 240 deletions(-) create mode 100644 alsa.c create mode 100644 alsa.h create mode 100644 usb.c create mode 100644 usb.h diff --git a/Makefile b/Makefile index 26775f1..d0ce221 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,14 @@ +CFLAGS += -Wall +CFLAGS += -Werror + all: hdjd aac123 -hdjd: CFLAGS += $(shell pkg-config --cflags libusb-1.0) hdjd: LDFLAGS += $(shell pkg-config --libs libusb-1.0) -hdjd: CFLAGS += $(shell pkg-config --cflags alsa) hdjd: LDFLAGS += $(shell pkg-config --libs alsa) +hdjd: hdjd.o usb.o alsa.o + +alsa.o: CFLAGS += $(shell pkg-config --cflags alsa) +usb.o: CFLAGS += $(shell pkg-config --cflags libusb-1.0) aac123: CFLAGS += $(shell pkg-config --cflags alsa) aac123: LDLIBS += $(shell pkg-config --libs alsa) diff --git a/alsa.c b/alsa.c new file mode 100644 index 0000000..4b13754 --- /dev/null +++ b/alsa.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include "dump.h" + +static snd_seq_t *snd_handle; +static int seq_port; +static snd_midi_event_t *midi_event_parser; + +int +alsa_setup(const char *name) +{ + if (snd_seq_open(&snd_handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { + perror("snd_seq_open"); + return -1; + } + snd_seq_nonblock(snd_handle, 1); + snd_seq_set_client_name(snd_handle, name); + seq_port = + snd_seq_create_simple_port(snd_handle, 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); + + if (snd_seq_event_input(handle, &ev) < 0) { + return -1; + } + + if (snd_midi_event_new(256, &midi_event_parser) < 0) { + return -1; + } + + return 0; +} + +#define MAX_PFDS 20 +int npfd; +struct pollfd pfd[MAX_PFDS]; + +void +alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds) +{ + npfd = snd_seq_poll_descriptors_count(snd_handle, POLLIN); + int i; + + if (npfd > MAX_PFDS) { + fprintf(stderr, "ALSA wants too many file descriptors\n"); + abort(); + } + + snd_seq_poll_descriptors(snd_handle, pfd, npfd, POLLIN); + for (i = 0; i < npfd; i += 1) { + if (pfd[i].fd > *nfds) { + *nfds = pfd[i].fd; + } + if (pfd[i].events & POLLIN) { + FD_SET(pfd[i].fd, rfds); + } + } +} + + +void +alsa_read_ready() +{ + snd_seq_event_t *ev; + int ret = 1; + + for (;;) { + char buf[256]; + long converted; + int i; + + if (snd_seq_event_input(handle, &ev) < 0) { + break; + } + if (!midi_event_parser) { + if (snd_midi_event_new(256, &midi_event_parser) < 0) { + continue; + } + } + converted = snd_midi_event_decode(midi_event_parser, buf, 256, ev); + printf(" << "); + for (i = 0; i < converted; i += 1) { + printf("%02x ", buf[i]); + } + printf(":\n"); + } +} + +void +alsa_check_fds(fd_set *rfds, fd_set *wfds) +{ + int i; + + for (i = 0; i < npfd; i += 1) { + int fd = pfds[i]->fd; + + if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds)) { + alsa_read_ready(); + return; + } + } +} diff --git a/alsa.h b/alsa.h new file mode 100644 index 0000000..fc0d3b3 --- /dev/null +++ b/alsa.h @@ -0,0 +1,10 @@ +#ifndef _ALSA_H_ +#define _ALSA_H_ + +#include + +int alsa_setup(const char *name); +void alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds); +void alsa_read_ready(); + +#endif diff --git a/hdjd.c b/hdjd.c index ab82e46..00269e0 100644 --- a/hdjd.c +++ b/hdjd.c @@ -1,262 +1,52 @@ #include #include -#include #include -#include +#include "alsa.h" +#include "usb.h" #include "dump.h" -/* - * Some things I use for debugging - */ -#ifdef NODUMP -#define DUMPf(fmt, args...) -#else -#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args) -#endif -#define DUMP() DUMPf("") -#define DUMP_d(v) DUMPf("%s = %d", #v, v) -#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v) -#define DUMP_s(v) DUMPf("%s = %s", #v, v) -#define DUMP_c(v) DUMPf("%s = '%c' (0x%02x)", #v, v, v) -#define DUMP_p(v) DUMPf("%s = %p", #v, v) - -struct device { - uint16_t product_id; - uint8_t ep_in; - uint8_t ep_out; -}; - -const struct device devices[] = { - { 0xb102, 0x83, 0x04 }, // Steel - { 0xb105, 0x82, 0x03 }, // MP3e2 - { 0, 0, 0 } -}; - -// Handle to ALSA sequencer -static snd_seq_t *handle; - -// Descriptor of our fake handle -int seq_port; - -void -midi_send(uint8_t *data, size_t datalen) +int +setup() { - snd_seq_event_t ev; - snd_midi_event_t *midi_event_parser; - - snd_midi_event_new(datalen, &midi_event_parser); + char name[100]; - snd_midi_event_encode(midi_event_parser, data, datalen, &ev); - snd_seq_ev_set_direct(&ev); - snd_seq_ev_set_source(&ev, seq_port); - snd_seq_ev_set_subs(&ev); - snd_seq_event_output(handle, &ev); - snd_seq_drain_output(handle); - - snd_midi_event_free(midi_event_parser); -} - -void -usb_xfer_done(struct libusb_transfer *transfer) -{ - uint8_t *data = transfer->buffer; - int datalen = transfer->actual_length; - int i; - - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); + if (usb_setup(name, sizeof(name)) < 0) { + return -1; } - printf("\n"); - midi_send(data, datalen); -} - -void -handle_alsa() -{ - static snd_midi_event_t *midi_event_parser = NULL; - snd_seq_event_t *ev; - int ret = 1; - -DUMP(); - for (;;) { - char buf[256]; - long converted; - int i; - - if (snd_seq_event_input(handle, &ev) < 0) { - break; - } - if (! midi_event_parser) { - if (snd_midi_event_new(256, &midi_event_parser) < 0) { - continue; - } - } - converted = snd_midi_event_decode(midi_event_parser, buf, 256, ev); - printf(" << "); - for (i = 0; i < converted; i += 1) { - printf("%02x ", buf[i]); - } - printf(":\n"); + if (alsa_setup(name) < 0) { + return -1; } + + return 0; } int -main(int argc, char **argv) +main(int argc, char *argv[]) { - struct libusb_device_handle *dev; - struct libusb_device_descriptor ddesc; - char name[100]; - const struct device *d; - nfds_t nfds = 0; - int ret; - - if (libusb_init(NULL) < 0) { + if (setup() < 0) { return 69; } - - for (d = devices; d->product_id; d += 1) { - dev = libusb_open_device_with_vid_pid(NULL, 0x6f8, d->product_id); - if (dev) { - break; - } - } - if (!dev) { - printf("Couldn't find a controller\n"); - return 69; - } - - // Figure out what this thing is called - libusb_get_device_descriptor(libusb_get_device(dev), &ddesc); - { - char *p = name; - - ret = libusb_get_string_descriptor_ascii(dev, ddesc.iManufacturer, name, sizeof(name)); - if (ret > 0) { - p = name + ret; - *p = ' '; - p += 1; - ret = libusb_get_string_descriptor_ascii(dev, ddesc.iProduct, p, sizeof(name) - ret - 1); - } - - if (ret < 0) { - printf("Can't figure out what to call this thing.\n"); - return 69; - } - } - printf("Opened a %s\n", name); - - // Initialize ALSA - if (snd_seq_open(&handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { - perror("snd_seq_open"); - return(69); - } - snd_seq_nonblock(handle, 1); - snd_seq_set_client_name(handle, name); - seq_port = snd_seq_create_simple_port(handle, 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); - - while (1) { - struct libusb_transfer *xfer = libusb_alloc_transfer(0); - uint8_t data[80]; - int transferred; - int i; - - if ((ret = libusb_bulk_transfer(dev, d->ep_in, data, sizeof data, &transferred, 0))) { - break; - } - - // Set up transfer - libusb_fill_bulk_transfer(xfer, dev, d->ep_in, data, sizeof data, usb_xfer_done, NULL, 0); - libusb_submit_transfer(xfer); - - // Select on our file descriptors - { - const struct libusb_pollfd **usb_fds = libusb_get_pollfds(NULL); - struct pollfd *pfd; - int npfd; - struct timeval tv; - struct timeval *timeout; - fd_set rfds, wfds; - int nfds = 0; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - // ALSA shit - { - - npfd = snd_seq_poll_descriptors_count(handle, POLLIN); - pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd)); - snd_seq_poll_descriptors(handle, pfd, npfd, POLLIN); - - for (i = 0; i < npfd; i += 1) { - if (pfd[i].fd > nfds) { - nfds = pfd[i].fd; - } - if (pfd[i].events & POLLIN) { - FD_SET(pfd[i].fd, &rfds); - } - } - } - - // USB shit - { - ret = libusb_get_next_timeout(NULL, &tv); - if (0 == ret) { - timeout = NULL; - } else { - timeout = &tv; - } - - for (i = 0; usb_fds[i]; i += 1) { - const struct libusb_pollfd *ufd = usb_fds[i]; + for (;;) { + fd_set rfds; + fd_set wfds; + int nfds = 0; + int ret; - if (ufd->fd > nfds) { - nfds = ufd->fd; - } - if (ufd->events & POLLIN) { - FD_SET(ufd->fd, &rfds); - } - if (ufd->events & POLLOUT) { - FD_SET(ufd->fd, &wfds); - } - } - } - - ret = select(nfds + 1, &rfds, &wfds, NULL, timeout); - DUMP_d(rfds); - - for (i = 0; usb_fds[i]; i += 1) { - int fd = usb_fds[i]->fd; - - if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds)) { - libusb_handle_events(NULL); - } - } - - for (i = 0; i < npfd; i += 1) { - int fd = pfd[i].fd; - - if (FD_ISSET(fd, &rfds)) { - handle_alsa(); - } - } + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + alsa_fd_setup(&nfds, &rfds, &wfds); + usb_fd_setup(&nfds, &rfds, &wfds); + + ret = select(nfds + 1, &rfds, &wfds, NULL, NULL); + if (-1 == ret) { + DUMP(); } - - libusb_free_transfer(xfer); - } - if (ret < 0) { - printf("ERROR: %s\n", libusb_error_name(ret)); + DUMP(); } - libusb_exit(NULL); - return 0; } diff --git a/usb.c b/usb.c new file mode 100644 index 0000000..305857a --- /dev/null +++ b/usb.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include +#include "dump.h" + +static struct libusb_device_handle *usb_dev; +static struct libusb_transfer *xfer; +static const struct device *d; +uint8_t data[80]; + +struct device { + uint16_t product_id; + uint8_t ep_in; + uint8_t ep_out; +}; + +const struct device devices[] = { + { 0xb102, 0x83, 0x04 }, // Steel + { 0xb105, 0x82, 0x03 }, // MP3e2 + { 0, 0, 0 } +}; + +void usb_xfer_done(struct libusb_transfer *transfer); + +static void +usb_initiate_transfer() +{ + // Tell libusb we want to know about bulk transfers + libusb_fill_bulk_transfer(xfer, usb_dev, d->ep_in, data, sizeof(data), usb_xfer_done, NULL, 0); + libusb_submit_transfer(xfer); +} + +void +usb_xfer_done(struct libusb_transfer *transfer) +{ + uint8_t *data = transfer->buffer; + int datalen = transfer->actual_length; + int i; + + for (i = 0; i < datalen; i += 1) { + printf("%02x ", data[i]); + } + printf("\n"); + + usb_initiate_transfer(); +} + +int +usb_setup(char *name, size_t namelen) +{ + if (libusb_init(NULL) < 0) { + return -1; + } + + for (d = devices; d->product_id; d += 1) { + usb_dev = libusb_open_device_with_vid_pid(NULL, 0x6f8, d->product_id); + if (usb_dev) { + break; + } + } + if (! usb_dev) { + printf("Couldn't find a controller.\n"); + return -1; + } + + // Figure out what it's called + { + int ret; + struct libusb_device_descriptor ddesc; + char *p = name; + + libusb_get_device_descriptor(libusb_get_device(usb_dev), &ddesc); + ret = libusb_get_string_descriptor_ascii(usb_dev, ddesc.iManufacturer, (unsigned char *)name, namelen); + if (ret > 0) { + p = name + ret; + *p = ' '; + p += 1; + 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"); + } + printf("Opened a %s\n", name); + } + + xfer = libusb_alloc_transfer(0); + + return 0; +} + +void +usb_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds) +{ + const struct libusb_pollfd **usb_fds = libusb_get_pollfds(NULL); + int i; + + for (i = 0; usb_fds[i]; i += 1) { + const struct libusb_pollfd *ufd = usb_fds[i]; + + if (ufd->fd > *nfds) { + *nfds = ufd->fd; + } + if (ufd->events & POLLIN) { + FD_SET(ufd->fd, rfds); + } + if (ufd->events & POLLOUT) { + FD_SET(ufd->fd, wfds); + } + } + + + usb_initiate_transfer(); +} + +void +usb_read_ready() +{ + libusb_handle_events(NULL); +} diff --git a/usb.h b/usb.h new file mode 100644 index 0000000..98d8b18 --- /dev/null +++ b/usb.h @@ -0,0 +1,10 @@ +#ifndef _USB_H_ +#define _USB_H_ + +#include + +int usb_setup(const char *name, size_t namelen); +void usb_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds); +void usb_check_fds(fd_set *rfds, fd_set *wfds); + +#endif