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 ***********************************************************/
24 #if defined(PLATFORM_LINUX)
25 #include <sys/ioctl.h>
26 #include <linux/soundcard.h>
27 #elif defined(PLATFORM_FREEBSD)
28 #include <machine/soundcard.h>
29 #elif defined(PLATFORM_NETBSD)
30 #include <sys/ioctl.h>
31 #include <sys/audioio.h>
32 #elif defined(PLATFORM_HPUX)
33 #include <sys/audio.h>
43 /* expiration time (in milliseconds) for sound loops */
44 #define SOUND_LOOP_EXPIRATION_TIME 200
46 /* one second fading interval == 1000 ticks (milliseconds) */
47 #define SOUND_FADING_INTERVAL 1000
49 #if defined(TARGET_SDL)
50 #define SOUND_MAX_VOLUME SDL_MIX_MAXVOLUME
53 #if defined(AUDIO_STREAMING_DSP)
54 #define SOUND_FADING_VOLUME_STEP (PSND_MAX_VOLUME / 40)
55 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
58 #if !defined(PLATFORM_HPUX)
59 #define SND_BLOCKSIZE 4096
61 #define SND_BLOCKSIZE 32768
64 #define SND_TYPE_NONE 0
65 #define SND_TYPE_WAV 1
67 #define MUS_TYPE_NONE 0
68 #define MUS_TYPE_WAV 1
69 #define MUS_TYPE_MOD 2
71 #define DEVICENAME_DSP "/dev/dsp"
72 #define DEVICENAME_AUDIO "/dev/audio"
73 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
77 struct SoundHeader_SUN
80 unsigned long hdr_size;
81 unsigned long data_size;
82 unsigned long encoding;
83 unsigned long sample_rate;
84 unsigned long channels;
87 struct SoundHeader_8SVX
90 unsigned long chunk_size;
95 struct AudioFormatInfo
97 boolean stereo; /* availability of stereo sound */
98 int format; /* size and endianess of sample data */
99 int sample_rate; /* sample frequency */
100 int fragment_size; /* audio device fragment size in bytes */
105 char *source_filename;
113 typedef struct SampleInfo SoundInfo;
114 typedef struct SampleInfo MusicInfo;
126 unsigned long playing_starttime;
127 unsigned long playing_pos;
134 #if defined(PLATFORM_MSDOS)
138 typedef struct SoundControl SoundControl;
144 struct ListNode *next;
146 typedef struct ListNode ListNode;
148 static ListNode *newListNode(void);
149 static void addNodeToList(ListNode **, char *, void *);
150 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
151 static ListNode *getNodeFromKey(ListNode *, char *);
152 static int getNumNodes(ListNode *);
155 static struct SoundEffectInfo *sound_effect;
156 static ListNode *SoundFileList = NULL;
157 static SoundInfo **Sound = NULL;
158 static MusicInfo **Music = NULL;
159 static int num_sounds = 0, num_music = 0;
162 /* ========================================================================= */
163 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
165 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
166 static int mixer_active_channels = 0;
168 #if defined(AUDIO_UNIX_NATIVE)
169 static struct AudioFormatInfo afmt;
171 static void Mixer_Main(void);
172 #if !defined(AUDIO_STREAMING_DSP)
173 static unsigned char linear_to_ulaw(int);
174 static int ulaw_to_linear(unsigned char);
178 static void ReloadCustomSounds();
179 static void ReloadCustomMusic();
180 static void FreeSound(void *);
183 /* ------------------------------------------------------------------------- */
184 /* functions for native (non-SDL) Unix audio/mixer support */
185 /* ------------------------------------------------------------------------- */
187 #if defined(AUDIO_UNIX_NATIVE)
189 static int OpenAudioDevice(char *audio_device_name)
193 /* check if desired audio device is accessible */
194 if (access(audio_device_name, W_OK) != 0)
197 /* try to open audio device in non-blocking mode */
198 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
199 return audio_device_fd;
201 /* re-open audio device in blocking mode */
202 close(audio_device_fd);
203 audio_device_fd = open(audio_device_name, O_WRONLY);
205 return audio_device_fd;
208 static void CloseAudioDevice(int *audio_device_fd)
210 if (*audio_device_fd == 0)
213 close(*audio_device_fd);
214 *audio_device_fd = -1;
217 static boolean TestAudioDevices(void)
219 static char *audio_device_name[] =
224 int audio_device_fd = -1;
227 /* look for available audio devices, starting with preferred ones */
228 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
229 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
232 if (audio_device_fd < 0)
234 Error(ERR_WARN, "cannot open audio device -- no sound");
238 close(audio_device_fd);
240 audio.device_name = audio_device_name[i];
245 static boolean ForkAudioProcess(void)
247 if (pipe(audio.mixer_pipe) < 0)
249 Error(ERR_WARN, "cannot create pipe -- no sounds");
253 if ((audio.mixer_pid = fork()) < 0)
255 Error(ERR_WARN, "cannot create sound server process -- no sounds");
259 if (IS_CHILD_PROCESS(audio.mixer_pid))
260 Mixer_Main(); /* this function never returns */
262 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
267 void UnixOpenAudio(void)
269 if (!TestAudioDevices())
272 audio.sound_available = TRUE;
273 audio.sound_enabled = TRUE;
275 #if defined(AUDIO_STREAMING_DSP)
276 audio.music_available = TRUE;
277 audio.loops_available = TRUE;
280 audio.num_channels = NUM_MIXER_CHANNELS;
281 audio.music_channel = MUSIC_CHANNEL;
282 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
285 void UnixCloseAudio(void)
288 close(audio.device_fd);
290 if (IS_PARENT_PROCESS(audio.mixer_pid))
291 kill(audio.mixer_pid, SIGTERM);
295 /* ------------------------------------------------------------------------- */
296 /* functions for platform specific audio device initialization */
297 /* ------------------------------------------------------------------------- */
299 #if defined(AUDIO_LINUX_IOCTL)
300 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
302 /* "ioctl()" expects pointer to 'int' value for stereo flag
303 (boolean is defined as 'char', which will not work here) */
304 unsigned int fragment_spec = 0;
305 int fragment_size_query;
314 /* supported audio format in preferred order */
315 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
316 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
317 { AFMT_U8, AUDIO_FORMAT_U8 },
322 /* determine logarithm (log2) of the fragment size */
323 while ((1 << fragment_spec) < afmt->fragment_size)
326 /* use two fragments (play one fragment, prepare the other);
327 one fragment would result in interrupted audio output, more
328 than two fragments would raise audio output latency to much */
329 fragment_spec |= 0x00020000;
331 /* Example for fragment specification:
332 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
333 - (with stereo the effective buffer size will shrink to 256)
334 => fragment_size = 0x00020009 */
336 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
337 Error(ERR_EXIT_SOUND_SERVER,
338 "cannot set fragment size of /dev/dsp -- no sounds");
342 while (formats[i].format_result != -1)
344 unsigned int audio_format = formats[i].format_ioctl;
345 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
347 afmt->format = formats[i].format_result;
352 if (afmt->format == 0) /* no supported audio format found */
353 Error(ERR_EXIT_SOUND_SERVER,
354 "cannot set audio format of /dev/dsp -- no sounds");
356 /* try if we can use stereo sound */
358 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
359 afmt->stereo = FALSE;
361 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
362 Error(ERR_EXIT_SOUND_SERVER,
363 "cannot set sample rate of /dev/dsp -- no sounds");
365 /* get the real fragmentation size; this should return 512 */
366 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
367 Error(ERR_EXIT_SOUND_SERVER,
368 "cannot get fragment size of /dev/dsp -- no sounds");
369 if (fragment_size_query != afmt->fragment_size)
370 Error(ERR_EXIT_SOUND_SERVER,
371 "cannot set fragment size of /dev/dsp -- no sounds");
373 #endif /* AUDIO_LINUX_IOCTL */
375 #if defined(PLATFORM_NETBSD)
376 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
379 boolean stereo = TRUE;
381 AUDIO_INITINFO(&a_info);
382 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
383 a_info.play.precision = 8;
384 a_info.play.channels = 2;
385 a_info.play.sample_rate = sample_rate;
386 a_info.blocksize = fragment_size;
388 afmt->format = AUDIO_FORMAT_U8;
391 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
393 /* try to disable stereo */
394 a_info.play.channels = 1;
396 afmt->stereo = FALSE;
398 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
399 Error(ERR_EXIT_SOUND_SERVER,
400 "cannot set sample rate of /dev/audio -- no sounds");
403 #endif /* PLATFORM_NETBSD */
405 #if defined(PLATFORM_HPUX)
406 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
408 struct audio_describe ainfo;
411 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
413 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
415 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
416 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
418 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
419 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
421 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
422 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
424 afmt->format = AUDIO_FORMAT_U8;
425 afmt->stereo = FALSE;
426 afmt->sample_rate = 8000;
430 #endif /* PLATFORM_HPUX */
432 static void InitAudioDevice(struct AudioFormatInfo *afmt)
435 afmt->format = AUDIO_FORMAT_UNKNOWN;
436 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
437 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
439 #if defined(AUDIO_LINUX_IOCTL)
440 InitAudioDevice_Linux(afmt);
441 #elif defined(PLATFORM_NETBSD)
442 InitAudioDevice_NetBSD(afmt);
443 #elif defined(PLATFORM_HPUX)
444 InitAudioDevice_HPUX(afmt);
446 /* generic /dev/audio stuff might be placed here */
451 /* ------------------------------------------------------------------------- */
452 /* functions for communication between main process and sound mixer process */
453 /* ------------------------------------------------------------------------- */
455 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
457 if (IS_CHILD_PROCESS(audio.mixer_pid))
460 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
462 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
463 audio.sound_available = audio.sound_enabled = FALSE;
468 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
470 if (IS_PARENT_PROCESS(audio.mixer_pid))
473 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
474 != sizeof(SoundControl))
475 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
478 static void WriteReloadInfoToPipe(char *set_name, int type)
480 SoundControl snd_ctrl;
481 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
482 artwork.mus_current);
483 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
484 unsigned long str_size2 = strlen(ti->basepath) + 1;
485 unsigned long str_size3 = strlen(ti->fullpath) + 1;
487 if (IS_CHILD_PROCESS(audio.mixer_pid))
490 if (leveldir_current == NULL) /* should never happen */
491 Error(ERR_EXIT, "leveldir_current == NULL");
493 snd_ctrl.active = FALSE;
494 snd_ctrl.state = type;
495 snd_ctrl.data_len = strlen(set_name) + 1;
497 if (write(audio.mixer_pipe[1], &snd_ctrl,
498 sizeof(snd_ctrl)) < 0 ||
499 write(audio.mixer_pipe[1], set_name,
500 snd_ctrl.data_len) < 0 ||
501 write(audio.mixer_pipe[1], leveldir_current,
502 sizeof(TreeInfo)) < 0 ||
503 write(audio.mixer_pipe[1], ti,
504 sizeof(TreeInfo)) < 0 ||
505 write(audio.mixer_pipe[1], &str_size1,
506 sizeof(unsigned long)) < 0 ||
507 write(audio.mixer_pipe[1], &str_size2,
508 sizeof(unsigned long)) < 0 ||
509 write(audio.mixer_pipe[1], &str_size3,
510 sizeof(unsigned long)) < 0 ||
511 write(audio.mixer_pipe[1], leveldir_current->fullpath,
513 write(audio.mixer_pipe[1], ti->basepath,
515 write(audio.mixer_pipe[1], ti->fullpath,
518 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
519 audio.sound_available = audio.sound_enabled = FALSE;
524 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
526 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
527 &artwork.snd_current : &artwork.mus_current);
528 TreeInfo *ti = *ti_ptr;
529 unsigned long str_size1, str_size2, str_size3;
530 static char *set_name = NULL;
535 set_name = checked_malloc(snd_ctrl->data_len);
537 if (leveldir_current == NULL)
538 leveldir_current = checked_calloc(sizeof(TreeInfo));
540 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
541 if (leveldir_current->fullpath != NULL)
542 free(leveldir_current->fullpath);
543 if (ti->basepath != NULL)
545 if (ti->fullpath != NULL)
548 if (read(audio.mixer_pipe[0], set_name,
549 snd_ctrl->data_len) != snd_ctrl->data_len ||
550 read(audio.mixer_pipe[0], leveldir_current,
551 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
552 read(audio.mixer_pipe[0], ti,
553 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
554 read(audio.mixer_pipe[0], &str_size1,
555 sizeof(unsigned long)) != sizeof(unsigned long) ||
556 read(audio.mixer_pipe[0], &str_size2,
557 sizeof(unsigned long)) != sizeof(unsigned long) ||
558 read(audio.mixer_pipe[0], &str_size3,
559 sizeof(unsigned long)) != sizeof(unsigned long))
560 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
562 leveldir_current->fullpath = checked_calloc(str_size1);
563 ti->basepath = checked_calloc(str_size2);
564 ti->fullpath = checked_calloc(str_size3);
566 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
567 str_size1) != str_size1 ||
568 read(audio.mixer_pipe[0], ti->basepath,
569 str_size2) != str_size2 ||
570 read(audio.mixer_pipe[0], ti->fullpath,
571 str_size3) != str_size3)
572 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
574 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
575 artwork.sounds_set_current = set_name;
577 artwork.music_set_current = set_name;
580 #endif /* AUDIO_UNIX_NATIVE */
583 /* ------------------------------------------------------------------------- */
584 /* mixer functions */
585 /* ------------------------------------------------------------------------- */
587 void Mixer_InitChannels()
591 for(i=0; i<audio.num_channels; i++)
592 mixer[i].active = FALSE;
593 mixer_active_channels = 0;
596 static void Mixer_ResetChannelExpiration(int channel)
598 mixer[channel].playing_starttime = Counter();
600 #if defined(TARGET_SDL)
601 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
602 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
606 static boolean Mixer_ChannelExpired(int channel)
608 if (!mixer[channel].active)
611 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
612 DelayReached(&mixer[channel].playing_starttime,
613 SOUND_LOOP_EXPIRATION_TIME))
616 #if defined(TARGET_SDL)
618 if (!Mix_Playing(channel))
621 #elif defined(TARGET_ALLEGRO)
623 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
624 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
626 /* sound sample has completed playing or was completely faded out */
627 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
630 #endif /* TARGET_ALLEGRO */
635 static void Mixer_PlayChannel(int channel)
637 /* start with inactive channel in case something goes wrong */
638 mixer[channel].active = FALSE;
640 if (mixer[channel].type != MUS_TYPE_WAV)
643 #if defined(TARGET_SDL)
644 Mix_Volume(channel, SOUND_MAX_VOLUME);
645 Mix_PlayChannel(channel, mixer[channel].data_ptr,
646 IS_LOOP(mixer[channel]) ? -1 : 0);
647 #elif defined(PLATFORM_MSDOS)
648 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
649 if (mixer[channel].voice < 0)
652 if (IS_LOOP(mixer[channel]))
653 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
655 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
656 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
657 voice_start(mixer[channel].voice);
660 Mixer_ResetChannelExpiration(channel);
662 mixer[channel].playing_pos = 0;
663 mixer[channel].active = TRUE;
664 mixer_active_channels++;
667 static void Mixer_PlayMusicChannel()
669 Mixer_PlayChannel(audio.music_channel);
671 #if defined(TARGET_SDL)
672 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
674 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
675 this looks like a bug in the SDL_mixer library */
676 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
677 Mix_VolumeMusic(SOUND_MAX_VOLUME);
682 static void Mixer_StopChannel(int channel)
684 if (!mixer[channel].active)
687 #if defined(TARGET_SDL)
688 Mix_HaltChannel(channel);
689 #elif defined(PLATFORM_MSDOS)
690 voice_set_volume(mixer[channel].voice, 0);
691 deallocate_voice(mixer[channel].voice);
694 mixer[channel].active = FALSE;
695 mixer_active_channels--;
698 static void Mixer_StopMusicChannel()
700 Mixer_StopChannel(audio.music_channel);
702 #if defined(TARGET_SDL)
707 static void Mixer_FadeChannel(int channel)
709 if (!mixer[channel].active)
712 mixer[channel].state |= SND_CTRL_FADE;
714 #if defined(TARGET_SDL)
715 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
716 #elif defined(PLATFORM_MSDOS)
717 if (voice_check(mixer[channel].voice))
718 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
722 static void Mixer_FadeMusicChannel()
724 Mixer_FadeChannel(audio.music_channel);
726 #if defined(TARGET_SDL)
727 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
731 static void Mixer_UnFadeChannel(int channel)
733 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
736 mixer[channel].state &= ~SND_CTRL_FADE;
737 mixer[channel].volume = PSND_MAX_VOLUME;
739 #if defined(TARGET_SDL)
740 Mix_ExpireChannel(channel, -1);
741 Mix_Volume(channel, SOUND_MAX_VOLUME);
742 #elif defined(TARGET_ALLEGRO)
743 voice_stop_volumeramp(mixer[channel].voice);
744 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
745 mixer[channel].volume);
749 static void Mixer_InsertSound(SoundControl snd_ctrl)
755 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
759 printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
762 if (IS_MUSIC(snd_ctrl))
763 snd_ctrl.nr = snd_ctrl.nr % num_music;
764 else if (snd_ctrl.nr >= num_sounds)
767 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
768 if (snd_info == NULL)
771 /* copy sound sample and format information */
772 snd_ctrl.type = snd_info->type;
773 snd_ctrl.format = snd_info->format;
774 snd_ctrl.data_ptr = snd_info->data_ptr;
775 snd_ctrl.data_len = snd_info->data_len;
777 /* play music samples on a dedicated music channel */
778 if (IS_MUSIC(snd_ctrl))
780 mixer[audio.music_channel] = snd_ctrl;
781 Mixer_PlayMusicChannel();
786 /* check if sound is already being played (and how often) */
787 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
788 if (mixer[i].active && mixer[i].nr == snd_ctrl.nr)
792 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
795 /* reset expiration delay for already playing loop sounds */
796 if (k > 0 && IS_LOOP(snd_ctrl))
798 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
800 if (mixer[i].active && mixer[i].nr == snd_ctrl.nr)
803 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
807 Mixer_ResetChannelExpiration(i);
809 if (IS_FADING(mixer[i]))
810 Mixer_UnFadeChannel(i);
817 /* don't play sound more than n times simultaneously (with n == 2 for now) */
820 unsigned long playing_current = Counter();
821 int longest = 0, longest_nr = audio.first_sound_channel;
823 /* look for oldest equal sound */
824 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
826 int playing_time = playing_current - mixer[i].playing_starttime;
829 if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
832 actual = 1000 * playing_time / mixer[i].data_len;
834 if (actual >= longest)
841 Mixer_StopChannel(longest_nr);
844 /* If all (non-music) channels are active, stop the channel that has
845 played its sound sample most completely (in percent of the sample
846 length). As we cannot currently get the actual playing position
847 of the channel's sound sample when compiling with the SDL mixer
848 library, we use the current playing time (in milliseconds) instead. */
850 if (mixer_active_channels ==
851 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
853 unsigned long playing_current = Counter();
854 int longest = 0, longest_nr = audio.first_sound_channel;
856 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
858 int playing_time = playing_current - mixer[i].playing_starttime;
859 int actual = 1000 * playing_time / mixer[i].data_len;
861 if (!IS_LOOP(mixer[i]) && actual > longest)
868 Mixer_StopChannel(longest_nr);
871 /* add the new sound to the mixer */
872 for(i=0; i<audio.num_channels; i++)
875 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
879 if (!mixer[i].active ||
880 (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
882 if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
883 (i != audio.music_channel && !mixer[i].active))
886 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
890 #if defined(AUDIO_UNIX_NATIVE)
891 if (snd_info->data_len == 0)
893 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
899 if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
901 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
904 Mixer_StopChannel(i);
910 Mixer_PlayChannel(i);
917 static void HandleSoundRequest(SoundControl snd_ctrl)
921 #if defined(AUDIO_UNIX_NATIVE)
922 if (IS_PARENT_PROCESS(audio.mixer_pid))
924 SendSoundControlToMixerProcess(&snd_ctrl);
929 /* deactivate channels that have expired since the last request */
930 for (i=0; i<audio.num_channels; i++)
931 if (mixer[i].active && Mixer_ChannelExpired(i))
932 Mixer_StopChannel(i);
934 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
936 Mixer_StopMusicChannel();
937 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
938 Mixer_StopChannel(i);
940 #if defined(AUDIO_UNIX_NATIVE)
941 CloseAudioDevice(&audio.device_fd);
942 ReadReloadInfoFromPipe(&snd_ctrl);
945 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
946 ReloadCustomSounds();
950 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
952 if (IS_MUSIC(snd_ctrl))
954 Mixer_FadeMusicChannel();
958 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
959 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
960 Mixer_FadeChannel(i);
962 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
964 if (IS_MUSIC(snd_ctrl))
966 Mixer_StopMusicChannel();
970 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
971 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
972 Mixer_StopChannel(i);
974 #if defined(AUDIO_UNIX_NATIVE)
975 if (!mixer_active_channels)
976 CloseAudioDevice(&audio.device_fd);
979 else if (snd_ctrl.active) /* add new sound to mixer */
981 Mixer_InsertSound(snd_ctrl);
985 void StartMixer(void)
988 SDL_version compile_version;
989 const SDL_version *link_version;
990 MIX_VERSION(&compile_version);
991 printf("compiled with SDL_mixer version: %d.%d.%d\n",
992 compile_version.major,
993 compile_version.minor,
994 compile_version.patch);
995 link_version = Mix_Linked_Version();
996 printf("running with SDL_mixer version: %d.%d.%d\n",
999 link_version->patch);
1002 if (!audio.sound_available)
1005 #if defined(AUDIO_UNIX_NATIVE)
1006 if (!ForkAudioProcess())
1007 audio.sound_available = FALSE;
1011 #if defined(AUDIO_UNIX_NATIVE)
1013 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1014 int sample_pos, int sample_size,
1017 void *sample_ptr = snd_ctrl->data_ptr;
1020 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1021 for (i=0; i<sample_size; i++)
1023 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1024 else /* AUDIO_FORMAT_S16 */
1025 for (i=0; i<sample_size; i++)
1027 ((short *)sample_ptr)[sample_pos + i];
1030 #if defined(AUDIO_STREAMING_DSP)
1031 static void Mixer_Main_DSP()
1033 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
1034 static boolean stereo_volume_calculated = FALSE;
1035 static short premix_first_buffer[SND_BLOCKSIZE];
1036 static short premix_left_buffer[SND_BLOCKSIZE];
1037 static short premix_right_buffer[SND_BLOCKSIZE];
1038 static long premix_last_buffer[SND_BLOCKSIZE];
1039 static byte playing_buffer[SND_BLOCKSIZE];
1043 int max_sample_size;
1046 if (!stereo_volume_calculated)
1048 for(i=0; i<=PSND_MAX_LEFT2RIGHT; i++)
1050 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
1052 stereo_volume_calculated = TRUE;
1055 if (!mixer_active_channels)
1058 if (audio.device_fd < 0)
1060 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1063 InitAudioDevice(&afmt);
1066 stereo = afmt.stereo;
1067 fragment_size = afmt.fragment_size;
1068 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1069 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1071 /* first clear the last premixing buffer */
1072 memset(premix_last_buffer, 0,
1073 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1075 for(i=0; i<audio.num_channels; i++)
1082 if (!mixer[i].active)
1085 if (Mixer_ChannelExpired(i))
1087 Mixer_StopChannel(i);
1091 /* pointer, lenght and actual playing position of sound sample */
1092 sample_ptr = mixer[i].data_ptr;
1093 sample_len = mixer[i].data_len;
1094 sample_pos = mixer[i].playing_pos;
1095 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1096 mixer[i].playing_pos += sample_size;
1098 /* copy original sample to first mixing buffer */
1099 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1100 premix_first_buffer);
1102 /* are we about to restart a looping sound? */
1103 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1105 while (sample_size < max_sample_size)
1107 int restarted_sample_size =
1108 MIN(max_sample_size - sample_size, sample_len);
1110 if (mixer[i].format == AUDIO_FORMAT_U8)
1111 for (j=0; j<restarted_sample_size; j++)
1112 premix_first_buffer[sample_size + j] =
1113 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1115 for (j=0; j<restarted_sample_size; j++)
1116 premix_first_buffer[sample_size + j] =
1117 ((short *)sample_ptr)[j];
1119 mixer[i].playing_pos = restarted_sample_size;
1120 sample_size += restarted_sample_size;
1124 /* decrease volume if sound is fading out */
1125 if (IS_FADING(mixer[i]) &&
1126 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1127 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1129 /* adjust volume of actual sound sample */
1130 if (mixer[i].volume != PSND_MAX_VOLUME)
1131 for(j=0; j<sample_size; j++)
1132 premix_first_buffer[j] =
1133 (mixer[i].volume * (long)premix_first_buffer[j])
1134 >> PSND_MAX_VOLUME_BITS;
1136 /* fill the last mixing buffer with stereo or mono sound */
1139 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
1140 int left_volume = stereo_volume[middle_pos + mixer[i].stereo_position];
1141 int right_volume= stereo_volume[middle_pos - mixer[i].stereo_position];
1143 for(j=0; j<sample_size; j++)
1145 premix_left_buffer[j] =
1146 (left_volume * premix_first_buffer[j])
1147 >> PSND_MAX_LEFT2RIGHT_BITS;
1148 premix_right_buffer[j] =
1149 (right_volume * premix_first_buffer[j])
1150 >> PSND_MAX_LEFT2RIGHT_BITS;
1152 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1153 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1158 for(j=0; j<sample_size; j++)
1159 premix_last_buffer[j] += premix_first_buffer[j];
1162 /* delete completed sound entries from the mixer */
1163 if (mixer[i].playing_pos >= mixer[i].data_len)
1165 if (IS_LOOP(mixer[i]))
1166 mixer[i].playing_pos = 0;
1168 Mixer_StopChannel(i);
1170 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1171 Mixer_StopChannel(i);
1174 /* prepare final playing buffer according to system audio format */
1175 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1177 /* cut off at 17 bit value */
1178 if (premix_last_buffer[i] < -65535)
1179 premix_last_buffer[i] = -65535;
1180 else if (premix_last_buffer[i] > 65535)
1181 premix_last_buffer[i] = 65535;
1183 /* shift to 16 bit value */
1184 premix_last_buffer[i] >>= 1;
1186 if (afmt.format & AUDIO_FORMAT_U8)
1188 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1190 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1192 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1193 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1195 else /* big endian */
1197 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1198 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1202 /* finally play the sound fragment */
1203 write(audio.device_fd, playing_buffer, fragment_size);
1205 if (!mixer_active_channels)
1206 CloseAudioDevice(&audio.device_fd);
1209 #else /* !AUDIO_STREAMING_DSP */
1211 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1213 static short premix_first_buffer[SND_BLOCKSIZE];
1214 static byte playing_buffer[SND_BLOCKSIZE];
1215 int max_sample_size = SND_BLOCKSIZE;
1224 /* pointer, lenght and actual playing position of sound sample */
1225 sample_ptr = mixer[i].data_ptr;
1226 sample_len = mixer[i].data_len;
1227 sample_pos = mixer[i].playing_pos;
1228 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1229 mixer[i].playing_pos += sample_size;
1231 /* copy original sample to first mixing buffer */
1232 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1233 premix_first_buffer);
1235 /* adjust volume of actual sound sample */
1236 if (mixer[i].volume != PSND_MAX_VOLUME)
1237 for(j=0; j<sample_size; j++)
1238 premix_first_buffer[j] =
1239 (mixer[i].volume * (long)premix_first_buffer[j])
1240 >> PSND_MAX_VOLUME_BITS;
1242 /* might be needed for u-law /dev/audio */
1244 for(j=0; j<sample_size; j++)
1246 linear_to_ulaw(premix_first_buffer[j]);
1249 /* delete completed sound entries from the mixer */
1250 if (mixer[i].playing_pos >= mixer[i].data_len)
1251 Mixer_StopChannel(i);
1253 for(i=0; i<sample_size; i++)
1254 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1256 /* finally play the sound fragment */
1257 write(audio.device_fd, playing_buffer, sample_size);
1261 #endif /* !AUDIO_STREAMING_DSP */
1265 SoundControl snd_ctrl;
1268 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1270 Mixer_InitChannels();
1272 #if defined(PLATFORM_HPUX)
1273 InitAudioDevice(&afmt);
1276 FD_ZERO(&mixer_fdset);
1277 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1279 while(1) /* wait for sound playing commands from client */
1281 struct timeval delay = { 0, 0 };
1283 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1284 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1285 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1288 ReadSoundControlFromMainProcess(&snd_ctrl);
1290 HandleSoundRequest(snd_ctrl);
1292 #if defined(AUDIO_STREAMING_DSP)
1294 while (mixer_active_channels &&
1295 select(audio.mixer_pipe[0] + 1,
1296 &mixer_fdset, NULL, NULL, &delay) < 1)
1298 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1303 #else /* !AUDIO_STREAMING_DSP */
1305 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1306 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1309 InitAudioDevice(&afmt);
1314 while (mixer_active_channels &&
1315 select(audio.mixer_pipe[0] + 1,
1316 &mixer_fdset, NULL, NULL, &delay) < 1)
1318 int wait_percent = 90; /* wait 90% of the real playing time */
1321 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1323 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1327 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1330 CloseAudioDevice(&audio.device_fd);
1332 Mixer_InitChannels(); /* remove all sounds from mixer */
1334 #endif /* !AUDIO_STREAMING_DSP */
1337 #endif /* AUDIO_UNIX_NATIVE */
1340 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1342 /* these two are stolen from "sox"... :) */
1345 ** This routine converts from linear to ulaw.
1347 ** Craig Reese: IDA/Supercomputing Research Center
1348 ** Joe Campbell: Department of Defense
1349 ** 29 September 1989
1352 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1353 ** 2) "A New Digital Technique for Implementation of Any
1354 ** Continuous PCM Companding Law," Villeret, Michel,
1355 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1356 ** 1973, pg. 11.12-11.17
1357 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1358 ** for Analog-to_Digital Conversion Techniques,"
1361 ** Input: Signed 16 bit linear sample
1362 ** Output: 8 bit ulaw sample
1365 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1366 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1369 static unsigned char linear_to_ulaw(int sample)
1371 static int exp_lut[256] =
1373 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1374 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1375 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1376 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1377 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1378 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1379 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1380 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1381 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1382 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1383 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1384 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1385 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1386 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1387 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1388 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1391 int sign, exponent, mantissa;
1392 unsigned char ulawbyte;
1394 /* Get the sample into sign-magnitude. */
1395 sign = (sample >> 8) & 0x80; /* set aside the sign */
1397 sample = -sample; /* get magnitude */
1399 sample = CLIP; /* clip the magnitude */
1401 /* Convert from 16 bit linear to ulaw. */
1402 sample = sample + BIAS;
1403 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1404 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1405 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1408 ulawbyte = 0x02; /* optional CCITT trap */
1415 ** This routine converts from ulaw to 16 bit linear.
1417 ** Craig Reese: IDA/Supercomputing Research Center
1418 ** 29 September 1989
1421 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1422 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1423 ** for Analog-to_Digital Conversion Techniques,"
1426 ** Input: 8 bit ulaw sample
1427 ** Output: signed 16 bit linear sample
1430 static int ulaw_to_linear(unsigned char ulawbyte)
1432 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1433 int sign, exponent, mantissa, sample;
1435 ulawbyte = ~ ulawbyte;
1436 sign = ( ulawbyte & 0x80 );
1437 exponent = ( ulawbyte >> 4 ) & 0x07;
1438 mantissa = ulawbyte & 0x0F;
1439 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1445 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1448 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1449 /* ========================================================================= */
1450 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1452 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1453 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1455 static SoundInfo *Load_WAV(char *filename)
1457 SoundInfo *snd_info;
1458 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1459 byte sound_header_buffer[WAV_HEADER_SIZE];
1460 char chunk_name[CHUNK_ID_LEN + 1];
1466 if (!audio.sound_available)
1470 printf("loading WAV file '%s'\n", filename);
1473 snd_info = checked_calloc(sizeof(SoundInfo));
1475 #if defined(TARGET_SDL)
1477 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1479 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1484 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1486 #elif defined(TARGET_ALLEGRO)
1488 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1490 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1495 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1497 #else /* AUDIO_UNIX_NATIVE */
1499 if ((file = fopen(filename, MODE_READ)) == NULL)
1501 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1506 /* read chunk id "RIFF" */
1507 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1508 if (strcmp(chunk_name, "RIFF") != 0)
1510 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1516 /* read "RIFF" type id "WAVE" */
1517 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1518 if (strcmp(chunk_name, "WAVE") != 0)
1520 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1526 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1528 if (strcmp(chunk_name, "fmt ") == 0)
1530 /* read header information */
1531 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1532 sound_header_buffer[i] = fgetc(file);
1534 if (chunk_size > WAV_HEADER_SIZE)
1535 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1537 else if (strcmp(chunk_name, "data") == 0)
1539 snd_info->data_len = chunk_size;
1540 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1542 /* read sound data */
1543 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1546 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1548 free(snd_info->data_ptr);
1553 /* check for odd number of sample bytes (data chunk is word aligned) */
1554 if ((chunk_size % 2) == 1)
1555 ReadUnusedBytesFromFile(file, 1);
1557 else /* unknown chunk -- ignore */
1558 ReadUnusedBytesFromFile(file, chunk_size);
1563 if (snd_info->data_ptr == NULL)
1565 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1570 snd_info->format = AUDIO_FORMAT_U8;
1572 #endif /* AUDIO_UNIX_NATIVE */
1574 snd_info->type = SND_TYPE_WAV;
1575 snd_info->source_filename = getStringCopy(filename);
1580 static void deleteSoundEntry(SoundInfo **snd_info)
1584 char *filename = (*snd_info)->source_filename;
1587 printf("[decrementing reference counter of sound '%s']\n", filename);
1590 if (--(*snd_info)->num_references <= 0)
1593 printf("[deleting sound '%s']\n", filename);
1597 FreeSound(*snd_info);
1599 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1606 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1610 /* check if the old and the new sound file are the same */
1611 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1613 /* The old and new sound are the same (have the same filename and path).
1614 This usually means that this sound does not exist in this sound set
1615 and a fallback to the existing sound is done. */
1618 printf("[sound '%s' already exists (same list entry)]\n", filename);
1624 /* delete existing sound file entry */
1625 deleteSoundEntry(snd_info);
1627 /* check if the new sound file already exists in the list of sounds */
1628 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1631 printf("[sound '%s' already exists (other list entry)]\n", filename);
1634 *snd_info = (SoundInfo *)node->content;
1635 (*snd_info)->num_references++;
1637 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1639 (*snd_info)->num_references = 1;
1640 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1644 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1646 char *filename = getCustomSoundFilename(basename);
1649 printf("GOT CUSTOM SOUND FILE '%s'\n", filename);
1652 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1654 deleteSoundEntry(snd_info);
1658 if (filename == NULL)
1660 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1664 replaceSoundEntry(snd_info, filename);
1667 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1670 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1672 sound_effect = sounds_list;
1673 num_sounds = num_list_entries;
1676 void LoadSoundToList(char *basename, int list_pos)
1678 if (Sound == NULL || list_pos >= num_sounds)
1682 printf("loading sound '%s' ... [%d]\n",
1683 basename, getNumNodes(SoundFileList));
1686 LoadCustomSound(&Sound[list_pos], basename);
1689 printf("loading sound '%s' done [%d]\n",
1690 basename, getNumNodes(SoundFileList));
1694 static MusicInfo *Load_MOD(char *filename)
1696 #if defined(TARGET_SDL)
1697 MusicInfo *mod_info;
1699 if (!audio.sound_available)
1702 mod_info = checked_calloc(sizeof(MusicInfo));
1704 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1706 Error(ERR_WARN, "cannot read music file '%s'", filename);
1711 mod_info->type = MUS_TYPE_MOD;
1712 mod_info->source_filename = getStringCopy(filename);
1720 void LoadCustomMusic(void)
1722 static boolean draw_init_text = TRUE; /* only draw at startup */
1723 char *music_directory = getCustomMusicDirectory();
1725 struct dirent *dir_entry;
1727 if (!audio.sound_available)
1730 if ((dir = opendir(music_directory)) == NULL)
1732 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1733 audio.music_available = FALSE;
1738 DrawInitText("Loading music:", 120, FC_GREEN);
1740 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1742 char *basename = dir_entry->d_name;
1743 char *filename = getPath2(music_directory, basename);
1744 MusicInfo *mus_info = NULL;
1747 DrawInitText(basename, 150, FC_YELLOW);
1749 if (FileIsSound(basename))
1750 mus_info = Load_WAV(filename);
1751 else if (FileIsMusic(basename))
1752 mus_info = Load_MOD(filename);
1759 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1760 Music[num_music -1] = mus_info;
1766 draw_init_text = FALSE;
1769 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1773 void PlayMusic(int nr)
1775 if (!audio.music_available)
1781 void PlaySound(int nr)
1783 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_SOUND);
1786 void PlaySoundStereo(int nr, int stereo_position)
1788 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1791 void PlaySoundLoop(int nr)
1793 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_LOOP);
1796 void PlaySoundMusic(int nr)
1798 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1801 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1803 SoundControl snd_ctrl;
1805 if (!audio.sound_available ||
1806 !audio.sound_enabled ||
1807 audio.sound_deactivated)
1810 if (volume < PSND_MIN_VOLUME)
1811 volume = PSND_MIN_VOLUME;
1812 else if (volume > PSND_MAX_VOLUME)
1813 volume = PSND_MAX_VOLUME;
1815 if (stereo_position < PSND_MAX_LEFT)
1816 stereo_position = PSND_MAX_LEFT;
1817 else if (stereo_position > PSND_MAX_RIGHT)
1818 stereo_position = PSND_MAX_RIGHT;
1820 snd_ctrl.active = TRUE;
1822 snd_ctrl.volume = volume;
1823 snd_ctrl.stereo_position = stereo_position;
1824 snd_ctrl.state = state;
1826 HandleSoundRequest(snd_ctrl);
1829 void FadeMusic(void)
1831 if (!audio.music_available)
1834 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1837 void FadeSound(int nr)
1839 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1845 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1848 void StopMusic(void)
1850 if (!audio.music_available)
1853 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1856 void StopSound(int nr)
1858 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1864 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1867 void StopSoundExt(int nr, int state)
1869 SoundControl snd_ctrl;
1871 if (!audio.sound_available)
1874 snd_ctrl.active = FALSE;
1876 snd_ctrl.state = state;
1878 HandleSoundRequest(snd_ctrl);
1881 ListNode *newListNode()
1883 return checked_calloc(sizeof(ListNode));
1886 void addNodeToList(ListNode **node_first, char *key, void *content)
1888 ListNode *node_new = newListNode();
1891 printf("LIST: adding node with key '%s'\n", key);
1894 node_new->key = getStringCopy(key);
1895 node_new->content = content;
1896 node_new->next = *node_first;
1897 *node_first = node_new;
1900 void deleteNodeFromList(ListNode **node_first, char *key,
1901 void (*destructor_function)(void *))
1903 if (node_first == NULL || *node_first == NULL)
1907 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1908 (*node_first)->key, key);
1911 if (strcmp((*node_first)->key, key) == 0)
1914 printf("[DELETING LIST ENTRY]\n");
1917 free((*node_first)->key);
1918 if (destructor_function)
1919 destructor_function((*node_first)->content);
1920 *node_first = (*node_first)->next;
1923 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1926 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1928 if (node_first == NULL)
1931 if (strcmp(node_first->key, key) == 0)
1934 return getNodeFromKey(node_first->next, key);
1937 int getNumNodes(ListNode *node_first)
1939 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1942 void dumpList(ListNode *node_first)
1944 ListNode *node = node_first;
1948 printf("['%s' (%d)]\n", node->key,
1949 ((SoundInfo *)node->content)->num_references);
1953 printf("[%d nodes]\n", getNumNodes(node_first));
1956 static void LoadSoundsInfo()
1958 char *filename = getCustomSoundConfigFilename();
1959 struct SetupFileList *setup_file_list;
1963 printf("GOT CUSTOM SOUND CONFIG FILE '%s'\n", filename);
1966 /* always start with reliable default values */
1967 for (i=0; i<num_sounds; i++)
1968 sound_effect[i].filename = NULL;
1970 if (filename == NULL)
1973 if ((setup_file_list = loadSetupFileList(filename)))
1975 for (i=0; i<num_sounds; i++)
1976 sound_effect[i].filename =
1977 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1979 freeSetupFileList(setup_file_list);
1982 for (i=0; i<num_sounds; i++)
1984 printf("'%s' ", sound_effect[i].text);
1985 if (sound_effect[i].filename)
1986 printf("-> '%s'\n", sound_effect[i].filename);
1988 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1994 static void ReloadCustomSounds()
1996 static boolean draw_init_text = TRUE; /* only draw at startup */
2000 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
2006 DrawInitText("Loading sounds:", 120, FC_GREEN);
2009 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
2012 for(i=0; i<num_sounds; i++)
2015 DrawInitText(sound_effect[i].text, 150, FC_YELLOW);
2017 if (sound_effect[i].filename)
2018 LoadSoundToList(sound_effect[i].filename, i);
2020 LoadSoundToList(sound_effect[i].default_filename, i);
2023 draw_init_text = FALSE;
2026 printf("list size == %d\n", getNumNodes(SoundFileList));
2030 dumpList(SoundFileList);
2034 static void ReloadCustomMusic()
2037 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
2045 void InitReloadSounds(char *set_name)
2047 if (!audio.sound_available)
2050 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
2051 ReloadCustomSounds();
2052 #elif defined(AUDIO_UNIX_NATIVE)
2053 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
2057 void InitReloadMusic(char *set_name)
2059 if (!audio.music_available)
2062 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
2063 ReloadCustomMusic();
2064 #elif defined(AUDIO_UNIX_NATIVE)
2065 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
2069 void FreeSound(void *ptr)
2071 SoundInfo *sound = (SoundInfo *)ptr;
2076 if (sound->data_ptr)
2078 #if defined(TARGET_SDL)
2079 Mix_FreeChunk(sound->data_ptr);
2080 #elif defined(TARGET_ALLEGRO)
2081 destroy_sample(sound->data_ptr);
2082 #else /* AUDIO_UNIX_NATIVE */
2083 free(sound->data_ptr);
2087 if (sound->source_filename)
2088 free(sound->source_filename);
2093 void FreeMusic(MusicInfo *music)
2098 if (music->data_ptr)
2100 #if defined(TARGET_SDL)
2101 if (music->type == MUS_TYPE_MOD)
2102 Mix_FreeMusic(music->data_ptr);
2104 Mix_FreeChunk(music->data_ptr);
2105 #elif defined(TARGET_ALLEGRO)
2106 destroy_sample(music->data_ptr);
2107 #else /* AUDIO_UNIX_NATIVE */
2108 free(music->data_ptr);
2115 void FreeAllSounds()
2123 printf("%s: FREEING SOUNDS ...\n",
2124 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2127 for(i=0; i<num_sounds; i++)
2128 deleteSoundEntry(&Sound[i]);
2130 FreeSound(Sound[i]);
2134 printf("%s: FREEING SOUNDS -- DONE\n",
2135 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2151 for(i=0; i<num_music; i++)
2152 FreeMusic(Music[i]);
2160 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2161 /* ========================================================================= */