okay, things are moving along quite well. Almost ready for my first test.
This commit is contained in:
parent
6d75249cb8
commit
09be0f349b
2
Makefile
2
Makefile
|
@ -16,7 +16,7 @@ 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
|
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
|
||||||
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||||
|
|
||||||
embeddedcc : os_generic.c embeddedcc.c dft.c
|
embeddedcc : os_generic.c embeddedcc.c dft.c embeddednf.c
|
||||||
gcc -o $@ $^ $(CFLAGS) -DCCEMBEDDED $(LDFLAGS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
gcc -o $@ $^ $(CFLAGS) -DCCEMBEDDED $(LDFLAGS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||||
|
|
||||||
runembedded : embeddedcc
|
runembedded : embeddedcc
|
||||||
|
|
4
dft.c
4
dft.c
|
@ -559,13 +559,13 @@ void HandleProgressiveIntSkippy( int8_t sample1 )
|
||||||
//Add TS and TC to the datspace stuff. (24 instructions)
|
//Add TS and TC to the datspace stuff. (24 instructions)
|
||||||
tmp1 = (*ds); //Read out, sin component. 4 Accurate.
|
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 -= tmp1>>4; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14
|
||||||
tmp1 += ts>>4; //Add MSBs with carry 2 -> 6 AS/IS: 6
|
tmp1 += ts>>SHIFT_ADD_DETAIL; //Add MSBs with carry 2 -> 6 AS/IS: 6
|
||||||
|
|
||||||
*(ds++) = tmp1; //Store values back 4
|
*(ds++) = tmp1; //Store values back 4
|
||||||
|
|
||||||
tmp1 = *ds; //Read out, sin component. 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 -= tmp1>>4; //Subtract from the MSB (with carry) 2 -> 6 AS/IS: 7+7 = 14
|
||||||
tmp1 += tc>>4; //Add MSBs with carry 2 -> 6 AS/IS: 6
|
tmp1 += tc>>SHIFT_ADD_DETAIL; //Add MSBs with carry 2 -> 6 AS/IS: 6
|
||||||
|
|
||||||
*ds++ = tmp1; //Store values back 4
|
*ds++ = tmp1; //Store values back 4
|
||||||
|
|
||||||
|
|
7
dft.h
7
dft.h
|
@ -56,6 +56,13 @@ void Push8BitIntegerSkippy( int8_t dat ); //Call this to push on new frames of s
|
||||||
#define FIXBINS (FIXBPERO*OCTAVES)
|
#define FIXBINS (FIXBPERO*OCTAVES)
|
||||||
#define BINCYCLE (1<<OCTAVES)
|
#define BINCYCLE (1<<OCTAVES)
|
||||||
|
|
||||||
|
//This variable determins how much to nerf the current sample of the DFT.
|
||||||
|
//I've found issues when this is smaller, but bigger values do have a negative
|
||||||
|
//impact on quality. We should strongly consider using 32-bit accumulators.
|
||||||
|
#ifndef SHIFT_ADD_DETAIL
|
||||||
|
#define SHIFT_ADD_DETAIL 5
|
||||||
|
#endif
|
||||||
|
|
||||||
//Whenever you need to read the bins, you can do it from here.
|
//Whenever you need to read the bins, you can do it from here.
|
||||||
extern uint16_t Sdatspace[]; //(advances,places,isses,icses)
|
extern uint16_t Sdatspace[]; //(advances,places,isses,icses)
|
||||||
extern uint16_t embeddedbins[]; //This is updated every time the DFT hits the octavecount, or 1/32 updates.
|
extern uint16_t embeddedbins[]; //This is updated every time the DFT hits the octavecount, or 1/32 updates.
|
||||||
|
|
96
embeddedcc.c
96
embeddedcc.c
|
@ -4,102 +4,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "embeddednf.h"
|
||||||
#include "dft.h"
|
#include "dft.h"
|
||||||
#define DFREQ 8000
|
|
||||||
#define BASE_FREQ 55.0
|
|
||||||
|
|
||||||
const float bf_table[24] = {
|
|
||||||
1.000000, 1.029302, 1.059463, 1.090508, 1.122462, 1.155353,
|
|
||||||
1.189207, 1.224054, 1.259921, 1.296840, 1.334840, 1.373954,
|
|
||||||
1.414214, 1.455653, 1.498307, 1.542211, 1.587401, 1.633915,
|
|
||||||
1.681793, 1.731073, 1.781797, 1.834008, 1.887749, 1.943064 };
|
|
||||||
|
|
||||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
|
||||||
|
|
||||||
/* The above table was generated using the following code:
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
#define FIXBPERO 24
|
|
||||||
printf( "const float bf_table[%d] = {", FIXBPERO );
|
|
||||||
for( i = 0; i < FIXBPERO; i++ )
|
|
||||||
{
|
|
||||||
if( ( i % 6 ) == 0 )
|
|
||||||
printf( "\n\t" );
|
|
||||||
printf( "%f, ", pow( 2, (float)i / (float)FIXBPERO ) );
|
|
||||||
}
|
|
||||||
printf( "};\n" );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void UpdateFreqs()
|
|
||||||
{
|
|
||||||
uint16_t fbins[FIXBPERO];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
BUILD_BUG_ON( sizeof(bf_table) != FIXBPERO*4 );
|
|
||||||
|
|
||||||
for( i = 0; i < FIXBPERO; i++ )
|
|
||||||
{
|
|
||||||
float frq = ( bf_table[i] * BASE_FREQ );
|
|
||||||
fbins[i] = ( 65536.0 ) / ( DFREQ ) * frq * 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateBinsForProgressiveIntegerSkippyInt( fbins );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
//Step 1: Initialize the Integer DFT.
|
|
||||||
SetupDFTProgressiveIntegerSkippy();
|
|
||||||
|
|
||||||
//Step 2: Set up the frequency list.
|
|
||||||
UpdateFreqs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleFrameInfo()
|
|
||||||
{
|
|
||||||
uint16_t folded_bins[FIXBPERO];
|
|
||||||
|
|
||||||
int i, j, k = 0;
|
|
||||||
|
|
||||||
for( i = 0; i < FIXBPERO; i++ )
|
|
||||||
folded_bins[i] = 0;
|
|
||||||
|
|
||||||
for( j = 0; j < OCTAVES; j++ )
|
|
||||||
{
|
|
||||||
for( i = 0; i < FIXBPERO; i++ )
|
|
||||||
{
|
|
||||||
folded_bins[i] += embeddedbins[k++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//XXX TODO Taper the first and last octaves.
|
|
||||||
// for( i = 0; i < freqbins; i++ )
|
|
||||||
// {
|
|
||||||
// nf->outbins[i] *= (i+1.0)/nf->freqbins;
|
|
||||||
// }
|
|
||||||
// for( i = 0; i < freqbins; i++ )
|
|
||||||
// {
|
|
||||||
// nf->outbins[freqs-i-1] *= (i+1.0)/nf->freqbins;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//We now have the system folded into one
|
|
||||||
|
|
||||||
for( i = 0; i < FIXBPERO; i++ )
|
|
||||||
{
|
|
||||||
printf( "%5d ", folded_bins[i] );
|
|
||||||
}
|
|
||||||
printf( "\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
342
embeddednf.c
Normal file
342
embeddednf.c
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
#include "embeddednf.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
uint16_t folded_bins[FIXBPERO];
|
||||||
|
uint16_t fuzzed_bins[FIXBINS];
|
||||||
|
uint8_t note_peak_freqs[MAXNOTES];
|
||||||
|
uint16_t note_peak_amps[MAXNOTES];
|
||||||
|
uint16_t note_peak_amps2[MAXNOTES];
|
||||||
|
|
||||||
|
|
||||||
|
static const float bf_table[24] = {
|
||||||
|
1.000000, 1.029302, 1.059463, 1.090508, 1.122462, 1.155353,
|
||||||
|
1.189207, 1.224054, 1.259921, 1.296840, 1.334840, 1.373954,
|
||||||
|
1.414214, 1.455653, 1.498307, 1.542211, 1.587401, 1.633915,
|
||||||
|
1.681793, 1.731073, 1.781797, 1.834008, 1.887749, 1.943064 };
|
||||||
|
|
||||||
|
/* The above table was generated using the following code:
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
#define FIXBPERO 24
|
||||||
|
printf( "const float bf_table[%d] = {", FIXBPERO );
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
if( ( i % 6 ) == 0 )
|
||||||
|
printf( "\n\t" );
|
||||||
|
printf( "%f, ", pow( 2, (float)i / (float)FIXBPERO ) );
|
||||||
|
}
|
||||||
|
printf( "};\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateFreqs()
|
||||||
|
{
|
||||||
|
uint16_t fbins[FIXBPERO];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BUILD_BUG_ON( sizeof(bf_table) != FIXBPERO*4 );
|
||||||
|
|
||||||
|
//Warning: This does floating point. Avoid doing this frequently. If you
|
||||||
|
//absolutely cannot have floating point on your system, you may precompute
|
||||||
|
//this and store it as a table. It does preclude you from changing
|
||||||
|
//BASE_FREQ in runtime.
|
||||||
|
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
float frq = ( bf_table[i] * BASE_FREQ );
|
||||||
|
fbins[i] = ( 65536.0 ) / ( DFREQ ) * frq * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBinsForProgressiveIntegerSkippyInt( fbins );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
//Set up and initialize arrays.
|
||||||
|
for( i = 0; i < MAXNOTES; i++ )
|
||||||
|
{
|
||||||
|
note_peak_freqs[i] = 255;
|
||||||
|
note_peak_amps[i] = 0;
|
||||||
|
note_peak_amps2[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
folded_bins[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < FIXBINS; i++ )
|
||||||
|
{
|
||||||
|
fuzzed_bins[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Step 1: Initialize the Integer DFT.
|
||||||
|
SetupDFTProgressiveIntegerSkippy();
|
||||||
|
|
||||||
|
//Step 2: Set up the frequency list. You could do this multiple times
|
||||||
|
//if you want to change the loadout of the frequencies.
|
||||||
|
UpdateFreqs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleFrameInfo()
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
//Copy out the bins from the DFT to our fuzzed bins.
|
||||||
|
for( i = 0; i < FIXBINS; i++ )
|
||||||
|
{
|
||||||
|
fuzzed_bins[i] = (fuzzed_bins[i] + (embeddedbins[i]>>FUZZ_IIR_BITS) -
|
||||||
|
(fuzzed_bins[i]>>FUZZ_IIR_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Taper first octave
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
uint32_t taperamt = (65536 / FIXBPERO) * i;
|
||||||
|
fuzzed_bins[i] = (taperamt * fuzzed_bins[i]) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Taper last octave
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
int newi = FIXBINS - i - 1;
|
||||||
|
uint32_t taperamt = (65536 / FIXBPERO) * i;
|
||||||
|
fuzzed_bins[newi] = (taperamt * fuzzed_bins[newi]) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fold the bins from fuzzedbins into one octave.
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
folded_bins[i] = 0;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
for( j = 0; j < OCTAVES; j++ )
|
||||||
|
{
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
folded_bins[i] += fuzzed_bins[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now, we must blur the folded bins to get a good result.
|
||||||
|
//Sometimes you may notice every other bin being out-of
|
||||||
|
//line, and this fixes that. We may consider running this
|
||||||
|
//more than once, but in my experience, once is enough.
|
||||||
|
{
|
||||||
|
//Extra scoping because this is a large on-stack buffer.
|
||||||
|
uint16_t folded_out[FIXBPERO];
|
||||||
|
uint8_t adjLeft = FIXBPERO-1;
|
||||||
|
uint8_t adjRight = 1;
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
uint16_t lbin = folded_bins[adjLeft]>>2;
|
||||||
|
uint16_t rbin = folded_bins[adjRight]>>2;
|
||||||
|
uint16_t tbin = folded_bins[i]>>1;
|
||||||
|
folded_out[i] = lbin + rbin + tbin;
|
||||||
|
|
||||||
|
//We do this funny dance to avoid a modulus operation. On some
|
||||||
|
//processors, a modulus operation is slow. This is cheap.
|
||||||
|
adjLeft++; if( adjLeft == FIXBPERO ) adjLeft = 0;
|
||||||
|
adjRight++; if( adjRight == FIXBPERO ) adjRight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
folded_bins[i] = folded_out[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Next, we have to find the peaks, this is what "decompose" does in our
|
||||||
|
//normal tool. As a warning, it expects that the values in foolded_bins
|
||||||
|
//do NOT exceed 32767.
|
||||||
|
{
|
||||||
|
uint8_t adjLeft = FIXBPERO-1;
|
||||||
|
uint8_t adjRight = 1;
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
int16_t prev = folded_bins[adjLeft];
|
||||||
|
int16_t next = folded_bins[adjRight];
|
||||||
|
int16_t this = folded_bins[i];
|
||||||
|
uint8_t thisfreq = i<<SEMIBITSPERBIN;
|
||||||
|
int16_t offset;
|
||||||
|
adjLeft++; if( adjLeft == FIXBPERO ) adjLeft = 0;
|
||||||
|
adjRight++; if( adjRight == FIXBPERO ) adjRight = 0;
|
||||||
|
if( this < MIN_AMP_FOR_NOTE ) continue;
|
||||||
|
if( prev > this || next > this ) continue;
|
||||||
|
if( prev == this && next == this ) continue;
|
||||||
|
|
||||||
|
//i is at a peak...
|
||||||
|
int32_t totaldiff = (( this - prev ) + ( this - next ));
|
||||||
|
int32_t porpdiffP = ((this-prev)<<16) / totaldiff; //close to 0 =
|
||||||
|
//closer to this side, 32768 = in the middle, 65535 away.
|
||||||
|
int32_t porpdiffN = ((this-next)<<16) / totaldiff;
|
||||||
|
|
||||||
|
if( porpdiffP < porpdiffN )
|
||||||
|
{
|
||||||
|
//Closer to prev.
|
||||||
|
offset = -(32768 - porpdiffP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Closer to next
|
||||||
|
offset = (32768 - porpdiffN);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Need to round. That's what that extra +(15.. is in the center.
|
||||||
|
thisfreq += (offset+(1<<(15-SEMIBITSPERBIN)))>>(16-SEMIBITSPERBIN);
|
||||||
|
|
||||||
|
//In the event we went 'below zero' need to wrap to the top.
|
||||||
|
if( thisfreq > 255-(1<<SEMIBITSPERBIN) )
|
||||||
|
thisfreq = (1<<SEMIBITSPERBIN)*FIXBPERO - (256-thisfreq);
|
||||||
|
|
||||||
|
//printf( "Peak At: %3d /(%2d) %4d/%4d/%4d\n", thisfreq, i,prev, this, next );
|
||||||
|
|
||||||
|
//Okay, we have a peak, and a frequency. Now, we need to search
|
||||||
|
//through the existing notes to see if we have any matches.
|
||||||
|
//If we have a note that's close enough, we will try to pull it
|
||||||
|
//closer to us and boost it.
|
||||||
|
|
||||||
|
int8_t lowest_found_free_note = -1;
|
||||||
|
int8_t closest_note_id = -1;
|
||||||
|
int16_t closest_note_distance = 32767;
|
||||||
|
|
||||||
|
for( j = 0; j < MAXNOTES; j++ )
|
||||||
|
{
|
||||||
|
uint8_t nf = note_peak_freqs[j];
|
||||||
|
|
||||||
|
if( nf == 255 )
|
||||||
|
{
|
||||||
|
if( lowest_found_free_note == -1 )
|
||||||
|
lowest_found_free_note = j;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t distance = thisfreq - nf;
|
||||||
|
|
||||||
|
if( distance < 0 ) distance = -distance;
|
||||||
|
|
||||||
|
//Make sure that if we've wrapped around the right side of the
|
||||||
|
//array, we can detect it and loop it back.
|
||||||
|
if( distance > ((1<<(SEMIBITSPERBIN-1))*FIXBPERO) )
|
||||||
|
{
|
||||||
|
distance = ((1<<(SEMIBITSPERBIN))*FIXBPERO) - distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( distance < closest_note_distance )
|
||||||
|
{
|
||||||
|
closest_note_id = j;
|
||||||
|
closest_note_distance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t marked_note = -1;
|
||||||
|
|
||||||
|
if( closest_note_distance <= MAX_JUMP_DISTANCE )
|
||||||
|
{
|
||||||
|
//We found the note we need to augment.
|
||||||
|
//XXX: TODO: Should we be IIRing this?
|
||||||
|
|
||||||
|
note_peak_freqs[closest_note_id] = thisfreq;
|
||||||
|
marked_note = closest_note_id;
|
||||||
|
}
|
||||||
|
//The note was not found.
|
||||||
|
else if( lowest_found_free_note != -1 )
|
||||||
|
{
|
||||||
|
note_peak_freqs[lowest_found_free_note] = thisfreq;
|
||||||
|
marked_note = lowest_found_free_note;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now we need to handle combining notes.
|
||||||
|
for( i = 0; i < MAXNOTES; i++ )
|
||||||
|
for( j = 0; j < i; j++ )
|
||||||
|
{
|
||||||
|
//We'd be combining nf2 (j) into nf1 (i) if they're close enough.
|
||||||
|
uint8_t nf1 = note_peak_freqs[i];
|
||||||
|
uint8_t nf2 = note_peak_freqs[j];
|
||||||
|
int16_t distance = nf1 - nf2;
|
||||||
|
|
||||||
|
if( nf1 == 255 || nf2 == 255 ) continue;
|
||||||
|
|
||||||
|
if( distance < 0 ) distance = -distance;
|
||||||
|
|
||||||
|
if( distance > ((1<<(SEMIBITSPERBIN-1))*FIXBPERO) )
|
||||||
|
{
|
||||||
|
distance = ((1<<(SEMIBITSPERBIN))*FIXBPERO) - distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( distance > MAX_JUMP_DISTANCE * 2 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We need to combine the notes. We need to move the new note freq
|
||||||
|
//towards the stronger of the two notes.
|
||||||
|
int16_t amp1 = note_peak_amps[i];
|
||||||
|
int16_t amp2 = note_peak_amps[j];
|
||||||
|
|
||||||
|
//0 to 32768 porportional to how much of amp1 we want.
|
||||||
|
uint32_t porp = (amp1<<15) / (amp1+amp2);
|
||||||
|
uint16_t newnote = (nf1 * porp + nf2 * (32768-porp))>>15;
|
||||||
|
|
||||||
|
note_peak_amps[i] = amp1 + amp2;
|
||||||
|
note_peak_amps[j] = 0;
|
||||||
|
note_peak_freqs[i] = newnote;
|
||||||
|
note_peak_freqs[j] = 255;
|
||||||
|
note_peak_amps2[i] += note_peak_amps2[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for( i = 0; i < MAXNOTES; i++ )
|
||||||
|
{
|
||||||
|
if( note_peak_freqs[i] == 255 ) 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;
|
||||||
|
|
||||||
|
if( note_peak_amps[i] < MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR )
|
||||||
|
{
|
||||||
|
note_peak_freqs[i] = 255;
|
||||||
|
note_peak_amps[i] = 0;
|
||||||
|
note_peak_amps2[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//We now have notes!!!
|
||||||
|
/*
|
||||||
|
for( i = 0; i < MAXNOTES; i++ )
|
||||||
|
{
|
||||||
|
if( note_peak_freqs[i] == 255 ) continue;
|
||||||
|
printf( "(%3d %4d %4d) ", note_peak_freqs[i], note_peak_amps[i], note_peak_amps2[i] );
|
||||||
|
}
|
||||||
|
printf( "\n") ;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
for( i = 0; i < FIXBPERO; i++ )
|
||||||
|
{
|
||||||
|
printf( "%5d ", folded_bins[i] );
|
||||||
|
}
|
||||||
|
printf( "\n" );*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
53
embeddednf.h
Normal file
53
embeddednf.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef _EMBEDDEDNF_H
|
||||||
|
#define _EMBEDDEDNF_H
|
||||||
|
|
||||||
|
#include "dft.h"
|
||||||
|
|
||||||
|
#define DFREQ 8000
|
||||||
|
#define BASE_FREQ 55.0 // You may make this a float.
|
||||||
|
|
||||||
|
//The higher the number the slackier your FFT will be come.
|
||||||
|
#define FUZZ_IIR_BITS 1
|
||||||
|
|
||||||
|
//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
|
||||||
|
|
||||||
|
//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.
|
||||||
|
//note_frequency = 0..((1<<SEMIBITSPERBIN)*FIXBPERO-1)
|
||||||
|
#define SEMIBITSPERBIN 3
|
||||||
|
|
||||||
|
//This is the amplitude, coming from folded_bins. If the value is below this
|
||||||
|
//it is considered a non-note.
|
||||||
|
#define MIN_AMP_FOR_NOTE 128
|
||||||
|
|
||||||
|
//If there is detected note this far away from an established note, we will
|
||||||
|
//then consider this new note the same one as last time, and move the established
|
||||||
|
//note. This is also used when combining notes. It is this distance times two.
|
||||||
|
#define MAX_JUMP_DISTANCE 7
|
||||||
|
|
||||||
|
#define MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR 64
|
||||||
|
#define AMP_1_NERFING_BITS 5
|
||||||
|
#define AMP_2_NERFING_BITS 3
|
||||||
|
|
||||||
|
extern uint16_t folded_bins[]; //[FIXBPERO] <- The folded fourier output.
|
||||||
|
extern uint16_t fuzzed_bins[]; //[FIXBINS] <- The Full DFT after IIR, Blur and Taper
|
||||||
|
|
||||||
|
//[MAXNOTES] <- frequency of note; Note if it is == 255, then it means it is not set.
|
||||||
|
extern uint8_t note_peak_freqs[];
|
||||||
|
extern uint16_t note_peak_amps[]; //[MAXNOTES]
|
||||||
|
extern uint16_t note_peak_amps2[]; //[MAXNOTES] (Responds quicker)
|
||||||
|
|
||||||
|
//XXX: TODO: Consider doing the fuzz IIR on the folded bins. That way we can
|
||||||
|
//save several bytes of RAM on not having to keep fuzzed_bins around.
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void UpdateFreqs();
|
||||||
|
void HandleFrameInfo();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue