Subversion Repositories eduke32

Rev

Rev 8132 | Go to most recent revision | 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; \
8561 terminx 153
    if (vi->pos >= vi->slen) return; \
6174 terminx 154
    int frac = (int)((1 << SMIX_SHIFT) * (vi->pos - (int)vi->pos))
6158 hendricks2 155
 
156
#define VAR_LINEAR_MONO(x) \
157
    VAR_NORM(x); \
158
    int old_vl = vi->old_vl; \
159
    int smp_l1, smp_dt
160
 
161
#define VAR_LINEAR_STEREO(x) \
162
    VAR_LINEAR_MONO(x); \
163
    int old_vr = vi->old_vr
164
 
165
#define VAR_SPLINE_MONO(x) \
166
    int old_vl = vi->old_vl; \
167
    VAR_NORM(x)
168
 
169
#define VAR_SPLINE_STEREO(x) \
170
    VAR_SPLINE_MONO(x); \
171
    int old_vr = vi->old_vr
172
 
173
#ifndef LIBXMP_CORE_DISABLE_IT
174
 
175
#define VAR_FILTER_MONO \
176
    int fl1 = vi->filter.l1, fl2 = vi->filter.l2; \
177
    int64 a0 = vi->filter.a0, b0 = vi->filter.b0, b1 = vi->filter.b1; \
178
    int sl
179
 
180
#define VAR_FILTER_STEREO \
181
    VAR_FILTER_MONO; \
182
    int fr1 = vi->filter.r1, fr2 = vi->filter.r2; \
183
    int sr
184
 
185
#define SAVE_FILTER_MONO() do { \
186
    vi->filter.l1 = fl1; \
187
    vi->filter.l2 = fl2; \
188
} while (0)
189
 
190
#define SAVE_FILTER_STEREO() do { \
191
    SAVE_FILTER_MONO(); \
192
    vi->filter.r1 = fr1; \
193
    vi->filter.r2 = fr2; \
194
} while (0)
195
 
196
#endif
197
 
198
 
199
/*
200
 * Nearest neighbor mixers
201
 */
202
 
203
/* Handler for 8 bit samples, nearest neighbor mono output
204
 */
205
MIXER(mono_8bit_nearest)
206
{
207
    VAR_NORM(int8);
208
 
209
    LOOP { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
210
}
211
 
212
 
213
/* Handler for 16 bit samples, nearest neighbor mono output
214
 */
215
MIXER(mono_16bit_nearest)
216
{
217
    VAR_NORM(int16);
218
 
219
    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_MONO(); UPDATE_POS(); }
220
}
221
 
222
/* Handler for 8 bit samples, nearest neighbor stereo output
223
 */
224
MIXER(stereo_8bit_nearest)
225
{
226
    VAR_NORM(int8);
227
 
228
    LOOP { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
229
}
230
 
231
/* Handler for 16 bit samples, nearest neighbor stereo output
232
 */
233
MIXER(stereo_16bit_nearest)
234
{
235
    VAR_NORM(int16);
236
 
237
    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_STEREO(); UPDATE_POS(); }
238
}
239
 
240
 
241
/*
242
 * Linear mixers
243
 */
244
 
245
/* Handler for 8 bit samples, linear interpolated mono output
246
 */
