From 0b212e22431f8e04fcbea96bf444529f2590581b Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Thu, 25 Mar 2021 17:30:40 -0500 Subject: [PATCH 1/4] Add non M4 audiomixer support --- ports/raspberrypi/mpconfigport.mk | 3 +-- shared-module/audiomixer/Mixer.c | 44 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index bcfe3efd1e..f37a7765a3 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -46,8 +46,7 @@ CIRCUITPY_AUDIOBUSIO ?= 1 CIRCUITPY_AUDIOCORE ?= 1 CIRCUITPY_AUDIOPWMIO ?= 1 -# These libraries require Cortex M4+ for fancy math instructions. -CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_AUDIOMIXER = 1 INTERNAL_LIBM = 1 diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index fdcd2dbfbf..2c524b3bfe 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -103,11 +103,28 @@ void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t *self, __attribute__((always_inline)) static inline uint32_t add16signed(uint32_t a, uint32_t b) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU return __QADD16(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + int16_t ai = a >> (sizeof(int16_t) * 8 * i); + int16_t bi = b >> (sizeof(int16_t) * 8 * i); + int32_t intermediate = (int32_t)ai + bi / 2; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t)intermediate) & 0xffff) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif } __attribute__((always_inline)) static inline uint32_t mult16signed(uint32_t val, int32_t mul) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU mul <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits @@ -118,18 +135,45 @@ static inline uint32_t mult16signed(uint32_t val, int32_t mul) { asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); asm volatile ("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack return val; + #else + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1 << 15) - 1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t)intermediate) + 0x8000) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif } static inline uint32_t tounsigned8(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU return __UADD8(val, 0x80808080); + #else + return val ^ 0x80808080; + #endif } static inline uint32_t tounsigned16(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU return __UADD16(val, 0x80008000); + #else + return val ^ 0x80008000; + #endif } static inline uint32_t tosigned16(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU return __UADD16(val, 0x80008000); + #else + return val ^ 0x80008000; + #endif } static inline uint32_t unpack8(uint16_t val) { From 9bf4b4d81e230edb636f4e1403603e4c479890e2 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Fri, 2 Apr 2021 16:47:25 -0500 Subject: [PATCH 2/4] Fixes to math for level calculations --- shared-module/audiomixer/Mixer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 2c524b3bfe..f91f5e18d3 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -110,7 +110,7 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { for (int8_t i = 0; i < 2; i++) { int16_t ai = a >> (sizeof(int16_t) * 8 * i); int16_t bi = b >> (sizeof(int16_t) * 8 * i); - int32_t intermediate = (int32_t)ai + bi / 2; + int32_t intermediate = (int32_t)ai + bi; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { @@ -139,14 +139,15 @@ static inline uint32_t mult16signed(uint32_t val, int32_t mul) { uint32_t result = 0; float mod_mul = (float)mul / (float)((1 << 15) - 1); for (int8_t i = 0; i < 2; i++) { - int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); int32_t intermediate = ai * mod_mul; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { intermediate = SHRT_MIN; } - result |= (((uint32_t)intermediate) + 0x8000) << (sizeof(int16_t) * 8 * i); + intermediate &= 0x0000FFFF; + result |= (((uint32_t)intermediate)) << (sizeof(int16_t) * 8 * i); } return result; #endif From 7ace53f22cb90687ae10a16e10254ca4992a3644 Mon Sep 17 00:00:00 2001 From: Mark <56205165+gamblor21@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:35:55 -0500 Subject: [PATCH 3/4] Remove comment for define being M4 only it can be M7 too Co-authored-by: Scott Shawcroft --- shared-module/audiomixer/Mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index f91f5e18d3..9b2f6ef6a7 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -103,7 +103,7 @@ void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t *self, __attribute__((always_inline)) static inline uint32_t add16signed(uint32_t a, uint32_t b) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __QADD16(a, b); #else uint32_t result = 0; From cd8deb0b720424afc950b37d84eb21d1a8b511a2 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 13 Apr 2021 17:36:14 -0500 Subject: [PATCH 4/4] Removed all the M4 comments --- shared-module/audiomixer/Mixer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 9b2f6ef6a7..20731933c4 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -124,7 +124,7 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { __attribute__((always_inline)) static inline uint32_t mult16signed(uint32_t val, int32_t mul) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) mul <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits @@ -154,7 +154,7 @@ static inline uint32_t mult16signed(uint32_t val, int32_t mul) { } static inline uint32_t tounsigned8(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD8(val, 0x80808080); #else return val ^ 0x80808080; @@ -162,7 +162,7 @@ static inline uint32_t tounsigned8(uint32_t val) { } static inline uint32_t tounsigned16(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD16(val, 0x80008000); #else return val ^ 0x80008000; @@ -170,7 +170,7 @@ static inline uint32_t tounsigned16(uint32_t val) { } static inline uint32_t tosigned16(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) // Cortex-M4 w/FPU + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD16(val, 0x80008000); #else return val ^ 0x80008000;