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 ***********************************************************/
31 struct ListNode *next;
33 typedef struct ListNode ListNode;
35 static ListNode *newListNode(void);
36 static void addNodeToList(ListNode **, char *, void *);
37 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
38 static ListNode *getNodeFromKey(ListNode *, char *);
39 static int getNumNodes(ListNode *);
42 static struct SoundEffectInfo *sound_effect;
43 static ListNode *SoundFileList = NULL;
44 static SoundInfo **Sound = NULL;
45 static MusicInfo **Music = NULL;
46 static int num_sounds = 0, num_music = 0;
49 /* ========================================================================= */
50 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
52 static struct AudioFormatInfo afmt =
54 TRUE, 0, DEFAULT_AUDIO_SAMPLE_RATE, DEFAULT_AUDIO_FRAGMENT_SIZE
57 static int playing_sounds = 0;
58 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
59 static struct SoundControl emptySoundControl =
61 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, 0,0, 0,NULL
64 #if defined(PLATFORM_UNIX)
65 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
66 static short premix_first_buffer[SND_BLOCKSIZE];
67 #if defined(AUDIO_STREAMING_DSP)
68 static short premix_left_buffer[SND_BLOCKSIZE];
69 static short premix_right_buffer[SND_BLOCKSIZE];
70 static long premix_last_buffer[SND_BLOCKSIZE];
72 static byte playing_buffer[SND_BLOCKSIZE];
75 /* forward declaration of internal functions */
76 #if defined(AUDIO_STREAMING_DSP)
77 static void SoundServer_InsertNewSound(struct SoundControl);
78 static void InitAudioDevice_DSP(struct AudioFormatInfo *);
79 #elif defined(PLATFORM_HPUX)
80 static void InitAudioDevice_HPUX(struct AudioFormatInfo *);
81 #elif defined(PLATFORM_UNIX)
82 static unsigned char linear_to_ulaw(int);
83 static int ulaw_to_linear(unsigned char);
84 #elif defined(PLATFORM_MSDOS)
85 static void SoundServer_InsertNewSound(struct SoundControl);
86 static void SoundServer_StopSound(struct SoundControl);
87 static void SoundServer_StopAllSounds();
90 static void ReloadCustomSounds();
91 static void ReloadCustomMusic();
92 static void FreeSound(void *);
94 #if defined(PLATFORM_UNIX)
95 static int OpenAudioDevice(char *audio_device_name)
99 /* check if desired audio device is accessible */
100 if (access(audio_device_name, W_OK) != 0)
103 /* try to open audio device in non-blocking mode */
104 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
107 /* re-open audio device in blocking mode */
109 audio_fd = open(audio_device_name, O_WRONLY);
114 static boolean TestAudioDevices(void)
116 static char *audio_device_name[] =
124 /* look for available audio devices, starting with preferred ones */
125 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
126 if ((audio_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
131 Error(ERR_WARN, "cannot open audio device -- no sound");
137 audio.device_name = audio_device_name[i];
142 #if !defined(TARGET_SDL)
143 static boolean ForkAudioProcess(void)
145 if (pipe(audio.soundserver_pipe) < 0)
147 Error(ERR_WARN, "cannot create pipe -- no sounds");
151 if ((audio.soundserver_pid = fork()) < 0)
153 Error(ERR_WARN, "cannot create sound server process -- no sounds");
157 if (audio.soundserver_pid == 0) /* we are child process */
164 else /* we are parent */
165 close(audio.soundserver_pipe[0]); /* no reading from pipe needed */
171 void UnixOpenAudio(void)
173 if (!TestAudioDevices())
176 audio.sound_available = TRUE;
177 audio.sound_enabled = TRUE;
179 #if defined(AUDIO_STREAMING_DSP)
180 audio.music_available = TRUE;
181 audio.loops_available = TRUE;
185 void UnixCloseAudio(void)
188 close(audio.device_fd);
190 if (audio.soundserver_pid > 0) /* we are parent process */
191 kill(audio.soundserver_pid, SIGTERM);
193 #endif /* PLATFORM_UNIX */
195 void InitPlaylist(void)
199 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
200 playlist[i] = emptySoundControl;
204 void StartSoundserver(void)
206 if (!audio.sound_available)
209 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
210 if (!ForkAudioProcess())
211 audio.sound_available = FALSE;
215 #if defined(PLATFORM_UNIX)
216 void SoundServer(void)
220 struct SoundControl snd_ctrl;
223 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
227 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
228 for(i=0; i<PSND_MAX_LEFT2RIGHT; i++)
230 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
232 #if defined(PLATFORM_HPUX)
233 InitAudioDevice_HPUX(&afmt);
236 FD_ZERO(&sound_fdset);
237 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
239 while(1) /* wait for sound playing commands from client */
241 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
242 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
243 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
245 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
247 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
249 if (snd_ctrl.reload_sounds || snd_ctrl.reload_music)
251 char *set_name = checked_malloc(snd_ctrl.data_len);
253 (snd_ctrl.reload_sounds ? &artwork.snd_current : &artwork.mus_current);
254 TreeInfo *ti = *ti_ptr;
255 unsigned long str_size1, str_size2, str_size3;
257 if (leveldir_current == NULL)
258 leveldir_current = checked_calloc(sizeof(TreeInfo));
260 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
261 if (leveldir_current->fullpath != NULL)
262 free(leveldir_current->fullpath);
263 if (ti->basepath != NULL)
265 if (ti->fullpath != NULL)
268 if (read(audio.soundserver_pipe[0], set_name,
269 snd_ctrl.data_len) != snd_ctrl.data_len ||
270 read(audio.soundserver_pipe[0], leveldir_current,
271 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
272 read(audio.soundserver_pipe[0], ti,
273 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
274 read(audio.soundserver_pipe[0], &str_size1,
275 sizeof(unsigned long)) != sizeof(unsigned long) ||
276 read(audio.soundserver_pipe[0], &str_size2,
277 sizeof(unsigned long)) != sizeof(unsigned long) ||
278 read(audio.soundserver_pipe[0], &str_size3,
279 sizeof(unsigned long)) != sizeof(unsigned long))
280 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
282 leveldir_current->fullpath = checked_calloc(str_size1);
283 ti->basepath = checked_calloc(str_size2);
284 ti->fullpath = checked_calloc(str_size3);
286 if (read(audio.soundserver_pipe[0], leveldir_current->fullpath,
287 str_size1) != str_size1 ||
288 read(audio.soundserver_pipe[0], ti->basepath,
289 str_size2) != str_size2 ||
290 read(audio.soundserver_pipe[0], ti->fullpath,
291 str_size3) != str_size3)
292 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
296 close(audio.device_fd);
298 if (snd_ctrl.reload_sounds)
300 artwork.sounds_set_current = set_name;
301 ReloadCustomSounds();
305 artwork.music_set_current = set_name;
314 #if defined(AUDIO_STREAMING_DSP)
316 if (snd_ctrl.fade_sound)
322 playlist[audio.music_channel].fade_sound = TRUE;
324 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
325 if (snd_ctrl.stop_all_sounds ||
326 (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr))
327 playlist[i].fade_sound = TRUE;
329 else if (snd_ctrl.stop_all_sounds)
334 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
335 playlist[i] = emptySoundControl;
338 close(audio.device_fd);
340 else if (snd_ctrl.stop_sound)
347 playlist[audio.music_channel] = emptySoundControl;
351 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
353 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
355 playlist[i] = emptySoundControl;
361 close(audio.device_fd);
364 if (playing_sounds || snd_ctrl.active)
366 if (playing_sounds ||
367 (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
369 struct timeval delay = { 0, 0 };
371 if (!playing_sounds) /* we just opened the audio device */
372 InitAudioDevice_DSP(&afmt);
374 if (snd_ctrl.active) /* new sound has arrived */
375 SoundServer_InsertNewSound(snd_ctrl);
377 while (playing_sounds &&
378 select(audio.soundserver_pipe[0] + 1,
379 &sound_fdset, NULL, NULL, &delay) < 1)
382 int fragment_size = afmt.fragment_size;
383 int sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
384 boolean stereo = afmt.stereo;
386 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
388 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
390 /* first clear the last premixing buffer */
391 memset(premix_last_buffer, 0,
392 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
394 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
402 if (!playlist[i].active)
405 /* pointer, lenght and actual playing position of sound sample */
406 sample_ptr = playlist[i].data_ptr;
407 sample_len = playlist[i].data_len;
408 sample_pos = playlist[i].playingpos;
409 sample_size = MIN(max_sample_size, sample_len - sample_pos);
410 playlist[i].playingpos += sample_size;
412 /* copy original sample to first mixing buffer */
413 if (playlist[i].format == AUDIO_FORMAT_U8)
414 for (j=0; j<sample_size; j++)
415 premix_first_buffer[j] =
416 ((short)(((byte *)sample_ptr)[sample_pos + j] ^ 0x80)) << 8;
417 else /* AUDIO_FORMAT_S16 */
418 for (j=0; j<sample_size; j++)
419 premix_first_buffer[j] =
420 ((short *)sample_ptr)[sample_pos + j];
422 /* are we about to restart a looping sound? */
423 if (playlist[i].loop && sample_size < max_sample_size)
425 while (sample_size < max_sample_size)
427 int restarted_sample_size =
428 MIN(max_sample_size - sample_size, sample_len);
430 if (playlist[i].format == AUDIO_FORMAT_U8)
431 for (j=0; j<restarted_sample_size; j++)
432 premix_first_buffer[sample_size + j] =
433 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
435 for (j=0; j<restarted_sample_size; j++)
436 premix_first_buffer[sample_size + j] =
437 ((short *)sample_ptr)[j];
439 playlist[i].playingpos = restarted_sample_size;
440 sample_size += restarted_sample_size;
444 /* decrease volume if sound is fading out */
445 if (playlist[i].fade_sound &&
446 playlist[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
447 playlist[i].volume -= SOUND_FADING_VOLUME_STEP;
449 /* adjust volume of actual sound sample */
450 if (playlist[i].volume != PSND_MAX_VOLUME)
451 for(j=0; j<sample_size; j++)
452 premix_first_buffer[j] =
453 (playlist[i].volume * (long)premix_first_buffer[j])
454 >> PSND_MAX_VOLUME_BITS;
456 /* fill the last mixing buffer with stereo or mono sound */
459 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
460 int left_volume = stereo_volume[middle_pos + playlist[i].stereo];
461 int right_volume= stereo_volume[middle_pos - playlist[i].stereo];
463 for(j=0; j<sample_size; j++)
465 premix_left_buffer[j] =
466 (left_volume * premix_first_buffer[j])
467 >> PSND_MAX_LEFT2RIGHT_BITS;
468 premix_right_buffer[j] =
469 (right_volume * premix_first_buffer[j])
470 >> PSND_MAX_LEFT2RIGHT_BITS;
472 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
473 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
478 for(j=0; j<sample_size; j++)
479 premix_last_buffer[j] += premix_first_buffer[j];
482 /* delete completed sound entries from the playlist */
483 if (playlist[i].playingpos >= playlist[i].data_len)
485 if (playlist[i].loop)
486 playlist[i].playingpos = 0;
489 playlist[i] = emptySoundControl;
493 else if (playlist[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
495 playlist[i] = emptySoundControl;
500 /* prepare final playing buffer according to system audio format */
501 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
503 /* cut off at 17 bit value */
504 if (premix_last_buffer[i] < -65535)
505 premix_last_buffer[i] = -65535;
506 else if (premix_last_buffer[i] > 65535)
507 premix_last_buffer[i] = 65535;
509 /* shift to 16 bit value */
510 premix_last_buffer[i] >>= 1;
512 if (afmt.format & AUDIO_FORMAT_U8)
514 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
516 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
518 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
519 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
521 else /* big endian */
523 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
524 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
528 /* finally play the sound fragment */
529 write(audio.device_fd, playing_buffer, fragment_size);
532 /* if no sounds playing, free device for other sound programs */
534 close(audio.device_fd);
538 #else /* !AUDIO_STREAMING_DSP */
540 if (snd_ctrl.active && !snd_ctrl.loop)
542 struct timeval delay = { 0, 0 };
544 long sample_size, max_sample_size = SND_BLOCKSIZE;
545 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
546 int wait_percent = 90; /* wait 90% of the real playing time */
549 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
553 while (playing_sounds &&
554 select(audio.soundserver_pipe[0] + 1,
555 &sound_fdset, NULL, NULL, &delay) < 1)
557 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
559 /* get pointer and size of the actual sound sample */
560 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
562 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
563 snd_ctrl.playingpos += sample_size;
565 /* fill the first mixing buffer with original sample */
566 memcpy(premix_first_buffer,sample_ptr,sample_size);
568 /* adjust volume of actual sound sample */
569 if (snd_ctrl.volume != PSND_MAX_VOLUME)
570 for(i=0;i<sample_size;i++)
571 premix_first_buffer[i] =
572 (snd_ctrl.volume * (int)premix_first_buffer[i])
573 >> PSND_MAX_VOLUME_BITS;
575 for(i=0;i<sample_size;i++)
577 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
579 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
582 /* finally play the sound fragment */
583 write(audio.device_fd,playing_buffer,sample_size);
586 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
588 close(audio.device_fd);
591 #endif /* !AUDIO_STREAMING_DSP */
594 #endif /* PLATFORM_UNIX */
596 #if defined(PLATFORM_MSDOS)
597 static void sound_handler(struct SoundControl snd_ctrl)
601 if (snd_ctrl.fade_sound)
606 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
607 if ((snd_ctrl.stop_all_sounds ||
608 (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr) ||
609 (i == audio.music_channel && snd_ctrl.music)) &&
610 !playlist[i].fade_sound)
612 playlist[i].fade_sound = TRUE;
613 if (voice_check(playlist[i].voice))
614 voice_ramp_volume(playlist[i].voice, 1000, 0);
615 playlist[i].loop = PSND_NO_LOOP;
618 else if (snd_ctrl.stop_all_sounds)
622 SoundServer_StopAllSounds();
624 else if (snd_ctrl.stop_sound)
628 SoundServer_StopSound(snd_ctrl);
631 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
633 if (!playlist[i].active || playlist[i].loop)
636 playlist[i].playingpos = voice_get_position(playlist[i].voice);
637 playlist[i].volume = voice_get_volume(playlist[i].voice);
638 if (playlist[i].playingpos == -1 || !playlist[i].volume)
640 deallocate_voice(playlist[i].voice);
641 playlist[i] = emptySoundControl;
647 SoundServer_InsertNewSound(snd_ctrl);
649 #endif /* PLATFORM_MSDOS */
651 #if !defined(PLATFORM_WIN32)
652 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
658 snd_ctrl.nr = snd_ctrl.nr % num_music;
659 else if (snd_ctrl.nr >= num_sounds)
662 snd_info = (snd_ctrl.music ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
663 if (snd_info == NULL)
666 printf("sound/music %d undefined\n", snd_ctrl.nr);
671 /* if playlist is full, remove oldest sound */
672 if (playing_sounds == MAX_SOUNDS_PLAYING)
674 int longest = 0, longest_nr = 0;
676 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
678 #if !defined(PLATFORM_MSDOS)
679 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
681 int actual = playlist[i].playingpos;
684 if (i != audio.music_channel && !playlist[i].loop && actual > longest)
690 #if defined(PLATFORM_MSDOS)
691 voice_set_volume(playlist[longest_nr].voice, 0);
692 deallocate_voice(playlist[longest_nr].voice);
694 playlist[longest_nr] = emptySoundControl;
698 /* check if sound is already being played (and how often) */
699 for (k=0,i=0; i<MAX_SOUNDS_PLAYING; i++)
700 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
703 /* restart loop sounds only if they are just fading out */
704 if (k >= 1 && snd_ctrl.loop)
706 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
708 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr &&
709 playlist[i].fade_sound)
711 playlist[i].fade_sound = FALSE;
712 playlist[i].volume = PSND_MAX_VOLUME;
713 #if defined(PLATFORM_MSDOS)
714 playlist[i].loop = PSND_LOOP;
715 voice_stop_volumeramp(playlist[i].voice);
716 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
724 /* don't play sound more than n times simultaneously (with n == 2 for now) */
727 int longest = 0, longest_nr = 0;
729 /* look for oldest equal sound */
730 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
734 if (!playlist[i].active ||
735 i == audio.music_channel ||
736 playlist[i].nr != snd_ctrl.nr)
739 #if !defined(PLATFORM_MSDOS)
740 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
742 actual = playlist[i].playingpos;
744 if (actual >= longest)
751 #if defined(PLATFORM_MSDOS)
752 voice_set_volume(playlist[longest_nr].voice, 0);
753 deallocate_voice(playlist[longest_nr].voice);
755 playlist[longest_nr] = emptySoundControl;
759 /* add new sound to playlist */
760 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
762 if (!playlist[i].active ||
763 (snd_ctrl.music && i == audio.music_channel))
765 snd_ctrl.data_ptr = snd_info->data_ptr;
766 snd_ctrl.data_len = snd_info->data_len;
767 snd_ctrl.format = snd_info->format;
769 playlist[i] = snd_ctrl;
772 #if defined(PLATFORM_MSDOS)
773 playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
776 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
778 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
779 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
780 voice_start(playlist[i].voice);
786 #endif /* !PLATFORM_WIN32 */
789 void SoundServer_FadeSound(int nr)
796 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
797 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
798 playlist[i].fade_sound = TRUE;
802 #if !defined(PLATFORM_WIN32)
803 #if defined(PLATFORM_MSDOS)
804 static void SoundServer_StopSound(struct SoundControl snd_ctrl)
806 int nr = snd_ctrl.nr;
812 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
814 if ((i == audio.music_channel && snd_ctrl.music) ||
815 (i != audio.music_channel && playlist[i].nr == nr))
817 #if defined(PLATFORM_MSDOS)
818 voice_set_volume(playlist[i].voice, 0);
819 deallocate_voice(playlist[i].voice);
821 playlist[i] = emptySoundControl;
826 #if !defined(PLATFORM_MSDOS)
828 close(audio.device_fd);
832 static void SoundServer_StopAllSounds()
836 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
838 #if defined(PLATFORM_MSDOS)
839 voice_set_volume(playlist[i].voice, 0);
840 deallocate_voice(playlist[i].voice);
842 playlist[i]=emptySoundControl;
846 #if !defined(PLATFORM_MSDOS)
847 close(audio.device_fd);
850 #endif /* PLATFORM_MSDOS */
851 #endif /* !PLATFORM_WIN32 */
854 /* ------------------------------------------------------------------------- */
855 /* platform dependant audio initialization code */
856 /* ------------------------------------------------------------------------- */
858 #if defined(AUDIO_LINUX_IOCTL)
859 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
861 /* "ioctl()" expects pointer to 'int' value for stereo flag
862 (boolean is defined as 'char', which will not work here) */
863 unsigned int fragment_spec = 0;
864 int fragment_size_query;
873 /* supported audio format in preferred order */
874 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
875 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
876 { AFMT_U8, AUDIO_FORMAT_U8 },
881 /* determine logarithm (log2) of the fragment size */
882 while ((1 << fragment_spec) < afmt->fragment_size)
885 /* use two fragments (play one fragment, prepare the other);
886 one fragment would result in interrupted audio output, more
887 than two fragments would raise audio output latency to much */
888 fragment_spec |= 0x00020000;
890 /* Example for fragment specification:
891 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
892 - (with stereo the effective buffer size will shrink to 256)
893 => fragment_size = 0x00020009 */
895 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
896 Error(ERR_EXIT_SOUND_SERVER,
897 "cannot set fragment size of /dev/dsp -- no sounds");
901 while (formats[i].format_result != -1)
903 unsigned int audio_format = formats[i].format_ioctl;
904 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
906 afmt->format = formats[i].format_result;
911 if (afmt->format == 0) /* no supported audio format found */
912 Error(ERR_EXIT_SOUND_SERVER,
913 "cannot set audio format of /dev/dsp -- no sounds");
915 /* try if we can use stereo sound */
917 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
918 afmt->stereo = FALSE;
920 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
921 Error(ERR_EXIT_SOUND_SERVER,
922 "cannot set sample rate of /dev/dsp -- no sounds");
924 /* get the real fragmentation size; this should return 512 */
925 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
926 Error(ERR_EXIT_SOUND_SERVER,
927 "cannot get fragment size of /dev/dsp -- no sounds");
928 if (fragment_size_query != afmt->fragment_size)
929 Error(ERR_EXIT_SOUND_SERVER,
930 "cannot set fragment size of /dev/dsp -- no sounds");
932 #endif /* AUDIO_LINUX_IOCTL */
934 #if defined(PLATFORM_NETBSD)
935 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
938 boolean stereo = TRUE;
940 AUDIO_INITINFO(&a_info);
941 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
942 a_info.play.precision = 8;
943 a_info.play.channels = 2;
944 a_info.play.sample_rate = sample_rate;
945 a_info.blocksize = fragment_size;
947 afmt->format = AUDIO_FORMAT_U8;
950 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
952 /* try to disable stereo */
953 a_info.play.channels = 1;
955 afmt->stereo = FALSE;
957 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
958 Error(ERR_EXIT_SOUND_SERVER,
959 "cannot set sample rate of /dev/audio -- no sounds");
962 #endif /* PLATFORM_NETBSD */
964 #if defined(PLATFORM_HPUX)
965 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
967 struct audio_describe ainfo;
970 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
972 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
974 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
975 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
977 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
978 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
980 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
981 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
983 afmt->format = AUDIO_FORMAT_U8;
984 afmt->stereo = FALSE;
985 afmt->sample_rate = 8000;
989 #endif /* PLATFORM_HPUX */
991 #if defined(PLATFORM_UNIX)
992 static void InitAudioDevice_DSP(struct AudioFormatInfo *afmt)
994 #if defined(AUDIO_LINUX_IOCTL)
995 InitAudioDevice_Linux(afmt);
996 #elif defined(PLATFORM_NETBSD)
997 InitAudioDevice_NetBSD(afmt);
998 #elif defined(PLATFORM_HPUX)
999 InitAudioDevice_HPUX(afmt);
1002 #endif /* PLATFORM_UNIX */
1004 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
1006 /* these two are stolen from "sox"... :) */
1009 ** This routine converts from linear to ulaw.
1011 ** Craig Reese: IDA/Supercomputing Research Center
1012 ** Joe Campbell: Department of Defense
1013 ** 29 September 1989
1016 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1017 ** 2) "A New Digital Technique for Implementation of Any
1018 ** Continuous PCM Companding Law," Villeret, Michel,
1019 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1020 ** 1973, pg. 11.12-11.17
1021 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1022 ** for Analog-to_Digital Conversion Techniques,"
1025 ** Input: Signed 16 bit linear sample
1026 ** Output: 8 bit ulaw sample
1029 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1030 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1033 static unsigned char linear_to_ulaw(int sample)
1035 static int exp_lut[256] =
1037 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1038 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1039 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1040 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1041 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1042 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1043 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1044 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1045 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1046 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1047 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1048 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1049 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1050 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1051 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1052 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1055 int sign, exponent, mantissa;
1056 unsigned char ulawbyte;
1058 /* Get the sample into sign-magnitude. */
1059 sign = (sample >> 8) & 0x80; /* set aside the sign */
1061 sample = -sample; /* get magnitude */
1063 sample = CLIP; /* clip the magnitude */
1065 /* Convert from 16 bit linear to ulaw. */
1066 sample = sample + BIAS;
1067 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1068 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1069 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1072 ulawbyte = 0x02; /* optional CCITT trap */
1079 ** This routine converts from ulaw to 16 bit linear.
1081 ** Craig Reese: IDA/Supercomputing Research Center
1082 ** 29 September 1989
1085 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1086 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1087 ** for Analog-to_Digital Conversion Techniques,"
1090 ** Input: 8 bit ulaw sample
1091 ** Output: signed 16 bit linear sample
1094 static int ulaw_to_linear(unsigned char ulawbyte)
1096 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1097 int sign, exponent, mantissa, sample;
1099 ulawbyte = ~ ulawbyte;
1100 sign = ( ulawbyte & 0x80 );
1101 exponent = ( ulawbyte >> 4 ) & 0x07;
1102 mantissa = ulawbyte & 0x0F;
1103 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1109 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
1112 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1113 /* ========================================================================= */
1114 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1116 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1117 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1119 static SoundInfo *Load_WAV(char *filename)
1121 SoundInfo *snd_info;
1122 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1123 byte sound_header_buffer[WAV_HEADER_SIZE];
1124 char chunk_name[CHUNK_ID_LEN + 1];
1130 if (!audio.sound_available)
1134 printf("loading WAV file '%s'\n", filename);
1137 snd_info = checked_calloc(sizeof(SoundInfo));
1139 #if defined(TARGET_SDL)
1141 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1143 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1148 #elif defined(TARGET_ALLEGRO)
1150 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1152 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1157 #else /* PLATFORM_UNIX */
1159 if ((file = fopen(filename, MODE_READ)) == NULL)
1161 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1166 /* read chunk id "RIFF" */
1167 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1168 if (strcmp(chunk_name, "RIFF") != 0)
1170 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1176 /* read "RIFF" type id "WAVE" */
1177 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1178 if (strcmp(chunk_name, "WAVE") != 0)
1180 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1186 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1188 if (strcmp(chunk_name, "fmt ") == 0)
1190 /* read header information */
1191 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1192 sound_header_buffer[i] = fgetc(file);
1194 if (chunk_size > WAV_HEADER_SIZE)
1195 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1197 else if (strcmp(chunk_name, "data") == 0)
1199 snd_info->data_len = chunk_size;
1200 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1202 /* read sound data */
1203 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1206 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1208 free(snd_info->data_ptr);
1213 /* check for odd number of sample bytes (data chunk is word aligned) */
1214 if ((chunk_size % 2) == 1)
1215 ReadUnusedBytesFromFile(file, 1);
1217 else /* unknown chunk -- ignore */
1218 ReadUnusedBytesFromFile(file, chunk_size);
1223 if (snd_info->data_ptr == NULL)
1225 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1230 snd_info->format = AUDIO_FORMAT_U8;
1232 #endif /* PLATFORM_UNIX */
1234 snd_info->type = SND_TYPE_WAV;
1235 snd_info->source_filename = getStringCopy(filename);
1240 static void deleteSoundEntry(SoundInfo **snd_info)
1244 char *filename = (*snd_info)->source_filename;
1247 printf("[decrementing reference counter of sound '%s']\n", filename);
1250 if (--(*snd_info)->num_references <= 0)
1253 printf("[deleting sound '%s']\n", filename);
1257 FreeSound(*snd_info);
1259 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1266 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1270 /* check if the old and the new sound file are the same */
1271 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1273 /* The old and new sound are the same (have the same filename and path).
1274 This usually means that this sound does not exist in this sound set
1275 and a fallback to the existing sound is done. */
1278 printf("[sound '%s' already exists (same list entry)]\n", filename);
1284 /* delete existing sound file entry */
1285 deleteSoundEntry(snd_info);
1287 /* check if the new sound file already exists in the list of sounds */
1288 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1291 printf("[sound '%s' already exists (other list entry)]\n", filename);
1294 *snd_info = (SoundInfo *)node->content;
1295 (*snd_info)->num_references++;
1297 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1299 (*snd_info)->num_references = 1;
1300 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1304 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1306 char *filename = getCustomSoundFilename(basename);
1308 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1310 deleteSoundEntry(snd_info);
1314 if (filename == NULL)
1316 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1320 replaceSoundEntry(snd_info, filename);
1323 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1326 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1328 sound_effect = sounds_list;
1329 num_sounds = num_list_entries;
1332 void LoadSoundToList(char *basename, int list_pos)
1334 if (Sound == NULL || list_pos >= num_sounds)
1338 printf("loading sound '%s' ... [%d]\n",
1339 basename, getNumNodes(SoundFileList));
1342 LoadCustomSound(&Sound[list_pos], basename);
1345 printf("loading sound '%s' done [%d]\n",
1346 basename, getNumNodes(SoundFileList));
1350 static MusicInfo *Load_MOD(char *filename)
1352 #if defined(TARGET_SDL)
1353 MusicInfo *mod_info;
1355 if (!audio.sound_available)
1358 mod_info = checked_calloc(sizeof(MusicInfo));
1360 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1362 Error(ERR_WARN, "cannot read music file '%s'", filename);
1367 mod_info->type = MUS_TYPE_MOD;
1368 mod_info->source_filename = getStringCopy(filename);
1376 void LoadCustomMusic(void)
1378 char *music_directory = getCustomMusicDirectory();
1380 struct dirent *dir_entry;
1382 if (!audio.sound_available)
1385 if ((dir = opendir(music_directory)) == NULL)
1387 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1388 audio.music_available = FALSE;
1392 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1394 char *basename = dir_entry->d_name;
1395 char *filename = getPath2(music_directory, basename);
1396 MusicInfo *mus_info = NULL;
1398 if (FileIsSound(basename))
1399 mus_info = Load_WAV(filename);
1400 else if (FileIsMusic(basename))
1401 mus_info = Load_MOD(filename);
1408 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1409 Music[num_music -1] = mus_info;
1416 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1420 void PlayMusic(int nr)
1422 if (!audio.music_available)
1425 #if defined(TARGET_SDL)
1427 nr = nr % num_music;
1429 if (Music[nr]->type == MUS_TYPE_MOD)
1431 Mix_PlayMusic(Music[nr]->data_ptr, -1);
1432 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1434 else /* play WAV music loop */
1436 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1437 Mix_PlayChannel(audio.music_channel, Music[nr]->data_ptr, -1);
1447 void PlaySound(int nr)
1449 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
1452 void PlaySoundStereo(int nr, int stereo)
1454 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
1457 void PlaySoundLoop(int nr)
1459 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
1462 void PlaySoundMusic(int nr)
1464 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_MUSIC);
1467 void PlaySoundExt(int nr, int volume, int stereo, boolean loop_type)
1469 struct SoundControl snd_ctrl = emptySoundControl;
1471 if (!audio.sound_available ||
1472 !audio.sound_enabled ||
1473 audio.sound_deactivated)
1476 if (volume < PSND_MIN_VOLUME)
1477 volume = PSND_MIN_VOLUME;
1478 else if (volume > PSND_MAX_VOLUME)
1479 volume = PSND_MAX_VOLUME;
1481 if (stereo < PSND_MAX_LEFT)
1482 stereo = PSND_MAX_LEFT;
1483 else if (stereo > PSND_MAX_RIGHT)
1484 stereo = PSND_MAX_RIGHT;
1487 snd_ctrl.volume = volume;
1488 snd_ctrl.stereo = stereo;
1489 snd_ctrl.loop = (loop_type != PSND_NO_LOOP);
1490 snd_ctrl.music = (loop_type == PSND_MUSIC);
1491 snd_ctrl.active = TRUE;
1494 /* now only used internally in sound server child process */
1495 snd_ctrl.data_ptr = Sound[nr].data_ptr;
1496 snd_ctrl.data_len = Sound[nr].data_len;
1499 #if defined(TARGET_SDL)
1500 Mix_Volume(-1, SOUND_MAX_VOLUME);
1501 Mix_PlayChannel(-1, Sound[nr]->data_ptr, (loop_type ? -1 : 0));
1502 #elif defined(PLATFORM_UNIX)
1503 if (audio.soundserver_pid == 0) /* we are child process */
1506 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1508 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1509 audio.sound_available = audio.sound_enabled = FALSE;
1512 #elif defined(PLATFORM_MSDOS)
1513 sound_handler(snd_ctrl);
1517 void FadeMusic(void)
1519 if (!audio.sound_available)
1522 #if defined(TARGET_SDL)
1523 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1524 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1526 StopSoundExt(-1, SSND_FADE_MUSIC);
1530 void FadeSound(int nr)
1532 StopSoundExt(nr, SSND_FADE_SOUND);
1538 StopSoundExt(-1, SSND_FADE_ALL);
1541 void StopMusic(void)
1543 #if defined(TARGET_SDL)
1544 if (!audio.sound_available)
1548 Mix_HaltChannel(audio.music_channel);
1550 StopSoundExt(-1, SSND_STOP_MUSIC);
1554 void StopSound(int nr)
1556 StopSoundExt(nr, SSND_STOP_SOUND);
1561 StopSoundExt(-1, SSND_STOP_ALL);
1564 void StopSoundExt(int nr, int method)
1566 struct SoundControl snd_ctrl = emptySoundControl;
1568 if (!audio.sound_available)
1571 if (method & SSND_FADING)
1572 snd_ctrl.fade_sound = TRUE;
1574 if (method & SSND_ALL)
1575 snd_ctrl.stop_all_sounds = TRUE;
1578 snd_ctrl.stop_sound = TRUE;
1582 if (method & SSND_MUSIC)
1583 snd_ctrl.music = TRUE;
1585 #if defined(TARGET_SDL)
1587 if (method & SSND_FADING)
1591 for (i=0; i<audio.channels; i++)
1592 if (i != audio.music_channel || snd_ctrl.music)
1593 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1595 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1601 for (i=0; i<audio.channels; i++)
1602 if (i != audio.music_channel || snd_ctrl.music)
1608 #elif !defined(PLATFORM_MSDOS)
1610 if (audio.soundserver_pid == 0) /* we are child process */
1613 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1615 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1616 audio.sound_available = audio.sound_enabled = FALSE;
1620 sound_handler(snd_ctrl);
1624 ListNode *newListNode()
1626 return checked_calloc(sizeof(ListNode));
1629 void addNodeToList(ListNode **node_first, char *key, void *content)
1631 ListNode *node_new = newListNode();
1634 printf("LIST: adding node with key '%s'\n", key);
1637 node_new->key = getStringCopy(key);
1638 node_new->content = content;
1639 node_new->next = *node_first;
1640 *node_first = node_new;
1643 void deleteNodeFromList(ListNode **node_first, char *key,
1644 void (*destructor_function)(void *))
1646 if (node_first == NULL || *node_first == NULL)
1649 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1650 (*node_first)->key, key);
1652 if (strcmp((*node_first)->key, key) == 0)
1654 printf("[DELETING LIST ENTRY]\n");
1656 free((*node_first)->key);
1657 if (destructor_function)
1658 destructor_function((*node_first)->content);
1659 *node_first = (*node_first)->next;
1662 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1665 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1667 if (node_first == NULL)
1670 if (strcmp(node_first->key, key) == 0)
1673 return getNodeFromKey(node_first->next, key);
1676 int getNumNodes(ListNode *node_first)
1678 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1681 void dumpList(ListNode *node_first)
1683 ListNode *node = node_first;
1687 printf("['%s' (%d)]\n", node->key,
1688 ((SoundInfo *)node->content)->num_references);
1692 printf("[%d nodes]\n", getNumNodes(node_first));
1695 static void LoadSoundsInfo()
1697 char *filename = getCustomSoundConfigFilename();
1698 struct SetupFileList *setup_file_list;
1701 /* always start with reliable default values */
1702 for (i=0; i<num_sounds; i++)
1703 sound_effect[i].filename = NULL;
1705 if (filename == NULL)
1708 if ((setup_file_list = loadSetupFileList(filename)))
1710 for (i=0; i<num_sounds; i++)
1711 sound_effect[i].filename =
1712 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1714 freeSetupFileList(setup_file_list);
1717 for (i=0; i<num_sounds; i++)
1719 printf("'%s' ", sound_effect[i].text);
1720 if (sound_effect[i].filename)
1721 printf("-> '%s'\n", sound_effect[i].filename);
1723 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1729 static void ReloadCustomSounds()
1734 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1739 for(i=0; i<num_sounds; i++)
1741 if (sound_effect[i].filename)
1742 LoadSoundToList(sound_effect[i].filename, i);
1744 LoadSoundToList(sound_effect[i].default_filename, i);
1748 printf("list size == %d\n", getNumNodes(SoundFileList));
1752 dumpList(SoundFileList);
1756 static void ReloadCustomMusic()
1759 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1767 static void InitReloadSoundsOrMusic(char *set_name, int type)
1769 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
1770 struct SoundControl snd_ctrl = emptySoundControl;
1772 (type == SND_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current);
1773 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
1774 unsigned long str_size2 = strlen(ti->basepath) + 1;
1775 unsigned long str_size3 = strlen(ti->fullpath) + 1;
1778 if (!audio.sound_available)
1781 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1782 if (type == SND_RELOAD_SOUNDS)
1783 audio.func_reload_sounds();
1785 audio.func_reload_music();
1786 #elif defined(PLATFORM_UNIX)
1787 if (audio.soundserver_pid == 0) /* we are child process */
1790 if (leveldir_current == NULL) /* should never happen */
1791 Error(ERR_EXIT, "leveldir_current == NULL");
1793 snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
1794 snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
1795 snd_ctrl.data_len = strlen(set_name) + 1;
1797 if (write(audio.soundserver_pipe[1], &snd_ctrl,
1798 sizeof(snd_ctrl)) < 0 ||
1799 write(audio.soundserver_pipe[1], set_name,
1800 snd_ctrl.data_len) < 0 ||
1801 write(audio.soundserver_pipe[1], leveldir_current,
1802 sizeof(TreeInfo)) < 0 ||
1803 write(audio.soundserver_pipe[1], ti,
1804 sizeof(TreeInfo)) < 0 ||
1805 write(audio.soundserver_pipe[1], &str_size1,
1806 sizeof(unsigned long)) < 0 ||
1807 write(audio.soundserver_pipe[1], &str_size2,
1808 sizeof(unsigned long)) < 0 ||
1809 write(audio.soundserver_pipe[1], &str_size3,
1810 sizeof(unsigned long)) < 0 ||
1811 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
1813 write(audio.soundserver_pipe[1], ti->basepath,
1815 write(audio.soundserver_pipe[1], ti->fullpath,
1818 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1819 audio.sound_available = audio.sound_enabled = FALSE;
1825 void InitReloadSounds(char *set_name)
1827 InitReloadSoundsOrMusic(set_name, SND_RELOAD_SOUNDS);
1830 void InitReloadMusic(char *set_name)
1832 InitReloadSoundsOrMusic(set_name, SND_RELOAD_MUSIC);
1835 void FreeSound(void *ptr)
1837 SoundInfo *sound = (SoundInfo *)ptr;
1842 if (sound->data_ptr)
1844 #if defined(TARGET_SDL)
1845 Mix_FreeChunk(sound->data_ptr);
1846 #elif defined(TARGET_ALLEGRO)
1847 destroy_sample(sound->data_ptr);
1848 #else /* PLATFORM_UNIX */
1849 free(sound->data_ptr);
1853 if (sound->source_filename)
1854 free(sound->source_filename);
1859 void FreeMusic(MusicInfo *music)
1864 if (music->data_ptr)
1866 #if defined(TARGET_SDL)
1867 if (music->type == MUS_TYPE_MOD)
1868 Mix_FreeMusic(music->data_ptr);
1870 Mix_FreeChunk(music->data_ptr);
1871 #elif defined(TARGET_ALLEGRO)
1872 destroy_sample(music->data_ptr);
1873 #else /* PLATFORM_UNIX */
1874 free(music->data_ptr);
1881 void FreeAllSounds()
1888 for(i=0; i<num_sounds; i++)
1889 FreeSound(Sound[i]);
1904 for(i=0; i<num_music; i++)
1905 FreeMusic(Music[i]);
1913 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1914 /* ========================================================================= */