diff --git a/colorchord2/Makefile b/colorchord2/Makefile index 9e96711..4919f93 100644 --- a/colorchord2/Makefile +++ b/colorchord2/Makefile @@ -16,10 +16,10 @@ LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse CFLAGS:=-g -O0 -flto -Wall -ffast-math -I../embeddedcommon -I. -DICACHE_FLASH_ATTR= EXTRALIBS:=-lusb-1.0 -colorchord : os_generic.o main.o dft.o decompose.o filter.o color.o sort.o notefinder.o util.o outdrivers.o $(RAWDRAW) $(SOUND) $(OUTS) parameters.o chash.o hook.o ../embeddedcommon/DFT32.o configs.o +colorchord : os_generic.o main.o dft.o decompose.o filter.o color.o notefinder.o util.o outdrivers.o $(RAWDRAW) $(SOUND) $(OUTS) parameters.o chash.o hook.o ../embeddedcommon/DFT32.o configs.o gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS) -colorchord.exe : os_generic.c main.c dft.c decompose.c filter.c color.c sort.c notefinder.c util.c outdrivers.c DrawFunctions.c parameters.c chash.c WinDriver.c sound.c sound_null.c sound_win.c OutputVoronoi.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c hook.c RecorderPlugin.c ../embeddedcommon/DFT32.c OutputCells.c configs.c +colorchord.exe : os_generic.c main.c dft.c decompose.c filter.c color.c notefinder.c util.c outdrivers.c DrawFunctions.c parameters.c chash.c WinDriver.c sound.c sound_null.c sound_win.c OutputVoronoi.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c hook.c RecorderPlugin.c ../embeddedcommon/DFT32.c OutputCells.c configs.c $(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS) diff --git a/colorchord2/decompose.c b/colorchord2/decompose.c index 9b76f6e..5746263 100644 --- a/colorchord2/decompose.c +++ b/colorchord2/decompose.c @@ -1,6 +1,7 @@ //Copyright 2015 <>< Charles Lohr under the ColorChord License. #include "decompose.h" +#include "notefinder.h" #include #include #include @@ -10,7 +11,7 @@ #ifdef TURBO_DECOMPOSE -int DecomposeHistogram( float * histogram, int bins, float * out_means, float * out_amps, float * out_sigmas, int max_dists, double default_sigma, int iterations ) +int DecomposeHistogram( float * histogram, int bins, struct NoteDists * out_dists, int max_dists, double default_sigma, int iterations ) { //Step 1: Find the actual peaks. @@ -41,35 +42,35 @@ int DecomposeHistogram( float * histogram, int bins, float * out_means, float * offset = (0.5 - porpdiffN); } - out_means[peak] = i + offset; + out_dists[peak].mean = i + offset; //XXX XXX TODO Examine difference or relationship of "this" and "totaldiff" - out_amps[peak] = this * 4; + out_dists[peak].amp = this * 4; //powf( totaldiff, .8) * 10;//powf( totaldiff, .5 )*4; // - out_sigmas[peak] = default_sigma; + out_dists[peak].sigma = default_sigma; peak++; } for( i = peak; i < max_dists; i++ ) { - out_means[i] = -1; - out_amps[i] = 0; - out_sigmas[i] = default_sigma; + out_dists[i].mean = -1; + out_dists[i].amp = 0; + out_dists[i].sigma = default_sigma; } return peak; } //Yick: Doesn't match.. I guess it's only for debugging, right? -float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ) +float CalcHistAt( float pt, int bins, struct NoteDists * out_dists, int cur_dists ) { int i; float mark = 0.0; for( i = 0; i < cur_dists; i++ ) { - float amp = out_amps[i]; - float mean = out_means[i]; - float var = out_sigmas[i]; + float amp = out_dists[i].amp; + float mean = out_dists[i].mean; + float var = out_dists[i].sigma; float x = mean - pt; if( x < - bins / 2 ) x += bins; @@ -83,11 +84,11 @@ float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float #else -float AttemptDecomposition( float * histogram, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ); -float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ); +float AttemptDecomposition( float * histogram, int bins, struct NoteDists * out_dists, int cur_dists ); +float CalcHistAt( float pt, int bins, struct NoteDists * out_dists, int cur_dists ); -int DecomposeHistogram( float * histogram, int bins, float * out_means, float * out_amps, float * out_sigmas, int max_dists, double default_sigma, int iterations ) +int DecomposeHistogram( float * histogram, int bins, struct NoteDists * out_dists, int max_dists, double default_sigma, int iterations ) { //NOTE: The sigma may change depending on all sorts of things, maybe? @@ -108,9 +109,9 @@ int DecomposeHistogram( float * histogram, int bins, float * out_means, float * else if( went_up) { went_up = 0; - out_amps[sigs] = thishist / (default_sigma + 1); - out_sigmas[sigs] = default_sigma; - out_means[sigs] = i-0.5; + out_dists[sigs].amp = thishist / (default_sigma + 1); + out_dists[sigs].sigma = default_sigma; + out_dists[sigs].mean = i-0.5; sigs++; } vhist = thishist; @@ -119,7 +120,7 @@ int DecomposeHistogram( float * histogram, int bins, float * out_means, float * return 0; int iteration; - float errbest = AttemptDecomposition( histogram, bins, out_means, out_amps, out_sigmas, sigs ); + float errbest = AttemptDecomposition( histogram, bins, out_dists, sigs ); int dropped[bins]; for( i = 0; i < bins; i++ ) { @@ -130,33 +131,28 @@ int DecomposeHistogram( float * histogram, int bins, float * out_means, float * { if( dropped[iteration%sigs] ) continue; //Tweak with the values until they are closer to what we want. - float backup_mean = out_means[iteration%sigs]; - float backup_amps = out_amps[iteration%sigs]; - float backup_sigmas = out_sigmas[iteration%sigs]; + struct NoteDists backup = out_dists[iteration%sigs]; float mute = 20. / (iteration+20.); #define RANDFN ((rand()%2)-0.5)*mute //#define RANDFN ((rand()%10000)-5000.0) / 5000.0 * mute -// out_sigmas[iteration%sigs] += RANDFN; - out_means[iteration%sigs] += RANDFN; - out_amps[iteration%sigs] += RANDFN; - float err = AttemptDecomposition( histogram, bins, out_means, out_amps, out_sigmas, sigs ); +// out_dists[iteration%sigs].sigma += RANDFN; + out_dists[iteration%sigs].mean += RANDFN; + out_dists[iteration%sigs].amp += RANDFN; + float err = AttemptDecomposition( histogram, bins, out_dists, sigs ); if( err > errbest ) { - out_means[iteration%sigs] = backup_mean; - out_amps[iteration%sigs] = backup_amps; - out_sigmas[iteration%sigs] = backup_sigmas; + out_dists[iteration%sigs] = backup; } else { - if( out_amps[iteration%sigs] < 0.01 ) + if( out_dists[iteration%sigs].amp < 0.01 ) { dropped[iteration%sigs] = 1; - out_amps[iteration%sigs] = 0.0; + out_dists[iteration%sigs].amp = 0.0; } errbest = err; } - } // printf( "%f / %f = %f\n", origerr, errbest, origerr/errbest ); @@ -164,15 +160,15 @@ int DecomposeHistogram( float * histogram, int bins, float * out_means, float * return sigs; } -float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ) +float CalcHistAt( float pt, int bins, struct NoteDists * out_dists, int cur_dists ) { int i; float mark = 0.0; for( i = 0; i < cur_dists; i++ ) { - float amp = out_amps[i]; - float mean = out_means[i]; - float var = out_sigmas[i]; + float amp = out_dists[i].amp; + float mean = out_dists[i].mean; + float var = out_dists[i].sigma; float x = mean - pt; if( x < - bins / 2 ) x += bins; @@ -183,16 +179,16 @@ float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float return mark; } -float AttemptDecomposition( float * histogram, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ) +float AttemptDecomposition( float * histogram, int bins, struct NoteDists * out_dists, int cur_dists ) { int i, j; float hist[bins]; memcpy( hist, histogram, sizeof(hist) ); for( i = 0; i < cur_dists; i++ ) { - float amp = out_amps[i]; - float mean = out_means[i]; - float var = out_sigmas[i]; + float amp = out_dists[i].amp; + float mean = out_dists[i].mean; + float var = out_dists[i].sigma; for( j = 0; j < bins; j++ ) { diff --git a/colorchord2/decompose.h b/colorchord2/decompose.h index 19ac4cf..9007529 100644 --- a/colorchord2/decompose.h +++ b/colorchord2/decompose.h @@ -3,9 +3,11 @@ #ifndef _DECOMPOSE_H #define _DECOMPOSE_H +#include "notefinder.h" + //Decompose a histogram into a series of normal distributions. -int DecomposeHistogram( float * histogram, int bins, float * out_means, float * out_amps, float * out_sigmas, int max_dists, double default_sigma, int iterations ); -float CalcHistAt( float pt, int bins, float * out_means, float * out_amps, float * out_sigmas, int cur_dists ); +int DecomposeHistogram( float * histogram, int bins, struct NoteDists * out_dists, int max_dists, double default_sigma, int iterations ); +float CalcHistAt( float pt, int bins, struct NoteDists * out_dists, int cur_dists ); #define TURBO_DECOMPOSE diff --git a/colorchord2/main.c b/colorchord2/main.c index 5c1a35d..306a8ab 100644 --- a/colorchord2/main.c +++ b/colorchord2/main.c @@ -306,13 +306,13 @@ int main(int argc, char ** argv) //char sttdebug[1024]; //char * sttend = sttdebug; - for( i = 0; i < nf->dists; i++ ) + for( i = 0; i < nf->dists_count; 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] ); -// sttend += sprintf( sttend, "%f/%f ",nf->dist_means[i], nf->dist_amps[i] ); + CNFGPenX = (nf->dists[i].mean + 0.5) / freqbins * screenx; //Move over 0.5 for visual purposes. The means is correct. + CNFGPenY = 400-nf->dists[i].amp * 150.0 / nf->dists[i].sigma; + //printf( "%f %f\n", dists[i].mean, dists[i].amp ); + sprintf( stt, "%f\n%f\n", nf->dists[i].mean, nf->dists[i].amp ); +// sttend += sprintf( sttend, "%f/%f ",nf->dists[i].mean, nf->dists[i].amp ); CNFGDrawText( stt, 2 ); } CNFGColor( 0xffffff ); @@ -366,7 +366,7 @@ int main(int argc, char ** argv) 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 ); + float thishistval = CalcHistAt( (float)i/(float)screenx*freqbins-0.5, nf->freqbins, nf->dists, nf->dists_count ); if( i >= 0 ) CNFGTackSegment( i, 400-lasthistval * 250.0, i+1, 400-thishistval * 250.0 ); lasthistval = thishistval; diff --git a/colorchord2/notefinder.c b/colorchord2/notefinder.c index fdc3cd9..0745e3e 100644 --- a/colorchord2/notefinder.c +++ b/colorchord2/notefinder.c @@ -10,7 +10,6 @@ #include "dft.h" #include "filter.h" #include "decompose.h" -#include "sort.h" #include "DFT32.h" struct NoteFinder * CreateNoteFinder( int spsRec ) @@ -151,18 +150,8 @@ printf( "%d %d %f %f %f\n", ret->freqbins, ret->octaves, ret->base_hz, ret->dft_ if( ret->folded_bins ) free( ret->folded_bins ); ret->folded_bins = calloc( 1, sizeof( float ) * ret->freqbins ); - - if( ret->dist_amps ) free( ret->dist_amps ); - ret->dist_amps = calloc( 1, sizeof( float ) * maxdists ); - - if( ret->dist_means ) free( ret->dist_means ); - ret->dist_means = calloc( 1, sizeof( float ) * maxdists ); - - if( ret->dist_sigmas ) free( ret->dist_sigmas ); - ret->dist_sigmas = calloc( 1, sizeof( float ) * maxdists ); - - if( ret->dist_takens ) free( ret->dist_takens ); - ret->dist_takens = calloc( 1, sizeof( unsigned char ) * maxdists ); + if( ret->dists ) free ( ret->dists ); + ret->dists = calloc( 1, sizeof( struct NoteDists ) * maxdists ); ret->ofreqs = freqs; } @@ -174,6 +163,12 @@ printf( "%d %d %f %f %f\n", ret->freqbins, ret->octaves, ret->base_hz, ret->dft_ } +int NoteDistsComparer(const void * a, const void * b) +{ + float v = ((struct NoteDists *)a)->amp - ((struct NoteDists *)b)->amp; + return (0.f < v) - (v < 0.f); +} + void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head, int buffersize ) { int i, j; @@ -242,37 +237,35 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head nf->FilterTime = OGGetAbsoluteTime(); - memset( nf->dist_takens, 0, sizeof( unsigned char ) * maxdists ); - nf->dists = DecomposeHistogram( nf->folded_bins, freqbins, nf->dist_means, nf->dist_amps, nf->dist_sigmas, maxdists, nf->default_sigma, nf->decompose_iterations ); + for (i = 0; i < maxdists; i++) + { + nf->dists[i].taken = 0; + } + nf->dists_count = DecomposeHistogram( nf->folded_bins, freqbins, nf->dists, maxdists, nf->default_sigma, nf->decompose_iterations ); //Compress/normalize dist_amps float total_dist = 0; - for( i = 0; i < nf->dists; i++ ) + for( i = 0; i < nf->dists_count; i++ ) { - total_dist += nf->dist_amps[i]; + total_dist += nf->dists[i].amp; } float muxer = nf->compress_coefficient/powf( total_dist * nf->compress_coefficient, nf->compress_exponenet ); total_dist = muxer; - for( i = 0; i < nf->dists; i++ ) + for( i = 0; i < nf->dists_count; i++ ) { - nf->dist_amps[i]*=total_dist; + nf->dists[i].amp*=total_dist; } - { - int dist_sorts[nf->dists]; - SortFloats( dist_sorts, nf->dist_amps, nf->dists ); - RemapFloats( dist_sorts, nf->dist_amps, nf->dists ); - RemapFloats( dist_sorts, nf->dist_means, nf->dists ); - RemapFloats( dist_sorts, nf->dist_sigmas, nf->dists ); - } + qsort(nf->dists, nf->dists_count, sizeof(struct NoteDists), NoteDistsComparer); + nf->DecomposeTime = OGGetAbsoluteTime(); //We now have the positions and amplitudes of the normal distributions that comprise our spectrum. IN SORTED ORDER! - //dists = # of distributions - //dist_amps[] = amplitudes of the normal distributions - //dist_means[] = positions of the normal distributions + //dists_count = # of distributions + //dists[].amp = amplitudes of the normal distributions + //dists[].mean = positions of the normal distributions //We need to use this in a filtered manner to obtain the "note" peaks //note_peaks = total number of peaks. @@ -283,26 +276,26 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head //First try to find any close peaks. for( i = 0; i < note_peaks; i++ ) { - for( j = 0; j < nf->dists; j++ ) + for( j = 0; j < nf->dists_count; j++ ) { - if( !nf->dist_takens[j] && !nf->note_founds[i] && fabsloop( nf->note_positions[i], nf->dist_means[j], freqbins ) < nf->note_jumpability && nf->dist_amps[j] > 0.00001 ) //0.00001 for stability. + if( !nf->dists[j].taken && !nf->note_founds[i] && fabsloop( nf->note_positions[i], nf->dists[j].mean, freqbins ) < nf->note_jumpability && nf->dists[j].amp > 0.00001 ) //0.00001 for stability. { //Attach ourselves to this bin. nf->note_peaks_to_dists_mapping[i] = j; - nf->dist_takens[j] = 1; + nf->dists[j].taken = 1; if( nf->enduring_note_id[i] == 0 ) nf->enduring_note_id[i] = nf->current_note_id++; nf->note_founds[i] = 1; - nf->note_positions[i] = avgloop( nf->note_positions[i], (1.-nf->note_attach_freq_iir), nf->dist_means[j], nf->note_attach_freq_iir, nf->freqbins); + nf->note_positions[i] = avgloop( nf->note_positions[i], (1.-nf->note_attach_freq_iir), nf->dists[j].mean, nf->note_attach_freq_iir, nf->freqbins); //I guess you can't IIR this like normal. - ////note_positions[i] * (1.-note_attach_freq_iir) + dist_means[j] * note_attach_freq_iir; + ////note_positions[i] * (1.-note_attach_freq_iir) + dists[j].mean * note_attach_freq_iir; - nf->note_amplitudes[i] = nf->note_amplitudes[i] * (1.-nf->note_attach_amp_iir) + nf->dist_amps[j] * nf->note_attach_amp_iir; + nf->note_amplitudes[i] = nf->note_amplitudes[i] * (1.-nf->note_attach_amp_iir) + nf->dists[j].amp * nf->note_attach_amp_iir; //XXX TODO: Consider: Always boost power, never reduce? -// if( dist_amps[i] > note_amplitudes[i] ) -// note_amplitudes[i] = dist_amps[i]; +// if( dists[i].amp > note_amplitudes[i] ) +// note_amplitudes[i] = dists[i].amp; } } } @@ -350,16 +343,15 @@ void RunNoteFinder( struct NoteFinder * nf, const float * audio_stream, int head nf->enduring_note_id[i] = 0; //Find a new peak for this note. - for( j = 0; j < nf->dists; j++ ) + for( j = 0; j < nf->dists_count; j++ ) { - if( !nf->dist_takens[j] && nf->dist_amps[j] > nf->note_minimum_new_distribution_value ) + if( !nf->dists[j].taken && nf->dists[j].amp > nf->note_minimum_new_distribution_value ) { nf->enduring_note_id[i] = nf->current_note_id++; - nf->dist_takens[j] = 1; - nf->note_amplitudes[i] = nf->dist_amps[j];//min_note_amplitude + dist_amps[j] * note_attach_amp_iir; //TODO: Should this jump? - nf->note_positions[i] = nf->dist_means[j]; + nf->dists[j].taken = 1; + nf->note_amplitudes[i] = nf->dists[j].amp;//min_note_amplitude + dists[j].amp * note_attach_amp_iir; //TODO: Should this jump? + nf->note_positions[i] = nf->dists[j].mean; nf->note_founds[i] = 1; - nf->dist_takens[j] = 1; } } } diff --git a/colorchord2/notefinder.h b/colorchord2/notefinder.h index cd9489b..e91ba9e 100644 --- a/colorchord2/notefinder.h +++ b/colorchord2/notefinder.h @@ -5,6 +5,12 @@ #include "os_generic.h" +struct NoteDists { + float amp; //Amplitude of normal distribution + float mean; //Mean of normal distribution + float sigma; //Sigma of normal distribution + unsigned char taken; //Is distribution associated with any notes? +}; struct NoteFinder { @@ -78,11 +84,8 @@ struct NoteFinder //Dists: These things are the distributions that are found, they are very fickle and change frequently. - int dists; //# of distributions (these are the precursors to notes - it is trying to find the normal distributions.) - float * dist_amps; //Amplitude of normal distribution... [nf->dists] - float * dist_means; //Mean of normal distribution... [nf->dists] - float * dist_sigmas; //Sigma of normal distribution... [nf->dists] - unsigned char * dist_takens; //Which distributions are now associated with notes + int dists_count; //# of distributions (these are the precursors to notes - it is trying to find the normal distributions.) + struct NoteDists * dists; //For profiling, all in absolute time in seconds. diff --git a/colorchord2/sort.c b/colorchord2/sort.c deleted file mode 100644 index 2787150..0000000 --- a/colorchord2/sort.c +++ /dev/null @@ -1,63 +0,0 @@ -//Copyright (Public Domain) 2015 <>< Charles Lohr, under the NewBSD License. -//This file may be used in whole or part in any way for any purpose by anyone -//without restriction. - -#include "sort.h" -#include -#include - -//Sort the indices of an array of floating point numbers -void SortFloats( int * indexouts, float * array, int count ) -{ - int i; - int j; - unsigned char selected[count]; - - memset( selected, 0, sizeof( selected ) ); - - for( i = 0; i < count; i++ ) - { - int leastindex = -1; - float leastval = -1e200; - - for( j = 0; j < count; j++ ) - { - if( !selected[j] && array[j] > leastval ) - { - leastval = array[j]; - leastindex = j; - } - } - - if( leastindex < 0 ) - { - fprintf( stderr, "ERROR: Sorting fault.\n" ); - goto fault; - } - - selected[leastindex] = 1; - indexouts[i] = leastindex; - } - - return; -fault: - for( i = 0; i < count; i++ ) - { - indexouts[i] = i; - } -} - - - -//Move the floats around according to the new index. -void RemapFloats( int * indexouts, float * array, int count ) -{ - int i; - float copyarray[count]; - memcpy( copyarray, array, sizeof( copyarray ) ); - for( i = 0; i < count; i++ ) - { - array[i] = copyarray[indexouts[i]];; - } -} - diff --git a/colorchord2/sort.h b/colorchord2/sort.h deleted file mode 100644 index 7b1a35c..0000000 --- a/colorchord2/sort.h +++ /dev/null @@ -1,20 +0,0 @@ -//Copyright (Public Domain) 2015 <>< Charles Lohr, under the NewBSD License. -//This file may be used in whole or part in any way for any purpose by anyone -//without restriction. - -#ifndef _SORT_H -#define _SORT_H - -//XXX WARNING: This is a TERRIBLE TERRIBLE O(N^2) SORTING ALGORITHM -//You should probably fix this!!! - -//Sort the indices of an array of floating point numbers -//Highest->Lowest -void SortFloats( int * indexouts, float * array, int count ); - -//Move the floats around according to the new index. -void RemapFloats( int * indexouts, float * array, int count ); - -#endif - - diff --git a/karaoke/composer.c b/karaoke/composer.c index a0654b5..a4149db 100644 --- a/karaoke/composer.c +++ b/karaoke/composer.c @@ -424,13 +424,13 @@ int main(int argc, char ** argv) //char sttdebug[1024]; //char * sttend = sttdebug; - for( i = 0; i < nf->dists; i++ ) + for( i = 0; i < nf->dists_count; 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] ); -// sttend += sprintf( sttend, "%f/%f ",nf->dist_means[i], nf->dist_amps[i] ); + CNFGPenX = (nf->dists[i].mean + 0.5) / freqbins * screenx; //Move over 0.5 for visual purposes. The means is correct. + CNFGPenY = 400-nf->dists[i].amp * 150.0 / nf->dists[i].sigma; + //printf( "%f %f\n", dists[i].mean, dists[i].amp ); + sprintf( stt, "%f\n%f\n", nf->dists[i].mean, nf->dists[i].amp ); +// sttend += sprintf( sttend, "%f/%f ",nf->dists[i].mean, nf->dists[i].amp ); CNFGDrawText( stt, 2 ); } CNFGColor( 0xffffff ); @@ -484,7 +484,7 @@ int main(int argc, char ** argv) 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 ); + float thishistval = CalcHistAt( (float)i/(float)screenx*freqbins-0.5, nf->freqbins, nf->dists, nf->dists_count ); if( i >= 0 ) CNFGTackSegment( i, 400-lasthistval * 250.0, i+1, 400-thishistval * 250.0 ); lasthistval = thishistval;