| #include "edge-impulse-sdk/dsp/config.hpp" |
| #if EIDSP_LOAD_CMSIS_DSP_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/transform_functions_f16.h" |
| #include "edge-impulse-sdk/CMSIS/DSP/Include/arm_common_tables_f16.h" |
|
|
| #if defined(ARM_FLOAT16_SUPPORTED) |
|
|
|
|
| #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE) |
|
|
| void stage_rfft_f16( |
| const arm_rfft_fast_instance_f16 * S, |
| float16_t * p, |
| float16_t * pOut) |
| { |
| int32_t k; |
| float16_t twR, twI; |
| const float16_t * pCoeff = S->pTwiddleRFFT; |
| float16_t *pA = p; |
| float16_t *pB = p; |
| float16_t xAR, xAI, xBR, xBI; |
| float16_t t1a, t1b; |
| float16_t p0, p1, p2, p3; |
|
|
| float16x8x2_t tw,xA,xB; |
| float16x8x2_t tmp1, tmp2, res; |
|
|
| uint16x8_t vecStridesBkwd; |
|
|
| vecStridesBkwd = vddupq_u16((uint16_t)14, 2); |
|
|
|
|
| int blockCnt; |
|
|
|
|
| k = (S->Sint).fftLen - 1; |
|
|
| |
|
|
| xBR = pB[0]; |
| xBI = pB[1]; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++ ; |
| twI = *pCoeff++ ; |
|
|
| |
| t1a = (_Float16)xBR + (_Float16)xAR ; |
|
|
| |
| t1b = (_Float16)xBI + (_Float16)xAI ; |
|
|
| |
| |
| *pOut++ = 0.5f16 * ( (_Float16)t1a + (_Float16)t1b ); |
| *pOut++ = 0.5f16 * ( (_Float16)t1a - (_Float16)t1b ); |
|
|
| |
| pB = p + 2*k - 14; |
| pA += 2; |
|
|
| blockCnt = k >> 3; |
| while (blockCnt > 0) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| xA = vld2q_f16(pA); |
| pA += 16; |
|
|
| xB = vld2q_f16(pB); |
|
|
| xB.val[0] = vldrhq_gather_shifted_offset_f16(pB, vecStridesBkwd); |
| xB.val[1] = vldrhq_gather_shifted_offset_f16(&pB[1], vecStridesBkwd); |
|
|
| xB.val[1] = vnegq_f16(xB.val[1]); |
| pB -= 16; |
|
|
|
|
| tw = vld2q_f16(pCoeff); |
| pCoeff += 16; |
|
|
|
|
| tmp1.val[0] = vaddq_f16(xA.val[0],xB.val[0]); |
| tmp1.val[1] = vaddq_f16(xA.val[1],xB.val[1]); |
|
|
| tmp2.val[0] = vsubq_f16(xB.val[0],xA.val[0]); |
| tmp2.val[1] = vsubq_f16(xB.val[1],xA.val[1]); |
|
|
| res.val[0] = vmulq(tw.val[0], tmp2.val[0]); |
| res.val[0] = vfmsq(res.val[0],tw.val[1], tmp2.val[1]); |
|
|
| res.val[1] = vmulq(tw.val[0], tmp2.val[1]); |
| res.val[1] = vfmaq(res.val[1], tw.val[1], tmp2.val[0]); |
|
|
| res.val[0] = vaddq_f16(res.val[0],tmp1.val[0] ); |
| res.val[1] = vaddq_f16(res.val[1],tmp1.val[1] ); |
|
|
| res.val[0] = vmulq_n_f16(res.val[0], 0.5f); |
| res.val[1] = vmulq_n_f16(res.val[1], 0.5f); |
|
|
|
|
| vst2q_f16(pOut, res); |
| pOut += 16; |
|
|
| |
| blockCnt--; |
| } |
|
|
| pB += 14; |
| blockCnt = k & 7; |
| while (blockCnt > 0) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| xBI = pB[1]; |
| xBR = pB[0]; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++; |
| twI = *pCoeff++; |
|
|
| t1a = (_Float16)xBR - (_Float16)xAR ; |
| t1b = (_Float16)xBI + (_Float16)xAI ; |
|
|
| |
| |
| p0 = (_Float16)twR * (_Float16)t1a; |
| p1 = (_Float16)twI * (_Float16)t1a; |
| p2 = (_Float16)twR * (_Float16)t1b; |
| p3 = (_Float16)twI * (_Float16)t1b; |
|
|
| *pOut++ = 0.5f16 * ((_Float16)xAR + (_Float16)xBR + (_Float16)p0 + (_Float16)p3 ); |
| *pOut++ = 0.5f16 * ((_Float16)xAI - (_Float16)xBI + (_Float16)p1 - (_Float16)p2 ); |
|
|
| pA += 2; |
| pB -= 2; |
| blockCnt--; |
| } |
| } |
|
|
| |
| void merge_rfft_f16( |
| const arm_rfft_fast_instance_f16 * S, |
| float16_t * p, |
| float16_t * pOut) |
| { |
| int32_t k; |
| float16_t twR, twI; |
| const float16_t *pCoeff = S->pTwiddleRFFT; |
| float16_t *pA = p; |
| float16_t *pB = p; |
| float16_t xAR, xAI, xBR, xBI; |
| float16_t t1a, t1b, r, s, t, u; |
|
|
| float16x8x2_t tw,xA,xB; |
| float16x8x2_t tmp1, tmp2, res; |
| uint16x8_t vecStridesBkwd; |
|
|
| vecStridesBkwd = vddupq_u16((uint16_t)14, 2); |
|
|
| int blockCnt; |
| |
|
|
| k = (S->Sint).fftLen - 1; |
|
|
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| pCoeff += 2 ; |
|
|
| *pOut++ = 0.5f16 * ( (_Float16)xAR + (_Float16)xAI ); |
| *pOut++ = 0.5f16 * ( (_Float16)xAR - (_Float16)xAI ); |
|
|
| pB = p + 2*k - 14; |
| pA += 2 ; |
|
|
| blockCnt = k >> 3; |
| while (blockCnt > 0) |
| { |
| |
| |
| |
| xA = vld2q_f16(pA); |
| pA += 16; |
|
|
| xB = vld2q_f16(pB); |
|
|
| xB.val[0] = vldrhq_gather_shifted_offset_f16(pB, vecStridesBkwd); |
| xB.val[1] = vldrhq_gather_shifted_offset_f16(&pB[1], vecStridesBkwd); |
|
|
| xB.val[1] = vnegq_f16(xB.val[1]); |
| pB -= 16; |
|
|
|
|
| tw = vld2q_f16(pCoeff); |
| tw.val[1] = vnegq_f16(tw.val[1]); |
| pCoeff += 16; |
|
|
|
|
| tmp1.val[0] = vaddq_f16(xA.val[0],xB.val[0]); |
| tmp1.val[1] = vaddq_f16(xA.val[1],xB.val[1]); |
|
|
| tmp2.val[0] = vsubq_f16(xB.val[0],xA.val[0]); |
| tmp2.val[1] = vsubq_f16(xB.val[1],xA.val[1]); |
|
|
| res.val[0] = vmulq(tw.val[0], tmp2.val[0]); |
| res.val[0] = vfmsq(res.val[0],tw.val[1], tmp2.val[1]); |
|
|
| res.val[1] = vmulq(tw.val[0], tmp2.val[1]); |
| res.val[1] = vfmaq(res.val[1], tw.val[1], tmp2.val[0]); |
|
|
| res.val[0] = vaddq_f16(res.val[0],tmp1.val[0] ); |
| res.val[1] = vaddq_f16(res.val[1],tmp1.val[1] ); |
|
|
| res.val[0] = vmulq_n_f16(res.val[0], 0.5f); |
| res.val[1] = vmulq_n_f16(res.val[1], 0.5f); |
|
|
|
|
| vst2q_f16(pOut, res); |
| pOut += 16; |
|
|
| |
| blockCnt--; |
| } |
|
|
| pB += 14; |
| blockCnt = k & 7; |
| while (blockCnt > 0) |
| { |
| |
| |
| |
| xBI = pB[1] ; |
| xBR = pB[0] ; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++; |
| twI = *pCoeff++; |
|
|
| t1a = (_Float16)xAR - (_Float16)xBR ; |
| t1b = (_Float16)xAI + (_Float16)xBI ; |
|
|
| r = (_Float16)twR * (_Float16)t1a; |
| s = (_Float16)twI * (_Float16)t1b; |
| t = (_Float16)twI * (_Float16)t1a; |
| u = (_Float16)twR * (_Float16)t1b; |
|
|
| |
| |
| *pOut++ = 0.5f16 * ((_Float16)xAR + (_Float16)xBR - (_Float16)r - (_Float16)s ); |
| *pOut++ = 0.5f16 * ((_Float16)xAI - (_Float16)xBI + (_Float16)t - (_Float16)u ); |
|
|
| pA += 2; |
| pB -= 2; |
| blockCnt--; |
| } |
|
|
| } |
| #else |
| void stage_rfft_f16( |
| const arm_rfft_fast_instance_f16 * S, |
| float16_t * p, |
| float16_t * pOut) |
| { |
| int32_t k; |
| float16_t twR, twI; |
| const float16_t * pCoeff = S->pTwiddleRFFT; |
| float16_t *pA = p; |
| float16_t *pB = p; |
| float16_t xAR, xAI, xBR, xBI; |
| float16_t t1a, t1b; |
| float16_t p0, p1, p2, p3; |
|
|
|
|
| k = (S->Sint).fftLen - 1; |
|
|
| |
|
|
| xBR = pB[0]; |
| xBI = pB[1]; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++ ; |
| twI = *pCoeff++ ; |
|
|
|
|
| |
| t1a = (_Float16)xBR + (_Float16)xAR ; |
|
|
| |
| t1b = (_Float16)xBI + (_Float16)xAI ; |
|
|
| |
| |
| *pOut++ = 0.5f16 * ( (_Float16)t1a + (_Float16)t1b ); |
| *pOut++ = 0.5f16 * ( (_Float16)t1a - (_Float16)t1b ); |
|
|
| |
| pB = p + 2*k; |
| pA += 2; |
|
|
| do |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| xBI = pB[1]; |
| xBR = pB[0]; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++; |
| twI = *pCoeff++; |
|
|
| t1a = (_Float16)xBR - (_Float16)xAR ; |
| t1b = (_Float16)xBI + (_Float16)xAI ; |
|
|
| |
| |
| p0 = (_Float16)twR * (_Float16)t1a; |
| p1 = (_Float16)twI * (_Float16)t1a; |
| p2 = (_Float16)twR * (_Float16)t1b; |
| p3 = (_Float16)twI * (_Float16)t1b; |
|
|
| *pOut++ = 0.5f16 * ((_Float16)xAR + (_Float16)xBR + (_Float16)p0 + (_Float16)p3 ); |
| *pOut++ = 0.5f16 * ((_Float16)xAI - (_Float16)xBI + (_Float16)p1 - (_Float16)p2 ); |
|
|
|
|
| pA += 2; |
| pB -= 2; |
| k--; |
| } while (k > 0); |
| } |
|
|
| |
| void merge_rfft_f16( |
| const arm_rfft_fast_instance_f16 * S, |
| float16_t * p, |
| float16_t * pOut) |
| { |
| int32_t k; |
| float16_t twR, twI; |
| const float16_t *pCoeff = S->pTwiddleRFFT; |
| float16_t *pA = p; |
| float16_t *pB = p; |
| float16_t xAR, xAI, xBR, xBI; |
| float16_t t1a, t1b, r, s, t, u; |
|
|
| k = (S->Sint).fftLen - 1; |
|
|
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| pCoeff += 2 ; |
|
|
| *pOut++ = 0.5f16 * ( (_Float16)xAR + (_Float16)xAI ); |
| *pOut++ = 0.5f16 * ( (_Float16)xAR - (_Float16)xAI ); |
|
|
| pB = p + 2*k ; |
| pA += 2 ; |
|
|
| while (k > 0) |
| { |
| |
| |
| |
| xBI = pB[1] ; |
| xBR = pB[0] ; |
| xAR = pA[0]; |
| xAI = pA[1]; |
|
|
| twR = *pCoeff++; |
| twI = *pCoeff++; |
|
|
| t1a = (_Float16)xAR - (_Float16)xBR ; |
| t1b = (_Float16)xAI + (_Float16)xBI ; |
|
|
| r = (_Float16)twR * (_Float16)t1a; |
| s = (_Float16)twI * (_Float16)t1b; |
| t = (_Float16)twI * (_Float16)t1a; |
| u = (_Float16)twR * (_Float16)t1b; |
|
|
| |
| |
| *pOut++ = 0.5f16 * ((_Float16)xAR + (_Float16)xBR - (_Float16)r - (_Float16)s ); |
| *pOut++ = 0.5f16 * ((_Float16)xAI - (_Float16)xBI + (_Float16)t - (_Float16)u ); |
|
|
| pA += 2; |
| pB -= 2; |
| k--; |
| } |
|
|
| } |
|
|
| #endif |
|
|
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| void arm_rfft_fast_f16( |
| const arm_rfft_fast_instance_f16 * S, |
| float16_t * p, |
| float16_t * pOut, |
| uint8_t ifftFlag) |
| { |
| const arm_cfft_instance_f16 * Sint = &(S->Sint); |
|
|
|
|
| |
| if (ifftFlag) |
| { |
| |
| merge_rfft_f16(S, p, pOut); |
| |
| arm_cfft_f16( Sint, pOut, ifftFlag, 1); |
| } |
| else |
| { |
|
|
| |
| arm_cfft_f16( Sint, p, ifftFlag, 1); |
|
|
| |
| stage_rfft_f16(S, p, pOut); |
| } |
| } |
|
|
| |
| |
| |
|
|
| #endif |
|
|
| #endif |
|
|