1 // SDL digital audio support
9 #include <SDL/SDL_audio.h>
16 #include "gr.h" // needed for piggy.h
24 int digi_sample_rate=11025;
26 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
27 //added on 980905 by adb to add inline fixmul for mixer on i386
30 #define do_fixmul(x,y) \
33 asm("imull %2\n\tshrdl %3,%1,%0" \
34 : "=a"(_ax), "=d"(_dx) \
35 : "rm"(y), "i"(16), "0"(x)); \
38 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
44 //changed on 980905 by adb to increase number of concurrent sounds
45 #define MAX_SOUND_SLOTS 32
47 #define SOUND_BUFFER_SIZE 512
51 /* This table is used to add two sound values together and pin
52 * the value to avoid overflow. (used with permission from ARDI)
53 * DPH: Taken from SDL/src/SDL_mixer.c.
55 static const Uint8 mix8[] =
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
69 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
70 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
71 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
72 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
73 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
74 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
75 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
76 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
77 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
78 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
79 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
80 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
81 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
82 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
83 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
84 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
85 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
86 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
87 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
88 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
89 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
90 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
91 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
95 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
99 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
101 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
103 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106 #define SOF_USED 1 // Set if this sample is used
107 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
108 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
109 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
110 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
112 typedef struct sound_object {
113 short signature; // A unique signature to this sound
114 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
115 fix max_volume; // Max volume that this sound is playing at
116 fix max_distance; // The max distance that this sound can be heard at...
117 int volume; // Volume that this sound is playing at
118 int pan; // Pan value that this sound is playing at
119 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
120 short soundnum; // The sound number that is playing
123 short segnum; // Used if SOF_LINK_TO_POS field is used
128 short objnum; // Used if SOF_LINK_TO_OBJ field is used
133 #define lp_segnum link.pos.segnum
134 #define lp_sidenum link.pos.sidenum
135 #define lp_position link.pos.position
137 #define lo_objnum link.obj.objnum
138 #define lo_objsignature link.obj.objsignature
140 #define MAX_SOUND_OBJECTS 16
141 sound_object SoundObjects[MAX_SOUND_OBJECTS];
142 short next_signature=0;
144 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
145 #define SOUND_MAX_VOLUME (F1_0 / 2)
147 int digi_volume = SOUND_MAX_VOLUME;
152 static int digi_initialised = 0;
156 int playing; // Is there a sample playing on this channel?
157 int looped; // Play this sample looped?
158 fix pan; // 0 = far left, 1 = far right
159 fix volume; // 0 = nothing, 1 = fully on
160 //changed on 980905 by adb from char * to unsigned char *
161 unsigned char *samples;
163 unsigned int length; // Length of the sample
164 unsigned int position; // Position we are at at the moment.
165 } SoundSlots[MAX_SOUND_SLOTS];
167 static SDL_AudioSpec WaveSpec;
168 static int digi_sounds_initialized = 0;
170 //added on 980905 by adb to add rotating/volume based sound kill system
171 static int digi_max_channels = 16;
172 static int next_handle = 0;
173 int SampleHandles[32];
174 void reset_sounds_on_channel(int channel);
177 void digi_reset_digi_sounds(void);
179 /* Audio mixing callback */
180 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
181 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
183 Uint8 *streamend = stream + len;
184 struct sound_slot *sl;
186 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
190 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
196 if ((x = sl->pan) & 0x8000)
198 vl = 0x20000 - x * 2;
206 vl = fixmul(vl, (x = sl->volume));
208 while (sp < streamend)
217 sldata = sl->samples;
219 v = *(sldata++) - 0x80;
220 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
221 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
223 sl->position = sldata - sl->samples;
229 /* Initialise audio devices. */
233 if (SDL_Init(SDL_INIT_AUDIO) < 0)
235 Warning("SDL library audio initialisation failed: %s.",SDL_GetError());
238 //added on 980905 by adb to init sound kill system
239 memset(SampleHandles, 255, sizeof(SampleHandles));
242 WaveSpec.freq = 11025;
243 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
244 WaveSpec.format = AUDIO_U8;
245 WaveSpec.channels = 2;
246 //end this section addition/change - SL
247 WaveSpec.samples = SOUND_BUFFER_SIZE;
248 WaveSpec.callback = audio_mixcallback;
250 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
251 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
252 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
260 digi_initialised = 1;
265 void digi_reset() { }
267 /* Shut down audio */
270 if (!digi_initialised) return;
271 digi_initialised = 0;
275 /* Find the sound which actually equates to a sound number */
276 int digi_xlat_sound(int soundno)
278 if ( soundno < 0 ) return -1;
281 soundno = AltSounds[soundno];
282 if ( soundno == 255 ) return -1;
284 return Sounds[soundno];
287 static int get_free_slot()
290 for (i=0; i<MAX_SOUND_SLOTS; i++)
292 if (!SoundSlots[i].playing) return i;
297 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
302 if (!digi_initialised) return -1;
304 //added on 980905 by adb from original source to add sound kill system
305 // play at most digi_max_channel samples, if possible kill sample with low volume
309 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
311 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
313 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
315 if ( next_handle >= digi_max_channels )
320 //mprintf(( 0, "[SS:%d]", next_handle ));
321 SoundSlots[SampleHandles[next_handle]].playing = 0;
322 SampleHandles[next_handle] = -1;
326 slot = get_free_slot();
327 if (slot<0) return -1;
329 SoundSlots[slot].soundno = soundnum;
330 SoundSlots[slot].samples = GameSounds[soundnum].data;
331 SoundSlots[slot].length = GameSounds[soundnum].length;
332 SoundSlots[slot].volume = fixmul(digi_volume, volume);
333 SoundSlots[slot].pan = pan;
334 SoundSlots[slot].position = 0;
335 SoundSlots[slot].looped = 0;
336 SoundSlots[slot].playing = 1;
338 //added on 980905 by adb to add sound kill system from original sos digi.c
339 reset_sounds_on_channel(slot);
340 SampleHandles[next_handle] = slot;
342 if ( next_handle >= digi_max_channels )
349 //added on 980905 by adb to add sound kill system from original sos digi.c
350 void reset_sounds_on_channel( int channel )
354 for (i=0; i<digi_max_channels; i++)
355 if (SampleHandles[i] == channel)
356 SampleHandles[i] = -1;
360 int digi_start_sound_object(int obj)
364 if (!digi_initialised) return -1;
365 slot = get_free_slot();
367 if (slot<0) return -1;
370 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
371 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
372 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
373 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
374 SoundSlots[slot].pan = SoundObjects[obj].pan;
375 SoundSlots[slot].position = 0;
376 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
377 SoundSlots[slot].playing = 1;
379 SoundObjects[obj].signature = next_signature++;
380 SoundObjects[obj].handle = slot;
382 SoundObjects[obj].flags |= SOF_PLAYING;
383 //added on 980905 by adb to add sound kill system from original sos digi.c
384 reset_sounds_on_channel(slot);
391 // Play the given sound number.
392 // Volume is max at F1_0.
393 void digi_play_sample( int soundno, fix max_volume )
396 if ( Newdemo_state == ND_STATE_RECORDING )
397 newdemo_record_sound( soundno );
399 soundno = digi_xlat_sound(soundno);
401 if (!digi_initialised) return;
403 if (soundno < 0 ) return;
405 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
408 // Play the given sound number. If the sound is already playing,
410 void digi_play_sample_once( int soundno, fix max_volume )
415 if ( Newdemo_state == ND_STATE_RECORDING )
416 newdemo_record_sound( soundno );
418 soundno = digi_xlat_sound(soundno);
420 if (!digi_initialised) return;
422 if (soundno < 0 ) return;
424 for (i=0; i < MAX_SOUND_SLOTS; i++)
425 if (SoundSlots[i].soundno == soundno)
426 SoundSlots[i].playing = 0;
427 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
431 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
436 if ( Newdemo_state == ND_STATE_RECORDING ) {
438 newdemo_record_sound_3d_once( soundno, angle, volume );
440 newdemo_record_sound_3d( soundno, angle, volume );
443 soundno = digi_xlat_sound(soundno);
445 if (!digi_initialised) return;
446 if (soundno < 0 ) return;
448 if (volume < MIN_VOLUME ) return;
449 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
452 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 )
454 vms_vector vector_to_sound;
455 fix angle_from_ear, cosang,sinang;
462 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
464 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
465 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
467 if (distance < max_distance ) {
468 int num_search_segs = f2i(max_distance/20);
469 if ( num_search_segs < 1 ) num_search_segs = 1;
471 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
472 if ( path_distance > -1 ) {
473 *volume = max_volume - fixdiv(path_distance,max_distance);
474 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
476 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
477 fix_sincos(angle_from_ear,&sinang,&cosang);
478 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
479 if (Config_channels_reversed) cosang *= -1;
480 *pan = (cosang + F1_0)/2;
488 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
494 soundnum = digi_xlat_sound(org_soundnum);
496 if ( max_volume < 0 ) return -1;
497 // if ( max_volume > F1_0 ) max_volume = F1_0;
499 if (!digi_initialised) return -1;
500 if (soundnum < 0 ) return -1;
501 if (GameSounds[soundnum].data==NULL) {
505 if ((objnum<0)||(objnum>Highest_object_index))
509 // Hack to keep sounds from building up...
510 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
511 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
515 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
516 if (SoundObjects[i].flags==0)
519 if (i==MAX_SOUND_OBJECTS) {
520 mprintf((1, "Too many sound objects!\n" ));
524 SoundObjects[i].signature=next_signature++;
525 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
527 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
528 SoundObjects[i].lo_objnum = objnum;
529 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
530 SoundObjects[i].max_volume = max_volume;
531 SoundObjects[i].max_distance = max_distance;
532 SoundObjects[i].volume = 0;
533 SoundObjects[i].pan = 0;
534 SoundObjects[i].soundnum = soundnum;
536 objp = &Objects[SoundObjects[i].lo_objnum];
537 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
538 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
539 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
541 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
542 digi_start_sound_object(i);
544 return SoundObjects[i].signature;
547 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
548 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
550 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
555 soundnum = digi_xlat_sound(org_soundnum);
557 if ( max_volume < 0 ) return -1;
558 // if ( max_volume > F1_0 ) max_volume = F1_0;
560 if (!digi_initialised) return -1;
561 if (soundnum < 0 ) return -1;
562 if (GameSounds[soundnum].data==NULL) {
567 if ((segnum<0)||(segnum>Highest_segment_index))
571 // Hack to keep sounds from building up...
572 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
573 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
577 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
578 if (SoundObjects[i].flags==0)
581 if (i==MAX_SOUND_OBJECTS) {
582 mprintf((1, "Too many sound objects!\n" ));
587 SoundObjects[i].signature=next_signature++;
588 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
590 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
591 SoundObjects[i].lp_segnum = segnum;
592 SoundObjects[i].lp_sidenum = sidenum;
593 SoundObjects[i].lp_position = *pos;
594 SoundObjects[i].soundnum = soundnum;
595 SoundObjects[i].max_volume = max_volume;
596 SoundObjects[i].max_distance = max_distance;
597 SoundObjects[i].volume = 0;
598 SoundObjects[i].pan = 0;
599 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
600 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
601 SoundObjects[i].max_volume,
602 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
604 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
605 digi_start_sound_object(i);
607 return SoundObjects[i].signature;
610 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
612 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
615 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
619 soundnum = digi_xlat_sound(soundnum);
621 if (!digi_initialised) return;
625 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
626 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
627 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
628 if ( SoundObjects[i].flags & SOF_PLAYING ) {
629 SoundSlots[SoundObjects[i].handle].playing = 0;
631 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
636 // If this assert happens, it means that there were 2 sounds
637 // that got deleted. Weird, get John.
639 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
643 void digi_kill_sound_linked_to_object( int objnum )
647 if (!digi_initialised) return;
651 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
652 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
653 if (SoundObjects[i].lo_objnum == objnum) {
654 if ( SoundObjects[i].flags & SOF_PLAYING ) {
655 SoundSlots[SoundObjects[i].handle].playing = 0;
657 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
662 // If this assert happens, it means that there were 2 sounds
663 // that got deleted. Weird, get John.
665 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
669 void digi_sync_sounds()
672 int oldvolume, oldpan;
674 if (!digi_initialised) return;
676 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
677 if ( SoundObjects[i].flags & SOF_USED ) {
678 oldvolume = SoundObjects[i].volume;
679 oldpan = SoundObjects[i].pan;
681 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
682 // Check if its done.
683 if (SoundObjects[i].flags & SOF_PLAYING) {
684 if (!SoundSlots[SoundObjects[i].handle].playing) {
685 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
686 continue; // Go on to next sound...
691 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
692 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
693 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
694 SoundObjects[i].max_volume,
695 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
697 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
700 objp = &Objects[SoundObjects[i].lo_objnum];
702 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
703 // The object that this is linked to is dead, so just end this sound if it is looping.
704 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
705 SoundSlots[SoundObjects[i].handle].playing = 0;
707 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
708 continue; // Go on to next sound...
710 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
711 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
712 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
716 if (oldvolume != SoundObjects[i].volume) {
717 if ( SoundObjects[i].volume < MIN_VOLUME ) {
718 // Sound is too far away, so stop it from playing.
719 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
720 SoundSlots[SoundObjects[i].handle].playing = 0;
721 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
724 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
725 digi_start_sound_object(i);
727 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
732 if (oldpan != SoundObjects[i].pan) {
733 if (SoundObjects[i].flags & SOF_PLAYING)
734 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
740 void digi_init_sounds()
744 if (!digi_initialised) return;
746 digi_reset_digi_sounds();
748 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
749 if (digi_sounds_initialized) {
750 if ( SoundObjects[i].flags & SOF_PLAYING ) {
751 SoundSlots[SoundObjects[i].handle].playing=0;
754 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
756 digi_sounds_initialized = 1;
759 //added on 980905 by adb from original source to make sfx volume work
760 void digi_set_digi_volume( int dvolume )
762 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
763 if ( dvolume > SOUND_MAX_VOLUME )
764 digi_volume = SOUND_MAX_VOLUME;
765 else if ( dvolume < 0 )
768 digi_volume = dvolume;
770 if ( !digi_initialised ) return;
776 void digi_set_volume( int dvolume, int mvolume ) { }
778 int digi_is_sound_playing(int soundno)
782 soundno = digi_xlat_sound(soundno);
784 for (i = 0; i < MAX_SOUND_SLOTS; i++)
785 //changed on 980905 by adb: added SoundSlots[i].playing &&
786 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
793 void digi_pause_all() { }
794 void digi_resume_all() { }
795 void digi_stop_all() { }
797 //added on 980905 by adb to make sound channel setting work
798 void digi_set_max_channels(int n) {
799 digi_max_channels = n;
801 if ( digi_max_channels < 1 )
802 digi_max_channels = 1;
803 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
804 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
806 if ( !digi_initialised ) return;
808 digi_reset_digi_sounds();
811 int digi_get_max_channels() {
812 return digi_max_channels;
816 void digi_reset_digi_sounds() {
819 for (i=0; i< MAX_SOUND_SLOTS; i++)
820 SoundSlots[i].playing=0;
822 //added on 980905 by adb to reset sound kill system
823 memset(SampleHandles, 255, sizeof(SampleHandles));
829 // MIDI stuff follows.
830 //added/killed on 11/25/98 by Matthew Mueller
831 //void digi_set_midi_volume( int mvolume ) { }
832 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
833 //void digi_stop_current_song()
842 //end this section kill - MM