DSPRelated.com
Forums

Changing the sampling rate of an audio signal.

Started by ma August 5, 2005
Hello,

    I want to change the sample rate of an audio signal.  Where can I find 
some information about it? Some mathematical model and some source code 
would be perfect.



What I want to do is:



 I have a device that can play audio signal with the sampling rate of 8KSPS. 
If I want to play a signal that is samples at say 44KSPS I need to change 
the sampling rate. How can I do it efficiently and mathematically correct 
( no aliasing)



In other hand this device can generate audio signal with the sampling rate 
of 8KBPS, How can change the sampling rate to say 44KSPS?



I am working on windows so any help from windows OS can be used.



Any suggestion on where I may start will be very appreciating?



Best regards




ma wrote:
> > Hello, > > I want to change the sample rate of an audio signal. Where can I find > some information about it? Some mathematical model and some source code > would be perfect.
Secret Rabbit Code: http://www.mega-nerd.com/SRC/ is released under the terms of the GNU General Public License.
> I am working on windows so any help from windows OS can be used.
It compiles for Linux, MacOSX and Win32. Erik -- +-----------------------------------------------------------+ Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) +-----------------------------------------------------------+ Linux: the only OS that makes you feel guilty when you reboot -- Kenneth Crudup in comp.os.linux.misc
ma wrote:
> Hello, > > I want to change the sample rate of an audio signal. Where can I find > some information about it? Some mathematical model and some source code > would be perfect.
There is an excellent tutorial at http://www.dspdimension.com/ that supplements Eric's, as well as some example (working) code. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Thanks,

    The tutorials in this page are very interesting and informative. I 
enjoyed reading them but I couldn't find any tutorial on sampling rate 
changing. Did I miss something?



Best regards



"Jerry Avins" <jya@ieee.org> wrote in message 
news:GamdnZ57FpHz927fRVn-iQ@rcn.net...
> ma wrote: >> Hello, >> >> I want to change the sample rate of an audio signal. Where can I >> find some information about it? Some mathematical model and some source >> code would be perfect. > > There is an excellent tutorial at http://www.dspdimension.com/ that > supplements Eric's, as well as some example (working) code. > > Jerry > -- > Engineering is the art of making what you want from things you can get. > &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Thanks,

Interesting code. But I couldn't find any mathematical model on how they are 
doing this. Why they need a whole file to do this? Why small chunk of data 
generate some effect?

Where can I find some mathematical modeling? I need to know the theory and 
then use the code as a learning practice.



Best regards





"Erik de Castro Lopo" <nospam@mega-nerd.com> wrote in message 
news:42F34E52.DCF15CD2@mega-nerd.com...
> ma wrote: >> >> Hello, >> >> I want to change the sample rate of an audio signal. Where can I >> find >> some information about it? Some mathematical model and some source code >> would be perfect. > > Secret Rabbit Code: > > http://www.mega-nerd.com/SRC/ > > is released under the terms of the GNU General Public License. > >> I am working on windows so any help from windows OS can be used. > > It compiles for Linux, MacOSX and Win32. > > Erik > -- > +-----------------------------------------------------------+ > Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) > +-----------------------------------------------------------+ > Linux: the only OS that makes you feel guilty when you reboot > -- Kenneth Crudup in comp.os.linux.misc
ma wrote:

(top-posting fixed)
> "Erik de Castro Lopo" <nospam@mega-nerd.com> wrote in message > news:42F34E52.DCF15CD2@mega-nerd.com... > >>ma wrote: >> >>>Hello, >>> >>> I want to change the sample rate of an audio signal. Where can I >>>find >>>some information about it? Some mathematical model and some source code >>>would be perfect. >> >>Secret Rabbit Code: >> >> http://www.mega-nerd.com/SRC/ >> >>is released under the terms of the GNU General Public License. >> >> >>>I am working on windows so any help from windows OS can be used. >> >>It compiles for Linux, MacOSX and Win32. >> >>Erik >>-- >>+-----------------------------------------------------------+ >> Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) >>+-----------------------------------------------------------+ >>Linux: the only OS that makes you feel guilty when you reboot >> -- Kenneth Crudup in comp.os.linux.misc > > >
> Thanks, > > Interesting code. But I couldn't find any mathematical model on how > they are doing this. Why they need a whole file to do this? Why small > chunk of data generate some effect? > > Where can I find some mathematical modeling? I need to know the theory > and then use the code as a learning practice. > The underlying technique is called polyphase filtering. I just tried to type up a synopsis and failed -- search for it on the web & you'll find some good description, no doubt. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
For some theory, start by reading the notes on analog devices on their hardware 
sample rate converters.  Here are a few links:
http://www.analog.com/UploadedFiles/Application_Notes/14452667AN394.pdf
http://www.analog.com/en/content/0,2886,765%255F807%255F9690,00.html

