From bc5c12acc8e9be61ac0df4d978fc229610314aa0 Mon Sep 17 00:00:00 2001 From: Charles Lohr Date: Tue, 31 May 2016 01:11:24 -0400 Subject: [PATCH] Update cells, fix windows build. --- colorchord2/Makefile | 4 +- colorchord2/OutputCells.c | 212 ++++++++++++++++++++++++++++++++++ colorchord2/OutputLinear.c | 6 +- colorchord2/cells_output.conf | 30 +++++ colorchord2/default.conf | 2 +- colorchord2/dmx.conf | 6 +- colorchord2/double_pie.conf | 4 +- colorchord2/main.c | 15 ++- 8 files changed, 265 insertions(+), 14 deletions(-) create mode 100644 colorchord2/OutputCells.c create mode 100644 colorchord2/cells_output.conf diff --git a/colorchord2/Makefile b/colorchord2/Makefile index 35351ae..70e3dba 100644 --- a/colorchord2/Makefile +++ b/colorchord2/Makefile @@ -5,8 +5,8 @@ SOUND:=sound.o sound_alsa.o sound_pulse.o sound_null.o OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayDMX.o OutputProminent.o RecorderPlugin.o OutputCells.o -WINGCC:=i586-mingw32msvc-gcc -WINGCCFLAGS:= -O2 -Wl,--relax -Wl,--gc-sections -ffunction-sections -fdata-sections -s -DICACHE_FLASH_ATTR= -I../embeddedcommon -I. +WINGCC:= i686-w64-mingw32-gcc +WINGCCFLAGS:= -g -DICACHE_FLASH_ATTR= -I../embeddedcommon -I. -O0 #-O2 -Wl,--relax -Wl,--gc-sections -ffunction-sections -fdata-sections WINLDFLAGS:=-lwinmm -lgdi32 -lws2_32 RAWDRAWLIBS:=-lX11 -lm -lpthread -lXinerama -lXext diff --git a/colorchord2/OutputCells.c b/colorchord2/OutputCells.c new file mode 100644 index 0000000..502f985 --- /dev/null +++ b/colorchord2/OutputCells.c @@ -0,0 +1,212 @@ +//Copyright 2015 <>< Charles Lohr under the ColorChord License. + +//XXX TODO Figure out why it STILL fails when going around a loop + + +#include "outdrivers.h" +#include "notefinder.h" +#include +#include +#include "parameters.h" +#include +#include "color.h" +#include +#include +#include + +extern float DeltaFrameTime; +extern double Now; + +struct CellsOutDriver +{ + int did_init; + int total_leds; + int led_note_attached[MAX_LEDS]; + double time_of_change[MAX_LEDS]; + + float last_led_pos[MAX_LEDS]; + float last_led_pos_filter[MAX_LEDS]; + float last_led_amp[MAX_LEDS]; + float led_floor; + float light_siding; + float satamp; + float qtyamp; + int steady_bright; + int lastadvance; + int timebased; //Useful for pies, turn off for linear systems. +}; + +static void LEDUpdate(void * id, struct NoteFinder*nf) +{ + struct CellsOutDriver * led = (struct CellsOutDriver*)id; + + //Step 1: Calculate the quantity of all the LEDs we'll want. + int totbins = nf->note_peaks;//nf->dists; + int i, j; + float binvals[totbins]; + float binvalsQ[totbins]; + float binpos[totbins]; + float totalbinval = 0; + + float qtyHave[totbins]; + float qtyWant[totbins]; + float totQtyWant = 0; + + memset( qtyHave, 0, sizeof( qtyHave ) ); + + for( i = 0; i < led->total_leds; i++ ) + { + int l = led->led_note_attached[i]; + if( l >= 0 ) + { + qtyHave[l] ++; + } + } + + + for( i = 0; i < totbins; i++ ) + { + binpos[i] = nf->note_positions[i] / nf->freqbins; + binvals[i] = pow( nf->note_amplitudes2[i], led->light_siding ); //Slow + binvalsQ[i] = pow( nf->note_amplitudes[i], led->light_siding ); //Fast + totalbinval += binvals[i]; + + float want = binvals[i] * led->qtyamp; + totQtyWant += want; + qtyWant[i] = want; + } + + if( totQtyWant > led->total_leds ) + { + float overage = led->total_leds/totQtyWant; + for( i = 0; i < totbins; i++ ) + qtyWant[i] *= overage; + } + + float qtyDiff[totbins]; + for( i = 0; i < totbins; i++ ) + { + qtyDiff[i] = qtyWant[i] - qtyHave[i]; + } + + //Step 1: Relinquish LEDs + for( i = 0; i < totbins; i++ ) + { + while( qtyDiff[i] < -0.5 ) + { + double maxtime = -1.0; + int maxindex = -1; + + //Find the LEDs that have been on least. + for( j = 0; j < led->total_leds; j++ ) + { + if( led->led_note_attached[j] != i ) continue; + if( !led->timebased ) { maxindex = j; break; } + if( led->time_of_change[j] > maxtime ) + { + maxtime = led->time_of_change[j]; + maxindex = j; + } + } + if( maxindex >= 0 ) + { + led->led_note_attached[maxindex] = -1; + led->time_of_change[maxindex] = Now; + } + qtyDiff[i]++; + } + } + + //Throw LEDs back in. + for( i = 0; i < totbins; i++ ) + { + while( qtyDiff[i] > 0.5 ) + { + double seltime = 1e20; + int selindex = -1; + + + //Find the LEDs that haven't been on in a long time. + for( j = 0; j < led->total_leds; j++ ) + { + if( led->led_note_attached[j] != -1 ) continue; + if( !led->timebased ) { selindex = j; break; } + if( led->time_of_change[j] < seltime ) + { + seltime = led->time_of_change[j]; + selindex = j; + } + } + if( selindex >= 0 ) + { + led->led_note_attached[selindex] = i; + led->time_of_change[selindex] = Now; + } + qtyDiff[i]--; + } + } + + //Advance the LEDs to this position when outputting the values. + for( i = 0; i < led->total_leds; i++ ) + { + int ia = led->led_note_attached[i]; + if( ia == -1 ) + { + OutLEDs[i*3+0] = 0; + OutLEDs[i*3+1] = 0; + OutLEDs[i*3+2] = 0; + continue; + } + float sat = binvals[ia] * led->satamp; + float satQ = binvalsQ[ia] * led->satamp; + if( satQ > 1 ) satQ = 1; + float sendsat = (led->steady_bright?sat:satQ); + if( sendsat > 1 ) sendsat = 1; + int r = CCtoHEX( binpos[ia], 1.0, sendsat ); + + OutLEDs[i*3+0] = r & 0xff; + OutLEDs[i*3+1] = (r>>8) & 0xff; + OutLEDs[i*3+2] = (r>>16) & 0xff; + } + +} + +static void LEDParams(void * id ) +{ + struct CellsOutDriver * led = (struct CellsOutDriver*)id; + + led->satamp = 2; RegisterValue( "satamp", PAFLOAT, &led->satamp, sizeof( led->satamp ) ); + led->total_leds = 300; RegisterValue( "leds", PAINT, &led->total_leds, sizeof( led->total_leds ) ); + led->steady_bright = 1; RegisterValue( "seady_bright", PAINT, &led->steady_bright, sizeof( led->steady_bright ) ); + led->led_floor = .1; RegisterValue( "led_floor", PAFLOAT, &led->led_floor, sizeof( led->led_floor ) ); + led->light_siding = 1.9;RegisterValue( "light_siding", PAFLOAT, &led->light_siding, sizeof( led->light_siding ) ); + led->qtyamp = 20; RegisterValue( "qtyamp", PAFLOAT, &led->qtyamp, sizeof( led->qtyamp ) ); + led->timebased = 1; RegisterValue( "timebased", PAINT, &led->timebased, sizeof( led->timebased ) ); + + printf( "Found LEDs for output. leds=%d\n", led->total_leds ); + +} + + +static struct DriverInstances * OutputCells() +{ + int i; + struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) ); + memset( ret, 0, sizeof( struct DriverInstances ) ); + struct CellsOutDriver * led = ret->id = malloc( sizeof( struct CellsOutDriver ) ); + memset( led, 0, sizeof( struct CellsOutDriver ) ); + + for( i = 0; i < MAX_LEDS; i++ ) + { + led->led_note_attached[i] = -1; + } + ret->Func = LEDUpdate; + ret->Params = LEDParams; + LEDParams( led ); + return ret; + +} + +REGISTER_OUT_DRIVER(OutputCells); + + diff --git a/colorchord2/OutputLinear.c b/colorchord2/OutputLinear.c index d285090..bac98ae 100644 --- a/colorchord2/OutputLinear.c +++ b/colorchord2/OutputLinear.c @@ -25,6 +25,7 @@ struct LEDOutDriver float last_led_amp[MAX_LEDS]; int steady_bright; float led_floor; + float led_limit; //Maximum brightness float satamp; int lastadvance; }; @@ -174,6 +175,9 @@ static void LEDUpdate(void * id, struct NoteFinder*nf) led->last_led_amp[i] = sat; float sendsat = (led->steady_bright?sat:satQ); if( sendsat > 1 ) sendsat = 1; + + if( sendsat > led->led_limit ) sendsat = led->led_limit; + int r = CCtoHEX( led->last_led_pos[i], 1.0, sendsat ); OutLEDs[i*3+0] = r & 0xff; @@ -202,7 +206,7 @@ static void LEDParams(void * id ) led->light_siding = 1.4;RegisterValue( "light_siding", PAFLOAT, &led->light_siding, sizeof( led->light_siding ) ); led->is_loop = 0; RegisterValue( "is_loop", PAINT, &led->is_loop, sizeof( led->is_loop ) ); led->steady_bright = 1; RegisterValue( "steady_bright", PAINT, &led->steady_bright, sizeof( led->steady_bright ) ); - + led->led_limit = 1; RegisterValue( "led_limit", PAFLOAT, &led->led_limit, sizeof( led->led_limit ) ); printf( "Found LEDs for output. leds=%d\n", led->total_leds ); diff --git a/colorchord2/cells_output.conf b/colorchord2/cells_output.conf new file mode 100644 index 0000000..ca6c5d5 --- /dev/null +++ b/colorchord2/cells_output.conf @@ -0,0 +1,30 @@ +#for a two-ring WS2812 light, 24 LEDs per layer, one layer clockwise, the other counter-clockwise. + +outdrivers = DisplayPie,DisplayNetwork,OutputCells +leds = 48 +light_siding = 1.9 #Turn this to ~1.9 for more uniformity, ~1.0 for less. +satamp = 1.600 +is_loop=1 +led_floor = .0 #Turn to .25 for more uniformity, .1 for less. +steady_bright = 0 + +skipfirst = 3 +firstval = 0 +port = 7777 +#address = 192.168.11.231 +address = 192.168.43.128 + +slope=.10 +amplify=.4 + + +compress_coefficient = 4.0 +compress_exponent = .5 + +sourcename = alsa_output.pci-0000_00_1f.3.analog-stereo.monitor + +fliprg = 1 +skittlequantity = 24 +timebased = 1 + +qtyamp = 30 diff --git a/colorchord2/default.conf b/colorchord2/default.conf index 5516e68..725ce96 100644 --- a/colorchord2/default.conf +++ b/colorchord2/default.conf @@ -13,7 +13,7 @@ set_screenx = 720 set_screeny = 480 #Sound properties. -buffer = 128 +buffer = 384 play = 0 rec = 1 channels = 2 diff --git a/colorchord2/dmx.conf b/colorchord2/dmx.conf index 3fcdab9..8777102 100644 --- a/colorchord2/dmx.conf +++ b/colorchord2/dmx.conf @@ -9,9 +9,9 @@ recorder_bypass = 44100 byte_offset = 32 ledoutamp = 1.0 -leds = 4 -lightx = 2 -lighty = 2 +leds = 16 +lightx = 4 +lighty = 4 light_siding = 1.6 diff --git a/colorchord2/double_pie.conf b/colorchord2/double_pie.conf index 0aeefd4..ad9110e 100644 --- a/colorchord2/double_pie.conf +++ b/colorchord2/double_pie.conf @@ -15,13 +15,13 @@ port = 7777 address = 192.168.43.128 slope=.10 -amplify=.3 +amplify=.5 lightx = 20 lighty = 20 -sourcename = alsa_output.pci-0000_00_1f.3.analog-stereo.monitor +sourcename = #alsa_output.pci-0000_00_1f.3.analog-stereo.monitor fliprg = 1 skittlequantity = 24 diff --git a/colorchord2/main.c b/colorchord2/main.c index 1534635..fe42b98 100644 --- a/colorchord2/main.c +++ b/colorchord2/main.c @@ -95,15 +95,17 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun //Load the samples into a ring buffer. Split the channels from interleved to one per buffer. - int i; int j; for( i = 0; i < samplesr; i++ ) { - for( j = 0; j < channelin; j++ ) + if( out ) { - out[i*channelin+j] = 0; + for( j = 0; j < channelin; j++ ) + { + out[i*channelin+j] = 0; + } } if( sample_channel < 0 ) @@ -145,7 +147,10 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun } SoundEventHappened( samplesr, in, 0, channelin ); - SoundEventHappened( samplesr, out, 1, sd->channelsPlay ); + if( out ) + { + SoundEventHappened( samplesr, out, 1, sd->channelsPlay ); + } *samplesp = samplesr; } @@ -335,7 +340,7 @@ int main(int argc, char ** argv) //Once everything was reinitialized, re-read the ini files. SetEnvValues( 1 ); - +printf( "OK\n" ); Now = OGGetAbsoluteTime(); double Last = Now; while(1)