Subversion Repositories eduke32

Rev

Rev 8561 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6158 hendricks2 1
/* Extended Module Player
8132 terminx 2
 * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
6158 hendricks2 3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
 * THE SOFTWARE.
21
 */
22
 
23
#include "common.h"
24
#include "virtual.h"
25
#include "mixer.h"
26
#include "precomp_lut.h"
27
 
28
/* Mixers
29
 *
30
 * To increase performance eight mixers are defined, one for each
31
 * combination of the following parameters: interpolation, resolution
32
 * and number of channels.
33
 */
34
#define NEAREST_NEIGHBOR() do { \
35
    smp_in = ((int16)sptr[pos] << 8); \
36
} while (0)
37
 
38
#define NEAREST_NEIGHBOR_16BIT() do { \
39
    smp_in = sptr[pos]; \
40
} while (0)
41
 
42
#define LINEAR_INTERP() do { \
43
    smp_l1 = ((int16)sptr[pos] << 8); \
44
    smp_dt = ((int16)sptr[pos + 1] << 8) - smp_l1; \
45
    smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
46
} while (0)
47
 
48
#define LINEAR_INTERP_16BIT() do { \
49
    smp_l1 = sptr[pos]; \
50
    smp_dt = sptr[pos + 1] - smp_l1; \
51
    smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
52
} while (0)
53
 
54
/* The following lut settings are PRECOMPUTED. If you plan on changing these
55
 * settings, you MUST also regenerate the arrays.
56
 */
57
/* number of bits used to scale spline coefs */
58
#define SPLINE_QUANTBITS  14
59
#define SPLINE_SHIFT    (SPLINE_QUANTBITS)
60
 
61
/* log2(number) of precalculated splines (range is [4..14]) */
62
#define SPLINE_FRACBITS 10
63
#define SPLINE_LUTLEN (1L<<SPLINE_FRACBITS)
64
 
65
#define SPLINE_FRACSHIFT ((16 - SPLINE_FRACBITS) - 2)
66
#define SPLINE_FRACMASK  (((1L << (16 - SPLINE_FRACSHIFT)) - 1) & ~3)
67
 
68
#define SPLINE_INTERP() do { \
69
    int f = frac >> 6; \
70
    smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
71
              cubic_spline_lut1[f] * sptr[pos    ] + \
72
              cubic_spline_lut3[f] * sptr[pos + 2] + \
73
              cubic_spline_lut2[f] * sptr[pos + 1]) >> (SPLINE_SHIFT - 8); \
74
} while (0)
75
 
76
#define SPLINE_INTERP_16BIT() do { \
77
    int f = frac >> 6; \
78
    smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
79
              cubic_spline_lut1[f] * sptr[pos    ] + \
80
              cubic_spline_lut3[f] * sptr[pos + 2] + \
81
              cubic_spline_lut2[f] * sptr[pos + 1]) >> SPLINE_SHIFT; \
82
} while (0)
83
 
84
#define LOOP_AC for (; count > ramp; count--)
85
 
86
#define LOOP for (; count; count--)
87
 
88
#define UPDATE_POS() do { \
89
    frac += step; \
90
    pos += frac >> SMIX_SHIFT; \
91
    frac &= SMIX_MASK; \
92
} while (0)
93
 
94
#define MIX_MONO() do { \
95
    *(buffer++) += smp_in * vl; \
96
} while (0)
97
 
98
#define MIX_MONO_AC() do { \
99
    *(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
100
} while (0)
101
 
102
#define MIX_MONO_FILTER() do { \
103
    sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
104
    fl2 = fl1; fl1 = sl; \
105
    *(buffer++) += sl; \
106
} while (0)
107
 
108
#define MIX_MONO_FILTER_AC() do { \
109
    int vl = old_vl >> 8; \
110
    MIX_MONO_FILTER(); \
111
    old_vl += delta_l; \
112
} while (0)
113
 
114
#define MIX_STEREO() do { \
115
    *(buffer++) += smp_in * vr; \
116
    *(buffer++) += smp_in * vl; \
117
} while (0)
118
 
119
#define MIX_STEREO_AC() do { \
120
    *(buffer++) += smp_in * (old_vr >> 8); old_vr += delta_r; \
121
    *(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
122
} while (0)
123
 
124
#define MIX_STEREO_FILTER() do { \
125
    sr = (a0 * smp_in * vr + b0 * fr1 + b1 * fr2) >> FILTER_SHIFT; \
126
    fr2 = fr1; fr1 = sr; \
127
    sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
128
    fl2 = fl1; fl1 = sl; \
129
    *(buffer++) += sr; \
130
    *(buffer++) += sl; \
131
} while (0)
132
 
133
#define MIX_STEREO_FILTER_AC() do { \
134
    int vr = old_vr >> 8; \