This focuses on real-time hardware implementations, but I find it to be a very 
readable introduction.

-- 
Jon Harris
SPAM blocker in place:
Remove 99 (but leave 7) to reply

"ma" <ma@nowhere.com> wrote in message 
news:VVLIe.108880$Pf3.64017@fe2.news.blueyonder.co.uk...
> Thanks, > > Interesting code. But I couldn't find any mathematical model on how they are > doing this. Why they need a whole file to do this? Why small chunk of data > generate some effect? > > Where can I find some mathematical modeling? I need to know the theory and > then use the code as a learning practice. > > > > Best regards > > > > "Erik de Castro Lopo" <nospam@mega-nerd.com> wrote in message > news:42F34E52.DCF15CD2@mega-nerd.com... >> ma wrote: >>> >>> Hello, >>> >>> I want to change the sample rate of an audio signal. Where can I find >>> some information about it? Some mathematical model and some source code >>> would be perfect. >> >> Secret Rabbit Code: >> >> http://www.mega-nerd.com/SRC/ >> >> is released under the terms of the GNU General Public License. >> >>> I am working on windows so any help from windows OS can be used. >> >> It compiles for Linux, MacOSX and Win32. >> >> Erik
in article VVLIe.108880$Pf3.64017@fe2.news.blueyonder.co.uk, ma at
ma@nowhere.com wrote on 08/05/2005 11:51:

