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 <stdlib.h>
24
#include <string.h>
25
#include <math.h>
26
#include "common.h"
27
#include "virtual.h"
28
#include "mixer.h"
29
#include "period.h"
30
#include "player.h"     /* for set_sample_end() */
31
 
32
#ifdef LIBXMP_PAULA_SIMULATOR
33
#include "paula.h"
34
#endif
35
 
36
 
37
#define FLAG_16_BITS    0x01
38
#define FLAG_STEREO     0x02
39
#define FLAG_FILTER     0x04
40
#define FLAG_ACTIVE     0x10
41
/* #define FLAG_SYNTH   0x20 */
42
#define FIDX_FLAGMASK   (FLAG_16_BITS | FLAG_STEREO | FLAG_FILTER)
43
 
44
#define DOWNMIX_SHIFT    12
45
#define LIM8_HI          127
46
#define LIM8_LO         -128
47
#define LIM16_HI         32767
48
#define LIM16_LO        -32768
49
 
50
#define MIX_FN(x) void libxmp_mix_##x(struct mixer_voice *, int32 *, int, int, int, int, int, int, int)
51
 
52
MIX_FN(mono_8bit_nearest);
53
MIX_FN(mono_8bit_linear);
54
MIX_FN(mono_16bit_nearest);
55
MIX_FN(mono_16bit_linear);
56
MIX_FN(stereo_8bit_nearest);
57
MIX_FN(stereo_8bit_linear);
58
MIX_FN(stereo_16bit_nearest);
59
MIX_FN(stereo_16bit_linear);
60
MIX_FN(mono_8bit_spline);
61
MIX_FN(mono_16bit_spline);
62
MIX_FN(stereo_8bit_spline);
63
MIX_FN(stereo_16bit_spline);
64
 
65
#ifndef LIBXMP_CORE_DISABLE_IT
66
MIX_FN(mono_8bit_linear_filter);
67
MIX_FN(mono_16bit_linear_filter);
68
MIX_FN(stereo_8bit_linear_filter);
69
MIX_FN(stereo_16bit_linear_filter);
70
MIX_FN(mono_8bit_spline_filter);
71
MIX_FN(mono_16bit_spline_filter);
72
MIX_FN(stereo_8bit_spline_filter);
73
MIX_FN(stereo_16bit_spline_filter);
74
#endif
75
 
76
#ifdef LIBXMP_PAULA_SIMULATOR
77
MIX_FN(mono_a500);
78
MIX_FN(mono_a500_filter);
79
MIX_FN(stereo_a500);
80
MIX_FN(stereo_a500_filter);
81
#endif
82
 
83
/* Mixers array index:
84
 *
85
 * bit 0: 0=8 bit sample, 1=16 bit sample
86
 * bit 1: 0=mono output, 1=stereo output
87
 * bit 2: 0=unfiltered, 1=filtered
88
 */
89
 
90
typedef void (*mixer_set[])(struct mixer_voice *, int32 *, int, int, int, int, int, int, int);
91
 
92
static mixer_set nearest_mixers = {
93
        libxmp_mix_mono_8bit_nearest,
94
        libxmp_mix_mono_16bit_nearest,
95
        libxmp_mix_stereo_8bit_nearest,
96
        libxmp_mix_stereo_16bit_nearest,
97
 
98
#ifndef LIBXMP_CORE_DISABLE_IT
99
        libxmp_mix_mono_8bit_nearest,
100
        libxmp_mix_mono_16bit_nearest,
101
        libxmp_mix_stereo_8bit_nearest,
102
        libxmp_mix_stereo_16bit_nearest,
103
#endif
104
};
105
 
