cancel
Showing results for 
Search instead for 
Did you mean: 

Sample Rate Distortion/Aliasing on ADCs

epalaima
Associate II
Posted on July 09, 2016 at 00:17

Hi, I am doing some audio programming on the STM32F4 and I am noticing that there is some distortion/aliasing happening around the sample rate. I was writing a program that reads the incoming audio into a delay buffer and reads back its contents at a slower rate, pitching down the signal, and this brings this aliasing/distortion into audible range. I have tested this out and have found that the pitch of the aliasing is a division of the sample rate based on how much I am slowing the signal down (i.e. If I play the buffer back at 10% speed with a sample rate of 48000 this will create a 4800Hz tone).

I am wondering if there is any way I can set up my program differently to avoid this aliasing. I am currently setting up sample rate via a 2 step timer set at a frequency of 48000. I use a flag to prevent steps from repeating. I have also tried implementing a simple lowpass filter, but the aliasing still occurs.

Is this an unavoidable biproduct of the onboard ADCs, or is there something I can do to get around this? Any suggestions appreciated, I just figured out how to set a lot of this stuff up so let me know if you see anything flawed in my methodology. Code below. Thanks!

Here is my while loop:

  while (1)

  {

      int timerValue = TIM_GetCounter(TIM2);

      if (timerValue == 1 && timerFlag == 0){

     timerFlag = 1;

     delayCounter++;

     if(delayCounter >= 48000){

     delayCounter -= 48000;

     }

     ADC2ConvertedVoltage = (ADC2ConvertedValue *3300/0xFFF);

     gain = ((float)ADC3ConvertedValue)/4095;

     diveSwitch = ((float)ADC1ConvertedValue[0])/4095;

 filterFeedback = (1.5*ADC2ConvertedValue) - (.5*filterFeedback);

     if(diveSwitch >= .5){

     if(delayCounter < 48000){

     delay[delayCounter] = filterFeedback;

     delayCounter++;

     }

     if(diveCounter <= 47999 && delayCounter >= 1){

     //diveIncr = .1;

     castDiveCounter = (int)diveCounter;

     interp = diveCounter - castDiveCounter;

     output = ((float)delay[castDiveCounter]*(1-interp))+((float)delay[castDiveCounter+1]*interp)*(3300/0xFFF);

     diveCounter += diveIncr;

     if(diveIncr >= 0.00004){

       diveIncr -= 0.000004;

     }

     }

     TM_DAC_SetValue(TM_DAC1, output);

     }

     else{

     delayCounter = 0;

     output = 0;

     diveCounter = 0;

     diveIncr = 1;

     TM_DAC_SetValue(TM_DAC1, filterFeedback);

     }

       TM_DAC_SetValue(TM_DAC2, ADC2ConvertedVoltage);

      }

      else if (timerValue == 0 && timerFlag == 1){

     timerFlag = 0;

      }

  }

#!stm32 #sampling-rate #aliasin
2 REPLIES 2
raptorhal2
Lead
Posted on July 09, 2016 at 16:36

It's an inherent characteristic of sampling. Do a search on ''Nyquist Shannon criteria'' for further enlightenment.

Regards, Hal

epalaima
Associate II
Posted on July 09, 2016 at 21:21

I am aware of the nyquist frenquency and the potential this brings for aliasing, though I don't think I have ever heard it this pronounced before. Can you recommend any digital filtering methods that would be well suited to smoothing this out before my pitch shifting?