#include "ref.h" #include "arm_const_structs.h" void ref_cfft_f32( const arm_cfft_instance_f32 * S, float32_t * p1, uint8_t ifftFlag, uint8_t bitReverseFlag) { int n, mmax, m, j, istep, i; float32_t wtemp, wr, wpr, wpi, wi, theta; float32_t tempr, tempi; float32_t * data = p1; uint32_t N = S->fftLen; int32_t dir = (ifftFlag) ? -1 : 1; // decrement pointer since the original version used fortran style indexing. data--; n = N << 1; j = 1; for (i = 1; i < n; i += 2) { if (j > i) { tempr = data[j]; data[j] = data[i]; data[i] = tempr; tempr = data[j+1]; data[j+1] = data[i+1]; data[i+1] = tempr; } m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } mmax = 2; while (n > mmax) { istep = 2*mmax; theta = -6.283185307179586f/(dir*mmax); wtemp = sinf(0.5f*theta); wpr = -2.0f*wtemp*wtemp; wpi = sinf(theta); wr = 1.0f; wi = 0.0f; for (m = 1; m < mmax; m += 2) { for (i = m; i <= n; i += istep) { j =i + mmax; tempr = wr*data[j] - wi*data[j+1]; tempi = wr*data[j+1] + wi*data[j]; data[j] = data[i] - tempr; data[j+1] = data[i+1] - tempi; data[i] += tempr; data[i+1] += tempi; } wr = (wtemp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + wtemp*wpi + wi; } mmax = istep; } // Inverse transform is scaled by 1/N if (ifftFlag) { data++; for(i = 0; i<2*N; i++) { data[i] /= N; } } } void ref_cfft_q31( const arm_cfft_instance_q31 * S, q31_t * p1, uint8_t ifftFlag, uint8_t bitReverseFlag) { uint32_t i; float32_t *fSrc = (float32_t*)p1; for(i=0;ifftLen*2;i++) { //read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)p1[i] / 2147483648.0f; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, ifftFlag, bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, ifftFlag, bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, ifftFlag, bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, ifftFlag, bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, ifftFlag, bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, ifftFlag, bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, ifftFlag, bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, ifftFlag, bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, ifftFlag, bitReverseFlag); break; } if (ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 p1[i] = (q31_t)( fSrc[i] * 2147483648.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 p1[i] = (q31_t)( fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_q15( const arm_cfft_instance_q15 * S, q15_t * pSrc, uint8_t ifftFlag, uint8_t bitReverseFlag) { uint32_t i; float32_t *fSrc = (float32_t*)pSrc; for(i=0;ifftLen*2;i++) { //read the q15 data, cast to float, scale down for float, place in temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for(i=0;ifftLen*2;i++) { //copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, ifftFlag, bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, ifftFlag, bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, ifftFlag, bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, ifftFlag, bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, ifftFlag, bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, ifftFlag, bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, ifftFlag, bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, ifftFlag, bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, ifftFlag, bitReverseFlag); break; } if (ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix2_f32( const arm_cfft_radix2_instance_f32 * S, float32_t * pSrc) { switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, pSrc, S->ifftFlag, S->bitReverseFlag); break; } } void ref_cfft_radix2_q31( const arm_cfft_radix2_instance_q31 * S, q31_t * pSrc) { uint32_t i; float32_t *fSrc = (float32_t*)pSrc; for(i=0;ifftLen*2;i++) { //read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)pSrc[i] / 2147483648.0f; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)( fSrc[i] * 2147483648.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)( fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix2_q15( const arm_cfft_radix2_instance_q15 * S, q15_t * pSrc) { uint32_t i; float32_t *fSrc = (float32_t*)pSrc; for(i=0;ifftLen*2;i++) { //read the q15 data, cast to float, scale down for float, place in temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for(i=0;ifftLen*2;i++) { //copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix4_f32( const arm_cfft_radix4_instance_f32 * S, float32_t * pSrc) { switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, pSrc, S->ifftFlag, S->bitReverseFlag); break; } } void ref_cfft_radix4_q31( const arm_cfft_radix4_instance_q31 * S, q31_t * pSrc) { uint32_t i; float32_t *fSrc = (float32_t*)pSrc; for(i=0;ifftLen*2;i++) { //read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)pSrc[i] / 2147483648.0f; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)( fSrc[i] * 2147483648.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)( fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix4_q15( const arm_cfft_radix4_instance_q15 * S, q15_t * pSrc) { uint32_t i; float32_t *fSrc = (float32_t*)pSrc; for(i=0;ifftLen*2;i++) { //read the q15 data, cast to float, scale down for float, place in temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for(i=0;ifftLen*2;i++) { //copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch(S->fftLen) { case 16: ref_cfft_f32(&arm_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&arm_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&arm_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&arm_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&arm_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&arm_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&arm_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&arm_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&arm_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f ); } } else { for(i=0;ifftLen*2;i++) { //read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)( fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } }