10 Replies Latest reply: Oct 17, 2011 1:55 PM by Mitesh RSS

    FIR filter Block Based Talk Thru 21369 EZ-kit

    toebs

      Hello

       

      I have never before programmed on a DSP, so i might have missed something obvious, but here is my problem:

       

      I am trying to implement a FIR filter in the Block Based Talk Thru example for the 21369.
      My delay line (temp) and my FIR filter seems to work when i use my debug code.

      But when i run the program with an input whitenoise the output is not filtered as it should be.

      I think the problem has to do with the numberformat used in the unsigned int, negative numbers, and the DAC.

       

      Any help will be greatly appreciated.

       

      P.S. Pardon broken english, it is not my native

       

      This is the code from the blockProcess.c

       

       

      #include "tt.h"
      #include <filter.h>
      // Place the audio processing algorith here. The input and output are given
      // as unsigned integer pointers.
      #define M 4
      int n;
      int i;
      int k;
      int u;
      float b[] = {0.25, 0.25, 0.25, 0.25};
      float old[M-1] = {0};
      void processBlock(unsigned int *block_ptr)
      {  
      #if USE_DEBUG_CODE
      float out_temp[NUM_SAMPLES] = {0};
      #endif
      //Clear the Block Ready Semaphore
      blockReady = 0;
         
      //Set the Processing Active Semaphore before starting processing
      isProcessing = 1;
         
          //Variabel til delay line
          float temp[NUM_SAMPLES + M - 1] = {0};
         
      //Set: First M-1 samples in temp to be the last M-1 samples from the block previously processed
          for(i=0;i<M-1;i++)
      {
      temp[i] = old[i];
      }
          //Fill the rest of temp with the samples from the current processing block
      for(i=0;i<NUM_SAMPLES;i++)
          {
               temp[i+M-1] = ((signed int) (block_ptr[i] << 8)) >> 8;
          }  
          //store last M-1 sample form the current processing block
          for(i=0;i<M-1;i++)
          {
               old[i] = ((signed int) (block_ptr[NUM_SAMPLES-M+i+1] << 8)) >> 8;//block_ptr[NUM_SAMPLES-M+i+1];
          }
      //FIR filter
          for(n=M-1;n<NUM_SAMPLES+M-1;n++)
          {
               float fold = 0.0f;
               for(k=0;k<M;k++)
               {
                    #if USE_DEBUG_CODE
                    out_temp[n-M+1] = out_temp[n-M+1] + b[k] * temp[n-k];
                    #endif
                    fold += b[k] * temp[n-k];
               }
        
               block_ptr[n-M+1] = (unsigned int) (fold + 0.5f);
          }
         
          isProcessing = 0;
         
      }
        • 1. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
          Mitesh

          Hi,

           

          You might want to use the "fir" library function already available with the VisualDSP++ directly for your application. Since the main source of this function is written in assembly language in an optimized manner, it should also give you better performance than the code you mentioned in your post. For more details about this function, please refer to the VisualDSP++ 5.0 Run-Time Library Manual for  SHARC Processsors available at the link below:

           

          http://www.analog.com/en/processors-dsp/sharc/processors/manuals/resources/index.html

           

          Hope this helps.

           

          Thanks,
          Mitesh

          • 2. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
            Copy

                 Hi!

             

                 I think you might use the "__builtin_conv_RtoF()" function to convert the unsigned int array "block_ptr[]" to float ponit foramt.

             

                 Hope this helps.

             

                 Thanks,
                 Copy.

            • 3. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
              toebs

              Thank you Mitesh. My problem with the built in fir function is, that i dont know how to use it when the talk thru example is block based.

              • 4. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                toebs

                Hello Copy. Thanks for the reply. I will try to use the __builtin_conv_RtoF(), however it puzzles me, that i can not find the function in the VisualDSP++ 5.0 help library:/

                • 5. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                  Mitesh

                  Hi,

                   

                  For block based filtering, you can use the "fir_vec" function. Also, you can use following functions for fixed to float and float to fixed conversion.

                   

                   

                  void    Block_Fixed_To_Float( int * Fixed_In, float * Float_Out_L, float * Float_Out_R )
                  {
                      int i;
                      #pragma SIMD_for
                      for (i=0;i<AUDIO_BLOCK_SIZE;i++)
                      {
                          Float_Out_L[i]  = ((float) (Fixed_In[2*i]<<8))   * (1.0/2147483648.0);    
                          Float_Out_R[i]  = ((float) (Fixed_In[2*i+1]<<8)) * (1.0/2147483648.0);    
                      }
                  }

                   

                  void    Block_Float_To_Fixed( int * Fixed_Out, float * Float_In_L, float * Float_In_R )
                  {
                      int i;
                      #pragma SIMD_for
                      for (i=0;i<AUDIO_BLOCK_SIZE;i++)
                      {
                          Fixed_Out[2*i]   = ((int) (2147483648.0*Float_In_L[i]))>>8;
                          Fixed_Out[2*i+1] = ((int) (2147483648.0*Float_In_R[i]))>>8;   
                      }
                  }

                   

                  Hope this helps.

                   

                  Thanks,

                  Mitesh

                  • 6. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                    Copy

                        Hi toebs!

                        I do not know what the key word  you search,but you can try to search "__builtin_conv_RtoF"  without bracket.

                    And I think the function "__builtin_conv_RtoF()" can help you to solve the problem about the variable format more easily.

                     

                        Best Regard! 

                    • 7. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                      toebs

                      Great it works, thanks alot. Now the next task awaits; implementing an LMS filter.

                       

                       

                      #include "tt.h"
                      #include <filter.h>
                      // Place the audio processing algorith here. The input and output are given
                      // as unsigned integer pointers.
                      #define TAPS 4
                      float pm coeffs[] = {0.25, 0.25, 0.25, 0.25};
                      float state_L[TAPS+1] = {0};
                      float state_R[TAPS+1] = {0};
                      float Float_Out_L[NUM_SAMPLES/2];
                      float Float_Out_R[NUM_SAMPLES/2];
                      float output_L[NUM_SAMPLES/2];
                      float output_R[NUM_SAMPLES/2];
                      void    Block_Fixed_To_Float( int * Fixed_In, float * Float_Out_L, float * Float_Out_R );
                      void    Block_Float_To_Fixed( int * Fixed_Out, float * Float_In_L, float * Float_In_R );
                      void processBlock(unsigned int *block_ptr)
                      {  
                      //Clear the Block Ready Semaphore
                      blockReady = 0;
                         
                      //Set the Processing Active Semaphore before starting processing
                      isProcessing = 1;
                          Block_Fixed_To_Float( (int *) block_ptr, Float_Out_L, Float_Out_R );
                        
                          //FIR Left
                          #if defined(__SIMDSHARC__)
                               fir (Float_Out_L, output_L, coeffs, state_L, NUM_SAMPLES/2, TAPS);
                          #else
                      fir_vec (Float_Out_L, output_L, coeffs, state_L, NUM_SAMPLES/2, TAPS);
                      #endif
                      //FIR Right
                      #if defined(__SIMDSHARC__)
                               fir (Float_Out_R, output_R, coeffs, state_R, NUM_SAMPLES/2, TAPS);
                          #else
                      fir_vec (Float_Out_R, output_R, coeffs, state_R, NUM_SAMPLES/2, TAPS);
                      #endif
                         
                          Block_Float_To_Fixed( (int *) block_ptr, output_L, output_R );
                          isProcessing = 0;
                       
                      }
                      #define AUDIO_BLOCK_SIZE (NUM_SAMPLES/2)
                      void    Block_Fixed_To_Float( int * Fixed_In, float * Float_Out_L, float * Float_Out_R )
                      {
                          int i;
                          #pragma SIMD_for
                          for (i=0;i<AUDIO_BLOCK_SIZE;i++)
                          {
                              Float_Out_L[i]  = ((float) (Fixed_In[2*i]<<8))   * (1.0/2147483648.0);    
                              Float_Out_R[i]  = ((float) (Fixed_In[2*i+1]<<8)) * (1.0/2147483648.0);    
                          }
                      }
                      void    Block_Float_To_Fixed( int * Fixed_Out, float * Float_In_L, float * Float_In_R )
                      {
                          int i;
                          #pragma SIMD_for
                          for (i=0;i<AUDIO_BLOCK_SIZE;i++)
                          {
                              Fixed_Out[2*i]   = ((int) (2147483648.0*Float_In_L[i]))>>8;
                              Fixed_Out[2*i+1] = ((int) (2147483648.0*Float_In_R[i]))>>8;   
                          }
                      }
                      • 8. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                        Mitesh

                        Hi,

                         

                        Glad to know that things are working for you as far as this issue is concerned. Please feel free to get back in case you have further questions.

                         

                        Thanks,

                        Mitesh

                        • 9. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                          toebs

                          Hi Again.

                          I have been strugling some, trying to get the project to output audio to for different channels instead of just left and right. I am trying to use the DSP as a cross over filter for a 2 way active speaker. Therefore i would like to be able to use two different filters on each input channel, and ouput the data filtered with filter1 to one channel and filter2, to another channel. Kinda like this:

                           

                           

                          Input left --- filter with filter1 -- output to chan_left_1

                          input left --- filter with filter2 -- output to chan_left_2

                           

                          Input right --- filter with filter1 -- output to chan_right_1

                          input right --- filter with filter2 -- output to chan_right_2

                           

                          And a bonus question. How do I estiame, how many filter taps the DSP can process? I can see that the 21369 uses 1.25ns pr. FIR  filter tap  ( http://www.analog.com/en/processors-dsp/sharc/ADSP-21369/products/benchmarks/sharc_benchmarks/resources/fca.html.)

                           

                          Say filter 1 and 2 are both 500 taps. Tha means that i have 4x500 = 2000 FIR filter taps. This takes 2000tap*1.25ns/tap = 2.5us.

                          To calculate how many times pr. second i can filter with my 2000 taps i take 2.5us^(-1) = 400kHz.

                          So with my sampling rate of 44.1kHz i am in the clear, using 2000 taps, or have i misunderstood something?

                          • 10. Re: FIR filter Block Based Talk Thru 21369 EZ-kit
                            Mitesh

                            Hi,

                             

                            Yes, ideally, your calculation is correct and you should be able to perform the filtering task you mentioned with in the available time. However, please note that the benchmark figures you are referring to and the actual no of cycles your algorithm might be taking might differ in a  slight to a higly significant  manner depending upon some of the the following important factors:

                             

                            1) The benchmark provided is based on the highly optimized assembly code making the optimum use of various processor features.  Since you are using C code, it may have its own overheads.

                             

                            2)  The actual performance you get would also depend largely on how do you place your buffers. E.g. placing both the coefficient(PM) and input buffer(DM) in the same memory block might directly reduce the performance by 100%.  The performance might further reduce if the core and DMA try to access the same memory block simulataneously due to bad buffer management.

                             

                            3) The extra overheads of converting the buffer from fixed to float and vice versa should also be counted.

                             

                            4)  The performance might greatly vary depending on the fact that whether the compiler optimization is enabled (for speed) or not and also on whether various other C code optimization techniques are being used wherever possible or not.

                             

                            I would suggest you to take care of the above facts and then calculate how many cycles are being actually taken by your algorithm. Please let me know your findings on whether this no. of cycles are more/less  than  the available no of cycles as per your sample rate.

                             

                            Thanks,

                            Mitesh