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 <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <stdarg.h>
28 
29 #include "format.h"
30 #include "virtual.h"
31 #include "mixer.h"
32 
33 const char *xmp_version = XMP_VERSION;
34 const unsigned int xmp_vercode = XMP_VERCODE;
35 
xmp_create_context()36 xmp_context xmp_create_context()
37 {
38 	struct context_data *ctx;
39 
40 	ctx = (struct context_data *)calloc(1, sizeof(struct context_data));
41 	if (ctx == NULL) {
42 		return NULL;
43 	}
44 
45 	ctx->state = XMP_STATE_UNLOADED;
46 	ctx->m.defpan = 100;
47 	ctx->s.numvoc = SMIX_NUMVOC;
48 
49 	return (xmp_context)ctx;
50 }
51 
xmp_free_context(xmp_context opaque)52 void xmp_free_context(xmp_context opaque)
53 {
54 	struct context_data *ctx = (struct context_data *)opaque;
55 
56 	if (ctx->state > XMP_STATE_UNLOADED)
57 		xmp_release_module(opaque);
58 
59 	free(opaque);
60 }
61 
set_position(struct context_data * ctx,int pos,int dir)62 static void set_position(struct context_data *ctx, int pos, int dir)
63 {
64 	struct player_data *p = &ctx->p;
65 	struct module_data *m = &ctx->m;
66 	struct xmp_module *mod = &m->mod;
67 	struct flow_control *f = &p->flow;
68 	int seq;
69 	int has_marker;
70 
71 	/* If dir is 0, we can jump to a different sequence */
72 	if (dir == 0) {
73 		seq = libxmp_get_sequence(ctx, pos);
74 	} else {
75 		seq = p->sequence;
76 	}
77 
78 	if (seq == 0xff) {
79 		return;
80 	}
81 
82 	has_marker = HAS_QUIRK(QUIRK_MARKER);
83 
84 	if (seq >= 0) {
85 		int start = m->seq_data[seq].entry_point;
86 
87 		p->sequence = seq;
88 
89 		if (pos >= 0) {
90 			int pat;
91 
92 			while (has_marker && mod->xxo[pos] == 0xfe) {
93 				if (dir < 0) {
94 					if (pos > start) {
95 						pos--;
96 					}
97 				} else {
98 					pos++;
99 				}
100 			}
101 			pat = mod->xxo[pos];
102 
103 			if (pat < mod->pat) {
104 				if (has_marker && pat == 0xff) {
105 					return;
106 				}
107 
108 				if (pos > p->scan[seq].ord) {
109 					f->end_point = 0;
110 				} else {
111 					f->num_rows = mod->xxp[pat]->rows;
112 					f->end_point = p->scan[seq].num;
113 					f->jumpline = 0;
114 				}
115 			}
116 		}
117 
118 		if (pos < mod->len) {
119 			if (pos == 0) {
120 				p->pos = -1;
121 			} else {
122 				p->pos = pos;
123 			}
124 		}
125 	}
126 }
127 
xmp_next_position(xmp_context opaque)128 int xmp_next_position(xmp_context opaque)
129 {
130 	struct context_data *ctx = (struct context_data *)opaque;
131 	struct player_data *p = &ctx->p;
132 	struct module_data *m = &ctx->m;
133 
134 	if (ctx->state < XMP_STATE_PLAYING)
135 		return -XMP_ERROR_STATE;
136 
137 	if (p->pos < m->mod.len)
138 		set_position(ctx, p->pos + 1, 1);
139 
140 	return p->pos;
141 }
142 
xmp_prev_position(xmp_context opaque)143 int xmp_prev_position(xmp_context opaque)
144 {
145 	struct context_data *ctx = (struct context_data *)opaque;
146 	struct player_data *p = &ctx->p;
147 	struct module_data *m = &ctx->m;
148 
149 	if (ctx->state < XMP_STATE_PLAYING)
150 		return -XMP_ERROR_STATE;
151 
152 	if (p->pos == m->seq_data[p->sequence].entry_point) {
153 		set_position(ctx, -1, -1);
154 	} else if (p->pos > m->seq_data[p->sequence].entry_point) {
155 		set_position(ctx, p->pos - 1, -1);
156 	}
157 	return p->pos < 0 ? 0 : p->pos;
158 }
159 
xmp_set_position(xmp_context opaque,int pos)160 int xmp_set_position(xmp_context opaque, int pos)
161 {
162 	struct context_data *ctx = (struct context_data *)opaque;
163 	struct player_data *p = &ctx->p;
164 	struct module_data *m = &ctx->m;
165 
166 	if (ctx->state < XMP_STATE_PLAYING)
167 		return -XMP_ERROR_STATE;
168 
169 	if (pos >= m->mod.len)
170 		return -XMP_ERROR_INVALID;
171 
172 	set_position(ctx, pos, 0);
173 
174 	return p->pos;
175 }
176 
xmp_set_row(xmp_context opaque,int row)177 int xmp_set_row(xmp_context opaque, int row)
178 {
179 	struct context_data *ctx = (struct context_data *)opaque;
180 	struct player_data *p = &ctx->p;
181 	struct module_data *m = &ctx->m;
182 	struct xmp_module *mod = &m->mod;
183 	struct flow_control *f = &p->flow;
184 	int pos = p->pos;
185 	int pattern = mod->xxo[pos];
186 
187 	if (pos < 0 || pos >= mod->len) {
188 		pos = 0;
189 	}
190 
191 	if (ctx->state < XMP_STATE_PLAYING)
192 		return -XMP_ERROR_STATE;
193 
194 	if (row >= mod->xxp[pattern]->rows)
195 		return -XMP_ERROR_INVALID;
196 
197 	/* See set_position. */
198 	if (p->pos < 0)
199 		p->pos = 0;
200 	p->ord = p->pos;
201 	p->row = row;
202 	p->frame = -1;
203 	f->num_rows = mod->xxp[mod->xxo[p->ord]]->rows;
204 
205 	return row;
206 }
207 
xmp_stop_module(xmp_context opaque)208 void xmp_stop_module(xmp_context opaque)
209 {
210 	struct context_data *ctx = (struct context_data *)opaque;
211 	struct player_data *p = &ctx->p;
212 
213 	if (ctx->state < XMP_STATE_PLAYING)
214 		return;
215 
216 	p->pos = -2;
217 }
218 
xmp_restart_module(xmp_context opaque)219 void xmp_restart_module(xmp_context opaque)
220 {
221 	struct context_data *ctx = (struct context_data *)opaque;
222 	struct player_data *p = &ctx->p;
223 
224 	if (ctx->state < XMP_STATE_PLAYING)
225 		return;
226 
227 	p->loop_count = 0;
228 	p->pos = -1;
229 }
230 
xmp_seek_time(xmp_context opaque,int time)231 int xmp_seek_time(xmp_context opaque, int time)
232 {
233 	struct context_data *ctx = (struct context_data *)opaque;
234 	struct player_data *p = &ctx->p;
235 	struct module_data *m = &ctx->m;
236 	int i, t;
237 
238 	if (ctx->state < XMP_STATE_PLAYING)
239 		return -XMP_ERROR_STATE;
240 
241 	for (i = m->mod.len - 1; i >= 0; i--) {
242 		int pat = m->mod.xxo[i];
243 		if (pat >= m->mod.pat) {
244 			continue;
245 		}
246 		if (libxmp_get_sequence(ctx, i) != p->sequence) {
247 			continue;
248 		}
249 		t = m->xxo_info[i].time;
250 		if (time >= t) {
251 			set_position(ctx, i, 1);
252 			break;
253 		}
254 	}
255 	if (i < 0) {
256 		xmp_set_position(opaque, 0);
257 	}
258 
259 	return p->pos < 0 ? 0 : p->pos;
260 }
261 
xmp_channel_mute(xmp_context opaque,int chn,int status)262 int xmp_channel_mute(xmp_context opaque, int chn, int status)
263 {
264 	struct context_data *ctx = (struct context_data *)opaque;
265 	struct player_data *p = &ctx->p;
266 	int ret;
267 
268 	if (ctx->state < XMP_STATE_PLAYING)
269 		return -XMP_ERROR_STATE;
270 
271 	if (chn < 0 || chn >= XMP_MAX_CHANNELS) {
272 		return -XMP_ERROR_INVALID;
273 	}
274 
275 	ret = p->channel_mute[chn];
276 
277 	if (status >= 2) {
278 		p->channel_mute[chn] = !p->channel_mute[chn];
279 	} else if (status >= 0) {
280 		p->channel_mute[chn] = status;
281 	}
282 
283 	return ret;
284 }
285 
xmp_channel_vol(xmp_context opaque,int chn,int vol)286 int xmp_channel_vol(xmp_context opaque, int chn, int vol)
287 {
288 	struct context_data *ctx = (struct context_data *)opaque;
289 	struct player_data *p = &ctx->p;
290 	int ret;
291 
292 	if (ctx->state < XMP_STATE_PLAYING)
293 		return -XMP_ERROR_STATE;
294 
295 	if (chn < 0 || chn >= XMP_MAX_CHANNELS) {
296 		return -XMP_ERROR_INVALID;
297 	}
298 
299 	ret = p->channel_vol[chn];
300 
301 	if (vol >= 0 && vol <= 100) {
302 		p->channel_vol[chn] = vol;
303 	}
304 
305 	return ret;
306 }
307 
308 #ifdef USE_VERSIONED_SYMBOLS
309 LIBXMP_EXPORT extern int xmp_set_player_v40__(xmp_context, int, int);
310 LIBXMP_EXPORT extern int xmp_set_player_v41__(xmp_context, int, int)
311 	__attribute__((alias("xmp_set_player_v40__")));
312 LIBXMP_EXPORT extern int xmp_set_player_v43__(xmp_context, int, int)
313 	__attribute__((alias("xmp_set_player_v40__")));
314 LIBXMP_EXPORT extern int xmp_set_player_v44__(xmp_context, int, int)
315 	__attribute__((alias("xmp_set_player_v40__")));
316 
317 asm(".symver xmp_set_player_v40__, xmp_set_player@XMP_4.0");
318 asm(".symver xmp_set_player_v41__, xmp_set_player@XMP_4.1");
319 asm(".symver xmp_set_player_v43__, xmp_set_player@XMP_4.3");
320 asm(".symver xmp_set_player_v44__, xmp_set_player@@XMP_4.4");
321 
322 #define xmp_set_player__ xmp_set_player_v40__
323 #else
324 #define xmp_set_player__ xmp_set_player
325 #endif
326 
xmp_set_player__(xmp_context opaque,int parm,int val)327 int xmp_set_player__(xmp_context opaque, int parm, int val)
328 {
329 	struct context_data *ctx = (struct context_data *)opaque;
330 	struct player_data *p = &ctx->p;
331 	struct module_data *m = &ctx->m;
332 	struct mixer_data *s = &ctx->s;
333 	int ret = -XMP_ERROR_INVALID;
334 
335 
336 	if (parm == XMP_PLAYER_SMPCTL || parm == XMP_PLAYER_DEFPAN) {
337 		/* these should be set before loading the module */
338 		if (ctx->state >= XMP_STATE_LOADED) {
339 			return -XMP_ERROR_STATE;
340 		}
341 	} else if (parm == XMP_PLAYER_VOICES) {
342 		/* these should be set before start playing */
343 		if (ctx->state >= XMP_STATE_PLAYING) {
344 			return -XMP_ERROR_STATE;
345 		}
346 	} else if (ctx->state < XMP_STATE_PLAYING) {
347 		return -XMP_ERROR_STATE;
348 	}
349 
350 	switch (parm) {
351 	case XMP_PLAYER_AMP:
352 		if (val >= 0 && val <= 3) {
353 			s->amplify = val;
354 			ret = 0;
355 		}
356 		break;
357 	case XMP_PLAYER_MIX:
358 		if (val >= -100 && val <= 100) {
359 			s->mix = val;
360 			ret = 0;
361 		}
362 		break;
363 	case XMP_PLAYER_INTERP:
364 		if (val >= XMP_INTERP_NEAREST && val <= XMP_INTERP_SPLINE) {
365 			s->interp = val;
366 			ret = 0;
367 		}
368 		break;
369 	case XMP_PLAYER_DSP:
370 		s->dsp = val;
371 		ret = 0;
372 		break;
373 	case XMP_PLAYER_FLAGS: {
374 		p->player_flags = val;
375 		ret = 0;
376 		break; }
377 
378 	/* 4.1 */
379 	case XMP_PLAYER_CFLAGS: {
380 		int vblank = p->flags & XMP_FLAGS_VBLANK;
381 		p->flags = val;
382 		if (vblank != (p->flags & XMP_FLAGS_VBLANK))
383 			libxmp_scan_sequences(ctx);
384 		ret = 0;
385 		break; }
386 	case XMP_PLAYER_SMPCTL:
387 		m->smpctl = val;
388 		ret = 0;
389 		break;
390 	case XMP_PLAYER_VOLUME:
391 		if (val >= 0 && val <= 200) {
392 			p->master_vol = val;
393 			ret = 0;
394 		}
395 		break;
396 	case XMP_PLAYER_SMIX_VOLUME:
397 		if (val >= 0 && val <= 200) {
398 			p->smix_vol = val;
399 			ret = 0;
400 		}
401 		break;
402 
403 	/* 4.3 */
404 	case XMP_PLAYER_DEFPAN:
405 		if (val >= 0 && val <= 100) {
406 			m->defpan = val;
407 			ret = 0;
408 		}
409 		break;
410 
411 	/* 4.4 */
412 	case XMP_PLAYER_MODE:
413 		p->mode = val;
414 		libxmp_set_player_mode(ctx);
415 		libxmp_scan_sequences(ctx);
416 		ret = 0;
417 		break;
418 	case XMP_PLAYER_VOICES:
419 		s->numvoc = val;
420 		break;
421 	}
422 
423 	return ret;
424 }
425 
426 #ifdef USE_VERSIONED_SYMBOLS
427 LIBXMP_EXPORT extern int xmp_get_player_v40__(xmp_context, int);
428 LIBXMP_EXPORT extern int xmp_get_player_v41__(xmp_context, int)
429 	__attribute__((alias("xmp_get_player_v40__")));
430 LIBXMP_EXPORT extern int xmp_get_player_v42__(xmp_context, int)
431 	__attribute__((alias("xmp_get_player_v40__")));
432 LIBXMP_EXPORT extern int xmp_get_player_v43__(xmp_context, int)
433 	__attribute__((alias("xmp_get_player_v40__")));
434 LIBXMP_EXPORT extern int xmp_get_player_v44__(xmp_context, int)
435 	__attribute__((alias("xmp_get_player_v40__")));
436 
437 asm(".symver xmp_get_player_v40__, xmp_get_player@XMP_4.0");
438 asm(".symver xmp_get_player_v41__, xmp_get_player@XMP_4.1");
439 asm(".symver xmp_get_player_v42__, xmp_get_player@XMP_4.2");
440 asm(".symver xmp_get_player_v43__, xmp_get_player@XMP_4.3");
441 asm(".symver xmp_get_player_v44__, xmp_get_player@@XMP_4.4");
442 
443 #define xmp_get_player__ xmp_get_player_v40__
444 #else
445 #define xmp_get_player__ xmp_get_player
446 #endif
447 
xmp_get_player__(xmp_context opaque,int parm)448 int xmp_get_player__(xmp_context opaque, int parm)
449 {
450 	struct context_data *ctx = (struct context_data *)opaque;
451 	struct player_data *p = &ctx->p;
452 	struct module_data *m = &ctx->m;
453 	struct mixer_data *s = &ctx->s;
454 	int ret = -XMP_ERROR_INVALID;
455 
456 	if (parm == XMP_PLAYER_SMPCTL || parm == XMP_PLAYER_DEFPAN) {
457 		// can read these at any time
458 	} else if (parm != XMP_PLAYER_STATE && ctx->state < XMP_STATE_PLAYING) {
459 		return -XMP_ERROR_STATE;
460 	}
461 
462 	switch (parm) {
463 	case XMP_PLAYER_AMP:
464 		ret = s->amplify;
465 		break;
466 	case XMP_PLAYER_MIX:
467 		ret = s->mix;
468 		break;
469 	case XMP_PLAYER_INTERP:
470 		ret = s->interp;
471 		break;
472 	case XMP_PLAYER_DSP:
473 		ret = s->dsp;
474 		break;
475 	case XMP_PLAYER_FLAGS:
476 		ret = p->player_flags;
477 		break;
478 
479 	/* 4.1 */
480 	case XMP_PLAYER_CFLAGS:
481 		ret = p->flags;
482 		break;
483 	case XMP_PLAYER_SMPCTL:
484 		ret = m->smpctl;
485 		break;
486 	case XMP_PLAYER_VOLUME:
487 		ret = p->master_vol;
488 		break;
489 	case XMP_PLAYER_SMIX_VOLUME:
490 		ret = p->smix_vol;
491 		break;
492 
493 	/* 4.2 */
494 	case XMP_PLAYER_STATE:
495 		ret = ctx->state;
496 		break;
497 
498 	/* 4.3 */
499 	case XMP_PLAYER_DEFPAN:
500 		ret = m->defpan;
501 		break;
502 
503 	/* 4.4 */
504 	case XMP_PLAYER_MODE:
505 		ret = p->mode;
506 		break;
507 	case XMP_PLAYER_MIXER_TYPE:
508 		ret = XMP_MIXER_STANDARD;
509 		if (p->flags & XMP_FLAGS_A500) {
510 			if (IS_AMIGA_MOD()) {
511 #ifdef LIBXMP_PAULA_SIMULATOR
512 				if (p->filter) {
513 					ret = XMP_MIXER_A500F;
514 				} else {
515 					ret = XMP_MIXER_A500;
516 				}
517 #endif
518 			}
519 		}
520 		break;
521 	case XMP_PLAYER_VOICES:
522 		ret = s->numvoc;
523 		break;
524 	}
525 
526 	return ret;
527 }
528 
xmp_get_format_list()529 const char **xmp_get_format_list()
530 {
531 	return format_list();
532 }
533 
xmp_inject_event(xmp_context opaque,int channel,struct xmp_event * e)534 void xmp_inject_event(xmp_context opaque, int channel, struct xmp_event *e)
535 {
536 	struct context_data *ctx = (struct context_data *)opaque;
537 	struct player_data *p = &ctx->p;
538 
539 	if (ctx->state < XMP_STATE_PLAYING)
540 		return;
541 
542 	memcpy(&p->inject_event[channel], e, sizeof(struct xmp_event));
543 	p->inject_event[channel]._flag = 1;
544 }
545 
xmp_set_instrument_path(xmp_context opaque,char * path)546 int xmp_set_instrument_path(xmp_context opaque, char *path)
547 {
548 	struct context_data *ctx = (struct context_data *)opaque;
549 	struct module_data *m = &ctx->m;
550 
551 	if (m->instrument_path != NULL)
552 		free(m->instrument_path);
553 
554 	m->instrument_path = strdup(path);
555 	if (m->instrument_path == NULL) {
556 		return -XMP_ERROR_SYSTEM;
557 	}
558 
559 	return 0;
560 }
561 
xmp_set_tempo_factor(xmp_context opaque,double val)562 int xmp_set_tempo_factor(xmp_context opaque, double val)
563 {
564 	struct context_data *ctx = (struct context_data *)opaque;
565 	struct player_data *p = &ctx->p;
566 	struct module_data *m = &ctx->m;
567 	struct mixer_data *s = &ctx->s;
568 	int ticksize;
569 
570 	if (val <= 0.0) {
571 		return -1;
572 	}
573 
574 	val *= 10;
575 	ticksize = s->freq * m->time_factor * m->rrate / p->bpm / 1000 * sizeof(int);
576 	if (ticksize > XMP_MAX_FRAMESIZE) {
577 		return -1;
578 	}
579 	m->time_factor = val;
580 
581 	return 0;
582 }
583