| #include "edge-impulse-sdk/dsp/config.hpp" |
| #if EIDSP_LOAD_CMSIS_DSP_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/transform_functions.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/statistics_functions.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/basic_math_functions.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/complex_math_functions.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/fast_math_functions.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/matrix_functions.h" |
|
|
| |
| #define LOG2TOLOG_Q15 0x02C5C860 |
| #define MICRO_Q15 0x00000219 |
| #define SHIFT_MELFILTER_SATURATION_Q15 10 |
| |
| |
| |
|
|
|
|
|
|
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| arm_status arm_mfcc_q15( |
| const arm_mfcc_instance_q15 * S, |
| q15_t *pSrc, |
| q15_t *pDst, |
| q31_t *pTmp |
| ) |
| { |
| q15_t m; |
| uint32_t index; |
| uint32_t fftShift=0; |
| q31_t logExponent; |
| q63_t result; |
| arm_matrix_instance_q15 pDctMat; |
| uint32_t i; |
| uint32_t coefsPos; |
| uint32_t filterLimit; |
| q15_t *pTmp2=(q15_t*)pTmp; |
|
|
| arm_status status = ARM_MATH_SUCCESS; |
| |
| |
| arm_absmax_q15(pSrc,S->fftLen,&m,&index); |
|
|
| if (m !=0) |
| { |
| q15_t quotient; |
| int16_t shift; |
|
|
| status = arm_divide_q15(0x7FFF,m,"ient,&shift); |
| if (status != ARM_MATH_SUCCESS) |
| { |
| return(status); |
| } |
| |
| arm_scale_q15(pSrc,quotient,shift,pSrc,S->fftLen); |
| } |
|
|
|
|
| |
| arm_mult_q15(pSrc,S->windowCoefs, pSrc, S->fftLen); |
|
|
|
|
| |
| |
| fftShift = 31 - __CLZ(S->fftLen); |
| #if defined(ARM_MFCC_CFFT_BASED) |
| |
| |
| |
| |
| |
| |
| |
| |
| for(i=0; i < S->fftLen ; i++) |
| { |
| pTmp2[2*i] = pSrc[i]; |
| pTmp2[2*i+1] = 0; |
| } |
| arm_cfft_q15(&(S->cfft),pTmp2,0,1); |
| #else |
| |
| arm_rfft_q15(&(S->rfft),pSrc,pTmp2); |
| #endif |
| filterLimit = 1 + (S->fftLen >> 1); |
|
|
|
|
| |
| arm_cmplx_mag_q15(pTmp2,pSrc,filterLimit); |
| |
|
|
| |
| coefsPos = 0; |
| for(i=0; i<S->nbMelFilters; i++) |
| { |
| arm_dot_prod_q15(pSrc+S->filterPos[i], |
| &(S->filterCoefs[coefsPos]), |
| S->filterLengths[i], |
| &result); |
|
|
| coefsPos += S->filterLengths[i]; |
|
|
| |
| result += MICRO_Q15; |
| result >>= SHIFT_MELFILTER_SATURATION_Q15; |
| |
| pTmp[i] = __SSAT(result,31) ; |
|
|
| } |
|
|
|
|
| |
| |
| arm_vlog_q31(pTmp,pTmp,S->nbMelFilters); |
|
|
|
|
| |
| |
| logExponent = fftShift + 2 + SHIFT_MELFILTER_SATURATION_Q15; |
| logExponent = logExponent * LOG2TOLOG_Q15; |
|
|
|
|
| |
| arm_offset_q31(pTmp,logExponent,pTmp,S->nbMelFilters); |
| arm_shift_q31(pTmp,-19,pTmp,S->nbMelFilters); |
| for(i=0; i<S->nbMelFilters; i++) |
| { |
| pSrc[i] = __SSAT((q15_t)pTmp[i],16); |
| } |
|
|
| |
|
|
| pDctMat.numRows=S->nbDctOutputs; |
| pDctMat.numCols=S->nbMelFilters; |
| pDctMat.pData=(q15_t*)S->dctCoefs; |
|
|
| arm_mat_vec_mult_q15(&pDctMat, pSrc, pDst); |
|
|
| return(status); |
| } |
|
|
| |
| |
| |
|
|
| #endif |
|
|