106
static mixer_set linear_mixers = {
107
        libxmp_mix_mono_8bit_linear,
108
        libxmp_mix_mono_16bit_linear,
109
        libxmp_mix_stereo_8bit_linear,
110
        libxmp_mix_stereo_16bit_linear,
111
 
112
#ifndef LIBXMP_CORE_DISABLE_IT
113
        libxmp_mix_mono_8bit_linear_filter,
114
        libxmp_mix_mono_16bit_linear_filter,
115
        libxmp_mix_stereo_8bit_linear_filter,
116
        libxmp_mix_stereo_16bit_linear_filter
117
#endif
118
};
119
 
120
static mixer_set spline_mixers = {
121
        libxmp_mix_mono_8bit_spline,
122
        libxmp_mix_mono_16bit_spline,
123
        libxmp_mix_stereo_8bit_spline,
124
        libxmp_mix_stereo_16bit_spline,
125
 
126
#ifndef LIBXMP_CORE_DISABLE_IT
127
        libxmp_mix_mono_8bit_spline_filter,
128
        libxmp_mix_mono_16bit_spline_filter,
129
        libxmp_mix_stereo_8bit_spline_filter,
130
        libxmp_mix_stereo_16bit_spline_filter
131
#endif
132
};
133
 
134
#ifdef LIBXMP_PAULA_SIMULATOR
135
static mixer_set a500_mixers = {
136
        libxmp_mix_mono_a500,
137
        NULL,
138
        libxmp_mix_stereo_a500,
139
        NULL,
140
        NULL,
141
        NULL,
142
        NULL,
143
        NULL
144
};
145
 
146
 
147
static mixer_set a500led_mixers = {
148
        libxmp_mix_mono_a500_filter,
149
        NULL,
150
        libxmp_mix_stereo_a500_filter,
151
        NULL,
152
        NULL,
153
        NULL,
154
        NULL,
155
        NULL
156
};
157
#endif
158
 
159
 
160
/* Downmix 32bit samples to 8bit, signed or unsigned, mono or stereo output */
7082 terminx 161
static void downmix_int_8bit(int8 *dest, int32 *src, int num, int amp, int offs)
6158 hendricks2 162
{
163
        int smp;
164
        int shift = DOWNMIX_SHIFT + 8 - amp;
165
 
166
        for (; num--; src++, dest++) {
167
                smp = *src >> shift;
168
                if (smp > LIM8_HI) {
169
                        *dest = LIM8_HI;
170
                } else if (smp < LIM8_LO) {
171
                        *dest = LIM8_LO;
172
                } else {
173
                        *dest = smp;
174
                }
175
 
176
                if (offs) *dest += offs;
177
        }
178
}
179
 
180
 
181
/* Downmix 32bit samples to 16bit, signed or unsigned, mono or stereo output */
182
static void downmix_int_16bit(int16 *dest, int32 *src, int num, int amp, int offs)
183
{
184
        int smp;
185
        int shift = DOWNMIX_SHIFT - amp;
186
 
187
        for (; num--; src++, dest++) {
188
                smp = *src >> shift;
189
                if (smp > LIM16_HI) {
190
                        *dest = LIM16_HI;
191
                } else if (smp < LIM16_LO) {
192
                        *dest = LIM16_LO;
193
                } else {
194
                        *dest = smp;
195
                }
196
 
197
                if (offs) *dest += offs;
198
        }
199
}
200
 
201
static void anticlick(struct mixer_voice *vi)
202
{
203
        vi->flags |= ANTICLICK;
204
        vi->old_vl = 0;
205
        vi->old_vr = 0;
206
}
207
 
