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