From 60a8c8805cf78b766dbb8f6d1e0cd22534a6c102 Mon Sep 17 00:00:00 2001 From: Christophe Favergeon Date: Wed, 19 Jul 2023 15:07:40 +0200 Subject: [PATCH] Corrected rescaling issue in the implementation of the MFCCs --- .../ComplexMathFunctions/arm_cmplx_mag_q15.c | 23 +++++++++---------- Source/TransformFunctions/arm_mfcc_f16.c | 9 +++++++- Source/TransformFunctions/arm_mfcc_f32.c | 9 +++++++- Source/TransformFunctions/arm_mfcc_q15.c | 7 ++++-- Source/TransformFunctions/arm_mfcc_q31.c | 8 +++++-- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c b/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c index 10ce3350..4038ab84 100644 --- a/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c +++ b/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c @@ -131,7 +131,7 @@ void arm_cmplx_mag_q15( acc0 = __SMUAD(in, in); /* store result in 2.14 format in destination buffer. */ - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; @@ -170,22 +170,22 @@ void arm_cmplx_mag_q15( in = read_q15x2_ia (&pSrc); acc0 = __SMUAD(in, in); /* store result in 2.14 format in destination buffer. */ - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; in = read_q15x2_ia (&pSrc); acc0 = __SMUAD(in, in); - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; in = read_q15x2_ia (&pSrc); acc0 = __SMUAD(in, in); - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; in = read_q15x2_ia (&pSrc); acc0 = __SMUAD(in, in); - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; #else real = *pSrc++; @@ -194,28 +194,28 @@ void arm_cmplx_mag_q15( acc1 = ((q31_t) imag * imag); /* store result in 2.14 format in destination buffer. */ - arm_sqrt_q31((acc0 + acc1) >> 1 , &res); + arm_sqrt_q31(((uint32_t)acc0 + (uint32_t)acc1) >> 1 , &res); *pDst++ = res >> 16; real = *pSrc++; imag = *pSrc++; acc0 = ((q31_t) real * real); acc1 = ((q31_t) imag * imag); - arm_sqrt_q31((acc0 + acc1) >> 1 , &res); + arm_sqrt_q31(((uint32_t)acc0 + (uint32_t)acc1) >> 1 , &res); *pDst++ = res >> 16; real = *pSrc++; imag = *pSrc++; acc0 = ((q31_t) real * real); acc1 = ((q31_t) imag * imag); - arm_sqrt_q31((acc0 + acc1) >> 1 , &res); + arm_sqrt_q31(((uint32_t)acc0 + (uint32_t)acc1) >> 1 , &res); *pDst++ = res >> 16; real = *pSrc++; imag = *pSrc++; acc0 = ((q31_t) real * real); acc1 = ((q31_t) imag * imag); - arm_sqrt_q31((acc0 + acc1) >> 1 , &res); + arm_sqrt_q31(((uint32_t)acc0 + (uint32_t)acc1) >> 1 , &res); *pDst++ = res >> 16; #endif /* #if defined (ARM_MATH_DSP) */ @@ -240,9 +240,8 @@ void arm_cmplx_mag_q15( #if defined (ARM_MATH_DSP) in = read_q15x2_ia (&pSrc); acc0 = __SMUAD(in, in); - /* store result in 2.14 format in destination buffer. */ - arm_sqrt_q31(acc0 >> 1 , &res); + arm_sqrt_q31((uint32_t)acc0 >> 1 , &res); *pDst++ = res >> 16; #else real = *pSrc++; @@ -251,7 +250,7 @@ void arm_cmplx_mag_q15( acc1 = ((q31_t) imag * imag); /* store result in 2.14 format in destination buffer. */ - arm_sqrt_q31((acc0 + acc1) >> 1 , &res); + arm_sqrt_q31(((uint32_t)acc0 + (uint32_t)acc1) >> 1 , &res); *pDst++ = res >> 16; #endif diff --git a/Source/TransformFunctions/arm_mfcc_f16.c b/Source/TransformFunctions/arm_mfcc_f16.c index 327f1dd8..e12b3760 100755 --- a/Source/TransformFunctions/arm_mfcc_f16.c +++ b/Source/TransformFunctions/arm_mfcc_f16.c @@ -94,7 +94,10 @@ void arm_mfcc_f16( /* Normalize */ arm_absmax_f16(pSrc,S->fftLen,&maxValue,&index); - arm_scale_f16(pSrc,1.0f16/(_Float16)maxValue,pSrc,S->fftLen); + if ((_Float16)maxValue != 0.0f16) + { + arm_scale_f16(pSrc,1.0f16/(_Float16)maxValue,pSrc,S->fftLen); + } /* Multiply by window */ arm_mult_f16(pSrc,S->windowCoefs,pSrc,S->fftLen); @@ -125,6 +128,10 @@ void arm_mfcc_f16( pTmp[1]=0.0f; #endif arm_cmplx_mag_f16(pTmp,pSrc,S->fftLen); + if ((_Float16)maxValue != 0.0f16) + { + arm_scale_f16(pSrc,maxValue,pSrc,S->fftLen); + } /* Apply MEL filters */ for(i=0; inbMelFilters; i++) diff --git a/Source/TransformFunctions/arm_mfcc_f32.c b/Source/TransformFunctions/arm_mfcc_f32.c index a8df9cc2..db1bfda6 100755 --- a/Source/TransformFunctions/arm_mfcc_f32.c +++ b/Source/TransformFunctions/arm_mfcc_f32.c @@ -84,7 +84,10 @@ void arm_mfcc_f32( /* Normalize */ arm_absmax_f32(pSrc,S->fftLen,&maxValue,&index); - arm_scale_f32(pSrc,1.0f/maxValue,pSrc,S->fftLen); + if (maxValue != 0.0f) + { + arm_scale_f32(pSrc,1.0f/maxValue,pSrc,S->fftLen); + } /* Multiply by window */ arm_mult_f32(pSrc,S->windowCoefs,pSrc,S->fftLen); @@ -115,6 +118,10 @@ void arm_mfcc_f32( pTmp[1]=0.0f; #endif arm_cmplx_mag_f32(pTmp,pSrc,S->fftLen); + if (maxValue != 0.0f) + { + arm_scale_f32(pSrc,maxValue,pSrc,S->fftLen); + } /* Apply MEL filters */ for(i=0; inbMelFilters; i++) diff --git a/Source/TransformFunctions/arm_mfcc_q15.c b/Source/TransformFunctions/arm_mfcc_q15.c index 7512afd1..ba7acd0b 100755 --- a/Source/TransformFunctions/arm_mfcc_q15.c +++ b/Source/TransformFunctions/arm_mfcc_q15.c @@ -72,7 +72,6 @@ point computations may saturate. */ - arm_status arm_mfcc_q15( const arm_mfcc_instance_q15 * S, q15_t *pSrc, @@ -163,7 +162,11 @@ arm_status arm_mfcc_q15( } - + if (m != 0) + { + arm_scale_q31(pTmp,m<<16,0,pTmp,S->nbMelFilters); + } + // q34.29 - fftShift - satShift /* Compute the log */ arm_vlog_q31(pTmp,pTmp,S->nbMelFilters); diff --git a/Source/TransformFunctions/arm_mfcc_q31.c b/Source/TransformFunctions/arm_mfcc_q31.c index 3a497b4f..5acd61e1 100755 --- a/Source/TransformFunctions/arm_mfcc_q31.c +++ b/Source/TransformFunctions/arm_mfcc_q31.c @@ -73,7 +73,6 @@ */ - arm_status arm_mfcc_q31( const arm_mfcc_instance_q31 * S, q31_t *pSrc, @@ -155,6 +154,7 @@ arm_status arm_mfcc_q31( S->filterLengths[i], &result); + coefsPos += S->filterLengths[i]; // q16.48 - fftShift @@ -165,7 +165,11 @@ arm_status arm_mfcc_q31( } - + if (m != 0) + { + arm_scale_q31(pTmp,m,0,pTmp,S->nbMelFilters); + } + // q16.29 - fftShift - satShift /* Compute the log */ arm_vlog_q31(pTmp,pTmp,S->nbMelFilters);