Forums

Resampling questions - from 44.1kHz to 48kHz

Started by Newbie January 28, 2004
I've had a look at dspguru.com and am trying to implement a program that will 
resample an audio signal from 44.1kHz to 48kHz. I'm running into some problems 
- namely too many zeros in my converted file. My algorithm is basically:


Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159 zeros 
in order to oversample.

Apply a low pass filter with a stop band freq. of 24kHz

Downsample by keeping every 1 out of 147 samples

Do I need to LPF again?


Another thing that I'm not sure about is if there is any requirement on the 
number of filter taps. Obviously the more taps I have, the fewer zero-valued 
samples will be in my output file.

Does anyone have any suggestions to implementing this SRC correctly?



Newbie wrote:
>
<snip>
> Does anyone have any suggestions to implementing this SRC > correctly?
You can do all the hard work yourself and probably not get it right or you can use a library which is known to be correct: http://www.mega-nerd.com/SRC/ Erik -- +-----------------------------------------------------------+ Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) +-----------------------------------------------------------+ Java : A language from the C family of languages. It has all the bad features of C++ but without the most powerful feature of C, pointers.
Newbie wrote:

> Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159 zeros > in order to oversample. > > Apply a low pass filter with a stop band freq. of 24kHz
24KHz? Shouldn't be 22.05KHz? bye, -- Piergiorgio Sartor
none@available.com (Newbie) writes:

> I've had a look at dspguru.com and am trying to implement a program that will > resample an audio signal from 44.1kHz to 48kHz. I'm running into some problems > - namely too many zeros in my converted file. My algorithm is basically: > > > Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159 zeros > in order to oversample.
OK, so you're upsampling by a factor of 160 to a sample rate of 160 * 44100 = 7.056 MHz.
> Apply a low pass filter with a stop band freq. of 24kHz
No. The typical upconverter consists of upsampling by a factor of N (inserting N-1 zeros) followed by a 1/N interpolating (lowpass) filter. The typical downconverter consists of a 1/M lowpass filter followed by a M:1 decimator (keeping 1 of M samples). You can combine the two filters (1/N and 1/M) by simply choosing the lowest. In this case N = 160 and M = 147, so 1/N is the lowest. Thus you want to filter by 1/N (relative to a sample rate of 7.056 MHz), which corresponds to a filter of bandwidth (7.056 MHz/2) / 160 = 22.05 kHz.
> Downsample by keeping every 1 out of 147 samples > > Do I need to LPF again?
Not if you did it right.
> Another thing that I'm not sure about is if there is any requirement on the > number of filter taps. Obviously the more taps I have, the fewer zero-valued > samples will be in my output file.
Aha. Well, yes there is a requirement, but it's not black-and-white. Let's just take the upsampling stage for a moment and think about what's happening in the frequency domain. The original 44.1 kHz signal has a repetitive spectrum out to infinity, repeating at multiples of 44.1 kHz. After you upsample by 160 by inserting 159 zeros, the resulting spectrum hasn't changed. However, since your sample rate is now 7.056 MHz, the stuff between 22.05 kHz and 7.056/2 MHz = 3.528 MHz has to be filtered out. If that filter isn't perfect, then, at the 7.056 MHz rate, the stuff above 22.05 kHz that leaks through will sound like garbage (if you could hear it). So the object is to have you're 1/160 lowpass filter be down as far as reasonable at 22.05 kHz. For high quality audio, it should probably be at least 90 dB or so down. Note that this means that you will necessarily have the cutoff frequency at something less than 22.05 kHz. The closer you get the cutoff frequency to 22.05 kHz, and the more you want the filter attenuation down at 22.05 kHz, the longer your filter will get. Another simple point: Obviously your filter was less than 161 taps long, hence you are getting the zeros you spoke of. That's a bad sign that you probably haven't chosen the passband/stopband characteristics properly. How did you design the filter?
> Does anyone have any suggestions to implementing this SRC correctly?
Erik has a good point - use his. Unless your goal is the learning experience. -- % Randy Yates % "Though you ride on the wheels of tomorrow, %% Fuquay-Varina, NC % you still wander the fields of your %%% 919-577-9882 % sorrow." %%%% <yates@ieee.org> % '21st Century Man', *Time*, ELO http://home.earthlink.net/~yatescr
You probably don't want to worry about this now since you are still trying
to get the basic operation correct, but you may notice some major
inefficiencies in your process.  In your filter, only 1 out of every 160
samples are non-zero.  So there's no reason to include them in the filtering
step since zero*filter coef = 0.  Then, you may notice that you are
calculating all these filtered values, and then throwing away 146 out of 147
of them.  So there is no need to calculate the 146 values that you are just
going to throw away anyway.  Once you take advantage of these 2 shortcuts,
you are left with the so-called polyphase implementation.

