initial

Dependencies:   mbed BSP_DISCO_F746NG mbed-dsp

Committer:
justenmg
Date:
Fri Mar 06 19:09:04 2020 +0000
Revision:
7:88543caf2b6e
Parent:
6:291e341f0d71
Child:
8:e66f32a7e3e7
all working

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 7:88543caf2b6e 39 #define Lab_Execution_Type 3
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 1:103e3e426b55 81 arm_fir_init_f32(&filter_left, OUR_NUM_TAPS, (float32_t *)&our_Filter_coeffs, (float32_t *)&lState, AUDIO_BLOCK_SAMPLES);
justenmg 1:103e3e426b55 82 arm_fir_init_f32(&filter_right, OUR_NUM_TAPS, (float32_t *)&our_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 5:a658cda1d619 181 // overlap-add to the buffer
justenmg 5:a658cda1d619 182 //overlap_buffer[shift] += result;
justenmg 5:a658cda1d619 183
justenmg 3:51e15bd15778 184 if(shift < sig_length)
justenmg 2:89234085faae 185 {
justenmg 5:a658cda1d619 186 d_out[shift] = overlap_buffer[shift] + result;
justenmg 2:89234085faae 187 }
justenmg 5:a658cda1d619 188 else if(shift < BUFFER_LENGTH)
justenmg 2:89234085faae 189 {
justenmg 5:a658cda1d619 190 overlap_buffer[shift - sig_length] = overlap_buffer[shift] + result;
justenmg 4:99de9b4005d2 191 }
justenmg 4:99de9b4005d2 192 else
justenmg 4:99de9b4005d2 193 {
justenmg 5:a658cda1d619 194 overlap_buffer[shift - sig_length] = result;
justenmg 4:99de9b4005d2 195 }
justenmg 4:99de9b4005d2 196 }
justenmg 4:99de9b4005d2 197 return;
justenmg 4:99de9b4005d2 198 }
justenmg 4:99de9b4005d2 199
justenmg 4:99de9b4005d2 200
justenmg 4:99de9b4005d2 201
justenmg 5:a658cda1d619 202 void filter_OA_FFT(
justenmg 5:a658cda1d619 203 float32_t* overlap_buffer,
justenmg 5:a658cda1d619 204 float32_t* fft_buffer,
justenmg 5:a658cda1d619 205 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 206 float32_t* d_in,
justenmg 5:a658cda1d619 207 float32_t* d_out,
justenmg 5:a658cda1d619 208 uint16_t sig_length)
justenmg 4:99de9b4005d2 209 {
justenmg 5:a658cda1d619 210 //fill the FFT buffer
justenmg 5:a658cda1d619 211 for(int i=0; i < FFT_LENGTH; i++)
justenmg 4:99de9b4005d2 212 {
justenmg 5:a658cda1d619 213 if(i < sig_length)
justenmg 2:89234085faae 214 {
justenmg 5:a658cda1d619 215 fft_buffer[2*i] = d_in[i];
justenmg 5:a658cda1d619 216 fft_buffer[2*i+1] = 0;
justenmg 2:89234085faae 217 }
justenmg 2:89234085faae 218 else
justenmg 2:89234085faae 219 {
justenmg 5:a658cda1d619 220 fft_buffer[2*i] = 0;
justenmg 5:a658cda1d619 221 fft_buffer[2*i+1] = 0;
justenmg 2:89234085faae 222 }
justenmg 1:103e3e426b55 223 }
justenmg 2:89234085faae 224
justenmg 5:a658cda1d619 225 //perform FFT in place
justenmg 5:a658cda1d619 226 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 227
justenmg 5:a658cda1d619 228
justenmg 5:a658cda1d619 229 //multiply with filter FFT
justenmg 5:a658cda1d619 230 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 231
justenmg 5:a658cda1d619 232 //perform inverse FFT in place
justenmg 5:a658cda1d619 233 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 234
justenmg 5:a658cda1d619 235 // overlap-add to the buffer
justenmg 5:a658cda1d619 236 for(uint16_t i = 0; i < CONV_LENGTH; i++)
justenmg 2:89234085faae 237 {
justenmg 5:a658cda1d619 238 if(i < sig_length)
justenmg 2:89234085faae 239 {
justenmg 5:a658cda1d619 240 d_out[i] = ifft_buffer[2*i] + overlap_buffer[i];
justenmg 5:a658cda1d619 241 }
justenmg 5:a658cda1d619 242 else if(i < BUFFER_LENGTH)
justenmg 5:a658cda1d619 243 {
justenmg 5:a658cda1d619 244 overlap_buffer[i - sig_length] = overlap_buffer[i] + ifft_buffer[2*i];
justenmg 2:89234085faae 245 }
justenmg 2:89234085faae 246 else
justenmg 2:89234085faae 247 {
justenmg 5:a658cda1d619 248 overlap_buffer[i - sig_length] = ifft_buffer[2*i];
justenmg 2:89234085faae 249 }
justenmg 5:a658cda1d619 250 }
justenmg 4:99de9b4005d2 251 return;
justenmg 4:99de9b4005d2 252 }
justenmg 4:99de9b4005d2 253
justenmg 4:99de9b4005d2 254
justenmg 5:a658cda1d619 255 //The overlap-add method uses previous outputs to adjust the filtered
justenmg 5:a658cda1d619 256 //output to be more representative of the continuous version of the signal
justenmg 5:a658cda1d619 257 void filter_OA_FFT_RI(
justenmg 5:a658cda1d619 258 float32_t* overlap_buffer1,
justenmg 5:a658cda1d619 259 float32_t* overlap_buffer2,
justenmg 5:a658cda1d619 260 float32_t* fft_buffer,
justenmg 5:a658cda1d619 261 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 262 float32_t* d_in1,
justenmg 5:a658cda1d619 263 float32_t* d_in2,
justenmg 5:a658cda1d619 264 float32_t* d_out1,
justenmg 5:a658cda1d619 265 float32_t* d_out2,
justenmg 5:a658cda1d619 266 uint16_t sig_length)
justenmg 5:a658cda1d619 267 {
justenmg 5:a658cda1d619 268 //fill the FFT buffer
justenmg 5:a658cda1d619 269 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 270 {
justenmg 5:a658cda1d619 271 if(i < sig_length)
justenmg 5:a658cda1d619 272 {
justenmg 5:a658cda1d619 273 fft_buffer[2*i] = d_in1[i];
justenmg 5:a658cda1d619 274 fft_buffer[2*i+1] = d_in2[i];
justenmg 5:a658cda1d619 275 }
justenmg 5:a658cda1d619 276 else
justenmg 5:a658cda1d619 277 {
justenmg 5:a658cda1d619 278 fft_buffer[2*i] = 0;
justenmg 5:a658cda1d619 279 fft_buffer[2*i+1] = 0;
justenmg 5:a658cda1d619 280 }
justenmg 5:a658cda1d619 281 }
justenmg 4:99de9b4005d2 282
justenmg 5:a658cda1d619 283 //perform FFT in place
justenmg 5:a658cda1d619 284 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 285
justenmg 5:a658cda1d619 286
justenmg 5:a658cda1d619 287 //multiply with filter FFT
justenmg 5:a658cda1d619 288 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 289
justenmg 5:a658cda1d619 290
justenmg 5:a658cda1d619 291 //perform inverse FFT in place
justenmg 5:a658cda1d619 292 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 293
justenmg 5:a658cda1d619 294 // overlap-add to the buffer
justenmg 5:a658cda1d619 295 for(uint16_t i = 0; i < CONV_LENGTH; i++)
justenmg 5:a658cda1d619 296 {
justenmg 5:a658cda1d619 297 if(i < sig_length)
justenmg 5:a658cda1d619 298 {
justenmg 5:a658cda1d619 299 d_out1[i] = ifft_buffer[2*i] + overlap_buffer1[i];
justenmg 5:a658cda1d619 300 d_out2[i] = ifft_buffer[2*i+1] + overlap_buffer2[i];
justenmg 5:a658cda1d619 301 }
justenmg 5:a658cda1d619 302 else if(i < BUFFER_LENGTH)
justenmg 5:a658cda1d619 303 {
justenmg 5:a658cda1d619 304 overlap_buffer1[i - sig_length] = overlap_buffer1[i] + ifft_buffer[2*i];
justenmg 5:a658cda1d619 305 overlap_buffer2[i - sig_length] = overlap_buffer2[i] + ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 306 }
justenmg 5:a658cda1d619 307 else
justenmg 5:a658cda1d619 308 {
justenmg 5:a658cda1d619 309 overlap_buffer1[i - sig_length] = ifft_buffer[2*i];
justenmg 5:a658cda1d619 310 overlap_buffer2[i - sig_length] = ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 311 }
justenmg 5:a658cda1d619 312 }
justenmg 2:89234085faae 313 return;
justenmg 1:103e3e426b55 314 }
justenmg 1:103e3e426b55 315
justenmg 4:99de9b4005d2 316
justenmg 5:a658cda1d619 317 //The overlap-save method uses previous inputs to perform a
justenmg 5:a658cda1d619 318 //more representative filtering operation
justenmg 5:a658cda1d619 319 void filter_OS_FFT_RI(
justenmg 5:a658cda1d619 320 float32_t* save_buffer1,
justenmg 5:a658cda1d619 321 float32_t* save_buffer2,
justenmg 5:a658cda1d619 322 float32_t* fft_buffer,
justenmg 5:a658cda1d619 323 float32_t* ifft_buffer,
justenmg 5:a658cda1d619 324 float32_t* d_in1,
justenmg 5:a658cda1d619 325 float32_t* d_in2,
justenmg 5:a658cda1d619 326 float32_t* d_out1,
justenmg 5:a658cda1d619 327 float32_t* d_out2,
justenmg 5:a658cda1d619 328 uint16_t sig_length)
justenmg 4:99de9b4005d2 329 {
justenmg 6:291e341f0d71 330 //shift the save buffers left by the input data size
justenmg 5:a658cda1d619 331 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 332 {
justenmg 6:291e341f0d71 333 if(i < (FFT_LENGTH - sig_length))
justenmg 5:a658cda1d619 334 {
justenmg 5:a658cda1d619 335 save_buffer1[i] = save_buffer1[i+sig_length];
justenmg 5:a658cda1d619 336 save_buffer2[i] = save_buffer2[i+sig_length];
justenmg 5:a658cda1d619 337 }
justenmg 5:a658cda1d619 338 else
justenmg 5:a658cda1d619 339 {
justenmg 6:291e341f0d71 340 save_buffer1[i] = d_in1[i - (FFT_LENGTH - sig_length)];
justenmg 6:291e341f0d71 341 save_buffer2[i] = d_in2[i - (FFT_LENGTH - sig_length)];
justenmg 5:a658cda1d619 342 }
justenmg 5:a658cda1d619 343 }
justenmg 5:a658cda1d619 344
justenmg 5:a658cda1d619 345 //fill the FFT buffer
justenmg 5:a658cda1d619 346 for(int i=0; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 347 {
justenmg 6:291e341f0d71 348 fft_buffer[2*i] = save_buffer1[i];
justenmg 6:291e341f0d71 349 fft_buffer[2*i+1] = save_buffer2[i];
justenmg 5:a658cda1d619 350 }
justenmg 5:a658cda1d619 351
justenmg 5:a658cda1d619 352 //perform FFT in place
justenmg 5:a658cda1d619 353 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1);
justenmg 5:a658cda1d619 354
justenmg 5:a658cda1d619 355 //multiply with filter FFT
justenmg 5:a658cda1d619 356 arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH);
justenmg 5:a658cda1d619 357
justenmg 5:a658cda1d619 358 //perform inverse FFT in place
justenmg 5:a658cda1d619 359 arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1);
justenmg 5:a658cda1d619 360
justenmg 5:a658cda1d619 361 // copy to output buffer
justenmg 6:291e341f0d71 362 for(uint16_t i = FFT_LENGTH - sig_length; i < FFT_LENGTH; i++)
justenmg 5:a658cda1d619 363 {
justenmg 6:291e341f0d71 364 d_out1[i - FFT_LENGTH + sig_length] = ifft_buffer[2*i];
justenmg 6:291e341f0d71 365 d_out2[i - FFT_LENGTH + sig_length] = ifft_buffer[2*i+1];
justenmg 5:a658cda1d619 366 }
justenmg 4:99de9b4005d2 367 return;
justenmg 4:99de9b4005d2 368 }
justenmg 4:99de9b4005d2 369
justenmg 4:99de9b4005d2 370
justenmg 4:99de9b4005d2 371
justenmg 4:99de9b4005d2 372
justenmg 4:99de9b4005d2 373
justenmg 4:99de9b4005d2 374
justenmg 4:99de9b4005d2 375 void filter_conv_init()
justenmg 1:103e3e426b55 376 {
justenmg 2:89234085faae 377 for(int i=0; i < BUFFER_LENGTH; i++)
justenmg 1:103e3e426b55 378 {
justenmg 2:89234085faae 379 l_buf[i] = 0;
justenmg 2:89234085faae 380 r_buf[i] = 0;
justenmg 1:103e3e426b55 381 }
justenmg 5:a658cda1d619 382 for(int i=0; i < PADDED_FILTER_LENGTH; i++)
justenmg 5:a658cda1d619 383 {
justenmg 5:a658cda1d619 384 if((i < AUDIO_BLOCK_SAMPLES - 1) || (i >= WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1))
justenmg 5:a658cda1d619 385 {
justenmg 5:a658cda1d619 386 padded_filter[i] = 0;
justenmg 5:a658cda1d619 387 }
justenmg 5:a658cda1d619 388 else
justenmg 5:a658cda1d619 389 {
justenmg 7:88543caf2b6e 390 padded_filter[i] = win_filter_coeffs[i - AUDIO_BLOCK_SAMPLES - 1];
justenmg 5:a658cda1d619 391 }
justenmg 5:a658cda1d619 392 }
justenmg 5:a658cda1d619 393
justenmg 3:51e15bd15778 394 return;
justenmg 1:103e3e426b55 395 }
justenmg 4:99de9b4005d2 396
justenmg 4:99de9b4005d2 397
justenmg 4:99de9b4005d2 398
justenmg 4:99de9b4005d2 399 void filter_fft_init()
justenmg 4:99de9b4005d2 400 {
justenmg 5:a658cda1d619 401 for(int i=0; i < FFT_LENGTH; i++)
justenmg 4:99de9b4005d2 402 {
justenmg 4:99de9b4005d2 403 if(i < WIN_NUM_TAPS)
justenmg 4:99de9b4005d2 404 {
justenmg 6:291e341f0d71 405 fft_of_filter[2*i] = win_filter_coeffs[i];
justenmg 6:291e341f0d71 406 fft_of_filter[2*i+1] = 0;
justenmg 4:99de9b4005d2 407 }
justenmg 4:99de9b4005d2 408 else
justenmg 4:99de9b4005d2 409 {
justenmg 6:291e341f0d71 410 fft_of_filter[2*i] = 0;
justenmg 6:291e341f0d71 411 fft_of_filter[2*i+1] = 0;
justenmg 4:99de9b4005d2 412 }
justenmg 4:99de9b4005d2 413 }
justenmg 4:99de9b4005d2 414
justenmg 4:99de9b4005d2 415 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_of_filter, 0, 1);
justenmg 4:99de9b4005d2 416
justenmg 4:99de9b4005d2 417 return;
justenmg 4:99de9b4005d2 418 }
justenmg 5:a658cda1d619 419
justenmg 6:291e341f0d71 420