Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed BSP_DISCO_F746NG mbed-dsp
spectrum.cpp
00001 #include "mbed.h" 00002 #include "stm32746g_discovery_lcd.h" 00003 #include "arm_math.h" 00004 #include "arm_const_structs.h" 00005 00006 #define AUDIO_BLOCK_SAMPLES ((uint32_t)128) // Number of samples (L and R) in audio block (each samples is 16 bits) 00007 #define DFT_SIZE 1024 00008 #define DFT_CMPLX_DATA_SIZE 2048 00009 #define FFT_TYPE arm_cfft_sR_f32_len1024 00010 00011 /* These definitions define the size of the oscilloscope that is used to display data. */ 00012 #define SPEC_ORIGIN_X_POS 100 00013 #define SPEC_X_LIMIT 256 00014 #define SPEC_ORIGIN_Y_POS 15 00015 #define SPEC_Y_LIMIT 100 00016 00017 /* For Lab Exercise */ 00018 #define Spectrum_Type 0 00019 00020 00021 float32_t l_input_buf[DFT_CMPLX_DATA_SIZE]; 00022 float32_t r_input_buf[DFT_CMPLX_DATA_SIZE]; 00023 00024 float32_t l_fft_buf[DFT_CMPLX_DATA_SIZE]; 00025 float32_t r_fft_buf[DFT_CMPLX_DATA_SIZE]; 00026 00027 float32_t l_display_spectrum[DFT_SIZE]; 00028 float32_t r_display_spectrum[DFT_SIZE]; 00029 00030 00031 void complx_dft(float32_t* dft_buffer, uint16_t dft_length) 00032 { 00033 uint16_t complx_dft_length = 2*dft_length; 00034 float32_t result[complx_dft_length]; 00035 float32_t W_n[2]; 00036 float32_t product[2]; 00037 00038 // k-loop 00039 for(uint16_t k = 0; k < dft_length; k++) 00040 { 00041 //n-loop 00042 for(int n=0; n < dft_length; n++) 00043 { 00044 //generate W_N^{kn} 00045 //calc theta 00046 float32_t theta = (2*k*n*PI)/dft_length; 00047 //calc real and imag parts of W 00048 arm_sin_cos_f32(theta, W_n+1, W_n); 00049 00050 //do the multiply 00051 arm_cmplx_mult_cmplx_f32(W_n, dft_buffer[2*n], product, 1); 00052 00053 //summation 00054 result[2*k] += product[0]; 00055 result[2*k+1] += product[1]; 00056 } 00057 } 00058 00059 //copy the result 00060 for(uint16_t k = 0; k < dft_length; k++) 00061 { 00062 dft_buffer[2*k] = result[2*k]; 00063 dft_buffer[2*k+1] = result[2*k+1]; 00064 } 00065 } 00066 00067 void FFT_audio_input(float32_t* L_channel_in, float32_t* R_channel_in, uint16_t Signal_Length) 00068 { 00069 Complex_Signal_Length = 2*Signal_Length; 00070 00071 //shift the buffers 00072 for(uint16_t i = 0; i < DFT_CMPLX_DATA_SIZE - Complex_Signal_Length; i++) 00073 { 00074 l_input_buf[i] = l_input_buf[i + Complex_Signal_Length]; 00075 r_input_buf[i] = r_input_buf[i + Complex_Signal_Length]; 00076 } 00077 00078 //insert the new data 00079 for(uint16_t i = DFT_SIZE - Signal_Length; i < DFT_SIZE; i++) 00080 { 00081 l_input_buf[2*i] = L_channel_in[i - DFT_SIZE + Signal_Length]; 00082 l_input_buf[2*i+1] = 0; 00083 r_input_buf[2*i] = r_input_buf[i - DFT_SIZE + Signal_Length]; 00084 r_input_buf[2*i+1] = 0; 00085 } 00086 00087 //copy to the fft buffer 00088 for(uint16_t i = 0; i < DFT_CMPLX_DATA_SIZE; i++) 00089 { 00090 l_fft_buf = l_input_buf[i]; 00091 r_fft_buf = r_input_buf[i]; 00092 } 00093 00094 //take the fft's 00095 arm_cfft_f32(&arm_cfft_sR_f32_len1024, l_fft_buf, 0, 1); 00096 arm_cfft_f32(&arm_cfft_sR_f32_len1024, r_fft_buf, 0, 1); 00097 00098 //do some extra math 00099 switch(Spectrum_Type) 00100 { 00101 case 0: // Two-channel spectrum analyzer - magnitude-squared version 00102 for(uint16_t i = 0 i < DFT_SIZE; i++) 00103 { 00104 l_display_spectrum[i] = l_fft_buf[2*i]^2 + l_fft_buf[2*i + 1]^2; 00105 r_display_spectrum[i] = r_fft_buf[2*i]^2 + r_fft_buf[2*i + 1]^2; 00106 } 00107 00108 00109 00110 00111 break; 00112 00113 case 1: // Two-channel spectrum analyzer - dB version 00114 break; 00115 00116 case 2: // Two-channel spectrum analyzer - dB Exponentially averaging version 00117 break; 00118 00119 case 3: // Single-channel spectrogram 00120 break; 00121 00122 00123 } 00124 } 00125 00126 00127 00128 00129 00130 00131 00132 void Draw_Spectrum_Background() 00133 { 00134 switch(Spectrum_Type) 00135 { 00136 case 0: // Two-channel spectrum analyzer - magnitude-squared version 00137 00138 break; 00139 00140 case 1: // Two-channel spectrum analyzer - dB version 00141 break; 00142 00143 case 2: // Two-channel spectrum analyzer - dB Exponentially averaging version 00144 break; 00145 00146 case 3: // Single-channel spectrogram 00147 break; 00148 00149 00150 } 00151 } 00152 00153 00154 00155 00156 00157 00158 00159 00160 /** 00161 * @brief erases the FFT currently being displayed 00162 * @param Xpos: X position 00163 * @param Ypos: Y position 00164 * @param Length: length of trace 00165 * @retval None 00166 */ 00167 void Erase_FFT(uint16_t Xpos, uint16_t Ypos, uint16_t Length) 00168 { 00169 /* Creates a brown rectangle above and below the axis */ 00170 BSP_LCD_SetTextColor(LCD_COLOR_BROWN); 00171 BSP_LCD_FillRect(Xpos, Ypos - AUDIO_DRAW_LIMIT, Length, AUDIO_DRAW_LIMIT); 00172 BSP_LCD_FillRect(Xpos, Ypos+1, Length, AUDIO_DRAW_LIMIT); 00173 00174 /* Draw axis for plotting */ 00175 BSP_LCD_SetTextColor(LCD_COLOR_WHITE); 00176 BSP_LCD_DrawHLine(Xpos, Ypos, Length); 00177 } 00178 00179 00180 /** 00181 * @brief Draws an FFT of the data line. 00182 * @param Xpos: X position 00183 * @param Ypos: Y position 00184 * @param Mem_start: Start of memory location 00185 * @param Length: length of trace 00186 * @retval None 00187 */ 00188 void Draw_FFT(uint16_t Xpos, uint16_t Ypos, uint16_t* Mem_start, uint16_t Length) 00189 { 00190 uint16_t i; 00191 uint16_t* mem_address; 00192 char buf[10]; 00193 int16_t L_audio_value; 00194 int16_t R_audio_value; 00195 00196 mem_address = Mem_start; 00197 00198 for (i=0; i<Length; i++) 00199 { 00200 R_audio_value = (int16_t) *mem_address; 00201 mem_address++; 00202 L_audio_value = (int16_t) *mem_address; 00203 mem_address++; 00204 00205 L_audio_value = L_audio_value / 100; 00206 R_audio_value = R_audio_value / 100; 00207 00208 if (L_audio_value > AUDIO_DRAW_LIMIT) {L_audio_value = AUDIO_DRAW_LIMIT;} 00209 else if (L_audio_value < -AUDIO_DRAW_LIMIT) {L_audio_value = -AUDIO_DRAW_LIMIT;} 00210 00211 if (R_audio_value > AUDIO_DRAW_LIMIT) {R_audio_value = AUDIO_DRAW_LIMIT;} 00212 else if (R_audio_value < -AUDIO_DRAW_LIMIT) {R_audio_value = -AUDIO_DRAW_LIMIT;} 00213 00214 BSP_LCD_DrawPixel(Xpos + i, (uint16_t) ((int16_t) Ypos + L_audio_value), LCD_COLOR_BLUE); 00215 BSP_LCD_DrawPixel(Xpos + i, (uint16_t) ((int16_t) Ypos + R_audio_value), LCD_COLOR_GREEN); 00216 } 00217 00218 }
Generated on Mon Aug 1 2022 10:03:27 by
