diff --git a/colorchord.exe b/colorchord.exe index 7e2638d..5c013e7 100755 Binary files a/colorchord.exe and b/colorchord.exe differ diff --git a/default.conf b/default.conf index dc09757..f96c54e 100644 --- a/default.conf +++ b/default.conf @@ -24,8 +24,7 @@ wininput = 0 #sound_source = PULSE #-1 indicates left and right, 0 left, 1 right. sample_channel = -1 -sourcename = - alsa_output.pci-0000_00_1b.0.analog-stereo.monitor +sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor ################################## # General ColorChord properties. # @@ -55,9 +54,9 @@ filter_strength = .5 freqbins = 24 # For the final note information... How much to slack everything? -note_attach_amp_iir = 0.3000 -note_attach_amp_iir2 = 0.200 -note_attach_freq_iir = 0.4000 +note_attach_amp_iir = 0.2000 +note_attach_amp_iir2 = 0.150 +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. diff --git a/dft.c b/dft.c index 8543846..c40ae19 100644 --- a/dft.c +++ b/dft.c @@ -192,8 +192,6 @@ void DoDFTProgressive( float * outbins, float * frequencies, int bins, const flo -#define PROGIIR .005 - //NOTES to self: // // Let's say we want to try this on an AVR. @@ -208,71 +206,70 @@ static int8_t sintable[512]; //Actually [sin][cos] pairs. //LDD instruction on AVR can read with constant offset. We can set Y to be the place in the buffer, and read with offset. static uint16_t * datspace; //(advances,places,isses,icses) -// void HandleProgressiveInt( int8_t sample1, int8_t sample2 ) { int i; - uint16_t startpl = 0; int16_t ts, tc; int16_t tmp1; int8_t s1, c1; uint16_t ipl, localipl, adv; + uint16_t * ds = &datspace[0]; + int8_t * st; + //Clocks are listed for AVR. - //startpl maps to 'Y' - // - - - //Estimated 68 minimum instructions... So for two pairs each... just under 5ksps, theoretical. - //Running overall at ~2kHz. - for( i = 0; i < gbins; i++ ) //Loop, fixed size = 3 + 2 cycles 5 + //Estimated 78 minimum instructions... So for two pairs each... just over 4ksps, theoretical. + //Running overall at ~2kHz. With GCC: YUCK! 102 cycles!!! + for( i = 0; i < gbins; i++ ) //Loop, fixed size = 3 + 2 cycles N/A { //12 cycles MIN - adv = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4 - ipl = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4 + adv = *(ds++); //Read, indirect from RAM (and increment) 2+2 cycles 4 + ipl = *(ds++); //Read, indirect from RAM (and increment) 2+2 cycles 4 //13 cycles MIN ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2 - localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1 + localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1 *** AS/IS: 4 - // need to load Z with 'sintable' and add localipl 2 - s1 = sintable[localipl++]; //Read s1 component out of table. 2+2 cycles 2 - c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2 + st = &sintable[localipl]; + s1 = *(st++); //Read s1 component out of table. 2+2 cycles 2 + c1 = *st; //Read c1 component out of table. 2 cycles 2 *** AS/IS: 4 - ts = (s1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB ts 2 - tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2 + ts = (s1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB ts 2 ->Deferred + tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2 ->Deferred //15 cycles MIN ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2 - localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1 + localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1 *** AS/IS: 4 // need to load Z with 'sintable' and add localipl 2 - s1 = sintable[localipl++]; //Read s1 component out of table. 2 cycles 2 - c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2 + st = &sintable[localipl]; + s1 = *(st++); //Read s1 component out of table. 2 cycles 2 + c1 = *st; //Read c1 component out of table. 2 cycles 2 *** AS/IS: 4 - ts += (s1 * sample2); // 8 x 8 multiply signed + add R1 out. 3 - tc += (c1 * sample2); // 8 x 8 multiply signed + add R1 out. 3 + ts += (s1 * sample2); // 8 x 8 multiply signed + add R1 out. 3 ->Deferred + tc += (c1 * sample2); // 8 x 8 multiply signed + add R1 out. 3 ->Deferred //Add TS and TC to the datspace stuff. (24 instructions) - tmp1 = datspace[startpl]; //Read out, sin component. 4 - tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2 - tmp1 += ts>>6; //Add MSBs with carry 2 + tmp1 = (*ds); //Read out, sin component. 4 Accurate. + tmp1 -= tmp1>>7; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14 + tmp1 += ts>>7; //Add MSBs with carry 2 -> 6 AS/IS: 6 - datspace[startpl++] = tmp1; //Store values back 4 + *(ds++) = tmp1; //Store values back 4 - tmp1 = datspace[startpl]; //Read out, sin component. 4 - tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2 - tmp1 += tc>>6; //Add MSBs with carry 2 + tmp1 = *ds; //Read out, sin component. 4 + tmp1 -= tmp1>>7; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14 + tmp1 += tc>>7; //Add MSBs with carry 2 -> 6 AS/IS: 6 - datspace[startpl++] = tmp1; //Store values back 4 + *ds++ = tmp1; //Store values back 4 - datspace[startpl-3] = ipl; //Store values back 4 + *(ds-3) = ipl; //Store values back 4 AS/IS: 6 + + //AS-IS: 8 loop overhead. } } - void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ) { int i; @@ -326,3 +323,220 @@ void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, co } + + + + + + + + + + + + +////////////////////////SKIPPY DFT + +//Skippy DFT is a very ood one. + + + +#define OCTAVES 5 +#define FIXBPERO 24 +#define FIXBINS (FIXBPERO*OCTAVES) +#define BINCYCLE (1< 128 ) + { + //Special: This is when we can update everything. + +/* if( (rand()%100) == 0 ) + { + for( i = 0; i < FIXBINS; i++ ) +// printf( "%0.2f ",goutbins[i]*100 ); + printf( "(%d %d)",Sdatspace[i*4+2], Sdatspace[i*4+3] ); + printf( "\n" ); + } */ + + for( i = 0; i < FIXBINS; i++ ) + { + int16_t isps = Sdatspace[i*4+2]; + int16_t ispc = Sdatspace[i*4+3]; + int16_t mux = ( (isps/256) * (isps/256)) + ((ispc/256) * (ispc/256)); + // printf( "%d (%d %d)\n", mux, isps, ispc ); + + int octave = i / FIXBPERO; +// mux >>= octave; + goutbins[i] = sqrt( mux ); +// goutbins[i]/=100.0; + goutbins[i]/=100*(1<>5; + Sdatspace[i*4+3] -= ispc>>5; + } + + } + + for( i = 0; i < OCTAVES;i++ ) + { + Saccum_octavebins[i] += sample1; + } + + uint16_t * ds = &Sdatspace[oct*FIXBPERO*4]; + int8_t * st; + + sample1 = Saccum_octavebins[oct]>>(OCTAVES-oct); + Saccum_octavebins[oct] = 0; + + for( i = 0; i < FIXBPERO; i++ ) //Loop, fixed size = 3 + 2 cycles N/A + { + //12 cycles MIN + adv = *(ds++); //Read, indirect from RAM (and increment) 2+2 cycles 4 + ipl = *(ds++); //Read, indirect from RAM (and increment) 2+2 cycles 4 + + //13 cycles MIN + ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2 + localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1 *** AS/IS: 4 + + st = &Ssintable[localipl]; + s1 = *(st++); //Read s1 component out of table. 2+2 cycles 2 + c1 = *st; //Read c1 component out of table. 2 cycles 2 *** AS/IS: 4 + + ts = (s1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB ts 2 ->Deferred + tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2 ->Deferred + + + //Add TS and TC to the datspace stuff. (24 instructions) + tmp1 = (*ds); //Read out, sin component. 4 Accurate. +// tmp1 -= tmp1>>4; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14 + tmp1 += ts>>3; //Add MSBs with carry 2 -> 6 AS/IS: 6 + + *(ds++) = tmp1; //Store values back 4 + + tmp1 = *ds; //Read out, sin component. 4 +// tmp1 -= tmp1>>4; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14 + tmp1 += tc>>3; //Add MSBs with carry 2 -> 6 AS/IS: 6 + + *ds++ = tmp1; //Store values back 4 + + *(ds-3) = ipl; //Store values back 4 AS/IS: 6 + + //AS-IS: 8 loop overhead. + } +} + +void DoDFTProgressiveIntegerSkippy( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ) +{ + static float backupbins[FIXBINS]; + int i, j; + static int last_place; + +//printf( "SKIPPY\n" ); + + if( !Sdonefirstrun ) + { + memset( outbins, 0, bins * sizeof( float ) ); + goutbins = outbins; + //Sdatspace = malloc(FIXBPERO*OCTAVES*8); + //memset(Sdatspace,0,FIXBPERO*OCTAVES*8); + //printf( "MS: %d\n", FIXBPERO*OCTAVES*8); + Sdonefirstrun = 1; + for( i = 0; i < 256; i++ ) + { + Ssintable[i*2+0] = (int8_t)((sinf( i / 256.0 * 6.283 ) * 127.0)); + Ssintable[i*2+1] = (int8_t)((cosf( i / 256.0 * 6.283 ) * 127.0)); + } + + for( i = 0; i < BINCYCLE; i++ ) + { + // Sdo_this_octave = + // 4 3 4 2 4 3 4 ... + //search for "first" zero + + for( j = 0; j <= OCTAVES; j++ ) + { + if( ((1< OCTAVES ) + { + fprintf( stderr, "Error: algorithm fault.\n" ); + exit( -1 ); + } + Sdo_this_octave[i] = OCTAVES-j-1; + } + } + + memcpy( outbins, backupbins, FIXBINS*4 ); + + if( FIXBINS != bins ) + { + fprintf( stderr, "Error: Bins was reconfigured. skippy requires a constant number of bins.\n" ); + return; + } + + + for( i = 0; i < bins; i++ ) + { + float freq = frequencies[(i%FIXBPERO) + (FIXBPERO*(OCTAVES-1))]; + Sdatspace[i*4] = (65536.0/freq);// / oneoveroctave; + } + + + for( i = last_place; i != place_in_data_buffer; i = (i+1)%size_of_data_buffer ) + { + int8_t ifr1 = (int8_t)( ((databuffer[i]) ) * 127 ); + HandleProgressiveIntSkippy( ifr1 ); + HandleProgressiveIntSkippy( ifr1 ); + } + + last_place = place_in_data_buffer; + + memcpy( backupbins, outbins, FIXBINS*4 ); + + //Extract bins. +/* + for( i = 0; i < bins; i++ ) + { + int16_t isps = Sdatspace[i*4+2]; + int16_t ispc = Sdatspace[i*4+3]; + int16_t mux = ( (isps/256) * (isps/256)) + ((ispc/256) * (ispc/256)); +// printf( "%d (%d %d)\n", mux, isps, ispc ); + outbins[i] = sqrt( mux )/100.0; + } +*/ + +// printf( "\n"); +} + + + + + + diff --git a/dft.h b/dft.h index bae53b5..944b949 100644 --- a/dft.h +++ b/dft.h @@ -1,14 +1,16 @@ #ifndef _DFT_H #define _DFT_H -//XXX WARNING: TODO: the last two parameters are a double due to a compiler bug. + +//There are several options here, the last few are selectable by modifying the do_progressive_dft flag. + //Do a DFT on a live audio ring buffer. It assumes new samples are added on in the + direction, older samples go negative. //Frequencies are as a function of the samplerate, for example, a frequency of 22050 is actually 2 Hz @ 44100 SPS //bins = number of frequencies to check against. void DoDFT( float * outbins, float * frequencies, int bins, float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q ); -//Skip many of the samples on lower frequencies; TODO: Need to fix the nyquist problem where high frequencies show low-frequency components. +//Skip many of the samples on lower frequencies. //Speedup = target number of data points void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ); @@ -16,8 +18,14 @@ void DoDFTQuick( float * outbins, float * frequencies, int bins, const float * d void DoDFTProgressive( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ); //A progressive DFT that's done using only low-bit integer math. +//This is almost fast enough to work on an AVR, with two AVRs, it's likely that it could be powerful enough. +//This is fast enough to run on an ESP8266 void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ); +//Everything the integer one buys, except it only calculates 2 octaves worth of notes per audio frame. +//This is sort of working, but still have some quality issues. +//It would theoretically be fast enough to work on an AVR. +void DoDFTProgressiveIntegerSkippy( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup ); #endif diff --git a/integerprog.conf b/integerprog.conf index d321461..62f5ad6 100644 --- a/integerprog.conf +++ b/integerprog.conf @@ -1,5 +1,5 @@ -do_progressive_dft = 1 +do_progressive_dft = 3 samplerate = 8000 -buffer = 128 - +buffer = 64 +sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor diff --git a/main.c b/main.c index be4cd84..3664a82 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,8 @@ #include "outdrivers.h" #include "parameters.h" +#define NRDEFFILES 10 + struct SoundDriver * sd; #ifdef WIN32 @@ -32,6 +34,7 @@ char ** gargv; struct DriverInstances * outdriver[MAX_OUT_DRIVERS]; +int headless = 0; REGISTER_PARAM( headless, PAINT ); int set_screenx = 640; REGISTER_PARAM( set_screenx, PAINT ); int set_screeny = 480; REGISTER_PARAM( set_screeny, PAINT ); char sound_source[16]; REGISTER_PARAM( sound_source, PABUFFER ); @@ -95,9 +98,12 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun for( j = 0; j < channelin; j++ ) { float f = in[i*channelin+j]; - if( f < -1 || f > 1 ) continue; - fo += f; + if( f > -1 && f < 1 ) + { + fo += f; + } } + fo /= channelin; sound[soundhead] = fo; soundhead = (soundhead+1)%SOUNDCBSIZE; @@ -106,9 +112,11 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun else { float f = in[i*channelin+sample_channel]; - if( f < -1 || f > 1 ) continue; - sound[soundhead] = f; - soundhead = (soundhead+1)%SOUNDCBSIZE; + if( f > -1 && f < 1 ) + { + sound[soundhead] = f; + soundhead = (soundhead+1)%SOUNDCBSIZE; + } } } } @@ -118,7 +126,6 @@ void LoadFile( const char * filename ) { char * buffer; int r; - int i; FILE * f = fopen( filename, "rb" ); if( !f ) @@ -144,26 +151,69 @@ void LoadFile( const char * filename ) } free( buffer ); } +} - if( gargc > 2 ) +const char * InitialFile[NRDEFFILES]; +double FileTimes[NRDEFFILES]; +int InitialFileCount = 1; + +void SetEnvValues() +{ + int i; + int hits = 0; + for( i = 0; i < InitialFileCount; i++ ) { - for( i = 2; i < gargc; i++ ) + double ft = OGGetFileTime( InitialFile[i] ); + if( FileTimes[i] != ft ) + { + FileTimes[i] = ft; + hits++; + } + } + + if( !hits ) return; + + //Otherwise, something changed. + + LoadFile( InitialFile[0] ); + + for( i = 1; i < gargc; i++ ) + { + if( strchr( gargv[i], '=' ) != 0 ) { printf( "AP: %s\n", gargv[i] ); SetParametersFromString( gargv[i] ); } + else + { + printf( "LF: %s\n", gargv[i] ); + LoadFile( gargv[i] ); + } } } +void ProcessArgs() +{ + int i; + for( i = 1; i < gargc; i++ ) + { + if( strchr( gargv[i], '=' ) != 0 ) + { + //A value setting operation + } + else + { + InitialFile[InitialFileCount++] = gargv[i]; + } + } + + SetEnvValues(); +} + int main(int argc, char ** argv) { -// const char * OutDriver = "name=LEDOutDriver;leds=512;light_siding=1.9"; - const char * InitialFile = 0; - const char * InitialFileDefault = "default.conf"; int i; - double LastFileTimeInit = 0; - double LastFileTimeDefault = 0; #ifdef WIN32 WSADATA wsaData; @@ -178,23 +228,9 @@ int main(int argc, char ** argv) gargc = argc; gargv = argv; - if( argc > 1 ) - { - InitialFile = argv[1]; - } - - - { - LastFileTimeDefault = OGGetFileTime( InitialFileDefault ); - LoadFile( InitialFileDefault ); - } - - if( InitialFile ) - { - LastFileTimeInit = OGGetFileTime( InitialFile ); - LoadFile( InitialFile ); - } + InitialFile[0] = "default.conf"; + ProcessArgs(); //Initialize Rawdraw int frames = 0; @@ -219,7 +255,8 @@ int main(int argc, char ** argv) tp++; } *tp = 0; - CNFGSetup( title, set_screenx, set_screeny ); + if( !headless ) + CNFGSetup( title, set_screenx, set_screeny ); char * OutDriverNames = strdup( GetParameterS( "outdrivers", "null" ) ); @@ -266,10 +303,14 @@ int main(int argc, char ** argv) { char stt[1024]; //Handle Rawdraw frame swappign - CNFGHandleInput(); - CNFGClearFrame(); - CNFGColor( 0xFFFFFF ); - CNFGGetDimensions( &screenx, &screeny ); + + if( !headless ) + { + CNFGHandleInput(); + CNFGClearFrame(); + CNFGColor( 0xFFFFFF ); + CNFGGetDimensions( &screenx, &screeny ); + } RunNoteFinder( nf, sound, (soundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE, SOUNDCBSIZE ); //Done all ColorChord work. @@ -281,123 +322,127 @@ int main(int argc, char ** argv) VisTimeEnd = OGGetAbsoluteTime(); - //Handle outputs. - int freqbins = nf->freqbins; - int note_peaks = freqbins/2; - int freqs = freqbins * nf->octaves; - //int maxdists = freqbins/2; - - //Do a bunch of debugging. - if( show_debug_basic ) + if( !headless ) { - for( i = 0; i < nf->dists; i++ ) + //Handle outputs. + int freqbins = nf->freqbins; + int note_peaks = freqbins/2; + int freqs = freqbins * nf->octaves; + //int maxdists = freqbins/2; + + //Do a bunch of debugging. + if( show_debug_basic ) { - CNFGPenX = (nf->dist_means[i] + 0.5) / freqbins * screenx; //Move over 0.5 for visual purposes. The means is correct. - CNFGPenY = 400-nf->dist_amps[i] * 150.0 / nf->dist_sigmas[i]; - //printf( "%f %f\n", dist_means[i], dist_amps[i] ); - sprintf( stt, "%f\n%f\n", nf->dist_means[i], nf->dist_amps[i] ); - CNFGDrawText( stt, 2 ); + for( i = 0; i < nf->dists; i++ ) + { + CNFGPenX = (nf->dist_means[i] + 0.5) / freqbins * screenx; //Move over 0.5 for visual purposes. The means is correct. + CNFGPenY = 400-nf->dist_amps[i] * 150.0 / nf->dist_sigmas[i]; + //printf( "%f %f\n", dist_means[i], dist_amps[i] ); + sprintf( stt, "%f\n%f\n", nf->dist_means[i], nf->dist_amps[i] ); + CNFGDrawText( stt, 2 ); + } + CNFGColor( 0xffffff ); + + //Draw the folded bins + for( i = 0; i < freqbins; i++ ) + { + float x0 = i / (float)freqbins * (float)screenx; + float x1 = (i+1) / (float)freqbins * (float)screenx; + float amp = nf->folded_bins[i] * 250.0; + CNFGDialogColor = CCtoHEX( ((float)(i+0.5) / freqbins), 1.0, 1.0 ); + CNFGDrawBox( x0, 400-amp, x1, 400 ); + } + CNFGDialogColor = 0xf0f000; + + for( i = 0; i < note_peaks; i++ ) + { + //printf( "%f %f /", note_positions[i], note_amplitudes[i] ); + if( nf->note_amplitudes_out[i] < 0 ) continue; + CNFGDialogColor = CCtoHEX( (nf->note_positions[i] / freqbins), 1.0, 1.0 ); + CNFGDrawBox( ((float)i / note_peaks) * screenx, 480 - nf->note_amplitudes_out[i] * 100, ((float)(i+1) / note_peaks) * screenx, 480 ); + CNFGPenX = ((float)(i+.4) / note_peaks) * screenx; + CNFGPenY = screeny - 30; + sprintf( stt, "%d\n%0.0f", nf->enduring_note_id[i], nf->note_amplitudes2[i]*1000.0 ); + CNFGDrawText( stt, 2 ); + + } + + //Let's draw the o-scope. + int thissoundhead = soundhead; + thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; + int lasty = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; + int thisy = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; + for( i = 0; i < screenx; i++ ) + { + CNFGTackSegment( i, lasty, i+1, thisy ); + lasty = thisy; + thisy = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; + } } + + //Extra debugging? + if( show_debug ) + { + //Draw the histogram + float lasthistval; + CNFGColor( 0xffffff ); + + for( i = -1; i < screenx; i++ ) + { + float thishistval = CalcHistAt( (float)i/(float)screenx*freqbins-0.5, nf->freqbins, nf->dist_means, nf->dist_amps, nf->dist_sigmas, nf->dists ); + if( i >= 0 ) + CNFGTackSegment( i, 400-lasthistval * 250.0, i+1, 400-thishistval * 250.0 ); + lasthistval = thishistval; + } + + CNFGColor( 0xffffff ); + + //Draw the bins + for( i = 0; i < freqs; i++ ) + { + float x0 = i / (float)freqs * (float)screenx; + float x1 = (i+1) / (float)freqs * (float)screenx; + float amp = nf->outbins[i] * 250.0; + CNFGDialogColor = CCtoHEX( ((float)i / freqbins), 1.0, 1.0 ); + CNFGDrawBox( x0, 0, x1, amp ); + } + CNFGDialogColor = 0x0f0f0f; + + char stdebug[1024]; + sprintf( stdebug, "DFT:%8.2fms\nFLT:%8.2f\nDEC:%8.2f\nFNL:%8.2f\nDPY:%8.2f", + (nf->DFTTime - nf->StartTime)*1000, + (nf->FilterTime - nf->DFTTime)*1000, + (nf->DecomposeTime - nf->FilterTime)*1000, + (nf->FinalizeTime - nf->DecomposeTime)*1000, + (VisTimeEnd - VisTimeStart)*1000 ); + CNFGPenX = 50; + CNFGPenY = 50; + CNFGDrawText( stdebug, 2 ); + } + + CNFGColor( show_debug?0xffffff:0x000000 ); + CNFGPenX = 0; CNFGPenY = screeny-10; + CNFGDrawText( "Extra Debug (D)", 2 ); + + CNFGColor( show_debug_basic?0xffffff:0x000000 ); + CNFGPenX = 120; CNFGPenY = screeny-10; + CNFGDrawText( "Basic Debug (E)", 2 ); + + CNFGColor( show_debug_basic?0xffffff:0x000000 ); + CNFGPenX = 240; CNFGPenY = screeny-10; + sprintf( stt, "[9] Key: %d [0] (%3.1f) [-]", gKey, nf->base_hz ); + CNFGDrawText( stt, 2 ); + CNFGColor( 0xffffff ); - - //Draw the folded bins - for( i = 0; i < freqbins; i++ ) - { - float x0 = i / (float)freqbins * (float)screenx; - float x1 = (i+1) / (float)freqbins * (float)screenx; - float amp = nf->folded_bins[i] * 250.0; - CNFGDialogColor = CCtoHEX( ((float)(i+0.5) / freqbins), 1.0, 1.0 ); - CNFGDrawBox( x0, 400-amp, x1, 400 ); - } - CNFGDialogColor = 0xf0f000; - - for( i = 0; i < note_peaks; i++ ) - { - //printf( "%f %f /", note_positions[i], note_amplitudes[i] ); - if( nf->note_amplitudes_out[i] < 0 ) continue; - CNFGDialogColor = CCtoHEX( (nf->note_positions[i] / freqbins), 1.0, 1.0 ); - CNFGDrawBox( ((float)i / note_peaks) * screenx, 480 - nf->note_amplitudes_out[i] * 100, ((float)(i+1) / note_peaks) * screenx, 480 ); - CNFGPenX = ((float)(i+.4) / note_peaks) * screenx; - CNFGPenY = screeny - 30; - sprintf( stt, "%d\n%0.0f", nf->enduring_note_id[i], nf->note_amplitudes2[i]*1000.0 ); - CNFGDrawText( stt, 2 ); - - } - - //Let's draw the o-scope. - int thissoundhead = soundhead; - thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; - int lasty = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; - int thisy = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; - for( i = 0; i < screenx; i++ ) - { - CNFGTackSegment( i, lasty, i+1, thisy ); - lasty = thisy; - thisy = sound[thissoundhead] * 128 + 128; thissoundhead = (thissoundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE; - } + CNFGPenX = 440; CNFGPenY = screeny-10; + sprintf( stt, "FPS: %d", lastfps ); + CNFGDrawText( stt, 2 ); + CNFGSwapBuffers(); } - //Extra debugging? - if( show_debug ) - { - //Draw the histogram - float lasthistval; - CNFGColor( 0xffffff ); - - for( i = -1; i < screenx; i++ ) - { - float thishistval = CalcHistAt( (float)i/(float)screenx*freqbins-0.5, nf->freqbins, nf->dist_means, nf->dist_amps, nf->dist_sigmas, nf->dists ); - if( i >= 0 ) - CNFGTackSegment( i, 400-lasthistval * 250.0, i+1, 400-thishistval * 250.0 ); - lasthistval = thishistval; - } - - CNFGColor( 0xffffff ); - - //Draw the bins - for( i = 0; i < freqs; i++ ) - { - float x0 = i / (float)freqs * (float)screenx; - float x1 = (i+1) / (float)freqs * (float)screenx; - float amp = nf->outbins[i] * 250.0; - CNFGDialogColor = CCtoHEX( ((float)i / freqbins), 1.0, 1.0 ); - CNFGDrawBox( x0, 0, x1, amp ); - } - CNFGDialogColor = 0x0f0f0f; - - char stdebug[1024]; - sprintf( stdebug, "DFT:%8.2fms\nFLT:%8.2f\nDEC:%8.2f\nFNL:%8.2f\nDPY:%8.2f", - (nf->DFTTime - nf->StartTime)*1000, - (nf->FilterTime - nf->DFTTime)*1000, - (nf->DecomposeTime - nf->FilterTime)*1000, - (nf->FinalizeTime - nf->DecomposeTime)*1000, - (VisTimeEnd - VisTimeStart)*1000 ); - CNFGPenX = 50; - CNFGPenY = 50; - CNFGDrawText( stdebug, 2 ); - } - - CNFGColor( show_debug?0xffffff:0x000000 ); - CNFGPenX = 0; CNFGPenY = screeny-10; - CNFGDrawText( "Extra Debug (D)", 2 ); - - CNFGColor( show_debug_basic?0xffffff:0x000000 ); - CNFGPenX = 120; CNFGPenY = screeny-10; - CNFGDrawText( "Basic Debug (E)", 2 ); - - CNFGColor( show_debug_basic?0xffffff:0x000000 ); - CNFGPenX = 240; CNFGPenY = screeny-10; - sprintf( stt, "[9] Key: %d [0] (%3.1f) [-]", gKey, nf->base_hz ); - CNFGDrawText( stt, 2 ); - - CNFGColor( 0xffffff ); - CNFGPenX = 440; CNFGPenY = screeny-10; - sprintf( stt, "FPS: %d", lastfps ); - CNFGDrawText( stt, 2 ); - //Finish Rawdraw with FPS counter, and a nice delay loop. frames++; - CNFGSwapBuffers(); + ThisTime = OGGetAbsoluteTime(); if( ThisTime > LastFPSTime + 1 ) { @@ -416,18 +461,7 @@ int main(int argc, char ** argv) OGUSleep( (int)( SecToWait * 1000000 ) ); } - if( OGGetFileTime( InitialFileDefault ) != LastFileTimeDefault || - (InitialFile && LastFileTimeInit != OGGetFileTime( InitialFile ) ) ) - { - LastFileTimeDefault = OGGetFileTime( InitialFileDefault ); - LoadFile( InitialFileDefault ); - - if( InitialFile ) - { - LastFileTimeInit = OGGetFileTime( InitialFile ); - LoadFile( InitialFile ); - } - } + SetEnvValues(); } diff --git a/netlight.conf b/netlight.conf index dd2a2e2..13ee3b5 100644 --- a/netlight.conf +++ b/netlight.conf @@ -1,12 +1,12 @@ -outdrivers = DisplayNetwork, OutputLinear +outdrivers = DisplayPie,DisplayNetwork, OutputLinear leds = 296 light_siding = 1.0 #Turn this to ~1.9 for more uniformity, ~1.0 for less. satamp = 1.600 is_loop=0 led_floor = .1 #Turn to .25 for more uniformity, .1 for less. -note_attach_amp_iir = .3000 -note_attach_amp_iir2 = .1500 -note_attach_freq_iir = 0.3000 +#note_attach_amp_iir = .3 #.3000 +#note_attach_amp_iir2 = .15 #.1500 +#note_attach_freq_iir = .3 #0.3000 steady_bright = 0 #dft_iir = 0.0 #dft_q = 20.0000 @@ -17,3 +17,10 @@ firstval = 0 port = 7777 address = 192.168.0.245 +slope=.10 +amplify=.3 + + +lightx = 20 +lighty = 20 + diff --git a/notefinder.c b/notefinder.c index 11078c8..3322929 100644 --- a/notefinder.c +++ b/notefinder.c @@ -25,6 +25,7 @@ struct NoteFinder * CreateNoteFinder( int spsRec ) ret->decompose_iterations = 1000; ret->dft_speedup = 300; ret->dft_q = 16; + ret->slope = 0.0; ret->do_progressive_dft = 0; ret->default_sigma = 1.4; ret->note_jumpability = 2.5; @@ -53,6 +54,7 @@ struct NoteFinder * CreateNoteFinder( int spsRec ) RegisterValue( "default_sigma", PAFLOAT, &ret->default_sigma, sizeof( ret->default_sigma ) ); RegisterValue( "note_jumpability", PAFLOAT, &ret->note_jumpability, sizeof( ret->note_jumpability ) ); RegisterValue( "note_combine_distance", PAFLOAT, &ret->note_combine_distance, sizeof( ret->note_combine_distance ) ); + RegisterValue( "slope", PAFLOAT, &ret->slope, sizeof( ret->slope ) ); RegisterValue( "note_attach_freq_iir", PAFLOAT, &ret->note_attach_freq_iir, sizeof( ret->note_attach_freq_iir ) ); RegisterValue( "note_attach_amp_iir", PAFLOAT, &ret->note_attach_amp_iir, sizeof( ret->note_attach_amp_iir ) ); RegisterValue( "note_attach_amp_iir2", PAFLOAT, &ret->note_attach_amp_iir2, sizeof( ret->note_attach_amp_iir2 ) ); @@ -188,6 +190,9 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head case 2: DoDFTProgressiveInteger( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup ); break; + case 3: + DoDFTProgressiveIntegerSkippy( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup ); + break; default: fprintf( stderr, "Error: No DFT Seleced\n" ); } @@ -195,7 +200,7 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head for( i = 0; i < freqs; i++ ) { - nf->outbins[i] = nf->outbins[i] * (nf->dft_iir) + (dftbins[i] * (1.-nf->dft_iir) * nf->amplify); + nf->outbins[i] = (nf->outbins[i] * (nf->dft_iir) + (dftbins[i] * (1.-nf->dft_iir) * nf->amplify * ( 1. + nf->slope * i ))); } diff --git a/notefinder.h b/notefinder.h index 937ebc7..5d56462 100644 --- a/notefinder.h +++ b/notefinder.h @@ -8,6 +8,7 @@ struct NoteFinder { //Setup DFT Bins int ofreqs; + float slope;// = 0 int octaves;// = 5; int freqbins;// = 24; int note_peaks; //Calculated from freqbins (not configurable)