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
26 #if !defined(MSDOS) && !defined(WIN32)
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];
35 #endif /* !MSDOS && !WIN32 */
37 /* forward declaration of internal functions */
39 static void SoundServer_InsertNewSound(struct SoundControl);
42 #if !defined(VOXWARE) && !defined(MSDOS) && !defined(WIN32)
43 static unsigned char linear_to_ulaw(int);
44 static int ulaw_to_linear(unsigned char);
48 static void HPUX_Audio_Control();
52 static void SoundServer_InsertNewSound(struct SoundControl);
53 static void SoundServer_StopSound(int);
54 static void SoundServer_StopAllSounds();
60 #if !defined(MSDOS) && !defined(WIN32)
61 struct SoundControl snd_ctrl;
64 close(sound_pipe[1]); /* no writing into pipe needed */
67 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
68 playlist[i] = emptySoundControl;
71 #if !defined(MSDOS) && !defined(WIN32)
72 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
73 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
75 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
81 FD_ZERO(&sound_fdset);
82 FD_SET(sound_pipe[0], &sound_fdset);
84 while(1) /* wait for sound playing commands from client */
86 FD_SET(sound_pipe[0], &sound_fdset);
87 select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
88 if (!FD_ISSET(sound_pipe[0], &sound_fdset))
90 if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
91 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
95 if (snd_ctrl.fade_sound)
100 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
101 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
102 playlist[i].fade_sound = TRUE;
104 else if (snd_ctrl.stop_all_sounds)
109 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
110 playlist[i]=emptySoundControl;
115 else if (snd_ctrl.stop_sound)
120 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
121 if (playlist[i].nr == snd_ctrl.nr)
123 playlist[i]=emptySoundControl;
131 if (playing_sounds || snd_ctrl.active)
133 struct timeval delay = { 0, 0 };
136 static long max_sample_size = 0;
137 static long fragment_size = 0;
138 /* Even if the stereo flag is used as being boolean, it must be
139 defined as an integer, else 'ioctl()' will fail! */
142 int sample_rate = 8000;
144 int sample_rate = 22050;
147 if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=0)
149 if (!playing_sounds) /* we just opened the audio device */
151 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
152 /* (with stereo the effective buffer size will shrink to 256) */
153 fragment_size = 0x00020009;
155 if (ioctl(sound_device, SNDCTL_DSP_SETFRAGMENT, &fragment_size) < 0)
156 Error(ERR_EXIT_SOUND_SERVER,
157 "cannot set fragment size of /dev/dsp - no sounds");
159 /* try if we can use stereo sound */
160 if (ioctl(sound_device, SNDCTL_DSP_STEREO, &stereo) < 0)
163 static boolean reported = FALSE;
167 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
174 if (ioctl(sound_device, SNDCTL_DSP_SPEED, &sample_rate) < 0)
175 Error(ERR_EXIT_SOUND_SERVER,
176 "cannot set sample rate of /dev/dsp - no sounds");
178 /* get the real fragmentation size; this should return 512 */
179 if (ioctl(sound_device, SNDCTL_DSP_GETBLKSIZE, &fragment_size) < 0)
180 Error(ERR_EXIT_SOUND_SERVER,
181 "cannot get fragment size of /dev/dsp - no sounds");
183 max_sample_size = fragment_size / (stereo ? 2 : 1);
186 if (snd_ctrl.active) /* new sound has arrived */
187 SoundServer_InsertNewSound(snd_ctrl);
189 while(playing_sounds &&
190 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
192 FD_SET(sound_pipe[0], &sound_fdset);
194 /* first clear the last premixing buffer */
195 memset(premix_last_buffer,0,fragment_size*sizeof(int));
197 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
201 if (!playlist[i].active)
204 /* get pointer and size of the actual sound sample */
205 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
207 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
208 playlist[i].playingpos += sample_size;
210 /* fill the first mixing buffer with original sample */
211 memcpy(premix_first_buffer,sample_ptr,sample_size);
213 /* are we about to restart a looping sound? */
214 if (playlist[i].loop && sample_size<max_sample_size)
216 playlist[i].playingpos = max_sample_size-sample_size;
217 memcpy(premix_first_buffer+sample_size,
218 playlist[i].data_ptr,max_sample_size-sample_size);
219 sample_size = max_sample_size;
222 /* decrease volume if sound is fading out */
223 if (playlist[i].fade_sound &&
224 playlist[i].volume>=PSND_MAX_VOLUME/10)
225 playlist[i].volume-=PSND_MAX_VOLUME/20;
227 /* adjust volume of actual sound sample */
228 if (playlist[i].volume != PSND_MAX_VOLUME)
229 for(j=0;j<sample_size;j++)
230 premix_first_buffer[j] =
231 (playlist[i].volume * (int)premix_first_buffer[j])
232 >> PSND_MAX_VOLUME_BITS;
234 /* fill the last mixing buffer with stereo or mono sound */
237 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
238 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
239 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
241 for(j=0;j<sample_size;j++)
243 premix_left_buffer[j] =
244 (left_volume * (int)premix_first_buffer[j])
245 >> PSND_MAX_LEFT2RIGHT_BITS;
246 premix_right_buffer[j] =
247 (right_volume * (int)premix_first_buffer[j])
248 >> PSND_MAX_LEFT2RIGHT_BITS;
249 premix_last_buffer[2*j+0] += premix_left_buffer[j];
250 premix_last_buffer[2*j+1] += premix_right_buffer[j];
255 for(j=0;j<sample_size;j++)
256 premix_last_buffer[j] += (int)premix_first_buffer[j];
259 /* delete completed sound entries from the playlist */
260 if (playlist[i].playingpos >= playlist[i].data_len)
262 if (playlist[i].loop)
263 playlist[i].playingpos = 0;
266 playlist[i] = emptySoundControl;
270 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
272 playlist[i] = emptySoundControl;
277 /* put last mixing buffer to final playing buffer */
278 for(i=0;i<fragment_size;i++)
280 if (premix_last_buffer[i]<-255)
281 playing_buffer[i] = 0;
282 else if (premix_last_buffer[i]>255)
283 playing_buffer[i] = 255;
285 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
288 /* finally play the sound fragment */
289 write(sound_device,playing_buffer,fragment_size);
292 /* if no sounds playing, free device for other sound programs */
300 if (snd_ctrl.active && !snd_ctrl.loop)
302 struct timeval delay = { 0, 0 };
304 long sample_size, max_sample_size = SND_BLOCKSIZE;
305 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
306 int wait_percent = 90; /* wait 90% of the real playing time */
309 if ((sound_device=open(sound_device_name,O_WRONLY))>=0)
313 while(playing_sounds &&
314 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
316 FD_SET(sound_pipe[0], &sound_fdset);
318 /* get pointer and size of the actual sound sample */
319 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
321 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
322 snd_ctrl.playingpos += sample_size;
324 /* fill the first mixing buffer with original sample */
325 memcpy(premix_first_buffer,sample_ptr,sample_size);
328 /* adjust volume of actual sound sample */
329 if (snd_ctrl.volume != PSND_MAX_VOLUME)
330 for(i=0;i<sample_size;i++)
331 premix_first_buffer[i] =
332 (snd_ctrl.volume * (int)premix_first_buffer[i])
333 >> PSND_MAX_VOLUME_BITS;
335 for(i=0;i<sample_size;i++)
337 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
339 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
342 /* finally play the sound fragment */
343 write(sound_device,playing_buffer,sample_size);
346 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
352 #endif /* !VOXWARE */
356 #endif /* !MSDOS && !WIN32 */
361 static void sound_handler(struct SoundControl snd_ctrl)
365 if (snd_ctrl.fade_sound)
370 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
371 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
372 !playlist[i].fade_sound)
374 playlist[i].fade_sound = TRUE;
375 if (voice_check(playlist[i].voice))
376 voice_ramp_volume(playlist[i].voice, 1000, 0);
377 playlist[i].loop = PSND_NO_LOOP;
380 else if (snd_ctrl.stop_all_sounds)
384 SoundServer_StopAllSounds();
386 else if (snd_ctrl.stop_sound)
390 SoundServer_StopSound(snd_ctrl.nr);
393 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
395 if (!playlist[i].active || playlist[i].loop)
398 playlist[i].playingpos = voice_get_position(playlist[i].voice);
399 playlist[i].volume = voice_get_volume(playlist[i].voice);
400 if (playlist[i].playingpos == -1 || !playlist[i].volume)
402 deallocate_voice(playlist[i].voice);
403 playlist[i] = emptySoundControl;
409 SoundServer_InsertNewSound(snd_ctrl);
414 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
418 /* if playlist is full, remove oldest sound */
419 if (playing_sounds==MAX_SOUNDS_PLAYING)
421 int longest=0, longest_nr=0;
423 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
426 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
428 int actual = playlist[i].playingpos;
431 if (!playlist[i].loop && actual>longest)
438 voice_set_volume(playlist[longest_nr].voice, 0);
439 deallocate_voice(playlist[longest_nr].voice);
441 playlist[longest_nr] = emptySoundControl;
445 /* check if sound is already being played (and how often) */
446 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
448 if (playlist[i].nr == snd_ctrl.nr)
452 /* restart loop sounds only if they are just fading out */
453 if (k>=1 && snd_ctrl.loop)
455 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
457 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
459 playlist[i].fade_sound = FALSE;
460 playlist[i].volume = PSND_MAX_VOLUME;
462 playlist[i].loop = PSND_LOOP;
463 voice_stop_volumeramp(playlist[i].voice);
464 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
471 /* don't play sound more than n times simultaneously (with n == 2 for now) */
474 int longest=0, longest_nr=0;
476 /* look for oldest equal sound */
477 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
481 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
485 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
487 actual = playlist[i].playingpos;
496 voice_set_volume(playlist[longest_nr].voice, 0);
497 deallocate_voice(playlist[longest_nr].voice);
499 playlist[longest_nr] = emptySoundControl;
503 /* neuen Sound in Liste packen */
504 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
506 if (!playlist[i].active)
508 playlist[i] = snd_ctrl;
511 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
513 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
514 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
515 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
516 voice_start(playlist[i].voice);
525 void SoundServer_FadeSound(int nr)
532 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
533 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
534 playlist[i].fade_sound = TRUE;
540 static void SoundServer_StopSound(int nr)
547 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
548 if (playlist[i].nr == nr)
551 voice_set_volume(playlist[i].voice, 0);
552 deallocate_voice(playlist[i].voice);
554 playlist[i] = emptySoundControl;
564 static void SoundServer_StopAllSounds()
568 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
571 voice_set_volume(playlist[i].voice, 0);
572 deallocate_voice(playlist[i].voice);
574 playlist[i]=emptySoundControl;
586 static void HPUX_Audio_Control()
588 struct audio_describe ainfo;
591 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
593 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
595 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
596 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
598 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
599 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
601 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
602 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
606 #endif /* HPUX_AUDIO */
608 #if !defined(VOXWARE) && !defined(MSDOS) && !defined(WIN32)
610 /* these two are stolen from "sox"... :) */
613 ** This routine converts from linear to ulaw.
615 ** Craig Reese: IDA/Supercomputing Research Center
616 ** Joe Campbell: Department of Defense
620 ** 1) CCITT Recommendation G.711 (very difficult to follow)
621 ** 2) "A New Digital Technique for Implementation of Any
622 ** Continuous PCM Companding Law," Villeret, Michel,
623 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
624 ** 1973, pg. 11.12-11.17
625 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
626 ** for Analog-to_Digital Conversion Techniques,"
629 ** Input: Signed 16 bit linear sample
630 ** Output: 8 bit ulaw sample
633 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
634 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
637 static unsigned char linear_to_ulaw(int sample)
639 static int exp_lut[256] =
641 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
642 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
643 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
644 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
645 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
646 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
647 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
648 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
649 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
650 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
651 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
652 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
653 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
654 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
655 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
656 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
659 int sign, exponent, mantissa;
660 unsigned char ulawbyte;
662 /* Get the sample into sign-magnitude. */
663 sign = (sample >> 8) & 0x80; /* set aside the sign */
665 sample = -sample; /* get magnitude */
667 sample = CLIP; /* clip the magnitude */
669 /* Convert from 16 bit linear to ulaw. */
670 sample = sample + BIAS;
671 exponent = exp_lut[( sample >> 7 ) & 0xFF];
672 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
673 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
676 ulawbyte = 0x02; /* optional CCITT trap */
683 ** This routine converts from ulaw to 16 bit linear.
685 ** Craig Reese: IDA/Supercomputing Research Center
689 ** 1) CCITT Recommendation G.711 (very difficult to follow)
690 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
691 ** for Analog-to_Digital Conversion Techniques,"
694 ** Input: 8 bit ulaw sample
695 ** Output: signed 16 bit linear sample
698 static int ulaw_to_linear(unsigned char ulawbyte)
700 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
701 int sign, exponent, mantissa, sample;
703 ulawbyte = ~ ulawbyte;
704 sign = ( ulawbyte & 0x80 );
705 exponent = ( ulawbyte >> 4 ) & 0x07;
706 mantissa = ulawbyte & 0x0F;
707 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
713 #endif /* !VOXWARE && !MSDOS && !WIN32 */
715 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
717 /*===========================================================================*/
719 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
721 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
722 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
724 boolean LoadSound(struct SoundInfo *snd_info)
727 char *sound_ext = "wav";
728 #ifndef USE_SDL_LIBRARY
730 byte sound_header_buffer[WAV_HEADER_SIZE];
731 char chunk[CHUNK_ID_LEN + 1];
732 int chunk_length, dummy;
738 sprintf(filename, "%s/%s/%s.%s",
739 options.ro_base_directory, SOUNDS_DIRECTORY,
740 snd_info->name, sound_ext);
742 #ifdef USE_SDL_LIBRARY
744 snd_info->mix_chunk = Mix_LoadWAV(filename);
745 if (snd_info->mix_chunk == NULL)
747 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
751 #else /* !USE_SDL_LIBRARY */
755 if ((file = fopen(filename, "r")) == NULL)
757 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
761 /* read chunk "RIFF" */
762 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
763 if (strcmp(chunk, "RIFF") != 0)
765 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
770 /* read chunk "WAVE" */
771 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
772 if (strcmp(chunk, "WAVE") != 0)
774 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
779 /* read header information */
780 for (i=0; i<WAV_HEADER_SIZE; i++)
781 sound_header_buffer[i] = fgetc(file);
783 /* read chunk "data" */
784 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
785 if (strcmp(chunk, "data") != 0)
787 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
792 snd_info->data_len = chunk_length;
793 snd_info->data_ptr = checked_malloc(snd_info->data_len);
795 /* read sound data */
796 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
799 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
806 for (i=0; i<snd_info->data_len; i++)
807 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
811 snd_info->sample_ptr = load_sample(filename);
812 if (!snd_info->sample_ptr)
814 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
819 #endif /* !USE_SDL_LIBRARY */
824 void PlaySound(int nr)
826 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
829 void PlaySoundStereo(int nr, int stereo)
831 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
834 void PlaySoundLoop(int nr)
836 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
839 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
841 struct SoundControl snd_ctrl = emptySoundControl;
843 if (sound_status==SOUND_OFF || !setup.sound)
846 if (volume<PSND_MIN_VOLUME)
847 volume = PSND_MIN_VOLUME;
848 else if (volume>PSND_MAX_VOLUME)
849 volume = PSND_MAX_VOLUME;
851 if (stereo<PSND_MAX_LEFT)
852 stereo = PSND_MAX_LEFT;
853 else if (stereo>PSND_MAX_RIGHT)
854 stereo = PSND_MAX_RIGHT;
857 snd_ctrl.volume = volume;
858 snd_ctrl.stereo = stereo;
859 snd_ctrl.loop = loop;
860 snd_ctrl.active = TRUE;
861 snd_ctrl.data_ptr = Sound[nr].data_ptr;
862 snd_ctrl.data_len = Sound[nr].data_len;
864 #ifdef USE_SDL_LIBRARY
866 Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
867 Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
869 Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
873 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
875 Error(ERR_WARN, "cannot pipe to child process - no sounds");
876 sound_status = SOUND_OFF;
880 sound_handler(snd_ctrl);
885 void FadeSound(int nr)
887 StopSoundExt(nr, SSND_FADE_SOUND);
892 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
895 void StopSound(int nr)
897 StopSoundExt(nr, SSND_STOP_SOUND);
902 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
905 void StopSoundExt(int nr, int method)
907 struct SoundControl snd_ctrl = emptySoundControl;
909 if (sound_status==SOUND_OFF)
912 if (SSND_FADING(method))
913 snd_ctrl.fade_sound = TRUE;
915 if (SSND_ALL(method))
916 snd_ctrl.stop_all_sounds = TRUE;
920 snd_ctrl.stop_sound = TRUE;
923 #ifdef USE_SDL_LIBRARY
925 if (SSND_FADING(method))
927 Mix_FadeOutChannel(-1, 1000);
928 Mix_FadeOutMusic(1000);
938 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
940 Error(ERR_WARN, "cannot pipe to child process - no sounds");
941 sound_status = SOUND_OFF;
945 sound_handler(snd_ctrl);
950 void FreeSounds(int num_sounds)
954 if (sound_status == SOUND_OFF)
957 for(i=0; i<num_sounds; i++)
959 free(Sound[i].data_ptr);
961 destroy_sample(Sound[i].sample_ptr);
965 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/