R&J / Mbed 2 deprecated 487_Laboratory_3

Dependencies:   mbed BSP_DISCO_F746NG mbed-dsp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spectrum.cpp Source File

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 }