1 /* Extended Module Player
2  * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
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 */
downmix_int_8bit(int8 * dest,int32 * src,int num,int amp,int offs)161 static void downmix_int_8bit(int8 *dest, int32 *src, int num, int amp, int offs)
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 */
downmix_int_16bit(int16 * dest,int32 * src,int num,int amp,int offs)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 
anticlick(struct mixer_voice * vi)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 */
do_anticlick(struct context_data * ctx,int voc,int32 * buf,int count)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 
set_sample_end(struct context_data * ctx,int voc,int end)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 
adjust_voice_end(struct mixer_voice * vi,struct xmp_sample * xxs)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 
loop_reposition(struct context_data * ctx,struct mixer_voice * vi,struct xmp_sample * xxs)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 */
libxmp_mixer_prepare(struct context_data * ctx)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 
319 	s->ticksize = (int)(s->freq * m->time_factor * m->rrate / p->bpm / 1000);
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  */
libxmp_mixer_softmixer(struct context_data * ctx)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:
349 		mixers = (mixer_set *)&nearest_mixers;
350 		break;
351 	case XMP_INTERP_LINEAR:
352 		mixers = (mixer_set *)&linear_mixers;
353 		break;
354 	case XMP_INTERP_SPLINE:
355 		mixers = (mixer_set *)&spline_mixers;
356 		break;
357 	default:
358 		mixers = (mixer_set *)&linear_mixers;
359 	}
360 
361 #ifdef LIBXMP_PAULA_SIMULATOR
362 	if (p->flags & XMP_FLAGS_A500) {
363 		if (IS_AMIGA_MOD()) {
364 			if (p->filter) {
365 				mixers = (mixer_set *)&a500led_mixers;
366 			} else {
367 				mixers = (mixer_set *)&a500_mixers;
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 
396 		vi->pos0 = (int)vi->pos;
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];
409 			c5spd = (int) m->xtra[vi->smp].c5spd;
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;
457 
458 			if (p->xc_data[vi->chn].split) {
459 				split_noloop = 1;
460 			}
461 
462 			/* How many samples we can write before the loop break
463 			 * or sample end... */
464 			if (vi->pos >= vi->end) {
465 				samples = 0;
466 				usmp = 1;
467 			} else {
468 				int s = (int) ceil(((double)vi->end - vi->pos) / step);
469 				/* ...inside the tick boundaries */
470 				if (s > size) {
471 					s = size;
472 				}
473 
474 				samples = s;
475 				if (samples > 0) {
476 					usmp = 0;
477 				}
478 			}
479 
480 			if (vi->vol) {
481 				int mix_size = samples;
482 				int mixer = vi->fidx & FIDX_FLAGMASK;
483 
484 				if (~s->format & XMP_FORMAT_MONO) {
485 					mix_size *= 2;
486 				}
487 
488 				/* For Hipolito's anticlick routine */
489 				if (samples > 0) {
490 					if (~s->format & XMP_FORMAT_MONO) {
491 						prev_r = buf_pos[mix_size - 2];
492 					}
493 					prev_l = buf_pos[mix_size - 1];
494 				} else {
495 					prev_r = prev_l = 0;
496 				}
497 
498 #ifndef LIBXMP_CORE_DISABLE_IT
499 				/* See OpenMPT env-flt-max.it */
500 				if (vi->filter.cutoff >= 0xfe &&
501                                     vi->filter.resonance == 0) {
502 					mixer &= ~FLAG_FILTER;
503 				}
504 #endif
505 
506 				mix_fn = (*mixers)[mixer];
507 
508 				/* Call the output handler */
509 				if (samples > 0 && vi->sptr != NULL) {
510 					int rsize = 0;
511 
512 					if (rampsize > samples) {
513 						rampsize -= samples;
514 					} else {
515 						rsize = samples - rampsize;
516 						rampsize = 0;
517 					}
518 
519 					if (delta_l == 0 && delta_r == 0) {
520 						/* no need to ramp */
521 						rsize = samples;
522 					}
523 
524 					if (mix_fn != NULL) {
525 						mix_fn(vi, buf_pos, samples,
526 							vol_l >> 8, vol_r >> 8, (int) (step * (1 << SMIX_SHIFT)), rsize, delta_l, delta_r);
527 					}
528 
529 					buf_pos += mix_size;
530 					vi->old_vl += samples * delta_l;
531 					vi->old_vr += samples * delta_r;
532 
533 
534 					/* For Hipolito's anticlick routine */
535 					if (~s->format & XMP_FORMAT_MONO) {
536 						vi->sright = buf_pos[-2] - prev_r;
537 					}
538 					vi->sleft = buf_pos[-1] - prev_l;
539 				}
540 			}
541 
542 			vi->pos += step * samples;
543 
544 			/* No more samples in this tick */
545 			size -= samples + usmp;
546 			if (size <= 0) {
547 				if (xxs->flg & XMP_SAMPLE_LOOP) {
548 					if (vi->pos + step > vi->end) {
549 						vi->pos += step;
550 						loop_reposition(ctx, vi, xxs);
551 					}
552 				}
553 				continue;
554 			}
555 
556 			/* First sample loop run */
557 			if ((~xxs->flg & XMP_SAMPLE_LOOP) || split_noloop) {
558 				do_anticlick(ctx, voc, buf_pos, size);
559 				set_sample_end(ctx, voc, 1);
560 				size = 0;
561 				continue;
562 			}
563 
564 			loop_reposition(ctx, vi, xxs);
565 		}
566 
567 		vi->old_vl = vol_l;
568 		vi->old_vr = vol_r;
569 	}
570 
571 	/* Render final frame */
572 
573 	size = s->ticksize;
574 	if (~s->format & XMP_FORMAT_MONO) {
575 		size *= 2;
576 	}
577 
578 	if (size > XMP_MAX_FRAMESIZE) {
579 		size = XMP_MAX_FRAMESIZE;
580 	}
581 
582 	if (s->format & XMP_FORMAT_8BIT) {
583 		downmix_int_8bit((int8 *)s->buffer, s->buf32, size, s->amplify,
584 				s->format & XMP_FORMAT_UNSIGNED ? 0x80 : 0);
585 	} else {
586 		downmix_int_16bit((int16 *)s->buffer, s->buf32, size,s->amplify,
587 				s->format & XMP_FORMAT_UNSIGNED ? 0x8000 : 0);
588 	}
589 
590 	s->dtright = s->dtleft = 0;
591 }
592 
libxmp_mixer_voicepos(struct context_data * ctx,int voc,double pos,int ac)593 void libxmp_mixer_voicepos(struct context_data *ctx, int voc, double pos, int ac)
594 {
595 	struct player_data *p = &ctx->p;
596 	struct module_data *m = &ctx->m;
597 	struct mixer_voice *vi = &p->virt.voice_array[voc];
598 	struct xmp_sample *xxs;
599 	int lps;
600 
601 	if (vi->smp < m->mod.smp) {
602  		xxs = &m->mod.xxs[vi->smp];
603 	} else {
604  		xxs = &ctx->smix.xxs[vi->smp - m->mod.smp];
605 	}
606 
607 	if (xxs->flg & XMP_SAMPLE_SYNTH) {
608 		return;
609 	}
610 
611 	vi->pos = pos;
612 
613 	adjust_voice_end(vi, xxs);
614 
615 	if (vi->pos >= vi->end) {
616 		if (xxs->flg & XMP_SAMPLE_LOOP) {
617 			vi->pos = xxs->lps;
618 		} else {
619 			vi->pos = xxs->len;
620 		}
621 	}
622 
623 	lps = xxs->lps;
624 	if (p->flags & XMP_FLAGS_FIXLOOP) {
625 		lps >>= 1;
626 	}
627 
628 	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
629 		vi->end += (xxs->lpe - lps);
630 
631 #ifndef LIBXMP_CORE_DISABLE_IT
632 		if (IS_PLAYER_MODE_IT()) {
633 			vi->end--;
634 		}
635 #endif
636 	}
637 
638 	if (ac) {
639 		anticlick(vi);
640 	}
641 }
642 
libxmp_mixer_getvoicepos(struct context_data * ctx,int voc)643 double libxmp_mixer_getvoicepos(struct context_data *ctx, int voc)
644 {
645 	struct player_data *p = &ctx->p;
646 	struct mixer_voice *vi = &p->virt.voice_array[voc];
647 	struct xmp_sample *xxs;
648 
649 	xxs = libxmp_get_sample(ctx, vi->smp);
650 
651 	if (xxs->flg & XMP_SAMPLE_SYNTH) {
652 		return 0;
653 	}
654 
655 	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
656 		if (vi->pos >= xxs->lpe) {
657 			return xxs->lpe - (vi->pos - xxs->lpe) - 1;
658 		}
659 	}
660 
661 	return vi->pos;
662 }
663 
libxmp_mixer_setpatch(struct context_data * ctx,int voc,int smp,int ac)664 void libxmp_mixer_setpatch(struct context_data *ctx, int voc, int smp, int ac)
665 {
666 	struct player_data *p = &ctx->p;
667 #ifndef LIBXMP_CORE_DISABLE_IT
668 	struct module_data *m = &ctx->m;
669 #endif
670 	struct mixer_data *s = &ctx->s;
671 	struct mixer_voice *vi = &p->virt.voice_array[voc];
672 	struct xmp_sample *xxs;
673 
674 	xxs = libxmp_get_sample(ctx, smp);
675 
676 	vi->smp = smp;
677 	vi->vol = 0;
678 	vi->pan = 0;
679 	vi->flags &= ~SAMPLE_LOOP;
680 
681 	vi->fidx = 0;
682 
683 	if (~s->format & XMP_FORMAT_MONO) {
684 		vi->fidx |= FLAG_STEREO;
685 	}
686 
687 	set_sample_end(ctx, voc, 0);
688 
689 	/*mixer_setvol(ctx, voc, 0);*/
690 
691 	vi->sptr = xxs->data;
692 	vi->fidx |= FLAG_ACTIVE;
693 
694 #ifndef LIBXMP_CORE_DISABLE_IT
695 	if (HAS_QUIRK(QUIRK_FILTER) && s->dsp & XMP_DSP_LOWPASS) {
696 		vi->fidx |= FLAG_FILTER;
697 	}
698 #endif
699 
700 	if (xxs->flg & XMP_SAMPLE_16BIT) {
701 		vi->fidx |= FLAG_16_BITS;
702 	}
703 
704 	libxmp_mixer_voicepos(ctx, voc, 0, ac);
705 }
706 
libxmp_mixer_setnote(struct context_data * ctx,int voc,int note)707 void libxmp_mixer_setnote(struct context_data *ctx, int voc, int note)
708 {
709 	struct player_data *p = &ctx->p;
710 	struct mixer_voice *vi = &p->virt.voice_array[voc];
711 
712 	/* FIXME: Workaround for crash on notes that are too high
713 	 *        see 6nations.it (+114 transposition on instrument 16)
714 	 */
715 	if (note > 149) {
716 		note = 149;
717 	}
718 
719 	vi->note = note;
720 	vi->period = libxmp_note_to_period_mix(note, 0);
721 
722 	anticlick(vi);
723 }
724 
libxmp_mixer_setperiod(struct context_data * ctx,int voc,double period)725 void libxmp_mixer_setperiod(struct context_data *ctx, int voc, double period)
726 {
727 	struct player_data *p = &ctx->p;
728 	struct mixer_voice *vi = &p->virt.voice_array[voc];
729 
730 	vi->period = period;
731 }
732 
libxmp_mixer_setvol(struct context_data * ctx,int voc,int vol)733 void libxmp_mixer_setvol(struct context_data *ctx, int voc, int vol)
734 {
735 	struct player_data *p = &ctx->p;
736 	struct mixer_voice *vi = &p->virt.voice_array[voc];
737 
738 	if (vol == 0) {
739 		anticlick(vi);
740 	}
741 
742 	vi->vol = vol;
743 }
744 
libxmp_mixer_release(struct context_data * ctx,int voc,int rel)745 void libxmp_mixer_release(struct context_data *ctx, int voc, int rel)
746 {
747 	struct player_data *p = &ctx->p;
748 	struct mixer_voice *vi = &p->virt.voice_array[voc];
749 
750 	if (rel) {
751 		vi->flags |= VOICE_RELEASE;
752 	} else {
753 		vi->flags &= ~VOICE_RELEASE;
754 	}
755 }
756 
libxmp_mixer_seteffect(struct context_data * ctx,int voc,int type,int val)757 void libxmp_mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
758 {
759 #ifndef LIBXMP_CORE_DISABLE_IT
760 	struct player_data *p = &ctx->p;
761 	struct mixer_voice *vi = &p->virt.voice_array[voc];
762 
763 	switch (type) {
764 	case DSP_EFFECT_CUTOFF:
765 		vi->filter.cutoff = val;
766 		break;
767 	case DSP_EFFECT_RESONANCE:
768 		vi->filter.resonance = val;
769 		break;
770 	case DSP_EFFECT_FILTER_A0:
771 		vi->filter.a0 = val;
772 		break;
773 	case DSP_EFFECT_FILTER_B0:
774 		vi->filter.b0 = val;
775 		break;
776 	case DSP_EFFECT_FILTER_B1:
777 		vi->filter.b1 = val;
778 		break;
779 	}
780 #endif
781 }
782 
libxmp_mixer_setpan(struct context_data * ctx,int voc,int pan)783 void libxmp_mixer_setpan(struct context_data *ctx, int voc, int pan)
784 {
785 	struct player_data *p = &ctx->p;
786 	struct mixer_voice *vi = &p->virt.voice_array[voc];
787 
788 	vi->pan = pan;
789 }
790 
libxmp_mixer_numvoices(struct context_data * ctx,int num)791 int libxmp_mixer_numvoices(struct context_data *ctx, int num)
792 {
793 	struct mixer_data *s = &ctx->s;
794 
795 	if (num > s->numvoc || num < 0) {
796 		return s->numvoc;
797 	} else {
798 		return num;
799 	}
800 }
801 
libxmp_mixer_on(struct context_data * ctx,int rate,int format,int c4rate)802 int libxmp_mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
803 {
804 	struct mixer_data *s = &ctx->s;
805 
806 	s->buffer = (char *)calloc(2, XMP_MAX_FRAMESIZE);
807 	if (s->buffer == NULL)
808 		goto err;
809 
810 	s->buf32 = (int32 *)calloc(sizeof(int32), XMP_MAX_FRAMESIZE);
811 	if (s->buf32 == NULL)
812 		goto err1;
813 
814 	s->freq = rate;
815 	s->format = format;
816 	s->amplify = DEFAULT_AMPLIFY;
817 	s->mix = DEFAULT_MIX;
818 	/* s->pbase = C4_PERIOD * c4rate / s->freq; */
819 	s->interp = XMP_INTERP_LINEAR;	/* default interpolation type */
820 	s->dsp = XMP_DSP_LOWPASS;	/* enable filters by default */
821 	/* s->numvoc = SMIX_NUMVOC; */
822 	s->dtright = s->dtleft = 0;
823 
824 	return 0;
825 
826     err1:
827 	free(s->buffer);
828     err:
829 	return -1;
830 }
831 
libxmp_mixer_off(struct context_data * ctx)832 void libxmp_mixer_off(struct context_data *ctx)
833 {
834 	struct mixer_data *s = &ctx->s;
835 
836 	free(s->buffer);
837 	free(s->buf32);
838 	s->buf32 = NULL;
839 	s->buffer = NULL;
840 }
841