initial

Dependencies:   mbed BSP_DISCO_F746NG mbed-dsp

Committer:
justenmg
Date:
Tue Mar 10 20:59:20 2020 +0000
Revision:
9:fb0eb0b2796c
Parent:
8:e66f32a7e3e7
finished

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bmazzeo 0:c0f52e8223fe 1 /**
bmazzeo 0:c0f52e8223fe 2 ******************************************************************************
bmazzeo 0:c0f52e8223fe 3 * @file signal_processing.c
bmazzeo 0:c0f52e8223fe 4 * @author Brian Mazzeo
bmazzeo 0:c0f52e8223fe 5 * @date 2020
bmazzeo 0:c0f52e8223fe 6 * @brief This file provides a set of code for signal processing in 487.
bmazzeo 0:c0f52e8223fe 7 * Parts are taken from example code from STMIcroelectronics
bmazzeo 0:c0f52e8223fe 8 ******************************************************************************
bmazzeo 0:c0f52e8223fe 9 * @attention
bmazzeo 0:c0f52e8223fe 10 * This code was specifically developed for BYU ECEn 487 course
bmazzeo 0:c0f52e8223fe 11 * Introduction to Digital Signal Processing.
bmazzeo 0:c0f52e8223fe 12 *
bmazzeo 0:c0f52e8223fe 13 *
bmazzeo 0:c0f52e8223fe 14 ******************************************************************************
bmazzeo 0:c0f52e8223fe 15 */
bmazzeo 0:c0f52e8223fe 16
bmazzeo 0:c0f52e8223fe 17 #include "mbed.h"
bmazzeo 0:c0f52e8223fe 18 #include "stm32746g_discovery_lcd.h"
bmazzeo 0:c0f52e8223fe 19 #include "arm_math.h"
bmazzeo 0:c0f52e8223fe 20 #include "arm_const_structs.h"
bmazzeo 0:c0f52e8223fe 21 #include "filter_coefficients.h"
justenmg 1:103e3e426b55 22 #include "our_filter.h"
justenmg 3:51e15bd15778 23 #include "windowed.h"
justenmg 3:51e15bd15778 24 #include "signal_processing.h"
bmazzeo 0:c0f52e8223fe 25
bmazzeo 0:c0f52e8223fe 26
bmazzeo 0:c0f52e8223fe 27 /* ----------------------------------------------------------------------
bmazzeo 0:c0f52e8223fe 28 ** Defines for signal processing
bmazzeo 0:c0f52e8223fe 29 ** ------------------------------------------------------------------- */
bmazzeo 0:c0f52e8223fe 30
bmazzeo 0:c0f52e8223fe 31 #define AUDIO_BLOCK_SAMPLES ((uint32_t)128) // Number of samples (L and R) in audio block (each samples is 16 bits)
justenmg 5:a658cda1d619 32 #define CONV_LENGTH (WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1)
justenmg 5:a658cda1d619 33 #define BUFFER_LENGTH (WIN_NUM_TAPS - 1)
justenmg 5:a658cda1d619 34 #define FFT_BUFFER_LENGTH 2048
justenmg 5:a658cda1d619 35 #define FFT_LENGTH 1024
justenmg 5:a658cda1d619 36 #define PADDED_FILTER_LENGTH (WIN_NUM_TAPS + 2*(AUDIO_BLOCK_SAMPLES - 1))
bmazzeo 0:c0f52e8223fe 37
bmazzeo 0:c0f52e8223fe 38 /* For Lab Exercise */
justenmg 9:fb0eb0b2796c 39 #define Lab_Execution_Type 6
justenmg 5:a658cda1d619 40
justenmg 5:a658cda1d619 41 float32_t padded_filter[PADDED_FILTER_LENGTH];
justenmg 1:103e3e426b55 42
justenmg 1:103e3e426b55 43 float32_t lState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1];
justenmg 1:103e3e426b55 44 float32_t rState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1];
bmazzeo 0:c0f52e8223fe 45
justenmg 1:103e3e426b55 46 float32_t l_buf[BUFFER_LENGTH];
justenmg 1:103e3e426b55 47 float32_t r_buf[BUFFER_LENGTH];
bmazzeo 0:c0f52e8223fe 48
justenmg 5:a658cda1d619 49 float32_t l_buf2[FFT_LENGTH];
justenmg 5:a658cda1d619 50 float32_t r_buf2[FFT_LENGTH];
justenmg 5:a658cda1d619 51
justenmg 1:103e3e426b55 52 arm_fir_instance_f32 filter_left;
justenmg 1:103e3e426b55 53 arm_fir_instance_f32 filter_right;
bmazzeo 0:c0f52e8223fe 54
justenmg 4:99de9b4005d2 55 float32_t fft_buf[FFT_BUFFER_LENGTH];
justenmg 5:a658cda1d619 56 float32_t ifft_buf[FFT_BUFFER_LENGTH];
justenmg 4:99de9b4005d2 57
justenmg 4:99de9b4005d2 58 float32_t fft_of_filter[FFT_BUFFER_LENGTH];
justenmg 4:99de9b4005d2 59
justenmg 4:99de9b4005d2 60
bmazzeo 0:c0f52e8223fe 61 /* FUNCTION DEFINITIONS BELOW */
bmazzeo 0:c0f52e8223fe 62
bmazzeo 0:c0f52e8223fe 63 /**
bmazzeo 0:c0f52e8223fe 64 * @brief Initialize filter structures to be used in loops later
bmazzeo 0:c0f52e8223fe 65 * @retval None
bmazzeo 0:c0f52e8223fe 66 */
justenmg 4:99de9b4005d2 67 void initalize_signal_processing(void)
justenmg 4:99de9b4005d2 68 {
bmazzeo 0:c0f52e8223fe 69
bmazzeo 0:c0f52e8223fe 70 switch (Lab_Execution_Type)
bmazzeo 0:c0f52e8223fe 71 {
bmazzeo 0:c0f52e8223fe 72 case 0: // Passthrough case
bmazzeo 0:c0f52e8223fe 73 break;
bmazzeo 0:c0f52e8223fe 74
bmazzeo 0:c0f52e8223fe 75 case 1: // FIR case (ARM)
justenmg 1:103e3e426b55 76 arm_fir_init_f32(&filter_left, NUM_TAPS, (float32_t *)&Filter_coeffs, (float32_t *)&lState, AUDIO_BLOCK_SAMPLES);
justenmg 1:103e3e426b55 77 arm_fir_init_f32(&filter_right, NUM_TAPS, (float32_t *)&Filter_coeffs, (float32_t *)&rState, AUDIO_BLOCK_SAMPLES);
bmazzeo 0:c0f52e8223fe 78 break;
bmazzeo 0:c0f52e8223fe 79
bmazzeo 0:c0f52e8223fe 80 case 2: // FIR case (student)
justenmg 9:fb0eb0b2796c 81 arm_fir_init_f32(&filter_left, WIN_NUM_TAPS, (float32_t *)&win_filter_coeffs, (float32_t *)&lState, AUDIO_BLOCK_SAMPLES);
justenmg 9:fb0eb0b2796c 82 arm_fir_init_f32(&filter_right, WIN_NUM_TAPS, (float32_t *)&win_filter_coeffs, (float32_t *)&rState, AUDIO_BLOCK_SAMPLES);
bmazzeo 0:c0f52e8223fe 83 break;
bmazzeo 0:c0f52e8223fe 84
justenmg 5:a658cda1d619 85 case 3: // conv Overlap-add
justenmg 4:99de9b4005d2 86 filter_conv_init();
bmazzeo 0:c0f52e8223fe 87 break;
bmazzeo 0:c0f52e8223fe 88
justenmg 4:99de9b4005d2 89 case 4: // FFT Overlap-add
justenmg 4:99de9b4005d2 90 filter_fft_init();
justenmg 4:99de9b4005d2 91 break;
justenmg 4:99de9b4005d2 92
justenmg 4:99de9b4005d2 93 case 5: // FFT Overlap-add with real-imag efficiency
justenmg 4:99de9b4005d2 94 filter_fft_init();
justenmg 4:99de9b4005d2 95 break;
justenmg 4:99de9b4005d2 96
justenmg 4:99de9b4005d2 97 case 6: // OS FFT RI
justenmg 4:99de9b4005d2 98 filter_fft_init();
bmazzeo 0:c0f52e8223fe 99 break;
bmazzeo 0:c0f52e8223fe 100
bmazzeo 0:c0f52e8223fe 101
bmazzeo 0:c0f52e8223fe 102 }
bmazzeo 0:c0f52e8223fe 103 }
bmazzeo 0:c0f52e8223fe 104
bmazzeo 0:c0f52e8223fe 105 /**
bmazzeo 0:c0f52e8223fe 106 * @brief Process audio channel signals
bmazzeo 0:c0f52e8223fe 107 * @param L_channel_in: Pointer to Left channel data input (float32_t)
bmazzeo 0:c0f52e8223fe 108 * @param R_channel_in: Pointer to Right channel data input (float32_t)
bmazzeo 0:c0f52e8223fe 109 * @param L_channel_out: Pointer to Left channel data output (float32_t)
bmazzeo 0:c0f52e8223fe 110 * @param R_channel_out: Pointer to Right channel data output (float32_t)
bmazzeo 0:c0f52e8223fe 111 * @param Signal_Length: length of data to process
bmazzeo 0:c0f52e8223fe 112 * @retval None
bmazzeo 0:c0f52e8223fe 113 */
bmazzeo 0:c0f52e8223fe 114 void process_audio_channel_signals(float32_t* L_channel_in, float32_t* R_channel_in, float32_t* L_channel_out, float32_t* R_channel_out, uint16_t Signal_Length)
bmazzeo 0:c0f52e8223fe 115 {
bmazzeo 0:c0f52e8223fe 116 char buf[70];
bmazzeo 0:c0f52e8223fe 117 BSP_LCD_SetFont(&Font8);
bmazzeo 0:c0f52e8223fe 118 BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
bmazzeo 0:c0f52e8223fe 119 sprintf(buf, "Processing Signals" );
bmazzeo 0:c0f52e8223fe 120 BSP_LCD_DisplayStringAt(0, 200, (uint8_t *) buf, LEFT_MODE);
bmazzeo 0:c0f52e8223fe 121
bmazzeo 0:c0f52e8223fe 122 switch(Lab_Execution_Type)
bmazzeo 0:c0f52e8223fe 123 {
bmazzeo 0:c0f52e8223fe 124 case 0: // Passthrough case
justenmg 2:89234085faae 125 arm_copy_f32(L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 126 arm_copy_f32(R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 127 break;
bmazzeo 0:c0f52e8223fe 128
bmazzeo 0:c0f52e8223fe 129 case 1: // FIR case (ARM)
justenmg 2:89234085faae 130 arm_fir_f32(&filter_left, L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 131 arm_fir_f32(&filter_right, R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 132 break;
bmazzeo 0:c0f52e8223fe 133
bmazzeo 0:c0f52e8223fe 134 case 2: // FIR case (student)
justenmg 2:89234085faae 135 arm_fir_f32(&filter_left, L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 136 arm_fir_f32(&filter_right, R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 137 break;
bmazzeo 0:c0f52e8223fe 138
justenmg 4:99de9b4005d2 139 case 3: // OA CONV
justenmg 5:a658cda1d619 140 filter_OA_CONV(l_buf, L_channel_in, L_channel_out, Signal_Length);
justenmg 5:a658cda1d619 141 filter_OA_CONV(r_buf, R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 142 break;
bmazzeo 0:c0f52e8223fe 143
justenmg 4:99de9b4005d2 144 case 4: // OA FFT Overlap-add
justenmg 5:a658cda1d619 145 filter_OA_FFT(l_buf, fft_buf, ifft_buf, L_channel_in, L_channel_out, Signal_Length);
justenmg 5:a658cda1d619 146 filter_OA_FFT(r_buf, fft_buf, ifft_buf, R_channel_in, R_channel_out, Signal_Length);
justenmg 4:99de9b4005d2 147 break;
justenmg 4:99de9b4005d2 148
justenmg 4:99de9b4005d2 149 case 5: // FFT Overlap-add with real-imag efficiency
justenmg 5:a658cda1d619 150 filter_OA_FFT_RI(l_buf, r_buf, fft_buf, ifft_buf, L_channel_in, R_channel_in, L_channel_out, R_channel_out, Signal_Length);
justenmg 4:99de9b4005d2 151 break;
justenmg 4:99de9b4005d2 152
justenmg 4:99de9b4005d2 153 case 6: // OS FFT RI
justenmg 5:a658cda1d619 154 filter_OS_FFT_RI(l_buf2, r_buf2, fft_buf, ifft_buf, L_channel_in, R_channel_in, L_channel_out, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 155 break;
bmazzeo 0:c0f52e8223fe 156
bmazzeo 0:c0f52e8223fe 157
bmazzeo 0:c0f52e8223fe 158 }
bmazzeo 0:c0f52e8223fe 159 /* Change font back */
bmazzeo 0:c0f52e8223fe 160 BSP_LCD_SetFont(&Font16);
bmazzeo 0:c0f52e8223fe 161 }
justenmg 1:103e3e426b55 162
justenmg 2:89234085faae 163 //buffer: pointer to the storage buffer for the filter output
justenmg 2:89234085faae 164 //buf_length: the length of the storage buffer (len_filter + len_batch - 1)
justenmg 5:a658cda1d619 165
justenmg 5:a658cda1d619 166 void filter_OA_CONV(float32_t* overlap_buffer, float32_t* d_in, float32_t* d_out, uint16_t sig_length)
justenmg 1:103e3e426b55 167 {
justenmg 1:103e3e426b55 168 float32_t result = 0;
justenmg 2:89234085faae 169
justenmg 5:a658cda1d619 170 //shift the data sample and convolve
justenmg 5:a658cda1d619 171 for(uint16_t shift = 0; shift < CONV_LENGTH; shift++)
justenmg 1:103e3e426b55 172 {
justenmg 5:a658cda1d619 173 result = 0;
justenmg 7:88543caf2b6e 174
justenmg 5:a658cda1d619 175 //multiply-add the shifted, reversed data sample to the padded filter
justenmg 5:a658cda1d619 176 for(int i=0; i<sig_length; i++)
justenmg 5:a658cda1d619 177 {
justenmg 7:88543caf2b6e 178 result += padded_filter[i + shift] * d_in[sig_length - i - 1];
justenmg 5:a658cda1d619 179 }
justenmg 5:a658cda1d619 180
justenmg 8:e66f32a7e3e7 181 // overlap-add to the buffer
justenmg 3:51e15bd15778 182 if(shift < sig_length)
justenmg 2:89234085faae 183 {
justenmg 5:a658cda1d619 184 d_out[shift] = overlap_buffer[shift] + result;
justenmg 2:89234085faae 185 }
justenmg 5:a658cda1d619 186 else if(shift < BUFFER_LENGTH)
justenmg 2:89234085faae 187 {
justenmg 5:a658cda1d619 188 overlap_buffer[shift - sig_length] = overlap_buffer[shift] + result;
justenmg 4:99de9b4005d2 189 }
justenmg 4:99de9b4005d2 190 else
justenmg 4:99de9b4005d2 191 {
justenmg 5:a658cda1d619 192 overlap_buffer[shift - sig_length] = result;
justenmg 4:99de9b4005d2 193 }
justenmg 4:99de9b4005d2 194 }
justenmg 4:99de9b4005d2 195 return;
justenmg 4:99de9b4005d2 196 }
justenmg 4:99de9b4005d2 197
justenmg 4:99de9b4005d2 198
justenmg 4:99de9b4005d2 199
justenmg 5:a658cda1d619 200 void filter_OA_FFT(
justenmg 5:a658cda1d619 201 float32_t* overlap_buffer,
justenmg 5:a658cda1d619 202 float32_t* fft_buffer,
justenmg 5:a658cda1d619 203 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 204 float32_t* d_in,
justenmg 5:a658cda1d619 205 float32_t* d_out,
justenmg 5:a658cda1d619 206 uint16_t sig_length)
justenmg 4:99de9b4005d2 207 {
justenmg 5:a658cda1d619 208 //fill the FFT buffer
justenmg 5:a658cda1d619 209 for(int i=0; i < FFT_LENGTH; i++)
justenmg 4:99de9b4005d2 210 {
justenmg 5:a658cda1d619 211 if(i < sig_length)
justenmg 2:89234085faae 212 {
justenmg 5:a658cda1d619 213 fft_buffer[2*i] = d_in[i];
justenmg 5:a658cda1d619 214 fft_buffer[2*i+1] = 0;
justenmg 2:89234085faae 215 }
justenmg 2:89234085faae 216 else
justenmg 2:89234085faae 217 {
justenmg 5:a658cda1d619 218 fft_buffer[2*i] = 0;
justenmg 5:a658cda1d619 219 fft_buffer[2*i+1] = 0;
justenmg 2:89234085faae 220 }
justenmg 1:103e3e426b55 221 }
justenmg 2:89234085faae 222
justenmg 5:a658cda1d619 223 //perform FFT in place
justenmg 5:a658cda1d619 224 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 225
justenmg 5:a658cda1d619 226
justenmg 5:a658cda1d619 227 //multiply with filter FFT
justenmg 5:a658cda1d619 228 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 229
justenmg 5:a658cda1d619 230 //perform inverse FFT in place
justenmg 5:a658cda1d619 231 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 232
justenmg 5:a658cda1d619 233 // overlap-add to the buffer
justenmg 5:a658cda1d619 234 for(uint16_t i = 0; i < CONV_LENGTH; i++)
justenmg 2:89234085faae 235 {
justenmg 5:a658cda1d619 236 if(i < sig_length)
justenmg 2:89234085faae 237 {
justenmg 5:a658cda1d619 238 d_out[i] = ifft_buffer[2*i] + overlap_buffer[i];
justenmg 5:a658cda1d619 239 }
justenmg 5:a658cda1d619 240 else if(i < BUFFER_LENGTH)
justenmg 5:a658cda1d619 241 {
justenmg 5:a658cda1d619 242 overlap_buffer[i - sig_length] = overlap_buffer[i] + ifft_buffer[2*i];
justenmg 2:89234085faae 243 }
justenmg 2:89234085faae 244 else
justenmg 2:89234085faae 245 {
justenmg 5:a658cda1d619 246 overlap_buffer[i - sig_length] = ifft_buffer[2*i];
justenmg 2:89234085faae 247 }
justenmg 5:a658cda1d619 248 }
justenmg 4:99de9b4005d2 249 return;
justenmg 4:99de9b4005d2 250 }
justenmg 4:99de9b4005d2 251
justenmg 4:99de9b4005d2 252
justenmg 5:a658cda1d619 253 //The overlap-add method uses previous outputs to adjust the filtered
justenmg 5:a658cda1d619 254 //output to be more representative of the continuous version of the signal
justenmg 5:a658cda1d619 255 void filter_OA_FFT_RI(
justenmg 5:a658cda1d619 256 float32_t* overlap_buffer1,
justenmg 5:a658cda1d619 257 float32_t* overlap_buffer2,
justenmg 5:a658cda1d619 258 float32_t* fft_buffer,
justenmg 5:a658cda1d619 259 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 260 float32_t* d_in1,
justenmg 5:a658cda1d619 261 float32_t* d_in2,
justenmg 5:a658cda1d619 262 float32_t* d_out1,
justenmg 5:a658cda1d619 263 float32_t* d_out2,
justenmg 5:a658cda1d619 264 uint16_t sig_length)
justenmg 5:a658cda1d619 265 {
justenmg 5:a658cda1d619 266 //fill the FFT buffer
justenmg 5:a658cda1d619 267 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 268 {
justenmg 5:a658cda1d619 269 if(i < sig_length)
justenmg 5:a658cda1d619 270 {
justenmg 5:a658cda1d619 271 fft_buffer[2*i] = d_in1[i];
justenmg 5:a658cda1d619 272 fft_buffer[2*i+1] = d_in2[i];
justenmg 5:a658cda1d619 273 }
justenmg 5:a658cda1d619 274 else
justenmg 5:a658cda1d619 275 {
justenmg 5:a658cda1d619 276 fft_buffer[2*i] = 0;
justenmg 5:a658cda1d619 277 fft_buffer[2*i+1] = 0;
justenmg 5:a658cda1d619 278 }
justenmg 5:a658cda1d619 279 }
justenmg 4:99de9b4005d2 280
justenmg 5:a658cda1d619 281 //perform FFT in place
justenmg 5:a658cda1d619 282 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 283
justenmg 5:a658cda1d619 284
justenmg 5:a658cda1d619 285 //multiply with filter FFT
justenmg 5:a658cda1d619 286 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 287
justenmg 5:a658cda1d619 288
justenmg 5:a658cda1d619 289 //perform inverse FFT in place
justenmg 5:a658cda1d619 290 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 291
justenmg 5:a658cda1d619 292 // overlap-add to the buffer
justenmg 5:a658cda1d619 293 for(uint16_t i = 0; i < CONV_LENGTH; i++)
justenmg 5:a658cda1d619 294 {
justenmg 5:a658cda1d619 295 if(i < sig_length)
justenmg 5:a658cda1d619 296 {
justenmg 5:a658cda1d619 297 d_out1[i] = ifft_buffer[2*i] + overlap_buffer1[i];
justenmg 5:a658cda1d619 298 d_out2[i] = ifft_buffer[2*i+1] + overlap_buffer2[i];
justenmg 5:a658cda1d619 299 }
justenmg 5:a658cda1d619 300 else if(i < BUFFER_LENGTH)
justenmg 5:a658cda1d619 301 {
justenmg 5:a658cda1d619 302 overlap_buffer1[i - sig_length] = overlap_buffer1[i] + ifft_buffer[2*i];
justenmg 5:a658cda1d619 303 overlap_buffer2[i - sig_length] = overlap_buffer2[i] + ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 304 }
justenmg 5:a658cda1d619 305 else
justenmg 5:a658cda1d619 306 {
justenmg 5:a658cda1d619 307 overlap_buffer1[i - sig_length] = ifft_buffer[2*i];
justenmg 5:a658cda1d619 308 overlap_buffer2[i - sig_length] = ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 309 }
justenmg 5:a658cda1d619 310 }
justenmg 2:89234085faae 311 return;
justenmg 1:103e3e426b55 312 }
justenmg 1:103e3e426b55 313
justenmg 4:99de9b4005d2 314
justenmg 5:a658cda1d619 315 //The overlap-save method uses previous inputs to perform a
justenmg 5:a658cda1d619 316 //more representative filtering operation
justenmg 5:a658cda1d619 317 void filter_OS_FFT_RI(
justenmg 5:a658cda1d619 318 float32_t* save_buffer1,
justenmg 5:a658cda1d619 319 float32_t* save_buffer2,
justenmg 5:a658cda1d619 320 float32_t* fft_buffer,
justenmg 5:a658cda1d619 321 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 322 float32_t* d_in1,
justenmg 5:a658cda1d619 323 float32_t* d_in2,
justenmg 5:a658cda1d619 324 float32_t* d_out1,
justenmg 5:a658cda1d619 325 float32_t* d_out2,
justenmg 5:a658cda1d619 326 uint16_t sig_length)
justenmg 4:99de9b4005d2 327 {
justenmg 6:291e341f0d71 328 //shift the save buffers left by the input data size
justenmg 5:a658cda1d619 329 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 330 {
justenmg 6:291e341f0d71 331 if(i < (FFT_LENGTH - sig_length))
justenmg 5:a658cda1d619 332 {
justenmg 5:a658cda1d619 333 save_buffer1[i] = save_buffer1[i+sig_length];
justenmg 5:a658cda1d619 334 save_buffer2[i] = save_buffer2[i+sig_length];
justenmg 5:a658cda1d619 335 }
justenmg 5:a658cda1d619 336 else
justenmg 5:a658cda1d619 337 {
justenmg 6:291e341f0d71 338 save_buffer1[i] = d_in1[i - (FFT_LENGTH - sig_length)];
justenmg 6:291e341f0d71 339 save_buffer2[i] = d_in2[i - (FFT_LENGTH - sig_length)];
justenmg 5:a658cda1d619 340 }
justenmg 5:a658cda1d619 341 }
justenmg 5:a658cda1d619 342
justenmg 5:a658cda1d619 343 //fill the FFT buffer
justenmg 5:a658cda1d619 344 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 345 {
justenmg 6:291e341f0d71 346 fft_buffer[2*i] = save_buffer1[i];
justenmg 6:291e341f0d71 347 fft_buffer[2*i+1] = save_buffer2[i];
justenmg 5:a658cda1d619 348 }
justenmg 5:a658cda1d619 349
justenmg 5:a658cda1d619 350 //perform FFT in place
justenmg 5:a658cda1d619 351 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 352
justenmg 5:a658cda1d619 353 //multiply with filter FFT
justenmg 5:a658cda1d619 354 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 355
justenmg 5:a658cda1d619 356 //perform inverse FFT in place
justenmg 5:a658cda1d619 357 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 358
justenmg 5:a658cda1d619 359 // copy to output buffer
justenmg 6:291e341f0d71 360 for(uint16_t i = FFT_LENGTH - sig_length; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 361 {
justenmg 6:291e341f0d71 362 d_out1[i - FFT_LENGTH + sig_length] = ifft_buffer[2*i];
justenmg 6:291e341f0d71 363 d_out2[i - FFT_LENGTH + sig_length] = ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 364 }
justenmg 4:99de9b4005d2 365 return;
justenmg 4:99de9b4005d2 366 }
justenmg 4:99de9b4005d2 367
justenmg 4:99de9b4005d2 368
justenmg 4:99de9b4005d2 369
justenmg 4:99de9b4005d2 370
justenmg 4:99de9b4005d2 371
justenmg 4:99de9b4005d2 372
justenmg 4:99de9b4005d2 373 void filter_conv_init()
justenmg 1:103e3e426b55 374 {
justenmg 2:89234085faae 375 for(int i=0; i < BUFFER_LENGTH; i++)
justenmg 1:103e3e426b55 376 {
justenmg 2:89234085faae 377 l_buf[i] = 0;
justenmg 2:89234085faae 378 r_buf[i] = 0;
justenmg 1:103e3e426b55 379 }
justenmg 5:a658cda1d619 380 for(int i=0; i < PADDED_FILTER_LENGTH; i++)
justenmg 5:a658cda1d619 381 {
justenmg 5:a658cda1d619 382 if((i < AUDIO_BLOCK_SAMPLES - 1) || (i >= WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1))
justenmg 5:a658cda1d619 383 {
justenmg 5:a658cda1d619 384 padded_filter[i] = 0;
justenmg 5:a658cda1d619 385 }
justenmg 5:a658cda1d619 386 else
justenmg 5:a658cda1d619 387 {
justenmg 7:88543caf2b6e 388 padded_filter[i] = win_filter_coeffs[i - AUDIO_BLOCK_SAMPLES - 1];
justenmg 5:a658cda1d619 389 }
justenmg 5:a658cda1d619 390 }
justenmg 5:a658cda1d619 391
justenmg 3:51e15bd15778 392 return;
justenmg 1:103e3e426b55 393 }
justenmg 4:99de9b4005d2 394
justenmg 4:99de9b4005d2 395
justenmg 4:99de9b4005d2 396
justenmg 4:99de9b4005d2 397 void filter_fft_init()
justenmg 4:99de9b4005d2 398 {
justenmg 5:a658cda1d619 399 for(int i=0; i < FFT_LENGTH; i++)
justenmg 4:99de9b4005d2 400 {
justenmg 4:99de9b4005d2 401 if(i < WIN_NUM_TAPS)
justenmg 4:99de9b4005d2 402 {
justenmg 6:291e341f0d71 403 fft_of_filter[2*i] = win_filter_coeffs[i];
justenmg 6:291e341f0d71 404 fft_of_filter[2*i+1] = 0;
justenmg 4:99de9b4005d2 405 }
justenmg 4:99de9b4005d2 406 else
justenmg 4:99de9b4005d2 407 {
justenmg 6:291e341f0d71 408 fft_of_filter[2*i] = 0;
justenmg 6:291e341f0d71 409 fft_of_filter[2*i+1] = 0;
justenmg 4:99de9b4005d2 410 }
justenmg 4:99de9b4005d2 411 }
justenmg 4:99de9b4005d2 412
justenmg 4:99de9b4005d2 413 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_of_filter, 0, 1);
justenmg 4:99de9b4005d2 414
justenmg 4:99de9b4005d2 415 return;
justenmg 4:99de9b4005d2 416 }
justenmg 5:a658cda1d619 417
justenmg 6:291e341f0d71 418