diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 464117fae8d..6af7f5526d1 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -72,7 +72,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)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __QADD16(a, b); #else uint32_t result = 0; @@ -93,12 +93,13 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { __attribute__((always_inline)) static inline uint32_t mult16signed(uint32_t val, int32_t lomul, int32_t himul) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) - lomul <<= 16; - himul <<= 16; + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP + // A level of 1.0 is 1 << 15, so shifting by 16 would overflow into the sign bit. + lomul <<= 15; + himul <<= 15; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits - enum { shift = 15 }; // shift is done automatically + enum { shift = 14 }; // smulw shifts by 16, so 14 more gives (val * mul) >> 15 __asm__ volatile ("smulwb %0, %1, %2" : "=r" (lo) : "r" (lomul), "r" (val)); __asm__ volatile ("smulwt %0, %1, %2" : "=r" (hi) : "r" (himul), "r" (val)); __asm__ volatile ("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); @@ -108,9 +109,8 @@ static inline uint32_t mult16signed(uint32_t val, int32_t lomul, int32_t himul) #else uint32_t result = 0; for (int8_t i = 0; i < 2; i++) { - float mod_mul = (float)(i ? himul : lomul) / (float)((1 << 15) - 1); int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); - int32_t intermediate = (int32_t)(ai * mod_mul); + int32_t intermediate = (ai * (i ? himul : lomul)) >> 15; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { @@ -124,7 +124,7 @@ static inline uint32_t mult16signed(uint32_t val, int32_t lomul, int32_t himul) } static inline uint32_t tounsigned8(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __UADD8(val, 0x80808080); #else return val ^ 0x80808080; @@ -132,7 +132,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)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __UADD16(val, 0x80008000); #else return val ^ 0x80008000; @@ -140,7 +140,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)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __UADD16(val, 0x80008000); #else return val ^ 0x80008000; @@ -156,7 +156,7 @@ static inline uint32_t pack8(uint32_t val) { } static inline uint32_t copy16lsb(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __PKHBT(val, val, 16); #else val &= 0x0000ffff; @@ -165,7 +165,7 @@ static inline uint32_t copy16lsb(uint32_t val) { } static inline uint32_t copy16msb(uint32_t val) { - #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) + #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP return __PKHTB(val, val, 16); #else val &= 0xffff0000; @@ -259,9 +259,9 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, uint16_t left_panning_scaled = 32768, right_panning_scaled = 32768; if (MP_LIKELY(self->base.channel_count == 2)) { if (panning >= 0) { - left_panning_scaled = 32767 - panning; + left_panning_scaled = 32768 - panning; } else { - right_panning_scaled = 32767 + panning; + right_panning_scaled = 32768 + panning; } }