135
    int vl = old_vl >> 8; \
136
    MIX_STEREO_FILTER(); \
137
    old_vr += delta_r; \
138
    old_vl += delta_l; \
139
} while (0)
140
 
141
#define MIX_STEREO_FILTER_AC() do { \
142
    int vr = old_vr >> 8; \
143
    int vl = old_vl >> 8; \
144
    MIX_STEREO_FILTER(); \
145
    old_vr += delta_r; \
146
    old_vl += delta_l; \
147
} while (0)
148
 
149
#define VAR_NORM(x) \
6312 hendricks2 150
    int smp_in; \
6162 hendricks2 151
    x *sptr = (x *)vi->sptr; \
6174 terminx 152
    unsigned int pos = (unsigned int)vi->pos; \
153
    int frac = (int)((1 << SMIX_SHIFT) * (vi->pos - (int)vi->pos))
6158 hendricks2 154
 
155
#define VAR_LINEAR_MONO(x) \
156
    VAR_NORM(x); \
157
    int old_vl = vi->old_vl; \
158
    int smp_l1, smp_dt
159
 
160
#define VAR_LINEAR_STEREO(x) \
161
    VAR_LINEAR_MONO(x); \
162
    int old_vr = vi->old_vr
163
 
164
#define VAR_SPLINE_MONO(x) \
165
    int old_vl = vi->old_vl; \
166
    VAR_NORM(x)
167
 
168
#define VAR_SPLINE_STEREO(x) \
169
    VAR_SPLINE_MONO(x); \
170
    int old_vr = vi->old_vr
171
 
172
#ifndef LIBXMP_CORE_DISABLE_IT
173
 
174
#define VAR_FILTER_MONO \
175
    int fl1 = vi->filter.l1, fl2 = vi->filter.l2; \
176
    int64 a0 = vi->filter.a0, b0 = vi->filter.b0, b1 = vi->filter.b1; \
177
    int sl
178
 
179
#define VAR_FILTER_STEREO \
180
    VAR_FILTER_MONO; \
181
    int fr1 = vi->filter.r1, fr2 = vi->filter.r2; \
182
    int sr
183
 
184
#define SAVE_FILTER_MONO() do { \
185
    vi->filter.l1 = fl1; \
186
    vi->filter.l2 = fl2; \
187
} while (0)
188
 
189
#define SAVE_FILTER_STEREO() do { \
190
    SAVE_FILTER_MONO(); \
191
    vi->filter.r1 = fr1; \
192
    vi->filter.r2 = fr2; \
193
} while (0)
194
 
195
#endif
196
 
197
 
198
/*
199
 * Nearest neighbor mixers
200
 */
201
 
202
/* Handler for 8 bit samples, nearest neighbor mono output
203
 */
204
MIXER(mono_8bit_nearest)
205
{
206
    VAR_NORM(int8);
207
 
208
    LOOP { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
209
}
210
 
211
 
212
/* Handler for 16 bit samples, nearest neighbor mono output
213
 */
214
MIXER(mono_16bit_nearest)
215
{
216
    VAR_NORM(int16);
217
 
218
    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_MONO(); UPDATE_POS(); }
219
}
220
 
221
/* Handler for 8 bit samples, nearest neighbor stereo output
222
 */
223
MIXER(stereo_8bit_nearest)
224
{
225
    VAR_NORM(int8);
226
 
227
    LOOP { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
228
}
229
 
230
/* Handler for 16 bit samples, nearest neighbor stereo output
231
 */
232
MIXER(stereo_16bit_nearest)
233
{
234
    VAR_NORM(int16);
235
 
236
    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_STEREO(); UPDATE_POS(); }
237
}
238
 
239
 
240
/*
241
 * Linear mixers
242
 */
243
 
244
/* Handler for 8 bit samples, linear interpolated mono output
245
 */