"Newbie" <none@available.com> wrote in message
news:tUHRb.10643$5G3.8881@newssvr22.news.prodigy.com...
> I've had a look at dspguru.com and am trying to implement a program that
will
> resample an audio signal from 44.1kHz to 48kHz. I'm running into some
problems
> - namely too many zeros in my converted file. My algorithm is basically: > > > Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159
zeros
> in order to oversample. > > Apply a low pass filter with a stop band freq. of 24kHz > > Downsample by keeping every 1 out of 147 samples > > Do I need to LPF again? > > Another thing that I'm not sure about is if there is any requirement on
the
> number of filter taps. Obviously the more taps I have, the fewer
zero-valued
> samples will be in my output file. > > Does anyone have any suggestions to implementing this SRC correctly?
In article <llnsuxgv.fsf@ieee.org>, yates@ieee.org says...
> >none@available.com (Newbie) writes: > >> I've had a look at dspguru.com and am trying to implement a program that
will
>> resample an audio signal from 44.1kHz to 48kHz. I'm running into some
problems
>> - namely too many zeros in my converted file. My algorithm is basically: >> >> >> Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159
zeros
>> in order to oversample. > >OK, so you're upsampling by a factor of 160 to a sample rate of 160 * 44100 =
7.056 MHz.
> >> Apply a low pass filter with a stop band freq. of 24kHz > >No. The typical upconverter consists of upsampling by a factor of N >(inserting N-1 zeros) followed by a 1/N interpolating (lowpass) >filter. The typical downconverter consists of a 1/M lowpass filter >followed by a M:1 decimator (keeping 1 of M samples). > >You can combine the two filters (1/N and 1/M) by simply choosing the lowest. >In this case N = 160 and M = 147, so 1/N is the lowest. Thus you want to
filter
>by 1/N (relative to a sample rate of 7.056 MHz), which corresponds to a
filter
>of bandwidth (7.056 MHz/2) / 160 = 22.05 kHz. > >> Downsample by keeping every 1 out of 147 samples >> >> Do I need to LPF again? > >Not if you did it right. > >> Another thing that I'm not sure about is if there is any requirement on the >> number of filter taps. Obviously the more taps I have, the fewer
zero-valued
>> samples will be in my output file. > >Aha. Well, yes there is a requirement, but it's not black-and-white. Let's >just take the upsampling stage for a moment and think about what's happening >in the frequency domain. The original 44.1 kHz signal has a repetitive
spectrum
>out to infinity, repeating at multiples of 44.1 kHz. After you upsample by
160
>by inserting 159 zeros, the resulting spectrum hasn't changed. However, since >your sample rate is now 7.056 MHz, the stuff between 22.05 kHz and 7.056/2
MHz = 3.528
>MHz has to be filtered out. If that filter isn't perfect, then, at the 7.056
MHz
>rate, the stuff above 22.05 kHz that leaks through will sound like garbage
(if
>you could hear it). So the object is to have you're 1/160 lowpass filter be >down as far as reasonable at 22.05 kHz. For high quality audio, it should >probably be at least 90 dB or so down. Note that this means that you will >necessarily have the cutoff frequency at something less than 22.05 kHz. The >closer you get the cutoff frequency to 22.05 kHz, and the more you want the >filter attenuation down at 22.05 kHz, the longer your filter will get. > >Another simple point: Obviously your filter was less than 161 taps long, >hence you are getting the zeros you spoke of. That's a bad sign that >you probably haven't chosen the passband/stopband characteristics properly. >How did you design the filter?
Thanks for all of the feedback. I think that you are correct about my filter not being designed correctly. I used ScopeFIR and chose Fs = 7056000, passband upper freq = 20kHz, stopband lower freq. = 22.05kHz, 1 dB passband ripple, and 100 dB stopband attenuation. I'm not sure what is going on here since the freq. response plot shows the signal to be attenuated ~-75dB at 0 Hz. Also, I've got several wide lobes above the cutoff freq. The lobes can be shorter if I increase the number of filter taps, but then I also get more lobes. Please suggest a filter for me to use, including the number of taps. If the number can be < 32 that would be good as my program doesn't support any higher. Lastly, I don't want to use someone elses program as I'm doing this for my own education. In separate projects, I've interpolated audio from 22.05kHz to 44.1kHz and in another decimated from 48kHz down to 24kHz - these worked fine. The 44.1kHz to 48kHz resampling project so far has proven to be a little more difficult, namely, I believe because of the large interpolation and decimation factors and long filters required. Thx.
> >> Does anyone have any suggestions to implementing this SRC correctly? > >Erik has a good point - use his. Unless your goal is the learning >experience. >-- >% Randy Yates % "Though you ride on the wheels of tomorrow, >%% Fuquay-Varina, NC % you still wander the fields of your >%%% 919-577-9882 % sorrow." >%%%% <yates@ieee.org> % '21st Century Man', *Time*, ELO >http://home.earthlink.net/~yatescr
In article <bv8u8i$pj8dg$1@ID-210375.news.uni-berlin.de>, 
goldentully@hotmail.com says...
> >You probably don't want to worry about this now since you are still trying >to get the basic operation correct, but you may notice some major >inefficiencies in your process. In your filter, only 1 out of every 160 >samples are non-zero. So there's no reason to include them in the filtering >step since zero*filter coef = 0. Then, you may notice that you are >calculating all these filtered values, and then throwing away 146 out of 147 >of them. So there is no need to calculate the 146 values that you are just >going to throw away anyway. Once you take advantage of these 2 shortcuts, >you are left with the so-called polyphase implementation. >
Yes, I've made provisions not to multiply zero-valued samples by the filter coeffs. I took advantage of this when I did my separate interpolation project. It surely will be beneficial in this case as well since my buffers can be much smaller. In this resampling project, I'm now troubleshooting my program to make sure that I'm aligning my filter coeffs with the correct sample value. Things were a lot easier when I did my interpolation project (x2) with a single zero pad between samples. Now I've got an L=160, and M=147. Thanks.
>"Newbie" <none@available.com> wrote in message >news:tUHRb.10643$5G3.8881@newssvr22.news.prodigy.com... >> I've had a look at dspguru.com and am trying to implement a program that >will >> resample an audio signal from 44.1kHz to 48kHz. I'm running into some >problems >> - namely too many zeros in my converted file. My algorithm is basically: >> >> > Take 44.1kHz signal and interpolate by padding the signal with L-1 = 159 >zeros >> in order to oversample. >> >> Apply a low pass filter with a stop band freq. of 24kHz >> >> Downsample by keeping every 1 out of 147 samples >> >> Do I need to LPF again? >> >> Another thing that I'm not sure about is if there is any requirement on >the >> number of filter taps. Obviously the more taps I have, the fewer >zero-valued >> samples will be in my output file. >> >> Does anyone have any suggestions to implementing this SRC correctly? > >
"Newbie" <none@available.com> wrote in message
news:usTRb.11943$7s7.4291@newssvr23.news.prodigy.com...
> In article <llnsuxgv.fsf@ieee.org>, yates@ieee.org says... > > > >none@available.com (Newbie) writes: > > > > Thanks for all of the feedback. I think that you are correct about my
filter
> not being designed correctly. > > I used ScopeFIR and chose Fs = 7056000, passband upper freq = 20kHz, > stopband lower freq. = 22.05kHz, 1 dB passband ripple, and 100 dB stopband > attenuation. I'm not sure what is going on here since the freq. response
plot
> shows the signal to be attenuated ~-75dB at 0 Hz. Also, I've got several
wide
> lobes above the cutoff freq. The lobes can be shorter if I increase the
number
> of filter taps, but then I also get more lobes. > > Please suggest a filter for me to use, including the number of taps. If
the
> number can be < 32 that would be good as my program doesn't support any > higher.
There is no way a filter with less than 32 taps will be close to adequate for this problem. For 160x oversampling, you would need something more like 321 taps just to do a relatively lousy job! Either you need to get a different program that supports more taps, or switch to a filter design method that allows more easily calculating the coefficients yourself, such as a windowed sinc. Alternatively, just to get up and running for now you could use linear interpolation as a crude low pass filter. This could even be implemented as a standard FIR filter to verify your code--just set up an array that varies from 0 to 1 linearly over 160 samples, then back to zero over .
> Lastly, I don't want to use someone elses program as I'm doing this for my
own
> education. In separate projects, I've interpolated audio from 22.05kHz to > 44.1kHz and in another decimated from 48kHz down to 24kHz - these worked
fine.
> The 44.1kHz to 48kHz resampling project so far has proven to be a little
more
> difficult, namely, I believe because of the large interpolation and
decimation
> factors and long filters required.
That's certainly a noble goal and you'll certainly learn more than if you use a canned routine. Go for it!
In article <bv929v$phlpa$1@ID-210375.news.uni-berlin.de>, 
goldentully@hotmail.com says...
> >"Newbie" <none@available.com> wrote in message >news:usTRb.11943$7s7.4291@newssvr23.news.prodigy.com... >> In article <llnsuxgv.fsf@ieee.org>, yates@ieee.org says... >> > >> >none@available.com (Newbie) writes: >> > >> >> Thanks for all of the feedback. I think that you are correct about my >filter >> not being designed correctly. >> >> I used ScopeFIR and chose Fs = 7056000, passband upper freq = 20kHz, >> stopband lower freq. = 22.05kHz, 1 dB passband ripple, and 100 dB stopband >> attenuation. I'm not sure what is going on here since the freq. response >plot >> shows the signal to be attenuated ~-75dB at 0 Hz. Also, I've got several >wide >> lobes above the cutoff freq. The lobes can be shorter if I increase the >number >> of filter taps, but then I also get more lobes. >> >> Please suggest a filter for me to use, including the number of taps. If >the >> number can be < 32 that would be good as my program doesn't support any >> higher. > >There is no way a filter with less than 32 taps will be close to adequate >for this problem. For 160x oversampling, you would need something more like >321 taps just to do a relatively lousy job! Either you need to get a >different program that supports more taps, or switch to a filter design >method that allows more easily calculating the coefficients yourself, such >as a windowed sinc. > >Alternatively, just to get up and running for now you could use linear >interpolation as a crude low pass filter. This could even be implemented as >a standard FIR filter to verify your code--just set up an array that varies >from 0 to 1 linearly over 160 samples, then back to zero over . > >> Lastly, I don't want to use someone elses program as I'm doing this for my >own >> education. In separate projects, I've interpolated audio from 22.05kHz to >> 44.1kHz and in another decimated from 48kHz down to 24kHz - these worked >fine. >> The 44.1kHz to 48kHz resampling project so far has proven to be a little >more >> difficult, namely, I believe because of the large interpolation and >decimation >> factors and long filters required. > >That's certainly a noble goal and you'll certainly learn more than if you >use a canned routine. Go for it! > >
Thanks. Do you have any recommendations on software I can use to design the filter - windowed sinc?
Jon Harris wrote:
> There is no way a filter with less than 32 taps will be close to adequate > for this problem. For 160x oversampling, you would need something more like > 321 taps just to do a relatively lousy job! Either you need to get a > different program that supports more taps, or switch to a filter design > method that allows more easily calculating the coefficients yourself, such > as a windowed sinc.
Another approach would be for you to interpolate to 160 in several smaller steps. 160=(2^5)*5, so you could interpolate by 2 five times, and then by 5 once. In each stage, set the cutoff frequency to 20KHz. The first stage will require a good (that is, long) filter. I think 32 taps would prolly be OK. After interpolating by 2 (and filtering) in the first stage, you'll have a spectrum something like this: ______ ________ \______|______/ fs/4 fs/2 fs/4 is roughly 20KHz. The next stage can get by with a much smaller filter, because the spectrum between 20K and 60K has already been supressed by a decent amount. The later stages should still roll off starting at 20KHz, but you don't have to worry about stopband attenuation until you get into the 60KHz neighborhood. That's a pretty relaxed filter. You could prolly get away with interpolating in fewer stages - say in four stages (2,4,4,5). Or as Jon suggested, you could use a windowed sinc and do it in one massive stage. The rule of thumb I use is that I use 16*N taps for interpolation by N (at least in the first stage). To do it in one stage would require 2560 taps. -- Jim Thomas Principal Applications Engineer Bittware, Inc jthomas@bittware.com http://www.bittware.com (703) 779-7770 The sooner you get behind, the more time you'll have to catch up