3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
10 * By Shawn Hargreaves,
16 * Sound setup routines and API framework functions.
18 * See readme.txt for copyright information.
31 #include <sys/farptr.h>
39 /* dummy functions for the nosound drivers */
40 int _dummy_detect() { return TRUE; }
41 int _dummy_init(int voices) { return 0; }
42 void _dummy_exit() { }
43 int _dummy_mixer_volume(int volume) { return 0; }
44 void _dummy_init_voice(int voice, SAMPLE *sample) { }
45 void _dummy_noop1(int p) { }
46 void _dummy_noop2(int p1, int p2) { }
47 void _dummy_noop3(int p1, int p2, int p3) { }
48 int _dummy_get_position(int voice) { return -1; }
49 int _dummy_get(int voice) { return 0; }
50 void _dummy_raw_midi(unsigned char data) { }
51 int _dummy_load_patches(char *patches, char *drums) { return 0; }
52 void _dummy_adjust_patches(char *patches, char *drums) { }
53 void _dummy_key_on(int inst, int note, int bend, int vol, int pan) { }
55 /* put this after all the dummy functions, so they will all get locked */
56 END_OF_FUNCTION(_dummy_detect);
60 DIGI_DRIVER digi_none =
62 "No sound", "The sound of silence",
93 MIDI_DRIVER midi_none =
95 "No sound", "The sound of silence",
96 0, 0, 0xFFFF, 0, -1, -1,
103 _dummy_adjust_patches,
113 int digi_card = DIGI_AUTODETECT; /* current driver ID numbers */
114 int midi_card = MIDI_AUTODETECT;
116 DIGI_DRIVER *digi_driver = &digi_none; /* these things do all the work */
117 MIDI_DRIVER *midi_driver = &midi_none;
119 static int sound_installed = FALSE; /* are we installed? */
121 static int digi_reserve = -1; /* how many voices to reserve */
122 static int midi_reserve = -1;
124 VOICE _voice[VIRTUAL_VOICES]; /* list of active samples */
126 PHYS_VOICE _phys_voice[DIGI_VOICES]; /* physical -> virtual voice map */
128 int _digi_volume = -1; /* current volume settings */
129 int _midi_volume = -1;
131 int _flip_pan = FALSE; /* reverse l/r sample panning? */
133 int _sb_freq = -1; /* hardware parameters */
140 #define SWEEP_FREQ 50
142 static void update_sweeps();
143 static void sound_lock_mem();
145 int (*_midi_init)() = NULL;
146 void (*_midi_exit)() = NULL;
150 /* read_sound_config:
151 * Helper for reading the sound hardware configuration data.
153 static void read_sound_config()
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);
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().
174 int detect_digi_driver(int driver_id)
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;
194 return digi_none.max_voices;
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().
209 int detect_midi_driver(int driver_id)
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;
229 return midi_none.max_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.
243 void reserve_voices(int digi_voices, int midi_voices)
245 digi_reserve = digi_voices;
246 midi_reserve = midi_voices;
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.
257 int install_sound(int digi, int midi, char *cfg_path)
259 int digi_voices, midi_voices;
265 for (c=0; c<VIRTUAL_VOICES; c++) {
266 _voice[c].sample = NULL;
270 for (c=0; c<DIGI_VOICES; c++)
271 _phys_voice[c].num = -1;
273 /* initialise the midi file player */
275 if (_midi_init() != 0)
278 /* register_datafile_object(DAT_SAMPLE, NULL, (void (*)(void *))destroy_sample);*/
283 /* read config information */
284 if (digi_card == DIGI_AUTODETECT)
285 digi_card = get_config_int("sound", "digi_card", DIGI_AUTODETECT);
287 if (midi_card == MIDI_AUTODETECT)
288 midi_card = get_config_int("sound", "midi_card", MIDI_AUTODETECT);
290 if (digi_reserve < 0)
291 digi_reserve = get_config_int("sound", "digi_voices", -1);
293 if (midi_reserve < 0)
294 midi_reserve = get_config_int("sound", "midi_voices", -1);
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;
317 /* autodetect digital 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;
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;
346 /* autodetect 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;
358 /* work out how many voices to allocate for each driver */
359 if (digi_reserve >= 0)
360 digi_voices = digi_reserve;
362 digi_voices = digi_driver->def_voices;
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;
369 midi_voices = MID(0, digi_driver->max_voices - digi_voices, midi_driver->def_voices);
371 digi_voices += midi_voices;
374 /* MIDI driver has voices of its own */
375 if (midi_reserve >= 0)
376 midi_voices = midi_reserve;
378 midi_voices = midi_driver->def_voices;
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;
392 /* initialise the digital sound driver */
393 if (digi_driver->init(digi_voices) != 0) {
394 digi_driver = &digi_none;
395 midi_driver = &midi_none;
401 /* initialise the midi driver */
402 if (midi_driver->init(midi_voices) != 0) {
404 digi_driver = &digi_none;
405 midi_driver = &midi_none;
411 digi_driver->voices = MIN(digi_driver->voices, DIGI_VOICES);
412 midi_driver->voices = MIN(midi_driver->voices, MIDI_VOICES);
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");
421 digi_driver = &digi_none;
422 midi_driver = &midi_none;
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;
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;
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));
447 /* set the global sound volume */
448 if ((_digi_volume >= 0) || (_midi_volume >= 0))
449 set_volume(_digi_volume, _midi_volume);
451 _add_exit_func(remove_sound);
452 sound_installed = TRUE;
459 * Sound module cleanup routine.
465 if (sound_installed) {
466 remove_int(update_sweeps);
468 for (c=0; c<VIRTUAL_VOICES; c++)
469 if (_voice[c].sample)
476 midi_driver = &midi_none;
479 digi_driver = &digi_none;
481 _remove_exit_func(remove_sound);
482 sound_installed = FALSE;
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
495 void set_volume(int digi_volume, int midi_volume)
497 if (digi_volume >= 0) {
498 digi_volume = MID(0, digi_volume, 255);
500 if ((digi_driver->mixer_volume) &&
501 (digi_driver->mixer_volume(digi_volume) == 0))
504 _digi_volume = digi_volume;
507 if (midi_volume >= 0) {
508 midi_volume = MID(0, midi_volume, 255);
510 if ((midi_driver->mixer_volume) &&
511 (midi_driver->mixer_volume(midi_volume) == 0))
514 _midi_volume = midi_volume;
521 * Locks a SAMPLE struct into physical memory. Pretty important, since
522 * they are mostly accessed inside interrupt handlers.
524 void lock_sample(SAMPLE *spl)
527 _go32_dpmi_lock_data(spl, sizeof(SAMPLE));
528 _go32_dpmi_lock_data(spl->data, spl->len*spl->bits/8);
535 * Loads a sample from disk.
537 SAMPLE *load_sample(char *filename)
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);
550 * Reads a mono 8 bit VOC format sample file, returning a SAMPLE structure,
553 SAMPLE *load_voc(char *filename)
563 f = pack_fopen(filename, F_READ);
567 pack_fread(buffer, 0x16, f);
569 if (memcmp(buffer, "Creative Voice File", 0x13))
572 if (pack_igetw(f) != 0x010A) /* version: should be 0x010A */
575 if (pack_igetw(f) != 0x1129) /* subversion: should be 0x1129 */
578 if (pack_getc(f) != 0x01) /* sound data: should be 0x01 */
581 len = pack_igetw(f); /* length is three bytes long: two */
582 x = pack_getc(f); /* .. and one byte */
586 x = pack_getc(f); /* one byte of frequency */
587 freq = 1000000 / (256-x);
589 x = pack_getc(f); /* skip one byte */
591 spl = malloc(sizeof(SAMPLE));
602 spl->data = malloc(len);
608 pack_fread(spl->data, len, f);
630 * Reads a mono RIFF WAV format sample file, returning a SAMPLE structure,
633 SAMPLE *load_wav(char *filename)
645 f = pack_fopen(filename, F_READ);
649 pack_fread(buffer, 12, f); /* check RIFF header */
650 if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4))
653 while (!pack_feof(f)) {
654 if (pack_fread(buffer, 4, f) != 4)
657 length = pack_igetl(f); /* read chunk length */
659 if (memcmp(buffer, "fmt ", 4) == 0) {
660 i = pack_igetw(f); /* should be 1 for PCM data */
665 i = pack_igetw(f); /* should be 1 for mono data */
670 freq = pack_igetl(f); /* sample frequency */
673 trashtmp=pack_igetl(f); /* skip six bytes */
674 trashtmp=pack_igetw(f);
677 bits = pack_igetw(f); /* 8 or 16 bit data? */
679 if ((bits != 8) && (bits != 16))
682 else if (memcmp(buffer, "data", 4) == 0) {
687 spl = malloc(sizeof(SAMPLE));
689 if (spl) { /* initialise the sample struct */
698 spl->data = malloc(length);
704 else { /* read the actual sample data */
706 pack_fread(spl->data, length, f);
709 for (i=0; i<len; i++) {
711 ((signed short *)spl->data)[i] = s^0x8000;
726 while (length > 0) { /* skip the remainder of the chunk */
727 if (pack_getc(f) == EOF)
747 * Frees a SAMPLE struct, checking whether the sample is currently playing,
748 * and stopping it if it is.
750 void destroy_sample(SAMPLE *spl)
756 _unlock_dpmi_data(spl->data, spl->len*spl->bits/8);
760 _unlock_dpmi_data(spl, sizeof(SAMPLE));
768 * Converts a pitch from the relative 1000 = original format to an absolute
771 static inline int absolute_freq(int freq, SAMPLE *spl)
776 return (spl->freq * freq) / 1000;
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
791 int play_sample(SAMPLE *spl, int vol, int pan, int freq, int loop)
793 int voice = allocate_voice(spl);
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));
801 release_voice(voice);
807 END_OF_FUNCTION(play_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
820 void adjust_sample(SAMPLE *spl, int vol, int pan, int freq, int loop)
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));
835 END_OF_FUNCTION(adjust_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.
844 void stop_sample(SAMPLE *spl)
848 for (c=0; c<VIRTUAL_VOICES; c++)
849 if (_voice[c].sample == spl)
853 END_OF_FUNCTION(stop_sample);
857 /* allocate_physical_voice:
858 * Allocates a physical voice, killing off others as required in order
859 * to make room for it.
861 static inline int allocate_physical_voice(int priority)
869 /* look for a free voice */
870 for (c=0; c<digi_driver->voices; c++)
871 if (_phys_voice[c].num < 0)
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;
881 _phys_voice[c].num = -1;
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;
890 /* sort by voice priorities */
891 if (voice->priority <= priority) {
892 score = 65536 - voice->priority * 256;
894 /* bias with a least-recently-used counter */
895 score += MID(0, retrace_count - voice->time, 32768);
897 /* bias according to whether the voice is looping or not */
898 if (!(_phys_voice[c].playmode & PLAYMODE_LOOP))
901 if (score > best_score) {
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;
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
927 static inline int allocate_virtual_voice()
931 virt_voices = VIRTUAL_VOICES;
932 if (midi_driver->max_voices < 0)
933 virt_voices -= midi_driver->voices;
935 /* look for a free voice */
936 for (c=0; c<virt_voices; c++)
937 if (!_voice[c].sample)
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;
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;
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 :-)
973 int allocate_voice(SAMPLE *spl)
975 int phys = allocate_physical_voice(spl->priority);
976 int virt = allocate_virtual_voice();
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;
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;
995 digi_driver->init_voice(phys, spl);
1002 END_OF_FUNCTION(allocate_voice);
1006 /* deallocate_voice:
1007 * Releases a voice that was previously returned by allocate_voice().
1009 void deallocate_voice(int voice)
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;
1018 _voice[voice].sample = NULL;
1021 END_OF_FUNCTION(deallocate_voice);
1025 /* reallocate_voice:
1026 * Switches an already-allocated voice to use a different sample.
1028 void reallocate_voice(int voice, SAMPLE *spl)
1030 int phys = _voice[voice].num;
1033 digi_driver->stop_voice(phys);
1034 digi_driver->release_voice(phys);
1037 _voice[voice].sample = spl;
1038 _voice[voice].autokill = FALSE;
1039 _voice[voice].time = retrace_count;
1040 _voice[voice].priority = spl->priority;
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;
1051 digi_driver->init_voice(phys, spl);
1055 END_OF_FUNCTION(reallocate_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.
1063 void release_voice(int voice)
1065 _voice[voice].autokill = TRUE;
1068 END_OF_FUNCTION(release_voice);
1073 * Starts a voice playing.
1075 void voice_start(int voice)
1077 if (_voice[voice].num >= 0)
1078 digi_driver->start_voice(_voice[voice].num);
1080 _voice[voice].time = retrace_count;
1083 END_OF_FUNCTION(voice_start);
1088 * Stops a voice from playing.
1090 void voice_stop(int voice)
1092 if (_voice[voice].num >= 0)
1093 digi_driver->stop_voice(_voice[voice].num);
1096 END_OF_FUNCTION(voice_stop);
1100 /* voice_set_priority:
1101 * Adjusts the priority of a voice (0-255).
1103 void voice_set_priority(int voice, int priority)
1105 _voice[voice].priority = priority;
1108 END_OF_FUNCTION(voice_set_priority);
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.
1116 SAMPLE *voice_check(int voice)
1118 if (_voice[voice].sample) {
1119 if (_voice[voice].num < 0)
1122 if (_voice[voice].autokill)
1123 if (voice_get_position(voice) < 0)
1126 return _voice[voice].sample;
1132 END_OF_FUNCTION(voice_check);
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
1141 int voice_get_position(int voice)
1143 if (_voice[voice].num >= 0)
1144 return digi_driver->get_position(_voice[voice].num);
1149 END_OF_FUNCTION(voice_get_position);
1153 /* voice_set_position:
1154 * Sets the play position of a voice.
1156 void voice_set_position(int voice, int position)
1158 if (_voice[voice].num >= 0)
1159 digi_driver->set_position(_voice[voice].num, position);
1162 END_OF_FUNCTION(voice_set_position);
1166 /* voice_set_playmode:
1167 * Sets the loopmode of a voice.
1169 void voice_set_playmode(int voice, int playmode)
1171 if (_voice[voice].num >= 0) {
1172 _phys_voice[_voice[voice].num].playmode = playmode;
1173 digi_driver->loop_voice(_voice[voice].num, playmode);
1175 if (playmode & PLAYMODE_BACKWARD)
1176 digi_driver->set_position(_voice[voice].num, _voice[voice].sample->len-1);
1180 END_OF_FUNCTION(voice_set_playmode);
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
1189 int voice_get_volume(int voice)
1193 if (_voice[voice].num >= 0)
1194 vol = digi_driver->get_volume(_voice[voice].num);
1198 if ((vol >= 0) && (_digi_volume >= 0)) {
1199 if (_digi_volume > 0)
1200 vol = MID(0, (vol * 255) / _digi_volume, 255);
1208 END_OF_FUNCTION(voice_get_volume);
1212 /* voice_set_volume:
1213 * Sets the current volume of a voice.
1215 void voice_set_volume(int voice, int volume)
1217 if (_digi_volume >= 0)
1218 volume = (volume * _digi_volume) / 255;
1220 if (_voice[voice].num >= 0) {
1221 _phys_voice[_voice[voice].num].vol = volume << 12;
1222 _phys_voice[_voice[voice].num].dvol = 0;
1224 digi_driver->set_volume(_voice[voice].num, volume);
1228 END_OF_FUNCTION(voice_set_volume);
1232 /* voice_ramp_volume:
1233 * Begins a volume ramp operation.
1235 void voice_ramp_volume(int voice, int time, int endvol)
1237 if (_digi_volume >= 0)
1238 endvol = (endvol * _digi_volume) / 255;
1240 if (_voice[voice].num >= 0) {
1241 if (digi_driver->ramp_volume) {
1242 digi_driver->ramp_volume(_voice[voice].num, time, endvol);
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;
1253 END_OF_FUNCTION(voice_ramp_volume);
1257 /* voice_stop_volumeramp:
1258 * Ends a volume ramp operation.
1260 void voice_stop_volumeramp(int voice)
1262 if (_voice[voice].num >= 0) {
1263 _phys_voice[_voice[voice].num].dvol = 0;
1265 if (digi_driver->stop_volume_ramp)
1266 digi_driver->stop_volume_ramp(_voice[voice].num);
1270 END_OF_FUNCTION(voice_stop_volumeramp);
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
1279 int voice_get_frequency(int voice)
1281 if (_voice[voice].num >= 0)
1282 return digi_driver->get_frequency(_voice[voice].num);
1287 END_OF_FUNCTION(voice_get_frequency);
1291 /* voice_set_frequency:
1292 * Sets the pitch of a voice.
1294 void voice_set_frequency(int voice, int frequency)
1296 if (_voice[voice].num >= 0) {
1297 _phys_voice[_voice[voice].num].freq = frequency << 12;
1298 _phys_voice[_voice[voice].num].dfreq = 0;
1300 digi_driver->set_frequency(_voice[voice].num, frequency);
1304 END_OF_FUNCTION(voice_set_frequency);
1308 /* voice_sweep_frequency:
1309 * Begins a frequency sweep (glissando) operation.
1311 void voice_sweep_frequency(int voice, int time, int endfreq)
1313 if (_voice[voice].num >= 0) {
1314 if (digi_driver->sweep_frequency) {
1315 digi_driver->sweep_frequency(_voice[voice].num, time, endfreq);
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;
1326 END_OF_FUNCTION(voice_sweep_frequency);
1330 /* voice_stop_frequency_sweep:
1331 * Ends a frequency sweep.
1333 void voice_stop_frequency_sweep(int voice)
1335 if (_voice[voice].num >= 0) {
1336 _phys_voice[_voice[voice].num].dfreq = 0;
1338 if (digi_driver->stop_frequency_sweep)
1339 digi_driver->stop_frequency_sweep(_voice[voice].num);
1343 END_OF_FUNCTION(voice_stop_frequency_sweep);
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
1352 int voice_get_pan(int voice)
1356 if (_voice[voice].num >= 0)
1357 pan = digi_driver->get_pan(_voice[voice].num);
1361 if ((pan >= 0) && (_flip_pan))
1367 END_OF_FUNCTION(voice_get_pan);
1372 * Sets the pan position of a voice.
1374 void voice_set_pan(int voice, int pan)
1379 if (_voice[voice].num >= 0) {
1380 _phys_voice[_voice[voice].num].pan = pan << 12;
1381 _phys_voice[_voice[voice].num].dpan = 0;
1383 digi_driver->set_pan(_voice[voice].num, pan);
1387 END_OF_FUNCTION(voice_set_pan);
1392 * Begins a pan sweep (left <-> right movement) operation.
1394 void voice_sweep_pan(int voice, int time, int endpan)
1397 endpan = 255 - endpan;
1399 if (_voice[voice].num >= 0) {
1400 if (digi_driver->sweep_pan) {
1401 digi_driver->sweep_pan(_voice[voice].num, time, endpan);
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;
1412 END_OF_FUNCTION(voice_sweep_pan);
1416 /* voice_stop_pan_sweep:
1419 void voice_stop_pan_sweep(int voice)
1421 if (_voice[voice].num >= 0) {
1422 _phys_voice[_voice[voice].num].dpan = 0;
1424 if (digi_driver->stop_pan_sweep)
1425 digi_driver->stop_pan_sweep(_voice[voice].num);
1429 END_OF_FUNCTION(voice_stop_pan_sweep);
1434 * Sets the echo parameters of a voice.
1436 void voice_set_echo(int voice, int strength, int delay)
1438 if ((_voice[voice].num >= 0) && (digi_driver->set_echo))
1439 digi_driver->set_echo(_voice[voice].num, strength, delay);
1442 END_OF_FUNCTION(voice_set_echo);
1446 /* voice_set_tremolo:
1447 * Sets the tremolo parameters of a voice.
1449 void voice_set_tremolo(int voice, int rate, int depth)
1451 if ((_voice[voice].num >= 0) && (digi_driver->set_tremolo))
1452 digi_driver->set_tremolo(_voice[voice].num, rate, depth);
1455 END_OF_FUNCTION(voice_set_tremolo);
1459 /* voice_set_vibrato:
1460 * Sets the vibrato parameters of a voice.
1462 void voice_set_vibrato(int voice, int rate, int depth)
1464 if ((_voice[voice].num >= 0) && (digi_driver->set_vibrato))
1465 digi_driver->set_vibrato(_voice[voice].num, rate, depth);
1468 END_OF_FUNCTION(voice_set_vibrato);
1473 * Timer callback routine used to implement volume/frequency/pan sweep
1474 * effects, for those drivers that can't do them directly.
1476 static void update_sweeps()
1480 phys_voices = digi_driver->voices;
1481 if (midi_driver->max_voices < 0)
1482 phys_voices += midi_driver->voices;
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;
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;
1496 digi_driver->set_volume(i, _phys_voice[i].vol >> 12);
1499 /* update frequency sweep */
1500 if ((!digi_driver->sweep_frequency) && (_phys_voice[i].dfreq)) {
1501 _phys_voice[i].freq += _phys_voice[i].dfreq;
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;
1509 digi_driver->set_frequency(i, _phys_voice[i].freq >> 12);
1512 /* update pan sweep */
1513 if ((!digi_driver->sweep_pan) && (_phys_voice[i].dpan)) {
1514 _phys_voice[i].pan += _phys_voice[i].dpan;
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;
1522 digi_driver->set_pan(i, _phys_voice[i].pan >> 12);
1528 static END_OF_FUNCTION(update_sweeps);
1533 * Locks memory used by the functions in this file.
1535 static void sound_lock_mem()
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);