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 ***********************************************************/
27 #define IS_PARENT_PROCESS(pid) ((pid) > 0)
28 #define IS_CHILD_PROCESS(pid) ((pid) == 0)
34 struct ListNode *next;
36 typedef struct ListNode ListNode;
38 static ListNode *newListNode(void);
39 static void addNodeToList(ListNode **, char *, void *);
40 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
41 static ListNode *getNodeFromKey(ListNode *, char *);
42 static int getNumNodes(ListNode *);
45 static struct SoundEffectInfo *sound_effect;
46 static ListNode *SoundFileList = NULL;
47 static SoundInfo **Sound = NULL;
48 static MusicInfo **Music = NULL;
49 static int num_sounds = 0, num_music = 0;
52 /* ========================================================================= */
53 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
55 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
56 static int mixer_active_channels = 0;
58 #if defined(AUDIO_UNIX_NATIVE)
59 static struct AudioFormatInfo afmt;
61 static void Mixer_Main(void);
62 #if !defined(AUDIO_STREAMING_DSP)
63 static unsigned char linear_to_ulaw(int);
64 static int ulaw_to_linear(unsigned char);
68 static void ReloadCustomSounds();
69 static void ReloadCustomMusic();
70 static void FreeSound(void *);
73 /* ------------------------------------------------------------------------- */
74 /* functions for native (non-SDL) Unix audio/mixer support */
75 /* ------------------------------------------------------------------------- */
77 #if defined(AUDIO_UNIX_NATIVE)
79 static int OpenAudioDevice(char *audio_device_name)
83 /* check if desired audio device is accessible */
84 if (access(audio_device_name, W_OK) != 0)
87 /* try to open audio device in non-blocking mode */
88 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
89 return audio_device_fd;
91 /* re-open audio device in blocking mode */
92 close(audio_device_fd);
93 audio_device_fd = open(audio_device_name, O_WRONLY);
95 return audio_device_fd;
98 static void CloseAudioDevice(int *audio_device_fd)
100 if (*audio_device_fd == 0)
103 close(*audio_device_fd);
104 *audio_device_fd = -1;
107 static boolean TestAudioDevices(void)
109 static char *audio_device_name[] =
114 int audio_device_fd = -1;
117 /* look for available audio devices, starting with preferred ones */
118 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
119 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
122 if (audio_device_fd < 0)
124 Error(ERR_WARN, "cannot open audio device -- no sound");
128 close(audio_device_fd);
130 audio.device_name = audio_device_name[i];
135 static boolean ForkAudioProcess(void)
137 if (pipe(audio.mixer_pipe) < 0)
139 Error(ERR_WARN, "cannot create pipe -- no sounds");
143 if ((audio.mixer_pid = fork()) < 0)
145 Error(ERR_WARN, "cannot create sound server process -- no sounds");
149 if (IS_CHILD_PROCESS(audio.mixer_pid))
150 Mixer_Main(); /* this function never returns */
152 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
157 void UnixOpenAudio(void)
159 if (!TestAudioDevices())
162 audio.sound_available = TRUE;
163 audio.sound_enabled = TRUE;
165 #if defined(AUDIO_STREAMING_DSP)
166 audio.music_available = TRUE;
167 audio.loops_available = TRUE;
170 audio.num_channels = NUM_MIXER_CHANNELS;
171 audio.music_channel = MUSIC_CHANNEL;
172 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
175 void UnixCloseAudio(void)
178 close(audio.device_fd);
180 if (IS_PARENT_PROCESS(audio.mixer_pid))
181 kill(audio.mixer_pid, SIGTERM);
185 /* ------------------------------------------------------------------------- */
186 /* functions for platform specific audio device initialization */
187 /* ------------------------------------------------------------------------- */
189 #if defined(AUDIO_LINUX_IOCTL)
190 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
192 /* "ioctl()" expects pointer to 'int' value for stereo flag
193 (boolean is defined as 'char', which will not work here) */
194 unsigned int fragment_spec = 0;
195 int fragment_size_query;
204 /* supported audio format in preferred order */
205 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
206 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
207 { AFMT_U8, AUDIO_FORMAT_U8 },
212 /* determine logarithm (log2) of the fragment size */
213 while ((1 << fragment_spec) < afmt->fragment_size)
216 /* use two fragments (play one fragment, prepare the other);
217 one fragment would result in interrupted audio output, more
218 than two fragments would raise audio output latency to much */
219 fragment_spec |= 0x00020000;
221 /* Example for fragment specification:
222 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
223 - (with stereo the effective buffer size will shrink to 256)
224 => fragment_size = 0x00020009 */
226 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
227 Error(ERR_EXIT_SOUND_SERVER,
228 "cannot set fragment size of /dev/dsp -- no sounds");
232 while (formats[i].format_result != -1)
234 unsigned int audio_format = formats[i].format_ioctl;
235 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
237 afmt->format = formats[i].format_result;
242 if (afmt->format == 0) /* no supported audio format found */
243 Error(ERR_EXIT_SOUND_SERVER,
244 "cannot set audio format of /dev/dsp -- no sounds");
246 /* try if we can use stereo sound */
248 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
249 afmt->stereo = FALSE;
251 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
252 Error(ERR_EXIT_SOUND_SERVER,
253 "cannot set sample rate of /dev/dsp -- no sounds");
255 /* get the real fragmentation size; this should return 512 */
256 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
257 Error(ERR_EXIT_SOUND_SERVER,
258 "cannot get fragment size of /dev/dsp -- no sounds");
259 if (fragment_size_query != afmt->fragment_size)
260 Error(ERR_EXIT_SOUND_SERVER,
261 "cannot set fragment size of /dev/dsp -- no sounds");
263 #endif /* AUDIO_LINUX_IOCTL */
265 #if defined(PLATFORM_NETBSD)
266 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
269 boolean stereo = TRUE;
271 AUDIO_INITINFO(&a_info);
272 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
273 a_info.play.precision = 8;
274 a_info.play.channels = 2;
275 a_info.play.sample_rate = sample_rate;
276 a_info.blocksize = fragment_size;
278 afmt->format = AUDIO_FORMAT_U8;
281 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
283 /* try to disable stereo */
284 a_info.play.channels = 1;
286 afmt->stereo = FALSE;
288 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
289 Error(ERR_EXIT_SOUND_SERVER,
290 "cannot set sample rate of /dev/audio -- no sounds");
293 #endif /* PLATFORM_NETBSD */
295 #if defined(PLATFORM_HPUX)
296 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
298 struct audio_describe ainfo;
301 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
303 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
305 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
306 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
308 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
309 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
311 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
312 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
314 afmt->format = AUDIO_FORMAT_U8;
315 afmt->stereo = FALSE;
316 afmt->sample_rate = 8000;
320 #endif /* PLATFORM_HPUX */
322 static void InitAudioDevice(struct AudioFormatInfo *afmt)
325 afmt->format = AUDIO_FORMAT_UNKNOWN;
326 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
327 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
329 #if defined(AUDIO_LINUX_IOCTL)
330 InitAudioDevice_Linux(afmt);
331 #elif defined(PLATFORM_NETBSD)
332 InitAudioDevice_NetBSD(afmt);
333 #elif defined(PLATFORM_HPUX)
334 InitAudioDevice_HPUX(afmt);
336 /* generic /dev/audio stuff might be placed here */
341 /* ------------------------------------------------------------------------- */
342 /* functions for communication between main process and sound mixer process */
343 /* ------------------------------------------------------------------------- */
345 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
347 if (IS_CHILD_PROCESS(audio.mixer_pid))
350 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
352 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
353 audio.sound_available = audio.sound_enabled = FALSE;
358 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
360 if (IS_PARENT_PROCESS(audio.mixer_pid))
363 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
364 != sizeof(SoundControl))
365 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
368 static void WriteReloadInfoToPipe(char *set_name, int type)
370 SoundControl snd_ctrl;
371 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
372 artwork.mus_current);
373 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
374 unsigned long str_size2 = strlen(ti->basepath) + 1;
375 unsigned long str_size3 = strlen(ti->fullpath) + 1;
377 if (IS_CHILD_PROCESS(audio.mixer_pid))
380 if (leveldir_current == NULL) /* should never happen */
381 Error(ERR_EXIT, "leveldir_current == NULL");
383 snd_ctrl.active = FALSE;
384 snd_ctrl.state = type;
385 snd_ctrl.data_len = strlen(set_name) + 1;
387 if (write(audio.mixer_pipe[1], &snd_ctrl,
388 sizeof(snd_ctrl)) < 0 ||
389 write(audio.mixer_pipe[1], set_name,
390 snd_ctrl.data_len) < 0 ||
391 write(audio.mixer_pipe[1], leveldir_current,
392 sizeof(TreeInfo)) < 0 ||
393 write(audio.mixer_pipe[1], ti,
394 sizeof(TreeInfo)) < 0 ||
395 write(audio.mixer_pipe[1], &str_size1,
396 sizeof(unsigned long)) < 0 ||
397 write(audio.mixer_pipe[1], &str_size2,
398 sizeof(unsigned long)) < 0 ||
399 write(audio.mixer_pipe[1], &str_size3,
400 sizeof(unsigned long)) < 0 ||
401 write(audio.mixer_pipe[1], leveldir_current->fullpath,
403 write(audio.mixer_pipe[1], ti->basepath,
405 write(audio.mixer_pipe[1], ti->fullpath,
408 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
409 audio.sound_available = audio.sound_enabled = FALSE;
414 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
416 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
417 &artwork.snd_current : &artwork.mus_current);
418 TreeInfo *ti = *ti_ptr;
419 unsigned long str_size1, str_size2, str_size3;
420 static char *set_name = NULL;
425 set_name = checked_malloc(snd_ctrl->data_len);
427 if (leveldir_current == NULL)
428 leveldir_current = checked_calloc(sizeof(TreeInfo));
430 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
431 if (leveldir_current->fullpath != NULL)
432 free(leveldir_current->fullpath);
433 if (ti->basepath != NULL)
435 if (ti->fullpath != NULL)
438 if (read(audio.mixer_pipe[0], set_name,
439 snd_ctrl->data_len) != snd_ctrl->data_len ||
440 read(audio.mixer_pipe[0], leveldir_current,
441 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
442 read(audio.mixer_pipe[0], ti,
443 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
444 read(audio.mixer_pipe[0], &str_size1,
445 sizeof(unsigned long)) != sizeof(unsigned long) ||
446 read(audio.mixer_pipe[0], &str_size2,
447 sizeof(unsigned long)) != sizeof(unsigned long) ||
448 read(audio.mixer_pipe[0], &str_size3,
449 sizeof(unsigned long)) != sizeof(unsigned long))
450 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
452 leveldir_current->fullpath = checked_calloc(str_size1);
453 ti->basepath = checked_calloc(str_size2);
454 ti->fullpath = checked_calloc(str_size3);
456 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
457 str_size1) != str_size1 ||
458 read(audio.mixer_pipe[0], ti->basepath,
459 str_size2) != str_size2 ||
460 read(audio.mixer_pipe[0], ti->fullpath,
461 str_size3) != str_size3)
462 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
464 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
465 artwork.sounds_set_current = set_name;
467 artwork.music_set_current = set_name;
470 #endif /* AUDIO_UNIX_NATIVE */
473 /* ------------------------------------------------------------------------- */
474 /* mixer functions */
475 /* ------------------------------------------------------------------------- */
477 void Mixer_InitChannels()
481 for(i=0; i<audio.num_channels; i++)
482 mixer[i].active = FALSE;
483 mixer_active_channels = 0;
486 static void Mixer_PlayChannel(int channel)
488 /* start with inactive channel in case something goes wrong */
489 mixer[channel].active = FALSE;
491 if (mixer[channel].type != MUS_TYPE_WAV)
494 mixer[channel].playing_pos = 0;
495 mixer[channel].playing_starttime = Counter();
497 #if defined(TARGET_SDL)
498 Mix_Volume(channel, SOUND_MAX_VOLUME);
499 Mix_PlayChannel(channel, mixer[channel].data_ptr,
500 IS_LOOP(mixer[channel]) ? -1 : 0);
501 #elif defined(PLATFORM_MSDOS)
502 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
503 if (mixer[channel].voice < 0)
506 if (IS_LOOP(mixer[channel]))
507 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
509 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
510 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
511 voice_start(mixer[channel].voice);
514 mixer[channel].active = TRUE;
515 mixer_active_channels++;
518 static void Mixer_PlayMusicChannel()
520 Mixer_PlayChannel(audio.music_channel);
522 #if defined(TARGET_SDL)
523 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
525 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
526 this looks like a bug in the SDL_mixer library */
527 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
528 Mix_VolumeMusic(SOUND_MAX_VOLUME);
533 static void Mixer_StopChannel(int channel)
536 #if defined(TARGET_SDL)
537 printf("----------> %d [%d]\n", Mix_Playing(channel), Mix_Playing(0));
541 if (!mixer[channel].active)
544 #if defined(TARGET_SDL)
545 Mix_HaltChannel(channel);
546 #elif defined(PLATFORM_MSDOS)
547 voice_set_volume(mixer[channel].voice, 0);
548 deallocate_voice(mixer[channel].voice);
551 mixer[channel].active = FALSE;
552 mixer_active_channels--;
555 static void Mixer_StopMusicChannel()
557 Mixer_StopChannel(audio.music_channel);
559 #if defined(TARGET_SDL)
564 static void Mixer_FadeChannel(int channel)
566 if (!mixer[channel].active)
569 mixer[channel].state |= SND_CTRL_FADE;
571 #if defined(TARGET_SDL)
572 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
573 #elif defined(PLATFORM_MSDOS)
574 if (voice_check(mixer[channel].voice))
575 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
579 static void Mixer_FadeMusicChannel()
581 Mixer_FadeChannel(audio.music_channel);
583 #if defined(TARGET_SDL)
584 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
588 static void Mixer_UnFadeChannel(int channel)
590 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
593 mixer[channel].state &= ~SND_CTRL_FADE;
594 mixer[channel].volume = PSND_MAX_VOLUME;
596 #if defined(TARGET_SDL)
597 Mix_ExpireChannel(channel, -1);
598 Mix_Volume(channel, SOUND_MAX_VOLUME);
599 #elif defined(TARGET_ALLEGRO)
600 voice_stop_volumeramp(mixer[channel].voice);
601 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
602 mixer[channel].volume);
606 static void Mixer_InsertSound(SoundControl snd_ctrl)
612 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
616 printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
619 if (IS_MUSIC(snd_ctrl))
620 snd_ctrl.nr = snd_ctrl.nr % num_music;
621 else if (snd_ctrl.nr >= num_sounds)
624 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
625 if (snd_info == NULL)
628 /* copy sound sample and format information */
629 snd_ctrl.type = snd_info->type;
630 snd_ctrl.format = snd_info->format;
631 snd_ctrl.data_ptr = snd_info->data_ptr;
632 snd_ctrl.data_len = snd_info->data_len;
634 /* play music samples on a dedicated music channel */
635 if (IS_MUSIC(snd_ctrl))
637 mixer[audio.music_channel] = snd_ctrl;
638 Mixer_PlayMusicChannel();
643 /* check if sound is already being played (and how often) */
644 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
645 if (mixer[i].nr == snd_ctrl.nr)
648 /* restart loop sounds only if they are just fading out */
649 if (k >= 1 && IS_LOOP(snd_ctrl))
651 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
652 if (mixer[i].nr == snd_ctrl.nr && IS_FADING(mixer[i]))
653 Mixer_UnFadeChannel(i);
658 /* don't play sound more than n times simultaneously (with n == 2 for now) */
661 unsigned long playing_current = Counter();
662 int longest = 0, longest_nr = audio.first_sound_channel;
664 /* look for oldest equal sound */
665 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
667 int playing_time = playing_current - mixer[i].playing_starttime;
670 if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
674 actual = 1000 * playing_time / mixer[i].data_len;
676 actual = 100 * mixer[i].playing_pos / mixer[i].data_len;
679 if (actual >= longest)
686 Mixer_StopChannel(longest_nr);
689 /* If all (non-music) channels are active, stop the channel that has
690 played its sound sample most completely (in percent of the sample
691 length). As we cannot currently get the actual playing position
692 of the channel's sound sample when compiling with the SDL mixer
693 library, we use the current playing time (in milliseconds) instead. */
695 if (mixer_active_channels ==
696 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
698 unsigned long playing_current = Counter();
699 int longest = 0, longest_nr = audio.first_sound_channel;
701 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
704 int playing_time = playing_current - mixer[i].playing_starttime;
705 int actual = 1000 * playing_time / mixer[i].data_len;
707 int actual = 100 * mixer[i].playing_pos / mixer[i].data_len;
710 if (!IS_LOOP(mixer[i]) && actual > longest)
717 Mixer_StopChannel(longest_nr);
720 /* add new sound to mixer */
721 for(i=0; i<audio.num_channels; i++)
724 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
728 if (!mixer[i].active ||
729 (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
731 if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
732 (i != audio.music_channel && !mixer[i].active))
735 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
739 #if defined(AUDIO_UNIX_NATIVE)
740 if (snd_info->data_len == 0)
742 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
748 if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
750 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
753 Mixer_StopChannel(i);
759 Mixer_PlayChannel(i);
766 static void HandleSoundRequest(SoundControl snd_ctrl)
770 #if defined(AUDIO_UNIX_NATIVE)
771 if (IS_PARENT_PROCESS(audio.mixer_pid))
773 SendSoundControlToMixerProcess(&snd_ctrl);
778 for (i=0; i<audio.num_channels; i++)
780 if (!mixer[i].active)
783 if (i != audio.music_channel &&
784 DelayReached(&mixer[i].playing_starttime, SOUND_LOOP_EXPIRATION_TIME))
786 Mixer_StopChannel(i);
790 #if defined(TARGET_SDL)
793 Mixer_StopChannel(i);
795 #elif defined(TARGET_ALLEGRO)
797 mixer[i].playing_pos = voice_get_position(mixer[i].voice);
798 mixer[i].volume = voice_get_volume(mixer[i].voice);
800 /* sound sample has completed playing or was completely faded out */
801 if (mixer[i].playing_pos == -1 || mixer[i].volume == 0)
802 Mixer_StopChannel(i);
804 #endif /* TARGET_ALLEGRO */
807 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
809 Mixer_StopMusicChannel();
810 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
811 Mixer_StopChannel(i);
813 #if defined(AUDIO_UNIX_NATIVE)
814 CloseAudioDevice(&audio.device_fd);
815 ReadReloadInfoFromPipe(&snd_ctrl);
818 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
819 ReloadCustomSounds();
823 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
825 if (IS_MUSIC(snd_ctrl))
827 Mixer_FadeMusicChannel();
831 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
832 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
833 Mixer_FadeChannel(i);
835 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
837 if (IS_MUSIC(snd_ctrl))
839 Mixer_StopMusicChannel();
843 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
844 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
845 Mixer_StopChannel(i);
847 #if defined(AUDIO_UNIX_NATIVE)
848 if (!mixer_active_channels)
849 CloseAudioDevice(&audio.device_fd);
852 else if (snd_ctrl.active) /* add new sound to mixer */
854 Mixer_InsertSound(snd_ctrl);
858 void StartMixer(void)
861 SDL_version compile_version;
862 const SDL_version *link_version;
863 MIX_VERSION(&compile_version);
864 printf("compiled with SDL_mixer version: %d.%d.%d\n",
865 compile_version.major,
866 compile_version.minor,
867 compile_version.patch);
868 link_version = Mix_Linked_Version();
869 printf("running with SDL_mixer version: %d.%d.%d\n",
872 link_version->patch);
875 if (!audio.sound_available)
878 #if defined(AUDIO_UNIX_NATIVE)
879 if (!ForkAudioProcess())
880 audio.sound_available = FALSE;
884 #if defined(AUDIO_UNIX_NATIVE)
886 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
887 int sample_pos, int sample_size,
890 void *sample_ptr = snd_ctrl->data_ptr;
893 if (snd_ctrl->format == AUDIO_FORMAT_U8)
894 for (i=0; i<sample_size; i++)
896 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
897 else /* AUDIO_FORMAT_S16 */
898 for (i=0; i<sample_size; i++)
900 ((short *)sample_ptr)[sample_pos + i];
903 #if defined(AUDIO_STREAMING_DSP)
904 static void Mixer_Main_DSP()
906 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
907 static boolean stereo_volume_calculated = FALSE;
908 static short premix_first_buffer[SND_BLOCKSIZE];
909 static short premix_left_buffer[SND_BLOCKSIZE];
910 static short premix_right_buffer[SND_BLOCKSIZE];
911 static long premix_last_buffer[SND_BLOCKSIZE];
912 static byte playing_buffer[SND_BLOCKSIZE];
919 if (!stereo_volume_calculated)
921 for(i=0; i<=PSND_MAX_LEFT2RIGHT; i++)
923 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
925 stereo_volume_calculated = TRUE;
928 if (!mixer_active_channels)
931 if (audio.device_fd < 0)
933 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
936 InitAudioDevice(&afmt);
939 stereo = afmt.stereo;
940 fragment_size = afmt.fragment_size;
941 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
942 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
944 /* first clear the last premixing buffer */
945 memset(premix_last_buffer, 0,
946 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
948 for(i=0; i<audio.num_channels; i++)
955 if (!mixer[i].active)
958 /* pointer, lenght and actual playing position of sound sample */
959 sample_ptr = mixer[i].data_ptr;
960 sample_len = mixer[i].data_len;
961 sample_pos = mixer[i].playing_pos;
962 sample_size = MIN(max_sample_size, sample_len - sample_pos);
963 mixer[i].playing_pos += sample_size;
965 /* copy original sample to first mixing buffer */
966 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
967 premix_first_buffer);
969 /* are we about to restart a looping sound? */
970 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
972 while (sample_size < max_sample_size)
974 int restarted_sample_size =
975 MIN(max_sample_size - sample_size, sample_len);
977 if (mixer[i].format == AUDIO_FORMAT_U8)
978 for (j=0; j<restarted_sample_size; j++)
979 premix_first_buffer[sample_size + j] =
980 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
982 for (j=0; j<restarted_sample_size; j++)
983 premix_first_buffer[sample_size + j] =
984 ((short *)sample_ptr)[j];
986 mixer[i].playing_pos = restarted_sample_size;
987 sample_size += restarted_sample_size;
991 /* decrease volume if sound is fading out */
992 if (IS_FADING(mixer[i]) &&
993 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
994 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
996 /* adjust volume of actual sound sample */
997 if (mixer[i].volume != PSND_MAX_VOLUME)
998 for(j=0; j<sample_size; j++)
999 premix_first_buffer[j] =
1000 (mixer[i].volume * (long)premix_first_buffer[j])
1001 >> PSND_MAX_VOLUME_BITS;
1003 /* fill the last mixing buffer with stereo or mono sound */
1006 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
1007 int left_volume = stereo_volume[middle_pos + mixer[i].stereo_position];
1008 int right_volume= stereo_volume[middle_pos - mixer[i].stereo_position];
1010 for(j=0; j<sample_size; j++)
1012 premix_left_buffer[j] =
1013 (left_volume * premix_first_buffer[j])
1014 >> PSND_MAX_LEFT2RIGHT_BITS;
1015 premix_right_buffer[j] =
1016 (right_volume * premix_first_buffer[j])
1017 >> PSND_MAX_LEFT2RIGHT_BITS;
1019 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1020 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1025 for(j=0; j<sample_size; j++)
1026 premix_last_buffer[j] += premix_first_buffer[j];
1029 /* delete completed sound entries from the mixer */
1030 if (mixer[i].playing_pos >= mixer[i].data_len)
1032 if (IS_LOOP(mixer[i]))
1033 mixer[i].playing_pos = 0;
1035 Mixer_StopChannel(i);
1037 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1038 Mixer_StopChannel(i);
1041 /* prepare final playing buffer according to system audio format */
1042 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1044 /* cut off at 17 bit value */
1045 if (premix_last_buffer[i] < -65535)
1046 premix_last_buffer[i] = -65535;
1047 else if (premix_last_buffer[i] > 65535)
1048 premix_last_buffer[i] = 65535;
1050 /* shift to 16 bit value */
1051 premix_last_buffer[i] >>= 1;
1053 if (afmt.format & AUDIO_FORMAT_U8)
1055 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1057 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1059 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1060 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1062 else /* big endian */
1064 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1065 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1069 /* finally play the sound fragment */
1070 write(audio.device_fd, playing_buffer, fragment_size);
1072 if (!mixer_active_channels)
1073 CloseAudioDevice(&audio.device_fd);
1076 #else /* !AUDIO_STREAMING_DSP */
1078 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1080 static short premix_first_buffer[SND_BLOCKSIZE];
1081 static byte playing_buffer[SND_BLOCKSIZE];
1082 int max_sample_size = SND_BLOCKSIZE;
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 /* adjust volume of actual sound sample */
1103 if (mixer[i].volume != PSND_MAX_VOLUME)
1104 for(j=0; j<sample_size; j++)
1105 premix_first_buffer[j] =
1106 (mixer[i].volume * (long)premix_first_buffer[j])
1107 >> PSND_MAX_VOLUME_BITS;
1109 /* might be needed for u-law /dev/audio */
1111 for(j=0; j<sample_size; j++)
1113 linear_to_ulaw(premix_first_buffer[j]);
1116 /* delete completed sound entries from the mixer */
1117 if (mixer[i].playing_pos >= mixer[i].data_len)
1118 Mixer_StopChannel(i);
1120 for(i=0; i<sample_size; i++)
1121 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1123 /* finally play the sound fragment */
1124 write(audio.device_fd, playing_buffer, sample_size);
1128 #endif /* !AUDIO_STREAMING_DSP */
1132 SoundControl snd_ctrl;
1135 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1137 Mixer_InitChannels();
1139 #if defined(PLATFORM_HPUX)
1140 InitAudioDevice(&afmt);
1143 FD_ZERO(&mixer_fdset);
1144 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1146 while(1) /* wait for sound playing commands from client */
1148 struct timeval delay = { 0, 0 };
1150 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1151 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1152 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1155 ReadSoundControlFromMainProcess(&snd_ctrl);
1157 HandleSoundRequest(snd_ctrl);
1159 #if defined(AUDIO_STREAMING_DSP)
1161 while (mixer_active_channels &&
1162 select(audio.mixer_pipe[0] + 1,
1163 &mixer_fdset, NULL, NULL, &delay) < 1)
1165 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1170 #else /* !AUDIO_STREAMING_DSP */
1172 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1173 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1176 InitAudioDevice(&afmt);
1181 while (mixer_active_channels &&
1182 select(audio.mixer_pipe[0] + 1,
1183 &mixer_fdset, NULL, NULL, &delay) < 1)
1185 int wait_percent = 90; /* wait 90% of the real playing time */
1188 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1190 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1194 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1197 CloseAudioDevice(&audio.device_fd);
1199 Mixer_InitChannels(); /* remove all sounds from mixer */
1201 #endif /* !AUDIO_STREAMING_DSP */
1204 #endif /* AUDIO_UNIX_NATIVE */
1207 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1209 /* these two are stolen from "sox"... :) */
1212 ** This routine converts from linear to ulaw.
1214 ** Craig Reese: IDA/Supercomputing Research Center
1215 ** Joe Campbell: Department of Defense
1216 ** 29 September 1989
1219 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1220 ** 2) "A New Digital Technique for Implementation of Any
1221 ** Continuous PCM Companding Law," Villeret, Michel,
1222 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1223 ** 1973, pg. 11.12-11.17
1224 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1225 ** for Analog-to_Digital Conversion Techniques,"
1228 ** Input: Signed 16 bit linear sample
1229 ** Output: 8 bit ulaw sample
1232 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1233 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1236 static unsigned char linear_to_ulaw(int sample)
1238 static int exp_lut[256] =
1240 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1241 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1242 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1243 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1244 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1245 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1246 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1247 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1248 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1249 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1250 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1251 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1252 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1253 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1254 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1255 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1258 int sign, exponent, mantissa;
1259 unsigned char ulawbyte;
1261 /* Get the sample into sign-magnitude. */
1262 sign = (sample >> 8) & 0x80; /* set aside the sign */
1264 sample = -sample; /* get magnitude */
1266 sample = CLIP; /* clip the magnitude */
1268 /* Convert from 16 bit linear to ulaw. */
1269 sample = sample + BIAS;
1270 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1271 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1272 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1275 ulawbyte = 0x02; /* optional CCITT trap */
1282 ** This routine converts from ulaw to 16 bit linear.
1284 ** Craig Reese: IDA/Supercomputing Research Center
1285 ** 29 September 1989
1288 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1289 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1290 ** for Analog-to_Digital Conversion Techniques,"
1293 ** Input: 8 bit ulaw sample
1294 ** Output: signed 16 bit linear sample
1297 static int ulaw_to_linear(unsigned char ulawbyte)
1299 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1300 int sign, exponent, mantissa, sample;
1302 ulawbyte = ~ ulawbyte;
1303 sign = ( ulawbyte & 0x80 );
1304 exponent = ( ulawbyte >> 4 ) & 0x07;
1305 mantissa = ulawbyte & 0x0F;
1306 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1312 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1315 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1316 /* ========================================================================= */
1317 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1319 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1320 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1322 static SoundInfo *Load_WAV(char *filename)
1324 SoundInfo *snd_info;
1325 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1326 byte sound_header_buffer[WAV_HEADER_SIZE];
1327 char chunk_name[CHUNK_ID_LEN + 1];
1333 if (!audio.sound_available)
1337 printf("loading WAV file '%s'\n", filename);
1340 snd_info = checked_calloc(sizeof(SoundInfo));
1342 #if defined(TARGET_SDL)
1344 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1346 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1351 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1353 #elif defined(TARGET_ALLEGRO)
1355 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1357 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1362 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1364 #else /* AUDIO_UNIX_NATIVE */
1366 if ((file = fopen(filename, MODE_READ)) == NULL)
1368 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1373 /* read chunk id "RIFF" */
1374 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1375 if (strcmp(chunk_name, "RIFF") != 0)
1377 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1383 /* read "RIFF" type id "WAVE" */
1384 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1385 if (strcmp(chunk_name, "WAVE") != 0)
1387 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1393 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1395 if (strcmp(chunk_name, "fmt ") == 0)
1397 /* read header information */
1398 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1399 sound_header_buffer[i] = fgetc(file);
1401 if (chunk_size > WAV_HEADER_SIZE)
1402 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1404 else if (strcmp(chunk_name, "data") == 0)
1406 snd_info->data_len = chunk_size;
1407 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1409 /* read sound data */
1410 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1413 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1415 free(snd_info->data_ptr);
1420 /* check for odd number of sample bytes (data chunk is word aligned) */
1421 if ((chunk_size % 2) == 1)
1422 ReadUnusedBytesFromFile(file, 1);
1424 else /* unknown chunk -- ignore */
1425 ReadUnusedBytesFromFile(file, chunk_size);
1430 if (snd_info->data_ptr == NULL)
1432 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1437 snd_info->format = AUDIO_FORMAT_U8;
1439 #endif /* AUDIO_UNIX_NATIVE */
1441 snd_info->type = SND_TYPE_WAV;
1442 snd_info->source_filename = getStringCopy(filename);
1447 static void deleteSoundEntry(SoundInfo **snd_info)
1451 char *filename = (*snd_info)->source_filename;
1454 printf("[decrementing reference counter of sound '%s']\n", filename);
1457 if (--(*snd_info)->num_references <= 0)
1460 printf("[deleting sound '%s']\n", filename);
1464 FreeSound(*snd_info);
1466 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1473 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1477 /* check if the old and the new sound file are the same */
1478 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1480 /* The old and new sound are the same (have the same filename and path).
1481 This usually means that this sound does not exist in this sound set
1482 and a fallback to the existing sound is done. */
1485 printf("[sound '%s' already exists (same list entry)]\n", filename);
1491 /* delete existing sound file entry */
1492 deleteSoundEntry(snd_info);
1494 /* check if the new sound file already exists in the list of sounds */
1495 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1498 printf("[sound '%s' already exists (other list entry)]\n", filename);
1501 *snd_info = (SoundInfo *)node->content;
1502 (*snd_info)->num_references++;
1504 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1506 (*snd_info)->num_references = 1;
1507 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1511 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1513 char *filename = getCustomSoundFilename(basename);
1515 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1517 deleteSoundEntry(snd_info);
1521 if (filename == NULL)
1523 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1527 replaceSoundEntry(snd_info, filename);
1530 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1533 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1535 sound_effect = sounds_list;
1536 num_sounds = num_list_entries;
1539 void LoadSoundToList(char *basename, int list_pos)
1541 if (Sound == NULL || list_pos >= num_sounds)
1545 printf("loading sound '%s' ... [%d]\n",
1546 basename, getNumNodes(SoundFileList));
1549 LoadCustomSound(&Sound[list_pos], basename);
1552 printf("loading sound '%s' done [%d]\n",
1553 basename, getNumNodes(SoundFileList));
1557 static MusicInfo *Load_MOD(char *filename)
1559 #if defined(TARGET_SDL)
1560 MusicInfo *mod_info;
1562 if (!audio.sound_available)
1565 mod_info = checked_calloc(sizeof(MusicInfo));
1567 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1569 Error(ERR_WARN, "cannot read music file '%s'", filename);
1574 mod_info->type = MUS_TYPE_MOD;
1575 mod_info->source_filename = getStringCopy(filename);
1583 void LoadCustomMusic(void)
1585 char *music_directory = getCustomMusicDirectory();
1587 struct dirent *dir_entry;
1589 if (!audio.sound_available)
1592 if ((dir = opendir(music_directory)) == NULL)
1594 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1595 audio.music_available = FALSE;
1599 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1601 char *basename = dir_entry->d_name;
1602 char *filename = getPath2(music_directory, basename);
1603 MusicInfo *mus_info = NULL;
1605 if (FileIsSound(basename))
1606 mus_info = Load_WAV(filename);
1607 else if (FileIsMusic(basename))
1608 mus_info = Load_MOD(filename);
1615 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1616 Music[num_music -1] = mus_info;
1623 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1627 void PlayMusic(int nr)
1629 if (!audio.music_available)
1635 void PlaySound(int nr)
1637 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_SOUND);
1640 void PlaySoundStereo(int nr, int stereo_position)
1642 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1645 void PlaySoundLoop(int nr)
1647 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_LOOP);
1650 void PlaySoundMusic(int nr)
1652 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1655 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1657 SoundControl snd_ctrl;
1659 if (!audio.sound_available ||
1660 !audio.sound_enabled ||
1661 audio.sound_deactivated)
1664 if (volume < PSND_MIN_VOLUME)
1665 volume = PSND_MIN_VOLUME;
1666 else if (volume > PSND_MAX_VOLUME)
1667 volume = PSND_MAX_VOLUME;
1669 if (stereo_position < PSND_MAX_LEFT)
1670 stereo_position = PSND_MAX_LEFT;
1671 else if (stereo_position > PSND_MAX_RIGHT)
1672 stereo_position = PSND_MAX_RIGHT;
1674 snd_ctrl.active = TRUE;
1676 snd_ctrl.volume = volume;
1677 snd_ctrl.stereo_position = stereo_position;
1678 snd_ctrl.state = state;
1680 HandleSoundRequest(snd_ctrl);
1683 void FadeMusic(void)
1685 if (!audio.music_available)
1688 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1691 void FadeSound(int nr)
1693 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1699 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1702 void StopMusic(void)
1704 if (!audio.music_available)
1707 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1710 void StopSound(int nr)
1712 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1718 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1721 void StopSoundExt(int nr, int state)
1723 SoundControl snd_ctrl;
1725 if (!audio.sound_available)
1728 snd_ctrl.active = FALSE;
1730 snd_ctrl.state = state;
1732 HandleSoundRequest(snd_ctrl);
1735 ListNode *newListNode()
1737 return checked_calloc(sizeof(ListNode));
1740 void addNodeToList(ListNode **node_first, char *key, void *content)
1742 ListNode *node_new = newListNode();
1745 printf("LIST: adding node with key '%s'\n", key);
1748 node_new->key = getStringCopy(key);
1749 node_new->content = content;
1750 node_new->next = *node_first;
1751 *node_first = node_new;
1754 void deleteNodeFromList(ListNode **node_first, char *key,
1755 void (*destructor_function)(void *))
1757 if (node_first == NULL || *node_first == NULL)
1761 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1762 (*node_first)->key, key);
1765 if (strcmp((*node_first)->key, key) == 0)
1768 printf("[DELETING LIST ENTRY]\n");
1771 free((*node_first)->key);
1772 if (destructor_function)
1773 destructor_function((*node_first)->content);
1774 *node_first = (*node_first)->next;
1777 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1780 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1782 if (node_first == NULL)
1785 if (strcmp(node_first->key, key) == 0)
1788 return getNodeFromKey(node_first->next, key);
1791 int getNumNodes(ListNode *node_first)
1793 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1796 void dumpList(ListNode *node_first)
1798 ListNode *node = node_first;
1802 printf("['%s' (%d)]\n", node->key,
1803 ((SoundInfo *)node->content)->num_references);
1807 printf("[%d nodes]\n", getNumNodes(node_first));
1810 static void LoadSoundsInfo()
1812 char *filename = getCustomSoundConfigFilename();
1813 struct SetupFileList *setup_file_list;
1816 /* always start with reliable default values */
1817 for (i=0; i<num_sounds; i++)
1818 sound_effect[i].filename = NULL;
1820 if (filename == NULL)
1823 if ((setup_file_list = loadSetupFileList(filename)))
1825 for (i=0; i<num_sounds; i++)
1826 sound_effect[i].filename =
1827 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1829 freeSetupFileList(setup_file_list);
1832 for (i=0; i<num_sounds; i++)
1834 printf("'%s' ", sound_effect[i].text);
1835 if (sound_effect[i].filename)
1836 printf("-> '%s'\n", sound_effect[i].filename);
1838 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1844 static void ReloadCustomSounds()
1849 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1855 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
1858 for(i=0; i<num_sounds; i++)
1860 if (sound_effect[i].filename)
1861 LoadSoundToList(sound_effect[i].filename, i);
1863 LoadSoundToList(sound_effect[i].default_filename, i);
1867 printf("list size == %d\n", getNumNodes(SoundFileList));
1871 dumpList(SoundFileList);
1875 static void ReloadCustomMusic()
1878 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1886 void InitReloadSounds(char *set_name)
1888 if (!audio.sound_available)
1891 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1892 ReloadCustomSounds();
1893 #elif defined(AUDIO_UNIX_NATIVE)
1894 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
1898 void InitReloadMusic(char *set_name)
1900 if (!audio.music_available)
1903 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1904 ReloadCustomMusic();
1905 #elif defined(AUDIO_UNIX_NATIVE)
1906 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
1910 void FreeSound(void *ptr)
1912 SoundInfo *sound = (SoundInfo *)ptr;
1917 if (sound->data_ptr)
1919 #if defined(TARGET_SDL)
1920 Mix_FreeChunk(sound->data_ptr);
1921 #elif defined(TARGET_ALLEGRO)
1922 destroy_sample(sound->data_ptr);
1923 #else /* AUDIO_UNIX_NATIVE */
1924 free(sound->data_ptr);
1928 if (sound->source_filename)
1929 free(sound->source_filename);
1934 void FreeMusic(MusicInfo *music)
1939 if (music->data_ptr)
1941 #if defined(TARGET_SDL)
1942 if (music->type == MUS_TYPE_MOD)
1943 Mix_FreeMusic(music->data_ptr);
1945 Mix_FreeChunk(music->data_ptr);
1946 #elif defined(TARGET_ALLEGRO)
1947 destroy_sample(music->data_ptr);
1948 #else /* AUDIO_UNIX_NATIVE */
1949 free(music->data_ptr);
1956 void FreeAllSounds()
1963 printf("%s: FREEING SOUNDS ...\n",
1964 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
1966 for(i=0; i<num_sounds; i++)
1967 deleteSoundEntry(&Sound[i]);
1969 FreeSound(Sound[i]);
1972 printf("%s: FREEING SOUNDS -- DONE\n",
1973 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
1988 for(i=0; i<num_music; i++)
1989 FreeMusic(Music[i]);
1997 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1998 /* ========================================================================= */