208
/* Ok, it's messy, but it works :-) Hipolito */
209
static void do_anticlick(struct context_data *ctx, int voc, int32 *buf, int count)
210
{
211
        struct player_data *p = &ctx->p;
212
        struct mixer_data *s = &ctx->s;
213
        struct mixer_voice *vi = &p->virt.voice_array[voc];
214
        int smp_l, smp_r, max_x2;
215
        int discharge = s->ticksize >> ANTICLICK_SHIFT;
216
 
217
        smp_r = vi->sright;
218
        smp_l = vi->sleft;
219
        vi->sright = vi->sleft = 0;
220
 
221
        if (smp_l == 0 && smp_r == 0) {
222
                return;
223
        }
224
 
225
        if (buf == NULL) {
226
                buf = s->buf32;
227
                count = discharge;
228
        } else if (count > discharge) {
229
                count = discharge;
230
        }
231
 
232
        if (count <= 0) {
233
                return;
234
        }
235
 
236
        max_x2 = count * count;
237
 
238
        while (count--) {
239
                if (~s->format & XMP_FORMAT_MONO) {
240
                        *buf++ += (count * (smp_r >> 10) / max_x2 * count) << 10;
241
                }
242
 
243
                *buf++ += (count * (smp_l >> 10) / max_x2 * count) << 10;
244
        }
245
}
246
 
247
static void set_sample_end(struct context_data *ctx, int voc, int end)
248
{
249
        struct player_data *p = &ctx->p;
250
        struct module_data *m = &ctx->m;
251
        struct mixer_voice *vi = &p->virt.voice_array[voc];
252
        struct channel_data *xc;
253
 
254
        if ((uint32)voc >= p->virt.maxvoc)
255
                return;
256
 
257
        xc = &p->xc_data[vi->chn];
258
 
259
        if (end) {
260
                SET_NOTE(NOTE_SAMPLE_END);
261
                if (HAS_QUIRK(QUIRK_RSTCHN)) {
262
                        libxmp_virt_resetvoice(ctx, voc, 0);
263
                }
264
        } else {
265
                RESET_NOTE(NOTE_SAMPLE_END);
266
        }
267
}
268
 
269
static void adjust_voice_end(struct mixer_voice *vi, struct xmp_sample *xxs)
270
{
271
        if (xxs->flg & XMP_SAMPLE_LOOP) {
272
                if ((xxs->flg & XMP_SAMPLE_LOOP_FULL) && (~vi->flags & SAMPLE_LOOP)) {
273
                        vi->end = xxs->len;
274
                } else {
275
                        vi->end = xxs->lpe;
276
                }
277
        } else {
278
                vi->end = xxs->len;
279
        }
280
}
281
 
282
static void loop_reposition(struct context_data *ctx, struct mixer_voice *vi, struct xmp_sample *xxs)
283
{
284
#ifndef LIBXMP_CORE_DISABLE_IT
285
        struct module_data *m = &ctx->m;
286
#endif
287
        int loop_size = xxs->lpe - xxs->lps;
288
 
289
        /* Reposition for next loop */
290
        vi->pos -= loop_size;           /* forward loop */
291
        vi->end = xxs->lpe;
292
        vi->flags |= SAMPLE_LOOP;
293
 
294
        if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
295
                vi->end += loop_size;   /* unrolled loop */
296
                vi->pos -= loop_size;   /* forward loop */
297
 
298
#ifndef LIBXMP_CORE_DISABLE_IT
299
                /* OpenMPT Bidi-Loops.it: "In Impulse Tracker’s software mixer,
300
                 * ping-pong loops are shortened by one sample.
301
                 */
302
                if (IS_PLAYER_MODE_IT()) {
303
                        vi->end--;
304
                        vi->pos++;
305
                }
306
#endif
307
        }
308
}
309
 
310
 
311
/* Prepare the mixer for the next tick */
312
void libxmp_mixer_prepare(struct context_data *ctx)
313
{
314
        struct player_data *p = &ctx->p;
315
        struct module_data *m = &ctx->m;
316
        struct mixer_data *s = &ctx->s;
317
        int bytelen;
318
 
6174 terminx 319
        s->ticksize = (int)(s->freq * m->time_factor * m->rrate / p->bpm / 1000);
6158 hendricks2 320
 
321
        bytelen = s->ticksize * sizeof(int);
322
        if (~s->format & XMP_FORMAT_MONO) {
323
                bytelen *= 2;
324
        }
325
        memset(s->buf32, 0, bytelen);
326
}
327
/* Fill the output buffer calling one of the handlers. The buffer contains
328
 * sound for one tick (a PAL frame or 1/50s for standard vblank-timed mods)
329
 */
