25#define __FPU_PRESENT 1U
26#include <cmsis/arm_math.h>
34typedef enum e_windowType {
44template <
int MAX_CHNUM,
int FFTLEN>
class FFTClass
48 begin(WindowHamming, MAX_CHNUM, (FFTLEN / 2));
51 bool begin(windowType_t type,
int channel,
int overlap){
52 if (channel > MAX_CHNUM)
return false;
53 if (overlap > (FFTLEN / 2))
return false;
64 for(
int i = 0; i < MAX_CHNUM; i++) {
65 ringbuf_fft[i] =
new RingBuff(MAX_CHNUM * FFTLEN *
sizeof(q15_t));
71 bool put(q15_t* pSrc,
int sample) {
73 if(m_channel > MAX_CHNUM)
return false;
74 if(sample > ringbuf_fft[0]->remain())
return false;
78 ringbuf_fft[0]->put((q15_t*)pSrc, sample);
80 for (
int i = 0; i < m_channel; i++) {
81 ringbuf_fft[i]->put(pSrc, sample, m_channel, i);
87 int get_raw(
float* out,
int channel) {
88 return get_raw(out, channel,
true);
91 int get(
float* out,
int channel) {
92 return get_raw(out, channel,
false);
96 for (
int i = 0; i < MAX_CHNUM; i++) {
97 memset(tmpInBuf[i], 0, FFTLEN);
104 bool empty(
int channel){
105 return (ringbuf_fft[channel]->stored() < FFTLEN);
114 arm_rfft_fast_instance_f32 S;
117 float tmpInBuf[MAX_CHNUM][FFTLEN];
119 float tmpOutBuf[FFTLEN];
121 void create_coef(windowType_t type) {
122 for (
int i = 0; i < FFTLEN / 2; i++) {
123 if (type == WindowHamming) {
124 coef[i] = 0.54f - (0.46f * arm_cos_f32(2 * PI * (
float)i / (FFTLEN - 1)));
125 }
else if (type == WindowHanning) {
126 coef[i] = 0.54f - (1.0f * arm_cos_f32(2 * PI * (
float)i / (FFTLEN - 1)));
127 }
else if (type == WindowFlattop) {
128 coef[i] = 0.21557895f - (0.41663158f * arm_cos_f32(2 * PI * (
float)i / (FFTLEN - 1)))
129 + (0.277263158f * arm_cos_f32(4 * PI * (
float)i / (FFTLEN - 1)))
130 - (0.083578947f * arm_cos_f32(6 * PI * (
float)i / (FFTLEN - 1)))
131 + (0.006947368f * arm_cos_f32(8 * PI * (
float)i / (FFTLEN - 1)));
135 coef[FFTLEN -1 - i] = coef[i];
142 arm_rfft_32_fast_init_f32(&S);
145 arm_rfft_64_fast_init_f32(&S);
148 arm_rfft_128_fast_init_f32(&S);
151 arm_rfft_256_fast_init_f32(&S);
154 arm_rfft_512_fast_init_f32(&S);
157 arm_rfft_1024_fast_init_f32(&S);
160 arm_rfft_2048_fast_init_f32(&S);
163 arm_rfft_4096_fast_init_f32(&S);
173 void fft(
float *pSrc,
float *pDst) {
174 arm_rfft_fast_f32(&S, pSrc, pDst, 0);
177 void fft_amp(
float *pSrc,
float *pDst) {
179 arm_rfft_fast_f32(&S, pSrc, tmpOutBuf, 0);
180 arm_cmplx_mag_f32(tmpOutBuf, pDst, FFTLEN / 2);
183 int get_raw(
float* out,
int channel,
int raw) {
184 static float tmpFft[FFTLEN];
186 if(channel >= m_channel)
return false;
187 if (ringbuf_fft[channel]->stored() < FFTLEN)
return 0;
189 for (
int i=0;i<m_overlap;i++) {
190 tmpInBuf[channel][i] = tmpInBuf[channel][FFTLEN - m_overlap + i];
194 ringbuf_fft[channel]->get(&tmpInBuf[channel][m_overlap], FFTLEN - m_overlap);
196 for (
int i = 0; i < FFTLEN; i++) {
197 tmpFft[i] = tmpInBuf[channel][i] * coef[i];
205 fft_amp(tmpFft, out);
207 return (FFTLEN - m_overlap);
Definition: RingBuff.h:26