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 ***********************************************************/
17 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
19 static int playing_sounds = 0;
20 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
21 static struct SoundControl emptySoundControl =
23 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
27 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
28 static char premix_first_buffer[SND_BLOCKSIZE];
30 static char premix_left_buffer[SND_BLOCKSIZE];
31 static char premix_right_buffer[SND_BLOCKSIZE];
32 static int premix_last_buffer[SND_BLOCKSIZE];
34 static unsigned char playing_buffer[SND_BLOCKSIZE];
37 /* forward declaration of internal functions */
39 static void SoundServer_InsertNewSound(struct SoundControl);
43 static unsigned char linear_to_ulaw(int);
44 static int ulaw_to_linear(unsigned char);
48 static void HPUX_Audio_Control();
51 static void SoundServer_InsertNewSound(struct SoundControl);
52 static void SoundServer_StopSound(int);
53 static void SoundServer_StopAllSounds();
60 struct SoundControl snd_ctrl;
63 close(sound_pipe[1]); /* no writing into pipe needed */
66 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
67 playlist[i] = emptySoundControl;
71 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
72 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
74 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
80 FD_ZERO(&sound_fdset);
81 FD_SET(sound_pipe[0], &sound_fdset);
83 while(1) /* wait for sound playing commands from client */
85 FD_SET(sound_pipe[0], &sound_fdset);
86 select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
87 if (!FD_ISSET(sound_pipe[0], &sound_fdset))
89 if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
90 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
94 if (snd_ctrl.fade_sound)
99 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
100 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
101 playlist[i].fade_sound = TRUE;
103 else if (snd_ctrl.stop_all_sounds)
108 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
109 playlist[i]=emptySoundControl;
114 else if (snd_ctrl.stop_sound)
119 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
120 if (playlist[i].nr == snd_ctrl.nr)
122 playlist[i]=emptySoundControl;
130 if (playing_sounds || snd_ctrl.active)
132 struct timeval delay = { 0, 0 };
135 static long max_sample_size = 0;
136 static long fragment_size = 0;
137 /* Even if the stereo flag is used as being boolean, it must be
138 defined as an integer, else 'ioctl()' will fail! */
140 int sample_rate = 8000;
142 if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=0)
144 if (!playing_sounds) /* we just opened the audio device */
146 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
147 /* (with stereo the effective buffer size will shrink to 256) */
148 fragment_size = 0x00020009;
150 if (ioctl(sound_device, SNDCTL_DSP_SETFRAGMENT, &fragment_size) < 0)
151 Error(ERR_EXIT_SOUND_SERVER,
152 "cannot set fragment size of /dev/dsp - no sounds");
154 /* try if we can use stereo sound */
155 if (ioctl(sound_device, SNDCTL_DSP_STEREO, &stereo) < 0)
158 static boolean reported = FALSE;
162 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
169 if (ioctl(sound_device, SNDCTL_DSP_SPEED, &sample_rate) < 0)
170 Error(ERR_EXIT_SOUND_SERVER,
171 "cannot set sample rate of /dev/dsp - no sounds");
173 /* get the real fragmentation size; this should return 512 */
174 if (ioctl(sound_device, SNDCTL_DSP_GETBLKSIZE, &fragment_size) < 0)
175 Error(ERR_EXIT_SOUND_SERVER,
176 "cannot get fragment size of /dev/dsp - no sounds");
178 max_sample_size = fragment_size / (stereo ? 2 : 1);
181 if (snd_ctrl.active) /* new sound has arrived */
182 SoundServer_InsertNewSound(snd_ctrl);
184 while(playing_sounds &&
185 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
187 FD_SET(sound_pipe[0], &sound_fdset);
189 /* first clear the last premixing buffer */
190 memset(premix_last_buffer,0,fragment_size*sizeof(int));
192 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
196 if (!playlist[i].active)
199 /* get pointer and size of the actual sound sample */
200 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
202 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
203 playlist[i].playingpos += sample_size;
205 /* fill the first mixing buffer with original sample */
206 memcpy(premix_first_buffer,sample_ptr,sample_size);
208 /* are we about to restart a looping sound? */
209 if (playlist[i].loop && sample_size<max_sample_size)
211 playlist[i].playingpos = max_sample_size-sample_size;
212 memcpy(premix_first_buffer+sample_size,
213 playlist[i].data_ptr,max_sample_size-sample_size);
214 sample_size = max_sample_size;
217 /* decrease volume if sound is fading out */
218 if (playlist[i].fade_sound &&
219 playlist[i].volume>=PSND_MAX_VOLUME/10)
220 playlist[i].volume-=PSND_MAX_VOLUME/20;
222 /* adjust volume of actual sound sample */
223 if (playlist[i].volume != PSND_MAX_VOLUME)
224 for(j=0;j<sample_size;j++)
225 premix_first_buffer[j] =
226 (playlist[i].volume * (int)premix_first_buffer[j])
227 >> PSND_MAX_VOLUME_BITS;
229 /* fill the last mixing buffer with stereo or mono sound */
232 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
233 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
234 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
236 for(j=0;j<sample_size;j++)
238 premix_left_buffer[j] =
239 (left_volume * (int)premix_first_buffer[j])
240 >> PSND_MAX_LEFT2RIGHT_BITS;
241 premix_right_buffer[j] =
242 (right_volume * (int)premix_first_buffer[j])
243 >> PSND_MAX_LEFT2RIGHT_BITS;
244 premix_last_buffer[2*j+0] += premix_left_buffer[j];
245 premix_last_buffer[2*j+1] += premix_right_buffer[j];
250 for(j=0;j<sample_size;j++)
251 premix_last_buffer[j] += (int)premix_first_buffer[j];
254 /* delete completed sound entries from the playlist */
255 if (playlist[i].playingpos >= playlist[i].data_len)
257 if (playlist[i].loop)
258 playlist[i].playingpos = 0;
261 playlist[i] = emptySoundControl;
265 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
267 playlist[i] = emptySoundControl;
272 /* put last mixing buffer to final playing buffer */
273 for(i=0;i<fragment_size;i++)
275 if (premix_last_buffer[i]<-255)
276 playing_buffer[i] = 0;
277 else if (premix_last_buffer[i]>255)
278 playing_buffer[i] = 255;
280 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
283 /* finally play the sound fragment */
284 write(sound_device,playing_buffer,fragment_size);
287 /* if no sounds playing, free device for other sound programs */
295 if (snd_ctrl.active && !snd_ctrl.loop)
297 struct timeval delay = { 0, 0 };
299 long sample_size, max_sample_size = SND_BLOCKSIZE;
300 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
301 int wait_percent = 90; /* wait 90% of the real playing time */
304 if ((sound_device=open(sound_device_name,O_WRONLY))>=0)
308 while(playing_sounds &&
309 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
311 FD_SET(sound_pipe[0], &sound_fdset);
313 /* get pointer and size of the actual sound sample */
314 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
316 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
317 snd_ctrl.playingpos += sample_size;
319 /* fill the first mixing buffer with original sample */
320 memcpy(premix_first_buffer,sample_ptr,sample_size);
323 /* adjust volume of actual sound sample */
324 if (snd_ctrl.volume != PSND_MAX_VOLUME)
325 for(i=0;i<sample_size;i++)
326 premix_first_buffer[i] =
327 (snd_ctrl.volume * (int)premix_first_buffer[i])
328 >> PSND_MAX_VOLUME_BITS;
330 for(i=0;i<sample_size;i++)
332 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
334 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
337 /* finally play the sound fragment */
338 write(sound_device,playing_buffer,sample_size);
341 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
347 #endif /* !VOXWARE */
354 static void sound_handler(struct SoundControl snd_ctrl)
358 if (snd_ctrl.fade_sound)
363 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
364 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
365 !playlist[i].fade_sound)
367 playlist[i].fade_sound = TRUE;
368 if (voice_check(playlist[i].voice))
369 voice_ramp_volume(playlist[i].voice, 1000, 0);
370 playlist[i].loop = PSND_NO_LOOP;
373 else if (snd_ctrl.stop_all_sounds)
377 SoundServer_StopAllSounds();
379 else if (snd_ctrl.stop_sound)
383 SoundServer_StopSound(snd_ctrl.nr);
386 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
388 if (!playlist[i].active || playlist[i].loop)
391 playlist[i].playingpos = voice_get_position(playlist[i].voice);
392 playlist[i].volume = voice_get_volume(playlist[i].voice);
393 if (playlist[i].playingpos == -1 || !playlist[i].volume)
395 deallocate_voice(playlist[i].voice);
396 playlist[i] = emptySoundControl;
402 SoundServer_InsertNewSound(snd_ctrl);
406 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
410 /* if playlist is full, remove oldest sound */
411 if (playing_sounds==MAX_SOUNDS_PLAYING)
413 int longest=0, longest_nr=0;
415 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
418 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
420 int actual = playlist[i].playingpos;
423 if (!playlist[i].loop && actual>longest)
430 voice_set_volume(playlist[longest_nr].voice, 0);
431 deallocate_voice(playlist[longest_nr].voice);
433 playlist[longest_nr] = emptySoundControl;
437 /* check if sound is already being played (and how often) */
438 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
440 if (playlist[i].nr == snd_ctrl.nr)
444 /* restart loop sounds only if they are just fading out */
445 if (k>=1 && snd_ctrl.loop)
447 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
449 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
451 playlist[i].fade_sound = FALSE;
452 playlist[i].volume = PSND_MAX_VOLUME;
454 playlist[i].loop = PSND_LOOP;
455 voice_stop_volumeramp(playlist[i].voice);
456 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
463 /* don't play sound more than n times simultaneously (with n == 2 for now) */
466 int longest=0, longest_nr=0;
468 /* look for oldest equal sound */
469 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
473 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
477 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
479 actual = playlist[i].playingpos;
488 voice_set_volume(playlist[longest_nr].voice, 0);
489 deallocate_voice(playlist[longest_nr].voice);
491 playlist[longest_nr] = emptySoundControl;
495 /* neuen Sound in Liste packen */
496 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
498 if (!playlist[i].active)
500 playlist[i] = snd_ctrl;
503 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
505 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
506 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
507 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
508 voice_start(playlist[i].voice);
516 void SoundServer_FadeSound(int nr)
523 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
524 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
525 playlist[i].fade_sound = TRUE;
530 static void SoundServer_StopSound(int nr)
537 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
538 if (playlist[i].nr == nr)
541 voice_set_volume(playlist[i].voice, 0);
542 deallocate_voice(playlist[i].voice);
544 playlist[i] = emptySoundControl;
554 static void SoundServer_StopAllSounds()
558 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
561 voice_set_volume(playlist[i].voice, 0);
562 deallocate_voice(playlist[i].voice);
564 playlist[i]=emptySoundControl;
575 static void HPUX_Audio_Control()
577 struct audio_describe ainfo;
580 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
582 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
584 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
585 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
587 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
588 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
590 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
591 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
595 #endif /* HPUX_AUDIO */
599 /* these two are stolen from "sox"... :) */
602 ** This routine converts from linear to ulaw.
604 ** Craig Reese: IDA/Supercomputing Research Center
605 ** Joe Campbell: Department of Defense
609 ** 1) CCITT Recommendation G.711 (very difficult to follow)
610 ** 2) "A New Digital Technique for Implementation of Any
611 ** Continuous PCM Companding Law," Villeret, Michel,
612 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
613 ** 1973, pg. 11.12-11.17
614 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
615 ** for Analog-to_Digital Conversion Techniques,"
618 ** Input: Signed 16 bit linear sample
619 ** Output: 8 bit ulaw sample
622 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
623 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
626 static unsigned char linear_to_ulaw(int sample)
628 static int exp_lut[256] =
630 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
631 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
632 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
633 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
634 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
635 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
636 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
637 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
638 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
639 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
640 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
641 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
642 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
643 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
644 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
645 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
648 int sign, exponent, mantissa;
649 unsigned char ulawbyte;
651 /* Get the sample into sign-magnitude. */
652 sign = (sample >> 8) & 0x80; /* set aside the sign */
654 sample = -sample; /* get magnitude */
656 sample = CLIP; /* clip the magnitude */
658 /* Convert from 16 bit linear to ulaw. */
659 sample = sample + BIAS;
660 exponent = exp_lut[( sample >> 7 ) & 0xFF];
661 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
662 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
665 ulawbyte = 0x02; /* optional CCITT trap */
672 ** This routine converts from ulaw to 16 bit linear.
674 ** Craig Reese: IDA/Supercomputing Research Center
678 ** 1) CCITT Recommendation G.711 (very difficult to follow)
679 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
680 ** for Analog-to_Digital Conversion Techniques,"
683 ** Input: 8 bit ulaw sample
684 ** Output: signed 16 bit linear sample
687 static int ulaw_to_linear(unsigned char ulawbyte)
689 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
690 int sign, exponent, mantissa, sample;
692 ulawbyte = ~ ulawbyte;
693 sign = ( ulawbyte & 0x80 );
694 exponent = ( ulawbyte >> 4 ) & 0x07;
695 mantissa = ulawbyte & 0x0F;
696 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
703 #endif /* !VOXWARE */
705 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
707 /*===========================================================================*/
709 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
711 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
712 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
714 boolean LoadSound(struct SoundInfo *snd_info)
717 char *sound_ext = "wav";
719 byte sound_header_buffer[WAV_HEADER_SIZE];
720 char chunk[CHUNK_ID_LEN + 1];
721 int chunk_length, dummy;
726 sprintf(filename, "%s/%s/%s.%s",
727 options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
731 if ((file = fopen(filename, "r")) == NULL)
733 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
737 /* read chunk "RIFF" */
738 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
739 if (strcmp(chunk, "RIFF") != 0)
741 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
746 /* read chunk "WAVE" */
747 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
748 if (strcmp(chunk, "WAVE") != 0)
750 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
755 /* read header information */
756 for (i=0; i<WAV_HEADER_SIZE; i++)
757 sound_header_buffer[i] = fgetc(file);
759 /* read chunk "data" */
760 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
761 if (strcmp(chunk, "data") != 0)
763 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
768 snd_info->data_len = chunk_length;
769 snd_info->data_ptr = checked_malloc(snd_info->data_len);
771 /* read sound data */
772 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
775 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
782 for (i=0; i<snd_info->data_len; i++)
783 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
787 snd_info->sample_ptr = load_sample(filename);
788 if (!snd_info->sample_ptr)
790 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
799 void PlaySound(int nr)
801 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
804 void PlaySoundStereo(int nr, int stereo)
806 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
809 void PlaySoundLoop(int nr)
811 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
814 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
816 struct SoundControl snd_ctrl = emptySoundControl;
818 if (sound_status==SOUND_OFF || !setup.sound)
821 if (volume<PSND_MIN_VOLUME)
822 volume = PSND_MIN_VOLUME;
823 else if (volume>PSND_MAX_VOLUME)
824 volume = PSND_MAX_VOLUME;
826 if (stereo<PSND_MAX_LEFT)
827 stereo = PSND_MAX_LEFT;
828 else if (stereo>PSND_MAX_RIGHT)
829 stereo = PSND_MAX_RIGHT;
832 snd_ctrl.volume = volume;
833 snd_ctrl.stereo = stereo;
834 snd_ctrl.loop = loop;
835 snd_ctrl.active = TRUE;
836 snd_ctrl.data_ptr = Sound[nr].data_ptr;
837 snd_ctrl.data_len = Sound[nr].data_len;
840 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
842 Error(ERR_WARN, "cannot pipe to child process - no sounds");
843 sound_status = SOUND_OFF;
847 sound_handler(snd_ctrl);
851 void FadeSound(int nr)
853 StopSoundExt(nr, SSND_FADE_SOUND);
858 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
861 void StopSound(int nr)
863 StopSoundExt(nr, SSND_STOP_SOUND);
868 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
871 void StopSoundExt(int nr, int method)
873 struct SoundControl snd_ctrl = emptySoundControl;
875 if (sound_status==SOUND_OFF)
878 if (SSND_FADING(method))
879 snd_ctrl.fade_sound = TRUE;
881 if (SSND_ALL(method))
882 snd_ctrl.stop_all_sounds = TRUE;
886 snd_ctrl.stop_sound = TRUE;
890 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
892 Error(ERR_WARN, "cannot pipe to child process - no sounds");
893 sound_status = SOUND_OFF;
897 sound_handler(snd_ctrl);
901 void FreeSounds(int num_sounds)
905 if (sound_status == SOUND_OFF)
908 for(i=0; i<num_sounds; i++)
910 free(Sound[i].data_ptr);
912 destroy_sample(Sound[i].sample_ptr);
916 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/