From c9ca95083553ace8d01abd7392e4f0bb9be25f3d Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sat, 18 Mar 2017 14:45:39 -0600 Subject: [PATCH] Standardize debugging, reindent (sorry, Plan 9 got me into some weird habits) --- Makefile | 12 +- aac123.c | 156 ---------------- alsa.c | 270 ++++++++++++++-------------- dump.h | 2 +- explore.c | 130 +++++++------- usb.c | 517 ++++++++++++++++++++++++++---------------------------- 6 files changed, 448 insertions(+), 639 deletions(-) delete mode 100644 aac123.c diff --git a/Makefile b/Makefile index 967ca09..b3b8b86 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS += -Wall CFLAGS += -Werror -TARGETS = hdjd aac123 explore -CFLAGS += -g +TARGETS = hdjd explore +#CFLAGS += -g -DDEBUG all: $(TARGETS) @@ -15,13 +15,5 @@ explore.o: CFLAGS += $(shell pkg-config --cflags libusb-1.0) 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) -aac123: LDLIBS += -lfaad -lmp4v2 - -aactest: CFLAGS += $(shell pkg-config --cflags alsa) -aactest: LDLIBS += $(shell pkg-config --libs alsa) -aactest: LDLIBS += -lfaad -lmp4v2 - clean: rm -f $(TARGETS) *.o diff --git a/aac123.c b/aac123.c deleted file mode 100644 index eff8f51..0000000 --- a/aac123.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "dump.h" - - -static int -GetAACTrack(MP4FileHandle *infile) -{ - /* find AAC track */ - MP4TrackId numTracks = MP4GetNumberOfTracks(infile, NULL, 0); - MP4TrackId i; - - for (i = 1; i <= numTracks; i++) - { - uint8_t obj_type; - const char *track_type = MP4GetTrackType(infile, i); - - if (! track_type) continue; - - if (!MP4_IS_AUDIO_TRACK_TYPE(track_type)) continue; - - /* MP4GetTrackAudioType */ - obj_type = MP4GetTrackEsdsObjectTypeId(infile, i); - if (obj_type == MP4_INVALID_AUDIO_TYPE) - continue; - - if (obj_type == MP4_MPEG4_AUDIO_TYPE) { - obj_type = MP4GetTrackAudioMpeg4Type(infile, i); - - if (MP4_IS_MPEG4_AAC_AUDIO_TYPE(obj_type)) - return i; - } else { - if (MP4_IS_AAC_AUDIO_TYPE(obj_type)) - return i; - } - } - - /* can't decode this */ - return -1; -} - -int -play_file(snd_pcm_t *snd, char *fn) -{ - - int track; - - MP4FileHandle infile; - - NeAACDecHandle hDecoder; - NeAACDecConfigurationPtr config; - - unsigned char *buffer; - uint32_t buffer_size; - unsigned long samplerate; - unsigned char channels; - - long sampleId, numSamples; - void *sample_buffer; - - infile = MP4Read(fn); - if (! infile) { - fprintf(stderr, "Unable to open stream\n"); - return 1; - } - - if ((track = GetAACTrack(infile)) < 0) { - fprintf(stderr, "GetAACTrack\n"); - return 1; - } - - hDecoder = NeAACDecOpen(); - config = NeAACDecGetCurrentConfiguration(hDecoder); - config->outputFormat = FAAD_FMT_16BIT; - config->downMatrix = 1; - config->defObjectType = LC; - NeAACDecSetConfiguration(hDecoder, config); - - buffer = NULL; - buffer_size = 0; - MP4GetTrackESConfiguration(infile, track, &buffer, &buffer_size); - - if (NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { - fprintf(stderr, "Initializing decoder\n"); - return 1; - } - if (snd_pcm_set_params(snd, - SND_PCM_FORMAT_S16, - SND_PCM_ACCESS_RW_INTERLEAVED, - channels, - samplerate, - 1, - 500000) < 0) { - fprintf(stderr, "Set ALSA params\n"); - return 1; - } - - if (buffer) { - free(buffer); - } - - DUMP_d(MP4GetTrackMaxSampleSize(infile, track)); - - numSamples = MP4GetTrackNumberOfSamples(infile, track); - - DUMP_d(numSamples); - for (sampleId = 1; sampleId <= numSamples; sampleId++) { - int rc; - unsigned int sample_count; - NeAACDecFrameInfo frameInfo; - - buffer = NULL; - buffer_size = 0; - - rc = MP4ReadSample(infile, track, sampleId, &buffer, &buffer_size, NULL, NULL, NULL, NULL); - if (rc == 0) { - fprintf(stderr, "Read failed\n"); - return 1; - } - - sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, buffer_size); - sample_count = frameInfo.samples; - - snd_pcm_writei(snd, sample_buffer, sample_count / channels); - } - - return 0; -} - -int -main(int argc, char *argv[]) -{ - int i; - snd_pcm_t *snd; - - if (snd_pcm_open(&snd, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { - fprintf(stderr, "Opening ALSA\n"); - return 1; - } - - for (i = 1; i < argc; i += 1) { - char *fn = argv[i]; - - printf("%s\n", fn); - - play_file(snd, fn); - } - - return 0; -} - diff --git a/alsa.c b/alsa.c index c33eb7d..3dad300 100644 --- a/alsa.c +++ b/alsa.c @@ -19,191 +19,191 @@ struct pollfd pfd[MAX_PFDS]; void alsa_interrupting() { - //Currently nothing to do. + //Currently nothing to do. } 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_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); - // 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 -1; - } else { - snd_midi_event_no_status(midi_event_parser,1); - return 0; - } + // 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 -1; + } else { + snd_midi_event_no_status(midi_event_parser,1); + return 0; + } } void alsa_close() { - if (midi_event_parser) { - snd_midi_event_free(midi_event_parser); - } - if (snd_handle) { - snd_seq_close(snd_handle); - } + if (midi_event_parser) { + snd_midi_event_free(midi_event_parser); + } + if (snd_handle) { + snd_seq_close(snd_handle); + } } void alsa_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds) { - npfd = snd_seq_poll_descriptors_count(snd_handle, POLLIN); - int i; + npfd = snd_seq_poll_descriptors_count(snd_handle, POLLIN); + int i; - if (npfd > MAX_PFDS) { - fatal("ALSA wants too many file descriptors"); - } + if (npfd > MAX_PFDS) { + fatal("ALSA wants too many file descriptors"); + } - 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); - } - } + 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_midi_event_init(midi_event_parser); + snd_midi_event_init(midi_event_parser); - for (;;) { - snd_seq_event_t *ev; - unsigned char buf[ALSA_BUFSIZE]; - long converted; - int r; + for (;;) { + snd_seq_event_t *ev; + unsigned char buf[ALSA_BUFSIZE]; + long converted; + int r; - r = snd_seq_event_input(snd_handle, &ev); + r = snd_seq_event_input(snd_handle, &ev); - if (r == -EAGAIN) { - // input queue empty - break; - } else if (r == -ENOSPC) { - warn("Input queue overflow"); - continue; - } else if (r < 0) { - warn("snd_seq_event_input() = %d", r); - continue; - } + if (r == -EAGAIN) { + // input queue empty + break; + } else if (r == -ENOSPC) { + warn("Input queue overflow"); + continue; + } else if (r < 0) { + warn("snd_seq_event_input() = %d", r); + continue; + } - converted = snd_midi_event_decode(midi_event_parser, buf, ALSA_BUFSIZE, ev); - if (converted < 0) { - if (ev->type == SND_SEQ_EVENT_CLIENT_START ) { - printf("Client started \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_CLIENT_EXIT) { - printf("Client exited \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_CLIENT_CHANGE) { - printf("Client status/info changed \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_PORT_START) { - printf("Port created \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) { - printf("Port deleted \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_PORT_CHANGE) { - printf("Port status/info changed \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_PORT_SUBSCRIBED) { - printf("Port connected \n"); - continue; - } else if (ev->type == SND_SEQ_EVENT_PORT_UNSUBSCRIBED) { - printf("Port disconnected \n"); - continue; - } else { - warn("Can't decode MIDI event type 0x%02x", ev->type); - } - continue; - } + converted = snd_midi_event_decode(midi_event_parser, buf, ALSA_BUFSIZE, ev); + if (converted < 0) { + if (ev->type == SND_SEQ_EVENT_CLIENT_START ) { + DUMPf("Client started \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_CLIENT_EXIT) { + DUMPf("Client exited \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_CLIENT_CHANGE) { + DUMPf("Client status/info changed \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_PORT_START) { + DUMPf("Port created \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) { + DUMPf("Port deleted \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_PORT_CHANGE) { + DUMPf("Port status/info changed \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_PORT_SUBSCRIBED) { + DUMPf("Port connected \n"); + continue; + } else if (ev->type == SND_SEQ_EVENT_PORT_UNSUBSCRIBED) { + DUMPf("Port disconnected \n"); + continue; + } else { + warn("Can't decode MIDI event type 0x%02x", ev->type); + } + continue; + } - if (converted < 3) { - int i; + if (converted < 3) { + int i; - warn("Uh oh, weird MIDI packet with length %ld (does this make sense if prefixed with 90?)", converted); + warn("Uh oh, weird MIDI packet with length %ld (does this make sense if prefixed with 90?)", converted); - for (i = 0; i < converted; i += 1) { - fprintf(stderr, " %02x", buf[i]); - } - fprintf(stderr, "\n"); - } + for (i = 0; i < converted; i += 1) { + fprintf(stderr, " %02x", buf[i]); + } + fprintf(stderr, "\n"); + } - usb_write(buf, converted); - } + usb_write(buf, converted); + } } void alsa_check_fds(fd_set *rfds, fd_set *wfds) { - int i; + int i; - for (i = 0; i < npfd; i += 1) { - int fd = pfd[i].fd; + for (i = 0; i < npfd; i += 1) { + int fd = pfd[i].fd; - if (FD_ISSET(fd, rfds) || FD_ISSET(fd, wfds)) { - alsa_read_ready(); - return; - } - } + if (FD_ISSET(fd, rfds) || FD_ISSET(fd, wfds)) { + alsa_read_ready(); + return; + } + } } void alsa_write(uint8_t *data, size_t datalen) { - size_t offset = 0; + size_t offset = 0; - snd_midi_event_init(midi_event_parser); + snd_midi_event_init(midi_event_parser); - while( datalen > offset) { - snd_seq_event_t ev; - long encoded; - int r; + while( 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; + 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, (long int)datalen); - fprintf(stderr, " "); - for (i = offset; i < (long int)datalen; i += 1) { - fprintf(stderr, "%02x ", data[i]); - } - fprintf(stderr, "\n"); + warn("Unable to encode MIDI message (%ld < %ld)", encoded, (long int)datalen); + fprintf(stderr, " "); + for (i = offset; i < (long int)datalen; i += 1) { + fprintf(stderr, "%02x ", data[i]); + } + fprintf(stderr, "\n"); - return; - } + 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); + 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); - } + 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); + offset += encoded; + } + snd_seq_drain_output(snd_handle); } diff --git a/dump.h b/dump.h index 1fb863b..04cadda 100644 --- a/dump.h +++ b/dump.h @@ -6,7 +6,7 @@ #include /* Some things I use for debugging */ -#ifdef NODUMP +#ifdef DEBUG # define DUMPf(fmt, args...) #else # define DUMPf(fmt, args...) fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##args) diff --git a/explore.c b/explore.c index 551776d..5abde0d 100644 --- a/explore.c +++ b/explore.c @@ -19,92 +19,92 @@ #define DUMP_p(v) DUMPf("%s = %p", #v, v) struct device { - char *name; - uint16_t product_id; - uint8_t ep_in; - uint8_t ep_out; + char *name; + uint16_t product_id; + uint8_t ep_in; + uint8_t ep_out; }; const struct device devices[] = { - {"Steel", 0xb102, 0x83, 0x04}, - {"MP3e2", 0xb105, 0x82, 0x03}, - {"4Set", 0xb10c, 0x84, 0x02}, - {0, 0, 0, 0} + {"Steel", 0xb102, 0x83, 0x04}, + {"MP3e2", 0xb105, 0x82, 0x03}, + {"4Set", 0xb10c, 0x84, 0x02}, + {0, 0, 0, 0} }; int main(int argc, char **argv) { - struct libusb_device_handle *dev; - struct libusb_device_descriptor ddesc; - unsigned char name[100]; - const struct device *d; - int ret; + struct libusb_device_handle *dev; + struct libusb_device_descriptor ddesc; + unsigned char name[100]; + const struct device *d; + int ret; - if (libusb_init(NULL) < 0) { - return 69; - } + if (libusb_init(NULL) < 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); - { - unsigned char *p = name; + 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); + { + unsigned 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); - } + 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); + if (ret < 0) { + printf("Can't figure out what to call this thing.\n"); + return 69; + } + } + printf("Opened a %s\n", name); - while (1) { - uint8_t data[256]; - int transferred; - int i; + while (1) { + uint8_t data[256]; + int transferred; + int i; - if ((ret = libusb_bulk_transfer(dev, d->ep_in, data, sizeof data, &transferred, 0))) { - break; - } + if ((ret = libusb_bulk_transfer(dev, d->ep_in, data, sizeof data, &transferred, 0))) { + break; + } - for (i = 0; i < transferred; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); + for (i = 0; i < transferred; i += 1) { + printf("%02x ", data[i]); + } + printf("\n"); - { - uint8_t data[16]; + { + uint8_t data[16]; - memset(data, 0xff, sizeof data); - libusb_bulk_transfer(dev, d->ep_out, data, sizeof data, &transferred, 0); - } + memset(data, 0xff, sizeof data); + libusb_bulk_transfer(dev, d->ep_out, data, sizeof data, &transferred, 0); + } - } + } - if (ret < 0) { - printf("ERROR: %s\n", libusb_error_name(ret)); - } + if (ret < 0) { + printf("ERROR: %s\n", libusb_error_name(ret)); + } - libusb_exit(NULL); + libusb_exit(NULL); - return 0; + return 0; } diff --git a/usb.c b/usb.c index 7afe577..d821d53 100644 --- a/usb.c +++ b/usb.c @@ -12,21 +12,21 @@ #define MAX_PFDS 20 struct device { - uint16_t product_id; - uint8_t interface_number; - uint8_t ep_in; - uint8_t ep_out; - uint8_t ep_in2; - uint8_t interface_number2; + uint16_t product_id; + uint8_t interface_number; + uint8_t ep_in; + uint8_t ep_out; + uint8_t ep_in2; + uint8_t interface_number2; }; const struct device devices[] = { - { 0xb102, 1, 0x83, 0x04, 0x0, 0 }, // Steel - { 0xb105, 1, 0x82, 0x03, 0x0, 0 }, // MP3e2 - { 0xb120, 1, 0x82, 0x03, 0x0, 0 }, // Hercules MP3 LE / Glow - { 0xb107, 1, 0x83, 0x03, 0x0, 0 }, // Hercules Mk4 - { 0xb100, 1, 0x86, 0x06, 0x0, 0 }, // Hercules Mk2 - { 0xb109, 5, 0x83, 0x03, 0x84, 0}, // 4-Mx - { 0, 0, 0, 0 } + { 0xb102, 1, 0x83, 0x04, 0x0, 0 }, // Steel + { 0xb105, 1, 0x82, 0x03, 0x0, 0 }, // MP3e2 + { 0xb120, 1, 0x82, 0x03, 0x0, 0 }, // Hercules MP3 LE / Glow + { 0xb107, 1, 0x83, 0x03, 0x0, 0 }, // Hercules Mk4 + { 0xb100, 1, 0x86, 0x06, 0x0, 0 }, // Hercules Mk2 + { 0xb109, 5, 0x83, 0x03, 0x84, 0}, // 4-Mx + { 0, 0, 0, 0 } }; static const int MANUFACTURER_HERCULES = 0x6f8; @@ -40,334 +40,307 @@ struct libusb_transfer *xfer_in2; static int writes_pending = 0; static int reads_pending = 0; +void +usb_debug_msg(char *action, int ep, uint8_t data[], size_t datalen) +{ +#ifdef DEBUG + fprintf(stderr, "%s on ep%02x:", action, ep); + for (int i = 0; i < datalen; i += 1) { + fprintf(stderr, " %02x", data[i]); + } + fprintf(stderr, "\n"); +#endif +} + void usb_xfer_done(struct libusb_transfer *xfer); void usb_xfer_done_additional(struct libusb_transfer *xfer); void usb_interrupting() { - libusb_cancel_transfer(xfer_in); - if (dev_info->ep_in2 != 0x0) { - libusb_cancel_transfer(xfer_in2); - } + libusb_cancel_transfer(xfer_in); + if (dev_info->ep_in2 != 0x0) { + libusb_cancel_transfer(xfer_in2); + } } static void usb_initiate_transfer() { - static const int buffsize = 256; - unsigned char *buf; + static const int buffsize = 256; + unsigned char *buf; - buf = (unsigned char *)malloc(buffsize); + buf = (unsigned char *)malloc(buffsize); - // Tell libusb we want to know about bulk transfers - xfer_in = libusb_alloc_transfer(0); - //timeout if in 1000 milliseconds it hasn't been sent - xfer_in->timeout=1000; - xfer_in->flags |=LIBUSB_TRANSFER_ADD_ZERO_PACKET; - libusb_fill_bulk_transfer(xfer_in, usb_dev, dev_info->ep_in, buf, buffsize, usb_xfer_done, NULL, 0); - libusb_submit_transfer(xfer_in); - reads_pending += 1; + // Tell libusb we want to know about bulk transfers + xfer_in = libusb_alloc_transfer(0); + //timeout if in 1000 milliseconds it hasn't been sent + xfer_in->timeout=1000; + xfer_in->flags |=LIBUSB_TRANSFER_ADD_ZERO_PACKET; + libusb_fill_bulk_transfer(xfer_in, usb_dev, dev_info->ep_in, buf, buffsize, usb_xfer_done, NULL, 0); + libusb_submit_transfer(xfer_in); + reads_pending += 1; } static void usb_initiate_transfer_additional() { - static const int buffsize = 256; - unsigned char *buf; + static const int buffsize = 256; + unsigned char *buf; - buf = (unsigned char *)malloc(buffsize); + buf = (unsigned char *)malloc(buffsize); - // Tell libusb we want to know about bulk transfers - xfer_in2 = libusb_alloc_transfer(0); - //timeout if in 1000 milliseconds it hasn't been sent - xfer_in2->timeout=1000; - xfer_in2->flags |=LIBUSB_TRANSFER_ADD_ZERO_PACKET; - libusb_fill_bulk_transfer(xfer_in2, usb_dev, dev_info->ep_in2, buf, buffsize, usb_xfer_done_additional, NULL, 0); - libusb_submit_transfer(xfer_in2); + // Tell libusb we want to know about bulk transfers + xfer_in2 = libusb_alloc_transfer(0); + //timeout if in 1000 milliseconds it hasn't been sent + xfer_in2->timeout=1000; + xfer_in2->flags |=LIBUSB_TRANSFER_ADD_ZERO_PACKET; + libusb_fill_bulk_transfer(xfer_in2, usb_dev, dev_info->ep_in2, buf, buffsize, usb_xfer_done_additional, NULL, 0); + libusb_submit_transfer(xfer_in2); } void usb_xfer_done(struct libusb_transfer *xfer) { - uint8_t *data = xfer->buffer; - int datalen = xfer->actual_length; - reads_pending -= 1; - if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { - #ifndef NDEBUG - printf("Receiving on %02x:", dev_info->ep_in); - int i; - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); - #endif - alsa_write(data, datalen); - } - free(data); - libusb_free_transfer(xfer); - if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { - usb_initiate_transfer(); - } else if ( xfer->status != LIBUSB_TRANSFER_CANCELLED ) { - fatal("Stopping EP_IN, because of status %d.\nSoftware needs restarting", xfer->status); - } + uint8_t *data = xfer->buffer; + int datalen = xfer->actual_length; + reads_pending -= 1; + if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { + usb_debug_msg("Receiving", dev_info->ep_in, data, datalen); + alsa_write(data, datalen); + } + free(data); + libusb_free_transfer(xfer); + if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { + usb_initiate_transfer(); + } else if ( xfer->status != LIBUSB_TRANSFER_CANCELLED ) { + fatal("Stopping EP_IN, because of status %d.\nSoftware needs restarting", xfer->status); + } } void usb_xfer_done_additional(struct libusb_transfer *xfer) { - uint8_t *data = xfer->buffer; - if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { - //We don't need to use the information of this call, but it is needed that we - //poll this, or else it hangs and doesn't receive more data. - #ifndef NDEBUG - int datalen = xfer->actual_length; - printf("Receiving on %02x:", dev_info->ep_in2); - int i; - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); - #endif - } - free(data); - libusb_free_transfer(xfer); - if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { - usb_initiate_transfer_additional(); - } else if ( xfer->status != LIBUSB_TRANSFER_CANCELLED ) { - fatal("Stopping EP_IN2, because of status %d\nSoftware needs restarting", xfer->status); - } + if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { + // We don't need to use the information of this call, but it is needed that we + // poll this, or else it hangs and doesn't receive more data. + usb_debug_msg("Receiving", dev_info->ep_in2, xfer->buffer, xfer->actual_length); + } + + if ( xfer->status == LIBUSB_TRANSFER_COMPLETED ) { + usb_initiate_transfer_additional(); + } else if ( xfer->status != LIBUSB_TRANSFER_CANCELLED ) { + fatal("Stopping EP_IN2, because of status %d\nSoftware needs restarting", xfer->status); + } + + free(xfer->buffer); + libusb_free_transfer(xfer); } int usb_setup(char *name, size_t namelen) { - int ret; - ret=libusb_init(&context); - if (ret < 0) { - fatal("ERROR: %s\n%s", libusb_error_name(ret), libusb_strerror(ret)); - return -1; - } - //---------------------------------------------------------------------------- - // Enable debug - //---------------------------------------------------------------------------- - #ifndef NDEBUG - libusb_set_debug(context, LIBUSB_LOG_LEVEL_WARNING); - #endif + int ret; + ret=libusb_init(&context); + if (ret < 0) { + fatal("ERROR: %s\n%s", libusb_error_name(ret), libusb_strerror(ret)); + return -1; + } + //---------------------------------------------------------------------------- + // Enable debug + //---------------------------------------------------------------------------- +#ifdef DEBUG + libusb_set_debug(context, LIBUSB_LOG_LEVEL_WARNING); +#endif - if (libusb_pollfds_handle_timeouts(context) == 0) { - fatal("I'm too dumb to handle events on such an old system."); - return -1; - } - //---------------------------------------------------------------------------- - // Get device list - //---------------------------------------------------------------------------- - struct libusb_device_descriptor founddesc = {0}; - { - libusb_device **devs; - ssize_t count; //holding number of devices in list - printf("Locating Hercules USB devices...\n(You can also use the lsusb command to locate this information)\n"); - count = libusb_get_device_list(context, &devs); - if ( count < 0) { - fatal("Error getting the device list: %s\n%s", libusb_error_name(count), libusb_strerror(count)); - return -1; - } else if (count == 0) { - warn("Seems that the USB device list is empty. Is the controller connected? "); - } - size_t idx; - for (idx = 0; idx < count; idx+=1) { - libusb_device *device = devs[idx]; - struct libusb_device_descriptor listdesc = {0}; - - ret = libusb_get_device_descriptor(device, &listdesc); - if ( ret != 0) { - warn("Could not get descriptor for device index %ld: %s\n%s", - (long int)idx, libusb_error_name(count), libusb_strerror(count)); - } else if (listdesc.idVendor == MANUFACTURER_HERCULES) { - printf("Vendor:Device = %04x:%04x\n", listdesc.idVendor, listdesc.idProduct); - founddesc = listdesc; - } - } - - libusb_free_device_list(devs, 1); //free the list, unref the devices in it - //---------------------------------------------------------------------------- + if (libusb_pollfds_handle_timeouts(context) == 0) { + fatal("I'm too dumb to handle events on such an old system."); + return -1; + } + //---------------------------------------------------------------------------- + // Get device list + //---------------------------------------------------------------------------- + struct libusb_device_descriptor founddesc = {0}; + { + libusb_device **devs; + ssize_t count; //holding number of devices in list + printf("Locating Hercules USB devices...\n(You can also use the lsusb command to locate this information)\n"); + count = libusb_get_device_list(context, &devs); + if ( count < 0) { + fatal("Error getting the device list: %s\n%s", libusb_error_name(count), libusb_strerror(count)); + return -1; + } else if (count == 0) { + warn("Seems that the USB device list is empty. Is the controller connected? "); } - for (dev_info = devices; dev_info->product_id; dev_info += 1) { - usb_dev = libusb_open_device_with_vid_pid(context, MANUFACTURER_HERCULES, dev_info->product_id); - if (usb_dev) { - break; - } else if (dev_info->product_id == founddesc.idProduct) { - fatal("The controller %04x:%04x could not be opened.\n" + size_t idx; + for (idx = 0; idx < count; idx+=1) { + libusb_device *device = devs[idx]; + struct libusb_device_descriptor listdesc = {0}; + + ret = libusb_get_device_descriptor(device, &listdesc); + if ( ret != 0) { + warn("Could not get descriptor for device index %ld: %s\n%s", + (long int)idx, libusb_error_name(count), libusb_strerror(count)); + } else if (listdesc.idVendor == MANUFACTURER_HERCULES) { + printf("Vendor:Device = %04x:%04x\n", listdesc.idVendor, listdesc.idProduct); + founddesc = listdesc; + } + } + + libusb_free_device_list(devs, 1); //free the list, unref the devices in it + //---------------------------------------------------------------------------- + } + for (dev_info = devices; dev_info->product_id; dev_info += 1) { + usb_dev = libusb_open_device_with_vid_pid(context, MANUFACTURER_HERCULES, dev_info->product_id); + if (usb_dev) { + break; + } else if (dev_info->product_id == founddesc.idProduct) { + fatal("The controller %04x:%04x could not be opened.\n" "Check that you have enough permissions over /dev/bus/usb/ subfolder elements.\n." "You might need to create an udev rule at /etc/udev/rules.d/", founddesc.idVendor,founddesc.idProduct); - } - } - if (! usb_dev) { - if (founddesc.idVendor != MANUFACTURER_HERCULES) { - fatal("Couldn't find a Hercules controller."); - } - else { - fatal("The controller %04x:%04x is not supported.", founddesc.idVendor,founddesc.idProduct); - } - return -1; - } - - // Figure out what it's called - { - struct libusb_device_descriptor ddesc; - name[0]='\0'; - 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) { - char *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) { - warn("I can't figure out what to call this thing."); - } - printf("Opened [%s]\n", name); - } - - ret = libusb_claim_interface(usb_dev, dev_info->interface_number); - if (ret == 0 ) { - if (dev_info->ep_in2 != 0x0) { - libusb_claim_interface(usb_dev, dev_info->interface_number2); - usb_initiate_transfer_additional(); - } - usb_initiate_transfer(); - return 0; - } else { - if (ret == LIBUSB_ERROR_BUSY) { - fatal("Couldn't claim interface %d. Already in use?", dev_info->interface_number); - } else { - fatal("Couldn't claim interface %d. %s\n%s", dev_info->interface_number, - libusb_error_name(ret), libusb_strerror(ret)); - } - return -1; } + } + if (! usb_dev) { + if (founddesc.idVendor != MANUFACTURER_HERCULES) { + fatal("Couldn't find a Hercules controller."); + } + else { + fatal("The controller %04x:%04x is not supported.", founddesc.idVendor,founddesc.idProduct); + } + return -1; + } + + // Figure out what it's called + { + struct libusb_device_descriptor ddesc; + name[0]='\0'; + 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) { + char *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) { + warn("I can't figure out what to call this thing."); + } + printf("Opened [%s]\n", name); + } + + ret = libusb_claim_interface(usb_dev, dev_info->interface_number); + if (ret == 0 ) { + if (dev_info->ep_in2 != 0x0) { + libusb_claim_interface(usb_dev, dev_info->interface_number2); + usb_initiate_transfer_additional(); + } + usb_initiate_transfer(); + return 0; + } else { + if (ret == LIBUSB_ERROR_BUSY) { + fatal("Couldn't claim interface %d. Already in use?", dev_info->interface_number); + } else { + fatal("Couldn't claim interface %d. %s\n%s", dev_info->interface_number, + libusb_error_name(ret), libusb_strerror(ret)); + } + return -1; + } } void usb_finish() { - int ret; - if (usb_dev) { - ret = libusb_release_interface(usb_dev, dev_info->interface_number); - if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) { - warn("Couldn't release interface %d. %s\n%s", dev_info->interface_number, - libusb_error_name(ret), libusb_strerror(ret)); - } - libusb_close(usb_dev); - usb_dev=NULL; + int ret; + if (usb_dev) { + ret = libusb_release_interface(usb_dev, dev_info->interface_number); + if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) { + warn("Couldn't release interface %d. %s\n%s", dev_info->interface_number, + libusb_error_name(ret), libusb_strerror(ret)); } - libusb_exit(context); + libusb_close(usb_dev); + usb_dev=NULL; + } + libusb_exit(context); } void usb_fd_setup(int *nfds, fd_set *rfds, fd_set *wfds) { - usb_fds = libusb_get_pollfds(context); - if (usb_fds == NULL) { - warn("could not get the filedescriptors! This is unexpected"); - } + usb_fds = libusb_get_pollfds(context); + if (usb_fds == NULL) { + warn("could not get the filedescriptors! This is unexpected"); + } - int i; - for (i = 0; usb_fds[i]; i += 1) { - const struct libusb_pollfd *ufd = usb_fds[i]; + 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); - } - } + 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); + } + } - if (reads_pending + writes_pending > 100) { - warn("%d(r)+%d(w) = %d outstanding USB transactions!", reads_pending, writes_pending, reads_pending + writes_pending); - } + if (reads_pending + writes_pending > 100) { + warn("%d(r)+%d(w) = %d outstanding USB transactions!", reads_pending, writes_pending, reads_pending + writes_pending); + } } void usb_check_fds(fd_set *rfds, fd_set *wfds) { - if (usb_fds == NULL) { - return; + if (usb_fds == NULL) { + return; + } + + int i; + 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(context); + return; } - - int i; - 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(context); - return; - } - } + } - #if LIBUSB_API_VERSION >= 0x01000104 - libusb_free_pollfds(usb_fds); - usb_fds = NULL; - #endif // LIBUSB_API_VERSION >= 0x01000104 +#if LIBUSB_API_VERSION >= 0x01000104 + libusb_free_pollfds(usb_fds); + usb_fds = NULL; +#endif // LIBUSB_API_VERSION >= 0x01000104 } void usb_write_done(struct libusb_transfer *xfer) { - if ( xfer->status == LIBUSB_TRANSFER_TIMED_OUT ) { - warn("Send timed out"); -#ifndef NDEBUG - uint8_t *data = xfer->buffer; - int datalen = xfer->actual_length; - int i; - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); -#endif - } else if ( xfer->status && xfer->status != LIBUSB_TRANSFER_CANCELLED) { - warn("USB Write status %d", xfer->status); - } - writes_pending -= 1; - uint8_t *data = xfer->buffer; -#ifndef NDEBUG - int datalen = xfer->actual_length; - printf("Sent on %02x:", dev_info->ep_out); - int i; - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); -#endif - free(data); - libusb_free_transfer(xfer); + if ( xfer->status == LIBUSB_TRANSFER_TIMED_OUT ) { + warn("Send timed out"); + } else if ( xfer->status && xfer->status != LIBUSB_TRANSFER_CANCELLED) { + warn("USB Write status %d", xfer->status); + } + writes_pending -= 1; + usb_debug_msg("Sent", dev_info->ep_out, xfer->buffer, xfer->actual_length); + free(xfer->buffer); + libusb_free_transfer(xfer); } void usb_write(uint8_t *data, size_t datalen) { - struct libusb_transfer *xfer; - unsigned char *buf; + struct libusb_transfer *xfer; + unsigned char *buf; - writes_pending += 1; - xfer = libusb_alloc_transfer(0); - //timeout if in 1000 milliseconds it hasn't been sent - xfer->timeout=1000; - buf = (unsigned char *)malloc(datalen); - memcpy(buf, data, datalen); - libusb_fill_bulk_transfer(xfer, usb_dev, dev_info->ep_out, buf, datalen, usb_write_done, NULL, 0); - libusb_submit_transfer(xfer); -#ifndef NDEBUG - printf("Preparing to send on %02x:", dev_info->ep_out); - int i; - for (i = 0; i < datalen; i += 1) { - printf("%02x ", data[i]); - } - printf("\n"); -#endif + writes_pending += 1; + xfer = libusb_alloc_transfer(0); + //timeout if in 1000 milliseconds it hasn't been sent + xfer->timeout=1000; + buf = (unsigned char *)malloc(datalen); + memcpy(buf, data, datalen); + libusb_fill_bulk_transfer(xfer, usb_dev, dev_info->ep_out, buf, datalen, usb_write_done, NULL, 0); + libusb_submit_transfer(xfer); + usb_debug_msg("Preparing to send", dev_info->ep_out, data, datalen); }