1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 * By Shawn Hargreaves,
11 * 1 Salisbury Road,
12 * Market Drayton,
13 * Shropshire,
14 * England, TF9 1AJ.
15 *
16 * Sound setup routines and API framework functions.
17 *
18 * See readme.txt for copyright information.
19 */
20
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <dir.h>
28
29 #ifdef DJGPP
30 #include <go32.h>
31 #include <sys/farptr.h>
32 #endif
33
34 #include "allegro.h"
35 #include "internal.h"
36
37
38
39 /* dummy functions for the nosound drivers */
_dummy_detect()40 int _dummy_detect() { return TRUE; }
_dummy_init(int voices)41 int _dummy_init(int voices) { return 0; }
_dummy_exit()42 void _dummy_exit() { }
_dummy_mixer_volume(int volume)43 int _dummy_mixer_volume(int volume) { return 0; }
_dummy_init_voice(int voice,SAMPLE * sample)44 void _dummy_init_voice(int voice, SAMPLE *sample) { }
_dummy_noop1(int p)45 void _dummy_noop1(int p) { }
_dummy_noop2(int p1,int p2)46 void _dummy_noop2(int p1, int p2) { }
_dummy_noop3(int p1,int p2,int p3)47 void _dummy_noop3(int p1, int p2, int p3) { }
_dummy_get_position(int voice)48 int _dummy_get_position(int voice) { return -1; }
_dummy_get(int voice)49 int _dummy_get(int voice) { return 0; }
_dummy_raw_midi(unsigned char data)50 void _dummy_raw_midi(unsigned char data) { }
_dummy_load_patches(char * patches,char * drums)51 int _dummy_load_patches(char *patches, char *drums) { return 0; }
_dummy_adjust_patches(char * patches,char * drums)52 void _dummy_adjust_patches(char *patches, char *drums) { }
_dummy_key_on(int inst,int note,int bend,int vol,int pan)53 void _dummy_key_on(int inst, int note, int bend, int vol, int pan) { }
54
55 /* put this after all the dummy functions, so they will all get locked */
56 END_OF_FUNCTION(_dummy_detect);
57
58
59
60 DIGI_DRIVER digi_none =
61 {
62 "No sound", "The sound of silence",
63 0, 0, 0xFFFF, 0,
64 _dummy_detect,
65 _dummy_init,
66 _dummy_exit,
67 _dummy_mixer_volume,
68 _dummy_init_voice,
69 _dummy_noop1,
70 _dummy_noop1,
71 _dummy_noop1,
72 _dummy_noop2,
73 _dummy_get_position,
74 _dummy_noop2,
75 _dummy_get,
76 _dummy_noop2,
77 _dummy_noop3,
78 _dummy_noop1,
79 _dummy_get,
80 _dummy_noop2,
81 _dummy_noop3,
82 _dummy_noop1,
83 _dummy_get,
84 _dummy_noop2,
85 _dummy_noop3,
86 _dummy_noop1,
87 _dummy_noop3,
88 _dummy_noop3,
89 _dummy_noop3
90 };
91
92
93 MIDI_DRIVER midi_none =
94 {
95 "No sound", "The sound of silence",
96 0, 0, 0xFFFF, 0, -1, -1,
97 _dummy_detect,
98 _dummy_init,
99 _dummy_exit,
100 _dummy_mixer_volume,
101 _dummy_raw_midi,
102 _dummy_load_patches,
103 _dummy_adjust_patches,
104 _dummy_key_on,
105 _dummy_noop1,
106 _dummy_noop2,
107 _dummy_noop3,
108 _dummy_noop2,
109 _dummy_noop2
110 };
111
112
113 int digi_card = DIGI_AUTODETECT; /* current driver ID numbers */
114 int midi_card = MIDI_AUTODETECT;
115
116 DIGI_DRIVER *digi_driver = &digi_none; /* these things do all the work */
117 MIDI_DRIVER *midi_driver = &midi_none;
118
119 static int sound_installed = FALSE; /* are we installed? */
120
121 static int digi_reserve = -1; /* how many voices to reserve */
122 static int midi_reserve = -1;
123
124 VOICE _voice[VIRTUAL_VOICES]; /* list of active samples */
125
126 PHYS_VOICE _phys_voice[DIGI_VOICES]; /* physical -> virtual voice map */
127
128 int _digi_volume = -1; /* current volume settings */
129 int _midi_volume = -1;
130
131 int _flip_pan = FALSE; /* reverse l/r sample panning? */
132
133 int _sb_freq = -1; /* hardware parameters */
134 int _sb_port = -1;
135 int _sb_dma = -1;
136 int _sb_irq = -1;
137 int _fm_port = -1;
138 int _mpu_port = -1;
139
140 #define SWEEP_FREQ 50
141
142 static void update_sweeps();
143 static void sound_lock_mem();
144
145 int (*_midi_init)() = NULL;
146 void (*_midi_exit)() = NULL;
147
148
149
150 /* read_sound_config:
151 * Helper for reading the sound hardware configuration data.
152 */
read_sound_config()153 static void read_sound_config()
154 {
155 _flip_pan = get_config_int("sound", "flip_pan", FALSE);
156 _sb_port = get_config_hex("sound", "sb_port", -1);
157 _sb_dma = get_config_int("sound", "sb_dma", -1);
158 _sb_irq = get_config_int("sound", "sb_irq", -1);
159 _sb_freq = get_config_int("sound", "sb_freq", -1);
160 _fm_port = get_config_hex("sound", "fm_port", -1);
161 _mpu_port = get_config_hex("sound", "mpu_port", -1);
162 _digi_volume = get_config_int("sound", "digi_volume", -1);
163 _midi_volume = get_config_int("sound", "midi_volume", -1);
164 }
165
166
167
168 /* detect_digi_driver:
169 * Detects whether the specified digital sound driver is available,
170 * returning the maximum number of voices that it can provide, or
171 * zero if the device is not present. This function must be called
172 * _before_ install_sound().
173 */
detect_digi_driver(int driver_id)174 int detect_digi_driver(int driver_id)
175 {
176 int i;
177
178 if (sound_installed)
179 return 0;
180
181 read_sound_config();
182
183 for (i=0; _digi_driver_list[i].driver_id; i++) {
184 if (_digi_driver_list[i].driver_id == driver_id) {
185 digi_card = driver_id;
186 midi_card = MIDI_AUTODETECT;
187 if (_digi_driver_list[i].driver->detect())
188 return _digi_driver_list[i].driver->max_voices;
189 else
190 return 0;
191 }
192 }
193
194 return digi_none.max_voices;
195 }
196
197
198
199 /* detect_midi_driver:
200 * Detects whether the specified midi sound driver is available,
201 * returning the maximum number of voices that it can provide, or
202 * zero if the device is not present. If this routine returns -1,
203 * it is a note-stealing MIDI driver, which shares voices with the
204 * current digital driver. In this situation you can use the
205 * reserve_voices() function to specify how the available voices are
206 * divided between the digital and MIDI playback routines. This function
207 * must be called _before_ install_sound().
208 */
detect_midi_driver(int driver_id)209 int detect_midi_driver(int driver_id)
210 {
211 int i;
212
213 if (sound_installed)
214 return 0;
215
216 read_sound_config();
217
218 for (i=0; _midi_driver_list[i].driver_id; i++) {
219 if (_midi_driver_list[i].driver_id == driver_id) {
220 digi_card = DIGI_AUTODETECT;
221 midi_card = driver_id;
222 if (_midi_driver_list[i].driver->detect())
223 return _midi_driver_list[i].driver->max_voices;
224 else
225 return 0;
226 }
227 }
228
229 return midi_none.max_voices;
230 }
231
232
233
234 /* reserve_voices:
235 * Reserves a number of voices for the digital and MIDI sound drivers
236 * respectively. This must be called _before_ install_sound(). If you
237 * attempt to reserve too many voices, subsequent calls to install_sound()
238 * will fail. Note that depending on the driver you may actually get
239 * more voices than you reserve: these values just specify the minimum
240 * that is appropriate for your application. Pass a negative reserve value
241 * to use the default settings.
242 */
reserve_voices(int digi_voices,int midi_voices)243 void reserve_voices(int digi_voices, int midi_voices)
244 {
245 digi_reserve = digi_voices;
246 midi_reserve = midi_voices;
247 }
248
249
250
251 /* install_sound:
252 * Initialises the sound module, returning zero on success. The two card
253 * parameters should use the DIGI_* and MIDI_* constants defined in
254 * allegro.h. Pass DIGI_AUTODETECT and MIDI_AUTODETECT if you don't know
255 * what the soundcard is.
256 */
install_sound(int digi,int midi,char * cfg_path)257 int install_sound(int digi, int midi, char *cfg_path)
258 {
259 int digi_voices, midi_voices;
260 int c;
261
262 if (sound_installed)
263 return 0;
264
265 for (c=0; c<VIRTUAL_VOICES; c++) {
266 _voice[c].sample = NULL;
267 _voice[c].num = -1;
268 }
269
270 for (c=0; c<DIGI_VOICES; c++)
271 _phys_voice[c].num = -1;
272
273 /* initialise the midi file player */
274 if (_midi_init)
275 if (_midi_init() != 0)
276 return -1;
277
278 /* register_datafile_object(DAT_SAMPLE, NULL, (void (*)(void *))destroy_sample);*/
279
280 digi_card = digi;
281 midi_card = midi;
282
283 /* read config information */
284 if (digi_card == DIGI_AUTODETECT)
285 digi_card = get_config_int("sound", "digi_card", DIGI_AUTODETECT);
286
287 if (midi_card == MIDI_AUTODETECT)
288 midi_card = get_config_int("sound", "midi_card", MIDI_AUTODETECT);
289
290 if (digi_reserve < 0)
291 digi_reserve = get_config_int("sound", "digi_voices", -1);
292
293 if (midi_reserve < 0)
294 midi_reserve = get_config_int("sound", "midi_voices", -1);
295
296 read_sound_config();
297
298 sound_lock_mem();
299 _dma_lock_mem();
300
301 digi_driver = NULL;
302
303 /* search table for a specific digital driver */
304 for (c=0; _digi_driver_list[c].driver; c++) {
305 if (_digi_driver_list[c].driver_id == digi_card) {
306 digi_driver = _digi_driver_list[c].driver;
307 if (!digi_driver->detect()) {
308 digi_driver = &digi_none;
309 if (_midi_exit)
310 _midi_exit();
311 return -1;
312 }
313 break;
314 }
315 }
316
317 /* autodetect digital driver */
318 if (!digi_driver) {
319 for (c=0; _digi_driver_list[c].driver; c++) {
320 digi_card = _digi_driver_list[c].driver_id;
321 if ((_digi_driver_list[c].autodetect) &&
322 (_digi_driver_list[c].driver->detect())) {
323 digi_driver = _digi_driver_list[c].driver;
324 break;
325 }
326 }
327 }
328
329 midi_driver = NULL;
330
331 /* search table for a specific MIDI driver */
332 for (c=0; _midi_driver_list[c].driver; c++) {
333 if (_midi_driver_list[c].driver_id == midi_card) {
334 midi_driver = _midi_driver_list[c].driver;
335 if (!midi_driver->detect()) {
336 digi_driver = &digi_none;
337 midi_driver = &midi_none;
338 if (_midi_exit)
339 _midi_exit();
340 return -1;
341 }
342 break;
343 }
344 }
345
346 /* autodetect MIDI driver */
347 if (!midi_driver) {
348 for (c=0; _midi_driver_list[c].driver; c++) {
349 midi_card = _midi_driver_list[c].driver_id;
350 if ((_midi_driver_list[c].autodetect) &&
351 (_midi_driver_list[c].driver->detect())) {
352 midi_driver = _midi_driver_list[c].driver;
353 break;
354 }
355 }
356 }
357
358 /* work out how many voices to allocate for each driver */
359 if (digi_reserve >= 0)
360 digi_voices = digi_reserve;
361 else
362 digi_voices = digi_driver->def_voices;
363
364 if (midi_driver->max_voices < 0) {
365 /* MIDI driver steals voices from the digital player */
366 if (midi_reserve >= 0)
367 midi_voices = midi_reserve;
368 else
369 midi_voices = MID(0, digi_driver->max_voices - digi_voices, midi_driver->def_voices);
370
371 digi_voices += midi_voices;
372 }
373 else {
374 /* MIDI driver has voices of its own */
375 if (midi_reserve >= 0)
376 midi_voices = midi_reserve;
377 else
378 midi_voices = midi_driver->def_voices;
379 }
380
381 /* make sure this is a reasonable number of voices to use */
382 if ((digi_voices > DIGI_VOICES) || (midi_voices > MIDI_VOICES)) {
383 sprintf(allegro_error, "Insufficient %s voices available",
384 (digi_voices > DIGI_VOICES) ? "digital" : "MIDI");
385 digi_driver = &digi_none;
386 midi_driver = &midi_none;
387 if (_midi_exit)
388 _midi_exit();
389 return -1;
390 }
391
392 /* initialise the digital sound driver */
393 if (digi_driver->init(digi_voices) != 0) {
394 digi_driver = &digi_none;
395 midi_driver = &midi_none;
396 if (_midi_exit)
397 _midi_exit();
398 return -1;
399 }
400
401 /* initialise the midi driver */
402 if (midi_driver->init(midi_voices) != 0) {
403 digi_driver->exit();
404 digi_driver = &digi_none;
405 midi_driver = &midi_none;
406 if (_midi_exit)
407 _midi_exit();
408 return -1;
409 }
410
411 digi_driver->voices = MIN(digi_driver->voices, DIGI_VOICES);
412 midi_driver->voices = MIN(midi_driver->voices, MIDI_VOICES);
413
414 /* check that we actually got enough voices */
415 if ((digi_driver->voices < digi_voices) ||
416 ((midi_driver->voices < midi_voices) && (!midi_driver->raw_midi))) {
417 sprintf(allegro_error, "Insufficient %s voices available",
418 (digi_driver->voices < digi_voices) ? "digital" : "MIDI");
419 midi_driver->exit();
420 digi_driver->exit();
421 digi_driver = &digi_none;
422 midi_driver = &midi_none;
423 if (_midi_exit)
424 _midi_exit();
425 return -1;
426 }
427
428 /* adjust for note-stealing MIDI drivers */
429 if (midi_driver->max_voices < 0) {
430 midi_voices += (digi_driver->voices - digi_voices) * 3/4;
431 digi_driver->voices -= midi_voices;
432 midi_driver->basevoice = VIRTUAL_VOICES - midi_voices;
433 midi_driver->voices = midi_voices;
434
435 for (c=0; c<midi_voices; c++) {
436 _voice[midi_driver->basevoice+c].num = digi_driver->voices+c;
437 _phys_voice[digi_driver->voices+c].num = midi_driver->basevoice+c;
438 }
439 }
440
441 /* simulate ramp/sweep effects for drivers that don't do it directly */
442 if ((!digi_driver->ramp_volume) ||
443 (!digi_driver->sweep_frequency) ||
444 (!digi_driver->sweep_pan))
445 install_int_ex(update_sweeps, BPS_TO_TIMER(SWEEP_FREQ));
446
447 /* set the global sound volume */
448 if ((_digi_volume >= 0) || (_midi_volume >= 0))
449 set_volume(_digi_volume, _midi_volume);
450
451 _add_exit_func(remove_sound);
452 sound_installed = TRUE;
453 return 0;
454 }
455
456
457
458 /* remove_sound:
459 * Sound module cleanup routine.
460 */
remove_sound()461 void remove_sound()
462 {
463 int c;
464
465 if (sound_installed) {
466 remove_int(update_sweeps);
467
468 for (c=0; c<VIRTUAL_VOICES; c++)
469 if (_voice[c].sample)
470 deallocate_voice(c);
471
472 if (_midi_exit)
473 _midi_exit();
474
475 midi_driver->exit();
476 midi_driver = &midi_none;
477
478 digi_driver->exit();
479 digi_driver = &digi_none;
480
481 _remove_exit_func(remove_sound);
482 sound_installed = FALSE;
483 }
484 }
485
486
487
488 /* set_volume:
489 * Alters the global sound output volume. Specify volumes for both digital
490 * samples and MIDI playback, as integers from 0 to 255. If possible this
491 * routine will use a hardware mixer to control the volume, otherwise it
492 * will tell the sample mixer and MIDI player to simulate a mixer in
493 * software.
494 */
set_volume(int digi_volume,int midi_volume)495 void set_volume(int digi_volume, int midi_volume)
496 {
497 if (digi_volume >= 0) {
498 digi_volume = MID(0, digi_volume, 255);
499
500 if ((digi_driver->mixer_volume) &&
501 (digi_driver->mixer_volume(digi_volume) == 0))
502 _digi_volume = -1;
503 else
504 _digi_volume = digi_volume;
505 }
506
507 if (midi_volume >= 0) {
508 midi_volume = MID(0, midi_volume, 255);
509
510 if ((midi_driver->mixer_volume) &&
511 (midi_driver->mixer_volume(midi_volume) == 0))
512 _midi_volume = -1;
513 else
514 _midi_volume = midi_volume;
515 }
516 }
517
518
519
520 /* lock_sample:
521 * Locks a SAMPLE struct into physical memory. Pretty important, since
522 * they are mostly accessed inside interrupt handlers.
523 */
lock_sample(SAMPLE * spl)524 void lock_sample(SAMPLE *spl)
525 {
526 #ifdef DJGPP
527 _go32_dpmi_lock_data(spl, sizeof(SAMPLE));
528 _go32_dpmi_lock_data(spl->data, spl->len*spl->bits/8);
529 #endif
530 }
531
532
533
534 /* load_sample:
535 * Loads a sample from disk.
536 */
load_sample(char * filename)537 SAMPLE *load_sample(char *filename)
538 {
539 if (stricmp(get_extension(filename), "wav") == 0)
540 return load_wav(filename);
541 else if (stricmp(get_extension(filename), "voc") == 0)
542 return load_voc(filename);
543 else
544 return NULL;
545 }
546
547
548
549 /* load_voc:
550 * Reads a mono 8 bit VOC format sample file, returning a SAMPLE structure,
551 * or NULL on error.
552 */
load_voc(char * filename)553 SAMPLE *load_voc(char *filename)
554 {
555 PACKFILE *f;
556 char buffer[30];
557 int freq = 22050;
558 int bits = 8;
559 SAMPLE *spl = NULL;
560 int len;
561 int x;
562
563 f = pack_fopen(filename, F_READ);
564 if (!f)
565 return NULL;
566
567 pack_fread(buffer, 0x16, f);
568
569 if (memcmp(buffer, "Creative Voice File", 0x13))
570 goto getout;
571
572 if (pack_igetw(f) != 0x010A) /* version: should be 0x010A */
573 goto getout;
574
575 if (pack_igetw(f) != 0x1129) /* subversion: should be 0x1129 */
576 goto getout;
577
578 if (pack_getc(f) != 0x01) /* sound data: should be 0x01 */
579 goto getout;
580
581 len = pack_igetw(f); /* length is three bytes long: two */
582 x = pack_getc(f); /* .. and one byte */
583 x <<= 16;
584 len += x-2;
585
586 x = pack_getc(f); /* one byte of frequency */
587 freq = 1000000 / (256-x);
588
589 x = pack_getc(f); /* skip one byte */
590
591 spl = malloc(sizeof(SAMPLE));
592
593 if (spl) {
594 spl->bits = bits;
595 spl->freq = freq;
596 spl->len = len;
597 spl->priority = 255;
598 spl->loop_start = 0;
599 spl->loop_end = len;
600 spl->param = -1;
601
602 spl->data = malloc(len);
603 if (!spl->data) {
604 free(spl);
605 spl = NULL;
606 }
607 else {
608 pack_fread(spl->data, len, f);
609 if (errno) {
610 free(spl->data);
611 free(spl);
612 spl = NULL;
613 }
614 }
615 }
616
617 getout:
618
619 pack_fclose(f);
620
621 if (spl)
622 lock_sample(spl);
623
624 return spl;
625 }
626
627
628
629 /* load_wav:
630 * Reads a mono RIFF WAV format sample file, returning a SAMPLE structure,
631 * or NULL on error.
632 */
load_wav(char * filename)633 SAMPLE *load_wav(char *filename)
634 {
635 int trashtmp;
636 PACKFILE *f;
637 char buffer[25];
638 int i;
639 int length, len;
640 int freq = 22050;
641 int bits = 8;
642 signed short s;
643 SAMPLE *spl = NULL;
644
645 f = pack_fopen(filename, F_READ);
646 if (!f)
647 return NULL;
648
649 pack_fread(buffer, 12, f); /* check RIFF header */
650 if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4))
651 goto getout;
652
653 while (!pack_feof(f)) {
654 if (pack_fread(buffer, 4, f) != 4)
655 break;
656
657 length = pack_igetl(f); /* read chunk length */
658
659 if (memcmp(buffer, "fmt ", 4) == 0) {
660 i = pack_igetw(f); /* should be 1 for PCM data */
661 length -= 2;
662 if (i != 1)
663 goto getout;
664
665 i = pack_igetw(f); /* should be 1 for mono data */
666 length -= 2;
667 if (i != 1)
668 goto getout;
669
670 freq = pack_igetl(f); /* sample frequency */
671 length -= 4;
672
673 trashtmp=pack_igetl(f); /* skip six bytes */
674 trashtmp=pack_igetw(f);
675 length -= 6;
676
677 bits = pack_igetw(f); /* 8 or 16 bit data? */
678 length -= 2;
679 if ((bits != 8) && (bits != 16))
680 goto getout;
681 }
682 else if (memcmp(buffer, "data", 4) == 0) {
683 len = length;
684 if (bits == 16)
685 len /= 2;
686
687 spl = malloc(sizeof(SAMPLE));
688
689 if (spl) { /* initialise the sample struct */
690 spl->bits = bits;
691 spl->freq = freq;
692 spl->len = len;
693 spl->priority = 255;
694 spl->loop_start = 0;
695 spl->loop_end = len;
696 spl->param = -1;
697
698 spl->data = malloc(length);
699
700 if (!spl->data) {
701 free(spl);
702 spl = NULL;
703 }
704 else { /* read the actual sample data */
705 if (bits == 8) {
706 pack_fread(spl->data, length, f);
707 }
708 else {
709 for (i=0; i<len; i++) {
710 s = pack_igetw(f);
711 ((signed short *)spl->data)[i] = s^0x8000;
712 }
713 }
714
715 length -= len;
716
717 if (errno) {
718 free(spl->data);
719 free(spl);
720 spl = NULL;
721 }
722 }
723 }
724 }
725
726 while (length > 0) { /* skip the remainder of the chunk */
727 if (pack_getc(f) == EOF)
728 break;
729
730 length--;
731 }
732 }
733
734 getout:
735
736 pack_fclose(f);
737
738 if (spl)
739 lock_sample(spl);
740
741 return spl;
742 }
743
744
745
746 /* destroy_sample:
747 * Frees a SAMPLE struct, checking whether the sample is currently playing,
748 * and stopping it if it is.
749 */
destroy_sample(SAMPLE * spl)750 void destroy_sample(SAMPLE *spl)
751 {
752 if (spl) {
753 stop_sample(spl);
754
755 if (spl->data) {
756 _unlock_dpmi_data(spl->data, spl->len*spl->bits/8);
757 free(spl->data);
758 }
759
760 _unlock_dpmi_data(spl, sizeof(SAMPLE));
761 free(spl);
762 }
763 }
764
765
766
767 /* absolute_freq:
768 * Converts a pitch from the relative 1000 = original format to an absolute
769 * value in hz.
770 */
absolute_freq(int freq,SAMPLE * spl)771 static inline int absolute_freq(int freq, SAMPLE *spl)
772 {
773 if (freq == 1000)
774 return spl->freq;
775 else
776 return (spl->freq * freq) / 1000;
777 }
778
779
780
781 /* play_sample:
782 * Triggers a sample at the specified volume, pan position, and frequency.
783 * The volume and pan range from 0 (min/left) to 255 (max/right), although
784 * the resolution actually used by the playback routines is likely to be
785 * less than this. Frequency is relative rather than absolute: 1000
786 * represents the frequency that the sample was recorded at, 2000 is
787 * twice this, etc. If loop is true the sample will repeat until you call
788 * stop_sample(), and can be manipulated while it is playing by calling
789 * adjust_sample().
790 */
play_sample(SAMPLE * spl,int vol,int pan,int freq,int loop)791 int play_sample(SAMPLE *spl, int vol, int pan, int freq, int loop)
792 {
793 int voice = allocate_voice(spl);
794
795 if (voice >= 0) {
796 voice_set_volume(voice, vol);
797 voice_set_pan(voice, pan);
798 voice_set_frequency(voice, absolute_freq(freq, spl));
799 voice_set_playmode(voice, (loop ? PLAYMODE_LOOP : PLAYMODE_PLAY));
800 voice_start(voice);
801 release_voice(voice);
802 }
803
804 return voice;
805 }
806
807 END_OF_FUNCTION(play_sample);
808
809
810
811 /* adjust_sample:
812 * Alters the parameters of a sample while it is playing, useful for
813 * manipulating looped sounds. You can alter the volume, pan, and
814 * frequency, and can also remove the looping flag, which will stop
815 * the sample when it next reaches the end of its loop. If there are
816 * several copies of the same sample playing, this will adjust the
817 * first one it comes across. If the sample is not playing it has no
818 * effect.
819 */
adjust_sample(SAMPLE * spl,int vol,int pan,int freq,int loop)820 void adjust_sample(SAMPLE *spl, int vol, int pan, int freq, int loop)
821 {
822 int c;
823
824 for (c=0; c<VIRTUAL_VOICES; c++) {
825 if (_voice[c].sample == spl) {
826 voice_set_volume(c, vol);
827 voice_set_pan(c, pan);
828 voice_set_frequency(c, absolute_freq(freq, spl));
829 voice_set_playmode(c, (loop ? PLAYMODE_LOOP : PLAYMODE_PLAY));
830 return;
831 }
832 }
833 }
834
835 END_OF_FUNCTION(adjust_sample);
836
837
838
839 /* stop_sample:
840 * Kills off a sample, which is required if you have set a sample going
841 * in looped mode. If there are several copies of the sample playing,
842 * it will stop them all.
843 */
stop_sample(SAMPLE * spl)844 void stop_sample(SAMPLE *spl)
845 {
846 int c;
847
848 for (c=0; c<VIRTUAL_VOICES; c++)
849 if (_voice[c].sample == spl)
850 deallocate_voice(c);
851 }
852
853 END_OF_FUNCTION(stop_sample);
854
855
856
857 /* allocate_physical_voice:
858 * Allocates a physical voice, killing off others as required in order
859 * to make room for it.
860 */
allocate_physical_voice(int priority)861 static inline int allocate_physical_voice(int priority)
862 {
863 VOICE *voice;
864 int best = -1;
865 int best_score = 0;
866 int score;
867 int c;
868
869 /* look for a free voice */
870 for (c=0; c<digi_driver->voices; c++)
871 if (_phys_voice[c].num < 0)
872 return c;
873
874 /* look for an autokill voice that has stopped */
875 for (c=0; c<digi_driver->voices; c++) {
876 voice = _voice + _phys_voice[c].num;
877 if ((voice->autokill) && (digi_driver->get_position(c) < 0)) {
878 digi_driver->release_voice(c);
879 voice->sample = NULL;
880 voice->num = -1;
881 _phys_voice[c].num = -1;
882 return c;
883 }
884 }
885
886 /* ok, we're going to have to get rid of something to make room... */
887 for (c=0; c<digi_driver->voices; c++) {
888 voice = _voice + _phys_voice[c].num;
889
890 /* sort by voice priorities */
891 if (voice->priority <= priority) {
892 score = 65536 - voice->priority * 256;
893
894 /* bias with a least-recently-used counter */
895 score += MID(0, retrace_count - voice->time, 32768);
896
897 /* bias according to whether the voice is looping or not */
898 if (!(_phys_voice[c].playmode & PLAYMODE_LOOP))
899 score += 32768;
900
901 if (score > best_score) {
902 best = c;
903 best_score = score;
904 }
905 }
906 }
907
908 if (best >= 0) {
909 /* kill off the old voice */
910 digi_driver->stop_voice(best);
911 digi_driver->release_voice(best);
912 _voice[_phys_voice[best].num].num = -1;
913 _phys_voice[best].num = -1;
914 return best;
915 }
916
917 return -1;
918 }
919
920
921
922 /* allocate_virtual_voice:
923 * Allocates a virtual voice. This doesn't need to worry about killing off
924 * others to make room, as we allow up to 256 virtual voices to be used
925 * simultaneously.
926 */
allocate_virtual_voice()927 static inline int allocate_virtual_voice()
928 {
929 int virt_voices, c;
930
931 virt_voices = VIRTUAL_VOICES;
932 if (midi_driver->max_voices < 0)
933 virt_voices -= midi_driver->voices;
934
935 /* look for a free voice */
936 for (c=0; c<virt_voices; c++)
937 if (!_voice[c].sample)
938 return c;
939
940 /* look for a stopped autokill voice */
941 for (c=0; c<virt_voices; c++) {
942 if (_voice[c].autokill) {
943 if (_voice[c].num < 0) {
944 _voice[c].sample = NULL;
945 return c;
946 }
947 else {
948 if (digi_driver->get_position(_voice[c].num) < 0) {
949 digi_driver->release_voice(_voice[c].num);
950 _phys_voice[_voice[c].num].num = -1;
951 _voice[c].sample = NULL;
952 _voice[c].num = -1;
953 return c;
954 }
955 }
956 }
957 }
958
959 return -1;
960 }
961
962
963
964 /* allocate_voice:
965 * Allocates a voice ready for playing the specified sample, returning
966 * the voice number (note this is not the same as the physical voice
967 * number used by the sound drivers, and must only be used with the other
968 * voice functions, _not_ passed directly to the driver routines).
969 * Returns -1 if there is no voice available (this should never happen,
970 * since there are 256 virtual voices and anyone who needs more than that
971 * needs some urgent repairs to their brain :-)
972 */
allocate_voice(SAMPLE * spl)973 int allocate_voice(SAMPLE *spl)
974 {
975 int phys = allocate_physical_voice(spl->priority);
976 int virt = allocate_virtual_voice();
977
978 if (virt >= 0) {
979 _voice[virt].sample = spl;
980 _voice[virt].num = phys;
981 _voice[virt].autokill = FALSE;
982 _voice[virt].time = retrace_count;
983 _voice[virt].priority = spl->priority;
984
985 if (phys >= 0) {
986 _phys_voice[phys].num = virt;
987 _phys_voice[phys].playmode = 0;
988 _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12;
989 _phys_voice[phys].pan = 128 << 12;
990 _phys_voice[phys].freq = spl->freq << 12;
991 _phys_voice[phys].dvol = 0;
992 _phys_voice[phys].dpan = 0;
993 _phys_voice[phys].dfreq = 0;
994
995 digi_driver->init_voice(phys, spl);
996 }
997 }
998
999 return virt;
1000 }
1001
1002 END_OF_FUNCTION(allocate_voice);
1003
1004
1005
1006 /* deallocate_voice:
1007 * Releases a voice that was previously returned by allocate_voice().
1008 */
deallocate_voice(int voice)1009 void deallocate_voice(int voice)
1010 {
1011 if (_voice[voice].num >= 0) {
1012 digi_driver->stop_voice(_voice[voice].num);
1013 digi_driver->release_voice(_voice[voice].num);
1014 _phys_voice[_voice[voice].num].num = -1;
1015 _voice[voice].num = -1;
1016 }
1017
1018 _voice[voice].sample = NULL;
1019 }
1020
1021 END_OF_FUNCTION(deallocate_voice);
1022
1023
1024
1025 /* reallocate_voice:
1026 * Switches an already-allocated voice to use a different sample.
1027 */
reallocate_voice(int voice,SAMPLE * spl)1028 void reallocate_voice(int voice, SAMPLE *spl)
1029 {
1030 int phys = _voice[voice].num;
1031
1032 if (phys >= 0) {
1033 digi_driver->stop_voice(phys);
1034 digi_driver->release_voice(phys);
1035 }
1036
1037 _voice[voice].sample = spl;
1038 _voice[voice].autokill = FALSE;
1039 _voice[voice].time = retrace_count;
1040 _voice[voice].priority = spl->priority;
1041
1042 if (phys >= 0) {
1043 _phys_voice[phys].playmode = 0;
1044 _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12;
1045 _phys_voice[phys].pan = 128 << 12;
1046 _phys_voice[phys].freq = spl->freq << 12;
1047 _phys_voice[phys].dvol = 0;
1048 _phys_voice[phys].dpan = 0;
1049 _phys_voice[phys].dfreq = 0;
1050
1051 digi_driver->init_voice(phys, spl);
1052 }
1053 }
1054
1055 END_OF_FUNCTION(reallocate_voice);
1056
1057
1058
1059 /* release_voice:
1060 * Flags that a voice is no longer going to be updated, so it can
1061 * automatically be freed as soon as the sample finishes playing.
1062 */
release_voice(int voice)1063 void release_voice(int voice)
1064 {
1065 _voice[voice].autokill = TRUE;
1066 }
1067
1068 END_OF_FUNCTION(release_voice);
1069
1070
1071
1072 /* voice_start:
1073 * Starts a voice playing.
1074 */
voice_start(int voice)1075 void voice_start(int voice)
1076 {
1077 if (_voice[voice].num >= 0)
1078 digi_driver->start_voice(_voice[voice].num);
1079
1080 _voice[voice].time = retrace_count;
1081 }
1082
1083 END_OF_FUNCTION(voice_start);
1084
1085
1086
1087 /* voice_stop:
1088 * Stops a voice from playing.
1089 */
voice_stop(int voice)1090 void voice_stop(int voice)
1091 {
1092 if (_voice[voice].num >= 0)
1093 digi_driver->stop_voice(_voice[voice].num);
1094 }
1095
1096 END_OF_FUNCTION(voice_stop);
1097
1098
1099
1100 /* voice_set_priority:
1101 * Adjusts the priority of a voice (0-255).
1102 */
voice_set_priority(int voice,int priority)1103 void voice_set_priority(int voice, int priority)
1104 {
1105 _voice[voice].priority = priority;
1106 }
1107
1108 END_OF_FUNCTION(voice_set_priority);
1109
1110
1111
1112 /* voice_check:
1113 * Checks whether a voice is playing, returning the sample if it is,
1114 * or NULL if it has finished or been preempted by a different sound.
1115 */
voice_check(int voice)1116 SAMPLE *voice_check(int voice)
1117 {
1118 if (_voice[voice].sample) {
1119 if (_voice[voice].num < 0)
1120 return NULL;
1121
1122 if (_voice[voice].autokill)
1123 if (voice_get_position(voice) < 0)
1124 return NULL;
1125
1126 return _voice[voice].sample;
1127 }
1128 else
1129 return NULL;
1130 }
1131
1132 END_OF_FUNCTION(voice_check);
1133
1134
1135
1136 /* voice_get_position:
1137 * Returns the current play position of a voice, or -1 if that cannot
1138 * be determined (because it has finished or been preempted by a
1139 * different sound).
1140 */
voice_get_position(int voice)1141 int voice_get_position(int voice)
1142 {
1143 if (_voice[voice].num >= 0)
1144 return digi_driver->get_position(_voice[voice].num);
1145 else
1146 return -1;
1147 }
1148
1149 END_OF_FUNCTION(voice_get_position);
1150
1151
1152
1153 /* voice_set_position:
1154 * Sets the play position of a voice.
1155 */
voice_set_position(int voice,int position)1156 void voice_set_position(int voice, int position)
1157 {
1158 if (_voice[voice].num >= 0)
1159 digi_driver->set_position(_voice[voice].num, position);
1160 }
1161
1162 END_OF_FUNCTION(voice_set_position);
1163
1164
1165
1166 /* voice_set_playmode:
1167 * Sets the loopmode of a voice.
1168 */
voice_set_playmode(int voice,int playmode)1169 void voice_set_playmode(int voice, int playmode)
1170 {
1171 if (_voice[voice].num >= 0) {
1172 _phys_voice[_voice[voice].num].playmode = playmode;
1173 digi_driver->loop_voice(_voice[voice].num, playmode);
1174
1175 if (playmode & PLAYMODE_BACKWARD)
1176 digi_driver->set_position(_voice[voice].num, _voice[voice].sample->len-1);
1177 }
1178 }
1179
1180 END_OF_FUNCTION(voice_set_playmode);
1181
1182
1183
1184 /* voice_get_volume:
1185 * Returns the current volume of a voice, or -1 if that cannot
1186 * be determined (because it has finished or been preempted by a
1187 * different sound).
1188 */
voice_get_volume(int voice)1189 int voice_get_volume(int voice)
1190 {
1191 int vol;
1192
1193 if (_voice[voice].num >= 0)
1194 vol = digi_driver->get_volume(_voice[voice].num);
1195 else
1196 vol = -1;
1197
1198 if ((vol >= 0) && (_digi_volume >= 0)) {
1199 if (_digi_volume > 0)
1200 vol = MID(0, (vol * 255) / _digi_volume, 255);
1201 else
1202 vol = 0;
1203 }
1204
1205 return vol;
1206 }
1207
1208 END_OF_FUNCTION(voice_get_volume);
1209
1210
1211
1212 /* voice_set_volume:
1213 * Sets the current volume of a voice.
1214 */
voice_set_volume(int voice,int volume)1215 void voice_set_volume(int voice, int volume)
1216 {
1217 if (_digi_volume >= 0)
1218 volume = (volume * _digi_volume) / 255;
1219
1220 if (_voice[voice].num >= 0) {
1221 _phys_voice[_voice[voice].num].vol = volume << 12;
1222 _phys_voice[_voice[voice].num].dvol = 0;
1223
1224 digi_driver->set_volume(_voice[voice].num, volume);
1225 }
1226 }
1227
1228 END_OF_FUNCTION(voice_set_volume);
1229
1230
1231
1232 /* voice_ramp_volume:
1233 * Begins a volume ramp operation.
1234 */
voice_ramp_volume(int voice,int time,int endvol)1235 void voice_ramp_volume(int voice, int time, int endvol)
1236 {
1237 if (_digi_volume >= 0)
1238 endvol = (endvol * _digi_volume) / 255;
1239
1240 if (_voice[voice].num >= 0) {
1241 if (digi_driver->ramp_volume) {
1242 digi_driver->ramp_volume(_voice[voice].num, time, endvol);
1243 }
1244 else {
1245 int d = (endvol << 12) - _phys_voice[_voice[voice].num].vol;
1246 time = MAX(time * SWEEP_FREQ / 1000, 1);
1247 _phys_voice[_voice[voice].num].target_vol = endvol << 12;
1248 _phys_voice[_voice[voice].num].dvol = d / time;
1249 }
1250 }
1251 }
1252
1253 END_OF_FUNCTION(voice_ramp_volume);
1254
1255
1256
1257 /* voice_stop_volumeramp:
1258 * Ends a volume ramp operation.
1259 */
voice_stop_volumeramp(int voice)1260 void voice_stop_volumeramp(int voice)
1261 {
1262 if (_voice[voice].num >= 0) {
1263 _phys_voice[_voice[voice].num].dvol = 0;
1264
1265 if (digi_driver->stop_volume_ramp)
1266 digi_driver->stop_volume_ramp(_voice[voice].num);
1267 }
1268 }
1269
1270 END_OF_FUNCTION(voice_stop_volumeramp);
1271
1272
1273
1274 /* voice_get_frequency:
1275 * Returns the current frequency of a voice, or -1 if that cannot
1276 * be determined (because it has finished or been preempted by a
1277 * different sound).
1278 */
voice_get_frequency(int voice)1279 int voice_get_frequency(int voice)
1280 {
1281 if (_voice[voice].num >= 0)
1282 return digi_driver->get_frequency(_voice[voice].num);
1283 else
1284 return -1;
1285 }
1286
1287 END_OF_FUNCTION(voice_get_frequency);
1288
1289
1290
1291 /* voice_set_frequency:
1292 * Sets the pitch of a voice.
1293 */
voice_set_frequency(int voice,int frequency)1294 void voice_set_frequency(int voice, int frequency)
1295 {
1296 if (_voice[voice].num >= 0) {
1297 _phys_voice[_voice[voice].num].freq = frequency << 12;
1298 _phys_voice[_voice[voice].num].dfreq = 0;
1299
1300 digi_driver->set_frequency(_voice[voice].num, frequency);
1301 }
1302 }
1303
1304 END_OF_FUNCTION(voice_set_frequency);
1305
1306
1307
1308 /* voice_sweep_frequency:
1309 * Begins a frequency sweep (glissando) operation.
1310 */
voice_sweep_frequency(int voice,int time,int endfreq)1311 void voice_sweep_frequency(int voice, int time, int endfreq)
1312 {
1313 if (_voice[voice].num >= 0) {
1314 if (digi_driver->sweep_frequency) {
1315 digi_driver->sweep_frequency(_voice[voice].num, time, endfreq);
1316 }
1317 else {
1318 int d = (endfreq << 12) - _phys_voice[_voice[voice].num].freq;
1319 time = MAX(time * SWEEP_FREQ / 1000, 1);
1320 _phys_voice[_voice[voice].num].target_freq = endfreq << 12;
1321 _phys_voice[_voice[voice].num].dfreq = d / time;
1322 }
1323 }
1324 }
1325
1326 END_OF_FUNCTION(voice_sweep_frequency);
1327
1328
1329
1330 /* voice_stop_frequency_sweep:
1331 * Ends a frequency sweep.
1332 */
voice_stop_frequency_sweep(int voice)1333 void voice_stop_frequency_sweep(int voice)
1334 {
1335 if (_voice[voice].num >= 0) {
1336 _phys_voice[_voice[voice].num].dfreq = 0;
1337
1338 if (digi_driver->stop_frequency_sweep)
1339 digi_driver->stop_frequency_sweep(_voice[voice].num);
1340 }
1341 }
1342
1343 END_OF_FUNCTION(voice_stop_frequency_sweep);
1344
1345
1346
1347 /* voice_get_pan:
1348 * Returns the current pan position of a voice, or -1 if that cannot
1349 * be determined (because it has finished or been preempted by a
1350 * different sound).
1351 */
voice_get_pan(int voice)1352 int voice_get_pan(int voice)
1353 {
1354 int pan;
1355
1356 if (_voice[voice].num >= 0)
1357 pan = digi_driver->get_pan(_voice[voice].num);
1358 else
1359 pan = -1;
1360
1361 if ((pan >= 0) && (_flip_pan))
1362 pan = 255 - pan;
1363
1364 return pan;
1365 }
1366
1367 END_OF_FUNCTION(voice_get_pan);
1368
1369
1370
1371 /* voice_set_pan:
1372 * Sets the pan position of a voice.
1373 */
voice_set_pan(int voice,int pan)1374 void voice_set_pan(int voice, int pan)
1375 {
1376 if (_flip_pan)
1377 pan = 255 - pan;
1378
1379 if (_voice[voice].num >= 0) {
1380 _phys_voice[_voice[voice].num].pan = pan << 12;
1381 _phys_voice[_voice[voice].num].dpan = 0;
1382
1383 digi_driver->set_pan(_voice[voice].num, pan);
1384 }
1385 }
1386
1387 END_OF_FUNCTION(voice_set_pan);
1388
1389
1390
1391 /* voice_sweep_pan:
1392 * Begins a pan sweep (left <-> right movement) operation.
1393 */
voice_sweep_pan(int voice,int time,int endpan)1394 void voice_sweep_pan(int voice, int time, int endpan)
1395 {
1396 if (_flip_pan)
1397 endpan = 255 - endpan;
1398
1399 if (_voice[voice].num >= 0) {
1400 if (digi_driver->sweep_pan) {
1401 digi_driver->sweep_pan(_voice[voice].num, time, endpan);
1402 }
1403 else {
1404 int d = (endpan << 12) - _phys_voice[_voice[voice].num].pan;
1405 time = MAX(time * SWEEP_FREQ / 1000, 1);
1406 _phys_voice[_voice[voice].num].target_pan = endpan << 12;
1407 _phys_voice[_voice[voice].num].dpan = d / time;
1408 }
1409 }
1410 }
1411
1412 END_OF_FUNCTION(voice_sweep_pan);
1413
1414
1415
1416 /* voice_stop_pan_sweep:
1417 * Ends a pan sweep.
1418 */
voice_stop_pan_sweep(int voice)1419 void voice_stop_pan_sweep(int voice)
1420 {
1421 if (_voice[voice].num >= 0) {
1422 _phys_voice[_voice[voice].num].dpan = 0;
1423
1424 if (digi_driver->stop_pan_sweep)
1425 digi_driver->stop_pan_sweep(_voice[voice].num);
1426 }
1427 }
1428
1429 END_OF_FUNCTION(voice_stop_pan_sweep);
1430
1431
1432
1433 /* voice_set_echo:
1434 * Sets the echo parameters of a voice.
1435 */
voice_set_echo(int voice,int strength,int delay)1436 void voice_set_echo(int voice, int strength, int delay)
1437 {
1438 if ((_voice[voice].num >= 0) && (digi_driver->set_echo))
1439 digi_driver->set_echo(_voice[voice].num, strength, delay);
1440 }
1441
1442 END_OF_FUNCTION(voice_set_echo);
1443
1444
1445
1446 /* voice_set_tremolo:
1447 * Sets the tremolo parameters of a voice.
1448 */
voice_set_tremolo(int voice,int rate,int depth)1449 void voice_set_tremolo(int voice, int rate, int depth)
1450 {
1451 if ((_voice[voice].num >= 0) && (digi_driver->set_tremolo))
1452 digi_driver->set_tremolo(_voice[voice].num, rate, depth);
1453 }
1454
1455 END_OF_FUNCTION(voice_set_tremolo);
1456
1457
1458
1459 /* voice_set_vibrato:
1460 * Sets the vibrato parameters of a voice.
1461 */
voice_set_vibrato(int voice,int rate,int depth)1462 void voice_set_vibrato(int voice, int rate, int depth)
1463 {
1464 if ((_voice[voice].num >= 0) && (digi_driver->set_vibrato))
1465 digi_driver->set_vibrato(_voice[voice].num, rate, depth);
1466 }
1467
1468 END_OF_FUNCTION(voice_set_vibrato);
1469
1470
1471
1472 /* update_sweeps:
1473 * Timer callback routine used to implement volume/frequency/pan sweep
1474 * effects, for those drivers that can't do them directly.
1475 */
update_sweeps()1476 static void update_sweeps()
1477 {
1478 int phys_voices, i;
1479
1480 phys_voices = digi_driver->voices;
1481 if (midi_driver->max_voices < 0)
1482 phys_voices += midi_driver->voices;
1483
1484 for (i=0; i<phys_voices; i++) {
1485 if (_phys_voice[i].num >= 0) {
1486 /* update volume ramp */
1487 if ((!digi_driver->ramp_volume) && (_phys_voice[i].dvol)) {
1488 _phys_voice[i].vol += _phys_voice[i].dvol;
1489
1490 if (((_phys_voice[i].dvol > 0) && (_phys_voice[i].vol >= _phys_voice[i].target_vol)) ||
1491 ((_phys_voice[i].dvol < 0) && (_phys_voice[i].vol <= _phys_voice[i].target_vol))) {
1492 _phys_voice[i].vol = _phys_voice[i].target_vol;
1493 _phys_voice[i].dvol = 0;
1494 }
1495
1496 digi_driver->set_volume(i, _phys_voice[i].vol >> 12);
1497 }
1498
1499 /* update frequency sweep */
1500 if ((!digi_driver->sweep_frequency) && (_phys_voice[i].dfreq)) {
1501 _phys_voice[i].freq += _phys_voice[i].dfreq;
1502
1503 if (((_phys_voice[i].dfreq > 0) && (_phys_voice[i].freq >= _phys_voice[i].target_freq)) ||
1504 ((_phys_voice[i].dfreq < 0) && (_phys_voice[i].freq <= _phys_voice[i].target_freq))) {
1505 _phys_voice[i].freq = _phys_voice[i].target_freq;
1506 _phys_voice[i].dfreq = 0;
1507 }
1508
1509 digi_driver->set_frequency(i, _phys_voice[i].freq >> 12);
1510 }
1511
1512 /* update pan sweep */
1513 if ((!digi_driver->sweep_pan) && (_phys_voice[i].dpan)) {
1514 _phys_voice[i].pan += _phys_voice[i].dpan;
1515
1516 if (((_phys_voice[i].dpan > 0) && (_phys_voice[i].pan >= _phys_voice[i].target_pan)) ||
1517 ((_phys_voice[i].dpan < 0) && (_phys_voice[i].pan <= _phys_voice[i].target_pan))) {
1518 _phys_voice[i].pan = _phys_voice[i].target_pan;
1519 _phys_voice[i].dpan = 0;
1520 }
1521
1522 digi_driver->set_pan(i, _phys_voice[i].pan >> 12);
1523 }
1524 }
1525 }
1526 }
1527
1528 static END_OF_FUNCTION(update_sweeps);
1529
1530
1531
1532 /* sound_lock_mem:
1533 * Locks memory used by the functions in this file.
1534 */
sound_lock_mem()1535 static void sound_lock_mem()
1536 {
1537 LOCK_VARIABLE(digi_none);
1538 LOCK_VARIABLE(midi_none);
1539 LOCK_VARIABLE(digi_card);
1540 LOCK_VARIABLE(midi_card);
1541 LOCK_VARIABLE(digi_driver);
1542 LOCK_VARIABLE(midi_driver);
1543 LOCK_VARIABLE(_voice);
1544 LOCK_VARIABLE(_phys_voice);
1545 LOCK_VARIABLE(_digi_volume);
1546 LOCK_VARIABLE(_midi_volume);
1547 LOCK_VARIABLE(_flip_pan);
1548 LOCK_FUNCTION(_dummy_detect);
1549 LOCK_FUNCTION(play_sample);
1550 LOCK_FUNCTION(adjust_sample);
1551 LOCK_FUNCTION(stop_sample);
1552 LOCK_FUNCTION(allocate_voice);
1553 LOCK_FUNCTION(deallocate_voice);
1554 LOCK_FUNCTION(reallocate_voice);
1555 LOCK_FUNCTION(voice_start);
1556 LOCK_FUNCTION(voice_stop);
1557 LOCK_FUNCTION(voice_set_priority);
1558 LOCK_FUNCTION(voice_check);
1559 LOCK_FUNCTION(voice_get_position);
1560 LOCK_FUNCTION(voice_set_position);
1561 LOCK_FUNCTION(voice_set_playmode);
1562 LOCK_FUNCTION(voice_get_volume);
1563 LOCK_FUNCTION(voice_set_volume);
1564 LOCK_FUNCTION(voice_ramp_volume);
1565 LOCK_FUNCTION(voice_stop_volumeramp);
1566 LOCK_FUNCTION(voice_get_frequency);
1567 LOCK_FUNCTION(voice_set_frequency);
1568 LOCK_FUNCTION(voice_sweep_frequency);
1569 LOCK_FUNCTION(voice_stop_frequency_sweep);
1570 LOCK_FUNCTION(voice_get_pan);
1571 LOCK_FUNCTION(voice_set_pan);
1572 LOCK_FUNCTION(voice_sweep_pan);
1573 LOCK_FUNCTION(voice_stop_pan_sweep);
1574 LOCK_FUNCTION(voice_set_echo);
1575 LOCK_FUNCTION(voice_set_tremolo);
1576 LOCK_FUNCTION(voice_set_vibrato);
1577 LOCK_FUNCTION(update_sweeps);
1578 }
1579
1580