diff --git a/DFT32.h b/DFT32.h index 6bce18d..1b64482 100644 --- a/DFT32.h +++ b/DFT32.h @@ -32,7 +32,7 @@ //must decrease. Increasing this value makes responses slower. Lower values are //more responsive. #ifndef DFTIIR -#define DFTIIR 4 +#define DFTIIR 6 #endif //Everything the integer one buys, except it only calculates 2 octaves worth of notes per audio frame. diff --git a/embeddednf.c b/embeddednf.c index 3a3f9e1..095d5ca 100644 --- a/embeddednf.c +++ b/embeddednf.c @@ -101,6 +101,11 @@ void Init() void HandleFrameInfo() { int i, j, k; + uint8_t hitnotes[MAXNOTES]; + for( i = 0; i < MAXNOTES; i++ ) + { + hitnotes[i] = 0; + } #ifdef USE_32DFT uint16_t * strens; @@ -275,10 +280,11 @@ void HandleFrameInfo() if( marked_note != -1 ) { - if( note_peak_amps[marked_note] <= this ) - note_peak_amps[marked_note] = this; - if( note_peak_amps2[marked_note] <= this ) - note_peak_amps2[marked_note] = this; + hitnotes[marked_note] = 1; +// if( note_peak_amps[marked_note] <= this ) + note_peak_amps[marked_note] = note_peak_amps[marked_note] - (note_peak_amps[marked_note]>>AMP_1_NERFING_BITS) + (this>>AMP_1_NERFING_BITS); +// if( note_peak_amps2[marked_note] <= this ) + note_peak_amps2[marked_note] = note_peak_amps2[marked_note] - (note_peak_amps2[marked_note]>>AMP_2_NERFING_BITS) + (this>>AMP_2_NERFING_BITS); } } } @@ -327,7 +333,7 @@ void HandleFrameInfo() for( i = 0; i < MAXNOTES; i++ ) { - if( note_peak_freqs[i] == 255 ) continue; + if( note_peak_freqs[i] == 255 || hitnotes[i] ) continue; note_peak_amps[i] -= note_peak_amps[i]>>AMP_1_NERFING_BITS; note_peak_amps2[i] -= note_peak_amps2[i]>>AMP_2_NERFING_BITS; diff --git a/embeddednf.h b/embeddednf.h index c0566e7..6841ccb 100644 --- a/embeddednf.h +++ b/embeddednf.h @@ -17,7 +17,7 @@ //Notes are the individually identifiable notes we receive from the sound. //We track up to this many at one time. Just because a note may appear to //vaporize in one frame doesn't mean it is annihilated immediately. -#define MAXNOTES 10 +#define MAXNOTES 12 //Determines bit shifts for where notes lie. We represent notes with an uint8_t //We have to define all of the possible locations on the note line in this. @@ -25,19 +25,22 @@ #define SEMIBITSPERBIN 3 #define NOTERANGE ((1<> 8; + porpamps[i] = (local_peak_amps[i] * porportional) >> 8; total_accounted_leds += porpamps[i]; } - uint16_t total_unaccounted_leds = NUM_LIN_LEDS - total_accounted_leds; + int16_t total_unaccounted_leds = NUM_LIN_LEDS - total_accounted_leds; - for( i = 0; i < MAXNOTES, total_unaccounted_leds; i++ ) + for( i = 0; i < MAXNOTES && total_unaccounted_leds; i++ ) { if( note_peak_freqs[i] == 255 ) continue; - porpamps[i]++; + porpamps[i]++; total_unaccounted_leds--; } //Now, we use porpamps to march through the LEDs, coloring them. j = 0; for( i = 0; i < MAXNOTES; i++ ) { - while( porpamps[i] ) + while( porpamps[i] > 0 ) { - uint16_t amp = note_peak_amps2[i]; + uint16_t amp = ((uint32_t)note_peak_amps2[i] * NOTE_FINAL_AMP) >> 8; if( amp > 255 ) amp = 255; uint32_t color = ECCtoHEX( note_peak_freqs[i], 255, amp ); - ledOut[i*3+0] = ( color >> 0 ) & 0xff; - ledOut[i*3+1] = ( color >> 8 ) & 0xff; - ledOut[i*3+2] = ( color >>16 ) & 0xff; + ledOut[j*3+0] = ( color >> 0 ) & 0xff; + ledOut[j*3+1] = ( color >> 8 ) & 0xff; + ledOut[j*3+2] = ( color >>16 ) & 0xff; + j++; porpamps[i]--; } @@ -69,43 +108,46 @@ void UpdateLinear() uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val ) { uint16_t hue = 0; - uint8_t third = 65535/3; - uint16_t scalednote = note - uint16_t renote = ((uint32_t)note * 65535) / NOTERANGE; + uint16_t third = 65535/3; + uint16_t scalednote = note; + uint32_t renote = ((uint32_t)note * 65536) / NOTERANGE; //Note is expected to be a vale from 0..(NOTERANGE-1) //renote goes from 0 to the next one under 65536. + if( renote < third ) { //Yellow to Red. hue = (third - renote) >> 1; } - else if( note < (third>>1) ) + else if( renote < (third<<1) ) { //Red to Blue hue = (third-renote); } else { - hue = (((65535-renote) * third) >> 1) + (third>>1); + //hue = ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1); + hue = (uint16_t)(((uint32_t)(65536-renote)<<16) / (third<<1)) + (third>>1); // ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1); } - hue >>= 8; +// printf( "%d;", hue ); + return EHSVtoHEX( hue, sat, val ); } uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ) { -#define SIXTH1 43 -#define SIXTH2 85 -#define SIXTH3 128 -#define SIXTH4 171 -#define SIXTH5 213 + #define SIXTH1 43 + #define SIXTH2 85 + #define SIXTH3 128 + #define SIXTH4 171 + #define SIXTH5 213 uint16_t or = 0, og = 0, ob = 0; - hue += SIXTH2; //Off by 60 degrees. + hue -= SIXTH1; //Off by 60 degrees. //TODO: There are colors that overlap here, consider //tweaking this to make the best use of the colorspace. @@ -155,15 +197,17 @@ uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ) //OR..OB == 0..65025 or = or * rs + 255 * (256-rs); - or = or * rs + 255 * (256-rs); - or = or * rs + 255 * (256-rs); + og = og * rs + 255 * (256-rs); + ob = ob * rs + 255 * (256-rs); +//printf( "__%d %d %d =-> %d\n", or, og, ob, rs ); or >>= 8; og >>= 8; ob >>= 8; - return or | (og<<8) | (ob<<16); -} + return or | (og<<8) | ((uint32_t)ob<<16); +} +/* uint32_t HSVtoHEX( float hue, float sat, float value ) { @@ -233,4 +277,4 @@ uint32_t HSVtoHEX( float hue, float sat, float value ) return (ob<<16) | (og<<8) | ora; } - +*/ diff --git a/embeddedout.h b/embeddedout.h index 54d1050..7d52369 100644 --- a/embeddedout.h +++ b/embeddedout.h @@ -3,13 +3,20 @@ #include "embeddednf.h" + +//Controls brightness +#define NOTE_FINAL_AMP 255 //Number from 0...255 + +//Controls, basically, the minimum size of the splotches. +#define NERF_NOTE_SIZE_VALUE 10 + #define NUM_LIN_LEDS 296 #define LIN_WRAPAROUND 0 //Whether the output lights wrap around. (TODO) extern uint8_t ledArray[]; extern uint8_t ledOut[]; //[NUM_LIN_LEDS*3] -void UpdateLinear(); +void UpdateLinearLEDs(); uint32_t ECCtoHEX( uint8_t note, uint8_t sat, uint8_t val ); uint32_t EHSVtoHEX( uint8_t hue, uint8_t sat, uint8_t val ); //hue = 0..255 // TODO: TEST ME!!! diff --git a/embeddedx86/Makefile b/embeddedx86/Makefile index af6483a..80ba9c9 100644 --- a/embeddedx86/Makefile +++ b/embeddedx86/Makefile @@ -3,11 +3,11 @@ all : embeddedcc CFLAGS:=-Ofast -DCCEMBEDDED -I.. -flto -m32 -DDFREQ=11025 LDFLAGS:=-ffunction-sections -Wl,--gc-sections -fno-asynchronous-unwind-tables -Wl,--strip-all -embeddedcc : ../embeddednf.c ../DFT32.c embeddedcc.c +embeddedcc : ../embeddednf.c ../DFT32.c embeddedcc.c ../embeddedout.c gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) runembedded : embeddedcc - parec --format=u8 --rate=11025 --channels=1 --device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor | ./embeddedcc + parec --format=u8 --rate=11025 --channels=1 --device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor --latency=128 | ./embeddedcc clean : rm -rf embeddedcc *~ diff --git a/embeddedx86/embeddedcc.c b/embeddedx86/embeddedcc.c index 127d68f..b393f30 100644 --- a/embeddedx86/embeddedcc.c +++ b/embeddedx86/embeddedcc.c @@ -3,14 +3,57 @@ // It is intended as a minimal scaffolding for testing Embedded ColorChord. // -#include + #include "embeddednf.h" +#include +#include +#include +#include +#include "embeddedout.h" + +struct sockaddr_in servaddr; +int sock; + +#define expected_lights 296 + +void NewFrame() +{ + int i; + char buffer[3000]; + + HandleFrameInfo(); + UpdateLinearLEDs(); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + + for( i = 0; i < expected_lights * 3; i++ ) + { + buffer[i+3] = ledOut[i]; + } + + int r = send(sock,buffer,expected_lights*3+3,0); +} + int main() { int wf = 0; int ci; + + sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); + printf( "%d\n", sock ); + + memset(&servaddr,0,sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("192.168.0.245"); + servaddr.sin_port=htons(7777); + + connect( sock, (struct sockaddr *)&servaddr, sizeof(servaddr) ); + Init(); + while( ( ci = getchar() ) != EOF ) { int cs = ci - 0x80; @@ -19,11 +62,10 @@ int main() #else Push8BitIntegerSkippy( (int8_t)cs ); #endif - //printf( "%d ", cs ); fflush( stdout ); wf++; if( wf == 64 ) { - HandleFrameInfo(); + NewFrame(); wf = 0; } }