annotate src/libsamplerate-0.1.8/doc/faq.html @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents c7265573341e
children
rev   line source
Chris@0 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
Chris@0 2 <HTML>
Chris@0 3
Chris@0 4 <HEAD>
Chris@0 5 <TITLE>
Chris@0 6 Secret Rabbit Code (aka libsamplerate)
Chris@0 7 </TITLE>
Chris@0 8 <META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
Chris@0 9 <META NAME="Version" CONTENT="libsamplerate-0.1.8">
Chris@0 10 <META NAME="Description" CONTENT="The Secret Rabbit Code Home Page">
Chris@0 11 <META NAME="Keywords" CONTENT="libsamplerate sound resample audio dsp Linux">
Chris@0 12 <LINK REL=StyleSheet HREF="SRC.css" TYPE="text/css" MEDIA="all">
Chris@0 13 </HEAD>
Chris@0 14
Chris@0 15 <BODY TEXT="#FFFFFF" BGCOLOR="#000000" LINK="#FB1465" VLINK="#FB1465" ALINK="#FB1465">
Chris@0 16 <!-- pepper -->
Chris@0 17 <CENTER>
Chris@0 18 <IMG SRC="SRC.png" HEIGHT=100 WIDTH=760 ALT="SRC.png">
Chris@0 19 </CENTER>
Chris@0 20 <!-- pepper -->
Chris@0 21 <BR>
Chris@0 22 <!-- pepper -->
Chris@0 23 <TABLE ALIGN="center" WIDTH="98%">
Chris@0 24 <TR>
Chris@0 25 <TD VALIGN="top">
Chris@0 26 <BR>
Chris@0 27 <DIV CLASS="nav">
Chris@0 28 <BR>
Chris@0 29 <A HREF="index.html">Home</A><BR>
Chris@0 30 <A HREF="license.html">License</A><BR>
Chris@0 31 <A HREF="history.html">History</A><BR>
Chris@0 32 <A HREF="download.html">Download</A><BR>
Chris@0 33 <A HREF="quality.html">Quality</A><BR>
Chris@0 34 <A HREF="api.html">API</A><BR>
Chris@0 35 <A HREF="bugs.html">Bug Reporting</A><BR>
Chris@0 36 <A HREF="win32.html">On Win32</A><BR>
Chris@0 37 <A HREF="faq.html">FAQ</A><BR>
Chris@0 38 <A HREF="lists.html">Mailing Lists</A><BR>
Chris@0 39 <A HREF="ChangeLog">ChangeLog</A><BR>
Chris@0 40 <BR>
Chris@0 41 <DIV CLASS="block">
Chris@0 42 Author :<BR>Erik de Castro Lopo
Chris@0 43 <!-- pepper -->
Chris@0 44 <BR><BR>
Chris@0 45 <!-- pepper -->
Chris@0 46
Chris@0 47 </DIV>
Chris@0 48 <IMG SRC=
Chris@0 49 "/cgi-bin/Count.cgi?ft=6|frgb=55;55;55|tr=0|md=6|dd=B|st=1|sh=1|df=src_api.dat"
Chris@0 50 HEIGHT=30 WIDTH=100 ALT="counter.gif">
Chris@0 51 </DIV>
Chris@0 52
Chris@0 53 </TD>
Chris@0 54 <!-- pepper -->
Chris@0 55 <!-- ######################################################################## -->
Chris@0 56 <!-- pepper -->
Chris@0 57 <TD VALIGN="top">
Chris@0 58 <DIV CLASS="block">
Chris@0 59
Chris@0 60 <H1><B>Frequently Asked Questions</B></H1>
Chris@0 61 <P>
Chris@0 62 <A HREF="#Q001">Q1 : Is it normal for the output of libsamplerate to be louder
Chris@0 63 than its input?</A><BR><BR>
Chris@0 64 <A HREF="#Q002">Q2 : On Unix/Linux/MacOSX, what is the best way of detecting
Chris@0 65 the presence and location of libsamplerate and its header file using
Chris@0 66 autoconf?</A><BR><BR>
Chris@0 67 <A HREF="#Q003">Q3 : If I upsample and downsample to the original rate, for
Chris@0 68 example 44.1->96->44.1, do I get an identical signal as the one before the
Chris@0 69 up/down resampling?</A><BR><BR>
Chris@0 70 <A HREF="#Q004">Q4 : If I ran src_simple (libsamplerate) on small chunks (160
Chris@0 71 frames) would that sound bad?</A><BR><BR>
Chris@0 72 <A HREF="#Q005">Q5 : I'm using libsamplerate but the high quality settings
Chris@0 73 sound worse than the SRC_LINEAR converter. Why?</A><BR><BR>
Chris@0 74 <A HREF="#Q006">Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of
Chris@0 75 2. I reset the converter and put in 1000 samples and I expect to get 2000
Chris@0 76 samples out, but I'm getting less than that. Why?</A><BR><BR>
Chris@0 77 <A HREF="#Q007">Q7 : I have input and output sample rates that are integer
Chris@0 78 values, but the API wants me to divide one by the other and put the result
Chris@0 79 in a floating point number. Won't this case problems for long running
Chris@0 80 conversions?</A><BR><BR>
Chris@0 81 </P>
Chris@0 82 <HR>
Chris@0 83 <!-- ========================================================================= -->
Chris@0 84 <A NAME="Q001"></A>
Chris@0 85 <H2><BR><B>Q1 : Is it normal for the output of libsamplerate to be louder
Chris@0 86 than its input?</B></H2>
Chris@0 87 <P>
Chris@0 88 The output of libsamplerate will be roughly the same volume as the input.
Chris@0 89 However, even if the input is strictly in the range (-1.0, 1.0), it is still
Chris@0 90 possible for the output to contain peak values outside this range.
Chris@0 91 </P>
Chris@0 92 <P>
Chris@0 93 Consider four consecutive samples of [0.5 0.999 0.999 0.5].
Chris@0 94 If we are up sampling by a factor of two we need to insert samples between
Chris@0 95 each of the existing samples.
Chris@0 96 Its pretty obvious then, that the sample between the two 0.999 values should
Chris@0 97 and will be bigger than 0.999.
Chris@0 98 </P>
Chris@0 99 <P>
Chris@0 100 This means that anyone using libsamplerate should normalize its output before
Chris@0 101 doing things like saving the audio to a 16 bit WAV file.
Chris@0 102 </P>
Chris@0 103
Chris@0 104 <!-- pepper -->
Chris@0 105 <!-- ========================================================================= -->
Chris@0 106
Chris@0 107 <a NAME="Q002"></a>
Chris@0 108 <h2><br><b>Q2 : On Unix/Linux/MacOSX, what is the best way of detecting
Chris@0 109 the presence and location of libsamplerate and its header file using
Chris@0 110 autoconf?</b></h2>
Chris@0 111
Chris@0 112 <p>
Chris@0 113 libsamplerate uses the pkg-config (man pkg-config) method of registering itself
Chris@0 114 with the host system.
Chris@0 115 The best way of detecting its presence is using something like this in configure.ac
Chris@0 116 (or configure.in):
Chris@0 117 </p>
Chris@0 118
Chris@0 119 <pre>
Chris@0 120 PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.1.3,
Chris@0 121 ac_cv_samplerate=1, ac_cv_samplerate=0)
Chris@0 122
Chris@0 123 AC_DEFINE_UNQUOTED([HAVE_SAMPLERATE],${ac_cv_samplerate},
Chris@0 124 [Set to 1 if you have libsamplerate.])
Chris@0 125
Chris@0 126 AC_SUBST(SAMPLERATE_CFLAGS)
Chris@0 127 AC_SUBST(SAMPLERATE_LIBS)
Chris@0 128 </pre>
Chris@0 129 <p>
Chris@0 130 This will automatically set the <b>SAMPLERATE_CFLAGS</b> and <b>SAMPLERATE_LIBS</b>
Chris@0 131 variables which can be used in Makefile.am or Makefile.in like this:
Chris@0 132 </p>
Chris@0 133 <pre>
Chris@0 134 SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@
Chris@0 135 SAMPLERATE_LIBS = @SAMPLERATE_LIBS@
Chris@0 136 </pre>
Chris@0 137
Chris@0 138 <p>
Chris@0 139 If you install libsamplerate from source, you will probably need to set the
Chris@0 140 <b>PKG_CONFIG_PATH</b> environment variable's suggested at the end of the
Chris@0 141 libsamplerate configure process. For instance on my system I get this:
Chris@0 142 </p>
Chris@0 143 <pre>
Chris@0 144 -=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-=-
Chris@0 145
Chris@0 146 Configuration summary :
Chris@0 147
Chris@0 148 Version : ..................... 0.1.3
Chris@0 149 Enable debugging : ............ no
Chris@0 150
Chris@0 151 Tools :
Chris@0 152
Chris@0 153 Compiler is GCC : ............. yes
Chris@0 154 GCC major version : ........... 3
Chris@0 155
Chris@0 156 Extra tools required for testing and examples :
Chris@0 157
Chris@0 158 Have FFTW : ................... yes
Chris@0 159 Have libsndfile : ............. yes
Chris@0 160 Have libefence : .............. no
Chris@0 161
Chris@0 162 Installation directories :
Chris@0 163
Chris@0 164 Library directory : ........... /usr/local/lib
Chris@0 165 Program directory : ........... /usr/local/bin
Chris@0 166 Pkgconfig directory : ......... /usr/local/lib/pkgconfig
Chris@0 167 </pre>
Chris@0 168
Chris@0 169
Chris@0 170 <!-- pepper -->
Chris@0 171 <!-- ========================================================================= -->
Chris@0 172 <A NAME="Q003"></A>
Chris@0 173 <H2><BR><B>Q3 : If I upsample and downsample to the original rate, for
Chris@0 174 example 44.1->96->44.1, do I get an identical signal as the one before the
Chris@0 175 up/down resampling?</B></H2>
Chris@0 176 <P>
Chris@0 177 The short answer is that for the general case, no, you don't.
Chris@0 178 The long answer is that for some signals, with some converters, you will
Chris@0 179 get very, very close.
Chris@0 180 </P>
Chris@0 181 <P>
Chris@0 182 In order to resample correctly (ie using the <B>SRC_SINC_*</B> converters),
Chris@0 183 filtering needs to be applied, regardless of whether its upsampling or
Chris@0 184 downsampling.
Chris@0 185 This filter needs to attenuate all frequencies above 0.5 times the minimum of
Chris@0 186 the source and destination sample rate (call this fshmin).
Chris@0 187 Since the filter needed to achieve full attenuation at this point, it has to
Chris@0 188 start rolling off a some frequency below this point.
Chris@0 189 It is this rolloff of the very highest frequencies which causes some of the
Chris@0 190 loss.
Chris@0 191 </P>
Chris@0 192 <P>
Chris@0 193 The other factor is that the filter itself can introduce transient artifacts
Chris@0 194 which causes the output to be different to the input.
Chris@0 195 </P>
Chris@0 196
Chris@0 197 <!-- pepper -->
Chris@0 198 <!-- ========================================================================= -->
Chris@0 199 <A NAME="Q004"></A>
Chris@0 200 <H2><BR><B>Q4 : If I ran src_simple on small chunks (say 160 frames) would that
Chris@0 201 sound bad?</B></H2>
Chris@0 202 <P>
Chris@0 203 Well if you are after odd sound effects, it might sound OK.
Chris@0 204 If you are after high quality sample rate conversion you will be disappointed.
Chris@0 205 </P>
Chris@0 206 <P>
Chris@0 207 The src_simple() was designed to provide a simple to use interface for people
Chris@0 208 who wanted to do sample rate conversion on say, a whole file all at once.
Chris@0 209 </P>
Chris@0 210
Chris@0 211 <!-- pepper -->
Chris@0 212 <!-- ========================================================================= -->
Chris@0 213 <A NAME="Q005"></A>
Chris@0 214 <H2><BR><B>Q5 : I'm using libsamplerate but the high quality settings
Chris@0 215 sound worse than the SRC_LINEAR converter. Why?</B></H2>
Chris@0 216 <P>
Chris@0 217 There are two possible problems.
Chris@0 218 Firstly, if you are using the src_simple() function on successive blocks
Chris@0 219 of a stream of samples, you will get bad results. The src_simple() function
Chris@0 220 is designed for use on a whole sound file, all at once, not on contiguous
Chris@0 221 segments of the same sound file.
Chris@0 222 To fix the problem, you need to move to the src_process() API or the callback
Chris@0 223 based API.
Chris@0 224 </P>
Chris@0 225 <P>
Chris@0 226 If you are already using the src_process() API or the callback based API and
Chris@0 227 the high quality settings sound worse than SRC_LINEAR, then you have other
Chris@0 228 problems.
Chris@0 229 Read on for more debugging hints.
Chris@0 230 </P>
Chris@0 231 <P>
Chris@0 232 All of the higher quality converters need to keep state while doing conversions
Chris@0 233 on segments of a large chunk of audio.
Chris@0 234 This state information is kept inside the private data pointed to by the
Chris@0 235 SRC_STATE pointer returned by the src_new() function.
Chris@0 236 This means, that when you want to start doing sample rate conversion on a
Chris@0 237 stream of data, you should call src_new() to get a new SRC_STATE pointer
Chris@0 238 (or alternatively, call src_reset() on an existing SRC_STATE pointer).
Chris@0 239 You should then pass this SRC_STATE pointer to the src_process() function
Chris@0 240 with each new block of audio data.
Chris@0 241 When you have completed the conversion, you can then call src_delete() on
Chris@0 242 the SRC_STATE pointer.
Chris@0 243 </P>
Chris@0 244 <P>
Chris@0 245 If you are doing all of the above correctly, you need to examine your usage
Chris@0 246 of the values passed to src_process() in the
Chris@0 247 <A HREF="api_misc.html#SRC_DATA">SRC_DATA</A>
Chris@0 248 struct.
Chris@0 249 Specifically:
Chris@0 250 </P>
Chris@0 251 <UL>
Chris@0 252 <LI> Check that input_frames and output_frames fields are being set in
Chris@0 253 terms of frames (number of sample values times channels) instead
Chris@0 254 of just the number of samples.
Chris@0 255 <LI> Check that you are using the return values input_frames_used and
Chris@0 256 output_frames_gen to update your source and destination pointers
Chris@0 257 correctly.
Chris@0 258 <LI> Check that you are updating the data_in and data_out pointers
Chris@0 259 correctly for each successive call.
Chris@0 260 </UL>
Chris@0 261 <P>
Chris@0 262 While doing the above, it is probably useful to compare what you are doing to
Chris@0 263 what is done in the example programs in the examples/ directory of the source
Chris@0 264 code tarball.
Chris@0 265 </P>
Chris@0 266 <P>
Chris@0 267 If you have done all of the above and are still having problems then its
Chris@0 268 probably time to email the author with the smallest chunk of code that
Chris@0 269 adequately demonstrates your problem.
Chris@0 270 This chunk should not need to be any more than 100 lines of code.
Chris@0 271 </P>
Chris@0 272
Chris@0 273 <!-- pepper -->
Chris@0 274 <!-- ========================================================================= -->
Chris@0 275 <A NAME="Q006"></A>
Chris@0 276 <H2><BR><B>Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of
Chris@0 277 2. I reset the converter and put in 1000 samples and I expect to get 2000
Chris@0 278 samples out, but I'm getting less than that. Why?</B></H2>
Chris@0 279 <P>
Chris@0 280 The short answer is that there is a transport delay inside the converter itself.
Chris@0 281 Long answer follows.
Chris@0 282 </P>
Chris@0 283 <P>
Chris@0 284 By way of example, the first time you call src_process() you might only get 1900
Chris@0 285 samples out.
Chris@0 286 However, after that first call all subsequent calls will probably get you about
Chris@0 287 2000 samples out for every 1000 samples you put in.
Chris@0 288 </P>
Chris@0 289 <P>
Chris@0 290 The main problems people have with this transport delay is that they need to read
Chris@0 291 out an exact number of samples and the transport delay scews this up.
Chris@0 292 The best way to overcome this problem is to always supply more samples on the
Chris@0 293 input than is actually needed to create the required number of output samples.
Chris@0 294 With reference to the example above, if you always supply 1500 samples at the
Chris@0 295 input, you will always get 2000 samples at the output.
Chris@0 296 You will always need to keep track of the number of input frames used on each
Chris@0 297 call to src_process() and deal with these values appropriately.
Chris@0 298 </P>
Chris@0 299
Chris@0 300 <!-- pepper -->
Chris@0 301 <!-- ========================================================================= -->
Chris@0 302 <A NAME="Q007"></A>
Chris@0 303 <H2><BR><B>Q7 : I have input and output sample rates that are integer
Chris@0 304 values, but the API wants me to divide one by the other and put the result
Chris@0 305 in a floating point number. Won't this case problems for long running
Chris@0 306 conversions?</B></H2>
Chris@0 307 <P>
Chris@0 308 The short answer is no, the precision of the ratio is many orders of magnitude
Chris@0 309 more than is really needed.
Chris@0 310 </P>
Chris@0 311 <P>
Chris@0 312 For the long answer, lets do come calculations.
Chris@0 313 Firstly, the <tt>src_ratio</tt> field is double precision floating point number
Chris@0 314 which has
Chris@0 315 <a href="http://en.wikipedia.org/wiki/Double_precision">
Chris@0 316 53 bits of precision</a>.
Chris@0 317 </P>
Chris@0 318 <P>
Chris@0 319 That means that the maximum error in your ratio converted to a double is one
Chris@0 320 bit in 2^53 which means the the double float value would be wrong by one sample
Chris@0 321 after 9007199254740992 samples have passed or wrong by more than half a sample
Chris@0 322 wrong after half that many (4503599627370496 samples) have passed.
Chris@0 323 </P>
Chris@0 324 <P>
Chris@0 325 Now if for example our output sample rate is 96kHz then
Chris@0 326 </P>
Chris@0 327 <pre>
Chris@0 328 4503599627370496 samples at 96kHz is 46912496118 seconds
Chris@0 329 46912496118 seconds is 781874935 minutes
Chris@0 330 781874935 minutes is 13031248 hours
Chris@0 331 13031248 hours is 542968 days
Chris@0 332 542968 days is 1486 years
Chris@0 333 </pre>
Chris@0 334 <P>
Chris@0 335 So, after 1486 years, the input will be wrong by more than half of one sampling
Chris@0 336 period.
Chris@0 337 </P>
Chris@0 338 <p>
Chris@0 339 All this assumes that the crystal oscillators uses to sample the audio stream
Chris@0 340 is perfect.
Chris@0 341 This is not the case.
Chris@0 342 According to
Chris@0 343 <a href="http://www.ieee-uffc.org/freqcontrol/quartz/vig/vigcomp.htm">
Chris@0 344 this web site</a>,
Chris@0 345 the accuracy of standard crystal oscillators (XO, TCXO, OCXO) is at best
Chris@0 346 1 in 100 million.
Chris@0 347 The <tt>src_ratio</tt> is therefore 45035996 times more accurate than the
Chris@0 348 crystal clock source used to sample the original audio signal and any potential
Chris@0 349 problem with the <tt>src_ratio</tt> being a floating point number will be
Chris@0 350 completely swamped by sampling inaccuracies.
Chris@0 351 </p>
Chris@0 352
Chris@0 353 <!-- <A HREF="mailto:aldel@mega-nerd.com">For the spam bots</A> -->
Chris@0 354
Chris@0 355 </DIV>
Chris@0 356 </TD></TR>
Chris@0 357 </TABLE>
Chris@0 358
Chris@0 359 </BODY>
Chris@0 360 </HTML>
Chris@0 361