I have an 8khz mono buffer of samples, and I am trying to manipulate the playback speed of it by modifying the number of samples in it. When slowing down (a speedScale value of 0.5 for example) then the values are repeated-- a buffer of samples: [0.1, 0.2, 0.3..] becomes [0.1, 0.1, 0.2, 0.2, 0.3, 0.3 ..]. When I do this, although the speed has slowed down correctly, I am noticing aliasing happening. I was under the impression that repeating samples like this would not require low pass filtering to avoid aliasing. Am I doing something wrong?

Here's the code for slowing-down/speeding-up:

function process(buffer, speedScale) {
    size = ceil(buffer.size / speedScale);

    counter = 0.0;
    ratio = 1 * speedScale;
    processed = [];

    for (i = 0; i < size; i++) {
        index = floor(counter);
        processed[i] = buffer.samples[index];
        counter += ratio;
    return processed;
  • $\begingroup$ because you are reconstructing you original audio using the zero-order hold (a.k.a. piecewise-constant) interpolation and then resampling. the ZOH reconstruction is far worse than the use of a windowed $\operatorname{sinc}(\cdot)$ function in that it leaves images that get reflected back into your baseband. $\endgroup$ – robert bristow-johnson Apr 6 '15 at 19:11

That's because you are interpolating the signal. Take a look at this figure:

enter image description here

This is zero interpolation, i.e. inserting zeros between samples, but applies to your case too. The replicas at 2*pi are distorting your signal. You can see them in the third graph, at -2pi/L, +2pi/L. So, you need a low pass filter with a cut off frequency pi/L, after expander.

In your case, the expander's output dtft will be X(w*2) + exp(-jw)*X(w*2), assuming input signal's dtft X(w). So, your extrapolator output will look a bit different, but the idea is the same.

  • $\begingroup$ It would be very helpful if you added a bit of Latex formatting to your math symbols. $\endgroup$ – Matt L. Apr 6 '15 at 9:18

square, triangle and saw waves have aliasing because they have sharp corners. Those sharp corners take frequencies beyond Nyquist to make perfectly sharp. When you repeat samples to slow it down, you are introducing sharp corners and thus are introducing aliasing. Hopefully that is a decent intuitive explanation. There is surely a more formal math heavy explanation as well (:

  • $\begingroup$ the means of interpolation that the OP is using (zero-order hold) with the index = floor(counter); processed[i] = buffer.samples[index]; code, does not attenuate the images very much and those images fold back into the baseband as aliases. unless the input has only very low-frequency content, that will be a problem for any signal that does not originally have frequency components extending beyond Nyquist. $\endgroup$ – robert bristow-johnson Apr 6 '15 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.