integer-based DFTs are working.
This commit is contained in:
parent
2e26b747fd
commit
3914898fbb
BIN
colorchord.exe
BIN
colorchord.exe
Binary file not shown.
|
@ -24,8 +24,7 @@ wininput = 0
|
||||||
#sound_source = PULSE
|
#sound_source = PULSE
|
||||||
#-1 indicates left and right, 0 left, 1 right.
|
#-1 indicates left and right, 0 left, 1 right.
|
||||||
sample_channel = -1
|
sample_channel = -1
|
||||||
sourcename =
|
sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
|
||||||
alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
|
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
# General ColorChord properties. #
|
# General ColorChord properties. #
|
||||||
|
@ -55,9 +54,9 @@ filter_strength = .5
|
||||||
freqbins = 24
|
freqbins = 24
|
||||||
|
|
||||||
# For the final note information... How much to slack everything?
|
# For the final note information... How much to slack everything?
|
||||||
note_attach_amp_iir = 0.3000
|
note_attach_amp_iir = 0.2000
|
||||||
note_attach_amp_iir2 = 0.200
|
note_attach_amp_iir2 = 0.150
|
||||||
note_attach_freq_iir = 0.4000
|
note_attach_freq_iir = 0.3000
|
||||||
|
|
||||||
#How many bins a note can jump from frame to frame to be considered a slide.
|
#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.
|
#this is used to prevent notes from popping in and out a lot.
|
||||||
|
|
282
dft.c
282
dft.c
|
@ -192,8 +192,6 @@ void DoDFTProgressive( float * outbins, float * frequencies, int bins, const flo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define PROGIIR .005
|
|
||||||
|
|
||||||
//NOTES to self:
|
//NOTES to self:
|
||||||
//
|
//
|
||||||
// Let's say we want to try this on an AVR.
|
// 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.
|
//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)
|
static uint16_t * datspace; //(advances,places,isses,icses)
|
||||||
|
|
||||||
//
|
|
||||||
void HandleProgressiveInt( int8_t sample1, int8_t sample2 )
|
void HandleProgressiveInt( int8_t sample1, int8_t sample2 )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint16_t startpl = 0;
|
|
||||||
int16_t ts, tc;
|
int16_t ts, tc;
|
||||||
int16_t tmp1;
|
int16_t tmp1;
|
||||||
int8_t s1, c1;
|
int8_t s1, c1;
|
||||||
uint16_t ipl, localipl, adv;
|
uint16_t ipl, localipl, adv;
|
||||||
|
|
||||||
|
uint16_t * ds = &datspace[0];
|
||||||
|
int8_t * st;
|
||||||
|
//Clocks are listed for AVR.
|
||||||
|
|
||||||
//startpl maps to 'Y'
|
//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
|
||||||
|
|
||||||
//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
|
|
||||||
{
|
{
|
||||||
//12 cycles MIN
|
//12 cycles MIN
|
||||||
adv = 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 = datspace[startpl++]; //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
|
//13 cycles MIN
|
||||||
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
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
|
st = &sintable[localipl];
|
||||||
s1 = sintable[localipl++]; //Read s1 component out of table. 2+2 cycles 2
|
s1 = *(st++); //Read s1 component out of table. 2+2 cycles 2
|
||||||
c1 = sintable[localipl++]; //Read c1 component out of table. 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
|
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
|
tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2 ->Deferred
|
||||||
|
|
||||||
|
|
||||||
//15 cycles MIN
|
//15 cycles MIN
|
||||||
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
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
|
// need to load Z with 'sintable' and add localipl 2
|
||||||
s1 = sintable[localipl++]; //Read s1 component out of table. 2 cycles 2
|
st = &sintable[localipl];
|
||||||
c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2
|
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
|
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
|
tc += (c1 * sample2); // 8 x 8 multiply signed + add R1 out. 3 ->Deferred
|
||||||
|
|
||||||
|
|
||||||
//Add TS and TC to the datspace stuff. (24 instructions)
|
//Add TS and TC to the datspace stuff. (24 instructions)
|
||||||
tmp1 = datspace[startpl]; //Read out, sin component. 4
|
tmp1 = (*ds); //Read out, sin component. 4 Accurate.
|
||||||
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
tmp1 -= tmp1>>7; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14
|
||||||
tmp1 += ts>>6; //Add MSBs with carry 2
|
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 = *ds; //Read out, sin component. 4
|
||||||
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
tmp1 -= tmp1>>7; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14
|
||||||
tmp1 += tc>>6; //Add MSBs with carry 2
|
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 )
|
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;
|
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<<OCTAVES)
|
||||||
|
|
||||||
|
//NOTES to self:
|
||||||
|
//
|
||||||
|
// Let's say we want to try this on an AVR.
|
||||||
|
// 24 bins, 5 octaves = 120 bins.
|
||||||
|
// 20 MHz clock / 4.8k sps = 4096 IPS = 34 clocks per bin = :(
|
||||||
|
// We can do two at the same time, this frees us up some
|
||||||
|
|
||||||
|
static uint8_t Sdonefirstrun;
|
||||||
|
static int8_t Ssintable[512]; //Actually [sin][cos] pairs.
|
||||||
|
static uint16_t Sdatspace[FIXBINS*4]; //(advances,places,isses,icses)
|
||||||
|
|
||||||
|
//For
|
||||||
|
static uint8_t Sdo_this_octave[BINCYCLE];
|
||||||
|
static int16_t Saccum_octavebins[OCTAVES];
|
||||||
|
static uint8_t Swhichoctaveplace;
|
||||||
|
|
||||||
|
void HandleProgressiveIntSkippy( int8_t sample1 )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int16_t ts, tc;
|
||||||
|
int16_t tmp1;
|
||||||
|
int8_t s1, c1;
|
||||||
|
uint16_t ipl, localipl, adv;
|
||||||
|
|
||||||
|
uint8_t oct = Sdo_this_octave[Swhichoctaveplace];
|
||||||
|
Swhichoctaveplace ++;
|
||||||
|
Swhichoctaveplace &= BINCYCLE-1;
|
||||||
|
|
||||||
|
if( oct > 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<<octave);
|
||||||
|
Sdatspace[i*4+2] -= isps>>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<<j) & i) == 0 ) break;
|
||||||
|
}
|
||||||
|
if( j > 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
12
dft.h
12
dft.h
|
@ -1,14 +1,16 @@
|
||||||
#ifndef _DFT_H
|
#ifndef _DFT_H
|
||||||
#define _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.
|
//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
|
//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.
|
//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 );
|
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
|
//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 );
|
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 );
|
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.
|
//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 );
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
do_progressive_dft = 1
|
do_progressive_dft = 3
|
||||||
samplerate = 8000
|
samplerate = 8000
|
||||||
buffer = 128
|
buffer = 64
|
||||||
|
sourcename = alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
|
||||||
|
|
||||||
|
|
344
main.c
344
main.c
|
@ -14,6 +14,8 @@
|
||||||
#include "outdrivers.h"
|
#include "outdrivers.h"
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
|
||||||
|
#define NRDEFFILES 10
|
||||||
|
|
||||||
struct SoundDriver * sd;
|
struct SoundDriver * sd;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -32,6 +34,7 @@ char ** gargv;
|
||||||
struct DriverInstances * outdriver[MAX_OUT_DRIVERS];
|
struct DriverInstances * outdriver[MAX_OUT_DRIVERS];
|
||||||
|
|
||||||
|
|
||||||
|
int headless = 0; REGISTER_PARAM( headless, PAINT );
|
||||||
int set_screenx = 640; REGISTER_PARAM( set_screenx, PAINT );
|
int set_screenx = 640; REGISTER_PARAM( set_screenx, PAINT );
|
||||||
int set_screeny = 480; REGISTER_PARAM( set_screeny, PAINT );
|
int set_screeny = 480; REGISTER_PARAM( set_screeny, PAINT );
|
||||||
char sound_source[16]; REGISTER_PARAM( sound_source, PABUFFER );
|
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++ )
|
for( j = 0; j < channelin; j++ )
|
||||||
{
|
{
|
||||||
float f = in[i*channelin+j];
|
float f = in[i*channelin+j];
|
||||||
if( f < -1 || f > 1 ) continue;
|
if( f > -1 && f < 1 )
|
||||||
fo += f;
|
{
|
||||||
|
fo += f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fo /= channelin;
|
fo /= channelin;
|
||||||
sound[soundhead] = fo;
|
sound[soundhead] = fo;
|
||||||
soundhead = (soundhead+1)%SOUNDCBSIZE;
|
soundhead = (soundhead+1)%SOUNDCBSIZE;
|
||||||
|
@ -106,9 +112,11 @@ void SoundCB( float * out, float * in, int samplesr, int * samplesp, struct Soun
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float f = in[i*channelin+sample_channel];
|
float f = in[i*channelin+sample_channel];
|
||||||
if( f < -1 || f > 1 ) continue;
|
if( f > -1 && f < 1 )
|
||||||
sound[soundhead] = f;
|
{
|
||||||
soundhead = (soundhead+1)%SOUNDCBSIZE;
|
sound[soundhead] = f;
|
||||||
|
soundhead = (soundhead+1)%SOUNDCBSIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +126,6 @@ void LoadFile( const char * filename )
|
||||||
{
|
{
|
||||||
char * buffer;
|
char * buffer;
|
||||||
int r;
|
int r;
|
||||||
int i;
|
|
||||||
|
|
||||||
FILE * f = fopen( filename, "rb" );
|
FILE * f = fopen( filename, "rb" );
|
||||||
if( !f )
|
if( !f )
|
||||||
|
@ -144,26 +151,69 @@ void LoadFile( const char * filename )
|
||||||
}
|
}
|
||||||
free( buffer );
|
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] );
|
printf( "AP: %s\n", gargv[i] );
|
||||||
SetParametersFromString( 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)
|
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;
|
int i;
|
||||||
double LastFileTimeInit = 0;
|
|
||||||
double LastFileTimeDefault = 0;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
@ -178,23 +228,9 @@ int main(int argc, char ** argv)
|
||||||
gargc = argc;
|
gargc = argc;
|
||||||
gargv = argv;
|
gargv = argv;
|
||||||
|
|
||||||
if( argc > 1 )
|
InitialFile[0] = "default.conf";
|
||||||
{
|
|
||||||
InitialFile = argv[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
LastFileTimeDefault = OGGetFileTime( InitialFileDefault );
|
|
||||||
LoadFile( InitialFileDefault );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( InitialFile )
|
|
||||||
{
|
|
||||||
LastFileTimeInit = OGGetFileTime( InitialFile );
|
|
||||||
LoadFile( InitialFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ProcessArgs();
|
||||||
|
|
||||||
//Initialize Rawdraw
|
//Initialize Rawdraw
|
||||||
int frames = 0;
|
int frames = 0;
|
||||||
|
@ -219,7 +255,8 @@ int main(int argc, char ** argv)
|
||||||
tp++;
|
tp++;
|
||||||
}
|
}
|
||||||
*tp = 0;
|
*tp = 0;
|
||||||
CNFGSetup( title, set_screenx, set_screeny );
|
if( !headless )
|
||||||
|
CNFGSetup( title, set_screenx, set_screeny );
|
||||||
|
|
||||||
|
|
||||||
char * OutDriverNames = strdup( GetParameterS( "outdrivers", "null" ) );
|
char * OutDriverNames = strdup( GetParameterS( "outdrivers", "null" ) );
|
||||||
|
@ -266,10 +303,14 @@ int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
char stt[1024];
|
char stt[1024];
|
||||||
//Handle Rawdraw frame swappign
|
//Handle Rawdraw frame swappign
|
||||||
CNFGHandleInput();
|
|
||||||
CNFGClearFrame();
|
if( !headless )
|
||||||
CNFGColor( 0xFFFFFF );
|
{
|
||||||
CNFGGetDimensions( &screenx, &screeny );
|
CNFGHandleInput();
|
||||||
|
CNFGClearFrame();
|
||||||
|
CNFGColor( 0xFFFFFF );
|
||||||
|
CNFGGetDimensions( &screenx, &screeny );
|
||||||
|
}
|
||||||
|
|
||||||
RunNoteFinder( nf, sound, (soundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE, SOUNDCBSIZE );
|
RunNoteFinder( nf, sound, (soundhead-1+SOUNDCBSIZE)%SOUNDCBSIZE, SOUNDCBSIZE );
|
||||||
//Done all ColorChord work.
|
//Done all ColorChord work.
|
||||||
|
@ -281,123 +322,127 @@ int main(int argc, char ** argv)
|
||||||
|
|
||||||
VisTimeEnd = OGGetAbsoluteTime();
|
VisTimeEnd = OGGetAbsoluteTime();
|
||||||
|
|
||||||
//Handle outputs.
|
if( !headless )
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
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.
|
for( i = 0; i < nf->dists; i++ )
|
||||||
CNFGPenY = 400-nf->dist_amps[i] * 150.0 / nf->dist_sigmas[i];
|
{
|
||||||
//printf( "%f %f\n", dist_means[i], dist_amps[i] );
|
CNFGPenX = (nf->dist_means[i] + 0.5) / freqbins * screenx; //Move over 0.5 for visual purposes. The means is correct.
|
||||||
sprintf( stt, "%f\n%f\n", nf->dist_means[i], nf->dist_amps[i] );
|
CNFGPenY = 400-nf->dist_amps[i] * 150.0 / nf->dist_sigmas[i];
|
||||||
CNFGDrawText( stt, 2 );
|
//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 );
|
CNFGColor( 0xffffff );
|
||||||
|
CNFGPenX = 440; CNFGPenY = screeny-10;
|
||||||
//Draw the folded bins
|
sprintf( stt, "FPS: %d", lastfps );
|
||||||
for( i = 0; i < freqbins; i++ )
|
CNFGDrawText( stt, 2 );
|
||||||
{
|
CNFGSwapBuffers();
|
||||||
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 );
|
|
||||||
CNFGPenX = 440; CNFGPenY = screeny-10;
|
|
||||||
sprintf( stt, "FPS: %d", lastfps );
|
|
||||||
CNFGDrawText( stt, 2 );
|
|
||||||
|
|
||||||
//Finish Rawdraw with FPS counter, and a nice delay loop.
|
//Finish Rawdraw with FPS counter, and a nice delay loop.
|
||||||
frames++;
|
frames++;
|
||||||
CNFGSwapBuffers();
|
|
||||||
ThisTime = OGGetAbsoluteTime();
|
ThisTime = OGGetAbsoluteTime();
|
||||||
if( ThisTime > LastFPSTime + 1 )
|
if( ThisTime > LastFPSTime + 1 )
|
||||||
{
|
{
|
||||||
|
@ -416,18 +461,7 @@ int main(int argc, char ** argv)
|
||||||
OGUSleep( (int)( SecToWait * 1000000 ) );
|
OGUSleep( (int)( SecToWait * 1000000 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( OGGetFileTime( InitialFileDefault ) != LastFileTimeDefault ||
|
SetEnvValues();
|
||||||
(InitialFile && LastFileTimeInit != OGGetFileTime( InitialFile ) ) )
|
|
||||||
{
|
|
||||||
LastFileTimeDefault = OGGetFileTime( InitialFileDefault );
|
|
||||||
LoadFile( InitialFileDefault );
|
|
||||||
|
|
||||||
if( InitialFile )
|
|
||||||
{
|
|
||||||
LastFileTimeInit = OGGetFileTime( InitialFile );
|
|
||||||
LoadFile( InitialFile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
outdrivers = DisplayNetwork, OutputLinear
|
outdrivers = DisplayPie,DisplayNetwork, OutputLinear
|
||||||
leds = 296
|
leds = 296
|
||||||
light_siding = 1.0 #Turn this to ~1.9 for more uniformity, ~1.0 for less.
|
light_siding = 1.0 #Turn this to ~1.9 for more uniformity, ~1.0 for less.
|
||||||
satamp = 1.600
|
satamp = 1.600
|
||||||
is_loop=0
|
is_loop=0
|
||||||
led_floor = .1 #Turn to .25 for more uniformity, .1 for less.
|
led_floor = .1 #Turn to .25 for more uniformity, .1 for less.
|
||||||
note_attach_amp_iir = .3000
|
#note_attach_amp_iir = .3 #.3000
|
||||||
note_attach_amp_iir2 = .1500
|
#note_attach_amp_iir2 = .15 #.1500
|
||||||
note_attach_freq_iir = 0.3000
|
#note_attach_freq_iir = .3 #0.3000
|
||||||
steady_bright = 0
|
steady_bright = 0
|
||||||
#dft_iir = 0.0
|
#dft_iir = 0.0
|
||||||
#dft_q = 20.0000
|
#dft_q = 20.0000
|
||||||
|
@ -17,3 +17,10 @@ firstval = 0
|
||||||
port = 7777
|
port = 7777
|
||||||
address = 192.168.0.245
|
address = 192.168.0.245
|
||||||
|
|
||||||
|
slope=.10
|
||||||
|
amplify=.3
|
||||||
|
|
||||||
|
|
||||||
|
lightx = 20
|
||||||
|
lighty = 20
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct NoteFinder * CreateNoteFinder( int spsRec )
|
||||||
ret->decompose_iterations = 1000;
|
ret->decompose_iterations = 1000;
|
||||||
ret->dft_speedup = 300;
|
ret->dft_speedup = 300;
|
||||||
ret->dft_q = 16;
|
ret->dft_q = 16;
|
||||||
|
ret->slope = 0.0;
|
||||||
ret->do_progressive_dft = 0;
|
ret->do_progressive_dft = 0;
|
||||||
ret->default_sigma = 1.4;
|
ret->default_sigma = 1.4;
|
||||||
ret->note_jumpability = 2.5;
|
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( "default_sigma", PAFLOAT, &ret->default_sigma, sizeof( ret->default_sigma ) );
|
||||||
RegisterValue( "note_jumpability", PAFLOAT, &ret->note_jumpability, sizeof( ret->note_jumpability ) );
|
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( "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_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_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 ) );
|
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:
|
case 2:
|
||||||
DoDFTProgressiveInteger( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
DoDFTProgressiveInteger( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
DoDFTProgressiveIntegerSkippy( dftbins, nf->frequencies, freqs, audio_stream, head, buffersize, nf->dft_q, nf->dft_speedup );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "Error: No DFT Seleced\n" );
|
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++ )
|
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 )));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ struct NoteFinder
|
||||||
{
|
{
|
||||||
//Setup DFT Bins
|
//Setup DFT Bins
|
||||||
int ofreqs;
|
int ofreqs;
|
||||||
|
float slope;// = 0
|
||||||
int octaves;// = 5;
|
int octaves;// = 5;
|
||||||
int freqbins;// = 24;
|
int freqbins;// = 24;
|
||||||
int note_peaks; //Calculated from freqbins (not configurable)
|
int note_peaks; //Calculated from freqbins (not configurable)
|
||||||
|
|
Loading…
Reference in a new issue