|
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <HTML>
-
- <HEAD>
- <TITLE>
- Secret Rabbit Code (aka libsamplerate)
- </TITLE>
- <META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <META NAME="Version" CONTENT="libsamplerate-0.1.8">
- <META NAME="Description" CONTENT="The Secret Rabbit Code Home Page">
- <META NAME="Keywords" CONTENT="libsamplerate sound resample audio dsp Linux">
- <LINK REL=StyleSheet HREF="SRC.css" TYPE="text/css" MEDIA="all">
- </HEAD>
-
- <BODY TEXT="#FFFFFF" BGCOLOR="#000000" LINK="#FB1465" VLINK="#FB1465" ALINK="#FB1465">
- <!-- pepper -->
- <CENTER>
- <IMG SRC="SRC.png" HEIGHT=100 WIDTH=760 ALT="SRC.png">
- </CENTER>
- <!-- pepper -->
- <BR>
- <!-- pepper -->
- <TABLE ALIGN="center" WIDTH="98%">
- <TR>
- <TD VALIGN="top">
- <BR>
- <DIV CLASS="nav">
- <BR>
- <A HREF="index.html">Home</A><BR>
- <A HREF="license.html">License</A><BR>
- <A HREF="history.html">History</A><BR>
- <A HREF="download.html">Download</A><BR>
- <A HREF="quality.html">Quality</A><BR>
- <A HREF="api.html">API</A><BR>
- <A HREF="bugs.html">Bug Reporting</A><BR>
- <A HREF="win32.html">On Win32</A><BR>
- <A HREF="faq.html">FAQ</A><BR>
- <A HREF="lists.html">Mailing Lists</A><BR>
- <A HREF="ChangeLog">ChangeLog</A><BR>
- <BR>
- <DIV CLASS="block">
- Author :<BR>Erik de Castro Lopo
- <!-- pepper -->
- <BR><BR>
- <!-- pepper -->
-
- </DIV>
- <IMG SRC=
- "/cgi-bin/Count.cgi?ft=6|frgb=55;55;55|tr=0|md=6|dd=B|st=1|sh=1|df=src_api.dat"
- HEIGHT=30 WIDTH=100 ALT="counter.gif">
- </DIV>
-
- </TD>
- <!-- pepper -->
- <!-- ######################################################################## -->
- <!-- pepper -->
- <TD VALIGN="top">
- <DIV CLASS="block">
-
- <H1><B>Frequently Asked Questions</B></H1>
- <P>
- <A HREF="#Q001">Q1 : Is it normal for the output of libsamplerate to be louder
- than its input?</A><BR><BR>
- <A HREF="#Q002">Q2 : On Unix/Linux/MacOSX, what is the best way of detecting
- the presence and location of libsamplerate and its header file using
- autoconf?</A><BR><BR>
- <A HREF="#Q003">Q3 : If I upsample and downsample to the original rate, for
- example 44.1->96->44.1, do I get an identical signal as the one before the
- up/down resampling?</A><BR><BR>
- <A HREF="#Q004">Q4 : If I ran src_simple (libsamplerate) on small chunks (160
- frames) would that sound bad?</A><BR><BR>
- <A HREF="#Q005">Q5 : I'm using libsamplerate but the high quality settings
- sound worse than the SRC_LINEAR converter. Why?</A><BR><BR>
- <A HREF="#Q006">Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of
- 2. I reset the converter and put in 1000 samples and I expect to get 2000
- samples out, but I'm getting less than that. Why?</A><BR><BR>
- <A HREF="#Q007">Q7 : I have input and output sample rates that are integer
- values, but the API wants me to divide one by the other and put the result
- in a floating point number. Won't this case problems for long running
- conversions?</A><BR><BR>
- </P>
- <HR>
- <!-- ========================================================================= -->
- <A NAME="Q001"></A>
- <H2><BR><B>Q1 : Is it normal for the output of libsamplerate to be louder
- than its input?</B></H2>
- <P>
- The output of libsamplerate will be roughly the same volume as the input.
- However, even if the input is strictly in the range (-1.0, 1.0), it is still
- possible for the output to contain peak values outside this range.
- </P>
- <P>
- Consider four consecutive samples of [0.5 0.999 0.999 0.5].
- If we are up sampling by a factor of two we need to insert samples between
- each of the existing samples.
- Its pretty obvious then, that the sample between the two 0.999 values should
- and will be bigger than 0.999.
- </P>
- <P>
- This means that anyone using libsamplerate should normalize its output before
- doing things like saving the audio to a 16 bit WAV file.
- </P>
-
- <!-- pepper -->
- <!-- ========================================================================= -->
-
- <a NAME="Q002"></a>
- <h2><br><b>Q2 : On Unix/Linux/MacOSX, what is the best way of detecting
- the presence and location of libsamplerate and its header file using
- autoconf?</b></h2>
-
- <p>
- libsamplerate uses the pkg-config (man pkg-config) method of registering itself
- with the host system.
- The best way of detecting its presence is using something like this in configure.ac
- (or configure.in):
- </p>
-
- <pre>
- PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.1.3,
- ac_cv_samplerate=1, ac_cv_samplerate=0)
-
- AC_DEFINE_UNQUOTED([HAVE_SAMPLERATE],${ac_cv_samplerate},
- [Set to 1 if you have libsamplerate.])
-
- AC_SUBST(SAMPLERATE_CFLAGS)
- AC_SUBST(SAMPLERATE_LIBS)
- </pre>
- <p>
- This will automatically set the <b>SAMPLERATE_CFLAGS</b> and <b>SAMPLERATE_LIBS</b>
- variables which can be used in Makefile.am or Makefile.in like this:
- </p>
- <pre>
- SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@
- SAMPLERATE_LIBS = @SAMPLERATE_LIBS@
- </pre>
-
- <p>
- If you install libsamplerate from source, you will probably need to set the
- <b>PKG_CONFIG_PATH</b> environment variable's suggested at the end of the
- libsamplerate configure process. For instance on my system I get this:
- </p>
- <pre>
- -=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-=-
-
- Configuration summary :
-
- Version : ..................... 0.1.3
- Enable debugging : ............ no
-
- Tools :
-
- Compiler is GCC : ............. yes
- GCC major version : ........... 3
-
- Extra tools required for testing and examples :
-
- Have FFTW : ................... yes
- Have libsndfile : ............. yes
- Have libefence : .............. no
-
- Installation directories :
-
- Library directory : ........... /usr/local/lib
- Program directory : ........... /usr/local/bin
- Pkgconfig directory : ......... /usr/local/lib/pkgconfig
- </pre>
-
-
- <!-- pepper -->
- <!-- ========================================================================= -->
- <A NAME="Q003"></A>
- <H2><BR><B>Q3 : If I upsample and downsample to the original rate, for
- example 44.1->96->44.1, do I get an identical signal as the one before the
- up/down resampling?</B></H2>
- <P>
- The short answer is that for the general case, no, you don't.
- The long answer is that for some signals, with some converters, you will
- get very, very close.
- </P>
- <P>
- In order to resample correctly (ie using the <B>SRC_SINC_*</B> converters),
- filtering needs to be applied, regardless of whether its upsampling or
- downsampling.
- This filter needs to attenuate all frequencies above 0.5 times the minimum of
- the source and destination sample rate (call this fshmin).
- Since the filter needed to achieve full attenuation at this point, it has to
- start rolling off a some frequency below this point.
- It is this rolloff of the very highest frequencies which causes some of the
- loss.
- </P>
- <P>
- The other factor is that the filter itself can introduce transient artifacts
- which causes the output to be different to the input.
- </P>
-
- <!-- pepper -->
- <!-- ========================================================================= -->
- <A NAME="Q004"></A>
- <H2><BR><B>Q4 : If I ran src_simple on small chunks (say 160 frames) would that
- sound bad?</B></H2>
- <P>
- Well if you are after odd sound effects, it might sound OK.
- If you are after high quality sample rate conversion you will be disappointed.
- </P>
- <P>
- The src_simple() was designed to provide a simple to use interface for people
- who wanted to do sample rate conversion on say, a whole file all at once.
- </P>
-
- <!-- pepper -->
- <!-- ========================================================================= -->
- <A NAME="Q005"></A>
- <H2><BR><B>Q5 : I'm using libsamplerate but the high quality settings
- sound worse than the SRC_LINEAR converter. Why?</B></H2>
- <P>
- There are two possible problems.
- Firstly, if you are using the src_simple() function on successive blocks
- of a stream of samples, you will get bad results. The src_simple() function
- is designed for use on a whole sound file, all at once, not on contiguous
- segments of the same sound file.
- To fix the problem, you need to move to the src_process() API or the callback
- based API.
- </P>
- <P>
- If you are already using the src_process() API or the callback based API and
- the high quality settings sound worse than SRC_LINEAR, then you have other
- problems.
- Read on for more debugging hints.
- </P>
- <P>
- All of the higher quality converters need to keep state while doing conversions
- on segments of a large chunk of audio.
- This state information is kept inside the private data pointed to by the
- SRC_STATE pointer returned by the src_new() function.
- This means, that when you want to start doing sample rate conversion on a
- stream of data, you should call src_new() to get a new SRC_STATE pointer
- (or alternatively, call src_reset() on an existing SRC_STATE pointer).
- You should then pass this SRC_STATE pointer to the src_process() function
- with each new block of audio data.
- When you have completed the conversion, you can then call src_delete() on
- the SRC_STATE pointer.
- </P>
- <P>
- If you are doing all of the above correctly, you need to examine your usage
- of the values passed to src_process() in the
- <A HREF="api_misc.html#SRC_DATA">SRC_DATA</A>
- struct.
- Specifically:
- </P>
- <UL>
- <LI> Check that input_frames and output_frames fields are being set in
- terms of frames (number of sample values times channels) instead
- of just the number of samples.
- <LI> Check that you are using the return values input_frames_used and
- output_frames_gen to update your source and destination pointers
- correctly.
- <LI> Check that you are updating the data_in and data_out pointers
- correctly for each successive call.
- </UL>
- <P>
- While doing the above, it is probably useful to compare what you are doing to
- what is done in the example programs in the examples/ directory of the source
- code tarball.
- </P>
- <P>
- If you have done all of the above and are still having problems then its
- probably time to email the author with the smallest chunk of code that
- adequately demonstrates your problem.
- This chunk should not need to be any more than 100 lines of code.
- </P>
-
- <!-- pepper -->
- <!-- ========================================================================= -->
- <A NAME="Q006"></A>
- <H2><BR><B>Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of
- 2. I reset the converter and put in 1000 samples and I expect to get 2000
- samples out, but I'm getting less than that. Why?</B></H2>
- <P>
- The short answer is that there is a transport delay inside the converter itself.
- Long answer follows.
- </P>
- <P>
- By way of example, the first time you call src_process() you might only get 1900
- samples out.
- However, after that first call all subsequent calls will probably get you about
- 2000 samples out for every 1000 samples you put in.
- </P>
- <P>
- The main problems people have with this transport delay is that they need to read
- out an exact number of samples and the transport delay scews this up.
- The best way to overcome this problem is to always supply more samples on the
- input than is actually needed to create the required number of output samples.
- With reference to the example above, if you always supply 1500 samples at the
- input, you will always get 2000 samples at the output.
- You will always need to keep track of the number of input frames used on each
- call to src_process() and deal with these values appropriately.
- </P>
-
- <!-- pepper -->
- <!-- ========================================================================= -->
- <A NAME="Q007"></A>
- <H2><BR><B>Q7 : I have input and output sample rates that are integer
- values, but the API wants me to divide one by the other and put the result
- in a floating point number. Won't this case problems for long running
- conversions?</B></H2>
- <P>
- The short answer is no, the precision of the ratio is many orders of magnitude
- more than is really needed.
- </P>
- <P>
- For the long answer, lets do come calculations.
- Firstly, the <tt>src_ratio</tt> field is double precision floating point number
- which has
- <a href="http://en.wikipedia.org/wiki/Double_precision">
- 53 bits of precision</a>.
- </P>
- <P>
- That means that the maximum error in your ratio converted to a double is one
- bit in 2^53 which means the the double float value would be wrong by one sample
- after 9007199254740992 samples have passed or wrong by more than half a sample
- wrong after half that many (4503599627370496 samples) have passed.
- </P>
- <P>
- Now if for example our output sample rate is 96kHz then
- </P>
- <pre>
- 4503599627370496 samples at 96kHz is 46912496118 seconds
- 46912496118 seconds is 781874935 minutes
- 781874935 minutes is 13031248 hours
- 13031248 hours is 542968 days
- 542968 days is 1486 years
- </pre>
- <P>
- So, after 1486 years, the input will be wrong by more than half of one sampling
- period.
- </P>
- <p>
- All this assumes that the crystal oscillators uses to sample the audio stream
- is perfect.
- This is not the case.
- According to
- <a href="http://www.ieee-uffc.org/freqcontrol/quartz/vig/vigcomp.htm">
- this web site</a>,
- the accuracy of standard crystal oscillators (XO, TCXO, OCXO) is at best
- 1 in 100 million.
- The <tt>src_ratio</tt> is therefore 45035996 times more accurate than the
- crystal clock source used to sample the original audio signal and any potential
- problem with the <tt>src_ratio</tt> being a floating point number will be
- completely swamped by sampling inaccuracies.
- </p>
-
- <!-- <A HREF="mailto:aldel@mega-nerd.com">For the spam bots</A> -->
-
- </DIV>
- </TD></TR>
- </TABLE>
-
- </BODY>
- </HTML>
|