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(PLATFORM_UNIX)
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);
41 #if defined(PLATFORM_UNIX)
42 static unsigned char linear_to_ulaw(int);
43 static int ulaw_to_linear(unsigned char);
48 static void HPUX_Audio_Control();
51 #if defined(PLATFORM_MSDOS)
52 static void SoundServer_InsertNewSound(struct SoundControl);
53 static void SoundServer_StopSound(int);
54 static void SoundServer_StopAllSounds();
57 #if defined(PLATFORM_UNIX)
58 int OpenAudio(char *audio_device_name)
62 /* try to open audio device in non-blocking mode */
63 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
66 /* re-open audio device in blocking mode */
68 audio_fd = open(audio_device_name, O_WRONLY);
73 int CheckAudio(char *audio_device_name)
77 if (access(audio_device_name, W_OK) != 0)
79 Error(ERR_WARN, "cannot access audio device - no sound");
83 if ((audio_fd = OpenAudio(sound_device_name)) < 0)
85 Error(ERR_WARN, "cannot open audio device - no sound");
91 return SOUND_AVAILABLE;
94 void UnixInitAudio(struct AudioSystemInfo *audio)
96 if (!(audio->sound_available = CheckAudio(sound_device_name)))
100 audio->loops_available = TRUE;
103 #endif /* PLATFORM_UNIX */
108 #if defined(PLATFORM_UNIX)
109 struct SoundControl snd_ctrl;
112 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
115 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
116 playlist[i] = emptySoundControl;
119 #if defined(PLATFORM_UNIX)
120 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
121 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
123 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
126 HPUX_Audio_Control();
129 FD_ZERO(&sound_fdset);
130 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
132 while(1) /* wait for sound playing commands from client */
134 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
135 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
136 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
138 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
140 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
144 if (snd_ctrl.fade_sound)
149 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
150 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
151 playlist[i].fade_sound = TRUE;
153 else if (snd_ctrl.stop_all_sounds)
158 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
159 playlist[i]=emptySoundControl;
162 close(audio.device_fd);
164 else if (snd_ctrl.stop_sound)
169 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
170 if (playlist[i].nr == snd_ctrl.nr)
172 playlist[i]=emptySoundControl;
177 close(audio.device_fd);
180 if (playing_sounds || snd_ctrl.active)
182 struct timeval delay = { 0, 0 };
185 static long max_sample_size = 0;
186 static long fragment_size = 0;
187 /* Even if the stereo flag is used as being boolean, it must be
188 defined as an integer, else 'ioctl()' will fail! */
191 int sample_rate = 8000;
193 int sample_rate = 22050;
196 if (playing_sounds ||
197 (audio.device_fd = OpenAudio(sound_device_name)) >= 0)
199 if (!playing_sounds) /* we just opened the audio device */
201 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
202 /* (with stereo the effective buffer size will shrink to 256) */
203 fragment_size = 0x00020009;
205 if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
206 Error(ERR_EXIT_SOUND_SERVER,
207 "cannot set fragment size of /dev/dsp - no sounds");
209 /* try if we can use stereo sound */
210 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
213 static boolean reported = FALSE;
217 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
224 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
225 Error(ERR_EXIT_SOUND_SERVER,
226 "cannot set sample rate of /dev/dsp - no sounds");
228 /* get the real fragmentation size; this should return 512 */
229 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
230 Error(ERR_EXIT_SOUND_SERVER,
231 "cannot get fragment size of /dev/dsp - no sounds");
233 max_sample_size = fragment_size / (stereo ? 2 : 1);
236 if (snd_ctrl.active) /* new sound has arrived */
237 SoundServer_InsertNewSound(snd_ctrl);
239 while(playing_sounds &&
240 select(audio.soundserver_pipe[0] + 1,
241 &sound_fdset, NULL, NULL, &delay) < 1)
243 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
245 /* first clear the last premixing buffer */
246 memset(premix_last_buffer,0,fragment_size*sizeof(int));
248 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
252 if (!playlist[i].active)
255 /* get pointer and size of the actual sound sample */
256 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
258 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
259 playlist[i].playingpos += sample_size;
261 /* fill the first mixing buffer with original sample */
262 memcpy(premix_first_buffer,sample_ptr,sample_size);
264 /* are we about to restart a looping sound? */
265 if (playlist[i].loop && sample_size<max_sample_size)
267 playlist[i].playingpos = max_sample_size-sample_size;
268 memcpy(premix_first_buffer+sample_size,
269 playlist[i].data_ptr,max_sample_size-sample_size);
270 sample_size = max_sample_size;
273 /* decrease volume if sound is fading out */
274 if (playlist[i].fade_sound &&
275 playlist[i].volume>=PSND_MAX_VOLUME/10)
276 playlist[i].volume-=PSND_MAX_VOLUME/20;
278 /* adjust volume of actual sound sample */
279 if (playlist[i].volume != PSND_MAX_VOLUME)
280 for(j=0;j<sample_size;j++)
281 premix_first_buffer[j] =
282 (playlist[i].volume * (int)premix_first_buffer[j])
283 >> PSND_MAX_VOLUME_BITS;
285 /* fill the last mixing buffer with stereo or mono sound */
288 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
289 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
290 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
292 for(j=0;j<sample_size;j++)
294 premix_left_buffer[j] =
295 (left_volume * (int)premix_first_buffer[j])
296 >> PSND_MAX_LEFT2RIGHT_BITS;
297 premix_right_buffer[j] =
298 (right_volume * (int)premix_first_buffer[j])
299 >> PSND_MAX_LEFT2RIGHT_BITS;
300 premix_last_buffer[2*j+0] += premix_left_buffer[j];
301 premix_last_buffer[2*j+1] += premix_right_buffer[j];
306 for(j=0;j<sample_size;j++)
307 premix_last_buffer[j] += (int)premix_first_buffer[j];
310 /* delete completed sound entries from the playlist */
311 if (playlist[i].playingpos >= playlist[i].data_len)
313 if (playlist[i].loop)
314 playlist[i].playingpos = 0;
317 playlist[i] = emptySoundControl;
321 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
323 playlist[i] = emptySoundControl;
328 /* put last mixing buffer to final playing buffer */
329 for(i=0;i<fragment_size;i++)
331 if (premix_last_buffer[i]<-255)
332 playing_buffer[i] = 0;
333 else if (premix_last_buffer[i]>255)
334 playing_buffer[i] = 255;
336 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
339 /* finally play the sound fragment */
340 write(audio.device_fd, playing_buffer,fragment_size);
343 /* if no sounds playing, free device for other sound programs */
345 close(audio.device_fd);
351 if (snd_ctrl.active && !snd_ctrl.loop)
353 struct timeval delay = { 0, 0 };
355 long sample_size, max_sample_size = SND_BLOCKSIZE;
356 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
357 int wait_percent = 90; /* wait 90% of the real playing time */
360 if ((audio.device_fd = OpenAudio(sound_device_name)) >= 0)
364 while(playing_sounds &&
365 select(audio.soundserver_pipe[0] + 1,
366 &sound_fdset, NULL, NULL, &delay) < 1)
368 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
370 /* get pointer and size of the actual sound sample */
371 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
373 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
374 snd_ctrl.playingpos += sample_size;
376 /* fill the first mixing buffer with original sample */
377 memcpy(premix_first_buffer,sample_ptr,sample_size);
380 /* adjust volume of actual sound sample */
381 if (snd_ctrl.volume != PSND_MAX_VOLUME)
382 for(i=0;i<sample_size;i++)
383 premix_first_buffer[i] =
384 (snd_ctrl.volume * (int)premix_first_buffer[i])
385 >> PSND_MAX_VOLUME_BITS;
387 for(i=0;i<sample_size;i++)
389 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
391 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
394 /* finally play the sound fragment */
395 write(audio.device_fd,playing_buffer,sample_size);
398 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
400 close(audio.device_fd);
404 #endif /* !VOXWARE */
408 #endif /* PLATFORM_UNIX */
412 #if defined(PLATFORM_MSDOS)
413 static void sound_handler(struct SoundControl snd_ctrl)
417 if (snd_ctrl.fade_sound)
422 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
423 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
424 !playlist[i].fade_sound)
426 playlist[i].fade_sound = TRUE;
427 if (voice_check(playlist[i].voice))
428 voice_ramp_volume(playlist[i].voice, 1000, 0);
429 playlist[i].loop = PSND_NO_LOOP;
432 else if (snd_ctrl.stop_all_sounds)
436 SoundServer_StopAllSounds();
438 else if (snd_ctrl.stop_sound)
442 SoundServer_StopSound(snd_ctrl.nr);
445 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
447 if (!playlist[i].active || playlist[i].loop)
450 playlist[i].playingpos = voice_get_position(playlist[i].voice);
451 playlist[i].volume = voice_get_volume(playlist[i].voice);
452 if (playlist[i].playingpos == -1 || !playlist[i].volume)
454 deallocate_voice(playlist[i].voice);
455 playlist[i] = emptySoundControl;
461 SoundServer_InsertNewSound(snd_ctrl);
463 #endif /* PLATFORM_MSDOS */
465 #if !defined(PLATFORM_WIN32)
466 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
470 /* if playlist is full, remove oldest sound */
471 if (playing_sounds==MAX_SOUNDS_PLAYING)
473 int longest=0, longest_nr=0;
475 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
477 #if !defined(PLATFORM_MSDOS)
478 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
480 int actual = playlist[i].playingpos;
483 if (!playlist[i].loop && actual>longest)
489 #if defined(PLATFORM_MSDOS)
490 voice_set_volume(playlist[longest_nr].voice, 0);
491 deallocate_voice(playlist[longest_nr].voice);
493 playlist[longest_nr] = emptySoundControl;
497 /* check if sound is already being played (and how often) */
498 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
500 if (playlist[i].nr == snd_ctrl.nr)
504 /* restart loop sounds only if they are just fading out */
505 if (k>=1 && snd_ctrl.loop)
507 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
509 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
511 playlist[i].fade_sound = FALSE;
512 playlist[i].volume = PSND_MAX_VOLUME;
513 #if defined(PLATFORM_MSDOS)
514 playlist[i].loop = PSND_LOOP;
515 voice_stop_volumeramp(playlist[i].voice);
516 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
523 /* don't play sound more than n times simultaneously (with n == 2 for now) */
526 int longest=0, longest_nr=0;
528 /* look for oldest equal sound */
529 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
533 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
536 #if !defined(PLATFORM_MSDOS)
537 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
539 actual = playlist[i].playingpos;
548 #if defined(PLATFORM_MSDOS)
549 voice_set_volume(playlist[longest_nr].voice, 0);
550 deallocate_voice(playlist[longest_nr].voice);
552 playlist[longest_nr] = emptySoundControl;
556 /* neuen Sound in Liste packen */
557 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
559 if (!playlist[i].active)
561 playlist[i] = snd_ctrl;
564 #if defined(PLATFORM_MSDOS)
565 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
567 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
568 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
569 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
570 voice_start(playlist[i].voice);
576 #endif /* !PLATFORM_WIN32 */
579 void SoundServer_FadeSound(int nr)
586 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
587 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
588 playlist[i].fade_sound = TRUE;
592 #if !defined(PLATFORM_WIN32)
593 #if defined(PLATFORM_MSDOS)
594 static void SoundServer_StopSound(int nr)
601 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
602 if (playlist[i].nr == nr)
604 #if defined(PLATFORM_MSDOS)
605 voice_set_volume(playlist[i].voice, 0);
606 deallocate_voice(playlist[i].voice);
608 playlist[i] = emptySoundControl;
612 #if !defined(PLATFORM_MSDOS)
614 close(audio.device_fd);
618 static void SoundServer_StopAllSounds()
622 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
624 #if defined(PLATFORM_MSDOS)
625 voice_set_volume(playlist[i].voice, 0);
626 deallocate_voice(playlist[i].voice);
628 playlist[i]=emptySoundControl;
632 #if !defined(PLATFORM_MSDOS)
633 close(audio.device_fd);
636 #endif /* PLATFORM_MSDOS */
637 #endif /* !PLATFORM_WIN32 */
640 static void HPUX_Audio_Control()
642 struct audio_describe ainfo;
645 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
647 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
649 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
650 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
652 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
653 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
655 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
656 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
660 #endif /* HPUX_AUDIO */
662 #if !defined(VOXWARE) && defined(PLATFORM_UNIX)
664 /* these two are stolen from "sox"... :) */
667 ** This routine converts from linear to ulaw.
669 ** Craig Reese: IDA/Supercomputing Research Center
670 ** Joe Campbell: Department of Defense
674 ** 1) CCITT Recommendation G.711 (very difficult to follow)
675 ** 2) "A New Digital Technique for Implementation of Any
676 ** Continuous PCM Companding Law," Villeret, Michel,
677 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
678 ** 1973, pg. 11.12-11.17
679 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
680 ** for Analog-to_Digital Conversion Techniques,"
683 ** Input: Signed 16 bit linear sample
684 ** Output: 8 bit ulaw sample
687 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
688 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
691 static unsigned char linear_to_ulaw(int sample)
693 static int exp_lut[256] =
695 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
696 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
697 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
698 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
699 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
700 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
701 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
702 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
703 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
704 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
705 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
706 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
707 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
708 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
709 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
710 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
713 int sign, exponent, mantissa;
714 unsigned char ulawbyte;
716 /* Get the sample into sign-magnitude. */
717 sign = (sample >> 8) & 0x80; /* set aside the sign */
719 sample = -sample; /* get magnitude */
721 sample = CLIP; /* clip the magnitude */
723 /* Convert from 16 bit linear to ulaw. */
724 sample = sample + BIAS;
725 exponent = exp_lut[( sample >> 7 ) & 0xFF];
726 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
727 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
730 ulawbyte = 0x02; /* optional CCITT trap */
737 ** This routine converts from ulaw to 16 bit linear.
739 ** Craig Reese: IDA/Supercomputing Research Center
743 ** 1) CCITT Recommendation G.711 (very difficult to follow)
744 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
745 ** for Analog-to_Digital Conversion Techniques,"
748 ** Input: 8 bit ulaw sample
749 ** Output: signed 16 bit linear sample
752 static int ulaw_to_linear(unsigned char ulawbyte)
754 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
755 int sign, exponent, mantissa, sample;
757 ulawbyte = ~ ulawbyte;
758 sign = ( ulawbyte & 0x80 );
759 exponent = ( ulawbyte >> 4 ) & 0x07;
760 mantissa = ulawbyte & 0x0F;
761 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
767 #endif /* !VOXWARE && PLATFORM_UNIX */
769 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
771 /*===========================================================================*/
773 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
775 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
776 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
778 boolean LoadSound(struct SampleInfo *snd_info)
781 char *sound_ext = "wav";
782 #if !defined(TARGET_SDL)
783 #if !defined(PLATFORM_MSDOS)
784 byte sound_header_buffer[WAV_HEADER_SIZE];
785 char chunk[CHUNK_ID_LEN + 1];
786 int chunk_length, dummy;
792 sprintf(filename, "%s/%s/%s.%s",
793 options.ro_base_directory, SOUNDS_DIRECTORY,
794 snd_info->name, sound_ext);
796 #if defined(TARGET_SDL)
798 snd_info->mix_chunk = Mix_LoadWAV(filename);
799 if (snd_info->mix_chunk == NULL)
801 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
805 #else /* !TARGET_SDL */
807 #if !defined(PLATFORM_MSDOS)
809 if ((file = fopen(filename, "r")) == NULL)
811 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
815 /* read chunk "RIFF" */
816 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
817 if (strcmp(chunk, "RIFF") != 0)
819 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
824 /* read chunk "WAVE" */
825 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
826 if (strcmp(chunk, "WAVE") != 0)
828 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
833 /* read header information */
834 for (i=0; i<WAV_HEADER_SIZE; i++)
835 sound_header_buffer[i] = fgetc(file);
837 /* read chunk "data" */
838 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
839 if (strcmp(chunk, "data") != 0)
841 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
846 snd_info->data_len = chunk_length;
847 snd_info->data_ptr = checked_malloc(snd_info->data_len);
849 /* read sound data */
850 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
853 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
860 for (i=0; i<snd_info->data_len; i++)
861 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
863 #else /* PLATFORM_MSDOS */
865 snd_info->sample_ptr = load_sample(filename);
866 if (!snd_info->sample_ptr)
868 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
872 #endif /* PLATFORM_MSDOS */
873 #endif /* !TARGET_SDL */
878 void PlaySound(int nr)
880 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
883 void PlaySoundStereo(int nr, int stereo)
885 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
888 void PlaySoundLoop(int nr)
890 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
893 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
895 struct SoundControl snd_ctrl = emptySoundControl;
897 if (!audio.sound_available || !setup.sound)
900 if (volume<PSND_MIN_VOLUME)
901 volume = PSND_MIN_VOLUME;
902 else if (volume>PSND_MAX_VOLUME)
903 volume = PSND_MAX_VOLUME;
905 if (stereo<PSND_MAX_LEFT)
906 stereo = PSND_MAX_LEFT;
907 else if (stereo>PSND_MAX_RIGHT)
908 stereo = PSND_MAX_RIGHT;
911 snd_ctrl.volume = volume;
912 snd_ctrl.stereo = stereo;
913 snd_ctrl.loop = loop;
914 snd_ctrl.active = TRUE;
915 snd_ctrl.data_ptr = Sound[nr].data_ptr;
916 snd_ctrl.data_len = Sound[nr].data_len;
918 #if defined(TARGET_SDL)
920 Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
921 Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
923 Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
926 #if !defined(PLATFORM_MSDOS)
927 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
929 Error(ERR_WARN, "cannot pipe to child process - no sounds");
930 audio.sound_available = FALSE;
934 sound_handler(snd_ctrl);
939 void FadeSound(int nr)
941 StopSoundExt(nr, SSND_FADE_SOUND);
946 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
949 void StopSound(int nr)
951 StopSoundExt(nr, SSND_STOP_SOUND);
956 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
959 void StopSoundExt(int nr, int method)
961 struct SoundControl snd_ctrl = emptySoundControl;
963 if (!audio.sound_available)
966 if (SSND_FADING(method))
967 snd_ctrl.fade_sound = TRUE;
969 if (SSND_ALL(method))
970 snd_ctrl.stop_all_sounds = TRUE;
974 snd_ctrl.stop_sound = TRUE;
977 #if defined(TARGET_SDL)
979 if (SSND_FADING(method))
981 Mix_FadeOutChannel(-1, 1000);
982 Mix_FadeOutMusic(1000);
991 #if !defined(PLATFORM_MSDOS)
992 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
994 Error(ERR_WARN, "cannot pipe to child process - no sounds");
995 audio.sound_available = FALSE;
999 sound_handler(snd_ctrl);
1004 void FreeSounds(int num_sounds)
1008 if (!audio.sound_available)
1011 for(i=0; i<num_sounds; i++)
1012 #if !defined(PLATFORM_MSDOS)
1013 free(Sound[i].data_ptr);
1015 destroy_sample(Sound[i].sample_ptr);
1019 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/