From af466f3cbfc718c0539f2cf7743d614ecf6cd159 Mon Sep 17 00:00:00 2001 From: Delyan Kratunov Date: Sun, 2 May 2010 20:30:44 +0000 Subject: FFT plugin: eliminate 64-bit math. This should result in faster and probably more accurate calculations. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25790 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/fft/SOURCES | 1 - apps/plugins/fft/fft.c | 35 +++++++++++++++++++++-------------- apps/plugins/fft/math.h | 8 -------- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/apps/plugins/fft/SOURCES b/apps/plugins/fft/SOURCES index 07fb013eaa..ebe5f3067b 100644 --- a/apps/plugins/fft/SOURCES +++ b/apps/plugins/fft/SOURCES @@ -1,4 +1,3 @@ kiss_fft.c kiss_fftr.c fft.c -math.c diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c index ae07179557..acc19fabe5 100644 --- a/apps/plugins/fft/fft.c +++ b/apps/plugins/fft/fft.c @@ -307,8 +307,8 @@ struct { /************************* End of globals *************************/ /************************* Math functions *************************/ -#define QLOG_MAX 286286 -#define QLIN_MAX 1534588906 +#define QLOG_MAX 0x00040000 +#define QLIN_MAX 0x5B000000 #define QLN_10 float_q16(2.302585093) #define LIN_MAX (QLIN_MAX >> 16) @@ -350,24 +350,31 @@ void apply_window_func(char mode) /* Calculates the magnitudes from complex numbers and returns the maximum */ int32_t calc_magnitudes(bool logarithmic) { - int64_t tmp; + /* A major assumption made when calculating the Q*MAX constants + * is that the maximum magnitude is 29 bits long. */ + + uint32_t tmp; size_t i; - int32_t max = -2147483647; - - /* Calculate the magnitude, discarding the phase. - * The sum of the squares can easily overflow the 15-bit (s15.16) - * requirement for fsqrt, so we scale the data down */ + int32_t max = 0; + + /* Calculate the magnitude, discarding the phase. */ for (i = 0; i < ARRAYSIZE_PLOT; ++i) { tmp = output[i].r * output[i].r + output[i].i * output[i].i; - tmp <<= 16; - - tmp = fsqrt64(tmp, 16); - - if (logarithmic) - tmp = get_log_value(tmp & 0x7FFFFFFF); + if (tmp > 0x7FFFFFFF) tmp >>= 1; /* if our assumptions are correct, + this should never happen. It's just + a safeguard. */ + if (tmp > 0) + { + tmp = fp_sqrt(tmp, 0); /* linear scaling, nothing + bad should happen */ + tmp <<= 16; + if (logarithmic) + tmp = get_log_value(tmp);/* the log function + expects s15.16 values */ + } plot[i] = tmp; if (plot[i] > max) diff --git a/apps/plugins/fft/math.h b/apps/plugins/fft/math.h index 450b9aafcb..ffacf1eedb 100644 --- a/apps/plugins/fft/math.h +++ b/apps/plugins/fft/math.h @@ -17,12 +17,4 @@ #define float_q15(a) float_q(a, 15) #define float_q16(a) float_q(a, 16) -/** - * Fixed point square root via Newton-Raphson. - * @param a square root argument. - * @param fracbits specifies number of fractional bits in argument. - * @return Square root of argument in same fixed point format as input. - */ -int64_t fsqrt64(int64_t a, unsigned int fracbits); - #endif -- cgit v1.2.3