330
void libxmp_mixer_softmixer(struct context_data *ctx)
331
{
332
        struct player_data *p = &ctx->p;
333
        struct mixer_data *s = &ctx->s;
334
        struct module_data *m = &ctx->m;
335
        struct xmp_module *mod = &m->mod;
336
        struct xmp_sample *xxs;
337
        struct mixer_voice *vi;
338
        double step;
339
        int samples, size;
340
        int vol_l, vol_r, voc, usmp;
341
        int prev_l, prev_r = 0;
342
        int lps, lpe;
343
        int32 *buf_pos;
344
        void (*mix_fn)(struct mixer_voice *, int32 *, int, int, int, int, int, int, int);
345
        mixer_set *mixers;
346
 
347
        switch (s->interp) {
348
        case XMP_INTERP_NEAREST:
6162 hendricks2 349
                mixers = (mixer_set *)&nearest_mixers;
6158 hendricks2 350
                break;
351
        case XMP_INTERP_LINEAR:
6162 hendricks2 352
                mixers = (mixer_set *)&linear_mixers;
6158 hendricks2 353
                break;
354
        case XMP_INTERP_SPLINE:
6162 hendricks2 355
                mixers = (mixer_set *)&spline_mixers;
6158 hendricks2 356
                break;
357
        default:
6162 hendricks2 358
                mixers = (mixer_set *)&linear_mixers;
6158 hendricks2 359
        }
360
 
361
#ifdef LIBXMP_PAULA_SIMULATOR
362
        if (p->flags & XMP_FLAGS_A500) {
363
                if (IS_AMIGA_MOD()) {
364
                        if (p->filter) {
6162 hendricks2 365
                                mixers = (mixer_set *)&a500led_mixers;
6158 hendricks2 366
                        } else {
6162 hendricks2 367
                                mixers = (mixer_set *)&a500_mixers;
6158 hendricks2 368
                        }
369
                }
370
        }
371
#endif
372
 
373
        libxmp_mixer_prepare(ctx);
374
 
375
        for (voc = 0; voc < p->virt.maxvoc; voc++) {
376
                int c5spd, rampsize, delta_l, delta_r;
377
 
378
                vi = &p->virt.voice_array[voc];
379
 
380
                if (vi->flags & ANTICLICK) {
381
                        if (s->interp > XMP_INTERP_NEAREST) {
382
                                do_anticlick(ctx, voc, NULL, 0);
383
                        }
384
                        vi->flags &= ~ANTICLICK;
385
                }
386
 
387
                if (vi->chn < 0) {
388
                        continue;
389
                }
390
 
391
                if (vi->period < 1) {
392
                        libxmp_virt_resetvoice(ctx, voc, 1);
393
                        continue;
394
                }
395
 
6174 terminx 396
                vi->pos0 = (int)vi->pos;
6158 hendricks2 397
 
398
                buf_pos = s->buf32;
399
                if (vi->pan == PAN_SURROUND) {
400
                        vol_r = vi->vol * 0x80;
401
                        vol_l = -vi->vol * 0x80;
402
                } else {
403
                        vol_r = vi->vol * (0x80 - vi->pan);
404
                        vol_l = vi->vol * (0x80 + vi->pan);
405
                }
406
 
407
                if (vi->smp < mod->smp) {
408
                        xxs = &mod->xxs[vi->smp];
6174 terminx 409
                        c5spd = (int) m->xtra[vi->smp].c5spd;
6158 hendricks2 410
                } else {
411
                        xxs = &ctx->smix.xxs[vi->smp - mod->smp];
412
                        c5spd = m->c4rate;
413
                }
414
 
415
                step = C4_PERIOD * c5spd / s->freq / vi->period;
416
 
417
                if (step < 0.001) {     /* otherwise m5v-nwlf.it crashes */
418
                        continue;
419
                }
420
 
421
#ifndef LIBXMP_CORE_DISABLE_IT
422
                if (xxs->flg & XMP_SAMPLE_SLOOP && vi->smp < mod->smp) {
423
                        if (~vi->flags & VOICE_RELEASE) {
424
                                if (vi->pos < m->xsmp[vi->smp].lpe) {
425
                                        xxs = &m->xsmp[vi->smp];
426
                                }
427
                        }
428
                }
429
 
430
                adjust_voice_end(vi, xxs);
431
#endif
432
 
433
                lps = xxs->lps;
434
                lpe = xxs->lpe;
435
 
436
                if (p->flags & XMP_FLAGS_FIXLOOP) {
437
                        lps >>= 1;
438
                }
439
 
440
                if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
441
                        vi->end += lpe - lps;
442
 
443
#ifndef LIBXMP_CORE_DISABLE_IT
444
                        if (IS_PLAYER_MODE_IT()) {
445
                                vi->end--;
446
                        }
447
#endif
448
                }
449
 
450
                rampsize = s->ticksize >> ANTICLICK_SHIFT;
451
                delta_l = (vol_l - vi->old_vl) / rampsize;
452
                delta_r = (vol_r - vi->old_vr) / rampsize;
453
 
454
                usmp = 0;
455
                for (size = s->ticksize; size > 0; ) {
456
                        int split_noloop = 0;
8561 terminx 457
                        vi->slen = xxs->len;
6158 hendricks2 458
 
459
                        if (p->xc_data[vi->chn].split) {
460
                                split_noloop = 1;
461
                        }
462
 
463
                        /* How many samples we can write before the loop break
464
                         * or sample end... */
465
                        if (vi->pos >= vi->end) {
466
                                samples = 0;
467
                                usmp = 1;
468
                        } else {
6174 terminx 469
                                int s = (int) ceil(((double)vi->end - vi->pos) / step);
6158 hendricks2 470
                                /* ...inside the tick boundaries */
471
                                if (s > size) {
472
                                        s = size;
473
                                }
474
 
475
                                samples = s;
476
                                if (samples > 0) {
477
                                        usmp = 0;
478
                                }
479
                        }
480
 
481
                        if (vi->vol) {
482
                                int mix_size = samples;
483
                                int mixer = vi->fidx & FIDX_FLAGMASK;
484
 
485
                                if (~s->format & XMP_FORMAT_MONO) {
486
                                        mix_size *= 2;
487
                                }
488
 
489
                                /* For Hipolito's anticlick routine */
490
                                if (samples > 0) {
491
                                        if (~s->format & XMP_FORMAT_MONO) {
492
                                                prev_r = buf_pos[mix_size - 2];
493
                                        }
494
                                        prev_l = buf_pos[mix_size - 1];
495
                                } else {
496
                                        prev_r = prev_l = 0;
497
                                }
498
 
499
#ifndef LIBXMP_CORE_DISABLE_IT
500
                                /* See OpenMPT env-flt-max.it */
501
                                if (vi->filter.cutoff >= 0xfe &&
502
                                    vi->filter.resonance == 0) {
503
                                        mixer &= ~FLAG_FILTER;
504
                                }
505
#endif
506
 
507
                                mix_fn = (*mixers)[mixer];
508
 
509
                                /* Call the output handler */
510
                                if (samples > 0 && vi->sptr != NULL) {
511
                                        int rsize = 0;
512
 
513
                                        if (rampsize > samples) {
514
                                                rampsize -= samples;
515
                                        } else {
516
                                                rsize = samples - rampsize;
517
                                                rampsize = 0;
518
                                        }
519
 
520
                                        if (delta_l == 0 && delta_r == 0) {
521
                                                /* no need to ramp */
522
                                                rsize = samples;
523
                                        }
524
 
525
                                        if (mix_fn != NULL) {
526
                                                mix_fn(vi, buf_pos, samples,
6179 hendricks2 527
                                                        vol_l >> 8, vol_r >> 8, (int) (step * (1 << SMIX_SHIFT)), rsize, delta_l, delta_r);
6158 hendricks2 528
                                        }
529
 
530
                                        buf_pos += mix_size;
531
                                        vi->old_vl += samples * delta_l;
532
                                        vi->old_vr += samples * delta_r;
533
 
534
 
535
                                        /* For Hipolito's anticlick routine */
536
                                        if (~s->format & XMP_FORMAT_MONO) {
537
                                                vi->sright = buf_pos[-2] - prev_r;
538
                                        }
539
                                        vi->sleft = buf_pos[-1] - prev_l;
540
                                }
541
                        }
542
 
543
                        vi->pos += step * samples;
544
 
545
                        /* No more samples in this tick */
546
                        size -= samples + usmp;
547
                        if (size <= 0) {
548
                                if (xxs->flg & XMP_SAMPLE_LOOP) {
549
                                        if (vi->pos + step > vi->end) {
550
                                                vi->pos += step;
551
                                                loop_reposition(ctx, vi, xxs);
552
                                        }
553
                                }
554
                                continue;
555
                        }
556
 
557
                        /* First sample loop run */
558
                        if ((~xxs->flg & XMP_SAMPLE_LOOP) || split_noloop) {
559
                                do_anticlick(ctx, voc, buf_pos, size);
560
                                set_sample_end(ctx, voc, 1);
561
                                size = 0;
562
                                continue;
563
                        }
564
 
565
                        loop_reposition(ctx, vi, xxs);
566
                }
567
 
568
                vi->old_vl = vol_l;
569
                vi->old_vr = vol_r;
570
        }
571
 
572
        /* Render final frame */
573
 
574
        size = s->ticksize;
575
        if (~s->format & XMP_FORMAT_MONO) {
576
                size *= 2;
577
        }
578
 
579
        if (size > XMP_MAX_FRAMESIZE) {
580
                size = XMP_MAX_FRAMESIZE;
581
        }
582
 
583
        if (s->format & XMP_FORMAT_8BIT) {
7082 terminx 584
                downmix_int_8bit((int8 *)s->buffer, s->buf32, size, s->amplify,
6158 hendricks2 585
                                s->format & XMP_FORMAT_UNSIGNED ? 0x80 : 0);
586
        } else {
587
                downmix_int_16bit((int16 *)s->buffer, s->buf32, size,s->amplify,
588
                                s->format & XMP_FORMAT_UNSIGNED ? 0x8000 : 0);
589
        }
590
 
591
        s->dtright = s->dtleft = 0;
592
}
593
 
594
void libxmp_mixer_voicepos(struct context_data *ctx, int voc, double pos, int ac)
595
{
596
        struct player_data *p = &ctx->p;
597
        struct module_data *m = &ctx->m;
598
        struct mixer_voice *vi = &p->virt.voice_array[voc];
599
        struct xmp_sample *xxs;
600
        int lps;
601
 
602
        if (vi->smp < m->mod.smp) {
603
                xxs = &m->mod.xxs[vi->smp];
604
        } else {
605
                xxs = &ctx->smix.xxs[vi->smp - m->mod.smp];
606
        }
607
 
608
        if (xxs->flg & XMP_SAMPLE_SYNTH) {
609
                return;
610
        }
611
 
612
        vi->pos = pos;
613
 
614
        adjust_voice_end(vi, xxs);
615
 
616
        if (vi->pos >= vi->end) {
617
                if (xxs->flg & XMP_SAMPLE_LOOP) {
618
                        vi->pos = xxs->lps;
619
                } else {
620
                        vi->pos = xxs->len;
621
                }
622
        }
623
 
624
        lps = xxs->lps;
625
        if (p->flags & XMP_FLAGS_FIXLOOP) {
626
                lps >>= 1;
627
        }
628
 
629
        if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
630
                vi->end += (xxs->lpe - lps);
631
 
632
#ifndef LIBXMP_CORE_DISABLE_IT
633
                if (IS_PLAYER_MODE_IT()) {
634
                        vi->end--;
635
                }
636
#endif
637
        }
