initial

Dependencies:   mbed BSP_DISCO_F746NG mbed-dsp

Committer:
justenmg
Date:
Wed Mar 04 00:55:43 2020 +0000
Revision:
4:99de9b4005d2
Parent:
3:51e15bd15778
Child:
5:a658cda1d619
march 3

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 1:103e3e426b55 32 #define BUFFER_LENGTH (WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1)
justenmg 4:99de9b4005d2 33 #define FFT_BUFFER_LENGTH 2048
bmazzeo 0:c0f52e8223fe 34
bmazzeo 0:c0f52e8223fe 35 /* For Lab Exercise */
justenmg 4:99de9b4005d2 36 #define Lab_Execution_Type 3
justenmg 1:103e3e426b55 37
justenmg 1:103e3e426b55 38 float32_t lState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1];
justenmg 1:103e3e426b55 39 float32_t rState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1];
bmazzeo 0:c0f52e8223fe 40
justenmg 1:103e3e426b55 41 float32_t l_buf[BUFFER_LENGTH];
justenmg 1:103e3e426b55 42 float32_t r_buf[BUFFER_LENGTH];
bmazzeo 0:c0f52e8223fe 43
justenmg 1:103e3e426b55 44 arm_fir_instance_f32 filter_left;
justenmg 1:103e3e426b55 45 arm_fir_instance_f32 filter_right;
bmazzeo 0:c0f52e8223fe 46
justenmg 4:99de9b4005d2 47 float32_t fft_buf[FFT_BUFFER_LENGTH];
justenmg 4:99de9b4005d2 48
justenmg 4:99de9b4005d2 49 float32_t fft_of_filter[FFT_BUFFER_LENGTH];
justenmg 4:99de9b4005d2 50
justenmg 4:99de9b4005d2 51
justenmg 4:99de9b4005d2 52
justenmg 4:99de9b4005d2 53
justenmg 4:99de9b4005d2 54
bmazzeo 0:c0f52e8223fe 55 /* FUNCTION DEFINITIONS BELOW */
bmazzeo 0:c0f52e8223fe 56
bmazzeo 0:c0f52e8223fe 57 /**
bmazzeo 0:c0f52e8223fe 58 * @brief Initialize filter structures to be used in loops later
bmazzeo 0:c0f52e8223fe 59 * @retval None
bmazzeo 0:c0f52e8223fe 60 */
justenmg 4:99de9b4005d2 61 void initalize_signal_processing(void)
justenmg 4:99de9b4005d2 62 {
bmazzeo 0:c0f52e8223fe 63
bmazzeo 0:c0f52e8223fe 64 switch (Lab_Execution_Type)
bmazzeo 0:c0f52e8223fe 65 {
bmazzeo 0:c0f52e8223fe 66 case 0: // Passthrough case
bmazzeo 0:c0f52e8223fe 67 break;
bmazzeo 0:c0f52e8223fe 68
bmazzeo 0:c0f52e8223fe 69 case 1: // FIR case (ARM)
justenmg 1:103e3e426b55 70 arm_fir_init_f32(&filter_left, NUM_TAPS, (float32_t *)&Filter_coeffs, (float32_t *)&lState, AUDIO_BLOCK_SAMPLES);
justenmg 1:103e3e426b55 71 arm_fir_init_f32(&filter_right, NUM_TAPS, (float32_t *)&Filter_coeffs, (float32_t *)&rState, AUDIO_BLOCK_SAMPLES);
bmazzeo 0:c0f52e8223fe 72 break;
bmazzeo 0:c0f52e8223fe 73
bmazzeo 0:c0f52e8223fe 74 case 2: // FIR case (student)
justenmg 1:103e3e426b55 75 arm_fir_init_f32(&filter_left, OUR_NUM_TAPS, (float32_t *)&our_Filter_coeffs, (float32_t *)&lState, AUDIO_BLOCK_SAMPLES);
justenmg 1:103e3e426b55 76 arm_fir_init_f32(&filter_right, OUR_NUM_TAPS, (float32_t *)&our_Filter_coeffs, (float32_t *)&rState, AUDIO_BLOCK_SAMPLES);
bmazzeo 0:c0f52e8223fe 77 break;
bmazzeo 0:c0f52e8223fe 78
bmazzeo 0:c0f52e8223fe 79 case 3: // FFT Overlap-add
justenmg 4:99de9b4005d2 80 filter_conv_init();
bmazzeo 0:c0f52e8223fe 81 break;
bmazzeo 0:c0f52e8223fe 82
justenmg 4:99de9b4005d2 83 case 4: // FFT Overlap-add
justenmg 4:99de9b4005d2 84 filter_fft_init();
justenmg 4:99de9b4005d2 85 break;
justenmg 4:99de9b4005d2 86
justenmg 4:99de9b4005d2 87 case 5: // FFT Overlap-add with real-imag efficiency
justenmg 4:99de9b4005d2 88 filter_fft_init();
justenmg 4:99de9b4005d2 89 break;
justenmg 4:99de9b4005d2 90
justenmg 4:99de9b4005d2 91 case 6: // OS FFT RI
justenmg 4:99de9b4005d2 92 filter_fft_init();
bmazzeo 0:c0f52e8223fe 93 break;
bmazzeo 0:c0f52e8223fe 94
bmazzeo 0:c0f52e8223fe 95
bmazzeo 0:c0f52e8223fe 96 }
bmazzeo 0:c0f52e8223fe 97 }
bmazzeo 0:c0f52e8223fe 98
bmazzeo 0:c0f52e8223fe 99 /**
bmazzeo 0:c0f52e8223fe 100 * @brief Process audio channel signals
bmazzeo 0:c0f52e8223fe 101 * @param L_channel_in: Pointer to Left channel data input (float32_t)
bmazzeo 0:c0f52e8223fe 102 * @param R_channel_in: Pointer to Right channel data input (float32_t)
bmazzeo 0:c0f52e8223fe 103 * @param L_channel_out: Pointer to Left channel data output (float32_t)
bmazzeo 0:c0f52e8223fe 104 * @param R_channel_out: Pointer to Right channel data output (float32_t)
bmazzeo 0:c0f52e8223fe 105 * @param Signal_Length: length of data to process
bmazzeo 0:c0f52e8223fe 106 * @retval None
bmazzeo 0:c0f52e8223fe 107 */
bmazzeo 0:c0f52e8223fe 108 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 109 {
bmazzeo 0:c0f52e8223fe 110 char buf[70];
bmazzeo 0:c0f52e8223fe 111 BSP_LCD_SetFont(&Font8);
bmazzeo 0:c0f52e8223fe 112 BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
bmazzeo 0:c0f52e8223fe 113 sprintf(buf, "Processing Signals" );
bmazzeo 0:c0f52e8223fe 114 BSP_LCD_DisplayStringAt(0, 200, (uint8_t *) buf, LEFT_MODE);
bmazzeo 0:c0f52e8223fe 115
bmazzeo 0:c0f52e8223fe 116 switch(Lab_Execution_Type)
bmazzeo 0:c0f52e8223fe 117 {
bmazzeo 0:c0f52e8223fe 118 case 0: // Passthrough case
justenmg 2:89234085faae 119 arm_copy_f32(L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 120 arm_copy_f32(R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 121 break;
bmazzeo 0:c0f52e8223fe 122
bmazzeo 0:c0f52e8223fe 123 case 1: // FIR case (ARM)
justenmg 2:89234085faae 124 arm_fir_f32(&filter_left, L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 125 arm_fir_f32(&filter_right, R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 126 break;
bmazzeo 0:c0f52e8223fe 127
bmazzeo 0:c0f52e8223fe 128 case 2: // FIR case (student)
justenmg 2:89234085faae 129 arm_fir_f32(&filter_left, L_channel_in, L_channel_out, Signal_Length);
justenmg 2:89234085faae 130 arm_fir_f32(&filter_right, R_channel_in, R_channel_out, Signal_Length);
bmazzeo 0:c0f52e8223fe 131 break;
bmazzeo 0:c0f52e8223fe 132
justenmg 4:99de9b4005d2 133 case 3: // OA CONV
justenmg 4:99de9b4005d2 134 filter_OA_CONV(l_buf, L_channel_in, L_channel_out, Signal_Length, BUFFER_LENGTH);
justenmg 4:99de9b4005d2 135 filter_OA_CONV(r_buf, R_channel_in, R_channel_out, Signal_Length, BUFFER_LENGTH);
bmazzeo 0:c0f52e8223fe 136 break;
bmazzeo 0:c0f52e8223fe 137
justenmg 4:99de9b4005d2 138 case 4: // OA FFT Overlap-add
justenmg 4:99de9b4005d2 139
justenmg 4:99de9b4005d2 140 break;
justenmg 4:99de9b4005d2 141
justenmg 4:99de9b4005d2 142 case 5: // FFT Overlap-add with real-imag efficiency
justenmg 4:99de9b4005d2 143
justenmg 4:99de9b4005d2 144 break;
justenmg 4:99de9b4005d2 145
justenmg 4:99de9b4005d2 146 case 6: // OS FFT RI
justenmg 4:99de9b4005d2 147
justenmg 4:99de9b4005d2 148
bmazzeo 0:c0f52e8223fe 149 break;
bmazzeo 0:c0f52e8223fe 150
bmazzeo 0:c0f52e8223fe 151
bmazzeo 0:c0f52e8223fe 152 }
bmazzeo 0:c0f52e8223fe 153 /* Change font back */
bmazzeo 0:c0f52e8223fe 154 BSP_LCD_SetFont(&Font16);
bmazzeo 0:c0f52e8223fe 155 }
justenmg 1:103e3e426b55 156
justenmg 2:89234085faae 157 //buffer: pointer to the storage buffer for the filter output
justenmg 2:89234085faae 158 //buf_length: the length of the storage buffer (len_filter + len_batch - 1)
justenmg 4:99de9b4005d2 159 void filter_OA_CONV(float32_t* overlap_buffer, float32_t* d_in, float32_t* d_out, uint16_t sig_length, uint16_t buf_length)
justenmg 1:103e3e426b55 160 {
justenmg 4:99de9b4005d2 161 float32_t* data_sample = d_in;
justenmg 3:51e15bd15778 162 float32_t* filter_sample = win_filter_coeffs;
justenmg 1:103e3e426b55 163 float32_t result = 0;
justenmg 2:89234085faae 164 uint16_t conv_length = 0;
justenmg 2:89234085faae 165
justenmg 2:89234085faae 166 //convolve and save to buffer
justenmg 4:99de9b4005d2 167 /*
justenmg 2:89234085faae 168 for(uint16_t shift = 0; shift < buf_length; shift++)
justenmg 1:103e3e426b55 169 {
justenmg 2:89234085faae 170 //shift
justenmg 3:51e15bd15778 171 if(shift < sig_length)
justenmg 2:89234085faae 172 {
justenmg 2:89234085faae 173 conv_length = shift + 1;
justenmg 2:89234085faae 174 }
justenmg 3:51e15bd15778 175 else if(shift >= sig_length && shift < WIN_NUM_TAPS)
justenmg 2:89234085faae 176 {
justenmg 3:51e15bd15778 177 conv_length = sig_length;
justenmg 2:89234085faae 178 }
justenmg 3:51e15bd15778 179 else if(shift >= WIN_NUM_TAPS)
justenmg 2:89234085faae 180 {
justenmg 3:51e15bd15778 181 conv_length = sig_length - (shift - WIN_NUM_TAPS + 1);
justenmg 2:89234085faae 182 }
justenmg 2:89234085faae 183
justenmg 2:89234085faae 184 result = 0;
justenmg 2:89234085faae 185 //multiply-add
justenmg 3:51e15bd15778 186 for(int i=0; i<conv_length; i++)
justenmg 2:89234085faae 187 {
justenmg 4:99de9b4005d2 188 result += (filter_sample[i]) * (data_sample[shift - i]);
justenmg 2:89234085faae 189 }
justenmg 2:89234085faae 190
justenmg 2:89234085faae 191 // save to the buffer
justenmg 4:99de9b4005d2 192 overlap_buffer[shift] += result;
justenmg 4:99de9b4005d2 193 }
justenmg 4:99de9b4005d2 194 */
justenmg 4:99de9b4005d2 195 for(int i=0; i < buf_length; i++)
justenmg 4:99de9b4005d2 196 {
justenmg 4:99de9b4005d2 197 if(i < sig_length)
justenmg 4:99de9b4005d2 198 {
justenmg 4:99de9b4005d2 199 overlap_buffer[i] = data_sample[i];
justenmg 4:99de9b4005d2 200 }
justenmg 4:99de9b4005d2 201 else
justenmg 4:99de9b4005d2 202 {
justenmg 4:99de9b4005d2 203 overlap_buffer[i] = 0;
justenmg 4:99de9b4005d2 204 }
justenmg 4:99de9b4005d2 205 }
justenmg 4:99de9b4005d2 206
justenmg 4:99de9b4005d2 207 //copy from buffer to d_out, shift buffer, zero pad
justenmg 4:99de9b4005d2 208 for(int i=0; i < buf_length; i++)
justenmg 4:99de9b4005d2 209 {
justenmg 4:99de9b4005d2 210 if(i < sig_length)
justenmg 4:99de9b4005d2 211 {
justenmg 4:99de9b4005d2 212 d_out[i] = overlap_buffer[i];
justenmg 4:99de9b4005d2 213 overlap_buffer[i] = overlap_buffer[i+sig_length];
justenmg 4:99de9b4005d2 214 }
justenmg 4:99de9b4005d2 215 else
justenmg 4:99de9b4005d2 216 {
justenmg 4:99de9b4005d2 217 overlap_buffer[i] = 0;
justenmg 4:99de9b4005d2 218 }
justenmg 4:99de9b4005d2 219 }
justenmg 4:99de9b4005d2 220 return;
justenmg 4:99de9b4005d2 221 }
justenmg 4:99de9b4005d2 222
justenmg 4:99de9b4005d2 223
justenmg 4:99de9b4005d2 224
justenmg 4:99de9b4005d2 225 void filter_OA_FFT(float32_t* buffer_begin, float32_t* buffer_head, uint16_t buffer_head_idx, float32_t* d_in, float32_t* d_out, uint16_t sig_length, uint16_t buf_length)
justenmg 4:99de9b4005d2 226 {
justenmg 4:99de9b4005d2 227 /*float32_t* data_sample = d_in+sig_length-1;
justenmg 4:99de9b4005d2 228 float32_t* filter_sample = win_filter_coeffs;
justenmg 4:99de9b4005d2 229 float32_t result = 0;
justenmg 4:99de9b4005d2 230 float32_t* buffer_data_location = buffer_head;
justenmg 4:99de9b4005d2 231
justenmg 4:99de9b4005d2 232 for(uint16_t i = 0; i < FFT_BUFFER_LENGTH; i++)
justenmg 4:99de9b4005d2 233 {
justenmg 4:99de9b4005d2 234 fft_buf[i] = d_in[i];
justenmg 4:99de9b4005d2 235 }
justenmg 4:99de9b4005d2 236
justenmg 4:99de9b4005d2 237 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buf, 0, 1);
justenmg 4:99de9b4005d2 238
justenmg 4:99de9b4005d2 239 for(uint16_t i = 0; i < FFT_BUFFER_LENGTH; i++)
justenmg 4:99de9b4005d2 240 {
justenmg 4:99de9b4005d2 241 fft_buf[i] = fft_buf[i]*fft_of_filter[i];
justenmg 4:99de9b4005d2 242 }
justenmg 4:99de9b4005d2 243
justenmg 4:99de9b4005d2 244 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buf, 1, 1);
justenmg 4:99de9b4005d2 245
justenmg 4:99de9b4005d2 246
justenmg 4:99de9b4005d2 247 // save to buffer
justenmg 4:99de9b4005d2 248 for(uint16_t i = 0; i < buf_length; i++)
justenmg 4:99de9b4005d2 249 {
justenmg 4:99de9b4005d2 250
justenmg 4:99de9b4005d2 251 // save to the buffer
justenmg 4:99de9b4005d2 252 *buffer_data_location += fft_buf[i];
justenmg 2:89234085faae 253 //increment, looping back to beginning of buffer
justenmg 2:89234085faae 254 if(buffer_data_location == (buffer_begin + buf_length - 1))
justenmg 2:89234085faae 255 {
justenmg 2:89234085faae 256 buffer_data_location = buffer_begin;
justenmg 2:89234085faae 257 }
justenmg 2:89234085faae 258 else
justenmg 2:89234085faae 259 {
justenmg 2:89234085faae 260 buffer_data_location++;
justenmg 2:89234085faae 261 }
justenmg 1:103e3e426b55 262 }
justenmg 2:89234085faae 263
justenmg 2:89234085faae 264 //copy from buffer to d_out
justenmg 2:89234085faae 265 buffer_data_location = buffer_head;
justenmg 3:51e15bd15778 266 for(int i=0; i < sig_length; i++)
justenmg 2:89234085faae 267 {
justenmg 2:89234085faae 268 d_out[i] = *buffer_data_location;
justenmg 2:89234085faae 269 *buffer_data_location = 0;
justenmg 2:89234085faae 270 //increment, looping back to beginning of buffer
justenmg 2:89234085faae 271 if(buffer_data_location + i == (buffer_begin + buf_length - 1))
justenmg 2:89234085faae 272 {
justenmg 2:89234085faae 273 buffer_data_location = buffer_begin;
justenmg 2:89234085faae 274 }
justenmg 2:89234085faae 275 else
justenmg 2:89234085faae 276 {
justenmg 2:89234085faae 277 buffer_data_location++;
justenmg 2:89234085faae 278 }
justenmg 4:99de9b4005d2 279 }*/
justenmg 4:99de9b4005d2 280 return;
justenmg 4:99de9b4005d2 281 }
justenmg 4:99de9b4005d2 282
justenmg 4:99de9b4005d2 283
justenmg 4:99de9b4005d2 284
justenmg 4:99de9b4005d2 285 void filter_OA_FFT_RI(float32_t* buffer_begin, float32_t* buffer_head, uint16_t buffer_head_idx, float32_t* d_in, float32_t* d_out, uint16_t sig_length, uint16_t buf_length)
justenmg 4:99de9b4005d2 286 {
justenmg 2:89234085faae 287 return;
justenmg 1:103e3e426b55 288 }
justenmg 1:103e3e426b55 289
justenmg 4:99de9b4005d2 290
justenmg 4:99de9b4005d2 291
justenmg 4:99de9b4005d2 292 void filter_OS_FFT_RI(float32_t* buffer_begin, float32_t* buffer_head, uint16_t buffer_head_idx, float32_t* d_in, float32_t* d_out, uint16_t sig_length, uint16_t buf_length)
justenmg 4:99de9b4005d2 293 {
justenmg 4:99de9b4005d2 294 return;
justenmg 4:99de9b4005d2 295 }
justenmg 4:99de9b4005d2 296
justenmg 4:99de9b4005d2 297
justenmg 4:99de9b4005d2 298
justenmg 4:99de9b4005d2 299
justenmg 4:99de9b4005d2 300
justenmg 4:99de9b4005d2 301
justenmg 4:99de9b4005d2 302 void filter_conv_init()
justenmg 1:103e3e426b55 303 {
justenmg 2:89234085faae 304 for(int i=0; i < BUFFER_LENGTH; i++)
justenmg 1:103e3e426b55 305 {
justenmg 2:89234085faae 306 l_buf[i] = 0;
justenmg 2:89234085faae 307 r_buf[i] = 0;
justenmg 1:103e3e426b55 308 }
justenmg 3:51e15bd15778 309 return;
justenmg 1:103e3e426b55 310 }
justenmg 4:99de9b4005d2 311
justenmg 4:99de9b4005d2 312
justenmg 4:99de9b4005d2 313
justenmg 4:99de9b4005d2 314 void filter_fft_init()
justenmg 4:99de9b4005d2 315 {
justenmg 4:99de9b4005d2 316 for(int i=0; i < FFT_BUFFER_LENGTH; i++)
justenmg 4:99de9b4005d2 317 {
justenmg 4:99de9b4005d2 318 if(i < WIN_NUM_TAPS)
justenmg 4:99de9b4005d2 319 {
justenmg 4:99de9b4005d2 320 fft_of_filter[i] = win_filter_coeffs[i];
justenmg 4:99de9b4005d2 321 }
justenmg 4:99de9b4005d2 322 else
justenmg 4:99de9b4005d2 323 {
justenmg 4:99de9b4005d2 324 fft_of_filter[i] = 0;
justenmg 4:99de9b4005d2 325 }
justenmg 4:99de9b4005d2 326 }
justenmg 4:99de9b4005d2 327
justenmg 4:99de9b4005d2 328 arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_of_filter, 0, 1);
justenmg 4:99de9b4005d2 329
justenmg 4:99de9b4005d2 330 return;
justenmg 4:99de9b4005d2 331 }