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)
657 snd_ctrl.nr = snd_ctrl.nr % num_music;
658 else if (snd_ctrl.nr >= num_sounds)
661 /* if playlist is full, remove oldest sound */
662 if (playing_sounds == MAX_SOUNDS_PLAYING)
664 int longest = 0, longest_nr = 0;
666 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
668 #if !defined(PLATFORM_MSDOS)
669 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
671 int actual = playlist[i].playingpos;
674 if (i != audio.music_channel && !playlist[i].loop && actual > longest)
680 #if defined(PLATFORM_MSDOS)
681 voice_set_volume(playlist[longest_nr].voice, 0);
682 deallocate_voice(playlist[longest_nr].voice);
684 playlist[longest_nr] = emptySoundControl;
688 /* check if sound is already being played (and how often) */
689 for (k=0,i=0; i<MAX_SOUNDS_PLAYING; i++)
690 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
693 /* restart loop sounds only if they are just fading out */
694 if (k >= 1 && snd_ctrl.loop)
696 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
698 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr &&
699 playlist[i].fade_sound)
701 playlist[i].fade_sound = FALSE;
702 playlist[i].volume = PSND_MAX_VOLUME;
703 #if defined(PLATFORM_MSDOS)
704 playlist[i].loop = PSND_LOOP;
705 voice_stop_volumeramp(playlist[i].voice);
706 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
714 /* don't play sound more than n times simultaneously (with n == 2 for now) */
717 int longest = 0, longest_nr = 0;
719 /* look for oldest equal sound */
720 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
724 if (!playlist[i].active ||
725 i == audio.music_channel ||
726 playlist[i].nr != snd_ctrl.nr)
729 #if !defined(PLATFORM_MSDOS)
730 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
732 actual = playlist[i].playingpos;
734 if (actual >= longest)
741 #if defined(PLATFORM_MSDOS)
742 voice_set_volume(playlist[longest_nr].voice, 0);
743 deallocate_voice(playlist[longest_nr].voice);
745 playlist[longest_nr] = emptySoundControl;
749 /* add new sound to playlist */
750 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
752 if (!playlist[i].active ||
753 (snd_ctrl.music && i == audio.music_channel))
755 SoundInfo *snd_info =
756 (snd_ctrl.music ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
758 snd_ctrl.data_ptr = snd_info->data_ptr;
759 snd_ctrl.data_len = snd_info->data_len;
760 snd_ctrl.format = snd_info->format;
762 playlist[i] = snd_ctrl;
765 #if defined(PLATFORM_MSDOS)
766 playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
769 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
771 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
772 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
773 voice_start(playlist[i].voice);
779 #endif /* !PLATFORM_WIN32 */
782 void SoundServer_FadeSound(int nr)
789 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
790 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
791 playlist[i].fade_sound = TRUE;
795 #if !defined(PLATFORM_WIN32)
796 #if defined(PLATFORM_MSDOS)
797 static void SoundServer_StopSound(struct SoundControl snd_ctrl)
799 int nr = snd_ctrl.nr;
805 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
807 if ((i == audio.music_channel && snd_ctrl.music) ||
808 (i != audio.music_channel && playlist[i].nr == nr))
810 #if defined(PLATFORM_MSDOS)
811 voice_set_volume(playlist[i].voice, 0);
812 deallocate_voice(playlist[i].voice);
814 playlist[i] = emptySoundControl;
819 #if !defined(PLATFORM_MSDOS)
821 close(audio.device_fd);
825 static void SoundServer_StopAllSounds()
829 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
831 #if defined(PLATFORM_MSDOS)
832 voice_set_volume(playlist[i].voice, 0);
833 deallocate_voice(playlist[i].voice);
835 playlist[i]=emptySoundControl;
839 #if !defined(PLATFORM_MSDOS)
840 close(audio.device_fd);
843 #endif /* PLATFORM_MSDOS */
844 #endif /* !PLATFORM_WIN32 */
847 /* ------------------------------------------------------------------------- */
848 /* platform dependant audio initialization code */
849 /* ------------------------------------------------------------------------- */
851 #if defined(AUDIO_LINUX_IOCTL)
852 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
854 /* "ioctl()" expects pointer to 'int' value for stereo flag
855 (boolean is defined as 'char', which will not work here) */
856 unsigned int fragment_spec = 0;
857 int fragment_size_query;
866 /* supported audio format in preferred order */
867 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
868 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
869 { AFMT_U8, AUDIO_FORMAT_U8 },
874 /* determine logarithm (log2) of the fragment size */
875 while ((1 << fragment_spec) < afmt->fragment_size)
878 /* use two fragments (play one fragment, prepare the other);
879 one fragment would result in interrupted audio output, more
880 than two fragments would raise audio output latency to much */
881 fragment_spec |= 0x00020000;
883 /* Example for fragment specification:
884 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
885 - (with stereo the effective buffer size will shrink to 256)
886 => fragment_size = 0x00020009 */
888 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
889 Error(ERR_EXIT_SOUND_SERVER,
890 "cannot set fragment size of /dev/dsp -- no sounds");
894 while (formats[i].format_result != -1)
896 unsigned int audio_format = formats[i].format_ioctl;
897 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
899 afmt->format = formats[i].format_result;
904 if (afmt->format == 0) /* no supported audio format found */
905 Error(ERR_EXIT_SOUND_SERVER,
906 "cannot set audio format of /dev/dsp -- no sounds");
908 /* try if we can use stereo sound */
910 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
911 afmt->stereo = FALSE;
913 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
914 Error(ERR_EXIT_SOUND_SERVER,
915 "cannot set sample rate of /dev/dsp -- no sounds");
917 /* get the real fragmentation size; this should return 512 */
918 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
919 Error(ERR_EXIT_SOUND_SERVER,
920 "cannot get fragment size of /dev/dsp -- no sounds");
921 if (fragment_size_query != afmt->fragment_size)
922 Error(ERR_EXIT_SOUND_SERVER,
923 "cannot set fragment size of /dev/dsp -- no sounds");
925 #endif /* AUDIO_LINUX_IOCTL */
927 #if defined(PLATFORM_NETBSD)
928 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
931 boolean stereo = TRUE;
933 AUDIO_INITINFO(&a_info);
934 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
935 a_info.play.precision = 8;
936 a_info.play.channels = 2;
937 a_info.play.sample_rate = sample_rate;
938 a_info.blocksize = fragment_size;
940 afmt->format = AUDIO_FORMAT_U8;
943 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
945 /* try to disable stereo */
946 a_info.play.channels = 1;
948 afmt->stereo = FALSE;
950 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
951 Error(ERR_EXIT_SOUND_SERVER,
952 "cannot set sample rate of /dev/audio -- no sounds");
955 #endif /* PLATFORM_NETBSD */
957 #if defined(PLATFORM_HPUX)
958 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
960 struct audio_describe ainfo;
963 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
965 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
967 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
968 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
970 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
971 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
973 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
974 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
976 afmt->format = AUDIO_FORMAT_U8;
977 afmt->stereo = FALSE;
978 afmt->sample_rate = 8000;
982 #endif /* PLATFORM_HPUX */
984 #if defined(PLATFORM_UNIX)
985 static void InitAudioDevice_DSP(struct AudioFormatInfo *afmt)
987 #if defined(AUDIO_LINUX_IOCTL)
988 InitAudioDevice_Linux(afmt);
989 #elif defined(PLATFORM_NETBSD)
990 InitAudioDevice_NetBSD(afmt);
991 #elif defined(PLATFORM_HPUX)
992 InitAudioDevice_HPUX(afmt);
995 #endif /* PLATFORM_UNIX */
997 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
999 /* these two are stolen from "sox"... :) */
1002 ** This routine converts from linear to ulaw.
1004 ** Craig Reese: IDA/Supercomputing Research Center
1005 ** Joe Campbell: Department of Defense
1006 ** 29 September 1989
1009 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1010 ** 2) "A New Digital Technique for Implementation of Any
1011 ** Continuous PCM Companding Law," Villeret, Michel,
1012 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1013 ** 1973, pg. 11.12-11.17
1014 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1015 ** for Analog-to_Digital Conversion Techniques,"
1018 ** Input: Signed 16 bit linear sample
1019 ** Output: 8 bit ulaw sample
1022 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1023 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1026 static unsigned char linear_to_ulaw(int sample)
1028 static int exp_lut[256] =
1030 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1031 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1032 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1033 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1034 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1035 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1036 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1037 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1038 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1039 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1040 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1041 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1042 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1043 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1044 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1045 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1048 int sign, exponent, mantissa;
1049 unsigned char ulawbyte;
1051 /* Get the sample into sign-magnitude. */
1052 sign = (sample >> 8) & 0x80; /* set aside the sign */
1054 sample = -sample; /* get magnitude */
1056 sample = CLIP; /* clip the magnitude */
1058 /* Convert from 16 bit linear to ulaw. */
1059 sample = sample + BIAS;
1060 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1061 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1062 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1065 ulawbyte = 0x02; /* optional CCITT trap */
1072 ** This routine converts from ulaw to 16 bit linear.
1074 ** Craig Reese: IDA/Supercomputing Research Center
1075 ** 29 September 1989
1078 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1079 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1080 ** for Analog-to_Digital Conversion Techniques,"
1083 ** Input: 8 bit ulaw sample
1084 ** Output: signed 16 bit linear sample
1087 static int ulaw_to_linear(unsigned char ulawbyte)
1089 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1090 int sign, exponent, mantissa, sample;
1092 ulawbyte = ~ ulawbyte;
1093 sign = ( ulawbyte & 0x80 );
1094 exponent = ( ulawbyte >> 4 ) & 0x07;
1095 mantissa = ulawbyte & 0x0F;
1096 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1102 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
1105 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1106 /* ========================================================================= */
1107 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1109 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1110 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1112 static SoundInfo *Load_WAV(char *filename)
1114 SoundInfo *snd_info;
1115 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1116 byte sound_header_buffer[WAV_HEADER_SIZE];
1117 char chunk_name[CHUNK_ID_LEN + 1];
1123 if (!audio.sound_available)
1127 printf("loading WAV file '%s'\n", filename);
1130 snd_info = checked_calloc(sizeof(SoundInfo));
1132 #if defined(TARGET_SDL)
1134 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1136 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1141 #elif defined(TARGET_ALLEGRO)
1143 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1145 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1150 #else /* PLATFORM_UNIX */
1152 if ((file = fopen(filename, MODE_READ)) == NULL)
1154 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1159 /* read chunk id "RIFF" */
1160 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1161 if (strcmp(chunk_name, "RIFF") != 0)
1163 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1169 /* read "RIFF" type id "WAVE" */
1170 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1171 if (strcmp(chunk_name, "WAVE") != 0)
1173 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1179 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1181 if (strcmp(chunk_name, "fmt ") == 0)
1183 /* read header information */
1184 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1185 sound_header_buffer[i] = fgetc(file);
1187 if (chunk_size > WAV_HEADER_SIZE)
1188 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1190 else if (strcmp(chunk_name, "data") == 0)
1192 snd_info->data_len = chunk_size;
1193 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1195 /* read sound data */
1196 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1199 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1201 free(snd_info->data_ptr);
1206 /* check for odd number of sample bytes (data chunk is word aligned) */
1207 if ((chunk_size % 2) == 1)
1208 ReadUnusedBytesFromFile(file, 1);
1210 else /* unknown chunk -- ignore */
1211 ReadUnusedBytesFromFile(file, chunk_size);
1216 if (snd_info->data_ptr == NULL)
1218 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1223 snd_info->format = AUDIO_FORMAT_U8;
1225 #endif /* PLATFORM_UNIX */
1227 snd_info->type = SND_TYPE_WAV;
1228 snd_info->source_filename = getStringCopy(filename);
1233 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1235 char *filename = getCustomSoundFilename(basename);
1238 if (filename == NULL) /* (should never happen) */
1240 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1246 char *filename_old = (*snd_info)->source_filename;
1248 if (strcmp(filename, filename_old) == 0)
1250 /* The old and new sound are the same (have the same filename and path).
1251 This usually means that this sound does not exist in this sound set
1252 and a fallback to the existing sound is done. */
1255 printf("[sound '%s' already exists (same list entry)]\n", filename);
1262 printf("[decrementing reference counter of sound '%s']\n", filename_old);
1265 if (--(*snd_info)->num_references <= 0)
1268 printf("[deleting sound '%s']\n", filename_old);
1272 FreeSound(*snd_info);
1274 deleteNodeFromList(&SoundFileList, filename_old, FreeSound);
1278 /* check if this sound already exists in the list of sounds */
1279 node = getNodeFromKey(SoundFileList, filename);
1283 printf("[sound '%s' already exists (other list entry)]\n", filename);
1286 *snd_info = (SoundInfo *)node->content;
1287 (*snd_info)->num_references++;
1292 *snd_info = Load_WAV(filename);
1293 (*snd_info)->num_references = 1;
1295 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1298 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1301 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1303 sound_effect = sounds_list;
1304 num_sounds = num_list_entries;
1307 void LoadSoundToList(char *basename, int list_pos)
1309 if (Sound == NULL || list_pos >= num_sounds)
1312 printf("loading sound '%s' ... [%d]\n",
1313 basename, getNumNodes(SoundFileList));
1315 LoadCustomSound(&Sound[list_pos], basename);
1317 printf("loading sound '%s' done [%d]\n",
1318 basename, getNumNodes(SoundFileList));
1321 static MusicInfo *Load_MOD(char *filename)
1323 #if defined(TARGET_SDL)
1324 MusicInfo *mod_info;
1326 if (!audio.sound_available)
1329 mod_info = checked_calloc(sizeof(MusicInfo));
1331 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1333 Error(ERR_WARN, "cannot read music file '%s'", filename);
1338 mod_info->type = MUS_TYPE_MOD;
1339 mod_info->source_filename = getStringCopy(filename);
1347 void LoadCustomMusic(void)
1349 char *music_directory = getCustomMusicDirectory();
1351 struct dirent *dir_entry;
1353 if (!audio.sound_available)
1356 if ((dir = opendir(music_directory)) == NULL)
1358 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1359 audio.music_available = FALSE;
1363 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1365 char *basename = dir_entry->d_name;
1366 char *filename = getPath2(music_directory, basename);
1367 MusicInfo *mus_info = NULL;
1369 if (FileIsSound(basename))
1370 mus_info = Load_WAV(filename);
1371 else if (FileIsMusic(basename))
1372 mus_info = Load_MOD(filename);
1379 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1380 Music[num_music -1] = mus_info;
1387 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1391 void PlayMusic(int nr)
1393 if (!audio.music_available)
1396 #if defined(TARGET_SDL)
1398 nr = nr % num_music;
1400 if (Music[nr]->type == MUS_TYPE_MOD)
1402 Mix_PlayMusic(Music[nr]->data_ptr, -1);
1403 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1405 else /* play WAV music loop */
1407 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1408 Mix_PlayChannel(audio.music_channel, Music[nr]->data_ptr, -1);
1418 void PlaySound(int nr)
1420 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
1423 void PlaySoundStereo(int nr, int stereo)
1425 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
1428 void PlaySoundLoop(int nr)
1430 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
1433 void PlaySoundMusic(int nr)
1435 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_MUSIC);
1438 void PlaySoundExt(int nr, int volume, int stereo, boolean loop_type)
1440 struct SoundControl snd_ctrl = emptySoundControl;
1442 if (!audio.sound_available ||
1443 !audio.sound_enabled ||
1444 audio.sound_deactivated)
1447 if (volume < PSND_MIN_VOLUME)
1448 volume = PSND_MIN_VOLUME;
1449 else if (volume > PSND_MAX_VOLUME)
1450 volume = PSND_MAX_VOLUME;
1452 if (stereo < PSND_MAX_LEFT)
1453 stereo = PSND_MAX_LEFT;
1454 else if (stereo > PSND_MAX_RIGHT)
1455 stereo = PSND_MAX_RIGHT;
1458 snd_ctrl.volume = volume;
1459 snd_ctrl.stereo = stereo;
1460 snd_ctrl.loop = (loop_type != PSND_NO_LOOP);
1461 snd_ctrl.music = (loop_type == PSND_MUSIC);
1462 snd_ctrl.active = TRUE;
1465 /* now only used internally in sound server child process */
1466 snd_ctrl.data_ptr = Sound[nr].data_ptr;
1467 snd_ctrl.data_len = Sound[nr].data_len;
1470 #if defined(TARGET_SDL)
1471 Mix_Volume(-1, SOUND_MAX_VOLUME);
1472 Mix_PlayChannel(-1, Sound[nr]->data_ptr, (loop_type ? -1 : 0));
1473 #elif defined(PLATFORM_UNIX)
1474 if (audio.soundserver_pid == 0) /* we are child process */
1477 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1479 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1480 audio.sound_available = audio.sound_enabled = FALSE;
1483 #elif defined(PLATFORM_MSDOS)
1484 sound_handler(snd_ctrl);
1488 void FadeMusic(void)
1490 if (!audio.sound_available)
1493 #if defined(TARGET_SDL)
1494 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1495 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1497 StopSoundExt(-1, SSND_FADE_MUSIC);
1501 void FadeSound(int nr)
1503 StopSoundExt(nr, SSND_FADE_SOUND);
1509 StopSoundExt(-1, SSND_FADE_ALL);
1512 void StopMusic(void)
1514 #if defined(TARGET_SDL)
1515 if (!audio.sound_available)
1519 Mix_HaltChannel(audio.music_channel);
1521 StopSoundExt(-1, SSND_STOP_MUSIC);
1525 void StopSound(int nr)
1527 StopSoundExt(nr, SSND_STOP_SOUND);
1532 StopSoundExt(-1, SSND_STOP_ALL);
1535 void StopSoundExt(int nr, int method)
1537 struct SoundControl snd_ctrl = emptySoundControl;
1539 if (!audio.sound_available)
1542 if (method & SSND_FADING)
1543 snd_ctrl.fade_sound = TRUE;
1545 if (method & SSND_ALL)
1546 snd_ctrl.stop_all_sounds = TRUE;
1549 snd_ctrl.stop_sound = TRUE;
1553 if (method & SSND_MUSIC)
1554 snd_ctrl.music = TRUE;
1556 #if defined(TARGET_SDL)
1558 if (method & SSND_FADING)
1562 for (i=0; i<audio.channels; i++)
1563 if (i != audio.music_channel || snd_ctrl.music)
1564 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1566 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1572 for (i=0; i<audio.channels; i++)
1573 if (i != audio.music_channel || snd_ctrl.music)
1579 #elif !defined(PLATFORM_MSDOS)
1581 if (audio.soundserver_pid == 0) /* we are child process */
1584 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1586 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1587 audio.sound_available = audio.sound_enabled = FALSE;
1591 sound_handler(snd_ctrl);
1595 ListNode *newListNode()
1597 return checked_calloc(sizeof(ListNode));
1600 void addNodeToList(ListNode **node_first, char *key, void *content)
1602 ListNode *node_new = newListNode();
1605 printf("LIST: adding node with key '%s'\n", key);
1608 node_new->key = getStringCopy(key);
1609 node_new->content = content;
1610 node_new->next = *node_first;
1611 *node_first = node_new;
1614 void deleteNodeFromList(ListNode **node_first, char *key,
1615 void (*destructor_function)(void *))
1617 if (node_first == NULL || *node_first == NULL)
1620 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1621 (*node_first)->key, key);
1623 if (strcmp((*node_first)->key, key) == 0)
1625 printf("[DELETING LIST ENTRY]\n");
1627 free((*node_first)->key);
1628 if (destructor_function)
1629 destructor_function((*node_first)->content);
1630 *node_first = (*node_first)->next;
1633 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1636 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1638 if (node_first == NULL)
1641 if (strcmp(node_first->key, key) == 0)
1644 return getNodeFromKey(node_first->next, key);
1647 int getNumNodes(ListNode *node_first)
1649 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1652 void dumpList(ListNode *node_first)
1654 ListNode *node = node_first;
1658 printf("['%s' (%d)]\n", node->key,
1659 ((SoundInfo *)node->content)->num_references);
1663 printf("[%d nodes]\n", getNumNodes(node_first));
1666 static void LoadSoundsInfo()
1668 char *filename = getCustomSoundConfigFilename();
1669 struct SetupFileList *setup_file_list;
1672 /* always start with reliable default values */
1673 for (i=0; i<num_sounds; i++)
1674 sound_effect[i].filename = NULL;
1676 if (filename == NULL)
1679 if ((setup_file_list = loadSetupFileList(filename)))
1681 for (i=0; i<num_sounds; i++)
1682 sound_effect[i].filename =
1683 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1685 freeSetupFileList(setup_file_list);
1688 for (i=0; i<num_sounds; i++)
1690 printf("'%s' ", sound_effect[i].text);
1691 if (sound_effect[i].filename)
1692 printf("-> '%s'\n", sound_effect[i].filename);
1694 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1700 static void ReloadCustomSounds()
1705 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1710 for(i=0; i<num_sounds; i++)
1712 if (sound_effect[i].filename)
1713 LoadSoundToList(sound_effect[i].filename, i);
1715 LoadSoundToList(sound_effect[i].default_filename, i);
1719 printf("list size == %d\n", getNumNodes(SoundFileList));
1721 dumpList(SoundFileList);
1724 static void ReloadCustomMusic()
1727 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1735 static void InitReloadSoundsOrMusic(char *set_name, int type)
1737 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
1738 struct SoundControl snd_ctrl = emptySoundControl;
1740 (type == SND_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current);
1741 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
1742 unsigned long str_size2 = strlen(ti->basepath) + 1;
1743 unsigned long str_size3 = strlen(ti->fullpath) + 1;
1746 if (!audio.sound_available)
1749 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1750 if (type == SND_RELOAD_SOUNDS)
1751 audio.func_reload_sounds();
1753 audio.func_reload_music();
1754 #elif defined(PLATFORM_UNIX)
1755 if (audio.soundserver_pid == 0) /* we are child process */
1758 if (leveldir_current == NULL) /* should never happen */
1759 Error(ERR_EXIT, "leveldir_current == NULL");
1761 snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
1762 snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
1763 snd_ctrl.data_len = strlen(set_name) + 1;
1765 if (write(audio.soundserver_pipe[1], &snd_ctrl,
1766 sizeof(snd_ctrl)) < 0 ||
1767 write(audio.soundserver_pipe[1], set_name,
1768 snd_ctrl.data_len) < 0 ||
1769 write(audio.soundserver_pipe[1], leveldir_current,
1770 sizeof(TreeInfo)) < 0 ||
1771 write(audio.soundserver_pipe[1], ti,
1772 sizeof(TreeInfo)) < 0 ||
1773 write(audio.soundserver_pipe[1], &str_size1,
1774 sizeof(unsigned long)) < 0 ||
1775 write(audio.soundserver_pipe[1], &str_size2,
1776 sizeof(unsigned long)) < 0 ||
1777 write(audio.soundserver_pipe[1], &str_size3,
1778 sizeof(unsigned long)) < 0 ||
1779 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
1781 write(audio.soundserver_pipe[1], ti->basepath,
1783 write(audio.soundserver_pipe[1], ti->fullpath,
1786 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1787 audio.sound_available = audio.sound_enabled = FALSE;
1793 void InitReloadSounds(char *set_name)
1795 InitReloadSoundsOrMusic(set_name, SND_RELOAD_SOUNDS);
1798 void InitReloadMusic(char *set_name)
1800 InitReloadSoundsOrMusic(set_name, SND_RELOAD_MUSIC);
1803 void FreeSound(void *ptr)
1805 SoundInfo *sound = (SoundInfo *)ptr;
1810 if (sound->data_ptr)
1812 #if defined(TARGET_SDL)
1813 Mix_FreeChunk(sound->data_ptr);
1814 #elif defined(TARGET_ALLEGRO)
1815 destroy_sample(sound->data_ptr);
1816 #else /* PLATFORM_UNIX */
1817 free(sound->data_ptr);
1821 if (sound->source_filename)
1822 free(sound->source_filename);
1827 void FreeMusic(MusicInfo *music)
1832 if (music->data_ptr)
1834 #if defined(TARGET_SDL)
1835 if (music->type == MUS_TYPE_MOD)
1836 Mix_FreeMusic(music->data_ptr);
1838 Mix_FreeChunk(music->data_ptr);
1839 #elif defined(TARGET_ALLEGRO)
1840 destroy_sample(music->data_ptr);
1841 #else /* PLATFORM_UNIX */
1842 free(music->data_ptr);
1849 void FreeAllSounds()
1856 for(i=0; i<num_sounds; i++)
1857 FreeSound(Sound[i]);
1872 for(i=0; i<num_music; i++)
1873 FreeMusic(Music[i]);
1881 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1882 /* ========================================================================= */