Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resampling a sound sample, what filter do I use?

I am trying to resample a signal (sound sample) from one sampling rate, to a higher sampling rate. Unfortunately it needs some kind of filter, as some 'aliasing' appears to occur, and I'm not familiar with filters. Here is what I came up with:

int i, j, a, b, z;

a = 44100;
b = 8363;

// upsample by a
for(i = z = 0; i < samplen; i++)
    for(j = 0; j < a; j++)
        cbuf[z++] = sampdata[i];

// some filter goes here???

// downsample by b
for(j = i = 0; i < z; i += b)
    buf[j++] = cbuf[i];

The new sample is very similar to the original, but it has some kind of noise. Can you please tell me what filter I need to add, and preferably some code related to that filter?

Original sound: http://www.mediafire.com/?9gnga1in52d6t4x Resampled sound: http://www.mediafire.com/?x34h7ggk8n9k8z1

like image 804
Ledio Berdellima Avatar asked Dec 08 '10 23:12

Ledio Berdellima


3 Answers

Don't use linear interpolation unless both sample rates (source and destination) are well above the highest frequency in your data. It's a very poor low-pass filter.

What you want is an interpolating low pass filter with a stop-band starting below half the lower of the two sample rates you are dealing with. Common methods of implementing this are upsampling/downsampling using IIR filters, and using poly-phase FIR filters. A windowed Sinc interpolator also works well for this if you don't need real-time performance, and don't want to upsample/downsample. Here's a Windowed Sinc interpolating low-pass filter in Basic, that should be trivial to convert into C.

If you want to use IIR filtering, here's the canonical Cookbook for biquad IIR filters.

If you want the best explanation of audio resampling theory, here's Stanford CCRMA's Resampling page.

like image 92
hotpaw2 Avatar answered Nov 13 '22 09:11

hotpaw2


Have you considered using a specialised library for this, such as libsamplerate?

It is quite portable and it is developed by people who know how to do things like this correctly. Even if you do not use it directly, you might find the algorithms it implements quite interesting.

like image 10
thkala Avatar answered Nov 13 '22 10:11

thkala


A few comments, although I'm only guessing at your actual intent:

  • You are up-sampling at a rate 44100 times the original sample rate. For example, if your input was at 10kHz your intermediate cbuf[] would be at 441MHz which is a tad high for most audio analysis. Assuming you want cbuf[] to be at 44100Hz then you only need to create 44100/OrigSampleRate of samples in cbuf[] per sample in sampdata[].
  • You are incrementing z twice in the up-sampling loop. This results in all odd elements of cbuf[] to have their original values. I believe this ultimately results in the final buf[] having invalid odd elements which may be the source of your noise. There is also a potential buffer overflow in cbuf if you didn't create it with at least twice the required number of elements.
  • As mentioned by Steve a linear interpolation is generally the simplest that creates a good result when up-sampling. More complicated up-sampling can be done if desired (polynomials, splines, etc...). Similarly, when down-sampling you may wish to average samples instead of just truncating.
like image 2
uesp Avatar answered Nov 13 '22 09:11

uesp