1 /* _______ ____ __ ___ ___
2 * \ _ \ \ / \ / \ \ / / ' ' '
3 * | | \ \ | | || | \/ | . .
4 * | | | | | | || ||\ /| |
5 * | | | | | | || || \/ | | ' ' '
6 * | | | | | | || || | | . .
7 * | |_/ / \ \__// || | |
8 * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
9 * / \
10 * / . \
11 * resample.c - Resampling helpers. / / \ \
12 * | < / \_
13 * By Bob and entheh. | \/ /\ /
14 * \_ / > /
15 * In order to find a good trade-off between | \ / /
16 * speed and accuracy in this code, some tests | ' /
17 * were carried out regarding the behaviour of \__/
18 * long long ints with gcc. The following code
19 * was tested:
20 *
21 * int a, b, c;
22 * c = ((long long)a * b) >> 16;
23 *
24 * DJGPP GCC Version 3.0.3 generated the following assembly language code for
25 * the multiplication and scaling, leaving the 32-bit result in EAX.
26 *
27 * movl -8(%ebp), %eax ; read one int into EAX
28 * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX
29 * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX
30 *
31 * Note that a 32*32->64 multiplication is performed, allowing for high
32 * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally),
33 * so it is a minor concern when four multiplications are being performed
34 * (the cubic resampler). On the Pentium MMX and earlier, it takes four or
35 * more cycles, so this method is unsuitable for use in the low-quality
36 * resamplers.
37 *
38 * Since "long long" is a gcc-specific extension, we use LONG_LONG instead,
39 * defined in dumb.h. We may investigate later what code MSVC generates, but
40 * if it seems too slow then we suggest you use a good compiler.
41 *
42 * FIXME: these comments are somewhat out of date now.
43 */
44
45 #include <math.h>
46 #include "dumb.h"
47
48 #include "internal/resampler.h"
49 #include "internal/mulsc.h"
50
51
52
53 /* Compile with -DHEAVYDEBUG if you want to make sure the pick-up function is
54 * called when it should be. There will be a considerable performance hit,
55 * since at least one condition has to be tested for every sample generated.
56 */
57 #ifdef HEAVYDEBUG
58 #define HEAVYASSERT(cond) ASSERT(cond)
59 #else
60 #define HEAVYASSERT(cond)
61 #endif
62
63
64
65 /* Make MSVC shut the hell up about if ( upd ) UPDATE_VOLUME() conditions being constant */
66 #ifdef _MSC_VER
67 #pragma warning(disable:4127 4701)
68 #endif
69
70
71
72 /* A global variable for controlling resampling quality wherever a local
73 * specification doesn't override it. The following values are valid:
74 *
75 * 0 - DUMB_RQ_ALIASING - fastest
76 * 1 - DUMB_RQ_BLEP - nicer than aliasing, but slower
77 * 2 - DUMB_RQ_LINEAR
78 * 3 - DUMB_RQ_BLAM - band-limited linear interpolation, nice but slower
79 * 4 - DUMB_RQ_CUBIC
80 * 5 - DUMB_RQ_FIR - nicest
81 *
82 * Values outside the range 0-4 will behave the same as the nearest
83 * value within the range.
84 */
85 int dumb_resampling_quality = DUMB_RQ_CUBIC;
86
87
88
89 /* From xs_Float.h ==============================================*/
90 #if __BIG_ENDIAN__
91 #define _xs_iman_ 1
92 #else
93 #define _xs_iman_ 0
94 #endif //BigEndian_
95
96 #ifdef __GNUC__
97 #define finline inline
98 #else
99 #define finline __forceinline
100 #endif
101
102 union _xs_doubleints
103 {
104 double val;
105 unsigned int ival[2];
106 };
107
108 static const double _xs_doublemagic = (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor
109 static const double _xs_doublemagicroundeps = (.5f-(1.5e-8)); //almost .5f = .5f - 1e^(number of exp bit)
110
xs_CRoundToInt(double val)111 static finline int xs_CRoundToInt(double val)
112 {
113 union _xs_doubleints uval;
114 val += _xs_doublemagic;
115 uval.val = val;
116 return uval.ival[_xs_iman_];
117 }
xs_FloorToInt(double val)118 static finline int xs_FloorToInt(double val)
119 {
120 union _xs_doubleints uval;
121 val -= _xs_doublemagicroundeps;
122 val += _xs_doublemagic;
123 uval.val = val;
124 return uval.ival[_xs_iman_];
125 }
126 /* Not from xs_Float.h ==========================================*/
127
128
129 /* Executes the content 'iterator' times.
130 * Clobbers the 'iterator' variable.
131 * The loop is unrolled by four.
132 */
133 #if 0
134 #define LOOP4(iterator, CONTENT) \
135 { \
136 if ((iterator) & 2) { \
137 CONTENT; \
138 CONTENT; \
139 } \
140 if ((iterator) & 1) { \
141 CONTENT; \
142 } \
143 (iterator) >>= 2; \
144 while (iterator) { \
145 CONTENT; \
146 CONTENT; \
147 CONTENT; \
148 CONTENT; \
149 (iterator)--; \
150 } \
151 }
152 #else
153 #define LOOP4(iterator, CONTENT) \
154 { \
155 while ( (iterator)-- ) \
156 { \
157 CONTENT; \
158 } \
159 }
160 #endif
161
162 #define PASTERAW(a, b) a ## b /* This does not expand macros in b ... */
163 #define PASTE(a, b) PASTERAW(a, b) /* ... but b is expanded during this substitution. */
164
165 #define X PASTE(x.x, SRCBITS)
166
167
168
169 /* Cubic resampler: look-up tables
170 *
171 * a = 1.5*x1 - 1.5*x2 + 0.5*x3 - 0.5*x0
172 * b = 2*x2 + x0 - 2.5*x1 - 0.5*x3
173 * c = 0.5*x2 - 0.5*x0
174 * d = x1
175 *
176 * x = a*t*t*t + b*t*t + c*t + d
177 * = (-0.5*x0 + 1.5*x1 - 1.5*x2 + 0.5*x3) * t*t*t +
178 * ( 1*x0 - 2.5*x1 + 2 *x2 - 0.5*x3) * t*t +
179 * (-0.5*x0 + 0.5*x2 ) * t +
180 * ( 1*x1 )
181 * = (-0.5*t*t*t + 1 *t*t - 0.5*t ) * x0 +
182 * ( 1.5*t*t*t - 2.5*t*t + 1) * x1 +
183 * (-1.5*t*t*t + 2 *t*t + 0.5*t ) * x2 +
184 * ( 0.5*t*t*t - 0.5*t*t ) * x3
185 * = A0(t) * x0 + A1(t) * x1 + A2(t) * x2 + A3(t) * x3
186 *
187 * A0, A1, A2 and A3 stay within the range [-1,1].
188 * In the tables, they are scaled with 14 fractional bits.
189 *
190 * Turns out we don't need to store A2 and A3; they are symmetrical to A1 and A0.
191 *
192 * TODO: A0 and A3 stay very small indeed. Consider different scale/resolution?
193 */
194
195 static short cubicA0[1025], cubicA1[1025];
196
_dumb_init_cubic(void)197 void _dumb_init_cubic(void)
198 {
199 unsigned int t; /* 3*1024*1024*1024 is within range if it's unsigned */
200 static int done = 0;
201 if (done) return;
202 for (t = 0; t < 1025; t++) {
203 /* int casts to pacify warnings about negating unsigned values */
204 cubicA0[t] = -(int)( t*t*t >> 17) + (int)( t*t >> 6) - (int)(t << 3);
205 cubicA1[t] = (int)(3*t*t*t >> 17) - (int)(5*t*t >> 7) + (int)(1 << 14);
206 }
207 resampler_init();
208
209 done = 1;
210 }
211
212
213
214 /* Create resamplers for 24-in-32-bit source samples. */
215
216 /* #define SUFFIX
217 * MSVC warns if we try to paste a null SUFFIX, so instead we define
218 * special macros for the function names that don't bother doing the
219 * corresponding paste. The more generic definitions are further down.
220 */
221 #define process_pickup PASTE(process_pickup, SUFFIX2)
222 #define dumb_resample PASTE(PASTE(dumb_resample, SUFFIX2), SUFFIX3)
223 #define dumb_resample_get_current_sample PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX2), SUFFIX3)
224
225 #define SRCTYPE sample_t
226 #define SRCBITS 24
227 #define ALIAS(x, vol) MULSC(x, vol)
228 #define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos))
229 #define CUBIC(x0, x1, x2, x3) ( \
230 MULSC(x0, cubicA0[subpos >> 6] << 2) + \
231 MULSC(x1, cubicA1[subpos >> 6] << 2) + \
232 MULSC(x2, cubicA1[1 + (subpos >> 6 ^ 1023)] << 2) + \
233 MULSC(x3, cubicA0[1 + (subpos >> 6 ^ 1023)] << 2))
234 #define CUBICVOL(x, vol) MULSC(x, vol)
235 #define FIR(x) (x >> 8)
236 #include "resample.inc"
237
238 /* Undefine the simplified macros. */
239 #undef dumb_resample_get_current_sample
240 #undef dumb_resample
241 #undef process_pickup
242
243
244 /* Now define the proper ones that use SUFFIX. */
245 #define dumb_reset_resampler PASTE(dumb_reset_resampler, SUFFIX)
246 #define dumb_start_resampler PASTE(dumb_start_resampler, SUFFIX)
247 #define process_pickup PASTE(PASTE(process_pickup, SUFFIX), SUFFIX2)
248 #define dumb_resample PASTE(PASTE(PASTE(dumb_resample, SUFFIX), SUFFIX2), SUFFIX3)
249 #define dumb_resample_get_current_sample PASTE(PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX), SUFFIX2), SUFFIX3)
250 #define dumb_end_resampler PASTE(dumb_end_resampler, SUFFIX)
251
252 /* Create resamplers for 16-bit source samples. */
253 #define SUFFIX _16
254 #define SRCTYPE short
255 #define SRCBITS 16
256 #define ALIAS(x, vol) (x * vol >> 8)
257 #define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos))
258 #define CUBIC(x0, x1, x2, x3) ( \
259 x0 * cubicA0[subpos >> 6] + \
260 x1 * cubicA1[subpos >> 6] + \
261 x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
262 x3 * cubicA0[1 + (subpos >> 6 ^ 1023)])
263 #define CUBICVOL(x, vol) MULSCV((x), ((vol) << 10))
264 #define FIR(x) (x)
265 #include "resample.inc"
266
267 /* Create resamplers for 8-bit source samples. */
268 #define SUFFIX _8
269 #define SRCTYPE signed char
270 #define SRCBITS 8
271 #define ALIAS(x, vol) (x * vol)
272 #define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos)
273 #define CUBIC(x0, x1, x2, x3) (( \
274 x0 * cubicA0[subpos >> 6] + \
275 x1 * cubicA1[subpos >> 6] + \
276 x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
277 x3 * cubicA0[1 + (subpos >> 6 ^ 1023)]) << 6)
278 #define CUBICVOL(x, vol) MULSCV((x), ((vol) << 12))
279 #define FIR(x) (x << 8)
280 #include "resample.inc"
281
282
283 #undef dumb_reset_resampler
284 #undef dumb_start_resampler
285 #undef process_pickup
286 #undef dumb_resample
287 #undef dumb_resample_get_current_sample
288 #undef dumb_end_resampler
289
290
291
dumb_reset_resampler_n(int n,DUMB_RESAMPLER * resampler,void * src,int src_channels,int32 pos,int32 start,int32 end,int quality)292 void dumb_reset_resampler_n(int n, DUMB_RESAMPLER *resampler, void *src, int src_channels, int32 pos, int32 start, int32 end, int quality)
293 {
294 if (n == 8)
295 dumb_reset_resampler_8(resampler, src, src_channels, pos, start, end, quality);
296 else if (n == 16)
297 dumb_reset_resampler_16(resampler, src, src_channels, pos, start, end, quality);
298 else
299 dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality);
300 }
301
302
303
dumb_start_resampler_n(int n,void * src,int src_channels,int32 pos,int32 start,int32 end,int quality)304 DUMB_RESAMPLER *dumb_start_resampler_n(int n, void *src, int src_channels, int32 pos, int32 start, int32 end, int quality)
305 {
306 if (n == 8)
307 return dumb_start_resampler_8(src, src_channels, pos, start, end, quality);
308 else if (n == 16)
309 return dumb_start_resampler_16(src, src_channels, pos, start, end, quality);
310 else
311 return dumb_start_resampler(src, src_channels, pos, start, end, quality);
312 }
313
314
315 #if 0
316 int32 dumb_resample_n_1_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, DUMB_VOLUME_RAMP_INFO * volume, double delta)
317 {
318 if (n == 8)
319 return dumb_resample_8_1_1(resampler, dst, dst_size, volume, delta);
320 else if (n == 16)
321 return dumb_resample_16_1_1(resampler, dst, dst_size, volume, delta);
322 else
323 return dumb_resample_1_1(resampler, dst, dst_size, volume, delta);
324 }
325 #endif
326
327
dumb_resample_n_1_2(int n,DUMB_RESAMPLER * resampler,sample_t * dst,int32 dst_size,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,double delta)328 int32 dumb_resample_n_1_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, double delta)
329 {
330 if (n == 8)
331 return dumb_resample_8_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
332 else if (n == 16)
333 return dumb_resample_16_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
334 else
335 return dumb_resample_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
336 }
337
338
339 #if 0
340 int32 dumb_resample_n_2_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, double delta)
341 {
342 if (n == 8)
343 return dumb_resample_8_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
344 else if (n == 16)
345 return dumb_resample_16_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
346 else
347 return dumb_resample_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
348 }
349 #endif
350
351
dumb_resample_n_2_2(int n,DUMB_RESAMPLER * resampler,sample_t * dst,int32 dst_size,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,double delta)352 int32 dumb_resample_n_2_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, double delta)
353 {
354 if (n == 8)
355 return dumb_resample_8_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
356 else if (n == 16)
357 return dumb_resample_16_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
358 else
359 return dumb_resample_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
360 }
361
362
363 #if 0
364 void dumb_resample_get_current_sample_n_1_1(int n, DUMB_RESAMPLER *resampler, DUMB_VOLUME_RAMP_INFO * volume, sample_t *dst)
365 {
366 if (n == 8)
367 dumb_resample_get_current_sample_8_1_1(resampler, volume, dst);
368 else if (n == 16)
369 dumb_resample_get_current_sample_16_1_1(resampler, volume, dst);
370 else
371 dumb_resample_get_current_sample_1_1(resampler, volume, dst);
372 }
373 #endif
374
375
dumb_resample_get_current_sample_n_1_2(int n,DUMB_RESAMPLER * resampler,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,sample_t * dst)376 void dumb_resample_get_current_sample_n_1_2(int n, DUMB_RESAMPLER *resampler, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, sample_t *dst)
377 {
378 if (n == 8)
379 dumb_resample_get_current_sample_8_1_2(resampler, volume_left, volume_right, dst);
380 else if (n == 16)
381 dumb_resample_get_current_sample_16_1_2(resampler, volume_left, volume_right, dst);
382 else
383 dumb_resample_get_current_sample_1_2(resampler, volume_left, volume_right, dst);
384 }
385
386
387 #if 0
388 void dumb_resample_get_current_sample_n_2_1(int n, DUMB_RESAMPLER *resampler, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, sample_t *dst)
389 {
390 if (n == 8)
391 dumb_resample_get_current_sample_8_2_1(resampler, volume_left, volume_right, dst);
392 else if (n == 16)
393 dumb_resample_get_current_sample_16_2_1(resampler, volume_left, volume_right, dst);
394 else
395 dumb_resample_get_current_sample_2_1(resampler, volume_left, volume_right, dst);
396 }
397 #endif
398
399
dumb_resample_get_current_sample_n_2_2(int n,DUMB_RESAMPLER * resampler,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,sample_t * dst)400 void dumb_resample_get_current_sample_n_2_2(int n, DUMB_RESAMPLER *resampler, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, sample_t *dst)
401 {
402 if (n == 8)
403 dumb_resample_get_current_sample_8_2_2(resampler, volume_left, volume_right, dst);
404 else if (n == 16)
405 dumb_resample_get_current_sample_16_2_2(resampler, volume_left, volume_right, dst);
406 else
407 dumb_resample_get_current_sample_2_2(resampler, volume_left, volume_right, dst);
408 }
409
410
411
dumb_end_resampler_n(int n,DUMB_RESAMPLER * resampler)412 void dumb_end_resampler_n(int n, DUMB_RESAMPLER *resampler)
413 {
414 if (n == 8)
415 dumb_end_resampler_8(resampler);
416 else if (n == 16)
417 dumb_end_resampler_16(resampler);
418 else
419 dumb_end_resampler(resampler);
420 }
421