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);
572 checked_free(set_identifier);
574 set_identifier = checked_malloc(snd_ctrl->data_len);
576 if (leveldir_current == NULL)
577 leveldir_current = checked_calloc(sizeof(TreeInfo));
580 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
582 checked_free(leveldir_current->fullpath);
583 checked_free(leveldir_current->sounds_path);
584 checked_free(leveldir_current->music_path);
585 checked_free(ti->basepath);
586 checked_free(ti->fullpath);
588 if (read(audio.mixer_pipe[0], set_identifier,
589 snd_ctrl->data_len) != snd_ctrl->data_len ||
590 read(audio.mixer_pipe[0], override_level_artwork,
591 sizeof(boolean)) != sizeof(boolean) ||
592 read(audio.mixer_pipe[0], leveldir_current,
593 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
594 read(audio.mixer_pipe[0], ti,
595 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
596 read(audio.mixer_pipe[0], &str_size1,
597 sizeof(unsigned long)) != sizeof(unsigned long) ||
598 read(audio.mixer_pipe[0], &str_size2,
599 sizeof(unsigned long)) != sizeof(unsigned long) ||
600 read(audio.mixer_pipe[0], &str_size3,
601 sizeof(unsigned long)) != sizeof(unsigned long) ||
602 read(audio.mixer_pipe[0], &str_size4,
603 sizeof(unsigned long)) != sizeof(unsigned long) ||
604 read(audio.mixer_pipe[0], &str_size5,
605 sizeof(unsigned long)) != sizeof(unsigned long))
606 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
608 leveldir_current->fullpath = checked_calloc(str_size1);
609 leveldir_current->sounds_path = checked_calloc(str_size2);
610 leveldir_current->music_path = checked_calloc(str_size3);
611 ti->basepath = checked_calloc(str_size4);
612 ti->fullpath = checked_calloc(str_size5);
614 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
615 str_size1) != str_size1 ||
616 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
617 str_size2) != str_size2 ||
618 read(audio.mixer_pipe[0], leveldir_current->music_path,
619 str_size3) != str_size3 ||
620 read(audio.mixer_pipe[0], ti->basepath,
621 str_size4) != str_size4 ||
622 read(audio.mixer_pipe[0], ti->fullpath,
623 str_size5) != str_size5)
624 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
626 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
627 artwork.snd_current_identifier = set_identifier;
629 artwork.mus_current_identifier = set_identifier;
632 #endif /* AUDIO_UNIX_NATIVE */
635 /* ------------------------------------------------------------------------- */
636 /* mixer functions */
637 /* ------------------------------------------------------------------------- */
639 void Mixer_InitChannels()
643 for (i = 0; i < audio.num_channels; i++)
644 mixer[i].active = FALSE;
645 mixer_active_channels = 0;
648 static void Mixer_ResetChannelExpiration(int channel)
650 mixer[channel].playing_starttime = Counter();
652 #if defined(TARGET_SDL)
653 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
654 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
658 static boolean Mixer_ChannelExpired(int channel)
660 if (!mixer[channel].active)
663 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
664 DelayReached(&mixer[channel].playing_starttime,
665 SOUND_LOOP_EXPIRATION_TIME))
668 #if defined(TARGET_SDL)
670 if (!Mix_Playing(channel))
673 #elif defined(TARGET_ALLEGRO)
675 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
676 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
678 /* sound sample has completed playing or was completely faded out */
679 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
682 #endif /* TARGET_ALLEGRO */
687 static boolean Mixer_AllocateChannel(int channel)
689 #if defined(TARGET_ALLEGRO)
690 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
691 if (mixer[channel].voice < 0)
698 static void Mixer_SetChannelProperties(int channel)
700 #if defined(TARGET_SDL)
701 Mix_Volume(channel, mixer[channel].volume);
702 Mix_SetPanning(channel,
703 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
704 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
705 #elif defined(TARGET_ALLEGRO)
706 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
707 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
711 static void Mixer_StartChannel(int channel)
713 #if defined(TARGET_SDL)
714 Mix_PlayChannel(channel, mixer[channel].data_ptr,
715 IS_LOOP(mixer[channel]) ? -1 : 0);
716 #elif defined(TARGET_ALLEGRO)
717 if (IS_LOOP(mixer[channel]))
718 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
720 voice_start(mixer[channel].voice);
724 static void Mixer_PlayChannel(int channel)
726 /* start with inactive channel in case something goes wrong */
727 mixer[channel].active = FALSE;
729 if (mixer[channel].type != MUS_TYPE_WAV)
732 if (!Mixer_AllocateChannel(channel))
735 Mixer_SetChannelProperties(channel);
736 Mixer_StartChannel(channel);
738 Mixer_ResetChannelExpiration(channel);
740 mixer[channel].playing_pos = 0;
741 mixer[channel].active = TRUE;
742 mixer_active_channels++;
745 static void Mixer_PlayMusicChannel()
747 Mixer_PlayChannel(audio.music_channel);
749 #if defined(TARGET_SDL)
750 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
752 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
753 this looks like a bug in the SDL_mixer library */
754 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
755 Mix_VolumeMusic(SOUND_MAX_VOLUME);
760 static void Mixer_StopChannel(int channel)
762 if (!mixer[channel].active)
765 #if defined(TARGET_SDL)
766 Mix_HaltChannel(channel);
767 #elif defined(TARGET_ALLEGRO)
768 voice_set_volume(mixer[channel].voice, 0);
769 deallocate_voice(mixer[channel].voice);
772 mixer[channel].active = FALSE;
773 mixer_active_channels--;
776 static void Mixer_StopMusicChannel()
778 Mixer_StopChannel(audio.music_channel);
780 #if defined(TARGET_SDL)
785 static void Mixer_FadeChannel(int channel)
787 if (!mixer[channel].active)
790 mixer[channel].state |= SND_CTRL_FADE;
792 #if defined(TARGET_SDL)
793 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
794 #elif defined(TARGET_ALLEGRO)
795 if (voice_check(mixer[channel].voice))
796 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
800 static void Mixer_FadeMusicChannel()
802 Mixer_FadeChannel(audio.music_channel);
804 #if defined(TARGET_SDL)
805 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
809 static void Mixer_UnFadeChannel(int channel)
811 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
814 mixer[channel].state &= ~SND_CTRL_FADE;
815 mixer[channel].volume = SOUND_MAX_VOLUME;
817 #if defined(TARGET_SDL)
818 Mix_ExpireChannel(channel, -1);
819 Mix_Volume(channel, mixer[channel].volume);
820 #elif defined(TARGET_ALLEGRO)
821 voice_stop_volumeramp(mixer[channel].voice);
822 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
823 mixer[channel].volume);
827 static void Mixer_InsertSound(SoundControl snd_ctrl)
831 int num_sounds = getSoundListSize();
832 int num_music = getMusicListSize();
835 if (IS_MUSIC(snd_ctrl))
836 printf("NEW MUSIC %d ARRIVED [%d/%d] [%d ACTIVE CHANNELS]\n",
837 snd_ctrl.nr, num_music, num_music_noconf, mixer_active_channels);
839 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
840 snd_ctrl.nr, num_sounds, mixer_active_channels);
844 /* !!! TEST ONLY !!! */
845 if (IS_MUSIC(snd_ctrl))
850 if (IS_MUSIC(snd_ctrl))
852 if (snd_ctrl.nr >= num_music) /* invalid music */
855 if (snd_ctrl.nr < 0) /* undefined music */
857 if (num_music_noconf == 0) /* no fallback music available */
860 snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
861 snd_info = Music_NoConf[snd_ctrl.nr];
864 snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
868 if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
871 snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
875 if (snd_ctrl.nr >= (IS_MUSIC(snd_ctrl) ? num_music : num_sounds))
879 if (IS_MUSIC(snd_ctrl))
881 if (num_music_noconf == 0)
884 snd_ctrl.nr = snd_ctrl.nr % num_music_noconf;
886 else if (snd_ctrl.nr >= num_sounds)
892 snd_info = (IS_MUSIC(snd_ctrl) ? getMusicInfoEntryFromMusicID(snd_ctrl.nr) :
893 getSoundInfoEntryFromSoundID(snd_ctrl.nr));
895 snd_info = (IS_MUSIC(snd_ctrl) ? Music_NoConf[snd_ctrl.nr] :
896 getSoundInfoEntryFromSoundID(snd_ctrl.nr));
900 if (snd_info == NULL)
903 /* copy sound sample and format information */
904 snd_ctrl.type = snd_info->type;
905 snd_ctrl.format = snd_info->format;
906 snd_ctrl.data_ptr = snd_info->data_ptr;
907 snd_ctrl.data_len = snd_info->data_len;
908 snd_ctrl.num_channels = snd_info->num_channels;
910 /* play music samples on a dedicated music channel */
911 if (IS_MUSIC(snd_ctrl))
914 printf("::: slot %d, ptr 0x%08x\n", snd_ctrl.nr, snd_ctrl.data_ptr);
917 Mixer_StopMusicChannel();
919 mixer[audio.music_channel] = snd_ctrl;
920 Mixer_PlayMusicChannel();
925 /* check if (and how often) this sound sample is already playing */
926 for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
927 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
931 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
934 /* reset expiration delay for already playing loop sounds */
935 if (k > 0 && IS_LOOP(snd_ctrl))
937 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
939 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
942 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
945 if (IS_FADING(mixer[i]))
946 Mixer_UnFadeChannel(i);
948 /* restore settings like volume and stereo position */
949 mixer[i].volume = snd_ctrl.volume;
950 mixer[i].stereo_position = snd_ctrl.stereo_position;
952 Mixer_SetChannelProperties(i);
953 Mixer_ResetChannelExpiration(i);
956 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
957 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
966 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
969 /* don't play sound more than n times simultaneously (with n == 2 for now) */
972 unsigned long playing_current = Counter();
973 int longest = 0, longest_nr = audio.first_sound_channel;
975 /* look for oldest equal sound */
976 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
978 int playing_time = playing_current - mixer[i].playing_starttime;
981 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
984 actual = 1000 * playing_time / mixer[i].data_len;
986 if (actual >= longest)
993 Mixer_StopChannel(longest_nr);
996 /* If all (non-music) channels are active, stop the channel that has
997 played its sound sample most completely (in percent of the sample
998 length). As we cannot currently get the actual playing position
999 of the channel's sound sample when compiling with the SDL mixer
1000 library, we use the current playing time (in milliseconds) instead. */
1003 /* channel allocation sanity check -- should not be needed */
1004 if (mixer_active_channels ==
1005 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
1007 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1009 if (!mixer[i].active)
1011 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
1012 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
1014 mixer_active_channels--;
1020 if (mixer_active_channels ==
1021 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
1023 unsigned long playing_current = Counter();
1024 int longest = 0, longest_nr = audio.first_sound_channel;
1028 /* print some debugging information about audio channel usage */
1029 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1031 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
1032 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
1037 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1039 int playing_time = playing_current - mixer[i].playing_starttime;
1040 int actual = 1000 * playing_time / mixer[i].data_len;
1042 if (!IS_LOOP(mixer[i]) && actual > longest)
1049 Mixer_StopChannel(longest_nr);
1052 /* add the new sound to the mixer */
1053 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1056 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
1059 if (!mixer[i].active)
1062 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
1065 #if defined(AUDIO_UNIX_NATIVE)
1066 if (snd_info->data_len == 0)
1068 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1072 mixer[i] = snd_ctrl;
1073 Mixer_PlayChannel(i);
1080 static void HandleSoundRequest(SoundControl snd_ctrl)
1084 #if defined(AUDIO_UNIX_NATIVE)
1085 if (IS_PARENT_PROCESS())
1087 SendSoundControlToMixerProcess(&snd_ctrl);
1092 /* deactivate channels that have expired since the last request */
1093 for (i = 0; i < audio.num_channels; i++)
1094 if (mixer[i].active && Mixer_ChannelExpired(i))
1095 Mixer_StopChannel(i);
1097 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1099 Mixer_StopMusicChannel();
1100 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1101 Mixer_StopChannel(i);
1103 #if defined(AUDIO_UNIX_NATIVE)
1104 CloseAudioDevice(&audio.device_fd);
1105 ReadReloadInfoFromPipe(&snd_ctrl);
1108 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1109 ReloadCustomSounds();
1111 ReloadCustomMusic();
1113 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1115 if (IS_MUSIC(snd_ctrl))
1117 Mixer_FadeMusicChannel();
1121 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1122 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1123 Mixer_FadeChannel(i);
1125 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1127 if (IS_MUSIC(snd_ctrl))
1129 Mixer_StopMusicChannel();
1133 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1134 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1135 Mixer_StopChannel(i);
1137 #if defined(AUDIO_UNIX_NATIVE)
1138 if (!mixer_active_channels)
1139 CloseAudioDevice(&audio.device_fd);
1142 else if (snd_ctrl.active) /* add new sound to mixer */
1144 Mixer_InsertSound(snd_ctrl);
1148 void StartMixer(void)
1153 SDL_version compile_version;
1154 const SDL_version *link_version;
1155 MIX_VERSION(&compile_version);
1156 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1157 compile_version.major,
1158 compile_version.minor,
1159 compile_version.patch);
1160 link_version = Mix_Linked_Version();
1161 printf("running with SDL_mixer version: %d.%d.%d\n",
1162 link_version->major,
1163 link_version->minor,
1164 link_version->patch);
1167 if (!audio.sound_available)
1170 /* initialize stereo position conversion information */
1171 for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1173 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1175 #if defined(AUDIO_UNIX_NATIVE)
1176 if (!ForkAudioProcess())
1177 audio.sound_available = FALSE;
1181 #if defined(AUDIO_UNIX_NATIVE)
1183 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1184 int sample_pos, int sample_size,
1185 short *buffer_base_ptr, int buffer_pos,
1186 int num_output_channels)
1188 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1189 int num_channels = snd_ctrl->num_channels;
1190 int stepsize = num_channels;
1191 int output_stepsize = num_output_channels;
1194 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1196 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1198 for (i = 0; i < num_output_channels; i++)
1200 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1202 for (j = 0; j < sample_size; j++)
1203 buffer_ptr[output_stepsize * j + i] =
1204 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1207 else /* AUDIO_FORMAT_S16 */
1209 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1211 for (i = 0; i < num_output_channels; i++)
1213 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1215 for (j = 0; j < sample_size; j++)
1216 buffer_ptr[output_stepsize * j + i] =
1217 sample_ptr[stepsize * j + offset];
1222 #if defined(AUDIO_STREAMING_DSP)
1223 static void Mixer_Main_DSP()
1225 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1226 static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1227 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1231 int max_sample_size;
1232 int num_output_channels;
1235 if (!mixer_active_channels)
1238 if (audio.device_fd < 0)
1240 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1243 InitAudioDevice(&afmt);
1246 stereo = afmt.stereo;
1247 fragment_size = afmt.fragment_size;
1248 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1249 num_output_channels = (stereo ? 2 : 1);
1250 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1252 /* first clear the last premixing buffer */
1253 memset(premix_last_buffer, 0,
1254 max_sample_size * num_output_channels * sizeof(long));
1256 for (i = 0; i < audio.num_channels; i++)
1263 if (!mixer[i].active)
1266 if (Mixer_ChannelExpired(i))
1268 Mixer_StopChannel(i);
1272 /* pointer, lenght and actual playing position of sound sample */
1273 sample_ptr = mixer[i].data_ptr;
1274 sample_len = mixer[i].data_len;
1275 sample_pos = mixer[i].playing_pos;
1276 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1277 mixer[i].playing_pos += sample_size;
1279 /* copy original sample to first mixing buffer */
1280 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1281 premix_first_buffer, 0, num_output_channels);
1283 /* are we about to restart a looping sound? */
1284 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1286 while (sample_size < max_sample_size)
1288 int restarted_sample_size =
1289 MIN(max_sample_size - sample_size, sample_len);
1291 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1292 premix_first_buffer, sample_size,
1293 num_output_channels);
1295 mixer[i].playing_pos = restarted_sample_size;
1296 sample_size += restarted_sample_size;
1300 /* decrease volume if sound is fading out */
1301 if (IS_FADING(mixer[i]) &&
1302 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1303 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1305 /* adjust volume of actual sound sample */
1306 if (mixer[i].volume != SOUND_MAX_VOLUME)
1307 for (j = 0; j < sample_size * num_output_channels; j++)
1308 premix_first_buffer[j] =
1309 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1311 /* adjust left and right channel volume due to stereo sound position */
1314 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1315 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1317 for (j = 0; j < sample_size; j++)
1319 premix_first_buffer[2 * j + 0] =
1320 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1321 premix_first_buffer[2 * j + 1] =
1322 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1326 /* fill the last mixing buffer with stereo or mono sound */
1327 for (j = 0; j < sample_size * num_output_channels; j++)
1328 premix_last_buffer[j] += premix_first_buffer[j];
1330 /* delete completed sound entries from the mixer */
1331 if (mixer[i].playing_pos >= mixer[i].data_len)
1333 if (IS_LOOP(mixer[i]))
1334 mixer[i].playing_pos = 0;
1336 Mixer_StopChannel(i);
1338 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1339 Mixer_StopChannel(i);
1342 /* prepare final playing buffer according to system audio format */
1343 for (i = 0; i < max_sample_size * num_output_channels; i++)
1345 /* cut off at 17 bit value */
1346 if (premix_last_buffer[i] < -65535)
1347 premix_last_buffer[i] = -65535;
1348 else if (premix_last_buffer[i] > 65535)
1349 premix_last_buffer[i] = 65535;
1351 /* shift to 16 bit value */
1352 premix_last_buffer[i] >>= 1;
1354 if (afmt.format & AUDIO_FORMAT_U8)
1356 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1358 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1360 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1361 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1363 else /* big endian */
1365 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1366 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1370 /* finally play the sound fragment */
1371 write(audio.device_fd, playing_buffer, fragment_size);
1373 if (!mixer_active_channels)
1374 CloseAudioDevice(&audio.device_fd);
1377 #else /* !AUDIO_STREAMING_DSP */
1379 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1381 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1382 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1383 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1384 int num_output_channels = 1;
1393 /* pointer, lenght and actual playing position of sound sample */
1394 sample_ptr = mixer[i].data_ptr;
1395 sample_len = mixer[i].data_len;
1396 sample_pos = mixer[i].playing_pos;
1397 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1398 mixer[i].playing_pos += sample_size;
1400 /* copy original sample to first mixing buffer */
1401 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1402 premix_first_buffer, 0, num_output_channels);
1404 /* adjust volume of actual sound sample */
1405 if (mixer[i].volume != SOUND_MAX_VOLUME)
1406 for (j = 0; j < sample_size; j++)
1407 premix_first_buffer[j] =
1408 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1410 /* might be needed for u-law /dev/audio */
1412 for (j = 0; j < sample_size; j++)
1414 linear_to_ulaw(premix_first_buffer[j]);
1417 /* delete completed sound entries from the mixer */
1418 if (mixer[i].playing_pos >= mixer[i].data_len)
1419 Mixer_StopChannel(i);
1421 for (i = 0; i < sample_size; i++)
1422 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1424 /* finally play the sound fragment */
1425 write(audio.device_fd, playing_buffer, sample_size);
1429 #endif /* !AUDIO_STREAMING_DSP */
1433 SoundControl snd_ctrl;
1436 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1438 Mixer_InitChannels();
1440 #if defined(PLATFORM_HPUX)
1441 InitAudioDevice(&afmt);
1444 FD_ZERO(&mixer_fdset);
1445 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1447 while (1) /* wait for sound playing commands from client */
1449 struct timeval delay = { 0, 0 };
1451 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1452 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1453 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1456 ReadSoundControlFromMainProcess(&snd_ctrl);
1458 HandleSoundRequest(snd_ctrl);
1460 #if defined(AUDIO_STREAMING_DSP)
1462 while (mixer_active_channels &&
1463 select(audio.mixer_pipe[0] + 1,
1464 &mixer_fdset, NULL, NULL, &delay) < 1)
1466 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1471 #else /* !AUDIO_STREAMING_DSP */
1473 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1474 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1477 InitAudioDevice(&afmt);
1482 while (mixer_active_channels &&
1483 select(audio.mixer_pipe[0] + 1,
1484 &mixer_fdset, NULL, NULL, &delay) < 1)
1486 int wait_percent = 90; /* wait 90% of the real playing time */
1489 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1491 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1495 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1498 CloseAudioDevice(&audio.device_fd);
1500 Mixer_InitChannels(); /* remove all sounds from mixer */
1502 #endif /* !AUDIO_STREAMING_DSP */
1505 #endif /* AUDIO_UNIX_NATIVE */
1508 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1510 /* these two are stolen from "sox"... :) */
1513 ** This routine converts from linear to ulaw.
1515 ** Craig Reese: IDA/Supercomputing Research Center
1516 ** Joe Campbell: Department of Defense
1517 ** 29 September 1989
1520 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1521 ** 2) "A New Digital Technique for Implementation of Any
1522 ** Continuous PCM Companding Law," Villeret, Michel,
1523 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1524 ** 1973, pg. 11.12-11.17
1525 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1526 ** for Analog-to_Digital Conversion Techniques,"
1529 ** Input: Signed 16 bit linear sample
1530 ** Output: 8 bit ulaw sample
1533 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1534 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1537 static unsigned char linear_to_ulaw(int sample)
1539 static int exp_lut[256] =
1541 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1542 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1543 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1544 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1545 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1546 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1547 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1548 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1549 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1550 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1551 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1552 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1553 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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
1559 int sign, exponent, mantissa;
1560 unsigned char ulawbyte;
1562 /* Get the sample into sign-magnitude. */
1563 sign = (sample >> 8) & 0x80; /* set aside the sign */
1565 sample = -sample; /* get magnitude */
1567 sample = CLIP; /* clip the magnitude */
1569 /* Convert from 16 bit linear to ulaw. */
1570 sample = sample + BIAS;
1571 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1572 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1573 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1576 ulawbyte = 0x02; /* optional CCITT trap */
1583 ** This routine converts from ulaw to 16 bit linear.
1585 ** Craig Reese: IDA/Supercomputing Research Center
1586 ** 29 September 1989
1589 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1590 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1591 ** for Analog-to_Digital Conversion Techniques,"
1594 ** Input: 8 bit ulaw sample
1595 ** Output: signed 16 bit linear sample
1598 static int ulaw_to_linear(unsigned char ulawbyte)
1600 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1601 int sign, exponent, mantissa, sample;
1603 ulawbyte = ~ ulawbyte;
1604 sign = ( ulawbyte & 0x80 );
1605 exponent = ( ulawbyte >> 4 ) & 0x07;
1606 mantissa = ulawbyte & 0x0F;
1607 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1613 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1616 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1617 /* ========================================================================= */
1618 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1620 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1621 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1623 static void *Load_WAV(char *filename)
1625 SoundInfo *snd_info;
1626 #if defined(AUDIO_UNIX_NATIVE)
1627 struct SoundHeader_WAV header;
1629 byte sound_header_buffer[WAV_HEADER_SIZE];
1632 char chunk_name[CHUNK_ID_LEN + 1];
1638 if (!audio.sound_available)
1642 printf("loading WAV file '%s'\n", filename);
1645 snd_info = checked_calloc(sizeof(SoundInfo));
1647 #if defined(TARGET_SDL)
1649 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1651 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1656 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1658 #elif defined(TARGET_ALLEGRO)
1660 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1662 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1667 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1669 #else /* AUDIO_UNIX_NATIVE */
1671 if ((file = fopen(filename, MODE_READ)) == NULL)
1673 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1678 /* read chunk id "RIFF" */
1679 getFileChunkLE(file, chunk_name, &chunk_size);
1680 if (strcmp(chunk_name, "RIFF") != 0)
1682 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1688 /* read "RIFF" type id "WAVE" */
1689 getFileChunkLE(file, chunk_name, NULL);
1690 if (strcmp(chunk_name, "WAVE") != 0)
1692 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1698 while (getFileChunkLE(file, chunk_name, &chunk_size))
1700 if (strcmp(chunk_name, "fmt ") == 0)
1702 if (chunk_size < WAV_HEADER_SIZE)
1704 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1710 header.compression_code = getFile16BitLE(file);
1711 header.num_channels = getFile16BitLE(file);
1712 header.sample_rate = getFile32BitLE(file);
1713 header.bytes_per_second = getFile32BitLE(file);
1714 header.block_align = getFile16BitLE(file);
1715 header.bits_per_sample = getFile16BitLE(file);
1717 if (chunk_size > WAV_HEADER_SIZE)
1718 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1720 if (header.compression_code != 1)
1722 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1723 filename, header.compression_code);
1729 if (header.num_channels != 1 &&
1730 header.num_channels != 2)
1732 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1733 filename, header.num_channels);
1739 if (header.bits_per_sample != 8 &&
1740 header.bits_per_sample != 16)
1742 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1743 filename, header.bits_per_sample);
1749 /* warn, but accept wrong sample rate (may be only slightly different) */
1750 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1751 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1752 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1755 printf("WAV file: '%s'\n", filename);
1756 printf(" Compression code: %d'\n", header.compression_code);
1757 printf(" Number of channels: %d'\n", header.num_channels);
1758 printf(" Sample rate: %ld'\n", header.sample_rate);
1759 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1760 printf(" Block align: %d'\n", header.block_align);
1761 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1764 else if (strcmp(chunk_name, "data") == 0)
1766 data_byte_len = chunk_size;
1768 snd_info->data_len = data_byte_len;
1769 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1771 /* read sound data */
1772 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1775 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1777 free(snd_info->data_ptr);
1782 /* check for odd number of data bytes (data chunk is word aligned) */
1783 if ((data_byte_len % 2) == 1)
1784 ReadUnusedBytesFromFile(file, 1);
1786 else /* unknown chunk -- ignore */
1787 ReadUnusedBytesFromFile(file, chunk_size);
1792 if (snd_info->data_ptr == NULL)
1794 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1799 if (header.bits_per_sample == 8)
1800 snd_info->format = AUDIO_FORMAT_U8;
1801 else /* header.bits_per_sample == 16 */
1803 snd_info->format = AUDIO_FORMAT_S16;
1804 snd_info->data_len /= 2; /* correct number of samples */
1807 snd_info->num_channels = header.num_channels;
1808 if (header.num_channels == 2)
1809 snd_info->data_len /= 2; /* correct number of samples */
1812 if (header.num_channels == 1) /* convert mono sound to stereo */
1814 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1815 void *sample_ptr = snd_info->data_ptr;
1816 int sample_size = snd_info->data_len;
1819 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1820 for (i = 0; i < sample_size; i++)
1822 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1823 else /* AUDIO_FORMAT_S16 */
1824 for (i = 0; i < sample_size; i++)
1826 ((short *)sample_ptr)[i];
1830 #endif /* AUDIO_UNIX_NATIVE */
1832 snd_info->type = SND_TYPE_WAV;
1833 snd_info->source_filename = getStringCopy(filename);
1838 static void *Load_MOD(char *filename)
1840 #if defined(TARGET_SDL)
1841 MusicInfo *mod_info;
1843 if (!audio.sound_available)
1846 mod_info = checked_calloc(sizeof(MusicInfo));
1848 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1850 Error(ERR_WARN, "cannot read music file '%s'", filename);
1855 mod_info->type = MUS_TYPE_MOD;
1856 mod_info->source_filename = getStringCopy(filename);
1864 static void *Load_WAV_or_MOD(char *filename)
1866 if (FileIsSound(filename))
1867 return Load_WAV(filename);
1868 else if (FileIsMusic(filename))
1869 return Load_MOD(filename);
1874 void LoadCustomMusic_NoConf(void)
1876 static boolean draw_init_text = TRUE; /* only draw at startup */
1877 static char *last_music_directory = NULL;
1878 char *music_directory = getCustomMusicDirectory();
1880 struct dirent *dir_entry;
1881 int num_music = getMusicListSize();
1883 if (!audio.sound_available)
1886 if (last_music_directory != NULL &&
1887 strcmp(last_music_directory, music_directory) == 0)
1888 return; /* old and new music directory are the same */
1890 if (last_music_directory != NULL)
1891 free(last_music_directory);
1892 last_music_directory = getStringCopy(music_directory);
1894 FreeAllMusic_NoConf();
1896 if ((dir = opendir(music_directory)) == NULL)
1898 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1899 audio.music_available = FALSE;
1904 DrawInitText("Loading music:", 120, FC_GREEN);
1906 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1908 char *basename = dir_entry->d_name;
1909 char *filename = NULL;
1910 MusicInfo *mus_info = NULL;
1911 boolean music_already_used = FALSE;
1914 /* skip all music files that are configured in music config file */
1915 for (i = 0; i < num_music; i++)
1917 struct FileInfo *music = getMusicListEntry(i);
1919 if (strcmp(basename, music->filename) == 0)
1921 music_already_used = TRUE;
1926 if (music_already_used)
1930 if (FileIsSound(basename) || FileIsMusic(basename))
1931 printf("DEBUG: loading music '%s' ...\n", basename);
1935 DrawInitText(basename, 150, FC_YELLOW);
1937 filename = getPath2(music_directory, basename);
1940 if (FileIsMusic(basename))
1941 mus_info = Load_WAV_or_MOD(filename);
1943 if (FileIsSound(basename))
1944 mus_info = Load_WAV(filename);
1945 else if (FileIsMusic(basename))
1946 mus_info = Load_MOD(filename);
1954 Music_NoConf = checked_realloc(Music_NoConf,
1955 num_music_noconf * sizeof(MusicInfo *));
1956 Music_NoConf[num_music_noconf - 1] = mus_info;
1962 draw_init_text = FALSE;
1965 int getSoundListSize()
1967 return (sound_info->num_file_list_entries +
1968 sound_info->num_dynamic_file_list_entries);
1971 int getMusicListSize()
1973 return (music_info->num_file_list_entries +
1974 music_info->num_dynamic_file_list_entries);
1977 struct FileInfo *getSoundListEntry(int pos)
1979 int num_list_entries = sound_info->num_file_list_entries;
1980 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1982 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1983 &sound_info->dynamic_file_list[list_pos]);
1986 struct FileInfo *getMusicListEntry(int pos)
1988 int num_list_entries = music_info->num_file_list_entries;
1989 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1991 return (pos < num_list_entries ? &music_info->file_list[list_pos] :
1992 &music_info->dynamic_file_list[list_pos]);
1995 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1997 int num_list_entries = sound_info->num_file_list_entries;
1998 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1999 SoundInfo **snd_info =
2000 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
2001 sound_info->dynamic_artwork_list);
2003 return snd_info[list_pos];
2006 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
2008 int num_list_entries = music_info->num_file_list_entries;
2009 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
2010 MusicInfo **mus_info =
2011 (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
2012 music_info->dynamic_artwork_list);
2014 return mus_info[list_pos];
2017 int getSoundListPropertyMappingSize()
2019 return sound_info->num_property_mapping_entries;
2022 int getMusicListPropertyMappingSize()
2024 return music_info->num_property_mapping_entries;
2027 struct PropertyMapping *getSoundListPropertyMapping()
2029 return sound_info->property_mapping;
2032 struct PropertyMapping *getMusicListPropertyMapping()
2034 return music_info->property_mapping;
2037 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
2038 struct ConfigTypeInfo *config_suffix_list,
2039 char **base_prefixes, char **ext1_suffixes,
2040 char **ext2_suffixes, char **ext3_suffixes,
2041 char **ignore_tokens)
2045 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
2046 sound_info->type = ARTWORK_TYPE_SOUNDS;
2048 /* ---------- initialize file list and suffix lists ---------- */
2050 sound_info->num_file_list_entries = num_file_list_entries;
2051 sound_info->num_dynamic_file_list_entries = 0;
2053 sound_info->file_list =
2054 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2055 num_file_list_entries);
2056 sound_info->dynamic_file_list = NULL;
2058 sound_info->num_suffix_list_entries = 0;
2059 for (i = 0; config_suffix_list[i].token != NULL; i++)
2060 sound_info->num_suffix_list_entries++;
2062 sound_info->suffix_list = config_suffix_list;
2064 /* ---------- initialize base prefix and suffixes lists ---------- */
2066 sound_info->num_base_prefixes = 0;
2067 for (i = 0; base_prefixes[i] != NULL; i++)
2068 sound_info->num_base_prefixes++;
2070 sound_info->num_ext1_suffixes = 0;
2071 for (i = 0; ext1_suffixes[i] != NULL; i++)
2072 sound_info->num_ext1_suffixes++;
2074 sound_info->num_ext2_suffixes = 0;
2075 for (i = 0; ext2_suffixes[i] != NULL; i++)
2076 sound_info->num_ext2_suffixes++;
2078 sound_info->num_ext3_suffixes = 0;
2079 for (i = 0; ext3_suffixes[i] != NULL; i++)
2080 sound_info->num_ext3_suffixes++;
2082 sound_info->num_ignore_tokens = 0;
2083 for (i = 0; ignore_tokens[i] != NULL; i++)
2084 sound_info->num_ignore_tokens++;
2086 sound_info->base_prefixes = base_prefixes;
2087 sound_info->ext1_suffixes = ext1_suffixes;
2088 sound_info->ext2_suffixes = ext2_suffixes;
2089 sound_info->ext3_suffixes = ext3_suffixes;
2090 sound_info->ignore_tokens = ignore_tokens;
2092 sound_info->num_property_mapping_entries = 0;
2094 sound_info->property_mapping = NULL;
2096 /* ---------- initialize artwork reference and content lists ---------- */
2098 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
2100 sound_info->artwork_list =
2101 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
2102 sound_info->dynamic_artwork_list = NULL;
2104 sound_info->content_list = NULL;
2106 /* ---------- initialize artwork loading/freeing functions ---------- */
2108 sound_info->load_artwork = Load_WAV;
2109 sound_info->free_artwork = FreeSound;
2112 num_sounds = sound_info->num_file_list_entries;
2113 Sound = (SoundInfo **)sound_info->artwork_list;
2117 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
2118 struct ConfigTypeInfo *config_suffix_list,
2119 char **base_prefixes, char **ext1_suffixes,
2120 char **ext2_suffixes, char **ext3_suffixes,
2121 char **ignore_tokens)
2125 music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2126 music_info->type = ARTWORK_TYPE_MUSIC;
2128 /* ---------- initialize file list and suffix lists ---------- */
2130 music_info->num_file_list_entries = num_file_list_entries;
2131 music_info->num_dynamic_file_list_entries = 0;
2133 music_info->file_list =
2134 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2135 num_file_list_entries);
2136 music_info->dynamic_file_list = NULL;
2138 music_info->num_suffix_list_entries = 0;
2139 for (i = 0; config_suffix_list[i].token != NULL; i++)
2140 music_info->num_suffix_list_entries++;
2142 music_info->suffix_list = config_suffix_list;
2144 /* ---------- initialize base prefix and suffixes lists ---------- */
2146 music_info->num_base_prefixes = 0;
2147 for (i = 0; base_prefixes[i] != NULL; i++)
2148 music_info->num_base_prefixes++;
2150 music_info->num_ext1_suffixes = 0;
2151 for (i = 0; ext1_suffixes[i] != NULL; i++)
2152 music_info->num_ext1_suffixes++;
2154 music_info->num_ext2_suffixes = 0;
2155 for (i = 0; ext2_suffixes[i] != NULL; i++)
2156 music_info->num_ext2_suffixes++;
2158 music_info->num_ext3_suffixes = 0;
2159 for (i = 0; ext3_suffixes[i] != NULL; i++)
2160 music_info->num_ext3_suffixes++;
2162 music_info->num_ignore_tokens = 0;
2163 for (i = 0; ignore_tokens[i] != NULL; i++)
2164 music_info->num_ignore_tokens++;
2166 music_info->base_prefixes = base_prefixes;
2167 music_info->ext1_suffixes = ext1_suffixes;
2168 music_info->ext2_suffixes = ext2_suffixes;
2169 music_info->ext3_suffixes = ext3_suffixes;
2170 music_info->ignore_tokens = ignore_tokens;
2172 music_info->num_property_mapping_entries = 0;
2174 music_info->property_mapping = NULL;
2176 /* ---------- initialize artwork reference and content lists ---------- */
2178 music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2180 music_info->artwork_list =
2181 checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2182 music_info->dynamic_artwork_list = NULL;
2184 music_info->content_list = NULL;
2186 /* ---------- initialize artwork loading/freeing functions ---------- */
2188 music_info->load_artwork = Load_WAV_or_MOD;
2189 music_info->free_artwork = FreeMusic;
2192 void PlayMusic(int nr)
2194 if (!audio.music_available)
2200 void PlaySound(int nr)
2202 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2205 void PlaySoundStereo(int nr, int stereo_position)
2207 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2210 void PlaySoundLoop(int nr)
2212 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2215 void PlaySoundMusic(int nr)
2217 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2220 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2222 SoundControl snd_ctrl;
2224 if (!audio.sound_available ||
2225 !audio.sound_enabled ||
2226 audio.sound_deactivated)
2229 if (volume < SOUND_MIN_VOLUME)
2230 volume = SOUND_MIN_VOLUME;
2231 else if (volume > SOUND_MAX_VOLUME)
2232 volume = SOUND_MAX_VOLUME;
2234 if (stereo_position < SOUND_MAX_LEFT)
2235 stereo_position = SOUND_MAX_LEFT;
2236 else if (stereo_position > SOUND_MAX_RIGHT)
2237 stereo_position = SOUND_MAX_RIGHT;
2239 memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */
2241 snd_ctrl.active = TRUE;
2243 snd_ctrl.volume = volume;
2244 snd_ctrl.stereo_position = stereo_position;
2245 snd_ctrl.state = state;
2247 HandleSoundRequest(snd_ctrl);
2250 void FadeMusic(void)
2252 if (!audio.music_available)
2255 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2258 void FadeSound(int nr)
2260 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2265 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2268 void FadeSoundsAndMusic()
2274 void StopMusic(void)
2276 if (!audio.music_available)
2279 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2282 void StopSound(int nr)
2284 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2290 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2293 void StopSoundExt(int nr, int state)
2295 SoundControl snd_ctrl;
2297 if (!audio.sound_available)
2300 memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */
2302 snd_ctrl.active = FALSE;
2304 snd_ctrl.state = state;
2306 HandleSoundRequest(snd_ctrl);
2309 static void ReloadCustomSounds()
2312 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2315 LoadArtworkConfig(sound_info);
2316 ReloadCustomArtworkList(sound_info);
2319 num_sounds = getSoundListSize();
2323 static void ReloadCustomMusic()
2326 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
2329 LoadArtworkConfig(music_info);
2330 ReloadCustomArtworkList(music_info);
2333 /* load all music files from directory not defined in "musicinfo.conf" */
2334 LoadCustomMusic_NoConf();
2338 void InitReloadCustomSounds(char *set_identifier)
2340 if (!audio.sound_available)
2343 #if defined(AUDIO_UNIX_NATIVE)
2344 LoadArtworkConfig(sound_info); /* also load config on sound client */
2345 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2347 ReloadCustomSounds();
2351 void InitReloadCustomMusic(char *set_identifier)
2353 if (!audio.music_available)
2356 #if defined(AUDIO_UNIX_NATIVE)
2357 LoadArtworkConfig(music_info); /* also load config on sound client */
2358 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2360 ReloadCustomMusic();
2364 void FreeSound(void *ptr)
2366 SoundInfo *sound = (SoundInfo *)ptr;
2371 if (sound->data_ptr)
2373 #if defined(TARGET_SDL)
2374 Mix_FreeChunk(sound->data_ptr);
2375 #elif defined(TARGET_ALLEGRO)
2376 destroy_sample(sound->data_ptr);
2377 #else /* AUDIO_UNIX_NATIVE */
2378 free(sound->data_ptr);
2382 checked_free(sound->source_filename);
2387 void FreeMusic(void *ptr)
2389 MusicInfo *music = (MusicInfo *)ptr;
2394 if (music->data_ptr)
2396 #if defined(TARGET_SDL)
2397 if (music->type == MUS_TYPE_MOD)
2398 Mix_FreeMusic(music->data_ptr);
2400 Mix_FreeChunk(music->data_ptr);
2401 #elif defined(TARGET_ALLEGRO)
2402 destroy_sample(music->data_ptr);
2403 #else /* AUDIO_UNIX_NATIVE */
2404 free(music->data_ptr);
2411 static void FreeAllMusic_NoConf()
2415 if (Music_NoConf == NULL)
2418 for (i = 0; i < num_music_noconf; i++)
2419 FreeMusic(Music_NoConf[i]);
2423 Music_NoConf = NULL;
2424 num_music_noconf = 0;
2427 void FreeAllSounds()
2429 FreeCustomArtworkLists(sound_info);
2434 FreeCustomArtworkLists(music_info);
2435 FreeAllMusic_NoConf();
2438 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2439 /* ========================================================================= */