1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Sound setup routines and API framework functions.
12 *
13 * By Shawn Hargreaves.
14 *
15 * Input routines added by Ove Kaaven.
16 *
17 * See readme.txt for copyright information.
18 */
19
20
21 #include <string.h>
22
23 #include "allegro.h"
24 #include "allegro/internal/aintern.h"
25
26
27
28 static DIGI_DRIVER digi_none;
29
30
31
32 /* dummy functions for the nosound drivers */
_dummy_detect(int input)33 int _dummy_detect(int input) { return TRUE; }
_dummy_init(int input,int voices)34 int _dummy_init(int input, int voices) { digi_none.desc = _midi_none.desc = get_config_text("The sound of silence"); return 0; }
_dummy_exit(int input)35 void _dummy_exit(int input) { }
_dummy_set_mixer_volume(int volume)36 int _dummy_set_mixer_volume(int volume) { return 0; }
_dummy_get_mixer_volume(void)37 int _dummy_get_mixer_volume(void) { return -1; }
_dummy_init_voice(int voice,AL_CONST SAMPLE * sample)38 void _dummy_init_voice(int voice, AL_CONST SAMPLE *sample) { }
_dummy_noop1(int p)39 void _dummy_noop1(int p) { }
_dummy_noop2(int p1,int p2)40 void _dummy_noop2(int p1, int p2) { }
_dummy_noop3(int p1,int p2,int p3)41 void _dummy_noop3(int p1, int p2, int p3) { }
_dummy_get_position(int voice)42 int _dummy_get_position(int voice) { return -1; }
_dummy_get(int voice)43 int _dummy_get(int voice) { return 0; }
_dummy_raw_midi(int data)44 void _dummy_raw_midi(int data) { }
_dummy_load_patches(AL_CONST char * patches,AL_CONST char * drums)45 int _dummy_load_patches(AL_CONST char *patches, AL_CONST char *drums) { return 0; }
_dummy_adjust_patches(AL_CONST char * patches,AL_CONST char * drums)46 void _dummy_adjust_patches(AL_CONST char *patches, AL_CONST char *drums) { }
_dummy_key_on(int inst,int note,int bend,int vol,int pan)47 void _dummy_key_on(int inst, int note, int bend, int vol, int pan) { }
48
49 /* put this after all the dummy functions, so they will all get locked */
50 END_OF_FUNCTION(_dummy_detect);
51
52
53
54 static DIGI_DRIVER digi_none =
55 {
56 DIGI_NONE,
57 empty_string,
58 empty_string,
59 "No sound",
60 0, 0, 0xFFFF, 0,
61 _dummy_detect,
62 _dummy_init,
63 _dummy_exit,
64 _dummy_set_mixer_volume,
65 _dummy_get_mixer_volume,
66 NULL,
67 NULL,
68 NULL,
69 _dummy_init_voice,
70 _dummy_noop1,
71 _dummy_noop1,
72 _dummy_noop1,
73 _dummy_noop2,
74 _dummy_get_position,
75 _dummy_noop2,
76 _dummy_get,
77 _dummy_noop2,
78 _dummy_noop3,
79 _dummy_noop1,
80 _dummy_get,
81 _dummy_noop2,
82 _dummy_noop3,
83 _dummy_noop1,
84 _dummy_get,
85 _dummy_noop2,
86 _dummy_noop3,
87 _dummy_noop1,
88 _dummy_noop3,
89 _dummy_noop3,
90 _dummy_noop3,
91 0, 0,
92 NULL, NULL, NULL, NULL, NULL, NULL
93 };
94
95
96 MIDI_DRIVER _midi_none =
97 {
98 MIDI_NONE,
99 empty_string,
100 empty_string,
101 "No sound",
102 0, 0, 0xFFFF, 0, -1, -1,
103 _dummy_detect,
104 _dummy_init,
105 _dummy_exit,
106 _dummy_set_mixer_volume,
107 _dummy_get_mixer_volume,
108 _dummy_raw_midi,
109 _dummy_load_patches,
110 _dummy_adjust_patches,
111 _dummy_key_on,
112 _dummy_noop1,
113 _dummy_noop2,
114 _dummy_noop3,
115 _dummy_noop2,
116 _dummy_noop2
117 };
118
119
120 int digi_card = DIGI_AUTODETECT; /* current driver ID numbers */
121 int midi_card = MIDI_AUTODETECT;
122
123 int digi_input_card = DIGI_AUTODETECT;
124 int midi_input_card = MIDI_AUTODETECT;
125
126 DIGI_DRIVER *digi_driver = &digi_none; /* these things do all the work */
127 MIDI_DRIVER *midi_driver = &_midi_none;
128
129 DIGI_DRIVER *digi_input_driver = &digi_none;
130 MIDI_DRIVER *midi_input_driver = &_midi_none;
131
132 void (*digi_recorder)(void) = NULL;
133 void (*midi_recorder)(unsigned char data) = NULL;
134
135 int _sound_installed = FALSE; /* are we installed? */
136 int _sound_input_installed = FALSE;
137
138 static int digi_reserve = -1; /* how many voices to reserve */
139 static int midi_reserve = -1;
140
141 static VOICE virt_voice[VIRTUAL_VOICES]; /* list of active samples */
142
143 PHYS_VOICE _phys_voice[DIGI_VOICES]; /* physical -> virtual voice map */
144
145 int _digi_volume = -1; /* current volume settings */
146 int _midi_volume = -1;
147
148 int _sound_flip_pan = FALSE; /* reverse l/r sample panning? */
149 int _sound_hq = 2; /* mixer speed vs. quality */
150
151 int _sound_freq = -1; /* common hardware parameters */
152 int _sound_stereo = -1;
153 int _sound_bits = -1;
154 int _sound_port = -1;
155 int _sound_dma = -1;
156 int _sound_irq = -1;
157
158 #define SWEEP_FREQ 50
159
160 static void update_sweeps(void);
161 static void sound_lock_mem(void);
162
163
164
165 /* read_sound_config:
166 * Helper for reading the sound hardware configuration data.
167 */
read_sound_config(void)168 static void read_sound_config(void)
169 {
170 char tmp1[64], tmp2[64];
171 char *sound = uconvert_ascii("sound", tmp1);
172
173 _sound_flip_pan = get_config_int(sound, uconvert_ascii("flip_pan", tmp2), FALSE);
174 _sound_hq = get_config_int(sound, uconvert_ascii("quality", tmp2), _sound_hq);
175 _sound_port = get_config_hex(sound, uconvert_ascii("sound_port", tmp2), -1);
176 _sound_dma = get_config_int(sound, uconvert_ascii("sound_dma", tmp2), -1);
177 _sound_irq = get_config_int(sound, uconvert_ascii("sound_irq", tmp2), -1);
178 _sound_freq = get_config_int(sound, uconvert_ascii("sound_freq", tmp2), -1);
179 _sound_bits = get_config_int(sound, uconvert_ascii("sound_bits", tmp2), -1);
180 _sound_stereo = get_config_int(sound, uconvert_ascii("sound_stereo", tmp2), -1);
181 _digi_volume = get_config_int(sound, uconvert_ascii("digi_volume", tmp2), -1);
182 _midi_volume = get_config_int(sound, uconvert_ascii("midi_volume", tmp2), -1);
183 }
184
185
186
187 /* detect_digi_driver:
188 * Detects whether the specified digital sound driver is available,
189 * returning the maximum number of voices that it can provide, or
190 * zero if the device is not present. This function must be called
191 * _before_ install_sound().
192 */
detect_digi_driver(int driver_id)193 int detect_digi_driver(int driver_id)
194 {
195 _DRIVER_INFO *digi_drivers;
196 int i, ret;
197
198 if (_sound_installed)
199 return 0;
200
201 read_sound_config();
202
203 if (system_driver->digi_drivers)
204 digi_drivers = system_driver->digi_drivers();
205 else
206 digi_drivers = _digi_driver_list;
207
208 for (i=0; digi_drivers[i].id; i++) {
209 if (digi_drivers[i].id == driver_id) {
210 digi_driver = digi_drivers[i].driver;
211 digi_driver->name = digi_driver->desc = get_config_text(digi_driver->ascii_name);
212 digi_card = driver_id;
213 midi_card = MIDI_AUTODETECT;
214
215 if (digi_driver->detect(FALSE))
216 ret = digi_driver->max_voices;
217 else
218 ret = 0;
219
220 digi_driver = &digi_none;
221 return ret;
222 }
223 }
224
225 return digi_none.max_voices;
226 }
227
228
229
230 /* detect_midi_driver:
231 * Detects whether the specified MIDI sound driver is available,
232 * returning the maximum number of voices that it can provide, or
233 * zero if the device is not present. If this routine returns -1,
234 * it is a note-stealing MIDI driver, which shares voices with the
235 * current digital driver. In this situation you can use the
236 * reserve_voices() function to specify how the available voices are
237 * divided between the digital and MIDI playback routines. This function
238 * must be called _before_ install_sound().
239 */
detect_midi_driver(int driver_id)240 int detect_midi_driver(int driver_id)
241 {
242 _DRIVER_INFO *midi_drivers;
243 int i, ret;
244
245 if (_sound_installed)
246 return 0;
247
248 read_sound_config();
249
250 if (system_driver->midi_drivers)
251 midi_drivers = system_driver->midi_drivers();
252 else
253 midi_drivers = _midi_driver_list;
254
255 for (i=0; midi_drivers[i].id; i++) {
256 if (midi_drivers[i].id == driver_id) {
257 midi_driver = midi_drivers[i].driver;
258 midi_driver->name = midi_driver->desc = get_config_text(midi_driver->ascii_name);
259 digi_card = DIGI_AUTODETECT;
260 midi_card = driver_id;
261
262 if (midi_driver->detect(FALSE))
263 ret = midi_driver->max_voices;
264 else
265 ret = 0;
266
267 midi_driver = &_midi_none;
268 return ret;
269 }
270 }
271
272 return _midi_none.max_voices;
273 }
274
275
276
277 /* reserve_voices:
278 * Reserves a number of voices for the digital and MIDI sound drivers
279 * respectively. This must be called _before_ install_sound(). If you
280 * attempt to reserve too many voices, subsequent calls to install_sound()
281 * will fail. Note that depending on the driver you may actually get
282 * more voices than you reserve: these values just specify the minimum
283 * that is appropriate for your application. Pass a negative reserve value
284 * to use the default settings.
285 */
reserve_voices(int digi_voices,int midi_voices)286 void reserve_voices(int digi_voices, int midi_voices)
287 {
288 digi_reserve = digi_voices;
289 midi_reserve = midi_voices;
290 }
291
292
293
294 /* install_sound:
295 * Initialises the sound module, returning zero on success. The two card
296 * parameters should use the DIGI_* and MIDI_* constants defined in
297 * allegro.h. Pass DIGI_AUTODETECT and MIDI_AUTODETECT if you don't know
298 * what the soundcard is.
299 */
install_sound(int digi,int midi,AL_CONST char * cfg_path)300 int install_sound(int digi, int midi, AL_CONST char *cfg_path)
301 {
302 char tmp1[64], tmp2[64];
303 char *sound = uconvert_ascii("sound", tmp1);
304 _DRIVER_INFO *digi_drivers, *midi_drivers;
305 int digi_voices, midi_voices;
306 int c;
307
308 if (_sound_installed)
309 return 0;
310
311 for (c=0; c<VIRTUAL_VOICES; c++) {
312 virt_voice[c].sample = NULL;
313 virt_voice[c].num = -1;
314 }
315
316 for (c=0; c<DIGI_VOICES; c++)
317 _phys_voice[c].num = -1;
318
319 /* initialise the MIDI file player */
320 if (_al_linker_midi)
321 if (_al_linker_midi->init() != 0)
322 return -1;
323
324 usetc(allegro_error, 0);
325
326 register_datafile_object(DAT_SAMPLE, NULL, (void (*)(void *))destroy_sample);
327
328 digi_card = digi;
329 midi_card = midi;
330
331 /* read config information */
332 if (digi_card == DIGI_AUTODETECT)
333 digi_card = get_config_id(sound, uconvert_ascii("digi_card", tmp2), DIGI_AUTODETECT);
334
335 if (midi_card == MIDI_AUTODETECT)
336 midi_card = get_config_id(sound, uconvert_ascii("midi_card", tmp2), MIDI_AUTODETECT);
337
338 if (digi_reserve < 0)
339 digi_reserve = get_config_int(sound, uconvert_ascii("digi_voices", tmp2), -1);
340
341 if (midi_reserve < 0)
342 midi_reserve = get_config_int(sound, uconvert_ascii("midi_voices", tmp2), -1);
343
344 read_sound_config();
345
346 sound_lock_mem();
347
348 /* set up digital sound driver */
349 if (system_driver->digi_drivers)
350 digi_drivers = system_driver->digi_drivers();
351 else
352 digi_drivers = _digi_driver_list;
353
354 for (c=0; digi_drivers[c].driver; c++) {
355 digi_driver = digi_drivers[c].driver;
356 digi_driver->name = digi_driver->desc = get_config_text(digi_driver->ascii_name);
357 }
358
359 digi_driver = NULL;
360
361 /* search table for a specific digital driver */
362 for (c=0; digi_drivers[c].driver; c++) {
363 if (digi_drivers[c].id == digi_card) {
364 digi_driver = digi_drivers[c].driver;
365 if (!digi_driver->detect(FALSE)) {
366 digi_driver = &digi_none;
367 if (_al_linker_midi)
368 _al_linker_midi->exit();
369 if (!ugetc(allegro_error))
370 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Digital sound driver not found"));
371 return -1;
372 }
373 break;
374 }
375 }
376
377 if (digi_card == DIGI_NONE)
378 digi_driver = &digi_none;
379
380 /* autodetect digital driver */
381 if (!digi_driver) {
382 for (c=0; digi_drivers[c].driver; c++) {
383 if (digi_drivers[c].autodetect) {
384 digi_card = digi_drivers[c].id;
385 digi_driver = digi_drivers[c].driver;
386 if (digi_driver->detect(FALSE))
387 break;
388 digi_driver = NULL;
389 }
390 }
391
392 if (!digi_driver) {
393 digi_card = DIGI_NONE;
394 digi_driver = &digi_none;
395 }
396 }
397
398 /* set up midi sound driver */
399 if (system_driver->midi_drivers)
400 midi_drivers = system_driver->midi_drivers();
401 else
402 midi_drivers = _midi_driver_list;
403
404 for (c=0; midi_drivers[c].driver; c++) {
405 midi_driver = midi_drivers[c].driver;
406 midi_driver->name = midi_driver->desc = get_config_text(midi_driver->ascii_name);
407 }
408
409 midi_driver = NULL;
410
411 /* search table for a specific MIDI driver */
412 for (c=0; midi_drivers[c].driver; c++) {
413 if (midi_drivers[c].id == midi_card) {
414 midi_driver = midi_drivers[c].driver;
415 if (!midi_driver->detect(FALSE)) {
416 digi_driver = &digi_none;
417 midi_driver = &_midi_none;
418 if (_al_linker_midi)
419 _al_linker_midi->exit();
420 if (!ugetc(allegro_error))
421 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MIDI music driver not found"));
422 return -1;
423 }
424 break;
425 }
426 }
427
428 if (midi_card == MIDI_NONE)
429 midi_driver = &_midi_none;
430
431 /* autodetect MIDI driver */
432 if (!midi_driver) {
433 for (c=0; midi_drivers[c].driver; c++) {
434 if (midi_drivers[c].autodetect) {
435 midi_card = midi_drivers[c].id;
436 midi_driver = midi_drivers[c].driver;
437 if (midi_driver->detect(FALSE))
438 break;
439 midi_driver = NULL;
440 }
441 }
442
443 if (!midi_driver) {
444 midi_card = MIDI_NONE;
445 midi_driver = &_midi_none;
446 }
447 }
448
449 /* work out how many voices to allocate for each driver */
450 if (digi_reserve >= 0)
451 digi_voices = digi_reserve;
452 else
453 digi_voices = digi_driver->def_voices;
454
455 if (midi_driver->max_voices < 0) {
456 /* MIDI driver steals voices from the digital player */
457 if (midi_reserve >= 0)
458 midi_voices = midi_reserve;
459 else
460 midi_voices = CLAMP(0, digi_driver->max_voices - digi_voices, midi_driver->def_voices);
461
462 digi_voices += midi_voices;
463 }
464 else {
465 /* MIDI driver has voices of its own */
466 if (midi_reserve >= 0)
467 midi_voices = midi_reserve;
468 else
469 midi_voices = midi_driver->def_voices;
470 }
471
472 /* make sure this is a reasonable number of voices to use */
473 if ((digi_voices > DIGI_VOICES) || (midi_voices > MIDI_VOICES)) {
474 uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Insufficient %s voices available"),
475 (digi_voices > DIGI_VOICES) ? get_config_text("digital") : get_config_text("MIDI"));
476 digi_driver = &digi_none;
477 midi_driver = &_midi_none;
478 if (_al_linker_midi)
479 _al_linker_midi->exit();
480 return -1;
481 }
482
483 /* initialise the digital sound driver */
484 if (digi_driver->init(FALSE, digi_voices) != 0) {
485 digi_driver = &digi_none;
486 midi_driver = &_midi_none;
487 if (_al_linker_midi)
488 _al_linker_midi->exit();
489 if (!ugetc(allegro_error))
490 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init digital sound driver"));
491 return -1;
492 }
493
494 /* initialise the MIDI driver */
495 if (midi_driver->init(FALSE, midi_voices) != 0) {
496 digi_driver->exit(FALSE);
497 digi_driver = &digi_none;
498 midi_driver = &_midi_none;
499 if (_al_linker_midi)
500 _al_linker_midi->exit();
501 if (!ugetc(allegro_error))
502 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init MIDI music driver"));
503 return -1;
504 }
505
506 digi_driver->voices = MIN(digi_driver->voices, DIGI_VOICES);
507 midi_driver->voices = MIN(midi_driver->voices, MIDI_VOICES);
508
509 /* check that we actually got enough voices */
510 if ((digi_driver->voices < digi_voices) ||
511 ((midi_driver->voices < midi_voices) && (!midi_driver->raw_midi))) {
512 uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Insufficient %s voices available"),
513 (digi_driver->voices < digi_voices) ? get_config_text("digital") : get_config_text("MIDI"));
514 midi_driver->exit(FALSE);
515 digi_driver->exit(FALSE);
516 digi_driver = &digi_none;
517 midi_driver = &_midi_none;
518 if (_al_linker_midi)
519 _al_linker_midi->exit();
520 return -1;
521 }
522
523 /* adjust for note-stealing MIDI drivers */
524 if (midi_driver->max_voices < 0) {
525 midi_voices += (digi_driver->voices - digi_voices) * 3/4;
526 digi_driver->voices -= midi_voices;
527 midi_driver->basevoice = VIRTUAL_VOICES - midi_voices;
528 midi_driver->voices = midi_voices;
529
530 for (c=0; c<midi_voices; c++) {
531 virt_voice[midi_driver->basevoice+c].num = digi_driver->voices+c;
532 _phys_voice[digi_driver->voices+c].num = midi_driver->basevoice+c;
533 }
534 }
535
536 /* simulate ramp/sweep effects for drivers that don't do it directly */
537 if ((!digi_driver->ramp_volume) ||
538 (!digi_driver->sweep_frequency) ||
539 (!digi_driver->sweep_pan))
540 install_int_ex(update_sweeps, BPS_TO_TIMER(SWEEP_FREQ));
541
542 /* set the global sound volume */
543 if ((_digi_volume >= 0) || (_midi_volume >= 0))
544 set_volume(_digi_volume, _midi_volume);
545
546 _add_exit_func(remove_sound, "remove_sound");
547 _sound_installed = TRUE;
548 return 0;
549 }
550
551
552
553 /* install_sound_input:
554 * Initialises the sound recorder module, returning zero on success. The
555 * two card parameters should use the DIGI_* and MIDI_* constants defined
556 * in allegro.h. Pass DIGI_AUTODETECT and MIDI_AUTODETECT if you don't know
557 * what the soundcard is.
558 */
install_sound_input(int digi,int midi)559 int install_sound_input(int digi, int midi)
560 {
561 char tmp1[64], tmp2[64];
562 char *sound = uconvert_ascii("sound", tmp1);
563 _DRIVER_INFO *digi_drivers, *midi_drivers;
564 int c;
565
566 if (_sound_input_installed)
567 return 0;
568
569 if (!_sound_installed) {
570 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Sound system not installed"));
571 return -1;
572 }
573
574 digi_recorder = NULL;
575 midi_recorder = NULL;
576
577 digi_input_card = digi;
578 midi_input_card = midi;
579
580 /* read config information */
581 if (digi_input_card == DIGI_AUTODETECT)
582 digi_input_card = get_config_id(sound, uconvert_ascii("digi_input_card", tmp2), DIGI_AUTODETECT);
583
584 if (midi_input_card == MIDI_AUTODETECT)
585 midi_input_card = get_config_id(sound, uconvert_ascii("midi_input_card", tmp2), MIDI_AUTODETECT);
586
587 /* search table for a good digital input driver */
588 usetc(allegro_error, 0);
589
590 if (system_driver->digi_drivers)
591 digi_drivers = system_driver->digi_drivers();
592 else
593 digi_drivers = _digi_driver_list;
594
595 for (c=0; digi_drivers[c].driver; c++) {
596 if ((digi_drivers[c].id == digi_input_card) || (digi_input_card == DIGI_AUTODETECT)) {
597 digi_input_driver = digi_drivers[c].driver;
598 if (digi_input_driver->detect(TRUE)) {
599 digi_input_card = digi_drivers[c].id;
600 break;
601 }
602 else {
603 digi_input_driver = &digi_none;
604 if (digi_input_card != DIGI_AUTODETECT) {
605 if (!ugetc(allegro_error))
606 uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s does not support audio input"),
607 ((DIGI_DRIVER *)digi_drivers[c].driver)->name);
608 break;
609 }
610 }
611 }
612 }
613
614 /* did we find one? */
615 if ((digi_input_driver == &digi_none) && (digi_input_card != DIGI_NONE)) {
616 if (!ugetc(allegro_error))
617 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Digital input driver not found"));
618 return -1;
619 }
620
621 /* search table for a good MIDI input driver */
622 usetc(allegro_error, 0);
623
624 if (system_driver->midi_drivers)
625 midi_drivers = system_driver->midi_drivers();
626 else
627 midi_drivers = _midi_driver_list;
628
629 for (c=0; midi_drivers[c].driver; c++) {
630 if ((midi_drivers[c].id == midi_input_card) || (midi_input_card == MIDI_AUTODETECT)) {
631 midi_input_driver = midi_drivers[c].driver;
632 if (midi_input_driver->detect(TRUE)) {
633 midi_input_card = midi_drivers[c].id;
634 break;
635 }
636 else {
637 midi_input_driver = &_midi_none;
638 if (midi_input_card != MIDI_AUTODETECT) {
639 if (!ugetc(allegro_error))
640 uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s does not support MIDI input"),
641 ((MIDI_DRIVER *)midi_drivers[c].driver)->name);
642 break;
643 }
644 }
645 }
646 }
647
648 /* did we find one? */
649 if ((midi_input_driver == &_midi_none) && (midi_input_card != MIDI_NONE)) {
650 digi_input_driver = &digi_none;
651 if (!ugetc(allegro_error))
652 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MIDI input driver not found"));
653 return -1;
654 }
655
656 /* initialise the digital input driver */
657 if (digi_input_driver->init(TRUE, 0) != 0) {
658 digi_input_driver = &digi_none;
659 midi_input_driver = &_midi_none;
660 if (!ugetc(allegro_error))
661 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init digital input driver"));
662 return -1;
663 }
664
665 /* initialise the MIDI input driver */
666 if (midi_input_driver->init(TRUE, 0) != 0) {
667 digi_input_driver->exit(TRUE);
668 digi_input_driver = &digi_none;
669 midi_input_driver = &_midi_none;
670 if (!ugetc(allegro_error))
671 ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init MIDI input driver"));
672 return -1;
673 }
674
675 _sound_input_installed = TRUE;
676 return 0;
677 }
678
679
680
681 /* remove_sound:
682 * Sound module cleanup routine.
683 */
remove_sound(void)684 void remove_sound(void)
685 {
686 int c;
687
688 if (_sound_installed) {
689 remove_sound_input();
690
691 remove_int(update_sweeps);
692
693 for (c=0; c<VIRTUAL_VOICES; c++)
694 if (virt_voice[c].sample)
695 deallocate_voice(c);
696
697 if (_al_linker_midi)
698 _al_linker_midi->exit();
699
700 midi_driver->exit(FALSE);
701 midi_driver = &_midi_none;
702
703 digi_driver->exit(FALSE);
704 digi_driver = &digi_none;
705
706 _remove_exit_func(remove_sound);
707 _sound_installed = FALSE;
708 }
709 }
710
711
712
713 /* remove_sound_input:
714 * Sound input module cleanup routine.
715 */
remove_sound_input(void)716 void remove_sound_input(void)
717 {
718 if (_sound_input_installed) {
719 digi_input_driver->exit(TRUE);
720 digi_input_driver = &digi_none;
721
722 midi_input_driver->exit(TRUE);
723 midi_input_driver = &_midi_none;
724
725 digi_recorder = NULL;
726 midi_recorder = NULL;
727
728 _sound_input_installed = FALSE;
729 }
730 }
731
732
733
734 /* set_volume:
735 * Alters the global sound output volume. Specify volumes for both digital
736 * samples and MIDI playback, as integers from 0 to 255. This routine will
737 * not alter the volume of the hardware mixer if it exists.
738 */
set_volume(int digi_volume,int midi_volume)739 void set_volume(int digi_volume, int midi_volume)
740 {
741 int *voice_vol;
742 int i;
743
744 if (digi_volume >= 0) {
745 voice_vol = _AL_MALLOC_ATOMIC(sizeof(int)*VIRTUAL_VOICES);
746
747 /* Retrieve the (relative) volume of each voice. */
748 for (i=0; i<VIRTUAL_VOICES; i++)
749 voice_vol[i] = voice_get_volume(i);
750
751 _digi_volume = CLAMP(0, digi_volume, 255);
752
753 /* Set the new (relative) volume for each voice. */
754 for (i=0; i<VIRTUAL_VOICES; i++) {
755 if (voice_vol[i] >= 0)
756 voice_set_volume(i, voice_vol[i]);
757 }
758
759 _AL_FREE(voice_vol);
760 }
761
762 if (midi_volume >= 0)
763 _midi_volume = CLAMP(0, midi_volume, 255);
764 }
765
766
767
768 /* get_volume:
769 * Retrieves the global sound output volume, both for digital samples and MIDI
770 * playback, as integers from 0 to 255. Parameters digi_volume and midi_volume
771 * must be valid pointers to int, or NULL if not interested in specific value.
772 */
get_volume(int * digi_volume,int * midi_volume)773 void get_volume(int *digi_volume, int *midi_volume)
774 {
775 if (digi_volume)
776 (*digi_volume) = _digi_volume;
777 if (midi_volume)
778 (*midi_volume) = _midi_volume;
779 }
780
781
782
783 /* set_hardware_volume:
784 * Alters the hardware sound output volume. Specify volumes for both digital
785 * samples and MIDI playback, as integers from 0 to 255. This routine will
786 * use the hardware mixer to control the volume if it exists, or do nothing.
787 */
set_hardware_volume(int digi_volume,int midi_volume)788 void set_hardware_volume(int digi_volume, int midi_volume)
789 {
790 if (digi_volume >= 0) {
791 digi_volume = CLAMP(0, digi_volume, 255);
792
793 if (digi_driver->set_mixer_volume)
794 digi_driver->set_mixer_volume(digi_volume);
795 }
796
797 if (midi_volume >= 0) {
798 midi_volume = CLAMP(0, midi_volume, 255);
799
800 if (midi_driver->set_mixer_volume)
801 midi_driver->set_mixer_volume(midi_volume);
802 }
803 }
804
805
806
807 /* get_hardware_volume:
808 * Retrieves the hardware sound output volume, both for digital samples and MIDI
809 * playback, as integers from 0 to 255, or -1 if the information is not
810 * available. Parameters digi_volume and midi_volume must be valid pointers to
811 * int, or NULL if not interested in specific value.
812 */
get_hardware_volume(int * digi_volume,int * midi_volume)813 void get_hardware_volume(int *digi_volume, int *midi_volume)
814 {
815 if (digi_volume) {
816 if (digi_driver->get_mixer_volume) {
817 (*digi_volume) = digi_driver->get_mixer_volume();
818 }
819 else {
820 (*digi_volume) = -1;
821 }
822 }
823
824 if (midi_volume) {
825 if (midi_driver->get_mixer_volume) {
826 (*midi_volume) = midi_driver->get_mixer_volume();
827 }
828 else {
829 (*midi_volume) = -1;
830 }
831 }
832 }
833
834
835
836 /* lock_sample:
837 * Locks a SAMPLE struct into physical memory. Pretty important, since
838 * they are mostly accessed inside interrupt handlers.
839 */
lock_sample(SAMPLE * spl)840 void lock_sample(SAMPLE *spl)
841 {
842 ASSERT(spl);
843 LOCK_DATA(spl, sizeof(SAMPLE));
844 LOCK_DATA(spl->data, spl->len * ((spl->bits==8) ? 1 : sizeof(short)) * ((spl->stereo) ? 2 : 1));
845 }
846
847
848
849 /* load_voc:
850 * Reads a mono VOC format sample file, returning a SAMPLE structure,
851 * or NULL on error.
852 */
load_voc(AL_CONST char * filename)853 SAMPLE *load_voc(AL_CONST char *filename)
854 {
855 PACKFILE *f;
856 SAMPLE *spl;
857 ASSERT(filename);
858
859 f = pack_fopen(filename, F_READ);
860 if (!f)
861 return NULL;
862
863 spl = load_voc_pf(f);
864
865 pack_fclose(f);
866
867 return spl;
868 }
869
870
871
872 /* load_voc_pf:
873 * Reads a mono VOC format sample from the packfile given, returning a
874 * SAMPLE structure, or NULL on error. If successful the offset into the
875 * file will be left just after the sample data. If unsuccessful the offset
876 * into the file is unspecified, i.e. you must either reset the offset to
877 * some known place or close the packfile. The packfile is not closed by
878 * this function.
879 */
load_voc_pf(PACKFILE * f)880 SAMPLE *load_voc_pf(PACKFILE *f)
881 {
882 char buffer[30];
883 int freq = 22050;
884 int bits = 8;
885 SAMPLE *spl = NULL;
886 int len;
887 int x, ver;
888 int s;
889 ASSERT(f);
890
891 memset(buffer, 0, sizeof buffer);
892
893 pack_fread(buffer, 0x16, f);
894
895 if (memcmp(buffer, "Creative Voice File", 0x13))
896 goto getout;
897
898 ver = pack_igetw(f);
899 if (ver != 0x010A && ver != 0x0114) /* version: should be 0x010A or 0x0114 */
900 goto getout;
901
902 ver = pack_igetw(f);
903 if (ver != 0x1129 && ver != 0x111f) /* subversion: should be 0x1129 or 0x111f */
904 goto getout;
905
906 ver = pack_getc(f);
907 if (ver != 0x01 && ver != 0x09) /* sound data: should be 0x01 or 0x09 */
908 goto getout;
909
910 len = pack_igetw(f); /* length is three bytes long: two */
911 x = pack_getc(f); /* .. and one byte */
912 x <<= 16;
913 len += x;
914
915 if (ver == 0x01) { /* block type 1 */
916 len -= 2; /* sub. size of the rest of block header */
917 x = pack_getc(f); /* one byte of frequency */
918 freq = 1000000 / (256-x);
919
920 x = pack_getc(f); /* skip one byte */
921
922 spl = create_sample(8, FALSE, freq, len);
923
924 if (spl) {
925 if (pack_fread(spl->data, len, f) < len) {
926 destroy_sample(spl);
927 spl = NULL;
928 }
929 }
930 }
931 else { /* block type 9 */
932 len -= 12; /* sub. size of the rest of block header */
933 freq = pack_igetw(f); /* two bytes of frequency */
934
935 x = pack_igetw(f); /* skip two bytes */
936
937 bits = pack_getc(f); /* # of bits per sample */
938 if (bits != 8 && bits != 16)
939 goto getout;
940
941 x = pack_getc(f);
942 if (x != 1) /* # of channels: should be mono */
943 goto getout;
944
945 pack_fread(buffer, 0x6, f); /* skip 6 bytes of unknown data */
946
947 spl = create_sample(bits, FALSE, freq, len*8/bits);
948
949 if (spl) {
950 if (bits == 8) {
951 if (pack_fread(spl->data, len, f) < len) {
952 destroy_sample(spl);
953 spl = NULL;
954 }
955 }
956 else {
957 len /= 2;
958 for (x=0; x<len; x++) {
959 if ((s = pack_igetw(f)) == EOF) {
960 destroy_sample(spl);
961 spl = NULL;
962 break;
963 }
964 ((signed short *)spl->data)[x] = (signed short)s^0x8000;
965 }
966 }
967 }
968 }
969
970 getout:
971 return spl;
972 }
973
974
975
976 /* load_wav:
977 * Reads a RIFF WAV format sample file, returning a SAMPLE structure,
978 * or NULL on error.
979 */
load_wav(AL_CONST char * filename)980 SAMPLE *load_wav(AL_CONST char *filename)
981 {
982 PACKFILE *f;
983 SAMPLE *spl;
984 ASSERT(filename);
985
986 f = pack_fopen(filename, F_READ);
987 if (!f)
988 return NULL;
989
990 spl = load_wav_pf(f);
991
992 pack_fclose(f);
993
994 return spl;
995 }
996
997
998
999 /* load_wav_pf:
1000 * Reads a RIFF WAV format sample from the packfile given, returning a
1001 * SAMPLE structure, or NULL on error.
1002 *
1003 * Note that the loader does not stop reading bytes from the PACKFILE until
1004 * it sees the EOF. If you want to embed a WAV file into another file, you
1005 * will have to implement your own chunking system that stops reading at the
1006 * end of the chunk.
1007 *
1008 * If unsuccessful the offset into the file is unspecified, i.e. you must
1009 * either reset the offset to some known place or close the packfile. The
1010 * packfile is not closed by this function.
1011 */
load_wav_pf(PACKFILE * f)1012 SAMPLE *load_wav_pf(PACKFILE *f)
1013 {
1014 char buffer[25];
1015 int i;
1016 int length, len;
1017 int freq = 22050;
1018 int bits = 8;
1019 int channels = 1;
1020 int s;
1021 SAMPLE *spl = NULL;
1022 ASSERT(f);
1023
1024 memset(buffer, 0, sizeof buffer);
1025
1026 pack_fread(buffer, 12, f); /* check RIFF header */
1027 if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4))
1028 goto getout;
1029
1030 while (TRUE) {
1031 if (pack_fread(buffer, 4, f) != 4)
1032 break;
1033
1034 length = pack_igetl(f); /* read chunk length */
1035
1036 if (memcmp(buffer, "fmt ", 4) == 0) {
1037 i = pack_igetw(f); /* should be 1 for PCM data */
1038 length -= 2;
1039 if (i != 1)
1040 goto getout;
1041
1042 channels = pack_igetw(f); /* mono or stereo data */
1043 length -= 2;
1044 if ((channels != 1) && (channels != 2))
1045 goto getout;
1046
1047 freq = pack_igetl(f); /* sample frequency */
1048 length -= 4;
1049
1050 pack_igetl(f); /* skip six bytes */
1051 pack_igetw(f);
1052 length -= 6;
1053
1054 bits = pack_igetw(f); /* 8 or 16 bit data? */
1055 length -= 2;
1056 if ((bits != 8) && (bits != 16))
1057 goto getout;
1058 }
1059 else if (memcmp(buffer, "data", 4) == 0) {
1060 if (channels == 2) {
1061 /* allocate enough space even if length is odd for some reason */
1062 len = (length + 1) / 2;
1063 }
1064 else {
1065 ASSERT(channels == 1);
1066 len = length;
1067 }
1068
1069 if (bits == 16)
1070 len /= 2;
1071
1072 spl = create_sample(bits, ((channels == 2) ? TRUE : FALSE), freq, len);
1073
1074 if (spl) {
1075 if (bits == 8) {
1076 if (pack_fread(spl->data, length, f) < length) {
1077 destroy_sample(spl);
1078 spl = NULL;
1079 }
1080 }
1081 else {
1082 for (i=0; i<len*channels; i++) {
1083 if ((s = pack_igetw(f)) == EOF) {
1084 destroy_sample(spl);
1085 spl = NULL;
1086 break;
1087 }
1088 ((signed short *)spl->data)[i] = (signed short)s^0x8000;
1089 }
1090 }
1091
1092 length = 0;
1093 }
1094 }
1095
1096 while (length > 0) { /* skip the remainder of the chunk */
1097 if (pack_getc(f) == EOF)
1098 break;
1099
1100 length--;
1101 }
1102 }
1103
1104 getout:
1105 return spl;
1106 }
1107
1108
1109
1110 /* create_sample:
1111 * Constructs a new sample structure of the specified type.
1112 */
create_sample(int bits,int stereo,int freq,int len)1113 SAMPLE *create_sample(int bits, int stereo, int freq, int len)
1114 {
1115 SAMPLE *spl;
1116 ASSERT(freq > 0);
1117 ASSERT(len > 0);
1118
1119 spl = _AL_MALLOC(sizeof(SAMPLE));
1120 if (!spl)
1121 return NULL;
1122
1123 spl->bits = bits;
1124 spl->stereo = stereo;
1125 spl->freq = freq;
1126 spl->priority = 128;
1127 spl->len = len;
1128 spl->loop_start = 0;
1129 spl->loop_end = len;
1130 spl->param = 0;
1131
1132 spl->data = _AL_MALLOC_ATOMIC(len * ((bits==8) ? 1 : sizeof(short)) * ((stereo) ? 2 : 1));
1133 if (!spl->data) {
1134 _AL_FREE(spl);
1135 return NULL;
1136 }
1137
1138 lock_sample(spl);
1139 return spl;
1140 }
1141
1142
1143
1144 /* destroy_sample:
1145 * Frees a SAMPLE struct, checking whether the sample is currently playing,
1146 * and stopping it if it is.
1147 */
destroy_sample(SAMPLE * spl)1148 void destroy_sample(SAMPLE *spl)
1149 {
1150 if (spl) {
1151 stop_sample(spl);
1152
1153 if (spl->data) {
1154 UNLOCK_DATA(spl->data, spl->len * ((spl->bits==8) ? 1 : sizeof(short)) * ((spl->stereo) ? 2 : 1));
1155 _AL_FREE(spl->data);
1156 }
1157
1158 UNLOCK_DATA(spl, sizeof(SAMPLE));
1159 _AL_FREE(spl);
1160 }
1161 }
1162
1163
1164
1165 /* absolute_freq:
1166 * Converts a pitch from the relative 1000 = original format to an absolute
1167 * value in hz.
1168 */
absolute_freq(int freq,AL_CONST SAMPLE * spl)1169 static INLINE int absolute_freq(int freq, AL_CONST SAMPLE *spl)
1170 {
1171 ASSERT(spl);
1172 if (freq == 1000)
1173 return spl->freq;
1174 else
1175 return (spl->freq * freq) / 1000;
1176 }
1177
1178
1179
1180 /* play_sample:
1181 * Triggers a sample at the specified volume, pan position, and frequency.
1182 * The volume and pan range from 0 (min/left) to 255 (max/right), although
1183 * the resolution actually used by the playback routines is likely to be
1184 * less than this. Frequency is relative rather than absolute: 1000
1185 * represents the frequency that the sample was recorded at, 2000 is
1186 * twice this, etc. If loop is true the sample will repeat until you call
1187 * stop_sample(), and can be manipulated while it is playing by calling
1188 * adjust_sample().
1189 */
play_sample(AL_CONST SAMPLE * spl,int vol,int pan,int freq,int loop)1190 int play_sample(AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop)
1191 {
1192 int voice;
1193 ASSERT(spl);
1194 ASSERT(vol >= 0 && vol <= 255);
1195 ASSERT(pan >= 0 && pan <= 255);
1196 ASSERT(freq > 0);
1197
1198 voice = allocate_voice(spl);
1199 if (voice >= 0) {
1200 voice_set_volume(voice, vol);
1201 voice_set_pan(voice, pan);
1202 voice_set_frequency(voice, absolute_freq(freq, spl));
1203 voice_set_playmode(voice, (loop ? PLAYMODE_LOOP : PLAYMODE_PLAY));
1204 voice_start(voice);
1205 release_voice(voice);
1206 }
1207
1208 return voice;
1209 }
1210
1211 END_OF_FUNCTION(play_sample);
1212
1213
1214
1215 /* adjust_sample:
1216 * Alters the parameters of a sample while it is playing, useful for
1217 * manipulating looped sounds. You can alter the volume, pan, and
1218 * frequency, and can also remove the looping flag, which will stop
1219 * the sample when it next reaches the end of its loop. If there are
1220 * several copies of the same sample playing, this will adjust the
1221 * first one it comes across. If the sample is not playing it has no
1222 * effect.
1223 */
adjust_sample(AL_CONST SAMPLE * spl,int vol,int pan,int freq,int loop)1224 void adjust_sample(AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop)
1225 {
1226 int c;
1227 ASSERT(spl);
1228
1229 for (c=0; c<VIRTUAL_VOICES; c++) {
1230 if (virt_voice[c].sample == spl) {
1231 voice_set_volume(c, vol);
1232 voice_set_pan(c, pan);
1233 voice_set_frequency(c, absolute_freq(freq, spl));
1234 voice_set_playmode(c, (loop ? PLAYMODE_LOOP : PLAYMODE_PLAY));
1235 return;
1236 }
1237 }
1238 }
1239
1240 END_OF_FUNCTION(adjust_sample);
1241
1242
1243
1244 /* stop_sample:
1245 * Kills off a sample, which is required if you have set a sample going
1246 * in looped mode. If there are several copies of the sample playing,
1247 * it will stop them all.
1248 */
stop_sample(AL_CONST SAMPLE * spl)1249 void stop_sample(AL_CONST SAMPLE *spl)
1250 {
1251 int c;
1252 ASSERT(spl);
1253
1254 for (c=0; c<VIRTUAL_VOICES; c++)
1255 if (virt_voice[c].sample == spl)
1256 deallocate_voice(c);
1257 }
1258
1259 END_OF_FUNCTION(stop_sample);
1260
1261
1262
1263 /* allocate_physical_voice:
1264 * Allocates a physical voice, killing off others as required in order
1265 * to make room for it.
1266 */
allocate_physical_voice(int priority)1267 static INLINE int allocate_physical_voice(int priority)
1268 {
1269 VOICE *voice;
1270 int best = -1;
1271 int best_score = 0;
1272 int score;
1273 int c;
1274
1275 /* look for a free voice */
1276 for (c=0; c<digi_driver->voices; c++)
1277 if (_phys_voice[c].num < 0)
1278 return c;
1279
1280 /* look for an autokill voice that has stopped */
1281 for (c=0; c<digi_driver->voices; c++) {
1282 voice = virt_voice + _phys_voice[c].num;
1283 if ((voice->autokill) && (digi_driver->get_position(c) < 0)) {
1284 digi_driver->release_voice(c);
1285 voice->sample = NULL;
1286 voice->num = -1;
1287 _phys_voice[c].num = -1;
1288 return c;
1289 }
1290 }
1291
1292 /* ok, we're going to have to get rid of something to make room... */
1293 for (c=0; c<digi_driver->voices; c++) {
1294 voice = virt_voice + _phys_voice[c].num;
1295
1296 /* sort by voice priorities */
1297 if (voice->priority <= priority) {
1298 score = 65536 - voice->priority * 256;
1299
1300 /* bias with a least-recently-used counter */
1301 score += CLAMP(0, retrace_count - voice->time, 32768);
1302
1303 /* bias according to whether the voice is looping or not */
1304 if (!(_phys_voice[c].playmode & PLAYMODE_LOOP))
1305 score += 32768;
1306
1307 if (score > best_score) {
1308 best = c;
1309 best_score = score;
1310 }
1311 }
1312 }
1313
1314 if (best >= 0) {
1315 /* kill off the old voice */
1316 digi_driver->stop_voice(best);
1317 digi_driver->release_voice(best);
1318 virt_voice[_phys_voice[best].num].num = -1;
1319 _phys_voice[best].num = -1;
1320 return best;
1321 }
1322
1323 return -1;
1324 }
1325
1326
1327
1328 /* allocate_virtual_voice:
1329 * Allocates a virtual voice. This doesn't need to worry about killing off
1330 * others to make room, as we allow up to 256 virtual voices to be used
1331 * simultaneously.
1332 */
allocate_virtual_voice(void)1333 static INLINE int allocate_virtual_voice(void)
1334 {
1335 int num_virt_voices, c;
1336
1337 num_virt_voices = VIRTUAL_VOICES;
1338 if (midi_driver->max_voices < 0)
1339 num_virt_voices -= midi_driver->voices;
1340
1341 /* look for a free voice */
1342 for (c=0; c<num_virt_voices; c++)
1343 if (!virt_voice[c].sample)
1344 return c;
1345
1346 /* look for a stopped autokill voice */
1347 for (c=0; c<num_virt_voices; c++) {
1348 if (virt_voice[c].autokill) {
1349 if (virt_voice[c].num < 0) {
1350 virt_voice[c].sample = NULL;
1351 return c;
1352 }
1353 else {
1354 if (digi_driver->get_position(virt_voice[c].num) < 0) {
1355 digi_driver->release_voice(virt_voice[c].num);
1356 _phys_voice[virt_voice[c].num].num = -1;
1357 virt_voice[c].sample = NULL;
1358 virt_voice[c].num = -1;
1359 return c;
1360 }
1361 }
1362 }
1363 }
1364
1365 return -1;
1366 }
1367
1368
1369
1370 /* allocate_voice:
1371 * Allocates a voice ready for playing the specified sample, returning
1372 * the voice number (note this is not the same as the physical voice
1373 * number used by the sound drivers, and must only be used with the other
1374 * voice functions, _not_ passed directly to the driver routines).
1375 * Returns -1 if there is no voice available (this should never happen,
1376 * since there are 256 virtual voices and anyone who needs more than that
1377 * needs some urgent repairs to their brain :-)
1378 */
allocate_voice(AL_CONST SAMPLE * spl)1379 int allocate_voice(AL_CONST SAMPLE *spl)
1380 {
1381 int phys, virt;
1382 ASSERT(spl);
1383
1384 phys = allocate_physical_voice(spl->priority);
1385 virt = allocate_virtual_voice();
1386
1387 if (virt >= 0) {
1388 virt_voice[virt].sample = spl;
1389 virt_voice[virt].num = phys;
1390 virt_voice[virt].autokill = FALSE;
1391 virt_voice[virt].time = retrace_count;
1392 virt_voice[virt].priority = spl->priority;
1393
1394 if (phys >= 0) {
1395 _phys_voice[phys].num = virt;
1396 _phys_voice[phys].playmode = 0;
1397 _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12;
1398 _phys_voice[phys].pan = 128 << 12;
1399 _phys_voice[phys].freq = spl->freq << 12;
1400 _phys_voice[phys].dvol = 0;
1401 _phys_voice[phys].dpan = 0;
1402 _phys_voice[phys].dfreq = 0;
1403
1404 digi_driver->init_voice(phys, spl);
1405 }
1406 }
1407
1408 return virt;
1409 }
1410
1411 END_OF_FUNCTION(allocate_voice);
1412
1413
1414
1415 /* deallocate_voice:
1416 * Releases a voice that was previously returned by allocate_voice().
1417 */
deallocate_voice(int voice)1418 void deallocate_voice(int voice)
1419 {
1420 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1421
1422 if (virt_voice[voice].num >= 0) {
1423 digi_driver->stop_voice(virt_voice[voice].num);
1424 digi_driver->release_voice(virt_voice[voice].num);
1425 _phys_voice[virt_voice[voice].num].num = -1;
1426 virt_voice[voice].num = -1;
1427 }
1428
1429 virt_voice[voice].sample = NULL;
1430 }
1431
1432 END_OF_FUNCTION(deallocate_voice);
1433
1434
1435
1436 /* reallocate_voice:
1437 * Switches an already-allocated voice to use a different sample.
1438 */
reallocate_voice(int voice,AL_CONST SAMPLE * spl)1439 void reallocate_voice(int voice, AL_CONST SAMPLE *spl)
1440 {
1441 int phys;
1442 ASSERT(spl);
1443 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1444
1445 phys = virt_voice[voice].num;
1446
1447 if (phys >= 0) {
1448 digi_driver->stop_voice(phys);
1449 digi_driver->release_voice(phys);
1450 }
1451
1452 virt_voice[voice].sample = spl;
1453 virt_voice[voice].autokill = FALSE;
1454 virt_voice[voice].time = retrace_count;
1455 virt_voice[voice].priority = spl->priority;
1456
1457 if (phys >= 0) {
1458 _phys_voice[phys].playmode = 0;
1459 _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12;
1460 _phys_voice[phys].pan = 128 << 12;
1461 _phys_voice[phys].freq = spl->freq << 12;
1462 _phys_voice[phys].dvol = 0;
1463 _phys_voice[phys].dpan = 0;
1464 _phys_voice[phys].dfreq = 0;
1465
1466 digi_driver->init_voice(phys, spl);
1467 }
1468 }
1469
1470 END_OF_FUNCTION(reallocate_voice);
1471
1472
1473
1474 /* release_voice:
1475 * Flags that a voice is no longer going to be updated, so it can
1476 * automatically be freed as soon as the sample finishes playing.
1477 */
release_voice(int voice)1478 void release_voice(int voice)
1479 {
1480 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1481 virt_voice[voice].autokill = TRUE;
1482 }
1483
1484 END_OF_FUNCTION(release_voice);
1485
1486
1487
1488 /* voice_start:
1489 * Starts a voice playing.
1490 */
voice_start(int voice)1491 void voice_start(int voice)
1492 {
1493 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1494 if (virt_voice[voice].num >= 0)
1495 digi_driver->start_voice(virt_voice[voice].num);
1496
1497 virt_voice[voice].time = retrace_count;
1498 }
1499
1500 END_OF_FUNCTION(voice_start);
1501
1502
1503
1504 /* voice_stop:
1505 * Stops a voice from playing.
1506 */
voice_stop(int voice)1507 void voice_stop(int voice)
1508 {
1509 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1510 if (virt_voice[voice].num >= 0)
1511 digi_driver->stop_voice(virt_voice[voice].num);
1512 }
1513
1514 END_OF_FUNCTION(voice_stop);
1515
1516
1517
1518 /* voice_set_priority:
1519 * Adjusts the priority of a voice (0-255).
1520 */
voice_set_priority(int voice,int priority)1521 void voice_set_priority(int voice, int priority)
1522 {
1523 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1524 ASSERT(priority >= 0 && priority <= 255);
1525 virt_voice[voice].priority = priority;
1526 }
1527
1528 END_OF_FUNCTION(voice_set_priority);
1529
1530
1531
1532 /* voice_check:
1533 * Checks whether a voice is playing, returning the sample if it is,
1534 * or NULL if it has finished or been preempted by a different sound.
1535 */
voice_check(int voice)1536 SAMPLE *voice_check(int voice)
1537 {
1538 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1539 if (virt_voice[voice].sample) {
1540 if (virt_voice[voice].num < 0)
1541 return NULL;
1542
1543 if (virt_voice[voice].autokill)
1544 if (voice_get_position(voice) < 0)
1545 return NULL;
1546
1547 return (SAMPLE*)virt_voice[voice].sample;
1548 }
1549 else
1550 return NULL;
1551 }
1552
1553 END_OF_FUNCTION(voice_check);
1554
1555
1556
1557 /* voice_get_position:
1558 * Returns the current play position of a voice, or -1 if that cannot
1559 * be determined (because it has finished or been preempted by a
1560 * different sound).
1561 */
voice_get_position(int voice)1562 int voice_get_position(int voice)
1563 {
1564 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1565 if (virt_voice[voice].num >= 0)
1566 return digi_driver->get_position(virt_voice[voice].num);
1567 else
1568 return -1;
1569 }
1570
1571 END_OF_FUNCTION(voice_get_position);
1572
1573
1574
1575 /* voice_set_position:
1576 * Sets the play position of a voice.
1577 */
voice_set_position(int voice,int position)1578 void voice_set_position(int voice, int position)
1579 {
1580 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1581 if (virt_voice[voice].num >= 0)
1582 digi_driver->set_position(virt_voice[voice].num, position);
1583 }
1584
1585 END_OF_FUNCTION(voice_set_position);
1586
1587
1588
1589 /* voice_set_playmode:
1590 * Sets the loopmode of a voice.
1591 */
voice_set_playmode(int voice,int playmode)1592 void voice_set_playmode(int voice, int playmode)
1593 {
1594 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1595 if (virt_voice[voice].num >= 0) {
1596 _phys_voice[virt_voice[voice].num].playmode = playmode;
1597 digi_driver->loop_voice(virt_voice[voice].num, playmode);
1598
1599 if (playmode & PLAYMODE_BACKWARD)
1600 digi_driver->set_position(virt_voice[voice].num, virt_voice[voice].sample->len-1);
1601 }
1602 }
1603
1604 END_OF_FUNCTION(voice_set_playmode);
1605
1606
1607
1608 /* voice_get_volume:
1609 * Returns the current volume of a voice, or -1 if that cannot
1610 * be determined (because it has finished or been preempted by a
1611 * different sound).
1612 */
voice_get_volume(int voice)1613 int voice_get_volume(int voice)
1614 {
1615 int vol;
1616 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1617
1618 if (virt_voice[voice].num >= 0)
1619 vol = digi_driver->get_volume(virt_voice[voice].num);
1620 else
1621 vol = -1;
1622
1623 if ((vol >= 0) && (_digi_volume >= 0)) {
1624 if (_digi_volume > 0)
1625 vol = CLAMP(0, (vol * 255) / _digi_volume, 255);
1626 else
1627 vol = 0;
1628 }
1629
1630 return vol;
1631 }
1632
1633 END_OF_FUNCTION(voice_get_volume);
1634
1635
1636
1637 /* voice_set_volume:
1638 * Sets the current volume of a voice.
1639 */
voice_set_volume(int voice,int volume)1640 void voice_set_volume(int voice, int volume)
1641 {
1642 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1643 ASSERT(volume >= 0 && volume <= 255);
1644
1645 if (_digi_volume >= 0)
1646 volume = (volume * _digi_volume) / 255;
1647
1648 if (virt_voice[voice].num >= 0) {
1649 _phys_voice[virt_voice[voice].num].vol = volume << 12;
1650 _phys_voice[virt_voice[voice].num].dvol = 0;
1651
1652 digi_driver->set_volume(virt_voice[voice].num, volume);
1653 }
1654 }
1655
1656 END_OF_FUNCTION(voice_set_volume);
1657
1658
1659
1660 /* voice_ramp_volume:
1661 * Begins a volume ramp operation.
1662 */
voice_ramp_volume(int voice,int time,int endvol)1663 void voice_ramp_volume(int voice, int time, int endvol)
1664 {
1665 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1666 ASSERT(endvol >= 0 && endvol <= 255);
1667 ASSERT(time >= 0);
1668
1669 if (_digi_volume >= 0)
1670 endvol = (endvol * _digi_volume) / 255;
1671
1672 if (virt_voice[voice].num >= 0) {
1673 if (digi_driver->ramp_volume) {
1674 digi_driver->ramp_volume(virt_voice[voice].num, time, endvol);
1675 }
1676 else {
1677 int d = (endvol << 12) - _phys_voice[virt_voice[voice].num].vol;
1678 time = MAX(time * SWEEP_FREQ / 1000, 1);
1679 _phys_voice[virt_voice[voice].num].target_vol = endvol << 12;
1680 _phys_voice[virt_voice[voice].num].dvol = d / time;
1681 }
1682 }
1683 }
1684
1685 END_OF_FUNCTION(voice_ramp_volume);
1686
1687
1688
1689 /* voice_stop_volumeramp:
1690 * Ends a volume ramp operation.
1691 */
voice_stop_volumeramp(int voice)1692 void voice_stop_volumeramp(int voice)
1693 {
1694 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1695 if (virt_voice[voice].num >= 0) {
1696 _phys_voice[virt_voice[voice].num].dvol = 0;
1697
1698 if (digi_driver->stop_volume_ramp)
1699 digi_driver->stop_volume_ramp(virt_voice[voice].num);
1700 }
1701 }
1702
1703 END_OF_FUNCTION(voice_stop_volumeramp);
1704
1705
1706
1707 /* voice_get_frequency:
1708 * Returns the current frequency of a voice, or -1 if that cannot
1709 * be determined (because it has finished or been preempted by a
1710 * different sound).
1711 */
voice_get_frequency(int voice)1712 int voice_get_frequency(int voice)
1713 {
1714 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1715 if (virt_voice[voice].num >= 0)
1716 return digi_driver->get_frequency(virt_voice[voice].num);
1717 else
1718 return -1;
1719 }
1720
1721 END_OF_FUNCTION(voice_get_frequency);
1722
1723
1724
1725 /* voice_set_frequency:
1726 * Sets the pitch of a voice.
1727 */
voice_set_frequency(int voice,int frequency)1728 void voice_set_frequency(int voice, int frequency)
1729 {
1730 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1731 ASSERT(frequency > 0);
1732
1733 if (virt_voice[voice].num >= 0) {
1734 _phys_voice[virt_voice[voice].num].freq = frequency << 12;
1735 _phys_voice[virt_voice[voice].num].dfreq = 0;
1736
1737 digi_driver->set_frequency(virt_voice[voice].num, frequency);
1738 }
1739 }
1740
1741 END_OF_FUNCTION(voice_set_frequency);
1742
1743
1744
1745 /* voice_sweep_frequency:
1746 * Begins a frequency sweep (glissando) operation.
1747 */
voice_sweep_frequency(int voice,int time,int endfreq)1748 void voice_sweep_frequency(int voice, int time, int endfreq)
1749 {
1750 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1751 ASSERT(endfreq > 0);
1752 ASSERT(time >= 0);
1753
1754 if (virt_voice[voice].num >= 0) {
1755 if (digi_driver->sweep_frequency) {
1756 digi_driver->sweep_frequency(virt_voice[voice].num, time, endfreq);
1757 }
1758 else {
1759 int d = (endfreq << 12) - _phys_voice[virt_voice[voice].num].freq;
1760 time = MAX(time * SWEEP_FREQ / 1000, 1);
1761 _phys_voice[virt_voice[voice].num].target_freq = endfreq << 12;
1762 _phys_voice[virt_voice[voice].num].dfreq = d / time;
1763 }
1764 }
1765 }
1766
1767 END_OF_FUNCTION(voice_sweep_frequency);
1768
1769
1770
1771 /* voice_stop_frequency_sweep:
1772 * Ends a frequency sweep.
1773 */
voice_stop_frequency_sweep(int voice)1774 void voice_stop_frequency_sweep(int voice)
1775 {
1776 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1777 if (virt_voice[voice].num >= 0) {
1778 _phys_voice[virt_voice[voice].num].dfreq = 0;
1779
1780 if (digi_driver->stop_frequency_sweep)
1781 digi_driver->stop_frequency_sweep(virt_voice[voice].num);
1782 }
1783 }
1784
1785 END_OF_FUNCTION(voice_stop_frequency_sweep);
1786
1787
1788
1789 /* voice_get_pan:
1790 * Returns the current pan position of a voice, or -1 if that cannot
1791 * be determined (because it has finished or been preempted by a
1792 * different sound).
1793 */
voice_get_pan(int voice)1794 int voice_get_pan(int voice)
1795 {
1796 int pan;
1797 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1798
1799 if (virt_voice[voice].num >= 0)
1800 pan = digi_driver->get_pan(virt_voice[voice].num);
1801 else
1802 pan = -1;
1803
1804 if ((pan >= 0) && (_sound_flip_pan))
1805 pan = 255 - pan;
1806
1807 return pan;
1808 }
1809
1810 END_OF_FUNCTION(voice_get_pan);
1811
1812
1813
1814 /* voice_set_pan:
1815 * Sets the pan position of a voice.
1816 */
voice_set_pan(int voice,int pan)1817 void voice_set_pan(int voice, int pan)
1818 {
1819 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1820 ASSERT(pan >= 0 && pan <= 255);
1821 if (_sound_flip_pan)
1822 pan = 255 - pan;
1823
1824 if (virt_voice[voice].num >= 0) {
1825 _phys_voice[virt_voice[voice].num].pan = pan << 12;
1826 _phys_voice[virt_voice[voice].num].dpan = 0;
1827
1828 digi_driver->set_pan(virt_voice[voice].num, pan);
1829 }
1830 }
1831
1832 END_OF_FUNCTION(voice_set_pan);
1833
1834
1835
1836 /* voice_sweep_pan:
1837 * Begins a pan sweep (left <-> right movement) operation.
1838 */
voice_sweep_pan(int voice,int time,int endpan)1839 void voice_sweep_pan(int voice, int time, int endpan)
1840 {
1841 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1842 ASSERT(endpan >= 0 && endpan <= 255);
1843 ASSERT(time >= 0);
1844
1845 if (_sound_flip_pan)
1846 endpan = 255 - endpan;
1847
1848 if (virt_voice[voice].num >= 0) {
1849 if (digi_driver->sweep_pan) {
1850 digi_driver->sweep_pan(virt_voice[voice].num, time, endpan);
1851 }
1852 else {
1853 int d = (endpan << 12) - _phys_voice[virt_voice[voice].num].pan;
1854 time = MAX(time * SWEEP_FREQ / 1000, 1);
1855 _phys_voice[virt_voice[voice].num].target_pan = endpan << 12;
1856 _phys_voice[virt_voice[voice].num].dpan = d / time;
1857 }
1858 }
1859 }
1860
1861 END_OF_FUNCTION(voice_sweep_pan);
1862
1863
1864
1865 /* voice_stop_pan_sweep:
1866 * Ends a pan sweep.
1867 */
voice_stop_pan_sweep(int voice)1868 void voice_stop_pan_sweep(int voice)
1869 {
1870 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1871 if (virt_voice[voice].num >= 0) {
1872 _phys_voice[virt_voice[voice].num].dpan = 0;
1873
1874 if (digi_driver->stop_pan_sweep)
1875 digi_driver->stop_pan_sweep(virt_voice[voice].num);
1876 }
1877 }
1878
1879 END_OF_FUNCTION(voice_stop_pan_sweep);
1880
1881
1882
1883 /* voice_set_echo:
1884 * Sets the echo parameters of a voice.
1885 */
voice_set_echo(int voice,int strength,int delay)1886 void voice_set_echo(int voice, int strength, int delay)
1887 {
1888 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1889 if ((virt_voice[voice].num >= 0) && (digi_driver->set_echo))
1890 digi_driver->set_echo(virt_voice[voice].num, strength, delay);
1891 }
1892
1893 END_OF_FUNCTION(voice_set_echo);
1894
1895
1896
1897 /* voice_set_tremolo:
1898 * Sets the tremolo parameters of a voice.
1899 */
voice_set_tremolo(int voice,int rate,int depth)1900 void voice_set_tremolo(int voice, int rate, int depth)
1901 {
1902 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1903 if ((virt_voice[voice].num >= 0) && (digi_driver->set_tremolo))
1904 digi_driver->set_tremolo(virt_voice[voice].num, rate, depth);
1905 }
1906
1907 END_OF_FUNCTION(voice_set_tremolo);
1908
1909
1910
1911 /* voice_set_vibrato:
1912 * Sets the vibrato parameters of a voice.
1913 */
voice_set_vibrato(int voice,int rate,int depth)1914 void voice_set_vibrato(int voice, int rate, int depth)
1915 {
1916 ASSERT(voice >= 0 && voice < VIRTUAL_VOICES);
1917 if ((virt_voice[voice].num >= 0) && (digi_driver->set_vibrato))
1918 digi_driver->set_vibrato(virt_voice[voice].num, rate, depth);
1919 }
1920
1921 END_OF_FUNCTION(voice_set_vibrato);
1922
1923
1924
1925 /* update_sweeps:
1926 * Timer callback routine used to implement volume/frequency/pan sweep
1927 * effects, for those drivers that can't do them directly.
1928 */
update_sweeps(void)1929 static void update_sweeps(void)
1930 {
1931 int phys_voices, i;
1932
1933 phys_voices = digi_driver->voices;
1934 if (midi_driver->max_voices < 0)
1935 phys_voices += midi_driver->voices;
1936
1937 for (i=0; i<phys_voices; i++) {
1938 if (_phys_voice[i].num >= 0) {
1939 /* update volume ramp */
1940 if ((!digi_driver->ramp_volume) && (_phys_voice[i].dvol)) {
1941 _phys_voice[i].vol += _phys_voice[i].dvol;
1942
1943 if (((_phys_voice[i].dvol > 0) && (_phys_voice[i].vol >= _phys_voice[i].target_vol)) ||
1944 ((_phys_voice[i].dvol < 0) && (_phys_voice[i].vol <= _phys_voice[i].target_vol))) {
1945 _phys_voice[i].vol = _phys_voice[i].target_vol;
1946 _phys_voice[i].dvol = 0;
1947 }
1948
1949 digi_driver->set_volume(i, _phys_voice[i].vol >> 12);
1950 }
1951
1952 /* update frequency sweep */
1953 if ((!digi_driver->sweep_frequency) && (_phys_voice[i].dfreq)) {
1954 _phys_voice[i].freq += _phys_voice[i].dfreq;
1955
1956 if (((_phys_voice[i].dfreq > 0) && (_phys_voice[i].freq >= _phys_voice[i].target_freq)) ||
1957 ((_phys_voice[i].dfreq < 0) && (_phys_voice[i].freq <= _phys_voice[i].target_freq))) {
1958 _phys_voice[i].freq = _phys_voice[i].target_freq;
1959 _phys_voice[i].dfreq = 0;
1960 }
1961
1962 digi_driver->set_frequency(i, _phys_voice[i].freq >> 12);
1963 }
1964
1965 /* update pan sweep */
1966 if ((!digi_driver->sweep_pan) && (_phys_voice[i].dpan)) {
1967 _phys_voice[i].pan += _phys_voice[i].dpan;
1968
1969 if (((_phys_voice[i].dpan > 0) && (_phys_voice[i].pan >= _phys_voice[i].target_pan)) ||
1970 ((_phys_voice[i].dpan < 0) && (_phys_voice[i].pan <= _phys_voice[i].target_pan))) {
1971 _phys_voice[i].pan = _phys_voice[i].target_pan;
1972 _phys_voice[i].dpan = 0;
1973 }
1974
1975 digi_driver->set_pan(i, _phys_voice[i].pan >> 12);
1976 }
1977 }
1978 }
1979 }
1980
1981 END_OF_STATIC_FUNCTION(update_sweeps);
1982
1983
1984
1985 /* get_sound_input_cap_bits:
1986 * Recording capabilities: number of bits
1987 */
get_sound_input_cap_bits(void)1988 int get_sound_input_cap_bits(void)
1989 {
1990 return digi_input_driver->rec_cap_bits;
1991 }
1992
1993
1994
1995 /* get_sound_input_cap_stereo:
1996 * Recording capabilities: stereo
1997 */
get_sound_input_cap_stereo(void)1998 int get_sound_input_cap_stereo(void)
1999 {
2000 return digi_input_driver->rec_cap_stereo;
2001 }
2002
2003
2004
2005 /* get_sound_input_cap_rate:
2006 * Recording capabilities: maximum sampling rate
2007 */
get_sound_input_cap_rate(int bits,int stereo)2008 int get_sound_input_cap_rate(int bits, int stereo)
2009 {
2010 if (digi_input_driver->rec_cap_rate)
2011 return digi_input_driver->rec_cap_rate(bits, stereo);
2012 else
2013 return 0;
2014 }
2015
2016
2017
2018 /* get_sound_input_cap_parm:
2019 * Checks whether given parameters can be set.
2020 */
get_sound_input_cap_parm(int rate,int bits,int stereo)2021 int get_sound_input_cap_parm(int rate, int bits, int stereo)
2022 {
2023 if (digi_input_driver->rec_cap_parm)
2024 return digi_input_driver->rec_cap_parm(rate, bits, stereo);
2025 else
2026 return 0;
2027 }
2028
2029
2030
2031 /* set_sound_input_source:
2032 * Selects the sampling source for audio recording.
2033 */
set_sound_input_source(int source)2034 int set_sound_input_source(int source)
2035 {
2036 if (digi_input_driver->rec_source)
2037 return digi_input_driver->rec_source(source);
2038 else
2039 return -1;
2040 }
2041
2042
2043
2044 /* start_sound_input:
2045 * Starts recording, and returns recording buffer size.
2046 */
start_sound_input(int rate,int bits,int stereo)2047 int start_sound_input(int rate, int bits, int stereo)
2048 {
2049 if (digi_input_driver->rec_start)
2050 return digi_input_driver->rec_start(rate, bits, stereo);
2051 else
2052 return 0;
2053 }
2054
2055
2056
2057 /* stop_sound_input:
2058 * Ends recording.
2059 */
stop_sound_input(void)2060 void stop_sound_input(void)
2061 {
2062 if (digi_input_driver->rec_stop)
2063 digi_input_driver->rec_stop();
2064 }
2065
2066
2067
2068 /* read_sound_input:
2069 * Reads audio data.
2070 */
read_sound_input(void * buffer)2071 int read_sound_input(void *buffer)
2072 {
2073 if (digi_input_driver->rec_read)
2074 return digi_input_driver->rec_read(buffer);
2075 else
2076 return 0;
2077 }
2078
2079 END_OF_FUNCTION(read_sound_input);
2080
2081
2082
2083 /* sound_lock_mem:
2084 * Locks memory used by the functions in this file.
2085 */
sound_lock_mem(void)2086 static void sound_lock_mem(void)
2087 {
2088 LOCK_VARIABLE(digi_none);
2089 LOCK_VARIABLE(_midi_none);
2090 LOCK_VARIABLE(digi_card);
2091 LOCK_VARIABLE(midi_card);
2092 LOCK_VARIABLE(digi_driver);
2093 LOCK_VARIABLE(midi_driver);
2094 LOCK_VARIABLE(digi_recorder);
2095 LOCK_VARIABLE(midi_recorder);
2096 LOCK_VARIABLE(virt_voice);
2097 LOCK_VARIABLE(_phys_voice);
2098 LOCK_VARIABLE(_digi_volume);
2099 LOCK_VARIABLE(_midi_volume);
2100 LOCK_VARIABLE(_sound_flip_pan);
2101 LOCK_VARIABLE(_sound_hq);
2102 LOCK_FUNCTION(_dummy_detect);
2103 LOCK_FUNCTION(play_sample);
2104 LOCK_FUNCTION(adjust_sample);
2105 LOCK_FUNCTION(stop_sample);
2106 LOCK_FUNCTION(allocate_voice);
2107 LOCK_FUNCTION(deallocate_voice);
2108 LOCK_FUNCTION(reallocate_voice);
2109 LOCK_FUNCTION(voice_start);
2110 LOCK_FUNCTION(voice_stop);
2111 LOCK_FUNCTION(voice_set_priority);
2112 LOCK_FUNCTION(voice_check);
2113 LOCK_FUNCTION(voice_get_position);
2114 LOCK_FUNCTION(voice_set_position);
2115 LOCK_FUNCTION(voice_set_playmode);
2116 LOCK_FUNCTION(voice_get_volume);
2117 LOCK_FUNCTION(voice_set_volume);
2118 LOCK_FUNCTION(voice_ramp_volume);
2119 LOCK_FUNCTION(voice_stop_volumeramp);
2120 LOCK_FUNCTION(voice_get_frequency);
2121 LOCK_FUNCTION(voice_set_frequency);
2122 LOCK_FUNCTION(voice_sweep_frequency);
2123 LOCK_FUNCTION(voice_stop_frequency_sweep);
2124 LOCK_FUNCTION(voice_get_pan);
2125 LOCK_FUNCTION(voice_set_pan);
2126 LOCK_FUNCTION(voice_sweep_pan);
2127 LOCK_FUNCTION(voice_stop_pan_sweep);
2128 LOCK_FUNCTION(voice_set_echo);
2129 LOCK_FUNCTION(voice_set_tremolo);
2130 LOCK_FUNCTION(voice_set_vibrato);
2131 LOCK_FUNCTION(update_sweeps);
2132 LOCK_FUNCTION(read_sound_input);
2133 }
2134
2135