FFT Plugin: Revamp the main code to rid it of 64-bit math. Use 32-bit kiss_fft_scalar because 16-bit integers are generally a poor choice for computation on-target. Simplify display code to speed it up. Add logarithmic frequency display (need keymappings, guessed on some). On dual-core, perform FFT on COP. Add some support function to fixedpoint.c. ... and stuff.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26470 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
bbe6c5a5e2
commit
30e2f42c82
6 changed files with 999 additions and 788 deletions
|
@ -171,6 +171,35 @@ long fp_sqrt(long x, unsigned int fracbits)
|
|||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Accurate int sqrt with only elementary operations. (the above
|
||||
* routine fails badly without enough iterations, more iterations
|
||||
* than this requires -- [give that one a FIXME]).
|
||||
* Snagged from:
|
||||
* http://www.devmaster.net/articles/fixed-point-optimizations/ */
|
||||
unsigned long isqrt(unsigned long x)
|
||||
{
|
||||
/* Adding CLZ could optimize this further */
|
||||
unsigned long g = 0;
|
||||
int bshift = 15;
|
||||
unsigned long b = 1ul << bshift;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned long temp = (g + g + b) << bshift;
|
||||
|
||||
if (x > temp)
|
||||
{
|
||||
g += b;
|
||||
x -= temp;
|
||||
}
|
||||
|
||||
b >>= 1;
|
||||
}
|
||||
while (bshift--);
|
||||
|
||||
return g;
|
||||
}
|
||||
#endif /* PLUGIN or CODEC */
|
||||
|
||||
|
||||
|
@ -256,6 +285,44 @@ long fp16_log(int x) {
|
|||
y-=x>>15;
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed-point exponential
|
||||
* taken from http://www.quinapalus.com/efunc.html
|
||||
* "The code assumes integers are at least 32 bits long. The (non-negative)
|
||||
* argument and the result of the function are both expressed as fixed-point
|
||||
* values with 16 fractional bits. Notice that after 11 steps of the
|
||||
* algorithm the constants involved become such that the code is simply
|
||||
* doing a multiplication: this is explained in the note below.
|
||||
* The extension to negative arguments is left as an exercise."
|
||||
*/
|
||||
long fp16_exp(int x)
|
||||
{
|
||||
int t,y;
|
||||
|
||||
y=0x00010000;
|
||||
t=x-0x58b91; if(t>=0) x=t,y<<=8;
|
||||
t=x-0x2c5c8; if(t>=0) x=t,y<<=4;
|
||||
t=x-0x162e4; if(t>=0) x=t,y<<=2;
|
||||
t=x-0x0b172; if(t>=0) x=t,y<<=1;
|
||||
t=x-0x067cd; if(t>=0) x=t,y+=y>>1;
|
||||
t=x-0x03920; if(t>=0) x=t,y+=y>>2;
|
||||
t=x-0x01e27; if(t>=0) x=t,y+=y>>3;
|
||||
t=x-0x00f85; if(t>=0) x=t,y+=y>>4;
|
||||
t=x-0x007e1; if(t>=0) x=t,y+=y>>5;
|
||||
t=x-0x003f8; if(t>=0) x=t,y+=y>>6;
|
||||
t=x-0x001fe; if(t>=0) x=t,y+=y>>7;
|
||||
if(x&0x100) y+=y>>8;
|
||||
if(x&0x080) y+=y>>9;
|
||||
if(x&0x040) y+=y>>10;
|
||||
if(x&0x020) y+=y>>11;
|
||||
if(x&0x010) y+=y>>12;
|
||||
if(x&0x008) y+=y>>13;
|
||||
if(x&0x004) y+=y>>14;
|
||||
if(x&0x002) y+=y>>15;
|
||||
if(x&0x001) y+=y>>16;
|
||||
return y;
|
||||
}
|
||||
#endif /* PLUGIN */
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,10 +18,10 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||
fixed or floating point complex numbers. It also delares the kf_ internal functions.
|
||||
*/
|
||||
|
||||
static kiss_fft_cpx *scratchbuf=NULL;
|
||||
static size_t nscratchbuf=0;
|
||||
static kiss_fft_cpx *tmpbuf=NULL;
|
||||
static size_t ntmpbuf=0;
|
||||
static kiss_fft_cpx *scratchbuf SHAREDBSS_ATTR = NULL;
|
||||
static size_t nscratchbuf SHAREDBSS_ATTR = 0;
|
||||
static kiss_fft_cpx *tmpbuf SHAREDBSS_ATTR = NULL;
|
||||
static size_t ntmpbuf SHAREDBSS_ATTR = 0;
|
||||
|
||||
#define CHECKBUF(buf,nbuf,n) \
|
||||
do { \
|
||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
|||
|
||||
#ifdef FIXED_POINT
|
||||
#include <inttypes.h>
|
||||
# if (FIXED_POINT == 32)
|
||||
# if 1 /* 16-bit data is _slow_ on devices (FIXED_POINT == 32) */
|
||||
# define kiss_fft_scalar int32_t
|
||||
# else
|
||||
# define kiss_fft_scalar int16_t
|
||||
|
|
|
@ -48,12 +48,11 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme
|
|||
for (i = 0; i < nfft/2; ++i) {
|
||||
/*double phase =
|
||||
-3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);*/
|
||||
if (inverse_fft)
|
||||
{
|
||||
if (inverse_fft) {
|
||||
DEBUGF("Inverse FFT not implemented!"); /*phase *= -1;*/
|
||||
}
|
||||
}
|
||||
|
||||
kf_cexp_round (st->super_twiddles+i, i+1, nfft);
|
||||
kf_cexp_round (st->super_twiddles+i, i+1, nfft);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,9 @@ long fp_sqrt(long a, unsigned int fracbits);
|
|||
long fp14_cos(int val);
|
||||
long fp14_sin(int val);
|
||||
long fp16_log(int x);
|
||||
long fp16_exp(int x);
|
||||
|
||||
unsigned long isqrt(unsigned long x);
|
||||
|
||||
/* fast unsigned multiplication (16x16bit->32bit or 32x32bit->32bit,
|
||||
* whichever is faster for the architecture) */
|
||||
|
|
Loading…
Reference in a new issue