2016-07-08 03: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 07: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?