]>
Commit | Line | Data |
---|---|---|
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 |