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
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.
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.
A few comments, although I'm only guessing at your actual intent:
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[]
.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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With