1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
25 #if defined(PLATFORM_LINUX)
26 #include <sys/ioctl.h>
27 #include <linux/soundcard.h>
28 #elif defined(PLATFORM_FREEBSD)
29 #include <machine/soundcard.h>
30 #elif defined(PLATFORM_NETBSD)
31 #include <sys/ioctl.h>
32 #include <sys/audioio.h>
33 #elif defined(PLATFORM_HPUX)
34 #include <sys/audio.h>
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME 200
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL 1000
50 #if defined(AUDIO_STREAMING_DSP)
51 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
52 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
55 #define SND_TYPE_NONE 0
56 #define SND_TYPE_WAV 1
58 #define MUS_TYPE_NONE 0
59 #define MUS_TYPE_WAV 1
60 #define MUS_TYPE_MOD 2
62 #define DEVICENAME_DSP "/dev/dsp"
63 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
64 #define DEVICENAME_AUDIO "/dev/audio"
65 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
67 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
68 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
70 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
71 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
74 struct SoundHeader_SUN
77 unsigned long hdr_size;
78 unsigned long data_size;
79 unsigned long encoding;
80 unsigned long sample_rate;
81 unsigned long channels;
84 struct SoundHeader_8SVX
87 unsigned long chunk_size;
92 #if defined(AUDIO_UNIX_NATIVE)
93 struct SoundHeader_WAV
95 unsigned short compression_code;
96 unsigned short num_channels;
97 unsigned long sample_rate;
98 unsigned long bytes_per_second;
99 unsigned short block_align;
100 unsigned short bits_per_sample;
104 struct AudioFormatInfo
106 boolean stereo; /* availability of stereo sound */
107 int format; /* size and endianess of sample data */
108 int sample_rate; /* sample frequency */
109 int fragment_size; /* audio device fragment size in bytes */
114 char *source_filename;
119 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
120 long data_len; /* number of samples, NOT number of bytes */
121 int num_channels; /* mono: 1 channel, stereo: 2 channels */
123 typedef struct SampleInfo SoundInfo;
124 typedef struct SampleInfo MusicInfo;
136 unsigned long playing_starttime;
137 unsigned long playing_pos;
141 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
142 long data_len; /* number of samples, NOT number of bytes */
143 int num_channels; /* mono: 1 channel, stereo: 2 channels */
145 #if defined(TARGET_ALLEGRO)
149 typedef struct SoundControl SoundControl;
151 static struct ArtworkListInfo *sound_info = NULL;
152 static struct ArtworkListInfo *music_info = NULL;
155 static SoundInfo **Sound = NULL;
158 static MusicInfo **Music_NoConf = NULL;
161 static int num_sounds = 0;
164 static int num_music_noconf = 0;
165 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
168 /* ========================================================================= */
169 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
171 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
172 static int mixer_active_channels = 0;
174 #if defined(AUDIO_UNIX_NATIVE)
175 static struct AudioFormatInfo afmt;
177 static void Mixer_Main(void);
178 #if !defined(AUDIO_STREAMING_DSP)
179 static unsigned char linear_to_ulaw(int);
180 static int ulaw_to_linear(unsigned char);
184 static void ReloadCustomSounds();
185 static void ReloadCustomMusic();
186 static void FreeSound(void *);
187 static void FreeMusic(void *);
188 static void FreeAllMusic_NoConf();
190 static SoundInfo *getSoundInfoEntryFromSoundID(int);
191 static MusicInfo *getMusicInfoEntryFromMusicID(int);
194 /* ------------------------------------------------------------------------- */
195 /* functions for native (non-SDL) Unix audio/mixer support */
196 /* ------------------------------------------------------------------------- */
198 #if defined(AUDIO_UNIX_NATIVE)
200 static int OpenAudioDevice(char *audio_device_name)
204 /* check if desired audio device is accessible */
205 if (access(audio_device_name, W_OK) != 0)
208 /* try to open audio device in non-blocking mode */
209 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
210 return audio_device_fd;
212 /* re-open audio device in blocking mode */
213 close(audio_device_fd);
214 audio_device_fd = open(audio_device_name, O_WRONLY);
216 return audio_device_fd;
219 static void CloseAudioDevice(int *audio_device_fd)
221 if (*audio_device_fd == 0)
224 close(*audio_device_fd);
225 *audio_device_fd = -1;
228 static boolean TestAudioDevices(void)
230 static char *audio_device_name[] =
233 DEVICENAME_SOUND_DSP,
236 int audio_device_fd = -1;
239 /* look for available audio devices, starting with preferred ones */
240 for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
241 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
244 if (audio_device_fd < 0)
246 Error(ERR_WARN, "cannot open audio device -- no sound");
250 close(audio_device_fd);
252 audio.device_name = audio_device_name[i];
257 static boolean ForkAudioProcess(void)
259 if (pipe(audio.mixer_pipe) < 0)
261 Error(ERR_WARN, "cannot create pipe -- no sounds");
265 if ((audio.mixer_pid = fork()) < 0)
267 Error(ERR_WARN, "cannot create sound server process -- no sounds");
271 if (audio.mixer_pid == 0) /* we are the child process */
272 audio.mixer_pid = getpid();
275 printf("PID: %d [%s]\n", getpid(),(IS_CHILD_PROCESS() ? "child" : "parent"));
279 if (IS_CHILD_PROCESS())
280 Mixer_Main(); /* this function never returns */
282 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
287 void UnixOpenAudio(void)
289 if (!TestAudioDevices())
292 audio.sound_available = TRUE;
293 audio.sound_enabled = TRUE;
295 #if defined(AUDIO_STREAMING_DSP)
296 audio.music_available = TRUE;
297 audio.loops_available = TRUE;
300 audio.num_channels = NUM_MIXER_CHANNELS;
301 audio.music_channel = MUSIC_CHANNEL;
302 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
305 void UnixCloseAudio(void)
308 close(audio.device_fd);
310 if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
311 kill(audio.mixer_pid, SIGTERM);
315 /* ------------------------------------------------------------------------- */
316 /* functions for platform specific audio device initialization */
317 /* ------------------------------------------------------------------------- */
319 #if defined(AUDIO_LINUX_IOCTL)
320 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
322 /* "ioctl()" expects pointer to 'int' value for stereo flag
323 (boolean is defined as 'char', which will not work here) */
324 unsigned int fragment_spec = 0;
325 int fragment_size_query = -1;
334 /* supported audio format in preferred order */
335 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
336 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
337 { AFMT_U8, AUDIO_FORMAT_U8 },
342 /* determine logarithm (log2) of the fragment size */
343 while ((1 << fragment_spec) < afmt->fragment_size)
346 /* use two fragments (play one fragment, prepare the other);
347 one fragment would result in interrupted audio output, more
348 than two fragments would raise audio output latency to much */
349 fragment_spec |= 0x00020000;
351 /* Example for fragment specification:
352 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
353 - (with stereo the effective buffer size will shrink to 256)
354 => fragment_size = 0x00020009 */
356 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
357 Error(ERR_EXIT_SOUND_SERVER,
358 "cannot set fragment size of audio device -- no sounds");
362 while (formats[i].format_result != -1)
364 unsigned int audio_format = formats[i].format_ioctl;
365 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
367 afmt->format = formats[i].format_result;
372 if (afmt->format == 0) /* no supported audio format found */
373 Error(ERR_EXIT_SOUND_SERVER,
374 "cannot set audio format of audio device -- no sounds");
376 /* try if we can use stereo sound */
378 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
379 afmt->stereo = FALSE;
381 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
382 Error(ERR_EXIT_SOUND_SERVER,
383 "cannot set sample rate of audio device -- no sounds");
385 /* get the real fragmentation size; this should return 512 */
386 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
387 Error(ERR_EXIT_SOUND_SERVER,
388 "cannot get fragment size of audio device -- no sounds");
389 if (fragment_size_query != afmt->fragment_size)
390 Error(ERR_EXIT_SOUND_SERVER,
391 "cannot set fragment size of audio device -- no sounds");
393 #endif /* AUDIO_LINUX_IOCTL */
395 #if defined(PLATFORM_NETBSD)
396 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
399 boolean stereo = TRUE;
401 AUDIO_INITINFO(&a_info);
402 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
403 a_info.play.precision = 8;
404 a_info.play.channels = 2;
405 a_info.play.sample_rate = afmt->sample_rate;
406 a_info.blocksize = afmt->fragment_size;
408 afmt->format = AUDIO_FORMAT_U8;
411 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
413 /* try to disable stereo */
414 a_info.play.channels = 1;
416 afmt->stereo = FALSE;
418 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
419 Error(ERR_EXIT_SOUND_SERVER,
420 "cannot set sample rate of audio device -- no sounds");
423 #endif /* PLATFORM_NETBSD */
425 #if defined(PLATFORM_HPUX)
426 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
428 struct audio_describe ainfo;
431 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
433 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
435 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
436 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
438 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
439 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
441 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
442 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
444 afmt->format = AUDIO_FORMAT_U8;
445 afmt->stereo = FALSE;
446 afmt->sample_rate = 8000;
450 #endif /* PLATFORM_HPUX */
452 static void InitAudioDevice(struct AudioFormatInfo *afmt)
455 afmt->format = AUDIO_FORMAT_UNKNOWN;
456 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
457 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
459 #if defined(AUDIO_LINUX_IOCTL)
460 InitAudioDevice_Linux(afmt);
461 #elif defined(PLATFORM_NETBSD)
462 InitAudioDevice_NetBSD(afmt);
463 #elif defined(PLATFORM_HPUX)
464 InitAudioDevice_HPUX(afmt);
466 /* generic /dev/audio stuff might be placed here */
471 /* ------------------------------------------------------------------------- */
472 /* functions for communication between main process and sound mixer process */
473 /* ------------------------------------------------------------------------- */
475 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
477 if (IS_CHILD_PROCESS())
480 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
482 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
483 audio.sound_available = audio.sound_enabled = FALSE;
488 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
490 if (IS_PARENT_PROCESS())
493 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
494 != sizeof(SoundControl))
495 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
498 static void WriteReloadInfoToPipe(char *set_identifier, int type)
500 SoundControl snd_ctrl;
501 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
502 artwork.mus_current);
503 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
504 unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
505 unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
506 unsigned long str_size4 = strlen(ti->basepath) + 1;
507 unsigned long str_size5 = strlen(ti->fullpath) + 1;
508 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
509 setup.override_level_sounds :
510 setup.override_level_music);
512 if (IS_CHILD_PROCESS())
515 if (leveldir_current == NULL) /* should never happen */
516 Error(ERR_EXIT, "leveldir_current == NULL");
518 memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */
520 snd_ctrl.active = FALSE;
521 snd_ctrl.state = type;
522 snd_ctrl.data_len = strlen(set_identifier) + 1;
524 if (write(audio.mixer_pipe[1], &snd_ctrl,
525 sizeof(snd_ctrl)) < 0 ||
526 write(audio.mixer_pipe[1], set_identifier,
527 snd_ctrl.data_len) < 0 ||
528 write(audio.mixer_pipe[1], &override_level_artwork,
529 sizeof(boolean)) < 0 ||
530 write(audio.mixer_pipe[1], leveldir_current,
531 sizeof(TreeInfo)) < 0 ||
532 write(audio.mixer_pipe[1], ti,
533 sizeof(TreeInfo)) < 0 ||
534 write(audio.mixer_pipe[1], &str_size1,
535 sizeof(unsigned long)) < 0 ||
536 write(audio.mixer_pipe[1], &str_size2,
537 sizeof(unsigned long)) < 0 ||
538 write(audio.mixer_pipe[1], &str_size3,
539 sizeof(unsigned long)) < 0 ||
540 write(audio.mixer_pipe[1], &str_size4,
541 sizeof(unsigned long)) < 0 ||
542 write(audio.mixer_pipe[1], &str_size5,
543 sizeof(unsigned long)) < 0 ||
544 write(audio.mixer_pipe[1], leveldir_current->fullpath,
546 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
548 write(audio.mixer_pipe[1], leveldir_current->music_path,
550 write(audio.mixer_pipe[1], ti->basepath,
552 write(audio.mixer_pipe[1], ti->fullpath,
555 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
556 audio.sound_available = audio.sound_enabled = FALSE;
561 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
563 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
564 &artwork.snd_current : &artwork.mus_current);
565 TreeInfo *ti = *ti_ptr;
566 unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
567 static char *set_identifier = NULL;
568 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
569 &setup.override_level_sounds :
570 &setup.override_level_music);
573 free(set_identifier);
575 set_identifier = checked_malloc(snd_ctrl->data_len);
577 if (leveldir_current == NULL)
578 leveldir_current = checked_calloc(sizeof(TreeInfo));
581 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
582 if (leveldir_current->fullpath != NULL)
583 free(leveldir_current->fullpath);
584 if (leveldir_current->sounds_path != NULL)
585 free(leveldir_current->sounds_path);
586 if (leveldir_current->music_path != NULL)
587 free(leveldir_current->music_path);
588 if (ti->basepath != NULL)
590 if (ti->fullpath != NULL)
593 if (read(audio.mixer_pipe[0], set_identifier,
594 snd_ctrl->data_len) != snd_ctrl->data_len ||
595 read(audio.mixer_pipe[0], override_level_artwork,
596 sizeof(boolean)) != sizeof(boolean) ||
597 read(audio.mixer_pipe[0], leveldir_current,
598 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
599 read(audio.mixer_pipe[0], ti,
600 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
601 read(audio.mixer_pipe[0], &str_size1,
602 sizeof(unsigned long)) != sizeof(unsigned long) ||
603 read(audio.mixer_pipe[0], &str_size2,
604 sizeof(unsigned long)) != sizeof(unsigned long) ||
605 read(audio.mixer_pipe[0], &str_size3,
606 sizeof(unsigned long)) != sizeof(unsigned long) ||
607 read(audio.mixer_pipe[0], &str_size4,
608 sizeof(unsigned long)) != sizeof(unsigned long) ||
609 read(audio.mixer_pipe[0], &str_size5,
610 sizeof(unsigned long)) != sizeof(unsigned long))
611 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
613 leveldir_current->fullpath = checked_calloc(str_size1);
614 leveldir_current->sounds_path = checked_calloc(str_size2);
615 leveldir_current->music_path = checked_calloc(str_size3);
616 ti->basepath = checked_calloc(str_size4);
617 ti->fullpath = checked_calloc(str_size5);
619 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
620 str_size1) != str_size1 ||
621 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
622 str_size2) != str_size2 ||
623 read(audio.mixer_pipe[0], leveldir_current->music_path,
624 str_size3) != str_size3 ||
625 read(audio.mixer_pipe[0], ti->basepath,
626 str_size4) != str_size4 ||
627 read(audio.mixer_pipe[0], ti->fullpath,
628 str_size5) != str_size5)
629 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
631 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
632 artwork.snd_current_identifier = set_identifier;
634 artwork.mus_current_identifier = set_identifier;
637 #endif /* AUDIO_UNIX_NATIVE */
640 /* ------------------------------------------------------------------------- */
641 /* mixer functions */
642 /* ------------------------------------------------------------------------- */
644 void Mixer_InitChannels()
648 for (i = 0; i < audio.num_channels; i++)
649 mixer[i].active = FALSE;
650 mixer_active_channels = 0;
653 static void Mixer_ResetChannelExpiration(int channel)
655 mixer[channel].playing_starttime = Counter();
657 #if defined(TARGET_SDL)
658 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
659 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
663 static boolean Mixer_ChannelExpired(int channel)
665 if (!mixer[channel].active)
668 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
669 DelayReached(&mixer[channel].playing_starttime,
670 SOUND_LOOP_EXPIRATION_TIME))
673 #if defined(TARGET_SDL)
675 if (!Mix_Playing(channel))
678 #elif defined(TARGET_ALLEGRO)
680 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
681 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
683 /* sound sample has completed playing or was completely faded out */
684 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
687 #endif /* TARGET_ALLEGRO */
692 static boolean Mixer_AllocateChannel(int channel)
694 #if defined(TARGET_ALLEGRO)
695 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
696 if (mixer[channel].voice < 0)
703 static void Mixer_SetChannelProperties(int channel)
705 #if defined(TARGET_SDL)
706 Mix_Volume(channel, mixer[channel].volume);
707 Mix_SetPanning(channel,
708 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
709 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
710 #elif defined(TARGET_ALLEGRO)
711 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
712 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
716 static void Mixer_StartChannel(int channel)
718 #if defined(TARGET_SDL)
719 Mix_PlayChannel(channel, mixer[channel].data_ptr,
720 IS_LOOP(mixer[channel]) ? -1 : 0);
721 #elif defined(TARGET_ALLEGRO)
722 if (IS_LOOP(mixer[channel]))
723 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
725 voice_start(mixer[channel].voice);
729 static void Mixer_PlayChannel(int channel)
731 /* start with inactive channel in case something goes wrong */
732 mixer[channel].active = FALSE;
734 if (mixer[channel].type != MUS_TYPE_WAV)
737 if (!Mixer_AllocateChannel(channel))
740 Mixer_SetChannelProperties(channel);
741 Mixer_StartChannel(channel);
743 Mixer_ResetChannelExpiration(channel);
745 mixer[channel].playing_pos = 0;
746 mixer[channel].active = TRUE;
747 mixer_active_channels++;
750 static void Mixer_PlayMusicChannel()
752 Mixer_PlayChannel(audio.music_channel);
754 #if defined(TARGET_SDL)
755 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
757 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
758 this looks like a bug in the SDL_mixer library */
759 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
760 Mix_VolumeMusic(SOUND_MAX_VOLUME);
765 static void Mixer_StopChannel(int channel)
767 if (!mixer[channel].active)
770 #if defined(TARGET_SDL)
771 Mix_HaltChannel(channel);
772 #elif defined(TARGET_ALLEGRO)
773 voice_set_volume(mixer[channel].voice, 0);
774 deallocate_voice(mixer[channel].voice);
777 mixer[channel].active = FALSE;
778 mixer_active_channels--;
781 static void Mixer_StopMusicChannel()
783 Mixer_StopChannel(audio.music_channel);
785 #if defined(TARGET_SDL)
790 static void Mixer_FadeChannel(int channel)
792 if (!mixer[channel].active)
795 mixer[channel].state |= SND_CTRL_FADE;
797 #if defined(TARGET_SDL)
798 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
799 #elif defined(TARGET_ALLEGRO)
800 if (voice_check(mixer[channel].voice))
801 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
805 static void Mixer_FadeMusicChannel()
807 Mixer_FadeChannel(audio.music_channel);
809 #if defined(TARGET_SDL)
810 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
814 static void Mixer_UnFadeChannel(int channel)
816 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
819 mixer[channel].state &= ~SND_CTRL_FADE;
820 mixer[channel].volume = SOUND_MAX_VOLUME;
822 #if defined(TARGET_SDL)
823 Mix_ExpireChannel(channel, -1);
824 Mix_Volume(channel, mixer[channel].volume);
825 #elif defined(TARGET_ALLEGRO)
826 voice_stop_volumeramp(mixer[channel].voice);
827 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
828 mixer[channel].volume);
832 static void Mixer_InsertSound(SoundControl snd_ctrl)
836 int num_sounds = getSoundListSize();
837 int num_music = getMusicListSize();
840 if (IS_MUSIC(snd_ctrl))
841 printf("NEW MUSIC %d ARRIVED [%d/%d] [%d ACTIVE CHANNELS]\n",
842 snd_ctrl.nr, num_music, num_music_noconf, mixer_active_channels);
844 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
845 snd_ctrl.nr, num_sounds, mixer_active_channels);
849 /* !!! TEST ONLY !!! */
850 if (IS_MUSIC(snd_ctrl))
855 if (IS_MUSIC(snd_ctrl))
857 if (snd_ctrl.nr >= num_music) /* invalid music */
860 if (snd_ctrl.nr < 0) /* undefined music */
862 if (num_music_noconf == 0) /* no fallback music available */
865 snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
866 snd_info = Music_NoConf[snd_ctrl.nr];
869 snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
873 if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
876 snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
880 if (snd_ctrl.nr >= (IS_MUSIC(snd_ctrl) ? num_music : num_sounds))
884 if (IS_MUSIC(snd_ctrl))
886 if (num_music_noconf == 0)
889 snd_ctrl.nr = snd_ctrl.nr % num_music_noconf;
891 else if (snd_ctrl.nr >= num_sounds)
897 snd_info = (IS_MUSIC(snd_ctrl) ? getMusicInfoEntryFromMusicID(snd_ctrl.nr) :
898 getSoundInfoEntryFromSoundID(snd_ctrl.nr));
900 snd_info = (IS_MUSIC(snd_ctrl) ? Music_NoConf[snd_ctrl.nr] :
901 getSoundInfoEntryFromSoundID(snd_ctrl.nr));
905 if (snd_info == NULL)
908 /* copy sound sample and format information */
909 snd_ctrl.type = snd_info->type;
910 snd_ctrl.format = snd_info->format;
911 snd_ctrl.data_ptr = snd_info->data_ptr;
912 snd_ctrl.data_len = snd_info->data_len;
913 snd_ctrl.num_channels = snd_info->num_channels;
915 /* play music samples on a dedicated music channel */
916 if (IS_MUSIC(snd_ctrl))
919 printf("::: slot %d, ptr 0x%08x\n", snd_ctrl.nr, snd_ctrl.data_ptr);
922 Mixer_StopMusicChannel();
924 mixer[audio.music_channel] = snd_ctrl;
925 Mixer_PlayMusicChannel();
930 /* check if (and how often) this sound sample is already playing */
931 for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
932 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
936 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
939 /* reset expiration delay for already playing loop sounds */
940 if (k > 0 && IS_LOOP(snd_ctrl))
942 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
944 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
947 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
950 if (IS_FADING(mixer[i]))
951 Mixer_UnFadeChannel(i);
953 /* restore settings like volume and stereo position */
954 mixer[i].volume = snd_ctrl.volume;
955 mixer[i].stereo_position = snd_ctrl.stereo_position;
957 Mixer_SetChannelProperties(i);
958 Mixer_ResetChannelExpiration(i);
961 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
962 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
971 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
974 /* don't play sound more than n times simultaneously (with n == 2 for now) */
977 unsigned long playing_current = Counter();
978 int longest = 0, longest_nr = audio.first_sound_channel;
980 /* look for oldest equal sound */
981 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
983 int playing_time = playing_current - mixer[i].playing_starttime;
986 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
989 actual = 1000 * playing_time / mixer[i].data_len;
991 if (actual >= longest)
998 Mixer_StopChannel(longest_nr);
1001 /* If all (non-music) channels are active, stop the channel that has
1002 played its sound sample most completely (in percent of the sample
1003 length). As we cannot currently get the actual playing position
1004 of the channel's sound sample when compiling with the SDL mixer
1005 library, we use the current playing time (in milliseconds) instead. */
1008 /* channel allocation sanity check -- should not be needed */
1009 if (mixer_active_channels ==
1010 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
1012 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1014 if (!mixer[i].active)
1016 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
1017 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
1019 mixer_active_channels--;
1025 if (mixer_active_channels ==
1026 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
1028 unsigned long playing_current = Counter();
1029 int longest = 0, longest_nr = audio.first_sound_channel;
1033 /* print some debugging information about audio channel usage */
1034 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1036 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
1037 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
1042 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1044 int playing_time = playing_current - mixer[i].playing_starttime;
1045 int actual = 1000 * playing_time / mixer[i].data_len;
1047 if (!IS_LOOP(mixer[i]) && actual > longest)
1054 Mixer_StopChannel(longest_nr);
1057 /* add the new sound to the mixer */
1058 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1061 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
1064 if (!mixer[i].active)
1067 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
1070 #if defined(AUDIO_UNIX_NATIVE)
1071 if (snd_info->data_len == 0)
1073 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1077 mixer[i] = snd_ctrl;
1078 Mixer_PlayChannel(i);
1085 static void HandleSoundRequest(SoundControl snd_ctrl)
1089 #if defined(AUDIO_UNIX_NATIVE)
1090 if (IS_PARENT_PROCESS())
1092 SendSoundControlToMixerProcess(&snd_ctrl);
1097 /* deactivate channels that have expired since the last request */
1098 for (i = 0; i < audio.num_channels; i++)
1099 if (mixer[i].active && Mixer_ChannelExpired(i))
1100 Mixer_StopChannel(i);
1102 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1104 Mixer_StopMusicChannel();
1105 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1106 Mixer_StopChannel(i);
1108 #if defined(AUDIO_UNIX_NATIVE)
1109 CloseAudioDevice(&audio.device_fd);
1110 ReadReloadInfoFromPipe(&snd_ctrl);
1113 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1114 ReloadCustomSounds();
1116 ReloadCustomMusic();
1118 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1120 if (IS_MUSIC(snd_ctrl))
1122 Mixer_FadeMusicChannel();
1126 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1127 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1128 Mixer_FadeChannel(i);
1130 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1132 if (IS_MUSIC(snd_ctrl))
1134 Mixer_StopMusicChannel();
1138 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1139 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1140 Mixer_StopChannel(i);
1142 #if defined(AUDIO_UNIX_NATIVE)
1143 if (!mixer_active_channels)
1144 CloseAudioDevice(&audio.device_fd);
1147 else if (snd_ctrl.active) /* add new sound to mixer */
1149 Mixer_InsertSound(snd_ctrl);
1153 void StartMixer(void)
1158 SDL_version compile_version;
1159 const SDL_version *link_version;
1160 MIX_VERSION(&compile_version);
1161 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1162 compile_version.major,
1163 compile_version.minor,
1164 compile_version.patch);
1165 link_version = Mix_Linked_Version();
1166 printf("running with SDL_mixer version: %d.%d.%d\n",
1167 link_version->major,
1168 link_version->minor,
1169 link_version->patch);
1172 if (!audio.sound_available)
1175 /* initialize stereo position conversion information */
1176 for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1178 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1180 #if defined(AUDIO_UNIX_NATIVE)
1181 if (!ForkAudioProcess())
1182 audio.sound_available = FALSE;
1186 #if defined(AUDIO_UNIX_NATIVE)
1188 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1189 int sample_pos, int sample_size,
1190 short *buffer_base_ptr, int buffer_pos,
1191 int num_output_channels)
1193 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1194 int num_channels = snd_ctrl->num_channels;
1195 int stepsize = num_channels;
1196 int output_stepsize = num_output_channels;
1199 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1201 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1203 for (i = 0; i < num_output_channels; i++)
1205 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1207 for (j = 0; j < sample_size; j++)
1208 buffer_ptr[output_stepsize * j + i] =
1209 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1212 else /* AUDIO_FORMAT_S16 */
1214 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1216 for (i = 0; i < num_output_channels; i++)
1218 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1220 for (j = 0; j < sample_size; j++)
1221 buffer_ptr[output_stepsize * j + i] =
1222 sample_ptr[stepsize * j + offset];
1227 #if defined(AUDIO_STREAMING_DSP)
1228 static void Mixer_Main_DSP()
1230 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1231 static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1232 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1236 int max_sample_size;
1237 int num_output_channels;
1240 if (!mixer_active_channels)
1243 if (audio.device_fd < 0)
1245 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1248 InitAudioDevice(&afmt);
1251 stereo = afmt.stereo;
1252 fragment_size = afmt.fragment_size;
1253 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1254 num_output_channels = (stereo ? 2 : 1);
1255 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1257 /* first clear the last premixing buffer */
1258 memset(premix_last_buffer, 0,
1259 max_sample_size * num_output_channels * sizeof(long));
1261 for (i = 0; i < audio.num_channels; i++)
1268 if (!mixer[i].active)
1271 if (Mixer_ChannelExpired(i))
1273 Mixer_StopChannel(i);
1277 /* pointer, lenght and actual playing position of sound sample */
1278 sample_ptr = mixer[i].data_ptr;
1279 sample_len = mixer[i].data_len;
1280 sample_pos = mixer[i].playing_pos;
1281 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1282 mixer[i].playing_pos += sample_size;
1284 /* copy original sample to first mixing buffer */
1285 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1286 premix_first_buffer, 0, num_output_channels);
1288 /* are we about to restart a looping sound? */
1289 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1291 while (sample_size < max_sample_size)
1293 int restarted_sample_size =
1294 MIN(max_sample_size - sample_size, sample_len);
1296 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1297 premix_first_buffer, sample_size,
1298 num_output_channels);
1300 mixer[i].playing_pos = restarted_sample_size;
1301 sample_size += restarted_sample_size;
1305 /* decrease volume if sound is fading out */
1306 if (IS_FADING(mixer[i]) &&
1307 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1308 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1310 /* adjust volume of actual sound sample */
1311 if (mixer[i].volume != SOUND_MAX_VOLUME)
1312 for (j = 0; j < sample_size * num_output_channels; j++)
1313 premix_first_buffer[j] =
1314 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1316 /* adjust left and right channel volume due to stereo sound position */
1319 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1320 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1322 for (j = 0; j < sample_size; j++)
1324 premix_first_buffer[2 * j + 0] =
1325 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1326 premix_first_buffer[2 * j + 1] =
1327 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1331 /* fill the last mixing buffer with stereo or mono sound */
1332 for (j = 0; j < sample_size * num_output_channels; j++)
1333 premix_last_buffer[j] += premix_first_buffer[j];
1335 /* delete completed sound entries from the mixer */
1336 if (mixer[i].playing_pos >= mixer[i].data_len)
1338 if (IS_LOOP(mixer[i]))
1339 mixer[i].playing_pos = 0;
1341 Mixer_StopChannel(i);
1343 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1344 Mixer_StopChannel(i);
1347 /* prepare final playing buffer according to system audio format */
1348 for (i = 0; i < max_sample_size * num_output_channels; i++)
1350 /* cut off at 17 bit value */
1351 if (premix_last_buffer[i] < -65535)
1352 premix_last_buffer[i] = -65535;
1353 else if (premix_last_buffer[i] > 65535)
1354 premix_last_buffer[i] = 65535;
1356 /* shift to 16 bit value */
1357 premix_last_buffer[i] >>= 1;
1359 if (afmt.format & AUDIO_FORMAT_U8)
1361 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1363 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1365 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1366 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1368 else /* big endian */
1370 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1371 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1375 /* finally play the sound fragment */
1376 write(audio.device_fd, playing_buffer, fragment_size);
1378 if (!mixer_active_channels)
1379 CloseAudioDevice(&audio.device_fd);
1382 #else /* !AUDIO_STREAMING_DSP */
1384 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1386 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1387 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1388 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1389 int num_output_channels = 1;
1398 /* pointer, lenght and actual playing position of sound sample */
1399 sample_ptr = mixer[i].data_ptr;
1400 sample_len = mixer[i].data_len;
1401 sample_pos = mixer[i].playing_pos;
1402 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1403 mixer[i].playing_pos += sample_size;
1405 /* copy original sample to first mixing buffer */
1406 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1407 premix_first_buffer, 0, num_output_channels);
1409 /* adjust volume of actual sound sample */
1410 if (mixer[i].volume != SOUND_MAX_VOLUME)
1411 for (j = 0; j < sample_size; j++)
1412 premix_first_buffer[j] =
1413 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1415 /* might be needed for u-law /dev/audio */
1417 for (j = 0; j < sample_size; j++)
1419 linear_to_ulaw(premix_first_buffer[j]);
1422 /* delete completed sound entries from the mixer */
1423 if (mixer[i].playing_pos >= mixer[i].data_len)
1424 Mixer_StopChannel(i);
1426 for (i = 0; i < sample_size; i++)
1427 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1429 /* finally play the sound fragment */
1430 write(audio.device_fd, playing_buffer, sample_size);
1434 #endif /* !AUDIO_STREAMING_DSP */
1438 SoundControl snd_ctrl;
1441 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1443 Mixer_InitChannels();
1445 #if defined(PLATFORM_HPUX)
1446 InitAudioDevice(&afmt);
1449 FD_ZERO(&mixer_fdset);
1450 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1452 while (1) /* wait for sound playing commands from client */
1454 struct timeval delay = { 0, 0 };
1456 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1457 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1458 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1461 ReadSoundControlFromMainProcess(&snd_ctrl);
1463 HandleSoundRequest(snd_ctrl);
1465 #if defined(AUDIO_STREAMING_DSP)
1467 while (mixer_active_channels &&
1468 select(audio.mixer_pipe[0] + 1,
1469 &mixer_fdset, NULL, NULL, &delay) < 1)
1471 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1476 #else /* !AUDIO_STREAMING_DSP */
1478 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1479 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1482 InitAudioDevice(&afmt);
1487 while (mixer_active_channels &&
1488 select(audio.mixer_pipe[0] + 1,
1489 &mixer_fdset, NULL, NULL, &delay) < 1)
1491 int wait_percent = 90; /* wait 90% of the real playing time */
1494 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1496 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1500 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1503 CloseAudioDevice(&audio.device_fd);
1505 Mixer_InitChannels(); /* remove all sounds from mixer */
1507 #endif /* !AUDIO_STREAMING_DSP */
1510 #endif /* AUDIO_UNIX_NATIVE */
1513 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1515 /* these two are stolen from "sox"... :) */
1518 ** This routine converts from linear to ulaw.
1520 ** Craig Reese: IDA/Supercomputing Research Center
1521 ** Joe Campbell: Department of Defense
1522 ** 29 September 1989
1525 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1526 ** 2) "A New Digital Technique for Implementation of Any
1527 ** Continuous PCM Companding Law," Villeret, Michel,
1528 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1529 ** 1973, pg. 11.12-11.17
1530 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1531 ** for Analog-to_Digital Conversion Techniques,"
1534 ** Input: Signed 16 bit linear sample
1535 ** Output: 8 bit ulaw sample
1538 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1539 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1542 static unsigned char linear_to_ulaw(int sample)
1544 static int exp_lut[256] =
1546 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1547 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1548 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1549 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1550 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1551 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1552 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1553 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1554 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1555 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1556 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1557 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1558 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1559 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1560 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1561 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1564 int sign, exponent, mantissa;
1565 unsigned char ulawbyte;
1567 /* Get the sample into sign-magnitude. */
1568 sign = (sample >> 8) & 0x80; /* set aside the sign */
1570 sample = -sample; /* get magnitude */
1572 sample = CLIP; /* clip the magnitude */
1574 /* Convert from 16 bit linear to ulaw. */
1575 sample = sample + BIAS;
1576 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1577 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1578 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1581 ulawbyte = 0x02; /* optional CCITT trap */
1588 ** This routine converts from ulaw to 16 bit linear.
1590 ** Craig Reese: IDA/Supercomputing Research Center
1591 ** 29 September 1989
1594 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1595 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1596 ** for Analog-to_Digital Conversion Techniques,"
1599 ** Input: 8 bit ulaw sample
1600 ** Output: signed 16 bit linear sample
1603 static int ulaw_to_linear(unsigned char ulawbyte)
1605 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1606 int sign, exponent, mantissa, sample;
1608 ulawbyte = ~ ulawbyte;
1609 sign = ( ulawbyte & 0x80 );
1610 exponent = ( ulawbyte >> 4 ) & 0x07;
1611 mantissa = ulawbyte & 0x0F;
1612 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1618 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1621 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1622 /* ========================================================================= */
1623 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1625 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1626 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1628 static void *Load_WAV(char *filename)
1630 SoundInfo *snd_info;
1631 #if defined(AUDIO_UNIX_NATIVE)
1632 struct SoundHeader_WAV header;
1634 byte sound_header_buffer[WAV_HEADER_SIZE];
1637 char chunk_name[CHUNK_ID_LEN + 1];
1643 if (!audio.sound_available)
1647 printf("loading WAV file '%s'\n", filename);
1650 snd_info = checked_calloc(sizeof(SoundInfo));
1652 #if defined(TARGET_SDL)
1654 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1656 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1661 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1663 #elif defined(TARGET_ALLEGRO)
1665 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1667 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1672 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1674 #else /* AUDIO_UNIX_NATIVE */
1676 if ((file = fopen(filename, MODE_READ)) == NULL)
1678 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1683 /* read chunk id "RIFF" */
1684 getFileChunkLE(file, chunk_name, &chunk_size);
1685 if (strcmp(chunk_name, "RIFF") != 0)
1687 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1693 /* read "RIFF" type id "WAVE" */
1694 getFileChunkLE(file, chunk_name, NULL);
1695 if (strcmp(chunk_name, "WAVE") != 0)
1697 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1703 while (getFileChunkLE(file, chunk_name, &chunk_size))
1705 if (strcmp(chunk_name, "fmt ") == 0)
1707 if (chunk_size < WAV_HEADER_SIZE)
1709 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1715 header.compression_code = getFile16BitLE(file);
1716 header.num_channels = getFile16BitLE(file);
1717 header.sample_rate = getFile32BitLE(file);
1718 header.bytes_per_second = getFile32BitLE(file);
1719 header.block_align = getFile16BitLE(file);
1720 header.bits_per_sample = getFile16BitLE(file);
1722 if (chunk_size > WAV_HEADER_SIZE)
1723 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1725 if (header.compression_code != 1)
1727 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1728 filename, header.compression_code);
1734 if (header.num_channels != 1 &&
1735 header.num_channels != 2)
1737 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1738 filename, header.num_channels);
1744 if (header.bits_per_sample != 8 &&
1745 header.bits_per_sample != 16)
1747 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1748 filename, header.bits_per_sample);
1754 /* warn, but accept wrong sample rate (may be only slightly different) */
1755 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1756 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1757 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1760 printf("WAV file: '%s'\n", filename);
1761 printf(" Compression code: %d'\n", header.compression_code);
1762 printf(" Number of channels: %d'\n", header.num_channels);
1763 printf(" Sample rate: %ld'\n", header.sample_rate);
1764 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1765 printf(" Block align: %d'\n", header.block_align);
1766 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1769 else if (strcmp(chunk_name, "data") == 0)
1771 data_byte_len = chunk_size;
1773 snd_info->data_len = data_byte_len;
1774 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1776 /* read sound data */
1777 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1780 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1782 free(snd_info->data_ptr);
1787 /* check for odd number of data bytes (data chunk is word aligned) */
1788 if ((data_byte_len % 2) == 1)
1789 ReadUnusedBytesFromFile(file, 1);
1791 else /* unknown chunk -- ignore */
1792 ReadUnusedBytesFromFile(file, chunk_size);
1797 if (snd_info->data_ptr == NULL)
1799 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1804 if (header.bits_per_sample == 8)
1805 snd_info->format = AUDIO_FORMAT_U8;
1806 else /* header.bits_per_sample == 16 */
1808 snd_info->format = AUDIO_FORMAT_S16;
1809 snd_info->data_len /= 2; /* correct number of samples */
1812 snd_info->num_channels = header.num_channels;
1813 if (header.num_channels == 2)
1814 snd_info->data_len /= 2; /* correct number of samples */
1817 if (header.num_channels == 1) /* convert mono sound to stereo */
1819 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1820 void *sample_ptr = snd_info->data_ptr;
1821 int sample_size = snd_info->data_len;
1824 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1825 for (i = 0; i < sample_size; i++)
1827 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1828 else /* AUDIO_FORMAT_S16 */
1829 for (i = 0; i < sample_size; i++)
1831 ((short *)sample_ptr)[i];
1835 #endif /* AUDIO_UNIX_NATIVE */
1837 snd_info->type = SND_TYPE_WAV;
1838 snd_info->source_filename = getStringCopy(filename);
1843 static void *Load_MOD(char *filename)
1845 #if defined(TARGET_SDL)
1846 MusicInfo *mod_info;
1848 if (!audio.sound_available)
1851 mod_info = checked_calloc(sizeof(MusicInfo));
1853 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1855 Error(ERR_WARN, "cannot read music file '%s'", filename);
1860 mod_info->type = MUS_TYPE_MOD;
1861 mod_info->source_filename = getStringCopy(filename);
1869 static void *Load_WAV_or_MOD(char *filename)
1871 if (FileIsSound(filename))
1872 return Load_WAV(filename);
1873 else if (FileIsMusic(filename))
1874 return Load_MOD(filename);
1879 void LoadCustomMusic_NoConf(void)
1881 static boolean draw_init_text = TRUE; /* only draw at startup */
1882 static char *last_music_directory = NULL;
1883 char *music_directory = getCustomMusicDirectory();
1885 struct dirent *dir_entry;
1886 int num_music = getMusicListSize();
1890 for (ii = 0; ii < num_music; ii++)
1892 struct FileInfo *music = getMusicListEntry(ii);
1893 printf("sound process: music %d: '%s'\n", ii, music->filename);
1897 if (!audio.sound_available)
1900 if (last_music_directory != NULL &&
1901 strcmp(last_music_directory, music_directory) == 0)
1902 return; /* old and new music directory are the same */
1904 if (last_music_directory != NULL)
1905 free(last_music_directory);
1906 last_music_directory = getStringCopy(music_directory);
1908 FreeAllMusic_NoConf();
1910 if ((dir = opendir(music_directory)) == NULL)
1912 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1913 audio.music_available = FALSE;
1918 DrawInitText("Loading music:", 120, FC_GREEN);
1920 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1922 char *basename = dir_entry->d_name;
1923 char *filename = NULL;
1924 MusicInfo *mus_info = NULL;
1925 boolean music_already_used = FALSE;
1928 for (i = 0; i < num_music; i++)
1930 struct FileInfo *music = getMusicListEntry(i);
1933 printf("sound process: '%s'\n", music->filename);
1936 if (strcmp(basename, music->filename) == 0)
1938 music_already_used = TRUE;
1943 if (music_already_used)
1947 if (FileIsSound(basename) || FileIsMusic(basename))
1948 printf("DEBUG: loading music '%s' ...\n", basename);
1952 DrawInitText(basename, 150, FC_YELLOW);
1954 filename = getPath2(music_directory, basename);
1957 if (FileIsMusic(basename))
1958 mus_info = Load_WAV_or_MOD(filename);
1960 if (FileIsSound(basename))
1961 mus_info = Load_WAV(filename);
1962 else if (FileIsMusic(basename))
1963 mus_info = Load_MOD(filename);
1971 Music_NoConf = checked_realloc(Music_NoConf,
1972 num_music_noconf * sizeof(MusicInfo *));
1973 Music_NoConf[num_music_noconf - 1] = mus_info;
1979 draw_init_text = FALSE;
1981 if (num_music_noconf == 0)
1982 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1986 int getSoundListSize()
1988 return (sound_info->num_file_list_entries +
1989 sound_info->num_dynamic_file_list_entries);
1992 int getMusicListSize()
1994 return (music_info->num_file_list_entries +
1995 music_info->num_dynamic_file_list_entries);
1998 struct FileInfo *getSoundListEntry(int pos)
2000 int num_list_entries = sound_info->num_file_list_entries;
2001 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
2003 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
2004 &sound_info->dynamic_file_list[list_pos]);
2007 struct FileInfo *getMusicListEntry(int pos)
2009 int num_list_entries = music_info->num_file_list_entries;
2010 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
2012 return (pos < num_list_entries ? &music_info->file_list[list_pos] :
2013 &music_info->dynamic_file_list[list_pos]);
2016 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
2018 int num_list_entries = sound_info->num_file_list_entries;
2019 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
2020 SoundInfo **snd_info =
2021 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
2022 sound_info->dynamic_artwork_list);
2024 return snd_info[list_pos];
2027 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
2029 int num_list_entries = music_info->num_file_list_entries;
2030 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
2031 MusicInfo **mus_info =
2032 (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
2033 music_info->dynamic_artwork_list);
2035 return mus_info[list_pos];
2038 int getSoundListPropertyMappingSize()
2040 return sound_info->num_property_mapping_entries;
2043 int getMusicListPropertyMappingSize()
2045 return music_info->num_property_mapping_entries;
2048 struct PropertyMapping *getSoundListPropertyMapping()
2050 return sound_info->property_mapping;
2053 struct PropertyMapping *getMusicListPropertyMapping()
2055 return music_info->property_mapping;
2058 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
2059 struct ConfigInfo *config_suffix_list,
2060 char **base_prefixes, char **ext1_suffixes,
2061 char **ext2_suffixes, char **ext3_suffixes,
2062 char **ignore_tokens)
2066 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
2067 sound_info->type = ARTWORK_TYPE_SOUNDS;
2069 /* ---------- initialize file list and suffix lists ---------- */
2071 sound_info->num_file_list_entries = num_file_list_entries;
2072 sound_info->num_dynamic_file_list_entries = 0;
2074 sound_info->file_list =
2075 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2076 num_file_list_entries);
2077 sound_info->dynamic_file_list = NULL;
2079 sound_info->num_suffix_list_entries = 0;
2080 for (i = 0; config_suffix_list[i].token != NULL; i++)
2081 sound_info->num_suffix_list_entries++;
2083 sound_info->suffix_list = config_suffix_list;
2085 /* ---------- initialize base prefix and suffixes lists ---------- */
2087 sound_info->num_base_prefixes = 0;
2088 for (i = 0; base_prefixes[i] != NULL; i++)
2089 sound_info->num_base_prefixes++;
2091 sound_info->num_ext1_suffixes = 0;
2092 for (i = 0; ext1_suffixes[i] != NULL; i++)
2093 sound_info->num_ext1_suffixes++;
2095 sound_info->num_ext2_suffixes = 0;
2096 for (i = 0; ext2_suffixes[i] != NULL; i++)
2097 sound_info->num_ext2_suffixes++;
2099 sound_info->num_ext3_suffixes = 0;
2100 for (i = 0; ext3_suffixes[i] != NULL; i++)
2101 sound_info->num_ext3_suffixes++;
2103 sound_info->num_ignore_tokens = 0;
2104 for (i = 0; ignore_tokens[i] != NULL; i++)
2105 sound_info->num_ignore_tokens++;
2107 sound_info->base_prefixes = base_prefixes;
2108 sound_info->ext1_suffixes = ext1_suffixes;
2109 sound_info->ext2_suffixes = ext2_suffixes;
2110 sound_info->ext3_suffixes = ext3_suffixes;
2111 sound_info->ignore_tokens = ignore_tokens;
2113 sound_info->num_property_mapping_entries = 0;
2115 sound_info->property_mapping = NULL;
2117 /* ---------- initialize artwork reference and content lists ---------- */
2119 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
2121 sound_info->artwork_list =
2122 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
2123 sound_info->dynamic_artwork_list = NULL;
2125 sound_info->content_list = NULL;
2127 /* ---------- initialize artwork loading/freeing functions ---------- */
2129 sound_info->load_artwork = Load_WAV;
2130 sound_info->free_artwork = FreeSound;
2133 num_sounds = sound_info->num_file_list_entries;
2134 Sound = (SoundInfo **)sound_info->artwork_list;
2138 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
2139 struct ConfigInfo *config_suffix_list,
2140 char **base_prefixes, char **ext1_suffixes,
2141 char **ext2_suffixes, char **ext3_suffixes,
2142 char **ignore_tokens)
2146 music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2147 music_info->type = ARTWORK_TYPE_MUSIC;
2149 /* ---------- initialize file list and suffix lists ---------- */
2151 music_info->num_file_list_entries = num_file_list_entries;
2152 music_info->num_dynamic_file_list_entries = 0;
2154 music_info->file_list =
2155 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2156 num_file_list_entries);
2157 music_info->dynamic_file_list = NULL;
2159 music_info->num_suffix_list_entries = 0;
2160 for (i = 0; config_suffix_list[i].token != NULL; i++)
2161 music_info->num_suffix_list_entries++;
2163 music_info->suffix_list = config_suffix_list;
2165 /* ---------- initialize base prefix and suffixes lists ---------- */
2167 music_info->num_base_prefixes = 0;
2168 for (i = 0; base_prefixes[i] != NULL; i++)
2169 music_info->num_base_prefixes++;
2171 music_info->num_ext1_suffixes = 0;
2172 for (i = 0; ext1_suffixes[i] != NULL; i++)
2173 music_info->num_ext1_suffixes++;
2175 music_info->num_ext2_suffixes = 0;
2176 for (i = 0; ext2_suffixes[i] != NULL; i++)
2177 music_info->num_ext2_suffixes++;
2179 music_info->num_ext3_suffixes = 0;
2180 for (i = 0; ext3_suffixes[i] != NULL; i++)
2181 music_info->num_ext3_suffixes++;
2183 music_info->num_ignore_tokens = 0;
2184 for (i = 0; ignore_tokens[i] != NULL; i++)
2185 music_info->num_ignore_tokens++;
2187 music_info->base_prefixes = base_prefixes;
2188 music_info->ext1_suffixes = ext1_suffixes;
2189 music_info->ext2_suffixes = ext2_suffixes;
2190 music_info->ext3_suffixes = ext3_suffixes;
2191 music_info->ignore_tokens = ignore_tokens;
2193 music_info->num_property_mapping_entries = 0;
2195 music_info->property_mapping = NULL;
2197 /* ---------- initialize artwork reference and content lists ---------- */
2199 music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2201 music_info->artwork_list =
2202 checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2203 music_info->dynamic_artwork_list = NULL;
2205 music_info->content_list = NULL;
2207 /* ---------- initialize artwork loading/freeing functions ---------- */
2209 music_info->load_artwork = Load_WAV_or_MOD;
2210 music_info->free_artwork = FreeMusic;
2213 void PlayMusic(int nr)
2215 if (!audio.music_available)
2221 void PlaySound(int nr)
2223 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2226 void PlaySoundStereo(int nr, int stereo_position)
2228 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2231 void PlaySoundLoop(int nr)
2233 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2236 void PlaySoundMusic(int nr)
2238 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2241 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2243 SoundControl snd_ctrl;
2245 if (!audio.sound_available ||
2246 !audio.sound_enabled ||
2247 audio.sound_deactivated)
2250 if (volume < SOUND_MIN_VOLUME)
2251 volume = SOUND_MIN_VOLUME;
2252 else if (volume > SOUND_MAX_VOLUME)
2253 volume = SOUND_MAX_VOLUME;
2255 if (stereo_position < SOUND_MAX_LEFT)
2256 stereo_position = SOUND_MAX_LEFT;
2257 else if (stereo_position > SOUND_MAX_RIGHT)
2258 stereo_position = SOUND_MAX_RIGHT;
2260 memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */
2262 snd_ctrl.active = TRUE;
2264 snd_ctrl.volume = volume;
2265 snd_ctrl.stereo_position = stereo_position;
2266 snd_ctrl.state = state;
2268 HandleSoundRequest(snd_ctrl);
2271 void FadeMusic(void)
2273 if (!audio.music_available)
2276 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2279 void FadeSound(int nr)
2281 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2286 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2289 void FadeSoundsAndMusic()
2295 void StopMusic(void)
2297 if (!audio.music_available)
2300 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2303 void StopSound(int nr)
2305 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2311 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2314 void StopSoundExt(int nr, int state)
2316 SoundControl snd_ctrl;
2318 if (!audio.sound_available)
2321 memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */
2323 snd_ctrl.active = FALSE;
2325 snd_ctrl.state = state;
2327 HandleSoundRequest(snd_ctrl);
2330 static void ReloadCustomSounds()
2333 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2336 LoadArtworkConfig(sound_info);
2337 ReloadCustomArtworkList(sound_info);
2340 num_sounds = getSoundListSize();
2344 static void ReloadCustomMusic()
2347 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
2350 LoadArtworkConfig(music_info);
2351 ReloadCustomArtworkList(music_info);
2354 /* load all music files from directory not defined in "musicinfo.conf" */
2355 LoadCustomMusic_NoConf();
2359 void InitReloadCustomSounds(char *set_identifier)
2361 if (!audio.sound_available)
2364 #if defined(AUDIO_UNIX_NATIVE)
2365 LoadArtworkConfig(sound_info); /* also load config on sound client */
2366 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2368 ReloadCustomSounds();
2372 void InitReloadCustomMusic(char *set_identifier)
2374 if (!audio.music_available)
2377 #if defined(AUDIO_UNIX_NATIVE)
2378 LoadArtworkConfig(music_info); /* also load config on sound client */
2379 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2381 ReloadCustomMusic();
2385 void FreeSound(void *ptr)
2387 SoundInfo *sound = (SoundInfo *)ptr;
2392 if (sound->data_ptr)
2394 #if defined(TARGET_SDL)
2395 Mix_FreeChunk(sound->data_ptr);
2396 #elif defined(TARGET_ALLEGRO)
2397 destroy_sample(sound->data_ptr);
2398 #else /* AUDIO_UNIX_NATIVE */
2399 free(sound->data_ptr);
2403 if (sound->source_filename)
2404 free(sound->source_filename);
2409 void FreeMusic(void *ptr)
2411 MusicInfo *music = (MusicInfo *)ptr;
2416 if (music->data_ptr)
2418 #if defined(TARGET_SDL)
2419 if (music->type == MUS_TYPE_MOD)
2420 Mix_FreeMusic(music->data_ptr);
2422 Mix_FreeChunk(music->data_ptr);
2423 #elif defined(TARGET_ALLEGRO)
2424 destroy_sample(music->data_ptr);
2425 #else /* AUDIO_UNIX_NATIVE */
2426 free(music->data_ptr);
2433 static void FreeAllMusic_NoConf()
2437 if (Music_NoConf == NULL)
2440 for (i = 0; i < num_music_noconf; i++)
2441 FreeMusic(Music_NoConf[i]);
2445 Music_NoConf = NULL;
2446 num_music_noconf = 0;
2449 void FreeAllSounds()
2451 FreeCustomArtworkLists(sound_info);
2456 FreeCustomArtworkLists(music_info);
2457 FreeAllMusic_NoConf();
2460 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2461 /* ========================================================================= */