2 * $Source: /cvs/cvsroot/d2x/sound/dos_digi.c,v $
5 * $Date: 2001-01-29 13:53:28 $
7 * DOS digital audio support
9 * $Log: not supported by cvs2svn $
25 #include "gr.h" // needed for piggy.h
33 int digi_sample_rate=11025;
34 int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz)
36 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
37 //added on 980905 by adb to add inline fixmul for mixer on i386
40 #define do_fixmul(x,y) \
43 asm("imull %2\n\tshrdl %3,%1,%0" \
44 : "=a"(_ax), "=d"(_dx) \
45 : "rm"(y), "i"(16), "0"(x)); \
48 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
54 //changed on 980905 by adb to increase number of concurrent sounds
55 #define MAX_SOUND_SLOTS 32
57 #define SOUND_BUFFER_SIZE 512
61 /* This table is used to add two sound values together and pin
62 * the value to avoid overflow. (used with permission from ARDI)
63 * DPH: Taken from SDL/src/SDL_mixer.c.
65 static const unsigned char mix8[] =
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01, 0x02, 0x03,
79 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
80 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
81 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
82 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
83 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
84 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
85 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
86 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
87 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
88 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
89 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
90 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
91 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
92 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
93 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
94 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
95 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
96 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
97 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
98 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
99 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
100 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
101 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
103 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
104 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
105 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
107 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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,
116 #define SOF_USED 1 // Set if this sample is used
117 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
118 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
119 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
120 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
122 typedef struct sound_object {
123 short signature; // A unique signature to this sound
124 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
125 fix max_volume; // Max volume that this sound is playing at
126 fix max_distance; // The max distance that this sound can be heard at...
127 int volume; // Volume that this sound is playing at
128 int pan; // Pan value that this sound is playing at
129 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
130 short soundnum; // The sound number that is playing
133 short segnum; // Used if SOF_LINK_TO_POS field is used
138 short objnum; // Used if SOF_LINK_TO_OBJ field is used
143 #define lp_segnum link.pos.segnum
144 #define lp_sidenum link.pos.sidenum
145 #define lp_position link.pos.position
147 #define lo_objnum link.obj.objnum
148 #define lo_objsignature link.obj.objsignature
150 #define MAX_SOUND_OBJECTS 16
151 sound_object SoundObjects[MAX_SOUND_OBJECTS];
152 short next_signature=0;
154 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
155 #define SOUND_MAX_VOLUME (F1_0 / 2)
157 int digi_volume = SOUND_MAX_VOLUME;
162 static int digi_initialised = 0;
166 int playing; // Is there a sample playing on this channel?
167 int looped; // Play this sample looped?
168 fix pan; // 0 = far left, 1 = far right
169 fix volume; // 0 = nothing, 1 = fully on
170 //changed on 980905 by adb from char * to unsigned char *
171 unsigned char *samples;
173 unsigned int length; // Length of the sample
174 unsigned int position; // Position we are at at the moment.
175 } SoundSlots[MAX_SOUND_SLOTS];
177 static int digi_sounds_initialized = 0;
179 //added on 980905 by adb to add rotating/volume based sound kill system
180 static int digi_max_channels = 16;
181 static int next_handle = 0;
182 int SampleHandles[32];
183 void reset_sounds_on_channel(int channel);
186 void digi_reset_digi_sounds(void);
188 /* Audio mixing callback */
189 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
190 static void audio_mixcallback(void *userdata, unsigned char *stream, int len)
192 unsigned char *streamend = stream + len;
193 struct sound_slot *sl;
195 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
199 unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
200 unsigned char *sp = stream;
205 if ((x = sl->pan) & 0x8000)
207 vl = 0x20000 - x * 2;
215 vl = fixmul(vl, (x = sl->volume));
217 while (sp < streamend)
226 sldata = sl->samples;
228 v = *(sldata++) - 0x80;
229 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
230 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
232 sl->position = sldata - sl->samples;
238 /* Initialise audio devices. */
246 void digi_reset() { }
248 /* Shut down audio */
251 if (!digi_initialised) return;
252 digi_initialised = 0;
255 /* Find the sound which actually equates to a sound number */
256 int digi_xlat_sound(int soundno)
258 if ( soundno < 0 ) return -1;
261 soundno = AltSounds[soundno];
262 if ( soundno == 255 ) return -1;
264 return Sounds[soundno];
267 static int get_free_slot()
270 for (i=0; i<MAX_SOUND_SLOTS; i++)
272 if (!SoundSlots[i].playing) return i;
277 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
282 if (!digi_initialised) return -1;
284 //added on 980905 by adb from original source to add sound kill system
285 // play at most digi_max_channel samples, if possible kill sample with low volume
289 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
291 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
293 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
295 if ( next_handle >= digi_max_channels )
300 //mprintf(( 0, "[SS:%d]", next_handle ));
301 SoundSlots[SampleHandles[next_handle]].playing = 0;
302 SampleHandles[next_handle] = -1;
306 slot = get_free_slot();
307 if (slot<0) return -1;
309 SoundSlots[slot].soundno = soundnum;
310 SoundSlots[slot].samples = GameSounds[soundnum].data;
311 SoundSlots[slot].length = GameSounds[soundnum].length;
312 SoundSlots[slot].volume = fixmul(digi_volume, volume);
313 SoundSlots[slot].pan = pan;
314 SoundSlots[slot].position = 0;
315 SoundSlots[slot].looped = 0;
316 SoundSlots[slot].playing = 1;
318 //added on 980905 by adb to add sound kill system from original sos digi.c
319 reset_sounds_on_channel(slot);
320 SampleHandles[next_handle] = slot;
322 if ( next_handle >= digi_max_channels )
329 //added on 980905 by adb to add sound kill system from original sos digi.c
330 void reset_sounds_on_channel( int channel )
334 for (i=0; i<digi_max_channels; i++)
335 if (SampleHandles[i] == channel)
336 SampleHandles[i] = -1;
340 int digi_start_sound_object(int obj)
344 if (!digi_initialised) return -1;
345 slot = get_free_slot();
347 if (slot<0) return -1;
350 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
351 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
352 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
353 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
354 SoundSlots[slot].pan = SoundObjects[obj].pan;
355 SoundSlots[slot].position = 0;
356 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
357 SoundSlots[slot].playing = 1;
359 SoundObjects[obj].signature = next_signature++;
360 SoundObjects[obj].handle = slot;
362 SoundObjects[obj].flags |= SOF_PLAYING;
363 //added on 980905 by adb to add sound kill system from original sos digi.c
364 reset_sounds_on_channel(slot);
371 // Play the given sound number.
372 // Volume is max at F1_0.
373 void digi_play_sample( int soundno, fix max_volume )
376 if ( Newdemo_state == ND_STATE_RECORDING )
377 newdemo_record_sound( soundno );
379 soundno = digi_xlat_sound(soundno);
381 if (!digi_initialised) return;
383 if (soundno < 0 ) return;
385 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
388 // Play the given sound number. If the sound is already playing,
390 void digi_play_sample_once( int soundno, fix max_volume )
395 if ( Newdemo_state == ND_STATE_RECORDING )
396 newdemo_record_sound( soundno );
398 soundno = digi_xlat_sound(soundno);
400 if (!digi_initialised) return;
402 if (soundno < 0 ) return;
404 for (i=0; i < MAX_SOUND_SLOTS; i++)
405 if (SoundSlots[i].soundno == soundno)
406 SoundSlots[i].playing = 0;
407 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
411 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
416 if ( Newdemo_state == ND_STATE_RECORDING ) {
418 newdemo_record_sound_3d_once( soundno, angle, volume );
420 newdemo_record_sound_3d( soundno, angle, volume );
423 soundno = digi_xlat_sound(soundno);
425 if (!digi_initialised) return;
426 if (soundno < 0 ) return;
428 if (volume < MIN_VOLUME ) return;
429 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
432 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 )
434 vms_vector vector_to_sound;
435 fix angle_from_ear, cosang,sinang;
442 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
444 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
445 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
447 if (distance < max_distance ) {
448 int num_search_segs = f2i(max_distance/20);
449 if ( num_search_segs < 1 ) num_search_segs = 1;
451 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
452 if ( path_distance > -1 ) {
453 *volume = max_volume - fixdiv(path_distance,max_distance);
454 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
456 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
457 fix_sincos(angle_from_ear,&sinang,&cosang);
458 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
459 if (Config_channels_reversed) cosang *= -1;
460 *pan = (cosang + F1_0)/2;
468 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
474 soundnum = digi_xlat_sound(org_soundnum);
476 if ( max_volume < 0 ) return -1;
477 // if ( max_volume > F1_0 ) max_volume = F1_0;
479 if (!digi_initialised) return -1;
480 if (soundnum < 0 ) return -1;
481 if (GameSounds[soundnum].data==NULL) {
485 if ((objnum<0)||(objnum>Highest_object_index))
489 // Hack to keep sounds from building up...
490 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
491 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
495 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
496 if (SoundObjects[i].flags==0)
499 if (i==MAX_SOUND_OBJECTS) {
500 mprintf((1, "Too many sound objects!\n" ));
504 SoundObjects[i].signature=next_signature++;
505 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
507 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
508 SoundObjects[i].lo_objnum = objnum;
509 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
510 SoundObjects[i].max_volume = max_volume;
511 SoundObjects[i].max_distance = max_distance;
512 SoundObjects[i].volume = 0;
513 SoundObjects[i].pan = 0;
514 SoundObjects[i].soundnum = soundnum;
516 objp = &Objects[SoundObjects[i].lo_objnum];
517 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
518 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
519 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
521 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
522 digi_start_sound_object(i);
524 return SoundObjects[i].signature;
527 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
528 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
530 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
535 soundnum = digi_xlat_sound(org_soundnum);
537 if ( max_volume < 0 ) return -1;
538 // if ( max_volume > F1_0 ) max_volume = F1_0;
540 if (!digi_initialised) return -1;
541 if (soundnum < 0 ) return -1;
542 if (GameSounds[soundnum].data==NULL) {
547 if ((segnum<0)||(segnum>Highest_segment_index))
551 // Hack to keep sounds from building up...
552 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
553 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
557 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
558 if (SoundObjects[i].flags==0)
561 if (i==MAX_SOUND_OBJECTS) {
562 mprintf((1, "Too many sound objects!\n" ));
567 SoundObjects[i].signature=next_signature++;
568 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
570 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
571 SoundObjects[i].lp_segnum = segnum;
572 SoundObjects[i].lp_sidenum = sidenum;
573 SoundObjects[i].lp_position = *pos;
574 SoundObjects[i].soundnum = soundnum;
575 SoundObjects[i].max_volume = max_volume;
576 SoundObjects[i].max_distance = max_distance;
577 SoundObjects[i].volume = 0;
578 SoundObjects[i].pan = 0;
579 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
580 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
581 SoundObjects[i].max_volume,
582 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
584 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
585 digi_start_sound_object(i);
587 return SoundObjects[i].signature;
590 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
592 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
595 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
599 soundnum = digi_xlat_sound(soundnum);
601 if (!digi_initialised) return;
605 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
606 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
607 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
608 if ( SoundObjects[i].flags & SOF_PLAYING ) {
609 SoundSlots[SoundObjects[i].handle].playing = 0;
611 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
616 // If this assert happens, it means that there were 2 sounds
617 // that got deleted. Weird, get John.
619 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
623 void digi_kill_sound_linked_to_object( int objnum )
627 if (!digi_initialised) return;
631 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
632 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
633 if (SoundObjects[i].lo_objnum == objnum) {
634 if ( SoundObjects[i].flags & SOF_PLAYING ) {
635 SoundSlots[SoundObjects[i].handle].playing = 0;
637 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
642 // If this assert happens, it means that there were 2 sounds
643 // that got deleted. Weird, get John.
645 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
649 void digi_sync_sounds()
652 int oldvolume, oldpan;
654 if (!digi_initialised) return;
656 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
657 if ( SoundObjects[i].flags & SOF_USED ) {
658 oldvolume = SoundObjects[i].volume;
659 oldpan = SoundObjects[i].pan;
661 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
662 // Check if its done.
663 if (SoundObjects[i].flags & SOF_PLAYING) {
664 if (!SoundSlots[SoundObjects[i].handle].playing) {
665 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
666 continue; // Go on to next sound...
671 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
672 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
673 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
674 SoundObjects[i].max_volume,
675 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
677 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
680 objp = &Objects[SoundObjects[i].lo_objnum];
682 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
683 // The object that this is linked to is dead, so just end this sound if it is looping.
684 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
685 SoundSlots[SoundObjects[i].handle].playing = 0;
687 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
688 continue; // Go on to next sound...
690 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
691 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
692 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
696 if (oldvolume != SoundObjects[i].volume) {
697 if ( SoundObjects[i].volume < MIN_VOLUME ) {
698 // Sound is too far away, so stop it from playing.
699 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
700 SoundSlots[SoundObjects[i].handle].playing = 0;
701 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
704 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
705 digi_start_sound_object(i);
707 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
712 if (oldpan != SoundObjects[i].pan) {
713 if (SoundObjects[i].flags & SOF_PLAYING)
714 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
720 void digi_init_sounds()
724 if (!digi_initialised) return;
726 digi_reset_digi_sounds();
728 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
729 if (digi_sounds_initialized) {
730 if ( SoundObjects[i].flags & SOF_PLAYING ) {
731 SoundSlots[SoundObjects[i].handle].playing=0;
734 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
736 digi_sounds_initialized = 1;
739 //added on 980905 by adb from original source to make sfx volume work
740 void digi_set_digi_volume( int dvolume )
742 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
743 if ( dvolume > SOUND_MAX_VOLUME )
744 digi_volume = SOUND_MAX_VOLUME;
745 else if ( dvolume < 0 )
748 digi_volume = dvolume;
750 if ( !digi_initialised ) return;
756 void digi_set_volume( int dvolume, int mvolume ) { }
758 int digi_is_sound_playing(int soundno)
762 soundno = digi_xlat_sound(soundno);
764 for (i = 0; i < MAX_SOUND_SLOTS; i++)
765 //changed on 980905 by adb: added SoundSlots[i].playing &&
766 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
773 void digi_pause_all() { }
774 void digi_resume_all() { }
775 void digi_stop_all() { }
777 //added on 980905 by adb to make sound channel setting work
778 void digi_set_max_channels(int n) {
779 digi_max_channels = n;
781 if ( digi_max_channels < 1 )
782 digi_max_channels = 1;
783 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
784 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
786 if ( !digi_initialised ) return;
788 digi_reset_digi_sounds();
791 int digi_get_max_channels() {
792 return digi_max_channels;
796 void digi_reset_digi_sounds() {
799 for (i=0; i< MAX_SOUND_SLOTS; i++)
800 SoundSlots[i].playing=0;
802 //added on 980905 by adb to reset sound kill system
803 memset(SampleHandles, 255, sizeof(SampleHandles));
809 // MIDI stuff follows.
810 //added/killed on 11/25/98 by Matthew Mueller
811 //void digi_set_midi_volume( int mvolume ) { }
812 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
813 //void digi_stop_current_song()
822 //end this section kill - MM