1 // SDL digital audio support
11 //#include "SDL_audio.h"
17 #include "gr.h" // needed for piggy.h
26 int digi_driver_board = 0;
27 int digi_driver_port = 0;
28 int digi_driver_irq = 0;
29 int digi_driver_dma = 0;
30 //int digi_midi_type = 0; // Midi driver type
31 //int digi_midi_port = 0; // Midi driver port
32 int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz)
35 /* stub vars/functions for midi */
36 int digi_midi_type = 0;
37 int digi_midi_port = 0;
39 void digi_set_midi_volume( int mvolume ) {}
40 void digi_play_midi_song( char * filename, char * melodic_bank,
41 char * drum_bank, int loop ) {}
42 void digi_midi_pause() {}
43 void digi_midi_resume() {}
44 void digi_midi_stop() {}
48 //added on 980905 by adb to add inline fixmul for mixer on i386
50 #define do_fixmul(x,y) \
53 asm("imull %2\n\tshrdl %3,%1,%0" \
54 : "=a"(_ax), "=d"(_dx) \
55 : "rm"(y), "i"(16), "0"(x)); \
58 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
62 //changed on 980905 by adb to increase number of concurrent sounds
63 #define MAX_SOUND_SLOTS 32
65 #define SOUND_BUFFER_SIZE 512
69 /* This table is used to add two sound values together and pin
70 * the value to avoid overflow. (used with permission from ARDI)
71 * DPH: Taken from SDL/src/SDL_mixer.c.
73 static const unsigned char mix8[] =
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
87 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
88 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
89 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
90 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
91 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
92 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
93 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
94 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
95 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
96 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
97 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
98 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
99 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
100 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
101 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
102 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
103 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
104 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
105 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
106 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
107 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
108 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
109 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
112 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
117 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
124 #define SOF_USED 1 // Set if this sample is used
125 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
126 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
127 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
128 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
130 typedef struct sound_object {
131 short signature; // A unique signature to this sound
132 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
133 fix max_volume; // Max volume that this sound is playing at
134 fix max_distance; // The max distance that this sound can be heard at...
135 int volume; // Volume that this sound is playing at
136 int pan; // Pan value that this sound is playing at
137 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
138 short soundnum; // The sound number that is playing
141 short segnum; // Used if SOF_LINK_TO_POS field is used
146 short objnum; // Used if SOF_LINK_TO_OBJ field is used
151 #define lp_segnum link.pos.segnum
152 #define lp_sidenum link.pos.sidenum
153 #define lp_position link.pos.position
155 #define lo_objnum link.obj.objnum
156 #define lo_objsignature link.obj.objsignature
158 #define MAX_SOUND_OBJECTS 16
159 sound_object SoundObjects[MAX_SOUND_OBJECTS];
160 short next_signature=0;
162 //added/changed on 980905 by adb to make sfx volume work
163 #define SOUND_MAX_VOLUME (F1_0/2) // don't use real max like in original
164 int digi_volume = SOUND_MAX_VOLUME;
169 static int digi_initialised = 0;
170 static int timer_system_initialized = 0;
174 int playing; // Is there a sample playing on this channel?
175 int looped; // Play this sample looped?
176 fix pan; // 0 = far left, 1 = far right
177 fix volume; // 0 = nothing, 1 = fully on
178 //changed on 980905 by adb from char * to unsigned char *
179 unsigned char *samples;
181 unsigned int length; // Length of the sample
182 unsigned int position; // Position we are at at the moment.
183 } SoundSlots[MAX_SOUND_SLOTS];
185 //static SDL_AudioSpec WaveSpec;
186 static int digi_sounds_initialized = 0;
188 //added on 980905 by adb to add rotating/volume based sound kill system
189 static int digi_max_channels = 16;
190 static int next_handle = 0;
191 int SampleHandles[32];
192 void reset_sounds_on_channel(int channel);
195 void digi_reset_digi_sounds(void);
197 /* Audio mixing callback */
198 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
199 ULONG VC_WriteBytes(SBYTE *stream, ULONG len)
201 unsigned char *streamend;
202 struct sound_slot *sl;
204 // if (grd_curscreen)
205 // grd_curscreen->sc_canvas.cv_bitmap.bm_data[8]++;
206 len &= ~1; /* stereo -> always write 2 byte pairs */
207 streamend = stream + len;
212 while(stream < streamend) {
213 *(stream++) = (n & 256) ? 256 - (n & 255) : (n & 255);
220 memset(stream, 0x80, len);
222 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
226 unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
227 unsigned char *sp = stream;
232 if ((x = sl->pan) & 0x8000)
234 vl = 0x20000 - x * 2;
242 vl = fixmul(vl, (x = sl->volume));
244 while (sp < streamend)
253 sldata = sl->samples;
255 v = *(sldata++) - 0x80;
256 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
257 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
259 sl->position = sldata - sl->samples;
266 extern MDRIVER drv_sb;
267 MDRIVER *drv = &drv_sb;
268 char allegro_error[128];
270 int md_mode = DMODE_STEREO;
271 int md_mixfreq = digi_sample_rate; //11025;
272 int md_dmabufsize = 1024;
274 void install_int_ex(void (*)(), long speed);
275 void remove_int(void(*)());
279 // if (grd_curscreen)
280 // (*grd_curscreen->sc_canvas.cv_bitmap.bm_data)++;
283 /* Initialise audio devices. */
286 //added on 980905 by adb to init sound kill system
287 memset(SampleHandles, 255, sizeof(SampleHandles));
291 WaveSpec.freq = digi_sample_rate; //11025;
292 WaveSpec.format = AUDIO_U8 | AUDIO_STEREO;
293 WaveSpec.samples = SOUND_BUFFER_SIZE;
294 WaveSpec.callback = audio_mixcallback;
296 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
297 printf("Couldn't open audio: %s\n", SDL_GetError());
303 printf("Couldn't open audio: %s", myerr);
308 if (!timer_system_initialized)
311 install_int_ex(mm_timer, digi_timer_rate);
313 timer_set_function(mm_timer);
315 timer_system_initialized = 1;
323 digi_initialised = 1;
328 void digi_reset() { }
330 /* Shut down audio */
333 if (!digi_initialised) return;
334 digi_initialised = 0;
337 if (timer_system_initialized)
340 remove_int(mm_timer);
342 timer_set_function(NULL);
344 timer_system_initialized = 0;
351 /* Find the sound which actually equates to a sound number */
352 int digi_xlat_sound(int soundno)
354 if ( soundno < 0 ) return -1;
357 soundno = AltSounds[soundno];
358 if ( soundno == 255 ) return -1;
360 return Sounds[soundno];
363 static int get_free_slot()
366 for (i=0; i<MAX_SOUND_SLOTS; i++)
368 if (!SoundSlots[i].playing) return i;
373 int digi_start_sound(int soundnum, fix volume, fix pan)
378 if (!digi_initialised) return -1;
380 //added on 980905 by adb from original source to add sound kill system
381 // play at most digi_max_channel samples, if possible kill sample with low volume
385 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
387 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
389 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
391 if ( next_handle >= digi_max_channels )
396 //mprintf(( 0, "[SS:%d]", next_handle ));
397 SoundSlots[SampleHandles[next_handle]].playing = 0;
398 SampleHandles[next_handle] = -1;
402 slot = get_free_slot();
403 if (slot<0) return -1;
407 SoundSlots[slot].soundno = soundnum;
408 SoundSlots[slot].samples = GameSounds[soundnum].data;
409 SoundSlots[slot].length = GameSounds[soundnum].length;
410 SoundSlots[slot].volume = fixmul(digi_volume, volume);
411 SoundSlots[slot].pan = pan;
412 SoundSlots[slot].position = 0;
413 SoundSlots[slot].looped = 0;
414 SoundSlots[slot].playing = 1;
416 //added on 980905 by adb to add sound kill system from original sos digi.c
417 reset_sounds_on_channel(slot);
418 SampleHandles[next_handle] = slot;
420 if ( next_handle >= digi_max_channels )
427 //added on 980905 by adb to add sound kill system from original sos digi.c
428 void reset_sounds_on_channel( int channel )
432 for (i=0; i<digi_max_channels; i++)
433 if (SampleHandles[i] == channel)
434 SampleHandles[i] = -1;
438 int digi_start_sound_object(int obj)
442 if (!digi_initialised) return -1;
443 slot = get_free_slot();
445 if (slot<0) return -1;
448 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
449 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
450 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
451 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
452 SoundSlots[slot].pan = SoundObjects[obj].pan;
453 SoundSlots[slot].position = 0;
454 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
455 SoundSlots[slot].playing = 1;
457 SoundObjects[obj].signature = next_signature++;
458 SoundObjects[obj].handle = slot;
460 SoundObjects[obj].flags |= SOF_PLAYING;
461 //added on 980905 by adb to add sound kill system from original sos digi.c
462 reset_sounds_on_channel(slot);
469 // Play the given sound number.
470 // Volume is max at F1_0.
471 void digi_play_sample( int soundno, fix max_volume )
474 if ( Newdemo_state == ND_STATE_RECORDING )
475 newdemo_record_sound( soundno );
477 soundno = digi_xlat_sound(soundno);
479 if (!digi_initialised) return;
481 if (soundno < 0 ) return;
483 digi_start_sound(soundno, max_volume, F0_5);
486 // Play the given sound number. If the sound is already playing,
488 void digi_play_sample_once( int soundno, fix max_volume )
493 if ( Newdemo_state == ND_STATE_RECORDING )
494 newdemo_record_sound( soundno );
496 soundno = digi_xlat_sound(soundno);
498 if (!digi_initialised) return;
500 if (soundno < 0 ) return;
502 for (i=0; i < MAX_SOUND_SLOTS; i++)
503 if (SoundSlots[i].soundno == soundno)
504 SoundSlots[i].playing = 0;
505 digi_start_sound(soundno, max_volume, F0_5);
509 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
514 if ( Newdemo_state == ND_STATE_RECORDING ) {
516 newdemo_record_sound_3d_once( soundno, angle, volume );
518 newdemo_record_sound_3d( soundno, angle, volume );
521 soundno = digi_xlat_sound(soundno);
523 if (!digi_initialised) return;
524 if (soundno < 0 ) return;
526 if (volume < MIN_VOLUME ) return;
527 digi_start_sound(soundno, volume, angle);
530 void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int listener_seg, vms_vector * sound_pos, int sound_seg, fix max_volume, int *volume, int *pan, fix max_distance )
532 vms_vector vector_to_sound;
533 fix angle_from_ear, cosang,sinang;
540 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
542 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
543 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
545 if (distance < max_distance ) {
546 int num_search_segs = f2i(max_distance/20);
547 if ( num_search_segs < 1 ) num_search_segs = 1;
549 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
550 if ( path_distance > -1 ) {
551 *volume = max_volume - fixdiv(path_distance,max_distance);
552 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
554 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
555 fix_sincos(angle_from_ear,&sinang,&cosang);
556 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
557 if (Config_channels_reversed) cosang *= -1;
558 *pan = (cosang + F1_0)/2;
566 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
572 soundnum = digi_xlat_sound(org_soundnum);
574 if ( max_volume < 0 ) return -1;
575 // if ( max_volume > F1_0 ) max_volume = F1_0;
577 if (!digi_initialised) return -1;
578 if (soundnum < 0 ) return -1;
579 if (GameSounds[soundnum].data==NULL) {
583 if ((objnum<0)||(objnum>Highest_object_index))
587 // Hack to keep sounds from building up...
588 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
589 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
593 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
594 if (SoundObjects[i].flags==0)
597 if (i==MAX_SOUND_OBJECTS) {
598 mprintf((1, "Too many sound objects!\n" ));
602 SoundObjects[i].signature=next_signature++;
603 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
605 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
606 SoundObjects[i].lo_objnum = objnum;
607 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
608 SoundObjects[i].max_volume = max_volume;
609 SoundObjects[i].max_distance = max_distance;
610 SoundObjects[i].volume = 0;
611 SoundObjects[i].pan = 0;
612 SoundObjects[i].soundnum = soundnum;
614 objp = &Objects[SoundObjects[i].lo_objnum];
615 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
616 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
617 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
619 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
620 digi_start_sound_object(i);
622 return SoundObjects[i].signature;
625 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
626 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
628 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
633 soundnum = digi_xlat_sound(org_soundnum);
635 if ( max_volume < 0 ) return -1;
636 // if ( max_volume > F1_0 ) max_volume = F1_0;
638 if (!digi_initialised) return -1;
639 if (soundnum < 0 ) return -1;
640 if (GameSounds[soundnum].data==NULL) {
645 if ((segnum<0)||(segnum>Highest_segment_index))
649 // Hack to keep sounds from building up...
650 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
651 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
655 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
656 if (SoundObjects[i].flags==0)
659 if (i==MAX_SOUND_OBJECTS) {
660 mprintf((1, "Too many sound objects!\n" ));
665 SoundObjects[i].signature=next_signature++;
666 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
668 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
669 SoundObjects[i].lp_segnum = segnum;
670 SoundObjects[i].lp_sidenum = sidenum;
671 SoundObjects[i].lp_position = *pos;
672 SoundObjects[i].soundnum = soundnum;
673 SoundObjects[i].max_volume = max_volume;
674 SoundObjects[i].max_distance = max_distance;
675 SoundObjects[i].volume = 0;
676 SoundObjects[i].pan = 0;
677 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
678 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
679 SoundObjects[i].max_volume,
680 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
682 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
683 digi_start_sound_object(i);
685 return SoundObjects[i].signature;
688 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
690 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
693 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
697 soundnum = digi_xlat_sound(soundnum);
699 if (!digi_initialised) return;
703 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
704 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
705 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
706 if ( SoundObjects[i].flags & SOF_PLAYING ) {
707 SoundSlots[SoundObjects[i].handle].playing = 0;
709 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
714 // If this assert happens, it means that there were 2 sounds
715 // that got deleted. Weird, get John.
717 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
721 void digi_kill_sound_linked_to_object( int objnum )
725 if (!digi_initialised) return;
729 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
730 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
731 if (SoundObjects[i].lo_objnum == objnum) {
732 if ( SoundObjects[i].flags & SOF_PLAYING ) {
733 SoundSlots[SoundObjects[i].handle].playing = 0;
735 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
740 // If this assert happens, it means that there were 2 sounds
741 // that got deleted. Weird, get John.
743 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
747 void digi_sync_sounds()
750 int oldvolume, oldpan;
752 if (!digi_initialised) return;
754 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
755 if ( SoundObjects[i].flags & SOF_USED ) {
756 oldvolume = SoundObjects[i].volume;
757 oldpan = SoundObjects[i].pan;
759 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
760 // Check if its done.
761 if (SoundObjects[i].flags & SOF_PLAYING) {
762 if (!SoundSlots[SoundObjects[i].handle].playing) {
763 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
764 continue; // Go on to next sound...
769 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
770 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
771 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
772 SoundObjects[i].max_volume,
773 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
775 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
778 objp = &Objects[SoundObjects[i].lo_objnum];
780 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
781 // The object that this is linked to is dead, so just end this sound if it is looping.
782 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
783 SoundSlots[SoundObjects[i].handle].playing = 0;
785 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
786 continue; // Go on to next sound...
788 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
789 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
790 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
794 if (oldvolume != SoundObjects[i].volume) {
795 if ( SoundObjects[i].volume < MIN_VOLUME ) {
796 // Sound is too far away, so stop it from playing.
797 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
798 SoundSlots[SoundObjects[i].handle].playing = 0;
799 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
802 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
803 digi_start_sound_object(i);
805 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
810 if (oldpan != SoundObjects[i].pan) {
811 if (SoundObjects[i].flags & SOF_PLAYING)
812 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
818 void digi_stop_soundobjects() {
821 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
822 if (digi_sounds_initialized) {
823 if ( SoundObjects[i].flags & SOF_PLAYING ) {
824 SoundSlots[SoundObjects[i].handle].playing=0;
827 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
831 void digi_init_sounds()
835 if (!digi_initialised) return;
837 digi_reset_digi_sounds();
839 // for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
840 // if (digi_sounds_initialized) {
841 // if ( SoundObjects[i].flags & SOF_PLAYING ) {
842 // SoundSlots[SoundObjects[i].handle].playing=0;
845 // SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
847 digi_stop_soundobjects();
849 digi_sounds_initialized = 1;
852 //added on 980905 by adb from original source to make sfx volume work
853 void digi_set_digi_volume( int dvolume )
855 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
856 if ( dvolume > SOUND_MAX_VOLUME )
857 digi_volume = SOUND_MAX_VOLUME;
858 else if ( dvolume < 0 )
861 digi_volume = dvolume;
863 if ( !digi_initialised ) return;
869 //void digi_set_volume( int dvolume, int mvolume ) {}
870 void digi_set_volume( int dvolume, int mvolume )
872 digi_set_midi_volume(mvolume);
873 digi_set_digi_volume(dvolume);
877 int digi_is_sound_playing(int soundno)
881 soundno = digi_xlat_sound(soundno);
883 for (i = 0; i < MAX_SOUND_SLOTS; i++)
884 //changed on 980905 by adb: added SoundSlots[i].playing &&
885 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
892 //void digi_pause_all() { }
893 //void digi_resume_all() { }
894 //void digi_stop_all() { }
896 //added on 980905 by adb to make sound channel setting work
897 void digi_set_max_channels(int n) {
898 digi_max_channels = n;
900 if ( digi_max_channels < 1 )
901 digi_max_channels = 1;
902 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
903 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
905 if ( !digi_initialised ) return;
907 digi_reset_digi_sounds();
910 int digi_get_max_channels() {
911 return digi_max_channels;
915 void digi_reset_digi_sounds()
919 for (i=0; i< MAX_SOUND_SLOTS; i++)
920 SoundSlots[i].playing=0;
922 //added on 980905 by adb to reset sound kill system
923 memset(SampleHandles, 255, sizeof(SampleHandles));
928 int sound_paused = 0;
930 void digi_pause_all()
932 if (!digi_initialised) return;
933 if (sound_paused==0) {
935 digi_stop_soundobjects();
940 void digi_resume_all()
942 if (!digi_initialised) return;
944 Assert( sound_paused > 0 );
946 if (sound_paused==1) {
954 if (!digi_initialised) return;
958 digi_stop_soundobjects();
962 BOOL VC_Init(void) { return 1; }
963 void VC_Exit(void) { }
964 BOOL VC_SetNumVoices(void) { return 0; }
965 ULONG VC_SampleSpace(int type) { return 0; }
966 ULONG VC_SampleLength(int type, SAMPLE *s) { return 0; }
968 BOOL VC_PlayStart(void) { return 0; }
969 void VC_PlayStop(void) { }
972 SWORD VC_SampleLoad(SAMPLOAD *sload, int type, FILE *fp) { return 0; }
974 SWORD VC_SampleLoad(FILE *fp,ULONG size,ULONG reppos,ULONG repend,UWORD flags) { return 0; }
976 void VC_SampleUnload(SWORD handle) { }
978 void VC_WriteSamples(SBYTE *buf,ULONG todo) { }
979 void VC_SilenceBytes(SBYTE *buf,ULONG todo) { }
982 void VC_VoiceSetVolume(UBYTE voice, UWORD vol) { }
983 void VC_VoiceSetPanning(UBYTE voice, ULONG pan) { }
985 void VC_VoiceSetVolume(UBYTE voice, UBYTE vol) { }
986 void VC_VoiceSetPanning(UBYTE voice, UBYTE pan) { }
988 void VC_VoiceSetFrequency(UBYTE voice, ULONG frq) { }
989 void VC_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) { }
991 void VC_VoiceStop(UBYTE voice) { }
992 BOOL VC_VoiceStopped(UBYTE voice) { return 0; }
993 void VC_VoiceReleaseSustain(UBYTE voice) { }
994 SLONG VC_VoiceGetPosition(UBYTE voice) { return 0; }
995 ULONG VC_VoiceRealVolume(UBYTE voice) { return 0; }