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