247
MIXER(mono_8bit_linear)
248
{
249
    VAR_LINEAR_MONO(int8);
250
 
251
    LOOP_AC { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
252
    LOOP    { LINEAR_INTERP(); MIX_MONO(); UPDATE_POS(); }
253
}
254
 
255
/* Handler for 16 bit samples, linear interpolated mono output
256
 */
257
MIXER(mono_16bit_linear)
258
{
259
    VAR_LINEAR_MONO(int16);
260
 
261
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
262
    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
263
}
264
 
265
/* Handler for 8 bit samples, linear interpolated stereo output
266
 */
267
MIXER(stereo_8bit_linear)
268
{
269
   VAR_LINEAR_STEREO(int8);
270
 
271
    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
272
    LOOP    { LINEAR_INTERP(); MIX_STEREO(); UPDATE_POS(); }
273
}
274
 
275
/* Handler for 16 bit samples, linear interpolated stereo output
276
 */
277
MIXER(stereo_16bit_linear)
278
{
279
    VAR_LINEAR_STEREO(int16);
280
 
281
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
282
    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
283
}
284
 
285
 
286
#ifndef LIBXMP_CORE_DISABLE_IT
287
 
288
/* Handler for 8 bit samples, filtered linear interpolated mono output
289
 */
290
MIXER(mono_8bit_linear_filter)
291
{
292
    VAR_LINEAR_MONO(int8);
293
    VAR_FILTER_MONO;
294
 
295
    LOOP_AC { LINEAR_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
296
    LOOP    { LINEAR_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
297
 
298
    SAVE_FILTER_MONO();
299
}
300
 
301
/* Handler for 16 bit samples, filtered linear interpolated mono output
302
 */
303
MIXER(mono_16bit_linear_filter)
304
{
305
    VAR_LINEAR_MONO(int16);
306
    VAR_FILTER_MONO;
307
 
308
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
309
    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
310
 
311
    SAVE_FILTER_MONO();
312
}
313
 
314
/* Handler for 8 bit samples, filtered linear interpolated stereo output
315
 */
316
MIXER(stereo_8bit_linear_filter)
317
{
318
    VAR_LINEAR_STEREO(int8);
319
    VAR_FILTER_STEREO;
320
 
321
    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
322
    LOOP    { LINEAR_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
323
 
324
    SAVE_FILTER_STEREO();
325
}
326
 
327
/* Handler for 16 bit samples, filtered linear interpolated stereo output
328
 */
329
MIXER(stereo_16bit_linear_filter)
330
{
331
    VAR_LINEAR_STEREO(int16);
332
    VAR_FILTER_STEREO;
333
 
334
    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
335
    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
336
 
337
    SAVE_FILTER_STEREO();
338
}
339
 
340
#endif
341
 
342
/*
343
 * Spline mixers
344
 */
345
 
346
/* Handler for 8 bit samples, spline interpolated mono output
347
 */
348
MIXER(mono_8bit_spline)
349
{
350
    VAR_SPLINE_MONO(int8);
351
 
352
    LOOP_AC { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
353
    LOOP    { SPLINE_INTERP(); MIX_MONO(); UPDATE_POS(); }
354
}
355
 
356
/* Handler for 16 bit samples, spline interpolated mono output
357
 */
358
MIXER(mono_16bit_spline)
359
{
360
    VAR_SPLINE_MONO(int16);
361
 
362
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
363
    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
364
}
365
 
366
/* Handler for 8 bit samples, spline interpolated stereo output
367
 */
368
MIXER(stereo_8bit_spline)
369
{
370
    VAR_SPLINE_STEREO(int8);
371
 
372
    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
373
    LOOP    { SPLINE_INTERP(); MIX_STEREO(); UPDATE_POS(); }
374
}
375
 
376
/* Handler for 16 bit samples, spline interpolated stereo output
377
 */
378
MIXER(stereo_16bit_spline)
379
{
380
    VAR_SPLINE_STEREO(int16);
381
 
382
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
383
    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
384
}
385
 
386
#ifndef LIBXMP_CORE_DISABLE_IT
387
 
388
/* Handler for 8 bit samples, filtered spline interpolated mono output
389
 */
390
MIXER(mono_8bit_spline_filter)
391
{
392
    VAR_SPLINE_MONO(int8);
393
    VAR_FILTER_MONO;
394
 
395
    LOOP_AC { SPLINE_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
396
    LOOP    { SPLINE_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
397
 
398
    SAVE_FILTER_MONO();
399
}
400
 
401
/* Handler for 16 bit samples, filtered spline interpolated mono output
402
 */
403
MIXER(mono_16bit_spline_filter)
404
{
405
    VAR_SPLINE_MONO(int16);
406
    VAR_FILTER_MONO;
407
 
408
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
409
    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
410
 
411
    SAVE_FILTER_MONO();
412
}
413
 
414
/* Handler for 8 bit samples, filtered spline interpolated stereo output
415
 */
416
MIXER(stereo_8bit_spline_filter)
417
{
418
    VAR_SPLINE_STEREO(int8);
419
    VAR_FILTER_STEREO;
420
 
421
    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
422
    LOOP    { SPLINE_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
423
 
424
    SAVE_FILTER_STEREO();
425
}
426
 
427
/* Handler for 16 bit samples, filtered spline interpolated stereo output
428
 */
429
MIXER(stereo_16bit_spline_filter)
430
{
431
    VAR_SPLINE_STEREO(int16);
432
    VAR_FILTER_STEREO;
433
 
434
    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
435
    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
436
 
437
    SAVE_FILTER_STEREO();
438
}
439
 
440
#endif