246
MIXER(mono_8bit_linear)
247
{
248
    VAR_LINEAR_MONO(int8);
249
 
250
    LOOP_AC { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
251
    LOOP    { LINEAR_INTERP(); MIX_MONO(); UPDATE_POS(); }
252
}
253
 
254
/* Handler for 16 bit samples, linear interpolated mono output
255
 */
256
MIXER(mono_16bit_linear)
257
{
258
    VAR_LINEAR_MONO(int16);
259
 
260
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
261
    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
262
}
263
 
264
/* Handler for 8 bit samples, linear interpolated stereo output
265
 */
266
MIXER(stereo_8bit_linear)
267
{
268
   VAR_LINEAR_STEREO(int8);
269
 
270
    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
271
    LOOP    { LINEAR_INTERP(); MIX_STEREO(); UPDATE_POS(); }
272
}
273
 
274
/* Handler for 16 bit samples, linear interpolated stereo output
275
 */
276
MIXER(stereo_16bit_linear)
277
{
278
    VAR_LINEAR_STEREO(int16);
279
 
280
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
281
    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
282
}
283
 
284
 
285
#ifndef LIBXMP_CORE_DISABLE_IT
286
 
287
/* Handler for 8 bit samples, filtered linear interpolated mono output
288
 */
289
MIXER(mono_8bit_linear_filter)
290
{
291
    VAR_LINEAR_MONO(int8);
292
    VAR_FILTER_MONO;
293
 
294
    LOOP_AC { LINEAR_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
295
    LOOP    { LINEAR_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
296
 
297
    SAVE_FILTER_MONO();
298
}
299
 
300
/* Handler for 16 bit samples, filtered linear interpolated mono output
301
 */
302
MIXER(mono_16bit_linear_filter)
303
{
304
    VAR_LINEAR_MONO(int16);
305
    VAR_FILTER_MONO;
306
 
307
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
308
    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
309
 
310
    SAVE_FILTER_MONO();
311
}
312
 
313
/* Handler for 8 bit samples, filtered linear interpolated stereo output
314
 */
315
MIXER(stereo_8bit_linear_filter)
316
{
317
    VAR_LINEAR_STEREO(int8);
318
    VAR_FILTER_STEREO;
319
 
320
    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
321
    LOOP    { LINEAR_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
322
 
323
    SAVE_FILTER_STEREO();
324
}
325
 
326
/* Handler for 16 bit samples, filtered linear interpolated stereo output
327
 */
328
MIXER(stereo_16bit_linear_filter)
329
{
330
    VAR_LINEAR_STEREO(int16);
331
    VAR_FILTER_STEREO;
332
 
333
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
334
    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
335
 
336
    SAVE_FILTER_STEREO();
337
}
338
 
339
#endif
340
 
341
/*
342
 * Spline mixers
343
 */
344
 
345
/* Handler for 8 bit samples, spline interpolated mono output
346
 */
347
MIXER(mono_8bit_spline)
348
{
349
    VAR_SPLINE_MONO(int8);
350
 
351
    LOOP_AC { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
352
    LOOP    { SPLINE_INTERP(); MIX_MONO(); UPDATE_POS(); }
353
}
354
 
355
/* Handler for 16 bit samples, spline interpolated mono output
356
 */
357
MIXER(mono_16bit_spline)
358
{
359
    VAR_SPLINE_MONO(int16);
360
 
361
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
362
    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
363
}
364
 
365
/* Handler for 8 bit samples, spline interpolated stereo output
366
 */
367
MIXER(stereo_8bit_spline)
368
{
369
    VAR_SPLINE_STEREO(int8);
370
 
371
    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
372
    LOOP    { SPLINE_INTERP(); MIX_STEREO(); UPDATE_POS(); }
373
}
374
 
375
/* Handler for 16 bit samples, spline interpolated stereo output
376
 */
377
MIXER(stereo_16bit_spline)
378
{
379
    VAR_SPLINE_STEREO(int16);
380
 
381
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
382
    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
383
}
384
 
385
#ifndef LIBXMP_CORE_DISABLE_IT
386
 
387
/* Handler for 8 bit samples, filtered spline interpolated mono output
388
 */
389
MIXER(mono_8bit_spline_filter)
390
{
391
    VAR_SPLINE_MONO(int8);
392
    VAR_FILTER_MONO;
393
 
394
    LOOP_AC { SPLINE_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
395
    LOOP    { SPLINE_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
396
 
397
    SAVE_FILTER_MONO();
398
}
399
 
400
/* Handler for 16 bit samples, filtered spline interpolated mono output
401
 */
402
MIXER(mono_16bit_spline_filter)
403
{
404
    VAR_SPLINE_MONO(int16);
405
    VAR_FILTER_MONO;
406
 
407
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
408
    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
409
 
410
    SAVE_FILTER_MONO();
411
}
412
 
413
/* Handler for 8 bit samples, filtered spline interpolated stereo output
414
 */
415
MIXER(stereo_8bit_spline_filter)
416
{
417
    VAR_SPLINE_STEREO(int8);
418
    VAR_FILTER_STEREO;
419
 
420
    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
421
    LOOP    { SPLINE_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
422
 
423
    SAVE_FILTER_STEREO();
424
}
425
 
426
/* Handler for 16 bit samples, filtered spline interpolated stereo output
427
 */
428
MIXER(stereo_16bit_spline_filter)
429
{
430
    VAR_SPLINE_STEREO(int16);
431
    VAR_FILTER_STEREO;
432
 
433
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
434
    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
435
 
436
    SAVE_FILTER_STEREO();
437
}
438
 
439
#endif