638
 
639
        if (ac) {
640
                anticlick(vi);
641
        }
642
}
643
 
644
double libxmp_mixer_getvoicepos(struct context_data *ctx, int voc)
645
{
646
        struct player_data *p = &ctx->p;
647
        struct mixer_voice *vi = &p->virt.voice_array[voc];
648
        struct xmp_sample *xxs;
649
 
650
        xxs = libxmp_get_sample(ctx, vi->smp);
651
 
652
        if (xxs->flg & XMP_SAMPLE_SYNTH) {
653
                return 0;
654
        }
655
 
656
        if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
657
                if (vi->pos >= xxs->lpe) {
658
                        return xxs->lpe - (vi->pos - xxs->lpe) - 1;
659
                }
660
        }
661
 
662
        return vi->pos;
663
}
664
 
665
void libxmp_mixer_setpatch(struct context_data *ctx, int voc, int smp, int ac)
666
{
667
        struct player_data *p = &ctx->p;
668
#ifndef LIBXMP_CORE_DISABLE_IT
669
        struct module_data *m = &ctx->m;
670
#endif
671
        struct mixer_data *s = &ctx->s;
672
        struct mixer_voice *vi = &p->virt.voice_array[voc];
673
        struct xmp_sample *xxs;
674
 
675
        xxs = libxmp_get_sample(ctx, smp);
676
 
677
        vi->smp = smp;
678
        vi->vol = 0;
679
        vi->pan = 0;
680
        vi->flags &= ~SAMPLE_LOOP;
681
 
682
        vi->fidx = 0;
683
 
684
        if (~s->format & XMP_FORMAT_MONO) {
685
                vi->fidx |= FLAG_STEREO;
686
        }
687
 
688
        set_sample_end(ctx, voc, 0);
689
 
690
        /*mixer_setvol(ctx, voc, 0);*/
691
 
692
        vi->sptr = xxs->data;
693
        vi->fidx |= FLAG_ACTIVE;
694
 
695
#ifndef LIBXMP_CORE_DISABLE_IT
696
        if (HAS_QUIRK(QUIRK_FILTER) && s->dsp & XMP_DSP_LOWPASS) {
697
                vi->fidx |= FLAG_FILTER;
698
        }
699
#endif
700
 
701
        if (xxs->flg & XMP_SAMPLE_16BIT) {
702
                vi->fidx |= FLAG_16_BITS;
703
        }
704
 
705
        libxmp_mixer_voicepos(ctx, voc, 0, ac);
706
}
707
 
