2016-07-08 3:17 PM
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 #aliasin2016-07-09 7:36 AM
It's an inherent characteristic of sampling. Do a search on ''Nyquist Shannon criteria'' for further enlightenment.
Regards, Hal2016-07-09 12:21 PM
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?
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.