> Where can I find some mathematical modeling? I need to know the theory and > then use the code as a learning practice.
you want theory? i'll give you theory. below is about as fundamental for the theory as you can get. it really is just a result or application of the Nyquist/Shannon Sampling and Reconstruction Theorem. imagine outputting your signal, at the original sampling rate, to an ideal D/A converter and then resampling that analog output signal with an ideal A/D converter (running at the new sampling rate). now convert that imagination to mathematics (see below). i could have just referred to the post (responding to the infamous "Airy-head") but Google is messing up the ASCII spacing and you don't wanna read what Airy had to say, anyway. so it's reposted below. -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge." (a monospaced font needed to view the following correctly) ____________________________________________________________________________ &#4294967295; &#4294967295; &#4294967295; &#4294967295; Bandlimited Interpolation, Sample Rate Conversion, or &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; Fractional-Sample Delay from the P.O.V. of the &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; Nyquist/Shannon Sampling and Reconstruction Theorem ____________________________________________________________________________ Here is the mathematical expression of the sampling and reconstruction theorem: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; x(t)*q(t) = T*SUM{x[k]*d(t-k*T)} &#4294967295; .------. &#4294967295; &#4294967295; x(t)--->(*)------------------------------------->| H(f) |---> x(t) &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;^ &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;'------' &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;| &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;| &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;'------- q(t) = T * SUM{ d(t - k*T) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;k=-inf where: d(t) = 'dirac' impulse function and T = 1/Fs = sampling period &#4294967295; &#4294967295; &#4294967295; &#4294967295; Fs = sampling frequency &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; q(t) = T * SUM{ d(t - k*T) } &#4294967295;is the "sampling function", is periodic &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;with period T, and can be expressed as a &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; Fourier series. &#4294967295;It turns out that ALL of &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; the Fourier coefficients are equal to 1. &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; q(t) = SUM{ c[n]*exp(j*2*pi*n/T*t) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; n=-inf where c[n] is the Fourier series coefficient: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; t0+T &#4294967295; &#4294967295; c[n] = &#4294967295;1/T * integral{q(t) * exp(-j*2*pi*n/T*t) dt} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;t0 and t0 can be any time. &#4294967295;We choose t0 to be -T/2. &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;T/2 &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; c[n] = &#4294967295;1/T * integral{T * SUM{ d(t - k*T) } * exp(-j*2*pi*n/T*t) dt} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; -T/2 &#4294967295; &#4294967295; k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; T/2 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;= integral{ d(t - 0*T) * exp(-j*2*pi*n/T*t) dt} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;-T/2 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; T/2 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;= integral{ d(t) * exp(-j*2*pi*n/T*t) dt} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;-T/2 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;= exp(-j*2*pi*n/T*0) = 1 So all Fourier series coefficients for the periodic q(t) are 1. This results in another valid expression for q(t): &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; q(t) = SUM{ exp(j*2*pi*n*Fs*t) } . &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;n=-inf The sampled signal looks like: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; x(t)*q(t) = x(t) * T * SUM{ d(t - k*T) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; = T * SUM{ x(t) * d(t - k*T) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; = T * SUM{ x(k*T) * d(t - k*T) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; = T * SUM{ x[k] * d(t - k*T) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf where x[k] =def x(k*T) by definition. (We are using the notation that x[] is a discrete sequence and x() is a continuous function.) BTW, if you where to compute the Laplace Transform of the sampled signal x(t)*q(t), you would get the Z Transform of x[k] scaled by the constant T. An alternative (and equally important representation) of the sampled signal is: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; x(t)*q(t) = x(t) * SUM{ exp(j*2*pi*n*Fs*t) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;n=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; = SUM{ x(t) * exp(j*2*pi*n*Fs*t) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; n=-inf Defining the spectrum of x(t) as its Fourier Transform: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; X(f) =def FT{ x(t) } =def integral{ x(t)*exp(-j*2*pi*f*t) dt} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; -inf Then using the frequency shifting property of the Fourier Transform, &#4294967295; &#4294967295; FT{ x(t)*exp(j*2*pi*f0*t) } = X(f - f0) results in &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; FT{ x(t)*q(t) } = SUM{ X(f - n*Fs) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; n=-inf This says, what we all know, that the spectrum of our signal being sampled is shifted and repeated forever at multiples of the sampling frequency, Fs. &#4294967295;If x(t) or X(f) is bandlimited to B (i.e. X(f) = 0 for all |f| > B) AND if there is no overlap of the tails of adjacent images X(f), that is: &#4294967295; right tail of nth image of X(f) < left tail of (n+1)th image &#4294967295; n*Fs + B < (n+1)*Fs - B = n*Fs + Fs - B &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;B < Fs - B &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;2*B < Fs = 1/T Then we ought to be able to reconstruct X(f) (and also x(t)) by low pass filtering out all of the images of X(f). &#4294967295;To do that, Fs > 2*B (to prevent overlap) and H(f) must be: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;{ &#4294967295;1 &#4294967295;for &#4294967295;|f| < &#4294967295;Fs/2 = 1/(2*T) &#4294967295; &#4294967295; H(f) = { &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;{ &#4294967295;0 &#4294967295;for &#4294967295;|f| >= Fs/2 = 1/(2*T) This is the "sampling" half of the Nyquist/Shannon sampling and reconstruction theorem. &#4294967295;It says that the sampling frequency, Fs, must be strictly greater than twice the bandwidth, B, of the continuous-time signal, x(t), for no information to be lost (or "aliased"). &#4294967295;The "reconstruction" half follows: The impulse response of the reconstruction LPF, H(f), is the inverse Fourier Transform of H(f), called h(t): &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+inf &#4294967295; &#4294967295; h(t) = iFT{ H(f) } = integral{ H(f)*exp(+j*2*pi*f*t) df} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;1/(2*T) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = integral{ exp(+j*2*pi*f*t) df} &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; -1/(2*T) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = (exp(+j*2*pi/(2*T)*t) - exp(+j*2*pi/(-2*T)*t))/(j*2*pi *t) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = ( exp(+j*pi/T*t) - exp(-j*pi/T*t) )/(j*2*pi*t) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = sin((pi/T)*t)/(pi*t) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = (1/T)*sin(pi*t/T)/(pi*t/T) &#4294967295; &#4294967295; &#4294967295; &#4294967295; = (1/T)*sinc(t/T) where sinc(u) =def sin(pi*u)/(pi*u) The input to the LPF is x(t)*q(t) = T*SUM{x[k]*d(t - k*T)} . Each d(t - k*T) impulse generates its own impulse response and since the LPF is linear and time invariant, all we have to do is add up the time-shifted impulse responses weighted by their coefficients, x[k]. &#4294967295;The T and 1/T kill each other off. The output of the LPF is &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; x(t) = SUM{ x[k]*sinc((t-k*T)/T) } = SUM{ x[k]*sinc(t/T - k) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf This equation tells us explicitly how to reconstruct our sampled, bandlimited input signal from the samples. &#4294967295;This is the "reconstruction" half of the Nyquist/Shannon sampling and reconstruction theorem. Interpolation, Fractional Delay, Sample Rate Conversion, etc: When interpolating (whether for fractional sample delay or for doing sample rate conversion), you must evaluate this equation for times that might not be integer multiples of your sampling period, T. The sinc(t/T) function is one for t = 0 and zero for t = k*T for k = nonzero integer. &#4294967295;This means that if your new sample time, t, happens to land exactly on an old sample time, k*T, only that sample (and none of the neighbors) contributes to the output sample and the output sample is equal to the input sample. &#4294967295;Only in the case where the output sample is in between input samples, do the neighbors contribute to the calculation. Since the sinc() function goes on forever to +/- infinity, it must be truncated somewhere to be of practical use. Truncating is actually applying the rectangular window (the worst kind) so it is advantageous to window down the sinc() function gradually using something like a Hamming or Kaiser window. &#4294967295;In my experience, with a good window, you'll need to keep the domain of the windowed sinc() function from -16 to +16 (a 32 tap FIR) and sample it 16384 times in that region (that would be 16384/32 = 512 polyphases or "fractional delays" if linear interpolation is subsequently used to get in between neighboring polyphases). Now we simply split the time, t, into an integer part, m, and fractional part, a, and substitute: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; x((m+a)*T) = SUM{ x[k]*sinc((m+a)*T/T - k) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;= SUM{ x[k]*sinc(a + m - k) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf where: t = (m + a)*T &#4294967295; and m = floor(t/T) &#4294967295; a = fract(t/T) = t/T - floor(t/T) t-T < m*T <= t &#4294967295;which means a is always nonnegative and less than 1: &#4294967295; 0 <= a < 1 The limits of the sum can be bumped around a bit without changing it and by substituting k <- k+m : &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; +inf &#4294967295; &#4294967295; x((m+a)*T) = SUM{ x[m+k] * sinc(a - k) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-inf Now, an approximation is made by truncating the summation to a finite amount (which is effectively windowing): &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;+16 &#4294967295; &#4294967295; x((m+a)*T) = SUM{ x[m+k] * sinc(a-k) * w((a-k)/16) } &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; k=-15 w(u) is the window function. &#4294967295;A Hamming window would be: &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;{ 0.54 + 0.46*cos(pi*u) &#4294967295; for |u| < 1 &#4294967295; &#4294967295; w(u) = { &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;{ 0 &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; for |u| >= 1 A Kaiser window would be better. This requires two 32 point FIR computations to calculate two adjacent interpolated samples (these are linearly interpolated to get the final output sample). &#4294967295;Since the sinc(u)*w(u) function is symmetrical, that means 8193 numbers stored somewhere in memory. &#4294967295;When interpolating, the integer part of t/T (or 'm') determines which 32 adjacent samples of x[k] to use, the fractional part of t/T (or 'a') determines which set of 32 windowed sinc() coefficients to be used to combine the 32 samples. ____________________________________________________________________________ ____________________________________________________________________________
ma wrote:
> Thanks, > > The tutorials in this page are very interesting and informative. I > enjoyed reading them but I couldn't find any tutorial on sampling rate > changing. Did I miss something?
... There's a close connection between pitch changing ans sample-rate changing. I hoped you would see how they fit. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
ma wrote:
> I want to change the sample rate of an audio signal. Where can I find > some information about it? Some mathematical model and some source code > would be perfect.
It's all about filtered interpolation. Most modern methods are based on windowed-Sinc interpolation. One of the fundamental papers on this subject is here: http://ccrma-www.stanford.edu/~jos/resample/ The various polyphase methods are just an optimization. On a fast PC, you can calculate exact Sinc filter coefficients on the fly for some simpler types of windows. IMHO. YMMV. -- rhn A.T nicholson d.O.t C-o-M