708
void libxmp_mixer_setnote(struct context_data *ctx, int voc, int note)
709
{
710
        struct player_data *p = &ctx->p;
711
        struct mixer_voice *vi = &p->virt.voice_array[voc];
712
 
713
        /* FIXME: Workaround for crash on notes that are too high
714
         *        see 6nations.it (+114 transposition on instrument 16)
715
         */
716
        if (note > 149) {
717
                note = 149;
718
        }
719
 
720
        vi->note = note;
721
        vi->period = libxmp_note_to_period_mix(note, 0);
722
 
723
        anticlick(vi);
724
}
725
 
726
void libxmp_mixer_setperiod(struct context_data *ctx, int voc, double period)
727
{
728
        struct player_data *p = &ctx->p;
729
        struct mixer_voice *vi = &p->virt.voice_array[voc];
730
 
731
        vi->period = period;
732
}
733
 
734
void libxmp_mixer_setvol(struct context_data *ctx, int voc, int vol)
735
{
736
        struct player_data *p = &ctx->p;
737
        struct mixer_voice *vi = &p->virt.voice_array[voc];
738
 
739
        if (vol == 0) {
740
                anticlick(vi);
741
        }
742
 
743
        vi->vol = vol;
744
}
745
 
746
void libxmp_mixer_release(struct context_data *ctx, int voc, int rel)
747
{
748
        struct player_data *p = &ctx->p;
749
        struct mixer_voice *vi = &p->virt.voice_array[voc];
750
 
751
        if (rel) {
752
                vi->flags |= VOICE_RELEASE;
753
        } else {
754
                vi->flags &= ~VOICE_RELEASE;
755
        }
756
}
757
 
