initial

Dependencies:   mbed BSP_DISCO_F746NG mbed-dsp

Committer:
justenmg
Date:
Fri Mar 06 01:41:05 2020 +0000
Revision:
5:a658cda1d619
Parent:
4:99de9b4005d2
Child:
6:291e341f0d71
march 5

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