1 /***************************************************************************
2                      sound.c  - sound system for xrally
3                              -------------------
4     begin                : Sun Jul 23 2000
5     copyright            : (C) 2000 by Claudio Matsuoka
6     email                : claudio@helllabs.org
7 
8     $Id: sound.c,v 1.8 2000/11/25 15:35:19 claudio2 Exp $
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19 #include <stdio.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <pthread.h>
27 #include "config.h"
28 #include "global.h"
29 #include "soundplayer.h"
30 
31 /***************************************************************************
32  *                                                                         *
33  * This player is based on the xmp 2.1 development tree, and has a fairly  *
34  * good M.K. MOD replaying support. For more information check the libxmp  *
35  * draft at http://xmp.helllabs.org/newxmp.                                *
36  *                                                                         *
37  ***************************************************************************/
38 
39 /* Amiga periods */
40 static int period_amiga[] = {
41    /*  0       1       2       3       4       5       6       7   */
42     0x1c56, 0x1c22, 0x1bee, 0x1bbb, 0x1b87, 0x1b55, 0x1b22, 0x1af0,  /* B  */
43     0x1abf, 0x1a8e, 0x1a5d, 0x1a2c, 0x19fc, 0x19cc, 0x199c, 0x196d,  /* C  */
44     0x193e, 0x1910, 0x18e2, 0x18b4, 0x1886, 0x1859, 0x182c, 0x1800,  /* C# */
45     0x17d4, 0x17a8, 0x177c, 0x1751, 0x1726, 0x16fb, 0x16d1, 0x16a7,  /* D  */
46     0x167d, 0x1654, 0x162b, 0x1602, 0x15d9, 0x15b1, 0x1589, 0x1562,  /* D# */
47     0x153a, 0x1513, 0x14ec, 0x14c6, 0x149f, 0x1479, 0x1454, 0x142e,  /* E  */
48     0x1409, 0x13e4, 0x13c0, 0x139b, 0x1377, 0x1353, 0x1330, 0x130c,  /* F  */
49     0x12e9, 0x12c6, 0x12a4, 0x1282, 0x125f, 0x123e, 0x121c, 0x11fb,  /* F# */
50     0x11da, 0x11b9, 0x1198, 0x1178, 0x1157, 0x1137, 0x1118, 0x10f8,  /* G  */
51     0x10d9, 0x10ba, 0x109b, 0x107d, 0x105e, 0x1040, 0x1022, 0x1004,  /* G# */
52     0x0fe7, 0x0fca, 0x0fad, 0x0f90, 0x0f73, 0x0f57, 0x0f3a, 0x0f1e,  /* A  */
53     0x0f02, 0x0ee7, 0x0ecb, 0x0eb0, 0x0e95, 0x0e7a, 0x0e5f, 0x0e45,  /* A# */
54     0x0e2b, 0x0e11, 0x0df7, 0x0ddd, 0x0dc3, 0x0daa, 0x0d91, 0x0d78,  /* B  */
55 };
56 
57 /* Vibrato/tremolo waveform tables */
58 static int waveform[4][64] = {
59    {   0,  24,  49,  74,  97, 120, 141, 161, 180, 197, 212, 224,
60      235, 244, 250, 253, 255, 253, 250, 244, 235, 224, 212, 197,
61      180, 161, 141, 120,  97,  74,  49,  24,   0, -24, -49, -74,
62      -97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,
63     -255,-253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,
64      -97, -74, -49, -24  },	/* Sine */
65 
66    {   0,  -8, -16, -24, -32, -40, -48, -56, -64, -72, -80, -88,
67      -96,-104,-112,-120,-128,-136,-144,-152,-160,-168,-176,-184,
68     -192,-200,-208,-216,-224,-232,-240,-248, 255, 248, 240, 232,
69      224, 216, 208, 200, 192, 184, 176, 168, 160, 152, 144, 136,
70      128, 120, 112, 104,  96,  88,  80,  72,  64,  56,  48,  40,
71       32,  24,  16,   8  },	/* Ramp down */
72 
73    { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74      255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75      255, 255, 255, 255, 255, 255, 255, 255,-255,-255,-255,-255,
76     -255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,
77     -255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,-255,
78     -255,-255,-255,-255  },	/* Square */
79 
80    {   0,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88,
81       96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184,
82      192, 200, 208, 216, 224, 232, 240, 248,-255,-248,-240,-232,
83     -224,-216,-208,-200,-192,-184,-176,-168,-160,-152,-144,-136,
84     -128,-120,-112,-104, -96, -88, -80, -72, -64, -56, -48, -40,
85      -32, -24, -16,  -8  }	/* Ramp up */
86 };
87 
88 
89 static struct mod_priv _priv, *PRIV = &_priv;
90 static struct mod_state mod[2];
91 static struct mod_channel channel[NUM_CH + 1];
92 static char *mod_ptr[2] = { NULL, NULL };
93 static int slot = 0;
94 
95 static pthread_t thread;
96 static pthread_mutex_t frame_mtx = PTHREAD_MUTEX_INITIALIZER;
97 
98 struct sound_driver *snddev;
99 
100 int16 *snd_buffer;
101 
mix_sound(void)102 static int mix_sound (void)
103 {
104 	register int i;
105 	int c, bsize;
106 
107 	bsize = BUFFER_SIZE /* * 125 / mod[slot].bpm */;
108 
109 	memset (snd_buffer, 0, BUFFER_SIZE << 1);
110 
111 	pthread_mutex_lock (&frame_mtx);
112 
113 	for (c = 0; c <= NUM_CH; c++) {
114 		int siz = mod[slot].header->ins[channel[c].sample].size;
115 		int lsz = mod[slot].header->ins[channel[c].sample].loop_size;
116 		int lst = mod[slot].header->ins[channel[c].sample].loop_start;
117 		int per = channel[c].period;
118 		int vol = channel[c].volume;
119 		int idx = channel[c].sidx;
120 		int8 *src = mod[slot].sample[channel[c].sample];
121 		int16 b;
122 		//int vib;
123 
124 		if (!vol || !per || !src)
125 			continue;
126 
127 		if (c < NUM_CH)
128 			vol = mod[slot].volume * vol / 100;
129 
130 		if (lsz <= 2)
131 			lsz = 0;
132 		else if ((lst + lsz) < siz)
133 			siz = lst + lsz;
134 
135 		for (i = 0; i < bsize; i++) {
136 			int hi = idx >> 8;
137 			int lo = idx & 0xff;
138 
139 			if (hi >= siz) {
140 				if (lsz) {
141 					idx = lst << 8;
142 					hi = lst;
143 					lo = 0;
144 				} else {
145 					break;
146 				}
147 			}
148 
149 			b = src[hi];
150 			/* interpolation */
151 			b += ((src[(hi + 1) % siz] - src[hi]) * lo) >> 8;
152 			snd_buffer[i] += b * vol;
153 
154 			idx += 660000 / per;
155 		}
156 		channel[c].sidx = idx;
157 	}
158 	pthread_mutex_unlock (&frame_mtx);
159 
160 	return bsize;
161 }
162 
163 /* Get period from note and finetune */
note_to_period(int n,int b)164 static int note_to_period (int n, int b)
165 {
166 	int *t = period_amiga;
167 	int f = ((b % 100) << 7) / 100;
168 
169 	if ((n += !((b < 0) && (f += 0x80)) + b / 100) < 0)
170 		n = 0;
171 	t += ((n % 12) << 3) + (f >> 4);
172 	return ((*t << 4) + (*t++ - *t) * (f & 0xf)) >> (n / 12);
173 }
174 
175 /* Get note from period using the Amiga frequency table */
period_to_note(int p)176 int period_to_note (int p)
177 {
178 	int n, f, *t = period_amiga + MAX_NOTE;
179 
180 	if (!p)
181 		return 0;
182 	for (n = NOTE_Bb0; p <= (MAX_PERIOD / 2); n += 12, p <<= 1);
183 	for (; p > *t; t -= 8, n--);
184 	for (f = 7; f && (*t > p); t++, f--);
185 	return n - (f >> 2);
186 }
187 
188 /* Get pitchbend from base note and period */
period_to_bend(int p,int n,int f,int g)189 int period_to_bend (int p, int n, int f, int g)
190 {
191 	int b, *t = period_amiga + MAX_NOTE;
192 
193 	if (!n) return 0;
194 
195 	if (p < MIN_PERIOD_A)
196 		p = MIN_PERIOD_A;
197 
198 	/* Fixup for panic.s3m  (from Toru Egashira's NSPmod) */
199 	for (n = NOTE_B0 - 1 - n; p <= (MAX_PERIOD / 2); n += 12, p <<= 1);
200 
201 	for (; p > *t; t -= 8, n--);
202 	b = 100 * n + (100 * (*t - p) / (*t - *(t + 8))) +
203 		((f - 128) % 16) * 100 / 128 * (f < 0 ? -1 : 1);
204 	return g ? b / 100 * 100 : b;
205 }
206 
event_convert(uint8 * e)207 static void event_convert (uint8 *e)
208 {
209 	struct mod_event n;
210 
211 	n.note = period_to_note ((LSN (e[0]) << 8) + e[1]);
212 	n.ins = ((MSN (e[0]) << 4) | MSN (e[2]));
213 	n.fxt = LSN (e[2]);
214 	n.fxp = e[3];
215 
216 	memcpy (e, &n, 4);
217 }
218 
mod_convert(char * p,int slot)219 static void mod_convert (char *p, int slot)
220 {
221 	int i, j, k;
222 	struct mod_event *e;
223 
224 	mod[slot].header = (struct mod_header *)p;
225 
226 	/* convert instrument data */
227 	for (i = 0; i < 31; i++) {
228 		B_ENDIAN16 (mod[slot].header->ins[i].size);
229 		B_ENDIAN16 (mod[slot].header->ins[i].loop_start);
230 		B_ENDIAN16 (mod[slot].header->ins[i].loop_size);
231 		mod[slot].header->ins[i].size <<= 1;
232 		mod[slot].header->ins[i].loop_start <<= 1;
233 		mod[slot].header->ins[i].loop_size <<= 1;
234 		mod[slot].header->ins[i].finetune =
235 			(int8)(mod[slot].header->ins[i].finetune << 4);
236 	}
237 
238 	mod[slot].header->pat = 0;
239 	for (i = 0; i < 128; i++) {
240 		if (mod[slot].header->order[i] > 0x7f)
241 			break;
242 		if (mod[slot].header->order[i] > mod[slot].header->pat)
243 		mod[slot].header->pat = mod[slot].header->order[i];
244 	}
245 	mod[slot].header->pat++;
246 
247 	mod[slot].pattern = (struct mod_event **)malloc
248 		(mod[slot].header->pat * sizeof (void *));
249 
250 	/* convert pattern data */
251 	for (i = 0; i < mod[slot].header->pat; i++) {
252 		mod[slot].pattern[i] =
253 			(struct mod_event *)((char *)mod[slot].header +
254 			sizeof (struct mod_header) + 256 * NUM_CH * i);
255 		e = mod[slot].pattern[i];
256 		for (j = 0; j < 64; j++) {
257 			for (k = 0; k < NUM_CH; k++) {
258 				event_convert ((char *)e);
259 				e++;
260 			}
261 		}
262 	}
263 
264 	mod[slot].sample[0] =
265 		(char *)mod[slot].pattern[mod[slot].header->pat - 1] +
266 		256 * NUM_CH;
267 
268 	for (i = 1; i < 31; i++) {
269 		mod[slot].sample[i] = mod[slot].sample[i - 1] +
270 			mod[slot].header->ins[i - 1].size;
271 	}
272 }
273 
mod_play_frame()274 int mod_play_frame ()
275 {
276 	int k;
277 	struct mod_event *e;
278 
279 	if (!mod[slot].enabled)
280 		return 0;
281 
282 	//cond_signal (XMP_WAIT_FRAME);
283 
284 	if (!mod[slot].frame) {
285 		//mod[slot].pattern = PRIV->order[mod[slot].order];
286 		//mod[slot].nrows = PRIV->rows;
287 		PRIV->jmp = 0;
288 		PRIV->pbreak = 0;
289 		PRIV->pjump = mod[slot].order + 1;
290 	}
291 
292 	/*
293 	 * Process this frame for all sound channels.
294 	 */
295 
296 	for (k = 0; k < NUM_CH /*mod[slot].nchannels*/; k++) {
297 		struct mod_channel *ck = &channel[k];
298 		//cond_signal (XMP_WAIT_CHN);
299 
300 		ck->dvolume = ck->dperiod = ck->dpan = 0;
301 
302 		if (!mod[slot].frame) {
303 			int i, fxp;
304 
305 			/*
306 			 * In the first frame of a row we collect event data,
307 			 * parse effects, and process "fine" effects. In the
308 			 * original Protracker playroutine the effect checks
309 			 * the frame number, this approach should work better.
310 			 */
311 
312 			e = mod[slot].pattern[mod[slot].header->order[mod[slot].order]] +
313 				NUM_CH /*mod[slot].nchannels*/ * mod[slot].row + k;
314 
315 #if 0
316 			/* Update channel data */
317 			ck->event.note = e->note;
318 			ck->event.ins = e->ins;
319 			ck->event.vol = 0;	/* FIXME! */
320 			ck->event.fxp = e->fxp;
321 			ck->event.fxt = e->fxt;
322 #endif
323 
324 			/*
325 	 	 	 * From the mod replaying notes for PT3.15:
326 	 		 *
327   	 		 *	  Instrument -> None    Same    Valid   Inval
328 			 * New note		Switch  Play    Play    Cut
329 			 * New instr. (no note) -       NewVol  NewVol  Cut
330 			 * Tone portamento	Cont    NewVol  NewVol  Cut
331 			 *
332 			 * Play    = Play new note with new default volume
333 			 * Switch  = Play new note with current volume
334 			 * NewVol  = Don't play sample, set new default volume
335 			 * Cont    = Continue playing sample
336 			 * Cut     = Stop playing sample
337 			 */
338 
339 			if (e->ins) {
340 				ck->volume = mod[slot].header->ins[e->ins - 1].volume;
341 				ck->fx[finetune].value =
342 					mod[slot].header->ins[e->ins - 1].finetune;
343 			}
344 
345 			if (e->note) {
346 				ck->note = e->note;
347 
348  				if (e->fxt != 0x3 && e->fxt != 0x5) {
349 					if (e->ins) {
350 						ck->instr = e->ins - 1;
351 						ck->sample = ck->instr;
352 					}
353 
354 					ck->sidx = 0;
355 					ck->period = ck->fx[portamento].target =
356 						note_to_period (e->note,
357 						ck->fx[finetune].value);
358 				}
359 			}
360 
361 			/*
362 			 * effects
363 			 */
364 
365 			for (i = 0; i < fx_last; i++)
366 				fx_disable (ck->fx[i]);
367 
368 			switch (e->fxt) {
369 			case 0x0:	/* arpeggio */
370 				if (!e->fxp)
371 					break;
372 				fx_enable (ck->fx[arpeggio]);
373 				ck->fx[arpeggio].data[0] = 0;
374 				ck->fx[arpeggio].data[1] = MSN(e->fxp);
375 				ck->fx[arpeggio].data[2] = LSN(e->fxp);
376 				ck->fx[arpeggio].value = 0;;
377 				break;
378 			case 0x1:	/* pitchbend up */
379 				fx_enable (ck->fx[pitchbend]);
380 				ck->fx[pitchbend].value = -e->fxp;
381 				break;
382 			case 0x2:	/* pitchbend down */
383 				fx_enable (ck->fx[pitchbend]);
384 				ck->fx[pitchbend].value = e->fxp;
385 				break;
386 			case 0x3:	/* tone portamento */
387 				fx_enable (ck->fx[portamento]);
388 				if (e->note) {
389 					ck->fx[portamento].target =
390 						note_to_period (e->note,
391 						ck->fx[finetune].value);
392 				}
393 				if (e->fxp)
394 					ck->fx[portamento].value = e->fxp;
395 				break;
396 			case 0x4:	/* vibrato */
397 				fx_enable (ck->fx[vibrato]);
398 				if (e->fxp) {
399 					ck->fx[vibrato].vdepth = LSN (e->fxp);
400 					ck->fx[vibrato].vspeed = MSN (e->fxp);
401 				}
402 				break;
403 			case 0x5:	/* portamento + vslide */
404 				fx_enable (ck->fx[portamento]);
405 				fx_enable (ck->fx[vslide]);
406 				if (e->note) {
407 					ck->fx[portamento].target =
408 						note_to_period (e->note,
409 						ck->fx[finetune].value);
410 				}
411 				ck->fx[vslide].value = MSN(e->fxp)-LSN(e->fxp);
412 				break;
413 			case 0x6:	/* vibrato + vslide */
414 				fx_enable (ck->fx[vibrato]);
415 				fx_enable (ck->fx[vslide]);
416 				ck->fx[vslide].value = MSN(e->fxp)-LSN(e->fxp);
417 				break;
418 			case 0x7:	/* tremolo */
419 				fx_enable (ck->fx[tremolo]);
420 				if (e->fxp) {
421 					ck->fx[tremolo].vdepth = LSN (e->fxp);
422 					ck->fx[tremolo].vspeed = MSN (e->fxp);
423 				}
424 				break;
425 			case 0x8:	/* pan setting -- not standard */
426 				/* not implemented */
427 				break;
428 			case 0x9:
429 				ck->sidx = e->fxp << 16;
430 				break;
431 			case 0xa:	/* volume slide */
432 				fx_enable (ck->fx[vslide]);
433 				ck->fx[vslide].value = MSN(e->fxp)-LSN(e->fxp);
434 				break;
435 			case 0xb:	/* pattern jump */
436 				PRIV->jmp = 1;
437 				PRIV->pjump = e->fxp;
438 				break;
439 			case 0xc:	/* volume set */
440 				ck->volume = e->fxp;
441 				break;
442 			case 0xd:	/* pattern break */
443 				PRIV->jmp = 1;
444 				PRIV->pbreak = (e->fxp >> 4) * 10 +
445 					(e->fxp & 0x0f);
446 				break;
447 			case 0xe:	/* extended effect */
448 				fx_enable (ck->fx[extended]);
449 				break;
450 			case 0xf:
451 				if (e->fxp == 0)
452 					break;
453 				if (e->fxp > 0x20)
454 					;//mod[slot].bpm = e->fxp;
455 				else
456 					mod[slot].speed = e->fxp;
457 				break;
458 			}
459 
460 			if (!fx_test (ck->fx[extended]))
461 				goto skip_extended;
462 
463 			/*
464 			 * extended effects
465 			 */
466 
467 			fxp = e->fxp & 0xf;
468 
469 			switch (e->fxp >> 4) {
470 			case 0x0:	/* filter on/off */
471 				/* not implemented */
472 				break;
473 			case 0x1:	/* fine portamento up */
474 				fx_enable (ck->fx[fineporta]);
475 				ck->fx[fineporta].value = -fxp;
476 				break;
477 			case 0x2:	/* fine portamento down */
478 				fx_enable (ck->fx[fineporta]);
479 				ck->fx[fineporta].value = fxp;
480 				break;
481 			case 0x3:	/* glissando */
482 				break;
483 			case 0x4:	/* vibrato waveform */
484 				PRIV->vibrato_wf = fxp;
485 				break;
486 			case 0x5:	/* set finetune */
487 				ck->fx[finetune].value = (uint8)(fxp << 4);
488 				break;
489 			case 0x6:	/* pattern loop */
490 				if (fxp == 0) {
491 					ck->fx[loop].data[0] = mod[slot].row;
492 					break;
493 				}
494 
495 				if (ck->fx[loop].value == 0) {
496 					ck->fx[loop].value = fxp;
497 				} else {
498 					ck->fx[loop].value--;
499 					if (ck->fx[loop].value == 0)
500 						break;
501 				}
502 
503 				PRIV->jmp = 1;
504 				PRIV->pjump = mod[slot].order;
505 				PRIV->pbreak = ck->fx[loop].data[0];
506 				break;
507 			case 0x7:	/* tremolo waveform */
508 				PRIV->tremolo_wf = fxp;
509 				break;
510 			case 0x8:	/* */
511 				break;
512 			case 0x9:	/* note retrig */
513 				fx_enable (ck->fx[retrig]);
514 				ck->fx[retrig].value = fxp;
515 				ck->fx[retrig].data[0] = 1;
516 				ck->fx[retrig].data[1] = 1;
517 				ck->fx[retrig].data[2] = ck->volume;
518 				break;
519 			case 0xa:	/* fine volslide up */
520 				fx_enable (ck->fx[finevol]);
521 				ck->fx[finevol].value = fxp;
522 				break;
523 			case 0xb:	/* fine volslide down */
524 				fx_enable (ck->fx[finevol]);
525 				ck->fx[finevol].value = -fxp;
526 				break;
527 			case 0xc:	/* note cut */
528 				fx_enable (ck->fx[retrig]);
529 				ck->fx[retrig].value = fxp;
530 				ck->fx[retrig].data[0] = 1;
531 				ck->fx[retrig].data[1] = 0;
532 				ck->fx[retrig].data[2] = ck->volume;
533 				break;
534 			case 0xd:	/* note delay */
535 				fx_enable (ck->fx[retrig]);
536 				ck->fx[retrig].value = fxp;
537 				ck->fx[retrig].data[0] = 0;
538 				ck->fx[retrig].data[1] = 1;
539 				ck->fx[retrig].data[2] = ck->volume;
540 				break;
541 			case 0xe:	/* pattern delay */
542 				ck->fx[pdelay].value = fxp;
543 				break;
544 			case 0xf:	/* not defined */
545 				break;
546 			}
547 
548 			/*
549 			 * "fine" effect processing
550 			 */
551 
552 			if (fx_test (ck->fx[finevol]))
553 				ck->volume += ck->fx[finevol].value;
554 
555 			if (fx_test (ck->fx[fineporta]))
556 				ck->period += ck->fx[fineporta].value;
557 
558 			/*
559 			 * Retrig (cut, delay) processing
560 			 */
561 			if (fx_test (ck->fx[retrig])) {
562 				ck->volume = ck->fx[retrig].data[0] *
563 					ck->fx[retrig].data[2];
564 			}
565 
566 skip_extended:
567 			while (0) {};
568 		} else {
569 			/*
570 			 * In the rest of the frames we slide volume, pitch,
571 			 * etc. as set in the first frame of the row.
572 			 */
573 
574 			if (fx_test (ck->fx[vslide]))
575 				ck->volume += ck->fx[vslide].value;
576 
577 			if (fx_test (ck->fx[pitchbend]))
578 				ck->period += ck->fx[pitchbend].value;
579 
580 			if (fx_test (ck->fx[portamento])) {
581 				if (abs (ck->fx[portamento].target - ck->period)
582 					< abs (ck->fx[portamento].value)) {
583 					ck->period = ck->fx[portamento].target;
584 					fx_disable (ck->fx[portamento]);
585 				} else {
586 					ck->period += (ck->fx[portamento].target
587 						> ck->period ? 1 : -1) *
588 						ck->fx[portamento].value;
589 				}
590 			}
591 		}
592 
593 		/*
594 		 * Arpeggio, vibrato and tremolo are processed in all frames.
595 		 * We also handle retrig events here.
596 		 */
597 
598 		if (fx_test (ck->fx[arpeggio])) {
599 			ck->period = note_to_period (ck->note +
600 				ck->fx[arpeggio].data[ck->fx[arpeggio].value++],
601 				ck->fx[finetune].value);
602 			ck->fx[arpeggio].value %= 3;
603 		}
604 
605 		if (fx_test (ck->fx[vibrato])) {
606 			ck->fx[vibrato].vphase %= 64;
607 			ck->dperiod = (waveform[PRIV->vibrato_wf]
608 				[ck->fx[vibrato].vphase] *
609 				ck->fx[vibrato].vdepth) >> 9;
610 			ck->fx[vibrato].vphase += ck->fx[vibrato].vspeed;
611 		}
612 
613 		if (fx_test (ck->fx[tremolo])) {
614 			ck->fx[tremolo].vphase %= 64;
615 			ck->dvolume = (waveform[PRIV->tremolo_wf]
616 				[ck->fx[tremolo].vphase] *
617 				ck->fx[tremolo].vdepth) >> 9;
618 			ck->fx[tremolo].vphase += ck->fx[tremolo].vspeed;
619 		}
620 
621 		if (fx_test (ck->fx[retrig])) {
622 			if (ck->fx[retrig].value == 0) {
623 				ck->sidx = 0;
624 				ck->volume = ck->fx[retrig].data[1] *
625 					ck->fx[retrig].data[2];
626 				fx_disable (ck->fx[retrig]);
627 			} else {
628 				ck->fx[retrig].value--;
629 			}
630 		}
631 
632 		/*
633 		 * Volume and period clipping
634 		 */
635 
636 		if (ck->volume > 64)
637 			ck->volume = 64;
638 		if (ck->volume < 0)
639 			ck->volume = 0;
640 
641 		if (ck->period < MIN_PERIOD_A)
642 			ck->period = MIN_PERIOD_A;
643 		else if (ck->period > MAX_PERIOD_A)
644 			ck->period = MAX_PERIOD_A;
645 	}
646 
647 	/*
648 	 * Update xmp variables
649 	 */
650 
651 	mod[slot].frame++;
652 
653 	if (mod[slot].frame < mod[slot].speed)
654 		return 0;
655 
656 	mod[slot].frame = 0;
657 	mod[slot].row++;
658 
659 	//cond_signal (XMP_WAIT_ROW);
660 
661 	if (!PRIV->jmp && mod[slot].row < 64)
662 		return 0;
663 
664 	mod[slot].row = PRIV->pbreak;
665 	mod[slot].order = PRIV->pjump;
666 
667 	//cond_signal (XMP_WAIT_ORD);
668 
669 	if (mod[slot].order < mod[slot].header->len)
670 		return 0;
671 
672 	//mod[slot].loop++;
673 	mod[slot].order = 0;
674 	//cond_signal (XMP_WAIT_LOOP);
675 
676 	return 0;
677 }
678 
play_thread(void * arg)679 static void *play_thread (void *arg)
680 {
681 	while (mod[slot].playing) {
682 		mod_play_frame ();
683 		mix_sound ();
684 		snddev->dump_buffer ();
685 	}
686 
687 	pthread_exit (NULL);
688 	return NULL;
689 }
690 
691 
sound_switch()692 void sound_switch ()
693 {
694 	slot ^= 1;
695 	dbg ("Switching to sound slot %d", slot);
696 }
697 
sound_select(int s)698 void sound_select (int s)
699 {
700 	dbg ("Selecting sound %d (slot %d)", s, slot);
701 
702 	mod[slot].order = s;
703 	mod[slot].row = 0;
704 	mod[slot].frame = 0;
705 	mod[slot].playing = 1;
706 }
707 
sound_start()708 void sound_start ()
709 {
710 	dbg ("Starting sound (slot %d)", slot);
711 
712 	if (!mod[slot].enabled)
713 		return;
714 
715 	if (mod_ptr[slot] == NULL)
716 		return;
717 
718 	dbg ("Creating sound thread");
719 	pthread_create (&thread, NULL, play_thread, NULL);
720 	pthread_detach (thread);
721 }
722 
sound_stop()723 void sound_stop ()
724 {
725 	dbg ("Stopping sound (slot %d)", slot);
726 	mod[slot].playing = 0;
727 }
728 
sound_load(char * m)729 int sound_load (char *m)
730 {
731 	FILE *f;
732 	struct stat st;
733 	int slot2 = slot ^ 1;	/* Work on the inactive slot */
734 
735 	dbg ("Loading %s in slot %d", m, slot2);
736 
737 	mod[slot2].enabled = 0;
738 	if (chdir("sounds") < 0) {
739 		fprintf(stderr, "can't go to sounds directory from %s...",
740 			getcwd(NULL, -1));
741 		return -1;
742 	}
743 
744 	f = fopen (m, "r");
745 	if (f == NULL) {
746 		chdir("..");
747 		fprintf(stderr, "can't load file...");
748 		return -1;
749 	}
750 
751 	fstat (fileno (f), &st);
752 
753 	if (mod_ptr[slot2] != NULL)
754 		free (mod_ptr[slot2]);
755 	mod_ptr[slot2] = malloc (st.st_size);
756 	fread (mod_ptr[slot2], 1, st.st_size, f);
757 
758 	mod_convert (mod_ptr[slot2], slot2);
759 	mod[slot2].speed = 6;
760 	mod[slot2].enabled = 1;
761 
762 	chdir("..");
763 	return 0;
764 }
765 
sound_play(int s,int n,int v)766 void sound_play (int s, int n, int v)
767 {
768 	pthread_mutex_lock (&frame_mtx);
769 
770 	channel[NUM_CH].note = n;
771 	channel[NUM_CH].period = note_to_period (n, 0);
772 	channel[NUM_CH].volume = v < 0 ? (mod[slot].header ?
773 		mod[slot].header->ins[s].volume : 0) : v;
774 	channel[NUM_CH].sample = s;
775 	channel[NUM_CH].sidx = 0;
776 
777 	pthread_mutex_unlock (&frame_mtx);
778 }
779 
sound_init()780 int sound_init ()
781 {
782 	dbg ("Initializing sound");
783 	snd_buffer = malloc (BUFFER_SIZE * sizeof (int16));
784 
785 	if (sound_oss.init () == 0) {
786 		snddev = &sound_oss;
787 		return 0;
788 	}
789 	snddev = &sound_dummy;
790 	return 0;
791 }
792 
sound_playing()793 int sound_playing ()
794 {
795 	return mod[slot].playing;
796 }
797 
sound_deinit()798 void sound_deinit ()
799 {
800 	dbg ("Deinitializing sound");
801 	sound_unload ();
802 	snddev->deinit ();
803 	free (snd_buffer);
804 }
805 
sound_volume(int i)806 void sound_volume (int i)
807 {
808 	mod[slot].volume = i;
809 }
810 
sound_unload()811 void sound_unload ()
812 {
813 	dbg ("Unloading mod in slot %d", slot);
814 	mod[slot].enabled = 0;
815 	sound_stop ();
816 	pthread_join (thread, NULL);
817 	free (mod_ptr[slot]);
818 	mod_ptr[slot] = NULL;
819 }
820 
sound_changevol(int i)821 void sound_changevol (int i)
822 {
823 	mod[slot].volume += i;
824 	if (mod[slot].volume < 0)
825 		mod[slot].volume = 0;
826 	if (mod[slot].volume > 64)
827 		mod[slot].volume = 64;
828 }
829