758
void libxmp_mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
759
{
760
#ifndef LIBXMP_CORE_DISABLE_IT
761
        struct player_data *p = &ctx->p;
762
        struct mixer_voice *vi = &p->virt.voice_array[voc];
763
 
764
        switch (type) {
765
        case DSP_EFFECT_CUTOFF:
766
                vi->filter.cutoff = val;
767
                break;
768
        case DSP_EFFECT_RESONANCE:
769
                vi->filter.resonance = val;
770
                break;
771
        case DSP_EFFECT_FILTER_A0:
772
                vi->filter.a0 = val;
773
                break;
774
        case DSP_EFFECT_FILTER_B0:
775
                vi->filter.b0 = val;
776
                break;
777
        case DSP_EFFECT_FILTER_B1:
778
                vi->filter.b1 = val;
779
                break;
780
        }
781
#endif
782
}
783
 
784
void libxmp_mixer_setpan(struct context_data *ctx, int voc, int pan)
785
{
786
        struct player_data *p = &ctx->p;
787
        struct mixer_voice *vi = &p->virt.voice_array[voc];
788
 
789
        vi->pan = pan;
790
}
791
 
792
int libxmp_mixer_numvoices(struct context_data *ctx, int num)
793
{
794
        struct mixer_data *s = &ctx->s;
795
 
796
        if (num > s->numvoc || num < 0) {
797
                return s->numvoc;
798
        } else {
799
                return num;
800
        }
801
}
802
 
803
int libxmp_mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
804
{
805
        struct mixer_data *s = &ctx->s;
806
 
6162 hendricks2 807
        s->buffer = (char *)calloc(2, XMP_MAX_FRAMESIZE);
6158 hendricks2 808
        if (s->buffer == NULL)
809
                goto err;
810
 
6162 hendricks2 811
        s->buf32 = (int32 *)calloc(sizeof(int32), XMP_MAX_FRAMESIZE);
6158 hendricks2 812
        if (s->buf32 == NULL)
813
                goto err1;
814
 
815
        s->freq = rate;
816
        s->format = format;
817
        s->amplify = DEFAULT_AMPLIFY;
818
        s->mix = DEFAULT_MIX;
819
        /* s->pbase = C4_PERIOD * c4rate / s->freq; */
820
        s->interp = XMP_INTERP_LINEAR;  /* default interpolation type */
821
        s->dsp = XMP_DSP_LOWPASS;       /* enable filters by default */
822
        /* s->numvoc = SMIX_NUMVOC; */
823
        s->dtright = s->dtleft = 0;
824
 
825
        return 0;
826
 
827
    err1:
828
        free(s->buffer);
829
    err:
830
        return -1;
831
}
832
 
833
void libxmp_mixer_off(struct context_data *ctx)
834
{
835
        struct mixer_data *s = &ctx->s;
836
 
837
        free(s->buffer);
838
        free(s->buf32);
839
        s->buf32 = NULL;
840
        s->buffer = NULL;
841
}