diff --git a/colorchord2/DisplayUSBIsochronous.c b/colorchord2/DisplayUSBIsochronous.c new file mode 100644 index 0000000..e20d42c --- /dev/null +++ b/colorchord2/DisplayUSBIsochronous.c @@ -0,0 +1,197 @@ +//Copyright 2015 <>< Charles Lohr under the ColorChord License. + +#include "outdrivers.h" +#include "notefinder.h" +#include +#include +#include "parameters.h" +#include +#include +#include "color.h" +#include +#include + +struct LEDOutDriver +{ + struct libusb_device_handle *devh; + int did_init; + int zigzag; + int total_leds; + int array; + float outamp; + uint8_t * last_leds; + volatile int readyFlag; + volatile int transferring; + int xn; + int yn; + int rot90; +}; + +static void isocb(struct libusb_transfer *tf) +{ + struct LEDOutDriver *led = (struct LEDOutDriver*)tf->user_data; + led->transferring = 0; +} + +static void * LEDOutThread( void * v ) +{ + struct LEDOutDriver * led = (struct LEDOutDriver*)v; + + while(1) + { + while(!led->readyFlag || !led->did_init || !led->devh) usleep(100); + + int transfers = ((led->total_leds + 19) / 20); + int totallength = transfers * 64; + + struct libusb_transfer *tf = libusb_alloc_transfer(transfers); + + tf->dev_handle = led->devh; + tf->flags = LIBUSB_TRANSFER_FREE_TRANSFER; + tf->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + tf->num_iso_packets = transfers; + libusb_set_iso_packet_lengths(tf, 64); + tf->endpoint = 1; + tf->flags = 0; + tf->buffer = led->last_leds; + tf->callback = isocb; + tf->length = totallength; + tf->user_data = led; + + if(libusb_submit_transfer(tf)) + { + led->did_init = 0; + printf( "Fault sending LEDs.\n" ); + } + led->transferring = 1; + + while(led->transferring) + { + libusb_handle_events(NULL); + } + led->readyFlag = 0; + } + + return 0; +} + +static void LEDUpdate(void * id, struct NoteFinder*nf) +{ + int i; + struct LEDOutDriver * led = (struct LEDOutDriver*)id; + + if( !led->did_init ) + { + led->did_init = 1; + if( libusb_init(NULL) < 0 ) + { + fprintf( stderr, "Error: Could not initialize libUSB\n" ); +// exit( -99 ); + } + + led->devh = libusb_open_device_with_vid_pid( NULL, 0x16c0, 0x05dc ); + + if( !led->devh ) + { + fprintf( stderr, "Error: Cannot find device.\n" ); +// exit( -98 ); + } + } + + while( led->readyFlag ) usleep(100); + + //Advance the LEDs to this position when outputting the values. + for( i = 0; i < led->total_leds; i++ ) + { + int source = i; + if( !led->array ) + { + int sx, sy; + if( led->rot90 ) + { + sy = i % led->yn; + sx = i / led->yn; + } + else + { + sx = i % led->xn; + sy = i / led->xn; + } + + if( led->zigzag ) + { + if( led->rot90 ) + { + if( sx & 1 ) + { + sy = led->yn - sy - 1; + } + } + else + { + if( sy & 1 ) + { + sx = led->xn - sx - 1; + } + } + } + + if( led->rot90 ) + { + source = sx + sy * led->xn; + } + else + { + source = sx + sy * led->yn; + } + } + + led->last_leds[i*3+0 + (i / 20 + 1) * 4] = OutLEDs[source*3+1] * led->outamp; + led->last_leds[i*3+1 + (i / 20 + 1) * 4] = OutLEDs[source*3+0] * led->outamp; + led->last_leds[i*3+2 + (i / 20 + 1) * 4] = OutLEDs[source*3+2] * led->outamp; + if(i % 20 == 0) + { + led->last_leds[(i / 20) * 64 + 0] = i; + led->last_leds[(i / 20) * 64 + 1] = i >> 8; + led->last_leds[(i / 20) * 64 + 2] = i >> 16; + led->last_leds[(i / 20) * 64 + 3] = i >> 24; + } + } + + led->readyFlag = 1; +} + +static void LEDParams(void * id ) +{ + struct LEDOutDriver * led = (struct LEDOutDriver*)id; + + led->total_leds = GetParameterI( "leds", 300 ); + led->last_leds = (uint8_t*)malloc( led->total_leds * 3 + 1 + ((led->total_leds + 19) / 20) * 4 + 64); + led->outamp = .1; RegisterValue( "ledoutamp", PAFLOAT, &led->outamp, sizeof( led->outamp ) ); + led->zigzag = 0; RegisterValue( "zigzag", PAINT, &led->zigzag, sizeof( led->zigzag ) ); + led->xn = 16; RegisterValue( "lightx", PAINT, &led->xn, sizeof( led->xn ) ); + led->yn = 9; RegisterValue( "lighty", PAINT, &led->yn, sizeof( led->yn ) ); + led->rot90 = 0; RegisterValue( "rot90", PAINT, &led->rot90, sizeof( led->rot90 ) ); + led->array = 0; RegisterValue( "ledarray", PAINT, &led->array, sizeof( led->array ) ); + + led->did_init = 0; +} + + +static struct DriverInstances * DisplayUSBIsochronous() +{ + struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) ); + memset( ret, 0, sizeof( struct DriverInstances ) ); + struct LEDOutDriver * led = ret->id = malloc( sizeof( struct LEDOutDriver ) ); + ret->Func = LEDUpdate; + ret->Params = LEDParams; + OGCreateThread( LEDOutThread, led ); + led->readyFlag = 0; + LEDParams( led ); + return ret; + +} + +REGISTER_OUT_DRIVER(DisplayUSBIsochronous); + + diff --git a/colorchord2/Makefile b/colorchord2/Makefile index d2f3487..806c780 100644 --- a/colorchord2/Makefile +++ b/colorchord2/Makefile @@ -1,6 +1,6 @@ all : colorchord colorchord-opengl -OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayDMX.o OutputProminent.o RecorderPlugin.o DisplayHIDAPI.o hidapi.o OutputCells.o DisplaySHM.o DisplayFileWrite.o DisplayRadialPoles.o +OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayUSBIsochronous.o DisplayDMX.o OutputProminent.o RecorderPlugin.o DisplayHIDAPI.o hidapi.o OutputCells.o DisplaySHM.o DisplayFileWrite.o DisplayRadialPoles.o WINGCC?=i686-w64-mingw32-gcc diff --git a/colorchord2/iso.conf b/colorchord2/iso.conf new file mode 100644 index 0000000..57f33a5 --- /dev/null +++ b/colorchord2/iso.conf @@ -0,0 +1,108 @@ +# This is the configuration file for colorchord. +# Most values are already defaulted in the software. +# This file is constantly checked for new versions. +# \r, and ; are used as terminators, so you can put +# multiple entries on the same line. + +#Whether to limit the control loop to ~60ish FPS. +cpu_autolimit = 1 + +#General GUI properties. +title = PA Test +#set_screenx = 720 +#set_screeny = 480 + +#Sound properties. +buffer = 384 +play = 0 +rec = 1 +channels = 2 +samplerate = 44100 +wininput = 1 + +#Compiled version will default this. +#sound_source = ALSA +#-1 indicates left and right, 0 left, 1 right. + +sample_channel = -1 +sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor +#alsa_output.pci-0000_00_1f.3.analog-stereo.monitor +#default +# alsa_output.pci-0000_00_1b.0.analog-stereo.monitor +#alsa_output.pci-0000_00_1f.3.analog-stereo.monitor << New laptop +#use pactl list | grep pci- | grep monitor + +################################## +# General ColorChord properties. # +################################## + +# How much to amplify the incoming signal. +amplify = 5 + +# What is the base note? I.e. the lowest note. +# Note that it won't have very much impact until an octave up though! +base_hz = 55 + +# This is only used when dealing with the slow decompose (now defunct) +# decompose_iterations = 1000 +# default_sigma = 1.4000 + +# DFT properties for the DFT up top. +dft_iir = 0.6 +dft_q = 20.0000 +dft_speedup = 1000.0000 +octaves = 5 + +# Should we use a progressive DFT? +# 0 = DFT Quick +# 1 = DFT Progressive +# 2 = DFT Progressive Integer +# 3 = DFT Progressive Integer Skippy +# 4 = Integer, 32-Bit, Progressive, Skippy. +do_progressive_dft = 4fa + + +filter_iter = 2 +filter_strength = .5 + +# How many bins per octave to use? +freqbins = 24 + +# For the final note information... How much to slack everything? +note_attach_amp_iir = 0.3500 +note_attach_amp_iir2 = 0.250 +note_attach_freq_iir = 0.3000 + +#How many bins a note can jump from frame to frame to be considered a slide. +#this is used to prevent notes from popping in and out a lot. +note_combine_distance = 0.5000 +note_jumpability = 1.8000 +note_minimum_new_distribution_value = 0.0200 +note_out_chop = 0.05000 + +#compress_coefficient = 4.0 +#compress_exponent = .5 + + +#======================================================================= +#Outputs + + +outdrivers = DisplayUSBIsochronous, OutputVoronoi, DisplayArray + +leds = 484 +lightx = 11 +lighty = 44 +fromsides = 1 +shape_cutoff = 0.03 +satamp = 2.000 +amppow = 2.5 +distpow = 1.500 +zigzag = 1 +rot90 = 1 +ledoutamp = .01 + +note_attach_amp_iir = .3000 +note_attach_amp_iir2 = .1500 +note_attach_freq_iir = 0.3000 +steady_bright = 0