initial
Dependencies: mbed BSP_DISCO_F746NG mbed-dsp
Diff: signal_processing.cpp
- Revision:
- 5:a658cda1d619
- Parent:
- 4:99de9b4005d2
- Child:
- 6:291e341f0d71
diff -r 99de9b4005d2 -r a658cda1d619 signal_processing.cpp --- a/signal_processing.cpp Wed Mar 04 00:55:43 2020 +0000 +++ b/signal_processing.cpp Fri Mar 06 01:41:05 2020 +0000 @@ -29,11 +29,16 @@ ** ------------------------------------------------------------------- */ #define AUDIO_BLOCK_SAMPLES ((uint32_t)128) // Number of samples (L and R) in audio block (each samples is 16 bits) -#define BUFFER_LENGTH (WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1) -#define FFT_BUFFER_LENGTH 2048 +#define CONV_LENGTH (WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1) +#define BUFFER_LENGTH (WIN_NUM_TAPS - 1) +#define FFT_BUFFER_LENGTH 2048 +#define FFT_LENGTH 1024 +#define PADDED_FILTER_LENGTH (WIN_NUM_TAPS + 2*(AUDIO_BLOCK_SAMPLES - 1)) /* For Lab Exercise */ -#define Lab_Execution_Type 3 +#define Lab_Execution_Type 6 + +float32_t padded_filter[PADDED_FILTER_LENGTH]; float32_t lState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1]; float32_t rState[NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1]; @@ -41,17 +46,18 @@ float32_t l_buf[BUFFER_LENGTH]; float32_t r_buf[BUFFER_LENGTH]; +float32_t l_buf2[FFT_LENGTH]; +float32_t r_buf2[FFT_LENGTH]; + arm_fir_instance_f32 filter_left; arm_fir_instance_f32 filter_right; float32_t fft_buf[FFT_BUFFER_LENGTH]; +float32_t ifft_buf[FFT_BUFFER_LENGTH]; float32_t fft_of_filter[FFT_BUFFER_LENGTH]; - - - /* FUNCTION DEFINITIONS BELOW */ /** @@ -76,7 +82,7 @@ arm_fir_init_f32(&filter_right, OUR_NUM_TAPS, (float32_t *)&our_Filter_coeffs, (float32_t *)&rState, AUDIO_BLOCK_SAMPLES); break; - case 3: // FFT Overlap-add + case 3: // conv Overlap-add filter_conv_init(); break; @@ -131,21 +137,21 @@ break; case 3: // OA CONV - filter_OA_CONV(l_buf, L_channel_in, L_channel_out, Signal_Length, BUFFER_LENGTH); - filter_OA_CONV(r_buf, R_channel_in, R_channel_out, Signal_Length, BUFFER_LENGTH); + filter_OA_CONV(l_buf, L_channel_in, L_channel_out, Signal_Length); + filter_OA_CONV(r_buf, R_channel_in, R_channel_out, Signal_Length); break; case 4: // OA FFT Overlap-add - + filter_OA_FFT(l_buf, fft_buf, ifft_buf, L_channel_in, L_channel_out, Signal_Length); + filter_OA_FFT(r_buf, fft_buf, ifft_buf, R_channel_in, R_channel_out, Signal_Length); break; case 5: // FFT Overlap-add with real-imag efficiency - + 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); break; case 6: // OS FFT RI - - + 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); break; @@ -156,65 +162,35 @@ //buffer: pointer to the storage buffer for the filter output //buf_length: the length of the storage buffer (len_filter + len_batch - 1) -void filter_OA_CONV(float32_t* overlap_buffer, float32_t* d_in, float32_t* d_out, uint16_t sig_length, uint16_t buf_length) + +void filter_OA_CONV(float32_t* overlap_buffer, float32_t* d_in, float32_t* d_out, uint16_t sig_length) { - float32_t* data_sample = d_in; - float32_t* filter_sample = win_filter_coeffs; float32_t result = 0; - uint16_t conv_length = 0; - //convolve and save to buffer - /* - for(uint16_t shift = 0; shift < buf_length; shift++) + //shift the data sample and convolve + for(uint16_t shift = 0; shift < CONV_LENGTH; shift++) { - //shift + result = 0; + //multiply-add the shifted, reversed data sample to the padded filter + for(int i=0; i<sig_length; i++) + { + result += padded_filter[i + shift] * d_in[i]; + } + + // overlap-add to the buffer + //overlap_buffer[shift] += result; + if(shift < sig_length) { - conv_length = shift + 1; - } - else if(shift >= sig_length && shift < WIN_NUM_TAPS) - { - conv_length = sig_length; - } - else if(shift >= WIN_NUM_TAPS) - { - conv_length = sig_length - (shift - WIN_NUM_TAPS + 1); + d_out[shift] = overlap_buffer[shift] + result; } - - result = 0; - //multiply-add - for(int i=0; i<conv_length; i++) + else if(shift < BUFFER_LENGTH) { - result += (filter_sample[i]) * (data_sample[shift - i]); - } - - // save to the buffer - overlap_buffer[shift] += result; - } - */ - for(int i=0; i < buf_length; i++) - { - if(i < sig_length) - { - overlap_buffer[i] = data_sample[i]; + overlap_buffer[shift - sig_length] = overlap_buffer[shift] + result; } else { - overlap_buffer[i] = 0; - } - } - - //copy from buffer to d_out, shift buffer, zero pad - for(int i=0; i < buf_length; i++) - { - if(i < sig_length) - { - d_out[i] = overlap_buffer[i]; - overlap_buffer[i] = overlap_buffer[i+sig_length]; - } - else - { - overlap_buffer[i] = 0; + overlap_buffer[shift - sig_length] = result; } } return; @@ -222,75 +198,180 @@ -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) +void filter_OA_FFT( +float32_t* overlap_buffer, +float32_t* fft_buffer, +float32_t* ifft_buffer, +float32_t* d_in, +float32_t* d_out, +uint16_t sig_length) { - /*float32_t* data_sample = d_in+sig_length-1; - float32_t* filter_sample = win_filter_coeffs; - float32_t result = 0; - float32_t* buffer_data_location = buffer_head; - - for(uint16_t i = 0; i < FFT_BUFFER_LENGTH; i++) - { - fft_buf[i] = d_in[i]; - } - - arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buf, 0, 1); - - for(uint16_t i = 0; i < FFT_BUFFER_LENGTH; i++) + //fill the FFT buffer + for(int i=0; i < FFT_LENGTH; i++) { - fft_buf[i] = fft_buf[i]*fft_of_filter[i]; - } - - arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buf, 1, 1); - - - // save to buffer - for(uint16_t i = 0; i < buf_length; i++) - { - - // save to the buffer - *buffer_data_location += fft_buf[i]; - //increment, looping back to beginning of buffer - if(buffer_data_location == (buffer_begin + buf_length - 1)) + if(i < sig_length) { - buffer_data_location = buffer_begin; + fft_buffer[2*i] = d_in[i]; + fft_buffer[2*i+1] = 0; } else { - buffer_data_location++; + fft_buffer[2*i] = 0; + fft_buffer[2*i+1] = 0; } } - //copy from buffer to d_out - buffer_data_location = buffer_head; - for(int i=0; i < sig_length; i++) + //perform FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1); + + + //multiply with filter FFT + arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH); + + //perform inverse FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1); + + // overlap-add to the buffer + for(uint16_t i = 0; i < CONV_LENGTH; i++) { - d_out[i] = *buffer_data_location; - *buffer_data_location = 0; - //increment, looping back to beginning of buffer - if(buffer_data_location + i == (buffer_begin + buf_length - 1)) + if(i < sig_length) { - buffer_data_location = buffer_begin; + d_out[i] = ifft_buffer[2*i] + overlap_buffer[i]; + } + else if(i < BUFFER_LENGTH) + { + overlap_buffer[i - sig_length] = overlap_buffer[i] + ifft_buffer[2*i]; } else { - buffer_data_location++; + overlap_buffer[i - sig_length] = ifft_buffer[2*i]; } - }*/ + } return; } +//The overlap-add method uses previous outputs to adjust the filtered +//output to be more representative of the continuous version of the signal +void filter_OA_FFT_RI( + float32_t* overlap_buffer1, + float32_t* overlap_buffer2, + float32_t* fft_buffer, + float32_t* ifft_buffer, + float32_t* d_in1, + float32_t* d_in2, + float32_t* d_out1, + float32_t* d_out2, + uint16_t sig_length) +{ + //fill the FFT buffer + for(int i=0; i < FFT_LENGTH; i++) + { + if(i < sig_length) + { + fft_buffer[2*i] = d_in1[i]; + fft_buffer[2*i+1] = d_in2[i]; + } + else + { + fft_buffer[2*i] = 0; + fft_buffer[2*i+1] = 0; + } + } -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) -{ + //perform FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1); + + + //multiply with filter FFT + arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH); + + + //perform inverse FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1); + + // overlap-add to the buffer + for(uint16_t i = 0; i < CONV_LENGTH; i++) + { + if(i < sig_length) + { + d_out1[i] = ifft_buffer[2*i] + overlap_buffer1[i]; + d_out2[i] = ifft_buffer[2*i+1] + overlap_buffer2[i]; + } + else if(i < BUFFER_LENGTH) + { + overlap_buffer1[i - sig_length] = overlap_buffer1[i] + ifft_buffer[2*i]; + overlap_buffer2[i - sig_length] = overlap_buffer2[i] + ifft_buffer[2*i+1]; + } + else + { + overlap_buffer1[i - sig_length] = ifft_buffer[2*i]; + overlap_buffer2[i - sig_length] = ifft_buffer[2*i+1]; + } + } return; } - -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) +//The overlap-save method uses previous inputs to perform a +//more representative filtering operation +void filter_OS_FFT_RI( + float32_t* save_buffer1, + float32_t* save_buffer2, + float32_t* fft_buffer, + float32_t* ifft_buffer, + float32_t* d_in1, + float32_t* d_in2, + float32_t* d_out1, + float32_t* d_out2, + uint16_t sig_length) { + //shift the save buffers by the input data size + for(int i=0; i < FFT_LENGTH; i++) + { + if(i < FFT_LENGTH - sig_length) + { + save_buffer1[i] = save_buffer1[i+sig_length]; + save_buffer2[i] = save_buffer2[i+sig_length]; + } + else + { + save_buffer1[i] = 0; + save_buffer2[i] = 0; + } + } + + //insert new data into save buffer + for(int i=0; i < sig_length; i++) + { + save_buffer1[(FFT_LENGTH - sig_length) + i] = d_in1[i]; + save_buffer2[(FFT_LENGTH - sig_length) + i] = d_in2[i]; + } + + //fill the FFT buffer + for(int i=0; i < FFT_LENGTH; i++) + { + fft_buffer[2*i] = save_buffer1[i]; + fft_buffer[2*i+1] = save_buffer2[i]; + } + + //perform FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_buffer, 0, 1); + + + //multiply with filter FFT + arm_cmplx_mult_cmplx_f32(fft_buffer, fft_of_filter, ifft_buffer, FFT_LENGTH); + + + //perform inverse FFT in place + arm_cfft_f32(&arm_cfft_sR_f32_len1024, ifft_buffer, 1, 1); + + // copy to output buffer + for(uint16_t i = CONV_LENGTH - sig_length; i < CONV_LENGTH; i++) + { + d_out1[i] = ifft_buffer[2*i]; + d_out2[i] = ifft_buffer[2*i+1]; + } return; } @@ -306,6 +387,18 @@ l_buf[i] = 0; r_buf[i] = 0; } + for(int i=0; i < PADDED_FILTER_LENGTH; i++) + { + if((i < AUDIO_BLOCK_SAMPLES - 1) || (i >= WIN_NUM_TAPS + AUDIO_BLOCK_SAMPLES - 1)) + { + padded_filter[i] = 0; + } + else + { + padded_filter[i] = win_filter_coeffs[WIN_NUM_TAPS - 1 - (i - AUDIO_BLOCK_SAMPLES - 1)]; + } + } + return; } @@ -313,15 +406,17 @@ void filter_fft_init() { - for(int i=0; i < FFT_BUFFER_LENGTH; i++) + for(int i=0; i < FFT_LENGTH; i++) { if(i < WIN_NUM_TAPS) { - fft_of_filter[i] = win_filter_coeffs[i]; + fft_of_filter[2*i] = win_filter_coeffs[i]; + fft_of_filter[2*i+1] = 0; } else { - fft_of_filter[i] = 0; + fft_of_filter[2*i] = 0; + fft_of_filter[2*i+1] = 0; } } @@ -329,3 +424,4 @@ return; } +