1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
18 extern void sound_handler(struct SoundControl);
21 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
24 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
25 static struct SoundControl emptySoundControl =
27 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
29 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
30 static char premix_first_buffer[SND_BLOCKSIZE];
32 static char premix_left_buffer[SND_BLOCKSIZE];
33 static char premix_right_buffer[SND_BLOCKSIZE];
34 static int premix_last_buffer[SND_BLOCKSIZE];
36 static unsigned char playing_buffer[SND_BLOCKSIZE];
37 static int playing_sounds = 0;
39 struct SoundControl playlist[MAX_SOUNDS_PLAYING];
40 struct SoundControl emptySoundControl;
48 struct SoundControl snd_ctrl;
51 close(sound_pipe[1]); /* no writing into pipe needed */
54 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
55 playlist[i] = emptySoundControl;
59 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
60 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
62 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
68 FD_ZERO(&sound_fdset);
69 FD_SET(sound_pipe[0], &sound_fdset);
71 for(;;) /* wait for calls from PlaySound(), StopSound(), ... */
73 FD_SET(sound_pipe[0], &sound_fdset);
74 select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
75 if (!FD_ISSET(sound_pipe[0], &sound_fdset))
77 if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
78 Error(ERR_EXIT_SOUNDSERVER, "broken pipe - no sounds");
82 if (snd_ctrl.fade_sound)
87 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
88 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
89 playlist[i].fade_sound = TRUE;
91 else if (snd_ctrl.stop_all_sounds)
96 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
97 playlist[i]=emptySoundControl;
102 else if (snd_ctrl.stop_sound)
107 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
108 if (playlist[i].nr == snd_ctrl.nr)
110 playlist[i]=emptySoundControl;
118 if (playing_sounds || snd_ctrl.active)
120 struct timeval delay = { 0, 0 };
122 long sample_size, max_sample_size;
126 if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=0)
128 if (!playing_sounds) /* we just opened the audio device */
130 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
131 /* (with stereo the effective buffer size will shrink to 256) */
132 fragment_size = 0x00020009;
133 ioctl(sound_device, SNDCTL_DSP_SETFRAGMENT, &fragment_size);
134 /* try if we can use stereo sound */
136 ioctl(sound_device, SNDCTL_DSP_STEREO, &stereo);
137 /* get the real fragmentation size; this should return 512 */
138 ioctl(sound_device, SNDCTL_DSP_GETBLKSIZE, &fragment_size);
139 max_sample_size = fragment_size / (stereo ? 2 : 1);
142 if (snd_ctrl.active) /* new sound has arrived */
143 SoundServer_InsertNewSound(snd_ctrl);
145 while(playing_sounds &&
146 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
148 FD_SET(sound_pipe[0], &sound_fdset);
150 /* first clear the last premixing buffer */
151 memset(premix_last_buffer,0,fragment_size*sizeof(int));
153 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
157 if (!playlist[i].active)
160 /* get pointer and size of the actual sound sample */
161 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
163 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
164 playlist[i].playingpos += sample_size;
166 /* fill the first mixing buffer with original sample */
167 memcpy(premix_first_buffer,sample_ptr,sample_size);
169 /* are we about to restart a looping sound? */
170 if (playlist[i].loop && sample_size<max_sample_size)
172 playlist[i].playingpos = max_sample_size-sample_size;
173 memcpy(premix_first_buffer+sample_size,
174 playlist[i].data_ptr,max_sample_size-sample_size);
175 sample_size = max_sample_size;
178 /* decrease volume if sound is fading out */
179 if (playlist[i].fade_sound &&
180 playlist[i].volume>=PSND_MAX_VOLUME/10)
181 playlist[i].volume-=PSND_MAX_VOLUME/20;
183 /* adjust volume of actual sound sample */
184 if (playlist[i].volume != PSND_MAX_VOLUME)
185 for(j=0;j<sample_size;j++)
186 premix_first_buffer[j] =
187 (playlist[i].volume * (int)premix_first_buffer[j])
188 >> PSND_MAX_VOLUME_BITS;
190 /* fill the last mixing buffer with stereo or mono sound */
193 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
194 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
195 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
197 for(j=0;j<sample_size;j++)
199 premix_left_buffer[j] =
200 (left_volume * (int)premix_first_buffer[j])
201 >> PSND_MAX_LEFT2RIGHT_BITS;
202 premix_right_buffer[j] =
203 (right_volume * (int)premix_first_buffer[j])
204 >> PSND_MAX_LEFT2RIGHT_BITS;
205 premix_last_buffer[2*j+0] += premix_left_buffer[j];
206 premix_last_buffer[2*j+1] += premix_right_buffer[j];
211 for(j=0;j<sample_size;j++)
212 premix_last_buffer[j] += (int)premix_first_buffer[j];
215 /* delete completed sound entries from the playlist */
216 if (playlist[i].playingpos >= playlist[i].data_len)
218 if (playlist[i].loop)
219 playlist[i].playingpos = 0;
222 playlist[i] = emptySoundControl;
226 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
228 playlist[i] = emptySoundControl;
233 /* put last mixing buffer to final playing buffer */
234 for(i=0;i<fragment_size;i++)
236 if (premix_last_buffer[i]<-255)
237 playing_buffer[i] = 0;
238 else if (premix_last_buffer[i]>255)
239 playing_buffer[i] = 255;
241 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
244 /* finally play the sound fragment */
245 write(sound_device,playing_buffer,fragment_size);
248 /* if no sounds playing, free device for other sound programs */
254 #else /* von '#ifdef VOXWARE' */
256 if (snd_ctrl.active && !snd_ctrl.loop)
258 struct timeval delay = { 0, 0 };
260 long sample_size, max_sample_size = SND_BLOCKSIZE;
261 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
262 int wait_percent = 90; /* wait 90% of the real playing time */
265 if ((sound_device=open(sound_device_name,O_WRONLY))>=0)
269 while(playing_sounds &&
270 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
272 FD_SET(sound_pipe[0], &sound_fdset);
274 /* get pointer and size of the actual sound sample */
275 sample_ptr = snd_ctrl.data_ptr+snd_ctrl.playingpos;
277 MIN(max_sample_size,snd_ctrl.data_len-snd_ctrl.playingpos);
278 snd_ctrl.playingpos += sample_size;
280 /* fill the first mixing buffer with original sample */
281 memcpy(premix_first_buffer,sample_ptr,sample_size);
284 /* adjust volume of actual sound sample */
285 if (snd_ctrl.volume != PSND_MAX_VOLUME)
286 for(i=0;i<sample_size;i++)
287 premix_first_buffer[i] =
288 (snd_ctrl.volume * (int)premix_first_buffer[i])
289 >> PSND_MAX_VOLUME_BITS;
291 for(i=0;i<sample_size;i++)
293 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
295 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
298 /* finally play the sound fragment */
299 write(sound_device,playing_buffer,sample_size);
302 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
308 #endif /* von '#ifdef VOXWARE' */
314 void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
318 /* wenn voll, ältesten Sound 'rauswerfen */
319 if (playing_sounds==MAX_SOUNDS_PLAYING)
321 int longest=0, longest_nr=0;
323 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
326 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
328 int actual = playlist[i].playingpos;
331 if (!playlist[i].loop && actual>longest)
338 voice_set_volume(playlist[longest_nr].voice, 0);
339 deallocate_voice(playlist[longest_nr].voice);
341 playlist[longest_nr] = emptySoundControl;
345 /* nachsehen, ob (und ggf. wie oft) Sound bereits gespielt wird */
346 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
348 if (playlist[i].nr == snd_ctrl.nr)
352 /* falls Sound-Loop: nur neu beginnen, wenn Sound gerade ausklingt */
353 if (k>=1 && snd_ctrl.loop)
355 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
357 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
359 playlist[i].fade_sound = FALSE;
360 playlist[i].volume = PSND_MAX_VOLUME;
362 playlist[i].loop = PSND_LOOP;
363 voice_stop_volumeramp(playlist[i].voice);
364 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
371 /* keinen Sound mehr als n mal gleichzeitig spielen (momentan n==2) */
374 int longest=0, longest_nr=0;
376 /* den bereits am längsten gespielten (gleichen) Sound suchen */
377 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
381 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
385 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
387 actual = playlist[i].playingpos;
396 voice_set_volume(playlist[longest_nr].voice, 0);
397 deallocate_voice(playlist[longest_nr].voice);
399 playlist[longest_nr] = emptySoundControl;
403 /* neuen Sound in Liste packen */
404 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
406 if (!playlist[i].active)
408 playlist[i] = snd_ctrl;
411 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
413 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
414 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
415 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
416 voice_start(playlist[i].voice);
424 void SoundServer_FadeSound(int nr)
431 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
432 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
433 playlist[i].fade_sound = TRUE;
437 void SoundServer_StopSound(int nr)
444 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
445 if (playlist[i].nr == nr)
448 voice_set_volume(playlist[i].voice, 0);
449 deallocate_voice(playlist[i].voice);
451 playlist[i] = emptySoundControl;
461 void SoundServer_StopAllSounds()
465 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
468 voice_set_volume(playlist[i].voice, 0);
469 deallocate_voice(playlist[i].voice);
471 playlist[i]=emptySoundControl;
481 void HPUX_Audio_Control()
483 struct audio_describe ainfo;
486 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
488 Error(ERR_EXIT_SOUNDSERVER, "cannot open /dev/audioCtl - no sounds");
490 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
491 Error(ERR_EXIT_SOUNDSERVER, "no audio info - no sounds");
493 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
494 Error(ERR_EXIT_SOUNDSERVER, "ulaw audio not available - no sounds");
496 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
497 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
501 #endif /* HPUX_AUDIO */
503 /* these two are stolen from "sox"... :) */
506 ** This routine converts from linear to ulaw.
508 ** Craig Reese: IDA/Supercomputing Research Center
509 ** Joe Campbell: Department of Defense
513 ** 1) CCITT Recommendation G.711 (very difficult to follow)
514 ** 2) "A New Digital Technique for Implementation of Any
515 ** Continuous PCM Companding Law," Villeret, Michel,
516 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
517 ** 1973, pg. 11.12-11.17
518 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
519 ** for Analog-to_Digital Conversion Techniques,"
522 ** Input: Signed 16 bit linear sample
523 ** Output: 8 bit ulaw sample
526 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
527 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
530 unsigned char linear_to_ulaw(int sample)
532 static int exp_lut[256] =
534 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
535 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
536 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
537 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
538 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
539 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
540 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
541 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
542 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
543 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
544 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
545 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
546 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
547 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
548 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
549 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
552 int sign, exponent, mantissa;
553 unsigned char ulawbyte;
555 /* Get the sample into sign-magnitude. */
556 sign = (sample >> 8) & 0x80; /* set aside the sign */
558 sample = -sample; /* get magnitude */
560 sample = CLIP; /* clip the magnitude */
562 /* Convert from 16 bit linear to ulaw. */
563 sample = sample + BIAS;
564 exponent = exp_lut[( sample >> 7 ) & 0xFF];
565 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
566 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
569 ulawbyte = 0x02; /* optional CCITT trap */
576 ** This routine converts from ulaw to 16 bit linear.
578 ** Craig Reese: IDA/Supercomputing Research Center
582 ** 1) CCITT Recommendation G.711 (very difficult to follow)
583 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
584 ** for Analog-to_Digital Conversion Techniques,"
587 ** Input: 8 bit ulaw sample
588 ** Output: signed 16 bit linear sample
591 int ulaw_to_linear(unsigned char ulawbyte)
593 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
594 int sign, exponent, mantissa, sample;
596 ulawbyte = ~ ulawbyte;
597 sign = ( ulawbyte & 0x80 );
598 exponent = ( ulawbyte >> 4 ) & 0x07;
599 mantissa = ulawbyte & 0x0F;
600 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
607 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
609 /*===========================================================================*/
611 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
613 static unsigned long be2long(unsigned long *be) /* big-endian -> longword */
615 unsigned char *ptr = (unsigned char *)be;
617 return(ptr[0]<<24 | ptr[1]<<16 | ptr[2]<<8 | ptr[3]);
620 static unsigned long le2long(unsigned long *be) /* little-endian -> longword */
622 unsigned char *ptr = (unsigned char *)be;
624 return(ptr[3]<<24 | ptr[2]<<16 | ptr[1]<<8 | ptr[0]);
627 boolean LoadSound(struct SoundInfo *snd_info)
631 char *sound_ext = "wav";
632 struct SoundHeader_WAV *sound_header;
635 sprintf(filename, "%s/%s/%s.%s",
636 options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
639 if ((file = fopen(filename, "r")) == NULL)
641 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
645 if (fseek(file, 0, SEEK_END) < 0)
647 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
652 snd_info->file_len = ftell(file);
655 snd_info->file_ptr = checked_malloc(snd_info->file_len);
657 if (fread(snd_info->file_ptr, 1, snd_info->file_len, file) !=
660 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
667 sound_header = (struct SoundHeader_WAV *)snd_info->file_ptr;
669 if (strncmp(sound_header->magic_RIFF, "RIFF", 4) ||
670 snd_info->file_len != le2long(&sound_header->header_size) + 8 ||
671 strncmp(sound_header->magic_WAVE, "WAVE", 4) ||
672 strncmp(sound_header->magic_DATA, "data", 4) ||
673 snd_info->file_len != le2long(&sound_header->data_size) + 44)
675 Error(ERR_WARN, "'%s' is not a RIFF/WAVE file or broken - no sounds",
680 snd_info->data_ptr = snd_info->file_ptr + 44;
681 snd_info->data_len = le2long(&sound_header->data_size);
683 for (i=0; i<snd_info->data_len; i++)
684 snd_info->data_ptr[i] = snd_info->data_ptr[i]^0x80;
688 snd_info->sample_ptr = load_sample(filename);
689 if (!snd_info->sample_ptr)
691 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
700 boolean LoadSound_8SVX(struct SoundInfo *snd_info)
705 char *sound_ext = "8svx";
707 char *sound_ext = "wav";
709 struct SoundHeader_8SVX *sound_header;
712 sprintf(filename, "%s/%s/%s.%s",
713 options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
716 if (!(file=fopen(filename,"r")))
718 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
722 if (fseek(file,0,SEEK_END)<0)
724 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
729 snd_info->file_len = ftell(file);
732 if (!(snd_info->file_ptr=malloc(snd_info->file_len)))
734 Error(ERR_WARN, "out of memory (this shouldn't happen :) - no sounds");
739 if (fread(snd_info->file_ptr,1,snd_info->file_len,file)!=snd_info->file_len)
741 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
748 sound_header = (struct SoundHeader_8SVX *)snd_info->file_ptr;
750 if (strncmp(sound_header->magic_FORM,"FORM",4) ||
751 snd_info->file_len != be2long(&sound_header->chunk_size)+8 ||
752 strncmp(sound_header->magic_8SVX,"8SVX",4))
754 Error(ERR_WARN, "'%s' is not an IFF/8SVX file or broken - no sounds",
759 ptr = snd_info->file_ptr + 12;
761 while(ptr < (unsigned char *)(snd_info->file_ptr + snd_info->file_len))
763 if (!strncmp(ptr,"VHDR",4))
765 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
768 else if (!strncmp(ptr,"ANNO",4))
770 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
773 else if (!strncmp(ptr,"CHAN",4))
775 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
778 else if (!strncmp(ptr,"BODY",4))
780 snd_info->data_ptr = ptr + 8;
781 snd_info->data_len = be2long((unsigned long *)(ptr + 4));
786 /* other chunk not recognized here */
787 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
794 snd_info->sample_ptr = load_sample(filename);
795 if(!snd_info->sample_ptr)
797 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
802 #endif // von #ifndef MSDOS
805 void PlaySound(int nr)
807 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
810 void PlaySoundStereo(int nr, int stereo)
812 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
815 void PlaySoundLoop(int nr)
817 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
820 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
822 struct SoundControl snd_ctrl = emptySoundControl;
824 if (sound_status==SOUND_OFF || !setup.sound)
827 if (volume<PSND_MIN_VOLUME)
828 volume = PSND_MIN_VOLUME;
829 else if (volume>PSND_MAX_VOLUME)
830 volume = PSND_MAX_VOLUME;
832 if (stereo<PSND_MAX_LEFT)
833 stereo = PSND_MAX_LEFT;
834 else if (stereo>PSND_MAX_RIGHT)
835 stereo = PSND_MAX_RIGHT;
838 snd_ctrl.volume = volume;
839 snd_ctrl.stereo = stereo;
840 snd_ctrl.loop = loop;
841 snd_ctrl.active = TRUE;
842 snd_ctrl.data_ptr = Sound[nr].data_ptr;
843 snd_ctrl.data_len = Sound[nr].data_len;
846 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
848 Error(ERR_WARN, "cannot pipe to child process - no sounds");
849 sound_status = SOUND_OFF;
853 sound_handler(snd_ctrl);
857 void FadeSound(int nr)
859 StopSoundExt(nr, SSND_FADE_SOUND);
864 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
867 void StopSound(int nr)
869 StopSoundExt(nr, SSND_STOP_SOUND);
874 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
877 void StopSoundExt(int nr, int method)
879 struct SoundControl snd_ctrl = emptySoundControl;
881 if (sound_status==SOUND_OFF)
884 if (SSND_FADING(method))
885 snd_ctrl.fade_sound = TRUE;
887 if (SSND_ALL(method))
888 snd_ctrl.stop_all_sounds = TRUE;
892 snd_ctrl.stop_sound = TRUE;
896 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
898 Error(ERR_WARN, "cannot pipe to child process - no sounds");
899 sound_status = SOUND_OFF;
903 sound_handler(snd_ctrl);
907 void FreeSounds(int max)
911 if (sound_status==SOUND_OFF)
916 free(Sound[i].file_ptr);
918 destroy_sample(Sound[i].sample_ptr);
922 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/