1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
26 static int num_sounds = 0, num_music = 0;
27 static struct SampleInfo *Sound = NULL;
28 #if defined(TARGET_SDL)
29 static int num_mods = 0;
30 static struct SampleInfo *Mod = NULL;
34 /* ========================================================================= */
35 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
37 static int playing_sounds = 0;
38 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
39 static struct SoundControl emptySoundControl =
41 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
44 #if defined(PLATFORM_UNIX)
45 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
46 static char premix_first_buffer[SND_BLOCKSIZE];
47 #if defined(AUDIO_STREAMING_DSP)
48 static char premix_left_buffer[SND_BLOCKSIZE];
49 static char premix_right_buffer[SND_BLOCKSIZE];
50 static int premix_last_buffer[SND_BLOCKSIZE];
52 static unsigned char playing_buffer[SND_BLOCKSIZE];
55 /* forward declaration of internal functions */
56 #if defined(AUDIO_STREAMING_DSP)
57 static void SoundServer_InsertNewSound(struct SoundControl);
58 #elif defined(PLATFORM_UNIX)
59 static unsigned char linear_to_ulaw(int);
60 static int ulaw_to_linear(unsigned char);
63 #if defined(AUDIO_LINUX_IOCTL)
64 static boolean InitAudioDevice_Linux();
65 #elif defined(PLATFORM_NETBSD)
66 static boolean InitAudioDevice_NetBSD();
67 #elif defined(PLATFORM_HPUX)
68 static boolean InitAudioDevice_HPUX();
69 #elif defined(PLATFORM_MSDOS)
70 static void SoundServer_InsertNewSound(struct SoundControl);
71 static void SoundServer_StopSound(int);
72 static void SoundServer_StopAllSounds();
75 #if defined(PLATFORM_UNIX)
76 static int OpenAudioDevice(char *audio_device_name)
80 /* check if desired audio device is accessible */
81 if (access(audio_device_name, W_OK) != 0)
84 /* try to open audio device in non-blocking mode */
85 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
88 /* re-open audio device in blocking mode */
90 audio_fd = open(audio_device_name, O_WRONLY);
95 static boolean TestAudioDevices(void)
97 static char *audio_device_name[] =
105 /* look for available audio devices, starting with preferred ones */
106 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
107 if ((audio_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
112 Error(ERR_WARN, "cannot open audio device -- no sound");
118 audio.device_name = audio_device_name[i];
123 #if !defined(TARGET_SDL)
124 static boolean ForkAudioProcess(void)
126 if (pipe(audio.soundserver_pipe) < 0)
128 Error(ERR_WARN, "cannot create pipe -- no sounds");
132 if ((audio.soundserver_pid = fork()) < 0)
134 Error(ERR_WARN, "cannot create sound server process -- no sounds");
138 if (audio.soundserver_pid == 0) /* we are child process */
145 else /* we are parent */
146 close(audio.soundserver_pipe[0]); /* no reading from pipe needed */
152 void UnixOpenAudio(void)
154 if (!TestAudioDevices())
157 audio.sound_available = TRUE;
158 audio.sound_enabled = TRUE;
160 #if defined(AUDIO_STREAMING_DSP)
161 audio.music_available = TRUE;
162 audio.loops_available = TRUE;
166 void UnixCloseAudio(void)
169 close(audio.device_fd);
171 if (audio.soundserver_pid > 0) /* we are parent process */
172 kill(audio.soundserver_pid, SIGTERM);
174 #endif /* PLATFORM_UNIX */
176 void InitPlaylist(void)
180 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
181 playlist[i] = emptySoundControl;
185 void StartSoundserver(void)
187 if (!audio.sound_available)
190 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
191 if (!ForkAudioProcess())
192 audio.sound_available = FALSE;
196 #if defined(PLATFORM_UNIX)
197 void SoundServer(void)
201 struct SoundControl snd_ctrl;
204 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
208 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
209 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
211 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
213 #if defined(PLATFORM_HPUX)
214 InitAudioDevice_HPUX();
217 FD_ZERO(&sound_fdset);
218 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
220 while(1) /* wait for sound playing commands from client */
222 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
223 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
224 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
226 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
228 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
230 if (snd_ctrl.reload_sounds || snd_ctrl.reload_music)
232 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
233 playlist[i] = emptySoundControl;
236 close(audio.device_fd);
238 if (snd_ctrl.reload_sounds)
246 #if defined(AUDIO_STREAMING_DSP)
248 if (snd_ctrl.fade_sound)
253 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
254 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
255 playlist[i].fade_sound = TRUE;
257 else if (snd_ctrl.stop_all_sounds)
262 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
263 playlist[i] = emptySoundControl;
266 close(audio.device_fd);
268 else if (snd_ctrl.stop_sound)
273 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
274 if (playlist[i].nr == snd_ctrl.nr)
276 playlist[i] = emptySoundControl;
281 close(audio.device_fd);
284 if (playing_sounds || snd_ctrl.active)
286 struct timeval delay = { 0, 0 };
289 static long max_sample_size = 0;
290 static long fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
291 int sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
292 static boolean stereo = TRUE;
294 if (playing_sounds ||
295 (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
297 if (!playing_sounds) /* we just opened the audio device */
299 #if defined(AUDIO_LINUX_IOCTL)
300 stereo = InitAudioDevice_Linux(fragment_size, sample_rate);
301 #elif defined(PLATFORM_NETBSD)
302 stereo = InitAudioDevice_NetBSD(fragment_size, sample_rate);
304 max_sample_size = fragment_size / (stereo ? 2 : 1);
307 if (snd_ctrl.active) /* new sound has arrived */
308 SoundServer_InsertNewSound(snd_ctrl);
310 while(playing_sounds &&
311 select(audio.soundserver_pipe[0] + 1,
312 &sound_fdset, NULL, NULL, &delay) < 1)
314 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
316 /* first clear the last premixing buffer */
317 memset(premix_last_buffer, 0, fragment_size * sizeof(int));
319 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
323 if (!playlist[i].active)
326 /* get pointer and size of the actual sound sample */
327 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
329 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
330 playlist[i].playingpos += sample_size;
332 /* fill the first mixing buffer with original sample */
333 memcpy(premix_first_buffer,sample_ptr,sample_size);
335 /* are we about to restart a looping sound? */
336 if (playlist[i].loop && sample_size<max_sample_size)
338 playlist[i].playingpos = max_sample_size-sample_size;
339 memcpy(premix_first_buffer+sample_size,
340 playlist[i].data_ptr,max_sample_size-sample_size);
341 sample_size = max_sample_size;
344 /* decrease volume if sound is fading out */
345 if (playlist[i].fade_sound &&
346 playlist[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
347 playlist[i].volume -= SOUND_FADING_VOLUME_STEP;
349 /* adjust volume of actual sound sample */
350 if (playlist[i].volume != PSND_MAX_VOLUME)
351 for(j=0;j<sample_size;j++)
352 premix_first_buffer[j] =
353 (playlist[i].volume * (int)premix_first_buffer[j])
354 >> PSND_MAX_VOLUME_BITS;
356 /* fill the last mixing buffer with stereo or mono sound */
359 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
360 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
361 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
363 for(j=0;j<sample_size;j++)
365 premix_left_buffer[j] =
366 (left_volume * (int)premix_first_buffer[j])
367 >> PSND_MAX_LEFT2RIGHT_BITS;
368 premix_right_buffer[j] =
369 (right_volume * (int)premix_first_buffer[j])
370 >> PSND_MAX_LEFT2RIGHT_BITS;
371 premix_last_buffer[2*j+0] += premix_left_buffer[j];
372 premix_last_buffer[2*j+1] += premix_right_buffer[j];
377 for(j=0;j<sample_size;j++)
378 premix_last_buffer[j] += (int)premix_first_buffer[j];
381 /* delete completed sound entries from the playlist */
382 if (playlist[i].playingpos >= playlist[i].data_len)
384 if (playlist[i].loop)
385 playlist[i].playingpos = 0;
388 playlist[i] = emptySoundControl;
392 else if (playlist[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
394 playlist[i] = emptySoundControl;
399 /* put last mixing buffer to final playing buffer */
400 for(i=0; i<fragment_size; i++)
402 if (premix_last_buffer[i]<-255)
403 playing_buffer[i] = 0;
404 else if (premix_last_buffer[i]>255)
405 playing_buffer[i] = 255;
407 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
410 /* finally play the sound fragment */
411 write(audio.device_fd, playing_buffer, fragment_size);
414 /* if no sounds playing, free device for other sound programs */
416 close(audio.device_fd);
420 #else /* !AUDIO_STREAMING_DSP */
422 if (snd_ctrl.active && !snd_ctrl.loop)
424 struct timeval delay = { 0, 0 };
426 long sample_size, max_sample_size = SND_BLOCKSIZE;
427 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
428 int wait_percent = 90; /* wait 90% of the real playing time */
431 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
435 while(playing_sounds &&
436 select(audio.soundserver_pipe[0] + 1,
437 &sound_fdset, NULL, NULL, &delay) < 1)
439 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
441 /* get pointer and size of the actual sound sample */
442 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
444 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
445 snd_ctrl.playingpos += sample_size;
447 /* fill the first mixing buffer with original sample */
448 memcpy(premix_first_buffer,sample_ptr,sample_size);
450 /* adjust volume of actual sound sample */
451 if (snd_ctrl.volume != PSND_MAX_VOLUME)
452 for(i=0;i<sample_size;i++)
453 premix_first_buffer[i] =
454 (snd_ctrl.volume * (int)premix_first_buffer[i])
455 >> PSND_MAX_VOLUME_BITS;
457 for(i=0;i<sample_size;i++)
459 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
461 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
464 /* finally play the sound fragment */
465 write(audio.device_fd,playing_buffer,sample_size);
468 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
470 close(audio.device_fd);
473 #endif /* !AUDIO_STREAMING_DSP */
476 #endif /* PLATFORM_UNIX */
478 #if defined(PLATFORM_MSDOS)
479 static void sound_handler(struct SoundControl snd_ctrl)
483 if (snd_ctrl.fade_sound)
488 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
489 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
490 !playlist[i].fade_sound)
492 playlist[i].fade_sound = TRUE;
493 if (voice_check(playlist[i].voice))
494 voice_ramp_volume(playlist[i].voice, 1000, 0);
495 playlist[i].loop = PSND_NO_LOOP;
498 else if (snd_ctrl.stop_all_sounds)
502 SoundServer_StopAllSounds();
504 else if (snd_ctrl.stop_sound)
508 SoundServer_StopSound(snd_ctrl.nr);
511 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
513 if (!playlist[i].active || playlist[i].loop)
516 playlist[i].playingpos = voice_get_position(playlist[i].voice);
517 playlist[i].volume = voice_get_volume(playlist[i].voice);
518 if (playlist[i].playingpos == -1 || !playlist[i].volume)
520 deallocate_voice(playlist[i].voice);
521 playlist[i] = emptySoundControl;
527 SoundServer_InsertNewSound(snd_ctrl);
529 #endif /* PLATFORM_MSDOS */
531 #if !defined(PLATFORM_WIN32)
532 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
536 /* if playlist is full, remove oldest sound */
537 if (playing_sounds==MAX_SOUNDS_PLAYING)
539 int longest=0, longest_nr=0;
541 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
543 #if !defined(PLATFORM_MSDOS)
544 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
546 int actual = playlist[i].playingpos;
549 if (!playlist[i].loop && actual>longest)
555 #if defined(PLATFORM_MSDOS)
556 voice_set_volume(playlist[longest_nr].voice, 0);
557 deallocate_voice(playlist[longest_nr].voice);
559 playlist[longest_nr] = emptySoundControl;
563 /* check if sound is already being played (and how often) */
564 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
566 if (playlist[i].nr == snd_ctrl.nr)
570 /* restart loop sounds only if they are just fading out */
571 if (k>=1 && snd_ctrl.loop)
573 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
575 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
577 playlist[i].fade_sound = FALSE;
578 playlist[i].volume = PSND_MAX_VOLUME;
579 #if defined(PLATFORM_MSDOS)
580 playlist[i].loop = PSND_LOOP;
581 voice_stop_volumeramp(playlist[i].voice);
582 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
589 /* don't play sound more than n times simultaneously (with n == 2 for now) */
592 int longest=0, longest_nr=0;
594 /* look for oldest equal sound */
595 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
599 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
602 #if !defined(PLATFORM_MSDOS)
603 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
605 actual = playlist[i].playingpos;
614 #if defined(PLATFORM_MSDOS)
615 voice_set_volume(playlist[longest_nr].voice, 0);
616 deallocate_voice(playlist[longest_nr].voice);
618 playlist[longest_nr] = emptySoundControl;
622 /* neuen Sound in Liste packen */
623 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
625 if (!playlist[i].active)
627 playlist[i] = snd_ctrl;
630 #if defined(PLATFORM_MSDOS)
631 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
633 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
634 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
635 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
636 voice_start(playlist[i].voice);
642 #endif /* !PLATFORM_WIN32 */
645 void SoundServer_FadeSound(int nr)
652 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
653 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
654 playlist[i].fade_sound = TRUE;
658 #if !defined(PLATFORM_WIN32)
659 #if defined(PLATFORM_MSDOS)
660 static void SoundServer_StopSound(int nr)
667 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
668 if (playlist[i].nr == nr)
670 #if defined(PLATFORM_MSDOS)
671 voice_set_volume(playlist[i].voice, 0);
672 deallocate_voice(playlist[i].voice);
674 playlist[i] = emptySoundControl;
678 #if !defined(PLATFORM_MSDOS)
680 close(audio.device_fd);
684 static void SoundServer_StopAllSounds()
688 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
690 #if defined(PLATFORM_MSDOS)
691 voice_set_volume(playlist[i].voice, 0);
692 deallocate_voice(playlist[i].voice);
694 playlist[i]=emptySoundControl;
698 #if !defined(PLATFORM_MSDOS)
699 close(audio.device_fd);
702 #endif /* PLATFORM_MSDOS */
703 #endif /* !PLATFORM_WIN32 */
706 /* ------------------------------------------------------------------------- */
707 /* platform dependant audio initialization code */
708 /* ------------------------------------------------------------------------- */
710 #if defined(AUDIO_LINUX_IOCTL)
711 static boolean InitAudioDevice_Linux(long fragment_size, int sample_rate)
713 /* "ioctl()" expects pointer to 'int' value for stereo flag
714 (boolean is defined as 'char', which will not work here) */
716 unsigned long fragment_spec = 0;
718 /* determine logarithm (log2) of the fragment size */
719 for (fragment_spec=0; (1 << fragment_spec) < fragment_size;
722 /* use two fragments (play one fragment, prepare the other);
723 one fragment would result in interrupted audio output, more
724 than two fragments would raise audio output latency to much */
725 fragment_spec |= 0x00020000;
727 /* Example for fragment specification:
728 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
729 - (with stereo the effective buffer size will shrink to 256)
730 => fragment_size = 0x00020009 */
732 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
733 Error(ERR_EXIT_SOUND_SERVER,
734 "cannot set fragment size of /dev/dsp -- no sounds");
736 /* try if we can use stereo sound */
737 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
740 static boolean reported = FALSE;
744 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
751 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
752 Error(ERR_EXIT_SOUND_SERVER,
753 "cannot set sample rate of /dev/dsp -- no sounds");
755 /* get the real fragmentation size; this should return 512 */
756 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size) < 0)
757 Error(ERR_EXIT_SOUND_SERVER,
758 "cannot get fragment size of /dev/dsp -- no sounds");
760 return (boolean)stereo;
762 #endif /* AUDIO_LINUX_IOCTL */
764 #if defined(PLATFORM_NETBSD)
765 static boolean InitAudioDevice_NetBSD(long fragment_size, int sample_rate)
768 boolean stereo = TRUE;
770 AUDIO_INITINFO(&a_info);
771 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
772 a_info.play.precision = 8;
773 a_info.play.channels = 2;
774 a_info.play.sample_rate = sample_rate;
775 a_info.blocksize = fragment_size;
777 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
779 /* try to disable stereo */
780 a_info.play.channels = 1;
783 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
784 Error(ERR_EXIT_SOUND_SERVER,
785 "cannot set sample rate of /dev/audio -- no sounds");
790 #endif /* PLATFORM_NETBSD */
792 #if defined(PLATFORM_HPUX)
793 static boolean InitAudioDevice_HPUX()
795 struct audio_describe ainfo;
798 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
800 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
802 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
803 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
805 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
806 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
808 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
809 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
813 return TRUE; /* to provide common interface for InitAudioDevice_...() */
815 #endif /* PLATFORM_HPUX */
817 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
819 /* these two are stolen from "sox"... :) */
822 ** This routine converts from linear to ulaw.
824 ** Craig Reese: IDA/Supercomputing Research Center
825 ** Joe Campbell: Department of Defense
829 ** 1) CCITT Recommendation G.711 (very difficult to follow)
830 ** 2) "A New Digital Technique for Implementation of Any
831 ** Continuous PCM Companding Law," Villeret, Michel,
832 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
833 ** 1973, pg. 11.12-11.17
834 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
835 ** for Analog-to_Digital Conversion Techniques,"
838 ** Input: Signed 16 bit linear sample
839 ** Output: 8 bit ulaw sample
842 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
843 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
846 static unsigned char linear_to_ulaw(int sample)
848 static int exp_lut[256] =
850 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
851 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
852 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
853 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
854 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
855 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
856 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
857 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
858 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
859 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
860 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
861 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
862 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
863 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
864 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
865 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
868 int sign, exponent, mantissa;
869 unsigned char ulawbyte;
871 /* Get the sample into sign-magnitude. */
872 sign = (sample >> 8) & 0x80; /* set aside the sign */
874 sample = -sample; /* get magnitude */
876 sample = CLIP; /* clip the magnitude */
878 /* Convert from 16 bit linear to ulaw. */
879 sample = sample + BIAS;
880 exponent = exp_lut[( sample >> 7 ) & 0xFF];
881 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
882 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
885 ulawbyte = 0x02; /* optional CCITT trap */
892 ** This routine converts from ulaw to 16 bit linear.
894 ** Craig Reese: IDA/Supercomputing Research Center
898 ** 1) CCITT Recommendation G.711 (very difficult to follow)
899 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
900 ** for Analog-to_Digital Conversion Techniques,"
903 ** Input: 8 bit ulaw sample
904 ** Output: signed 16 bit linear sample
907 static int ulaw_to_linear(unsigned char ulawbyte)
909 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
910 int sign, exponent, mantissa, sample;
912 ulawbyte = ~ ulawbyte;
913 sign = ( ulawbyte & 0x80 );
914 exponent = ( ulawbyte >> 4 ) & 0x07;
915 mantissa = ulawbyte & 0x0F;
916 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
922 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
925 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
926 /* ========================================================================= */
927 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
931 printf("reloading sounds ...\n");
936 printf("reloading music ...\n");
939 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
940 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
942 static boolean LoadSoundExt(char *sound_name, boolean is_music)
944 struct SampleInfo *snd_info;
946 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
947 byte sound_header_buffer[WAV_HEADER_SIZE];
948 char chunk[CHUNK_ID_LEN + 1];
949 int chunk_size, dummy;
954 if (!audio.sound_available)
958 Sound = checked_realloc(Sound, num_sounds * sizeof(struct SampleInfo));
960 snd_info = &Sound[num_sounds - 1];
961 snd_info->name = sound_name;
963 filename = getPath2((is_music ? options.music_directory :
964 options.sounds_directory), snd_info->name);
966 #if defined(TARGET_SDL)
968 if ((snd_info->mix_chunk = Mix_LoadWAV(filename)) == NULL)
970 Error(ERR_WARN, "cannot read sound file '%s' -- no sounds", filename);
975 #elif defined(PLATFORM_UNIX)
977 if ((file = fopen(filename, MODE_READ)) == NULL)
979 Error(ERR_WARN, "cannot open sound file '%s' -- no sounds", filename);
984 /* read chunk "RIFF" */
985 getFileChunk(file, chunk, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
986 if (strcmp(chunk, "RIFF") != 0)
988 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
994 /* read chunk "WAVE" */
995 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
996 if (strcmp(chunk, "WAVE") != 0)
998 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
1004 /* read header information */
1005 for (i=0; i<WAV_HEADER_SIZE; i++)
1006 sound_header_buffer[i] = fgetc(file);
1008 /* read chunk "data" */
1009 getFileChunk(file, chunk, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1010 if (strcmp(chunk, "data") != 0)
1012 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1018 snd_info->data_len = chunk_size;
1019 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1021 /* read sound data */
1022 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1025 Error(ERR_WARN, "cannot read sound file '%s' -- no sounds", filename);
1033 for (i=0; i<snd_info->data_len; i++)
1034 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
1036 #else /* PLATFORM_MSDOS */
1038 snd_info->sample_ptr = load_sample(filename);
1039 if (!snd_info->sample_ptr)
1041 Error(ERR_WARN, "cannot read sound file '%s' -- no sounds", filename);
1052 boolean LoadSound(char *sound_name)
1054 return LoadSoundExt(sound_name, FALSE);
1057 boolean LoadMod(char *mod_name)
1059 #if defined(TARGET_SDL)
1060 struct SampleInfo *mod_info;
1064 Mod = checked_realloc(Mod, num_mods * sizeof(struct SampleInfo));
1066 mod_info = &Mod[num_mods - 1];
1067 mod_info->name = mod_name;
1069 filename = getPath2(options.music_directory, mod_info->name);
1071 if ((mod_info->mix_music = Mix_LoadMUS(filename)) == NULL)
1073 Error(ERR_WARN, "cannot read music file '%s' -- no music", filename);
1089 struct dirent *dir_entry;
1090 int num_wav_music = 0;
1091 int num_mod_music = 0;
1093 if (!audio.sound_available)
1096 if ((dir = opendir(options.music_directory)) == NULL)
1098 Error(ERR_WARN, "cannot read music directory '%s'",
1099 options.music_directory);
1100 audio.music_available = FALSE;
1104 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1106 char *filename = dir_entry->d_name;
1108 if (FileIsSound(filename) && LoadSoundExt(filename, TRUE))
1110 else if (FileIsMusic(filename) && LoadMod(filename))
1116 if (num_wav_music == 0 && num_mod_music == 0)
1117 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1118 options.music_directory);
1120 num_music = (num_mod_music > 0 ? num_mod_music : num_wav_music);
1122 audio.mods_available = (num_mod_music > 0);
1123 audio.music_available = (num_music > 0);
1128 void PlayMusic(int nr)
1130 if (!audio.music_available)
1133 if (!audio.mods_available)
1134 nr = num_sounds - num_music + nr;
1136 #if defined(TARGET_SDL)
1137 if (audio.mods_available) /* play MOD music */
1139 Mix_PlayMusic(Mod[nr].mix_music, -1);
1140 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1142 else /* play WAV music loop */
1144 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1145 Mix_PlayChannel(audio.music_channel, Sound[nr].mix_chunk, -1);
1148 audio.music_nr = nr;
1153 void PlaySound(int nr)
1155 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
1158 void PlaySoundStereo(int nr, int stereo)
1160 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
1163 void PlaySoundLoop(int nr)
1165 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
1168 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
1170 struct SoundControl snd_ctrl = emptySoundControl;
1172 if (!audio.sound_available || !audio.sound_enabled)
1175 if (volume<PSND_MIN_VOLUME)
1176 volume = PSND_MIN_VOLUME;
1177 else if (volume>PSND_MAX_VOLUME)
1178 volume = PSND_MAX_VOLUME;
1180 if (stereo<PSND_MAX_LEFT)
1181 stereo = PSND_MAX_LEFT;
1182 else if (stereo>PSND_MAX_RIGHT)
1183 stereo = PSND_MAX_RIGHT;
1186 snd_ctrl.volume = volume;
1187 snd_ctrl.stereo = stereo;
1188 snd_ctrl.loop = loop;
1189 snd_ctrl.active = TRUE;
1190 snd_ctrl.data_ptr = Sound[nr].data_ptr;
1191 snd_ctrl.data_len = Sound[nr].data_len;
1193 #if defined(TARGET_SDL)
1194 Mix_Volume(-1, SOUND_MAX_VOLUME);
1195 Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
1196 #elif defined(PLATFORM_UNIX)
1197 if (audio.soundserver_pid == 0) /* we are child process */
1200 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1202 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1203 audio.sound_available = audio.sound_enabled = FALSE;
1206 #elif defined(PLATFORM_MSDOS)
1207 sound_handler(snd_ctrl);
1211 void FadeMusic(void)
1213 #if defined(TARGET_SDL)
1214 if (!audio.sound_available)
1217 if (audio.mods_available)
1218 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1220 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1222 FadeSound(audio.music_nr);
1226 void FadeSound(int nr)
1228 StopSoundExt(nr, SSND_FADE_SOUND);
1234 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
1237 void StopMusic(void)
1239 #if defined(TARGET_SDL)
1240 if (!audio.sound_available)
1243 if (audio.mods_available)
1246 Mix_HaltChannel(audio.music_channel);
1248 StopSound(audio.music_nr);
1252 void StopSound(int nr)
1254 StopSoundExt(nr, SSND_STOP_SOUND);
1259 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
1262 void StopSoundExt(int nr, int method)
1264 struct SoundControl snd_ctrl = emptySoundControl;
1266 if (!audio.sound_available)
1269 if (SSND_FADING(method))
1270 snd_ctrl.fade_sound = TRUE;
1272 if (SSND_ALL(method))
1273 snd_ctrl.stop_all_sounds = TRUE;
1277 snd_ctrl.stop_sound = TRUE;
1280 #if defined(TARGET_SDL)
1282 if (SSND_FADING(method))
1286 for (i=0; i<audio.channels; i++)
1287 if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
1288 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1289 if (snd_ctrl.stop_all_sounds)
1290 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1296 for (i=0; i<audio.channels; i++)
1297 if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
1299 if (snd_ctrl.stop_all_sounds)
1304 #if !defined(PLATFORM_MSDOS)
1305 if (audio.soundserver_pid == 0) /* we are child process */
1308 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1310 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1311 audio.sound_available = audio.sound_enabled = FALSE;
1315 sound_handler(snd_ctrl);
1320 void InitReloadSounds(char *set_name)
1322 struct SoundControl snd_ctrl = emptySoundControl;
1324 if (!audio.sound_available)
1327 snd_ctrl.reload_sounds = TRUE;
1329 #if defined(TARGET_SDL)
1331 #elif defined(PLATFORM_UNIX)
1332 if (audio.soundserver_pid == 0) /* we are child process */
1335 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1337 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1338 audio.sound_available = audio.sound_enabled = FALSE;
1341 #elif defined(PLATFORM_MSDOS)
1342 sound_handler(snd_ctrl);
1346 void InitReloadMusic(char *set_name)
1348 struct SoundControl snd_ctrl = emptySoundControl;
1350 if (!audio.sound_available)
1353 snd_ctrl.reload_music = TRUE;
1355 #if defined(TARGET_SDL)
1357 #elif defined(PLATFORM_UNIX)
1358 if (audio.soundserver_pid == 0) /* we are child process */
1361 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1363 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1364 audio.sound_available = audio.sound_enabled = FALSE;
1367 #elif defined(PLATFORM_MSDOS)
1368 sound_handler(snd_ctrl);
1372 void FreeSounds(int num_sounds)
1376 if (!audio.sound_available)
1379 for(i=0; i<num_sounds; i++)
1380 #if defined(TARGET_SDL)
1381 free(Sound[i].mix_chunk);
1382 #elif !defined(PLATFORM_MSDOS)
1383 free(Sound[i].data_ptr);
1385 destroy_sample(Sound[i].sample_ptr);
1389 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1390 /* ========================================================================= */