Other Parts Discussed in Thread: BOOSTXL-AUDIO,
Tool/software:
Hello,
I am working on The MSP430FR5994 to applu FFT on captured signal using BOOSTXL-AUDIO, so after doing the signal acquisition I am applyting the function runFftWithLea on the voice signal Buffer
, the function is designed to perform a Fast Fourier Transform (FFT) on segments of a buffer containing 16-bit unsigned integer (uint16_t) samples. So the logic behinf this function is
- The function processes the input buffer in segments (
taille_totale
indicates the total size of the buffer). -
- For each segment, the function calculates the mean value to center the data around zero. This helps in reducing DC offset in the signal.
-
Zero Padding:
- Zero padding is applied symmetrically around the segment to improve FFT resolution. This involves adding zeros before and after the actual data segment.
-
Data Preparation:
- The data is prepared for FFT by converting the 16-bit unsigned integers to
_q15
format, which is a fixed-point representation used in DSP. This involves centering the data around zero and scaling.
- The data is prepared for FFT by converting the 16-bit unsigned integers to
-
FFT Computation:
- The complex FFT is applied to the prepared data using the LEA module. This transforms the time-domain data into the frequency domain.
-
Magnitude Calculation:
- For each FFT coefficient, the magnitude is computed. This involves calculating the square of the real and imaginary parts, summing them, and then taking the square root.
- The magnitude is approximated due to the fixed-point representation constraints.
-
Magnitude Conversion and Transmission:
- The magnitudes are converted from
_q15
format touint16_t
for easier interpretation and transmission. - The magnitudes are then sent via UART for further processing or display.
- The magnitudes are converted from
The problem is BuffCopy1 and buffCopy are not filled and basically the FFT is not returning any values
#pragma PERSISTENT(buffCopy1); uint16_t buffCopy1[FFT_LENGTH] = {0}; DSPLIB_DATA(buffCopy, MSP_ALIGN_CMPLX_FFT_Q15(FFT_LENGTH)) _q15 buffCopy[FFT_LENGTH * 2]; DSPLIB_DATA(magnitude_q15, 4) _q15 magnitude_q15[FFT_LENGTH]; DSPLIB_DATA(magnitude_uint16, 4) uint16_t magnitude_uint16[FFT_LENGTH]; /* Hamming window parameters */ int32_t real_sq, imag_sq; msp_status status; //static msp_mpy_q15_params mpyParams; msp_fft_q15_params fftParams; void runFftWithLea(uint16_t *buffer, int taille_totale) { uint16_t i; int position = 0; //uint16_t shift; //int16_t inter, real1, imag1; _q15 real, imag, real_squared, imag_squared, sum_of_squares, magnitude; fftParams.length = FFT_LENGTH; fftParams.bitReverse = 1; fftParams.twiddleTable = msp_cmplx_twiddle_table_256_q15; uint16_t b; // Initialiser le module LEA et les paramètres de la FFT msp_lea_init(); initUART(); while (position < taille_totale) { // Calculer la moyenne des valeurs dans le segment float moyenne = 0; uint16_t m; for (i = 0; i < taille_totale; i++) { //if (position + i < taille_totale) { moyenne += buffer[position + i]; //} } moyenne /= FFT_LENGTH; m= (uint16_t)round (moyenne); // Copier le segment de 128 échantillons dans buffCopy1 avec zero-padding symétrique int zero_padding = 64; // Nombre de zéros à ajouter de chaque côté for (i = 0; i < FFT_LENGTH + 2 * zero_padding; i++) { if (i < zero_padding || i >= FFT_LENGTH + zero_padding) { buffCopy1[i] = 0; // Remplissage zéro } else { b = (buffer[position + i - zero_padding]); buffCopy1[i] = b - m; } } int j=0; for (j = 0; j < 256; j++) { // Convertir la valeur uint16_t en _q15 // Soustraire 2048 pour centrer autour de 0 // Multiplier par 16 pour utiliser toute la plage _q15 int32_t temp = ((int32_t)buffCopy1[i] - 2048) * 16; // Saturer à la plage _q15 (-32768 à 32767) if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768; buffCopy[i] = (int16_t)temp; } // Appliquer la FFT complexe sur le segment buffCopy status = msp_cmplx_fft_fixed_q15(&fftParams, buffCopy);//la il y'a un probleme msp_checkStatus(status); // Calculer la magnitude pour chaque coefficient FFT for (i = 0; i < FFT_LENGTH; i++) { real = buffCopy[2 * i]; imag = buffCopy[2 * i + 1]; // Calculer le carré de la partie réelle et imaginaire real_squared = __q15mpy(real, real); // Utilisation de la multiplication Q15 imag_squared = __q15mpy(imag, imag); // Calculer la somme des carrés avec saturation sum_of_squares = real_squared + imag_squared; // Calculer la magnitude comme racine carrée (approximative) // Ici, sqrt est approximée par une simple division et ajustement de la précision magnitude = (_q15)sqrt(sum_of_squares); // Convertir en _q15 magnitude_q15[i] = magnitude; } // Convertir les valeurs de magnitude en uint16_t for (i = 0; i < FFT_LENGTH; i++) { // Convertir _q15 (plage -1 à 1) à uint16_t (plage 0 à 4096) magnitude_uint16[i] = (uint16_t)((magnitude_q15[i] * MAX_VALUE)>>15); } UART_sendBuffer(magnitude_uint16, FFT_LENGTH); position += FFT_LENGTH; } } void runFftWithLea(uint16_t *buffer, int taille_totale) { uint16_t i; int position = 0; //uint16_t shift; //int16_t inter, real1, imag1; _q15 real, imag, real_squared, imag_squared, sum_of_squares, magnitude; fftParams.length = FFT_LENGTH; fftParams.bitReverse = 1; fftParams.twiddleTable = msp_cmplx_twiddle_table_256_q15; uint16_t b; // Initialiser le module LEA et les paramètres de la FFT msp_lea_init(); initUART(); while (position < taille_totale) { // Calculer la moyenne des valeurs dans le segment float moyenne = 0; uint16_t m; for (i = 0; i < taille_totale; i++) { //if (position + i < taille_totale) { moyenne += buffer[position + i]; //} } moyenne /= FFT_LENGTH; m= (uint16_t)round (moyenne); // Copier le segment de 128 échantillons dans buffCopy1 avec zero-padding symétrique int zero_padding = 64; // Nombre de zéros à ajouter de chaque côté for (i = 0; i < FFT_LENGTH + 2 * zero_padding; i++) { if (i < zero_padding || i >= FFT_LENGTH + zero_padding) { buffCopy1[i] = 0; // Remplissage zéro } else { b = (buffer[position + i - zero_padding]); buffCopy1[i] = b - m; } } int j=0; for (j = 0; j < 256; j++) { // Convertir la valeur uint16_t en _q15 // Soustraire 2048 pour centrer autour de 0 // Multiplier par 16 pour utiliser toute la plage _q15 int32_t temp = ((int32_t)buffCopy1[i] - 2048) * 16; // Saturer à la plage _q15 (-32768 à 32767) if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768; buffCopy[i] = (int16_t)temp; } // Appliquer la FFT complexe sur le segment buffCopy status = msp_cmplx_fft_fixed_q15(&fftParams, buffCopy);//la il y'a un probleme msp_checkStatus(status); // Calculer la magnitude pour chaque coefficient FFT for (i = 0; i < FFT_LENGTH; i++) { real = buffCopy[2 * i]; imag = buffCopy[2 * i + 1]; // Calculer le carré de la partie réelle et imaginaire real_squared = __q15mpy(real, real); // Utilisation de la multiplication Q15 imag_squared = __q15mpy(imag, imag); // Calculer la somme des carrés avec saturation sum_of_squares = real_squared + imag_squared; // Calculer la magnitude comme racine carrée (approximative) // Ici, sqrt est approximée par une simple division et ajustement de la précision magnitude = (_q15)sqrt(sum_of_squares); // Convertir en _q15 magnitude_q15[i] = magnitude; } // Convertir les valeurs de magnitude en uint16_t for (i = 0; i < FFT_LENGTH; i++) { // Convertir _q15 (plage -1 à 1) à uint16_t (plage 0 à 4096) magnitude_uint16[i] = (uint16_t)((magnitude_q15[i] * MAX_VALUE)>>15); } UART_sendBuffer(magnitude_uint16, FFT_LENGTH); position += FFT_LENGTH; } }
Here is the code.If there is any missing configuration or error in the code could you please tell me