How can this be done? My application is converting the sample rate of 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) and playing back at 44.1kHz, so that the speed sounds different. This is being done in C++. So far, what i've read seems to only apply to SRC by integer factors. One method is: Upsampling: Interpolate zeroes (in time domain?), low pass filter with Fc at new Nyquist freq Downsampling: Low pass filter + decimation (of every nth sample, n being the conversion factor) OR FFT -> low pass filter with Fc at new Nyquist frequency -> IFFT. How does this change to be able to change the sample rate by a Real factor? Please correct any and all errors i've made above. Thanks for any and all help.
Sample Rate Conversion by non integer factor
Started by ●June 30, 2004
Reply by ●June 30, 20042004-06-30
Perceptually, converting by any rational factor can be accomplished by combining integer upsampling and downsampling, e.g. for 0.75, upsample by 3, downsample by 4. There are efficiency tricks that can do this all in one step with much less computation (try searching on polyphase filters). "David Reid" <dreid_nospam@remove_no_spam_mechtronix.ca> wrote in message news:W6CEc.179470$207.1255211@news20.bellglobal.com...> How can this be done? My application is converting the sample rate of > 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) > and playing back at 44.1kHz, so that the speed sounds different. This is > being done in C++. > > So far, what i've read seems to only apply to SRC by integer factors. One > method is: > > Upsampling: Interpolate zeroes (in time domain?), low pass filter with Fc at > new Nyquist freq > > Downsampling: Low pass filter + decimation (of every nth sample, n being the > conversion factor) > > OR > > FFT -> low pass filter with Fc at new Nyquist frequency -> IFFT. > > How does this change to be able to change the sample rate by a Real factor? > Please correct any and all errors i've made above. > > Thanks for any and all help. > >
Reply by ●June 30, 20042004-06-30
David Reid wrote:> How can this be done? My application is converting the sample rate of > 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) > and playing back at 44.1kHz, so that the speed sounds different. This is > being done in C++. > > So far, what i've read seems to only apply to SRC by integer factors. One > method is: > > Upsampling: Interpolate zeroes (in time domain?), low pass filter with Fc at > new Nyquist freq >Going up I would use a cutoff at the old nyquist since the signal does not contain any more information than that. When going down I would check if the new sample freq is lower than the old one and use that nyquist for a lowpass filter cutoff.> Downsampling: Low pass filter + decimation (of every nth sample, n being the > conversion factor) >Check the 'Data resampling' topic of janey posted on 06/16/2004> OR > > FFT -> low pass filter with Fc at new Nyquist frequency -> IFFT.FFT (Overlap-add) would also work fine but you do not need a real lowpass filter just trow away bins. And transform back using lesser bins or more bins padded with zeros.> > How does this change to be able to change the sample rate by a Real factor? > Please correct any and all errors i've made above.Real=Up/Down fs*0.75= 3 up and 4 down fs*1.3 = 13 up 10 down etc.> > Thanks for any and all help. > >
Reply by ●June 30, 20042004-06-30
Suodatin Pussi wrote:> David Reid wrote: > >> How can this be done? My application is converting the sample rate of >> 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) >> and playing back at 44.1kHz, so that the speed sounds different. This is >> being done in C++.When using integer up and down values and a fir interpolation filter: Let say you need to go from fs=44.1kHz to fs=32khz. That would be 320 up and 441 down (44.1x320/441=32). The lowest samplerate allows only for freqs upto 32/2=16kHz. So your interpolation or lowpassfilter will have its cutoff at 16kHz or lower (for example at 0.93*16kHz) you need some room for the roll-off of your fir filter. The fir filter should have a relatively high order because filtering is done at samplerate of 44.1*320 kHz. So check if you can construct such a filter. After you have constructed the appropriate filter. Take a sample from your original signal and add 320-1 zeros. repeat that for all samples. So you will get a sample, 319 zeros, next sample, 319 zeros etc.. Be aware that the total energy of your signal drops. You have to gain you signal with a factor 320. Now you would fir filter it at the new samplerate 44.1*320 using the lowpass (interpolation) filter. But as you see there are a lot of useless calculations because multiplying a zero sample value with a filter coeff would result in zero output. So you only need to muliply each sample at your inputbuffer with the correponsding 320th filter coefficient. This saves a lot of calculations. Shift your filter 1 sample and look again. Now you see that each sample correponds with the every 320th coefffient starting at the 319th coeff. etc.. After filtering you need to downsample. Down 441 means that you take the 0 sample, the 441th sample, the 882th etc. So downsampling is nothing more than trowing all those samples away you just calculated. You could have skipped these calculations at the upsampling stage. Saving some more calculations. It's all about organizing your calculations. The main problem is to get a good fir interpolation filter Try to draw it out on a sheet of paper and use some more reasonable up and downfactors like up 3 and down 4. Before I write down a similar procedure using overlap-add. I first have to check it myself. There are a few tricky things. earlier I said that you could trow away bins or padd zeros (for going down or up). But thats not all, you also need to reorganize the bin content and store them at the (new) appropriate locations. sorry for the typos, I have to watch football now. damn portugal scores.
Reply by ●June 30, 20042004-06-30
David Reid wrote:> > How can this be done? My application is converting the sample rate of > 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) > and playing back at 44.1kHz, so that the speed sounds different. This is > being done in C++. > > So far, what i've read seems to only apply to SRC by integer factors.Well obviously you have never heard of Secret Rabbit Code . http://www.mega-nerd.com/SRC/ or Julius O. Smith (see URL below).> How does this change to be able to change the sample rate by a Real factor? > Please correct any and all errors i've made above.The best explanation is here: http://ccrma-www.stanford.edu/~jos/resample/ Erik -- +-----------------------------------------------------------+ Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) +-----------------------------------------------------------+ "I've nothing against OO, I do have something against C++. Its a dogs dinner. Anyone who's (tried) to read Stroustrups book on C++ like I had the misfortune of doing knows that the man is very intelligent but has about as much clarity of thought as Timothy Leary on a bad day." -- NJR in comp.os.linux.development.apps
Reply by ●June 30, 20042004-06-30
Hey, thanks for the replies. Your explanations seem very useful. However, i don't think i will be using them....for the following reason. My manager came to see why it was taking so long for me to get this thing working and we had a debate about the proper way to do resampling. He suggested a technique, which i don't know where it came from but for some reason it works (i just implemented it). It goes against pretty much all that i've read on the web, and what i've read on this news group. I will post the question and algorithm for everyone to respond to in another post, if your interested. david "Suodatin Pussi" <Suodatin_Pussi@kokonaisuutena.hotmail.com> wrote in message news:40e3105c$0$42417$e4fe514c@news.xs4all.nl...> Suodatin Pussi wrote: > > > David Reid wrote: > > > >> How can this be done? My application is converting the sample rate of > >> 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or1.3)> >> and playing back at 44.1kHz, so that the speed sounds different. Thisis> >> being done in C++. > When using integer up and down values and a fir interpolation filter: > Let say you need to go from fs=44.1kHz to fs=32khz. That would be 320 up > and 441 down (44.1x320/441=32). The lowest samplerate allows only for > freqs upto 32/2=16kHz. So your interpolation or lowpassfilter will have > its cutoff at 16kHz or lower (for example at 0.93*16kHz) you need some > room for the roll-off of your fir filter. The fir filter should have a > relatively high order because filtering is done at samplerate of > 44.1*320 kHz. So check if you can construct such a filter. > > After you have constructed the appropriate filter. Take a sample from > your original signal and add 320-1 zeros. repeat that for all samples. > So you will get a sample, 319 zeros, next sample, 319 zeros etc.. > Be aware that the total energy of your signal drops. You have to gain > you signal with a factor 320. > Now you would fir filter it at the new samplerate 44.1*320 using the > lowpass (interpolation) filter. But as you see there are a lot of > useless calculations because multiplying a zero sample value with a > filter coeff would result in zero output. So you only need to muliply > each sample at your inputbuffer with the correponsding 320th filter > coefficient. This saves a lot of calculations. Shift your filter 1 > sample and look again. Now you see that each sample correponds with the > every 320th coefffient starting at the 319th coeff. etc.. > > After filtering you need to downsample. Down 441 means that you take the > 0 sample, the 441th sample, the 882th etc. So downsampling is nothing > more than trowing all those samples away you just calculated. You could > have skipped these calculations at the upsampling stage. Saving some > more calculations. It's all about organizing your calculations. The main > problem is to get a good fir interpolation filter > > Try to draw it out on a sheet of paper and use some more reasonable up > and downfactors like up 3 and down 4. > > Before I write down a similar procedure using overlap-add. I first have > to check it myself. There are a few tricky things. earlier I said that > you could trow away bins or padd zeros (for going down or up). But thats > not all, you also need to reorganize the bin content and store them at > the (new) appropriate locations. > > sorry for the typos, I have to watch football now. damn portugal scores. > >
Reply by ●June 30, 20042004-06-30
David Reid wrote:> Hey, thanks for the replies. Your explanations seem very useful. However, > i don't think i will be using them....for the following reason. > > My manager came to see why it was taking so long for me to get this thing > working and we had a debate about the proper way to do resampling. He > suggested a technique, which i don't know where it came from but for some > reason it works (i just implemented it). It goes against pretty much all > that i've read on the web, and what i've read on this news group. I will > post the question and algorithm for everyone to respond to in another post, > if your interested. > > davidSure, share it with us, if you're allowed to, it seems to be a very quick method.
Reply by ●June 30, 20042004-06-30
I have actually. i've also heard of Open source audio library on sourceforge.net. i think the implementation for the class afLibConverter (used for sample rate conversion) is a reimplementation of the Secret Rabbit Code functions in C++. Anyway, I've posted the algorithm. don't care if i can't share it. dont really like this company much.... "Erik de Castro Lopo" <nospam@mega-nerd.com> wrote in message news:40E32AD9.D0CAB4DC@mega-nerd.com...> David Reid wrote: > > > > How can this be done? My application is converting the sample rate of > > 44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or1.3)> > and playing back at 44.1kHz, so that the speed sounds different. Thisis> > being done in C++. > > > > So far, what i've read seems to only apply to SRC by integer factors. > > Well obviously you have never heard of Secret Rabbit Code . > > http://www.mega-nerd.com/SRC/ > > or Julius O. Smith (see URL below). > > > How does this change to be able to change the sample rate by a Realfactor?> > Please correct any and all errors i've made above. > > The best explanation is here: > > http://ccrma-www.stanford.edu/~jos/resample/ > > Erik > -- > +-----------------------------------------------------------+ > Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) > +-----------------------------------------------------------+ > "I've nothing against OO, I do have something against C++. Its a dogs > dinner. Anyone who's (tried) to read Stroustrups book on C++ like I had > the misfortune of doing knows that the man is very intelligent but has > about as much clarity of thought as Timothy Leary on a bad day." > -- NJR in comp.os.linux.development.apps
Reply by ●June 30, 20042004-06-30
Let me guess--linear interpolation? If not, please post. "David Reid" <dreid_nospam@remove_no_spam_mechtronix.ca> wrote in message news:0UFEc.185159$207.1297924@news20.bellglobal.com...> Hey, thanks for the replies. Your explanations seem very useful. However, > i don't think i will be using them....for the following reason. > > My manager came to see why it was taking so long for me to get this thing > working and we had a debate about the proper way to do resampling. He > suggested a technique, which i don't know where it came from but for some > reason it works (i just implemented it). It goes against pretty much all > that i've read on the web, and what i've read on this news group. I will > post the question and algorithm for everyone to respond to in another post, > if your interested. > > david
Reply by ●July 1, 20042004-07-01
In article <W6CEc.179470$207.1255211@news20.bellglobal.com>, David Reid <dreid_nospam@remove_no_spam_mechtronix.ca> wrote:>How can this be done? My application is converting the sample rate of >44.1kHz wave files to sample rate X (eg change SR by factor of 0.75, or 1.3) >and playing back at 44.1kHz, so that the speed sounds different.Interpolation can give you any point between sample points, and thus will work for any arbitrary or even time varying sample ratios. Sinc interpolation will produce much less distortion than linear or low order polynomial interpolation (see the "reconstruction" theorems), although linear interpolation may work if the frequency content of the original signal is way below the sample rate. An interpolation method with suitable approximations for the windowed-Sinc function will allow you to trade off compute time against S/N ratio. You can play with the type of window, width of window and various approximation tricks for the windowed-Sinc function. The various polyphase resampling methods are just table-lookup driven optimization tricks which one can use with DSP's that are too slow (or as an optimization when needed for power reduction or something). On a fast PC you may not need to do this, as a well tuned math library can often calculate the window and Sinc tap coefficients in real time. IMHO. YMMV. -- Ron Nicholson rhn AT nicholson DOT com http://www.nicholson.com/rhn/ #include <canonical.disclaimer> // only my own opinions, etc.