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