From cf95f18880d2bf68eccacd7a3682044e988db620 Mon Sep 17 00:00:00 2001 From: George Norton Date: Thu, 22 Jun 2023 20:46:58 +0100 Subject: [PATCH] Increase the max fix16 size to -32.0..32.0 as it seems it is possible to create coefficients which are >16. --- firmware/code/fix16.c | 9 +++++---- firmware/code/fix16.h | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/firmware/code/fix16.c b/firmware/code/fix16.c index 53d0b98..50f05d9 100644 --- a/firmware/code/fix16.c +++ b/firmware/code/fix16.c @@ -61,15 +61,15 @@ fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) { } #else fix16_t fix16_from_s16sample(int16_t a) { - return a * fix16_one_normalized; + return a * fix16_lsb; } int16_t fix16_to_s16sample(fix16_t a) { // Handle rounding up front, adding one can cause an overflow/underflow if (a < 0) { - a -= (fix16_one_normalized >> 1); + a -= (fix16_lsb >> 1); } else { - a += (fix16_one_normalized >> 1); + a += (fix16_lsb >> 1); } // Saturate the value if an overflow has occurred @@ -100,9 +100,10 @@ double fix16_to_dbl(fix16_t a) { // We work in 64bits then shift the result to get // the bit representing 1 back into the correct position. +// i.e. 1*1 == 1, so 20000000^2 >> 25 = 20000000 fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) { const int64_t product = (int64_t)inArg0 * inArg1; - fix16_t result = product >> 29; + fix16_t result = product >> 25; // Handle rounding where we are choppping off low order bits // Disabled for now, too much load. We get crackling when adjusting // the volume. diff --git a/firmware/code/fix16.h b/firmware/code/fix16.h index d1528af..42b0c03 100644 --- a/firmware/code/fix16.h +++ b/firmware/code/fix16.h @@ -30,18 +30,18 @@ #ifdef USE_DOUBLE typedef double fix16_t; static const fix16_t fix16_zero = 0; +static const fix16_t fix16_one = 1; #else -// We normalize all values into the range -1..1 with 1 extra bit for overflows +// We normalize all values into the range -32..32 with 1 extra bit for overflows // and one bit for the sign. We allow fixed point values to overflow, but they // are clipped at the point they are written back to a s16sample. // // The reason for normalizing the samples is because the filter coefficients are -// small (usually in the range -1..1), by normalizing everything the coefficients +// small (usually well within in the range -32..32), by normalizing everything the coefficients // get lots of additional bits of precision. typedef int32_t fix16_t; -static const fix16_t fix16_overflow = 0x80000000; -static const fix16_t fix16_one_normalized = 0x00008000; -static const fix16_t fix16_one = 0x20000000; +static const fix16_t fix16_lsb = 0x8000; +static const fix16_t fix16_one = 0x002000000; static const fix16_t fix16_zero = 0x00000000; #endif