1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2006 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
26 #if defined(PLATFORM_LINUX)
27 #include <sys/ioctl.h>
28 #include <linux/soundcard.h>
29 #elif defined(PLATFORM_FREEBSD)
30 #include <machine/soundcard.h>
31 #elif defined(PLATFORM_NETBSD)
32 #include <sys/ioctl.h>
33 #include <sys/audioio.h>
34 #elif defined(PLATFORM_HPUX)
35 #include <sys/audio.h>
45 /* expiration time (in milliseconds) for sound loops */
46 #define SOUND_LOOP_EXPIRATION_TIME 200
48 /* one second fading interval == 1000 ticks (milliseconds) */
49 #define SOUND_FADING_INTERVAL 1000
51 #if defined(AUDIO_STREAMING_DSP)
52 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
53 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
56 #define SND_TYPE_NONE 0
57 #define SND_TYPE_WAV 1
59 #define MUS_TYPE_NONE 0
60 #define MUS_TYPE_WAV 1
61 #define MUS_TYPE_MOD 2
63 #define DEVICENAME_DSP "/dev/dsp"
64 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
65 #define DEVICENAME_AUDIO "/dev/audio"
66 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
68 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
69 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
71 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
72 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
74 #define SOUND_VOLUME_FROM_PERCENT(v,p) ((p) < 0 ? SOUND_MIN_VOLUME : \
78 #define SOUND_VOLUME_SIMPLE(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_simple)
79 #define SOUND_VOLUME_LOOPS(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_loops)
80 #define SOUND_VOLUME_MUSIC(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_music)
82 #define SETUP_SOUND_VOLUME(v,s) ((s) == SND_CTRL_PLAY_MUSIC ? \
83 SOUND_VOLUME_MUSIC(v) : \
84 (s) == SND_CTRL_PLAY_LOOP ? \
85 SOUND_VOLUME_LOOPS(v) : \
86 SOUND_VOLUME_SIMPLE(v))
89 #if defined(AUDIO_UNIX_NATIVE)
90 struct SoundHeader_WAV
92 unsigned short compression_code;
93 unsigned short num_channels;
94 unsigned int sample_rate;
95 unsigned int bytes_per_second;
96 unsigned short block_align;
97 unsigned short bits_per_sample;
101 struct AudioFormatInfo
103 boolean stereo; /* availability of stereo sound */
104 int format; /* size and endianess of sample data */
105 int sample_rate; /* sample frequency */
106 int fragment_size; /* audio device fragment size in bytes */
111 char *source_filename;
116 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
117 int data_len; /* number of samples, NOT number of bytes */
118 int num_channels; /* mono: 1 channel, stereo: 2 channels */
120 typedef struct SampleInfo SoundInfo;
121 typedef struct SampleInfo MusicInfo;
133 unsigned int playing_starttime;
134 unsigned int playing_pos;
138 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
139 int data_len; /* number of samples, NOT number of bytes */
140 int num_channels; /* mono: 1 channel, stereo: 2 channels */
142 #if defined(TARGET_ALLEGRO)
146 typedef struct SoundControl SoundControl;
148 static struct ArtworkListInfo *sound_info = NULL;
149 static struct ArtworkListInfo *music_info = NULL;
151 static MusicInfo **Music_NoConf = NULL;
153 static int num_music_noconf = 0;
154 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
157 /* ========================================================================= */
158 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
160 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
161 static int mixer_active_channels = 0;
163 #if defined(AUDIO_UNIX_NATIVE)
164 static struct AudioFormatInfo afmt;
166 static void Mixer_Main(void);
167 #if !defined(AUDIO_STREAMING_DSP)
168 static unsigned char linear_to_ulaw(int);
169 static int ulaw_to_linear(unsigned char);
173 static void ReloadCustomSounds();
174 static void ReloadCustomMusic();
175 static void FreeSound(void *);
176 static void FreeMusic(void *);
177 static void FreeAllMusic_NoConf();
179 static SoundInfo *getSoundInfoEntryFromSoundID(int);
180 static MusicInfo *getMusicInfoEntryFromMusicID(int);
183 /* ------------------------------------------------------------------------- */
184 /* functions for native (non-SDL) Unix audio/mixer support */
185 /* ------------------------------------------------------------------------- */
187 #if defined(AUDIO_UNIX_NATIVE)
189 static int OpenAudioDevice(char *audio_device_name)
193 /* check if desired audio device is accessible */
194 if (access(audio_device_name, W_OK) != 0)
197 /* try to open audio device in non-blocking mode */
198 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
199 return audio_device_fd;
201 /* re-open audio device in blocking mode */
202 close(audio_device_fd);
203 audio_device_fd = open(audio_device_name, O_WRONLY);
205 return audio_device_fd;
208 static void CloseAudioDevice(int *audio_device_fd)
210 if (*audio_device_fd == 0)
213 close(*audio_device_fd);
214 *audio_device_fd = -1;
217 static boolean TestAudioDevices(void)
219 static char *audio_device_name[] =
222 DEVICENAME_SOUND_DSP,
225 int audio_device_fd = -1;
228 /* look for available audio devices, starting with preferred ones */
229 for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
230 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
233 if (audio_device_fd < 0)
235 Error(ERR_WARN, "cannot open audio device -- no sound");
239 close(audio_device_fd);
241 audio.device_name = audio_device_name[i];
246 static boolean ForkAudioProcess(void)
248 if (pipe(audio.mixer_pipe) < 0)
250 Error(ERR_WARN, "cannot create pipe -- no sounds");
254 if ((audio.mixer_pid = fork()) < 0)
256 Error(ERR_WARN, "cannot create sound server process -- no sounds");
260 if (audio.mixer_pid == 0) /* we are the child process */
261 audio.mixer_pid = getpid();
263 if (IS_CHILD_PROCESS())
264 Mixer_Main(); /* this function never returns */
266 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
271 void UnixOpenAudio(void)
273 if (!TestAudioDevices())
276 audio.sound_available = TRUE;
277 audio.sound_enabled = TRUE;
279 #if defined(AUDIO_STREAMING_DSP)
280 audio.music_available = TRUE;
281 audio.loops_available = TRUE;
284 audio.num_channels = NUM_MIXER_CHANNELS;
285 audio.music_channel = MUSIC_CHANNEL;
286 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
289 void UnixCloseAudio(void)
292 close(audio.device_fd);
294 if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
295 kill(audio.mixer_pid, SIGTERM);
299 /* ------------------------------------------------------------------------- */
300 /* functions for platform specific audio device initialization */
301 /* ------------------------------------------------------------------------- */
303 #if defined(AUDIO_LINUX_IOCTL)
304 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
306 /* "ioctl()" expects pointer to 'int' value for stereo flag
307 (boolean is defined as 'char', which will not work here) */
308 unsigned int fragment_spec = 0;
309 int fragment_size_query = -1;
318 /* supported audio format in preferred order */
319 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
320 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
321 { AFMT_U8, AUDIO_FORMAT_U8 },
326 /* determine logarithm (log2) of the fragment size */
327 while ((1 << fragment_spec) < afmt->fragment_size)
330 /* use two fragments (play one fragment, prepare the other);
331 one fragment would result in interrupted audio output, more
332 than two fragments would raise audio output latency to much */
333 fragment_spec |= 0x00020000;
335 /* Example for fragment specification:
336 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
337 - (with stereo the effective buffer size will shrink to 256)
338 => fragment_size = 0x00020009 */
340 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
341 Error(ERR_EXIT_SOUND_SERVER,
342 "cannot set fragment size of audio device -- no sounds");
346 while (formats[i].format_result != -1)
348 unsigned int audio_format = formats[i].format_ioctl;
349 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
351 afmt->format = formats[i].format_result;
356 if (afmt->format == 0) /* no supported audio format found */
357 Error(ERR_EXIT_SOUND_SERVER,
358 "cannot set audio format of audio device -- no sounds");
360 /* try if we can use stereo sound */
362 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
363 afmt->stereo = FALSE;
365 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
366 Error(ERR_EXIT_SOUND_SERVER,
367 "cannot set sample rate of audio device -- no sounds");
369 /* get the real fragmentation size; this should return 512 */
370 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
371 Error(ERR_EXIT_SOUND_SERVER,
372 "cannot get fragment size of audio device -- no sounds");
373 if (fragment_size_query != afmt->fragment_size)
374 Error(ERR_EXIT_SOUND_SERVER,
375 "cannot set fragment size of audio device -- no sounds");
377 #endif /* AUDIO_LINUX_IOCTL */
379 #if defined(PLATFORM_NETBSD)
380 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
383 boolean stereo = TRUE;
385 AUDIO_INITINFO(&a_info);
386 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
387 a_info.play.precision = 8;
388 a_info.play.channels = 2;
389 a_info.play.sample_rate = afmt->sample_rate;
390 a_info.blocksize = afmt->fragment_size;
392 afmt->format = AUDIO_FORMAT_U8;
395 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
397 /* try to disable stereo */
398 a_info.play.channels = 1;
400 afmt->stereo = FALSE;
402 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
403 Error(ERR_EXIT_SOUND_SERVER,
404 "cannot set sample rate of audio device -- no sounds");
407 #endif /* PLATFORM_NETBSD */
409 #if defined(PLATFORM_HPUX)
410 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
412 struct audio_describe ainfo;
415 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
417 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
419 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
420 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
422 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
423 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
425 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
426 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
428 afmt->format = AUDIO_FORMAT_U8;
429 afmt->stereo = FALSE;
430 afmt->sample_rate = 8000;
434 #endif /* PLATFORM_HPUX */
436 static void InitAudioDevice(struct AudioFormatInfo *afmt)
439 afmt->format = AUDIO_FORMAT_UNKNOWN;
440 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
441 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
443 #if defined(AUDIO_LINUX_IOCTL)
444 InitAudioDevice_Linux(afmt);
445 #elif defined(PLATFORM_NETBSD)
446 InitAudioDevice_NetBSD(afmt);
447 #elif defined(PLATFORM_HPUX)
448 InitAudioDevice_HPUX(afmt);
450 /* generic /dev/audio stuff might be placed here */
455 /* ------------------------------------------------------------------------- */
456 /* functions for communication between main process and sound mixer process */
457 /* ------------------------------------------------------------------------- */
459 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
461 if (IS_CHILD_PROCESS())
464 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
466 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
467 audio.sound_available = audio.sound_enabled = FALSE;
472 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
474 if (IS_PARENT_PROCESS())
477 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
478 != sizeof(SoundControl))
479 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
482 static void WriteReloadInfoToPipe(char *set_identifier, int type)
484 SoundControl snd_ctrl;
485 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
486 artwork.mus_current);
487 unsigned int str_size1 = strlen(leveldir_current->fullpath) + 1;
488 unsigned int str_size2 = strlen(leveldir_current->sounds_path) + 1;
489 unsigned int str_size3 = strlen(leveldir_current->music_path) + 1;
490 unsigned int str_size4 = strlen(ti->basepath) + 1;
491 unsigned int str_size5 = strlen(ti->fullpath) + 1;
492 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
493 gfx.override_level_sounds :
494 gfx.override_level_music);
496 if (IS_CHILD_PROCESS())
499 if (leveldir_current == NULL) /* should never happen */
500 Error(ERR_EXIT, "leveldir_current == NULL");
502 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
504 snd_ctrl.active = FALSE;
505 snd_ctrl.state = type;
506 snd_ctrl.data_len = strlen(set_identifier) + 1;
508 if (write(audio.mixer_pipe[1], &snd_ctrl,
509 sizeof(snd_ctrl)) < 0 ||
510 write(audio.mixer_pipe[1], set_identifier,
511 snd_ctrl.data_len) < 0 ||
512 write(audio.mixer_pipe[1], &override_level_artwork,
513 sizeof(boolean)) < 0 ||
514 write(audio.mixer_pipe[1], leveldir_current,
515 sizeof(TreeInfo)) < 0 ||
516 write(audio.mixer_pipe[1], ti,
517 sizeof(TreeInfo)) < 0 ||
518 write(audio.mixer_pipe[1], &str_size1,
519 sizeof(unsigned int)) < 0 ||
520 write(audio.mixer_pipe[1], &str_size2,
521 sizeof(unsigned int)) < 0 ||
522 write(audio.mixer_pipe[1], &str_size3,
523 sizeof(unsigned int)) < 0 ||
524 write(audio.mixer_pipe[1], &str_size4,
525 sizeof(unsigned int)) < 0 ||
526 write(audio.mixer_pipe[1], &str_size5,
527 sizeof(unsigned int)) < 0 ||
528 write(audio.mixer_pipe[1], leveldir_current->fullpath,
530 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
532 write(audio.mixer_pipe[1], leveldir_current->music_path,
534 write(audio.mixer_pipe[1], ti->basepath,
536 write(audio.mixer_pipe[1], ti->fullpath,
539 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
540 audio.sound_available = audio.sound_enabled = FALSE;
545 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
547 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
548 &artwork.snd_current : &artwork.mus_current);
549 TreeInfo *ti = *ti_ptr;
550 unsigned int str_size1, str_size2, str_size3, str_size4, str_size5;
551 static char *set_identifier = NULL;
552 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
553 &gfx.override_level_sounds :
554 &gfx.override_level_music);
556 checked_free(set_identifier);
558 set_identifier = checked_malloc(snd_ctrl->data_len);
560 if (leveldir_current == NULL)
561 leveldir_current = checked_calloc(sizeof(TreeInfo));
564 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
566 checked_free(leveldir_current->fullpath);
567 checked_free(leveldir_current->sounds_path);
568 checked_free(leveldir_current->music_path);
569 checked_free(ti->basepath);
570 checked_free(ti->fullpath);
572 if (read(audio.mixer_pipe[0], set_identifier,
573 snd_ctrl->data_len) != snd_ctrl->data_len ||
574 read(audio.mixer_pipe[0], override_level_artwork,
575 sizeof(boolean)) != sizeof(boolean) ||
576 read(audio.mixer_pipe[0], leveldir_current,
577 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
578 read(audio.mixer_pipe[0], ti,
579 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
580 read(audio.mixer_pipe[0], &str_size1,
581 sizeof(unsigned int)) != sizeof(unsigned int) ||
582 read(audio.mixer_pipe[0], &str_size2,
583 sizeof(unsigned int)) != sizeof(unsigned int) ||
584 read(audio.mixer_pipe[0], &str_size3,
585 sizeof(unsigned int)) != sizeof(unsigned int) ||
586 read(audio.mixer_pipe[0], &str_size4,
587 sizeof(unsigned int)) != sizeof(unsigned int) ||
588 read(audio.mixer_pipe[0], &str_size5,
589 sizeof(unsigned int)) != sizeof(unsigned int))
590 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
592 leveldir_current->fullpath = checked_calloc(str_size1);
593 leveldir_current->sounds_path = checked_calloc(str_size2);
594 leveldir_current->music_path = checked_calloc(str_size3);
595 ti->basepath = checked_calloc(str_size4);
596 ti->fullpath = checked_calloc(str_size5);
598 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
599 str_size1) != str_size1 ||
600 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
601 str_size2) != str_size2 ||
602 read(audio.mixer_pipe[0], leveldir_current->music_path,
603 str_size3) != str_size3 ||
604 read(audio.mixer_pipe[0], ti->basepath,
605 str_size4) != str_size4 ||
606 read(audio.mixer_pipe[0], ti->fullpath,
607 str_size5) != str_size5)
608 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
610 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
611 artwork.snd_current_identifier = set_identifier;
613 artwork.mus_current_identifier = set_identifier;
616 #endif /* AUDIO_UNIX_NATIVE */
619 /* ------------------------------------------------------------------------- */
620 /* mixer functions */
621 /* ------------------------------------------------------------------------- */
623 void Mixer_InitChannels()
627 for (i = 0; i < audio.num_channels; i++)
628 mixer[i].active = FALSE;
629 mixer_active_channels = 0;
632 static void Mixer_ResetChannelExpiration(int channel)
634 mixer[channel].playing_starttime = Counter();
636 #if defined(TARGET_SDL)
637 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
638 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
642 static boolean Mixer_ChannelExpired(int channel)
644 if (!mixer[channel].active)
647 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
648 DelayReached(&mixer[channel].playing_starttime,
649 SOUND_LOOP_EXPIRATION_TIME))
652 #if defined(TARGET_SDL)
654 if (!Mix_Playing(channel))
657 #elif defined(TARGET_ALLEGRO)
659 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
660 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
662 /* sound sample has completed playing or was completely faded out */
663 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
666 #endif /* TARGET_ALLEGRO */
671 static boolean Mixer_AllocateChannel(int channel)
673 #if defined(TARGET_ALLEGRO)
674 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
675 if (mixer[channel].voice < 0)
682 static void Mixer_SetChannelProperties(int channel)
684 #if defined(TARGET_SDL)
685 Mix_Volume(channel, mixer[channel].volume);
686 Mix_SetPanning(channel,
687 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
688 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
689 #elif defined(TARGET_ALLEGRO)
690 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
691 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
695 static void Mixer_StartChannel(int channel)
697 #if defined(TARGET_SDL)
698 Mix_PlayChannel(channel, mixer[channel].data_ptr,
699 IS_LOOP(mixer[channel]) ? -1 : 0);
700 #elif defined(TARGET_ALLEGRO)
701 if (IS_LOOP(mixer[channel]))
702 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
704 voice_start(mixer[channel].voice);
708 static void Mixer_PlayChannel(int channel)
710 /* start with inactive channel in case something goes wrong */
711 mixer[channel].active = FALSE;
713 if (mixer[channel].type != MUS_TYPE_WAV)
716 if (!Mixer_AllocateChannel(channel))
719 Mixer_SetChannelProperties(channel);
720 Mixer_StartChannel(channel);
722 Mixer_ResetChannelExpiration(channel);
724 mixer[channel].playing_pos = 0;
725 mixer[channel].active = TRUE;
726 mixer_active_channels++;
729 static void Mixer_PlayMusicChannel()
731 Mixer_PlayChannel(audio.music_channel);
733 #if defined(TARGET_SDL)
734 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
736 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
737 this looks like a bug in the SDL_mixer library */
738 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
739 Mix_VolumeMusic(mixer[audio.music_channel].volume);
744 static void Mixer_StopChannel(int channel)
746 if (!mixer[channel].active)
749 #if defined(TARGET_SDL)
750 Mix_HaltChannel(channel);
751 #elif defined(TARGET_ALLEGRO)
752 voice_set_volume(mixer[channel].voice, 0);
753 deallocate_voice(mixer[channel].voice);
756 mixer[channel].active = FALSE;
757 mixer_active_channels--;
760 static void Mixer_StopMusicChannel()
762 Mixer_StopChannel(audio.music_channel);
764 #if defined(TARGET_SDL)
769 static void Mixer_FadeChannel(int channel)
771 if (!mixer[channel].active)
774 mixer[channel].state |= SND_CTRL_FADE;
776 #if defined(TARGET_SDL)
777 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
778 #elif defined(TARGET_ALLEGRO)
779 if (voice_check(mixer[channel].voice))
780 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
784 static void Mixer_FadeMusicChannel()
786 Mixer_FadeChannel(audio.music_channel);
788 #if defined(TARGET_SDL)
789 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
793 static void Mixer_UnFadeChannel(int channel)
795 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
798 mixer[channel].state &= ~SND_CTRL_FADE;
799 mixer[channel].volume = SOUND_MAX_VOLUME;
801 #if defined(TARGET_SDL)
802 Mix_ExpireChannel(channel, -1);
803 Mix_Volume(channel, mixer[channel].volume);
804 #elif defined(TARGET_ALLEGRO)
805 voice_stop_volumeramp(mixer[channel].voice);
806 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
807 mixer[channel].volume);
811 static void Mixer_InsertSound(SoundControl snd_ctrl)
815 int num_sounds = getSoundListSize();
816 int num_music = getMusicListSize();
818 if (IS_MUSIC(snd_ctrl))
820 if (snd_ctrl.nr >= num_music) /* invalid music */
823 if (snd_ctrl.nr < 0) /* undefined music */
825 if (num_music_noconf == 0) /* no fallback music available */
828 snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
829 snd_info = Music_NoConf[snd_ctrl.nr];
832 snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
836 if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
839 snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
842 if (snd_info == NULL)
845 /* copy sound sample and format information */
846 snd_ctrl.type = snd_info->type;
847 snd_ctrl.format = snd_info->format;
848 snd_ctrl.data_ptr = snd_info->data_ptr;
849 snd_ctrl.data_len = snd_info->data_len;
850 snd_ctrl.num_channels = snd_info->num_channels;
852 /* play music samples on a dedicated music channel */
853 if (IS_MUSIC(snd_ctrl))
855 Mixer_StopMusicChannel();
857 mixer[audio.music_channel] = snd_ctrl;
858 Mixer_PlayMusicChannel();
863 /* check if (and how often) this sound sample is already playing */
864 for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
865 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
868 /* reset expiration delay for already playing loop sounds */
869 if (k > 0 && IS_LOOP(snd_ctrl))
871 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
873 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
875 if (IS_FADING(mixer[i]))
876 Mixer_UnFadeChannel(i);
878 /* restore settings like volume and stereo position */
879 mixer[i].volume = snd_ctrl.volume;
880 mixer[i].stereo_position = snd_ctrl.stereo_position;
882 Mixer_SetChannelProperties(i);
883 Mixer_ResetChannelExpiration(i);
890 /* don't play sound more than n times simultaneously (with n == 2 for now) */
893 unsigned int playing_current = Counter();
894 int longest = 0, longest_nr = audio.first_sound_channel;
896 /* look for oldest equal sound */
897 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
899 int playing_time = playing_current - mixer[i].playing_starttime;
902 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
905 actual = 1000 * playing_time / mixer[i].data_len;
907 if (actual >= longest)
914 Mixer_StopChannel(longest_nr);
917 /* If all (non-music) channels are active, stop the channel that has
918 played its sound sample most completely (in percent of the sample
919 length). As we cannot currently get the actual playing position
920 of the channel's sound sample when compiling with the SDL mixer
921 library, we use the current playing time (in milliseconds) instead. */
924 /* channel allocation sanity check -- should not be needed */
925 if (mixer_active_channels ==
926 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
928 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
930 if (!mixer[i].active)
932 Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i);
933 Error(ERR_INFO, "Mixer_InsertSound: This should never happen!");
935 mixer_active_channels--;
941 if (mixer_active_channels ==
942 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
944 unsigned int playing_current = Counter();
945 int longest = 0, longest_nr = audio.first_sound_channel;
949 /* print some debugging information about audio channel usage */
950 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
952 Error(ERR_INFO, "Mixer_InsertSound: %d [%d]: %d (%d)",
953 i, mixer[i].active, mixer[i].data_len, (int)mixer[i].data_ptr);
958 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
960 int playing_time = playing_current - mixer[i].playing_starttime;
961 int actual = 1000 * playing_time / mixer[i].data_len;
963 if (!IS_LOOP(mixer[i]) && actual > longest)
970 Mixer_StopChannel(longest_nr);
973 /* add the new sound to the mixer */
974 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
976 if (!mixer[i].active)
978 #if defined(AUDIO_UNIX_NATIVE)
979 if (snd_info->data_len == 0)
981 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
986 Mixer_PlayChannel(i);
993 static void HandleSoundRequest(SoundControl snd_ctrl)
997 #if defined(AUDIO_UNIX_NATIVE)
998 if (IS_PARENT_PROCESS())
1000 SendSoundControlToMixerProcess(&snd_ctrl);
1005 /* deactivate channels that have expired since the last request */
1006 for (i = 0; i < audio.num_channels; i++)
1007 if (mixer[i].active && Mixer_ChannelExpired(i))
1008 Mixer_StopChannel(i);
1010 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1012 Mixer_StopMusicChannel();
1013 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1014 Mixer_StopChannel(i);
1016 #if defined(AUDIO_UNIX_NATIVE)
1017 CloseAudioDevice(&audio.device_fd);
1018 ReadReloadInfoFromPipe(&snd_ctrl);
1021 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1022 ReloadCustomSounds();
1024 ReloadCustomMusic();
1026 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1028 if (IS_MUSIC(snd_ctrl))
1030 Mixer_FadeMusicChannel();
1034 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1035 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1036 Mixer_FadeChannel(i);
1038 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1040 if (IS_MUSIC(snd_ctrl))
1042 Mixer_StopMusicChannel();
1046 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1047 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1048 Mixer_StopChannel(i);
1050 #if defined(AUDIO_UNIX_NATIVE)
1051 if (!mixer_active_channels)
1052 CloseAudioDevice(&audio.device_fd);
1055 else if (snd_ctrl.active) /* add new sound to mixer */
1057 Mixer_InsertSound(snd_ctrl);
1061 void StartMixer(void)
1066 SDL_version compile_version;
1067 const SDL_version *link_version;
1068 MIX_VERSION(&compile_version);
1069 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1070 compile_version.major,
1071 compile_version.minor,
1072 compile_version.patch);
1073 link_version = Mix_Linked_Version();
1074 printf("running with SDL_mixer version: %d.%d.%d\n",
1075 link_version->major,
1076 link_version->minor,
1077 link_version->patch);
1080 if (!audio.sound_available)
1083 /* initialize stereo position conversion information */
1084 for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1086 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1088 #if defined(AUDIO_UNIX_NATIVE)
1089 if (!ForkAudioProcess())
1090 audio.sound_available = FALSE;
1094 #if defined(AUDIO_UNIX_NATIVE)
1096 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1097 int sample_pos, int sample_size,
1098 short *buffer_base_ptr, int buffer_pos,
1099 int num_output_channels)
1101 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1102 int num_channels = snd_ctrl->num_channels;
1103 int stepsize = num_channels;
1104 int output_stepsize = num_output_channels;
1107 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1109 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1111 for (i = 0; i < num_output_channels; i++)
1113 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1115 for (j = 0; j < sample_size; j++)
1116 buffer_ptr[output_stepsize * j + i] =
1117 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1120 else /* AUDIO_FORMAT_S16 */
1122 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1124 for (i = 0; i < num_output_channels; i++)
1126 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1128 for (j = 0; j < sample_size; j++)
1129 buffer_ptr[output_stepsize * j + i] =
1130 sample_ptr[stepsize * j + offset];
1135 #if defined(AUDIO_STREAMING_DSP)
1136 static void Mixer_Main_DSP()
1138 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1139 static int premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1140 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1144 int max_sample_size;
1145 int num_output_channels;
1148 if (!mixer_active_channels)
1151 if (audio.device_fd < 0)
1153 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1156 InitAudioDevice(&afmt);
1159 stereo = afmt.stereo;
1160 fragment_size = afmt.fragment_size;
1161 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1162 num_output_channels = (stereo ? 2 : 1);
1163 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1165 /* first clear the last premixing buffer */
1166 clear_mem(premix_last_buffer,
1167 max_sample_size * num_output_channels * sizeof(int));
1169 for (i = 0; i < audio.num_channels; i++)
1171 // void *sample_ptr;
1176 if (!mixer[i].active)
1179 if (Mixer_ChannelExpired(i))
1181 Mixer_StopChannel(i);
1185 /* pointer, lenght and actual playing position of sound sample */
1186 // sample_ptr = mixer[i].data_ptr;
1187 sample_len = mixer[i].data_len;
1188 sample_pos = mixer[i].playing_pos;
1189 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1190 mixer[i].playing_pos += sample_size;
1192 /* copy original sample to first mixing buffer */
1193 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1194 premix_first_buffer, 0, num_output_channels);
1196 /* are we about to restart a looping sound? */
1197 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1199 while (sample_size < max_sample_size)
1201 int restarted_sample_size =
1202 MIN(max_sample_size - sample_size, sample_len);
1204 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1205 premix_first_buffer, sample_size,
1206 num_output_channels);
1208 mixer[i].playing_pos = restarted_sample_size;
1209 sample_size += restarted_sample_size;
1213 /* decrease volume if sound is fading out */
1214 if (IS_FADING(mixer[i]) &&
1215 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1216 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1218 /* adjust volume of actual sound sample */
1219 if (mixer[i].volume != SOUND_MAX_VOLUME)
1220 for (j = 0; j < sample_size * num_output_channels; j++)
1221 premix_first_buffer[j] =
1222 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1224 /* adjust left and right channel volume due to stereo sound position */
1227 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1228 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1230 for (j = 0; j < sample_size; j++)
1232 premix_first_buffer[2 * j + 0] =
1233 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1234 premix_first_buffer[2 * j + 1] =
1235 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1239 /* fill the last mixing buffer with stereo or mono sound */
1240 for (j = 0; j < sample_size * num_output_channels; j++)
1241 premix_last_buffer[j] += premix_first_buffer[j];
1243 /* delete completed sound entries from the mixer */
1244 if (mixer[i].playing_pos >= mixer[i].data_len)
1246 if (IS_LOOP(mixer[i]))
1247 mixer[i].playing_pos = 0;
1249 Mixer_StopChannel(i);
1251 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1252 Mixer_StopChannel(i);
1255 /* prepare final playing buffer according to system audio format */
1256 for (i = 0; i < max_sample_size * num_output_channels; i++)
1258 /* cut off at 17 bit value */
1259 if (premix_last_buffer[i] < -65535)
1260 premix_last_buffer[i] = -65535;
1261 else if (premix_last_buffer[i] > 65535)
1262 premix_last_buffer[i] = 65535;
1264 /* shift to 16 bit value */
1265 premix_last_buffer[i] >>= 1;
1267 if (afmt.format & AUDIO_FORMAT_U8)
1269 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1271 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1273 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1274 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1276 else /* big endian */
1278 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1279 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1283 /* finally play the sound fragment */
1284 if (write(audio.device_fd, playing_buffer, fragment_size) == -1)
1285 Error(ERR_WARN, "write() failed; %s", strerror(errno));
1287 if (!mixer_active_channels)
1288 CloseAudioDevice(&audio.device_fd);
1291 #else /* !AUDIO_STREAMING_DSP */
1293 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1295 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1296 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1297 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1298 int num_output_channels = 1;
1307 /* pointer, lenght and actual playing position of sound sample */
1308 sample_ptr = mixer[i].data_ptr;
1309 sample_len = mixer[i].data_len;
1310 sample_pos = mixer[i].playing_pos;
1311 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1312 mixer[i].playing_pos += sample_size;
1314 /* copy original sample to first mixing buffer */
1315 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1316 premix_first_buffer, 0, num_output_channels);
1318 /* adjust volume of actual sound sample */
1319 if (mixer[i].volume != SOUND_MAX_VOLUME)
1320 for (j = 0; j < sample_size; j++)
1321 premix_first_buffer[j] =
1322 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1324 /* might be needed for u-law /dev/audio */
1325 for (j = 0; j < sample_size; j++)
1327 linear_to_ulaw(premix_first_buffer[j]);
1329 /* delete completed sound entries from the mixer */
1330 if (mixer[i].playing_pos >= mixer[i].data_len)
1331 Mixer_StopChannel(i);
1333 for (i = 0; i < sample_size; i++)
1334 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1336 /* finally play the sound fragment */
1337 write(audio.device_fd, playing_buffer, sample_size);
1341 #endif /* !AUDIO_STREAMING_DSP */
1345 SoundControl snd_ctrl;
1348 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1350 Mixer_InitChannels();
1352 #if defined(PLATFORM_HPUX)
1353 InitAudioDevice(&afmt);
1356 FD_ZERO(&mixer_fdset);
1357 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1359 while (1) /* wait for sound playing commands from client */
1361 struct timeval delay = { 0, 0 };
1363 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1364 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1365 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1368 ReadSoundControlFromMainProcess(&snd_ctrl);
1370 HandleSoundRequest(snd_ctrl);
1372 #if defined(AUDIO_STREAMING_DSP)
1374 while (mixer_active_channels &&
1375 select(audio.mixer_pipe[0] + 1,
1376 &mixer_fdset, NULL, NULL, &delay) < 1)
1378 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1383 #else /* !AUDIO_STREAMING_DSP */
1385 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1386 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1389 InitAudioDevice(&afmt);
1394 while (mixer_active_channels &&
1395 select(audio.mixer_pipe[0] + 1,
1396 &mixer_fdset, NULL, NULL, &delay) < 1)
1398 int wait_percent = 90; /* wait 90% of the real playing time */
1401 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1403 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1407 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1410 CloseAudioDevice(&audio.device_fd);
1412 Mixer_InitChannels(); /* remove all sounds from mixer */
1414 #endif /* !AUDIO_STREAMING_DSP */
1417 #endif /* AUDIO_UNIX_NATIVE */
1420 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1422 /* these two are stolen from "sox"... :) */
1425 ** This routine converts from linear to ulaw.
1427 ** Craig Reese: IDA/Supercomputing Research Center
1428 ** Joe Campbell: Department of Defense
1429 ** 29 September 1989
1432 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1433 ** 2) "A New Digital Technique for Implementation of Any
1434 ** Continuous PCM Companding Law," Villeret, Michel,
1435 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1436 ** 1973, pg. 11.12-11.17
1437 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1438 ** for Analog-to_Digital Conversion Techniques,"
1441 ** Input: Signed 16 bit linear sample
1442 ** Output: 8 bit ulaw sample
1445 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1446 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1449 static unsigned char linear_to_ulaw(int sample)
1451 static int exp_lut[256] =
1453 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1454 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1455 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1456 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1457 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1458 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1459 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1460 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1461 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1462 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1463 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1464 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1465 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1466 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1467 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1468 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1471 int sign, exponent, mantissa;
1472 unsigned char ulawbyte;
1474 /* Get the sample into sign-magnitude. */
1475 sign = (sample >> 8) & 0x80; /* set aside the sign */
1477 sample = -sample; /* get magnitude */
1479 sample = CLIP; /* clip the magnitude */
1481 /* Convert from 16 bit linear to ulaw. */
1482 sample = sample + BIAS;
1483 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1484 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1485 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1488 ulawbyte = 0x02; /* optional CCITT trap */
1495 ** This routine converts from ulaw to 16 bit linear.
1497 ** Craig Reese: IDA/Supercomputing Research Center
1498 ** 29 September 1989
1501 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1502 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1503 ** for Analog-to_Digital Conversion Techniques,"
1506 ** Input: 8 bit ulaw sample
1507 ** Output: signed 16 bit linear sample
1510 static int ulaw_to_linear(unsigned char ulawbyte)
1512 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1513 int sign, exponent, mantissa, sample;
1515 ulawbyte = ~ ulawbyte;
1516 sign = ( ulawbyte & 0x80 );
1517 exponent = ( ulawbyte >> 4 ) & 0x07;
1518 mantissa = ulawbyte & 0x0F;
1519 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1525 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1528 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1529 /* ========================================================================= */
1530 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1532 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1533 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1535 static void *Load_WAV(char *filename)
1537 SoundInfo *snd_info;
1538 #if defined(AUDIO_UNIX_NATIVE)
1539 struct SoundHeader_WAV header;
1541 byte sound_header_buffer[WAV_HEADER_SIZE];
1544 char chunk_name[CHUNK_ID_LEN + 1];
1550 if (!audio.sound_available)
1553 snd_info = checked_calloc(sizeof(SoundInfo));
1555 #if defined(TARGET_SDL)
1557 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1559 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1564 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1566 #elif defined(TARGET_ALLEGRO)
1568 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1570 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1575 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1577 #else /* AUDIO_UNIX_NATIVE */
1579 clear_mem(&header, sizeof(struct SoundHeader_WAV)); /* to make gcc happy */
1581 if ((file = fopen(filename, MODE_READ)) == NULL)
1583 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1588 /* read chunk id "RIFF" */
1589 getFileChunkLE(file, chunk_name, &chunk_size);
1590 if (!strEqual(chunk_name, "RIFF"))
1592 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1598 /* read "RIFF" type id "WAVE" */
1599 getFileChunkLE(file, chunk_name, NULL);
1600 if (!strEqual(chunk_name, "WAVE"))
1602 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1608 while (getFileChunkLE(file, chunk_name, &chunk_size))
1610 if (strEqual(chunk_name, "fmt "))
1612 if (chunk_size < WAV_HEADER_SIZE)
1614 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1620 header.compression_code = getFile16BitLE(file);
1621 header.num_channels = getFile16BitLE(file);
1622 header.sample_rate = getFile32BitLE(file);
1623 header.bytes_per_second = getFile32BitLE(file);
1624 header.block_align = getFile16BitLE(file);
1625 header.bits_per_sample = getFile16BitLE(file);
1627 if (chunk_size > WAV_HEADER_SIZE)
1628 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1630 if (header.compression_code != 1)
1632 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1633 filename, header.compression_code);
1639 if (header.num_channels != 1 &&
1640 header.num_channels != 2)
1642 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1643 filename, header.num_channels);
1649 if (header.bits_per_sample != 8 &&
1650 header.bits_per_sample != 16)
1652 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1653 filename, header.bits_per_sample);
1659 /* warn, but accept wrong sample rate (may be only slightly different) */
1660 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1661 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1662 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1665 printf("WAV file: '%s'\n", filename);
1666 printf(" Compression code: %d'\n", header.compression_code);
1667 printf(" Number of channels: %d'\n", header.num_channels);
1668 printf(" Sample rate: %d'\n", header.sample_rate);
1669 printf(" Average bytes per second: %d'\n", header.bytes_per_second);
1670 printf(" Block align: %d'\n", header.block_align);
1671 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1674 else if (strEqual(chunk_name, "data"))
1676 data_byte_len = chunk_size;
1678 snd_info->data_len = data_byte_len;
1679 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1681 /* read sound data */
1682 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1685 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1687 free(snd_info->data_ptr);
1692 /* check for odd number of data bytes (data chunk is word aligned) */
1693 if ((data_byte_len % 2) == 1)
1694 ReadUnusedBytesFromFile(file, 1);
1696 else /* unknown chunk -- ignore */
1697 ReadUnusedBytesFromFile(file, chunk_size);
1702 if (snd_info->data_ptr == NULL)
1704 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1709 if (header.bits_per_sample == 8)
1710 snd_info->format = AUDIO_FORMAT_U8;
1711 else /* header.bits_per_sample == 16 */
1713 snd_info->format = AUDIO_FORMAT_S16;
1714 snd_info->data_len /= 2; /* correct number of samples */
1717 snd_info->num_channels = header.num_channels;
1718 if (header.num_channels == 2)
1719 snd_info->data_len /= 2; /* correct number of samples */
1722 if (header.num_channels == 1) /* convert mono sound to stereo */
1724 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1725 void *sample_ptr = snd_info->data_ptr;
1726 int sample_size = snd_info->data_len;
1729 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1730 for (i = 0; i < sample_size; i++)
1732 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1733 else /* AUDIO_FORMAT_S16 */
1734 for (i = 0; i < sample_size; i++)
1736 ((short *)sample_ptr)[i];
1740 #endif /* AUDIO_UNIX_NATIVE */
1742 snd_info->type = SND_TYPE_WAV;
1743 snd_info->source_filename = getStringCopy(filename);
1748 static void *Load_MOD(char *filename)
1750 #if defined(TARGET_SDL)
1751 MusicInfo *mod_info;
1753 if (!audio.sound_available)
1756 mod_info = checked_calloc(sizeof(MusicInfo));
1758 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1760 Error(ERR_WARN, "cannot read music file '%s'", filename);
1765 mod_info->type = MUS_TYPE_MOD;
1766 mod_info->source_filename = getStringCopy(filename);
1774 static void *Load_WAV_or_MOD(char *filename)
1776 if (FileIsSound(filename))
1777 return Load_WAV(filename);
1778 else if (FileIsMusic(filename))
1779 return Load_MOD(filename);
1784 void LoadCustomMusic_NoConf(void)
1786 static boolean draw_init_text = TRUE; /* only draw at startup */
1787 static char *last_music_directory = NULL;
1788 char *music_directory = getCustomMusicDirectory();
1790 struct dirent *dir_entry;
1791 int num_music = getMusicListSize();
1793 if (!audio.sound_available)
1796 if (last_music_directory != NULL &&
1797 strEqual(last_music_directory, music_directory))
1798 return; /* old and new music directory are the same */
1800 if (last_music_directory != NULL)
1801 free(last_music_directory);
1802 last_music_directory = getStringCopy(music_directory);
1804 FreeAllMusic_NoConf();
1806 if ((dir = opendir(music_directory)) == NULL)
1808 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1809 audio.music_available = FALSE;
1814 DrawInitText("Loading music", 120, FC_GREEN);
1816 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1818 char *basename = dir_entry->d_name;
1819 char *filename = NULL;
1820 MusicInfo *mus_info = NULL;
1821 boolean music_already_used = FALSE;
1824 /* skip all music files that are configured in music config file */
1825 for (i = 0; i < num_music; i++)
1827 struct FileInfo *music = getMusicListEntry(i);
1829 if (strEqual(basename, music->filename))
1831 music_already_used = TRUE;
1836 if (music_already_used)
1840 DrawInitText(basename, 150, FC_YELLOW);
1842 filename = getPath2(music_directory, basename);
1844 if (FileIsMusic(basename))
1845 mus_info = Load_WAV_or_MOD(filename);
1852 Music_NoConf = checked_realloc(Music_NoConf,
1853 num_music_noconf * sizeof(MusicInfo *));
1854 Music_NoConf[num_music_noconf - 1] = mus_info;
1860 draw_init_text = FALSE;
1863 int getSoundListSize()
1865 return (sound_info->num_file_list_entries +
1866 sound_info->num_dynamic_file_list_entries);
1869 int getMusicListSize()
1871 return (music_info->num_file_list_entries +
1872 music_info->num_dynamic_file_list_entries);
1875 struct FileInfo *getSoundListEntry(int pos)
1877 int num_list_entries = sound_info->num_file_list_entries;
1878 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1880 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1881 &sound_info->dynamic_file_list[list_pos]);
1884 struct FileInfo *getMusicListEntry(int pos)
1886 int num_list_entries = music_info->num_file_list_entries;
1887 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1889 return (pos < num_list_entries ? &music_info->file_list[list_pos] :
1890 &music_info->dynamic_file_list[list_pos]);
1893 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1895 int num_list_entries = sound_info->num_file_list_entries;
1896 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1897 SoundInfo **snd_info =
1898 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
1899 sound_info->dynamic_artwork_list);
1901 return snd_info[list_pos];
1904 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
1906 int num_list_entries = music_info->num_file_list_entries;
1907 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1908 MusicInfo **mus_info =
1909 (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
1910 music_info->dynamic_artwork_list);
1912 return mus_info[list_pos];
1915 int getSoundListPropertyMappingSize()
1917 return sound_info->num_property_mapping_entries;
1920 int getMusicListPropertyMappingSize()
1922 return music_info->num_property_mapping_entries;
1925 struct PropertyMapping *getSoundListPropertyMapping()
1927 return sound_info->property_mapping;
1930 struct PropertyMapping *getMusicListPropertyMapping()
1932 return music_info->property_mapping;
1935 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1936 struct ConfigTypeInfo *config_suffix_list,
1937 char **base_prefixes, char **ext1_suffixes,
1938 char **ext2_suffixes, char **ext3_suffixes,
1939 char **ignore_tokens)
1943 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1944 sound_info->type = ARTWORK_TYPE_SOUNDS;
1946 /* ---------- initialize file list and suffix lists ---------- */
1948 sound_info->num_file_list_entries = num_file_list_entries;
1949 sound_info->num_dynamic_file_list_entries = 0;
1951 sound_info->file_list =
1952 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
1953 num_file_list_entries);
1954 sound_info->dynamic_file_list = NULL;
1956 sound_info->num_suffix_list_entries = 0;
1957 for (i = 0; config_suffix_list[i].token != NULL; i++)
1958 sound_info->num_suffix_list_entries++;
1960 sound_info->suffix_list = config_suffix_list;
1962 /* ---------- initialize base prefix and suffixes lists ---------- */
1964 sound_info->num_base_prefixes = 0;
1965 for (i = 0; base_prefixes[i] != NULL; i++)
1966 sound_info->num_base_prefixes++;
1968 sound_info->num_ext1_suffixes = 0;
1969 for (i = 0; ext1_suffixes[i] != NULL; i++)
1970 sound_info->num_ext1_suffixes++;
1972 sound_info->num_ext2_suffixes = 0;
1973 for (i = 0; ext2_suffixes[i] != NULL; i++)
1974 sound_info->num_ext2_suffixes++;
1976 sound_info->num_ext3_suffixes = 0;
1977 for (i = 0; ext3_suffixes[i] != NULL; i++)
1978 sound_info->num_ext3_suffixes++;
1980 sound_info->num_ignore_tokens = 0;
1981 for (i = 0; ignore_tokens[i] != NULL; i++)
1982 sound_info->num_ignore_tokens++;
1984 sound_info->base_prefixes = base_prefixes;
1985 sound_info->ext1_suffixes = ext1_suffixes;
1986 sound_info->ext2_suffixes = ext2_suffixes;
1987 sound_info->ext3_suffixes = ext3_suffixes;
1988 sound_info->ignore_tokens = ignore_tokens;
1990 sound_info->num_property_mapping_entries = 0;
1992 sound_info->property_mapping = NULL;
1994 /* ---------- initialize artwork reference and content lists ---------- */
1996 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
1998 sound_info->artwork_list =
1999 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
2000 sound_info->dynamic_artwork_list = NULL;
2002 sound_info->content_list = NULL;
2004 /* ---------- initialize artwork loading/freeing functions ---------- */
2006 sound_info->load_artwork = Load_WAV;
2007 sound_info->free_artwork = FreeSound;
2010 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
2011 struct ConfigTypeInfo *config_suffix_list,
2012 char **base_prefixes, char **ext1_suffixes,
2013 char **ext2_suffixes, char **ext3_suffixes,
2014 char **ignore_tokens)
2018 music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2019 music_info->type = ARTWORK_TYPE_MUSIC;
2021 /* ---------- initialize file list and suffix lists ---------- */
2023 music_info->num_file_list_entries = num_file_list_entries;
2024 music_info->num_dynamic_file_list_entries = 0;
2026 music_info->file_list =
2027 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2028 num_file_list_entries);
2029 music_info->dynamic_file_list = NULL;
2031 music_info->num_suffix_list_entries = 0;
2032 for (i = 0; config_suffix_list[i].token != NULL; i++)
2033 music_info->num_suffix_list_entries++;
2035 music_info->suffix_list = config_suffix_list;
2037 /* ---------- initialize base prefix and suffixes lists ---------- */
2039 music_info->num_base_prefixes = 0;
2040 for (i = 0; base_prefixes[i] != NULL; i++)
2041 music_info->num_base_prefixes++;
2043 music_info->num_ext1_suffixes = 0;
2044 for (i = 0; ext1_suffixes[i] != NULL; i++)
2045 music_info->num_ext1_suffixes++;
2047 music_info->num_ext2_suffixes = 0;
2048 for (i = 0; ext2_suffixes[i] != NULL; i++)
2049 music_info->num_ext2_suffixes++;
2051 music_info->num_ext3_suffixes = 0;
2052 for (i = 0; ext3_suffixes[i] != NULL; i++)
2053 music_info->num_ext3_suffixes++;
2055 music_info->num_ignore_tokens = 0;
2056 for (i = 0; ignore_tokens[i] != NULL; i++)
2057 music_info->num_ignore_tokens++;
2059 music_info->base_prefixes = base_prefixes;
2060 music_info->ext1_suffixes = ext1_suffixes;
2061 music_info->ext2_suffixes = ext2_suffixes;
2062 music_info->ext3_suffixes = ext3_suffixes;
2063 music_info->ignore_tokens = ignore_tokens;
2065 music_info->num_property_mapping_entries = 0;
2067 music_info->property_mapping = NULL;
2069 /* ---------- initialize artwork reference and content lists ---------- */
2071 music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2073 music_info->artwork_list =
2074 checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2075 music_info->dynamic_artwork_list = NULL;
2077 music_info->content_list = NULL;
2079 /* ---------- initialize artwork loading/freeing functions ---------- */
2081 music_info->load_artwork = Load_WAV_or_MOD;
2082 music_info->free_artwork = FreeMusic;
2085 void PlayMusic(int nr)
2087 if (!audio.music_available)
2093 void PlaySound(int nr)
2095 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2098 void PlaySoundStereo(int nr, int stereo_position)
2100 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2103 void PlaySoundLoop(int nr)
2105 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2108 void PlaySoundMusic(int nr)
2110 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2113 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2115 SoundControl snd_ctrl;
2117 if (!audio.sound_available ||
2118 !audio.sound_enabled ||
2119 audio.sound_deactivated)
2122 volume = SETUP_SOUND_VOLUME(volume, state);
2124 if (volume < SOUND_MIN_VOLUME)
2125 volume = SOUND_MIN_VOLUME;
2126 else if (volume > SOUND_MAX_VOLUME)
2127 volume = SOUND_MAX_VOLUME;
2129 if (stereo_position < SOUND_MAX_LEFT)
2130 stereo_position = SOUND_MAX_LEFT;
2131 else if (stereo_position > SOUND_MAX_RIGHT)
2132 stereo_position = SOUND_MAX_RIGHT;
2134 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2136 snd_ctrl.active = TRUE;
2138 snd_ctrl.volume = volume;
2139 snd_ctrl.stereo_position = stereo_position;
2140 snd_ctrl.state = state;
2142 HandleSoundRequest(snd_ctrl);
2145 void FadeMusic(void)
2147 if (!audio.music_available)
2150 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2153 void FadeSound(int nr)
2155 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2160 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2163 void FadeSoundsAndMusic()
2169 void StopMusic(void)
2171 if (!audio.music_available)
2174 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2177 void StopSound(int nr)
2179 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2185 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2188 void StopSoundExt(int nr, int state)
2190 SoundControl snd_ctrl;
2192 if (!audio.sound_available)
2195 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2197 snd_ctrl.active = FALSE;
2199 snd_ctrl.state = state;
2201 HandleSoundRequest(snd_ctrl);
2204 static void ReloadCustomSounds()
2207 printf("::: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2210 LoadArtworkConfig(sound_info);
2211 ReloadCustomArtworkList(sound_info);
2214 static void ReloadCustomMusic()
2217 printf("::: reloading music '%s' ...\n", artwork.mus_current_identifier);
2220 LoadArtworkConfig(music_info);
2221 ReloadCustomArtworkList(music_info);
2223 /* load all music files from directory not defined in "musicinfo.conf" */
2224 LoadCustomMusic_NoConf();
2227 void InitReloadCustomSounds(char *set_identifier)
2229 if (!audio.sound_available)
2232 #if defined(AUDIO_UNIX_NATIVE)
2233 LoadArtworkConfig(sound_info); /* also load config on sound client */
2234 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2236 ReloadCustomSounds();
2240 void InitReloadCustomMusic(char *set_identifier)
2242 if (!audio.music_available)
2245 #if defined(AUDIO_UNIX_NATIVE)
2246 LoadArtworkConfig(music_info); /* also load config on sound client */
2247 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2249 ReloadCustomMusic();
2253 void FreeSound(void *ptr)
2255 SoundInfo *sound = (SoundInfo *)ptr;
2260 if (sound->data_ptr)
2262 #if defined(TARGET_SDL)
2263 Mix_FreeChunk(sound->data_ptr);
2264 #elif defined(TARGET_ALLEGRO)
2265 destroy_sample(sound->data_ptr);
2266 #else /* AUDIO_UNIX_NATIVE */
2267 free(sound->data_ptr);
2271 checked_free(sound->source_filename);
2276 void FreeMusic(void *ptr)
2278 MusicInfo *music = (MusicInfo *)ptr;
2283 if (music->data_ptr)
2285 #if defined(TARGET_SDL)
2286 if (music->type == MUS_TYPE_MOD)
2287 Mix_FreeMusic(music->data_ptr);
2289 Mix_FreeChunk(music->data_ptr);
2290 #elif defined(TARGET_ALLEGRO)
2291 destroy_sample(music->data_ptr);
2292 #else /* AUDIO_UNIX_NATIVE */
2293 free(music->data_ptr);
2300 static void FreeAllMusic_NoConf()
2304 if (Music_NoConf == NULL)
2307 for (i = 0; i < num_music_noconf; i++)
2308 FreeMusic(Music_NoConf[i]);
2312 Music_NoConf = NULL;
2313 num_music_noconf = 0;
2316 void FreeAllSounds()
2318 FreeCustomArtworkLists(sound_info);
2323 FreeCustomArtworkLists(music_info);
2324 FreeAllMusic_NoConf();
2327 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2328 /* ========================================================================= */