summaryrefslogtreecommitdiff
path: root/apps/plugins/fft/fft.c
diff options
context:
space:
mode:
authorDelyan Kratunov <delyan.kratunov@gmail.com>2010-05-02 20:30:44 +0000
committerDelyan Kratunov <delyan.kratunov@gmail.com>2010-05-02 20:30:44 +0000
commitaf466f3cbfc718c0539f2cf7743d614ecf6cd159 (patch)
treea7ac350f1e5a21cc1a53849766d0200ae3eecb7a /apps/plugins/fft/fft.c
parent7f9d30ba3eb97cf8b304b0d546f1b3311cc1ffae (diff)
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
Diffstat (limited to 'apps/plugins/fft/fft.c')
-rw-r--r--apps/plugins/fft/fft.c35
1 files changed, 21 insertions, 14 deletions
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)