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
50
51
52 /* Compile with -DHEAVYDEBUG if you want to make sure the pick-up function is
53 * called when it should be. There will be a considerable performance hit,
54 * since at least one condition has to be tested for every sample generated.
55 */
56 #ifdef HEAVYDEBUG
57 #define HEAVYASSERT(cond) ASSERT(cond)
58 #else
59 #define HEAVYASSERT(cond)
60 #endif
61
62
63
64 /* Make MSVC shut the hell up about if ( upd ) UPDATE_VOLUME() conditions being constant */
65 #ifdef _MSC_VER
66 #pragma warning(disable:4127 4701)
67 #endif
68
69
70
71 /* A global variable for controlling resampling quality wherever a local
72 * specification doesn't override it. The following values are valid:
73 *
74 * 0 - DUMB_RQ_ALIASING - fastest
75 * 1 - DUMB_RQ_BLEP - nicer than aliasing, but slower
76 * 2 - DUMB_RQ_LINEAR
77 * 3 - DUMB_RQ_BLAM - band-limited linear interpolation, nice but slower
78 * 4 - DUMB_RQ_CUBIC
79 * 5 - DUMB_RQ_FIR - nicest
80 *
81 * Values outside the range 0-4 will behave the same as the nearest
82 * value within the range.
83 */
84 int dumb_resampling_quality = DUMB_RQ_CUBIC;
85
86
87
88 //#define MULSC(a, b) ((int)((LONG_LONG)(a) * (b) >> 16))
89 //#define MULSC(a, b) ((a) * ((b) >> 2) >> 14)
90 #define MULSCV(a, b) ((int)((LONG_LONG)(a) * (b) >> 32))
91 #define MULSC(a, b) ((int)((LONG_LONG)((a) << 4) * ((b) << 12) >> 32))
92 #define MULSC16(a, b) ((int)((LONG_LONG)((a) << 12) * ((b) << 12) >> 32))
93
94
95
96 /* Executes the content 'iterator' times.
97 * Clobbers the 'iterator' variable.
98 * The loop is unrolled by four.
99 */
100 #if 0
101 #define LOOP4(iterator, CONTENT) \
102 { \
103 if ((iterator) & 2) { \
104 CONTENT; \
105 CONTENT; \
106 } \
107 if ((iterator) & 1) { \
108 CONTENT; \
109 } \
110 (iterator) >>= 2; \
111 while (iterator) { \
112 CONTENT; \
113 CONTENT; \
114 CONTENT; \
115 CONTENT; \
116 (iterator)--; \
117 } \
118 }
119 #else
120 #define LOOP4(iterator, CONTENT) \
121 { \
122 while ( (iterator)-- ) \
123 { \
124 CONTENT; \
125 } \
126 }
127 #endif
128
129 #define PASTERAW(a, b) a ## b /* This does not expand macros in b ... */
130 #define PASTE(a, b) PASTERAW(a, b) /* ... but b is expanded during this substitution. */
131
132 #define X PASTE(x.x, SRCBITS)
133
134
135
_dumb_init_cubic(void)136 void _dumb_init_cubic(void)
137 {
138 static int done = 0;
139 if (done) return;
140
141 resampler_init();
142
143 done = 1;
144 }
145
146
147
148 /* Create resamplers for 24-in-32-bit source samples. */
149
150 /* #define SUFFIX
151 * MSVC warns if we try to paste a null SUFFIX, so instead we define
152 * special macros for the function names that don't bother doing the
153 * corresponding paste. The more generic definitions are further down.
154 */
155 #define process_pickup PASTE(process_pickup, SUFFIX2)
156 #define dumb_resample PASTE(PASTE(dumb_resample, SUFFIX2), SUFFIX3)
157 #define dumb_resample_get_current_sample PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX2), SUFFIX3)
158
159 #define SRCTYPE sample_t
160 #define SRCBITS 24
161 #define FIR(x) (x >> 8)
162 #include "resample.inc"
163
164 /* Undefine the simplified macros. */
165 #undef dumb_resample_get_current_sample
166 #undef dumb_resample
167 #undef process_pickup
168
169
170 /* Now define the proper ones that use SUFFIX. */
171 #define dumb_reset_resampler PASTE(dumb_reset_resampler, SUFFIX)
172 #define dumb_start_resampler PASTE(dumb_start_resampler, SUFFIX)
173 #define process_pickup PASTE(PASTE(process_pickup, SUFFIX), SUFFIX2)
174 #define dumb_resample PASTE(PASTE(PASTE(dumb_resample, SUFFIX), SUFFIX2), SUFFIX3)
175 #define dumb_resample_get_current_sample PASTE(PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX), SUFFIX2), SUFFIX3)
176 #define dumb_end_resampler PASTE(dumb_end_resampler, SUFFIX)
177
178 /* Create resamplers for 16-bit source samples. */
179 #define SUFFIX _16
180 #define SRCTYPE short
181 #define SRCBITS 16
182 #define FIR(x) (x)
183 #include "resample.inc"
184
185 /* Create resamplers for 8-bit source samples. */
186 #define SUFFIX _8
187 #define SRCTYPE signed char
188 #define SRCBITS 8
189 #define FIR(x) (x << 8)
190 #include "resample.inc"
191
192
193 #undef dumb_reset_resampler
194 #undef dumb_start_resampler
195 #undef process_pickup
196 #undef dumb_resample
197 #undef dumb_resample_get_current_sample
198 #undef dumb_end_resampler
199
200
201
dumb_reset_resampler_n(int n,DUMB_RESAMPLER * resampler,void * src,int src_channels,long pos,long start,long end,int quality)202 void dumb_reset_resampler_n(int n, DUMB_RESAMPLER *resampler, void *src, int src_channels, long pos, long start, long end, int quality)
203 {
204 if (n == 8)
205 dumb_reset_resampler_8(resampler, src, src_channels, pos, start, end, quality);
206 else if (n == 16)
207 dumb_reset_resampler_16(resampler, src, src_channels, pos, start, end, quality);
208 else
209 dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality);
210 }
211
212
213
dumb_start_resampler_n(int n,void * src,int src_channels,long pos,long start,long end,int quality)214 DUMB_RESAMPLER *dumb_start_resampler_n(int n, void *src, int src_channels, long pos, long start, long end, int quality)
215 {
216 if (n == 8)
217 return dumb_start_resampler_8(src, src_channels, pos, start, end, quality);
218 else if (n == 16)
219 return dumb_start_resampler_16(src, src_channels, pos, start, end, quality);
220 else
221 return dumb_start_resampler(src, src_channels, pos, start, end, quality);
222 }
223
224
225
dumb_resample_n_1_1(int n,DUMB_RESAMPLER * resampler,sample_t * dst,long dst_size,DUMB_VOLUME_RAMP_INFO * volume,float delta)226 long dumb_resample_n_1_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, DUMB_VOLUME_RAMP_INFO * volume, float delta)
227 {
228 if (n == 8)
229 return dumb_resample_8_1_1(resampler, dst, dst_size, volume, delta);
230 else if (n == 16)
231 return dumb_resample_16_1_1(resampler, dst, dst_size, volume, delta);
232 else
233 return dumb_resample_1_1(resampler, dst, dst_size, volume, delta);
234 }
235
236
237
dumb_resample_n_1_2(int n,DUMB_RESAMPLER * resampler,sample_t * dst,long dst_size,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,float delta)238 long dumb_resample_n_1_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, float delta)
239 {
240 if (n == 8)
241 return dumb_resample_8_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
242 else if (n == 16)
243 return dumb_resample_16_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
244 else
245 return dumb_resample_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
246 }
247
248
249
dumb_resample_n_2_1(int n,DUMB_RESAMPLER * resampler,sample_t * dst,long dst_size,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,float delta)250 long dumb_resample_n_2_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, float delta)
251 {
252 if (n == 8)
253 return dumb_resample_8_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
254 else if (n == 16)
255 return dumb_resample_16_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
256 else
257 return dumb_resample_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
258 }
259
260
261
dumb_resample_n_2_2(int n,DUMB_RESAMPLER * resampler,sample_t * dst,long dst_size,DUMB_VOLUME_RAMP_INFO * volume_left,DUMB_VOLUME_RAMP_INFO * volume_right,float delta)262 long dumb_resample_n_2_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, DUMB_VOLUME_RAMP_INFO * volume_left, DUMB_VOLUME_RAMP_INFO * volume_right, float delta)
263 {
264 if (n == 8)
265 return dumb_resample_8_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
266 else if (n == 16)
267 return dumb_resample_16_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
268 else
269 return dumb_resample_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
270 }
271
272
273
dumb_resample_get_current_sample_n_1_1(int n,DUMB_RESAMPLER * resampler,DUMB_VOLUME_RAMP_INFO * volume,sample_t * dst)274 void dumb_resample_get_current_sample_n_1_1(int n, DUMB_RESAMPLER *resampler, DUMB_VOLUME_RAMP_INFO * volume, sample_t *dst)
275 {
276 if (n == 8)
277 dumb_resample_get_current_sample_8_1_1(resampler, volume, dst);
278 else if (n == 16)
279 dumb_resample_get_current_sample_16_1_1(resampler, volume, dst);
280 else
281 dumb_resample_get_current_sample_1_1(resampler, volume, dst);
282 }
283
284
285
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)286 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)
287 {
288 if (n == 8)
289 dumb_resample_get_current_sample_8_1_2(resampler, volume_left, volume_right, dst);
290 else if (n == 16)
291 dumb_resample_get_current_sample_16_1_2(resampler, volume_left, volume_right, dst);
292 else
293 dumb_resample_get_current_sample_1_2(resampler, volume_left, volume_right, dst);
294 }
295
296
297
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)298 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)
299 {
300 if (n == 8)
301 dumb_resample_get_current_sample_8_2_1(resampler, volume_left, volume_right, dst);
302 else if (n == 16)
303 dumb_resample_get_current_sample_16_2_1(resampler, volume_left, volume_right, dst);
304 else
305 dumb_resample_get_current_sample_2_1(resampler, volume_left, volume_right, dst);
306 }
307
308
309
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)310 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)
311 {
312 if (n == 8)
313 dumb_resample_get_current_sample_8_2_2(resampler, volume_left, volume_right, dst);
314 else if (n == 16)
315 dumb_resample_get_current_sample_16_2_2(resampler, volume_left, volume_right, dst);
316 else
317 dumb_resample_get_current_sample_2_2(resampler, volume_left, volume_right, dst);
318 }
319
320
321
dumb_end_resampler_n(int n,DUMB_RESAMPLER * resampler)322 void dumb_end_resampler_n(int n, DUMB_RESAMPLER *resampler)
323 {
324 if (n == 8)
325 dumb_end_resampler_8(resampler);
326 else if (n == 16)
327 dumb_end_resampler_16(resampler);
328 else
329 dumb_end_resampler(resampler);
330 }
331