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;
153 static SoundInfo **Sound = NULL;
155 static MusicInfo **Music = NULL;
157 static int num_sounds = 0;
159 static int num_music = 0;
160 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
163 /* ========================================================================= */
164 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
166 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
167 static int mixer_active_channels = 0;
169 #if defined(AUDIO_UNIX_NATIVE)
170 static struct AudioFormatInfo afmt;
172 static void Mixer_Main(void);
173 #if !defined(AUDIO_STREAMING_DSP)
174 static unsigned char linear_to_ulaw(int);
175 static int ulaw_to_linear(unsigned char);
179 static void ReloadCustomSounds();
180 static void ReloadCustomMusic();
181 static void FreeSound(void *);
183 static SoundInfo *getSoundInfoEntryFromSoundID(int);
186 /* ------------------------------------------------------------------------- */
187 /* functions for native (non-SDL) Unix audio/mixer support */
188 /* ------------------------------------------------------------------------- */
190 #if defined(AUDIO_UNIX_NATIVE)
192 static int OpenAudioDevice(char *audio_device_name)
196 /* check if desired audio device is accessible */
197 if (access(audio_device_name, W_OK) != 0)
200 /* try to open audio device in non-blocking mode */
201 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
202 return audio_device_fd;
204 /* re-open audio device in blocking mode */
205 close(audio_device_fd);
206 audio_device_fd = open(audio_device_name, O_WRONLY);
208 return audio_device_fd;
211 static void CloseAudioDevice(int *audio_device_fd)
213 if (*audio_device_fd == 0)
216 close(*audio_device_fd);
217 *audio_device_fd = -1;
220 static boolean TestAudioDevices(void)
222 static char *audio_device_name[] =
225 DEVICENAME_SOUND_DSP,
228 int audio_device_fd = -1;
231 /* look for available audio devices, starting with preferred ones */
232 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
233 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
236 if (audio_device_fd < 0)
238 Error(ERR_WARN, "cannot open audio device -- no sound");
242 close(audio_device_fd);
244 audio.device_name = audio_device_name[i];
249 static boolean ForkAudioProcess(void)
251 if (pipe(audio.mixer_pipe) < 0)
253 Error(ERR_WARN, "cannot create pipe -- no sounds");
257 if ((audio.mixer_pid = fork()) < 0)
259 Error(ERR_WARN, "cannot create sound server process -- no sounds");
263 if (audio.mixer_pid == 0) /* we are the child process */
264 audio.mixer_pid = getpid();
267 printf("PID: %d [%s]\n", getpid(),(IS_CHILD_PROCESS() ? "child" : "parent"));
271 if (IS_CHILD_PROCESS())
272 Mixer_Main(); /* this function never returns */
274 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
279 void UnixOpenAudio(void)
281 if (!TestAudioDevices())
284 audio.sound_available = TRUE;
285 audio.sound_enabled = TRUE;
287 #if defined(AUDIO_STREAMING_DSP)
288 audio.music_available = TRUE;
289 audio.loops_available = TRUE;
292 audio.num_channels = NUM_MIXER_CHANNELS;
293 audio.music_channel = MUSIC_CHANNEL;
294 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
297 void UnixCloseAudio(void)
300 close(audio.device_fd);
302 if (IS_PARENT_PROCESS())
303 kill(audio.mixer_pid, SIGTERM);
307 /* ------------------------------------------------------------------------- */
308 /* functions for platform specific audio device initialization */
309 /* ------------------------------------------------------------------------- */
311 #if defined(AUDIO_LINUX_IOCTL)
312 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
314 /* "ioctl()" expects pointer to 'int' value for stereo flag
315 (boolean is defined as 'char', which will not work here) */
316 unsigned int fragment_spec = 0;
317 int fragment_size_query;
326 /* supported audio format in preferred order */
327 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
328 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
329 { AFMT_U8, AUDIO_FORMAT_U8 },
334 /* determine logarithm (log2) of the fragment size */
335 while ((1 << fragment_spec) < afmt->fragment_size)
338 /* use two fragments (play one fragment, prepare the other);
339 one fragment would result in interrupted audio output, more
340 than two fragments would raise audio output latency to much */
341 fragment_spec |= 0x00020000;
343 /* Example for fragment specification:
344 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
345 - (with stereo the effective buffer size will shrink to 256)
346 => fragment_size = 0x00020009 */
348 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
349 Error(ERR_EXIT_SOUND_SERVER,
350 "cannot set fragment size of audio device -- no sounds");
354 while (formats[i].format_result != -1)
356 unsigned int audio_format = formats[i].format_ioctl;
357 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
359 afmt->format = formats[i].format_result;
364 if (afmt->format == 0) /* no supported audio format found */
365 Error(ERR_EXIT_SOUND_SERVER,
366 "cannot set audio format of audio device -- no sounds");
368 /* try if we can use stereo sound */
370 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
371 afmt->stereo = FALSE;
373 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
374 Error(ERR_EXIT_SOUND_SERVER,
375 "cannot set sample rate of audio device -- no sounds");
377 /* get the real fragmentation size; this should return 512 */
378 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
379 Error(ERR_EXIT_SOUND_SERVER,
380 "cannot get fragment size of audio device -- no sounds");
381 if (fragment_size_query != afmt->fragment_size)
382 Error(ERR_EXIT_SOUND_SERVER,
383 "cannot set fragment size of audio device -- no sounds");
385 #endif /* AUDIO_LINUX_IOCTL */
387 #if defined(PLATFORM_NETBSD)
388 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
391 boolean stereo = TRUE;
393 AUDIO_INITINFO(&a_info);
394 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
395 a_info.play.precision = 8;
396 a_info.play.channels = 2;
397 a_info.play.sample_rate = afmt->sample_rate;
398 a_info.blocksize = afmt->fragment_size;
400 afmt->format = AUDIO_FORMAT_U8;
403 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
405 /* try to disable stereo */
406 a_info.play.channels = 1;
408 afmt->stereo = FALSE;
410 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
411 Error(ERR_EXIT_SOUND_SERVER,
412 "cannot set sample rate of audio device -- no sounds");
415 #endif /* PLATFORM_NETBSD */
417 #if defined(PLATFORM_HPUX)
418 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
420 struct audio_describe ainfo;
423 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
425 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
427 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
428 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
430 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
431 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
433 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
434 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
436 afmt->format = AUDIO_FORMAT_U8;
437 afmt->stereo = FALSE;
438 afmt->sample_rate = 8000;
442 #endif /* PLATFORM_HPUX */
444 static void InitAudioDevice(struct AudioFormatInfo *afmt)
447 afmt->format = AUDIO_FORMAT_UNKNOWN;
448 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
449 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
451 #if defined(AUDIO_LINUX_IOCTL)
452 InitAudioDevice_Linux(afmt);
453 #elif defined(PLATFORM_NETBSD)
454 InitAudioDevice_NetBSD(afmt);
455 #elif defined(PLATFORM_HPUX)
456 InitAudioDevice_HPUX(afmt);
458 /* generic /dev/audio stuff might be placed here */
463 /* ------------------------------------------------------------------------- */
464 /* functions for communication between main process and sound mixer process */
465 /* ------------------------------------------------------------------------- */
467 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
469 if (IS_CHILD_PROCESS())
472 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
474 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
475 audio.sound_available = audio.sound_enabled = FALSE;
480 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
482 if (IS_PARENT_PROCESS())
485 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
486 != sizeof(SoundControl))
487 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
490 static void WriteReloadInfoToPipe(char *set_identifier, int type)
492 SoundControl snd_ctrl;
493 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
494 artwork.mus_current);
495 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
496 unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
497 unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
498 unsigned long str_size4 = strlen(ti->basepath) + 1;
499 unsigned long str_size5 = strlen(ti->fullpath) + 1;
500 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
501 setup.override_level_sounds :
502 setup.override_level_music);
504 if (IS_CHILD_PROCESS())
507 if (leveldir_current == NULL) /* should never happen */
508 Error(ERR_EXIT, "leveldir_current == NULL");
510 snd_ctrl.active = FALSE;
511 snd_ctrl.state = type;
512 snd_ctrl.data_len = strlen(set_identifier) + 1;
514 if (write(audio.mixer_pipe[1], &snd_ctrl,
515 sizeof(snd_ctrl)) < 0 ||
516 write(audio.mixer_pipe[1], set_identifier,
517 snd_ctrl.data_len) < 0 ||
518 write(audio.mixer_pipe[1], &override_level_artwork,
519 sizeof(boolean)) < 0 ||
520 write(audio.mixer_pipe[1], leveldir_current,
521 sizeof(TreeInfo)) < 0 ||
522 write(audio.mixer_pipe[1], ti,
523 sizeof(TreeInfo)) < 0 ||
524 write(audio.mixer_pipe[1], &str_size1,
525 sizeof(unsigned long)) < 0 ||
526 write(audio.mixer_pipe[1], &str_size2,
527 sizeof(unsigned long)) < 0 ||
528 write(audio.mixer_pipe[1], &str_size3,
529 sizeof(unsigned long)) < 0 ||
530 write(audio.mixer_pipe[1], &str_size4,
531 sizeof(unsigned long)) < 0 ||
532 write(audio.mixer_pipe[1], &str_size5,
533 sizeof(unsigned long)) < 0 ||
534 write(audio.mixer_pipe[1], leveldir_current->fullpath,
536 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
538 write(audio.mixer_pipe[1], leveldir_current->music_path,
540 write(audio.mixer_pipe[1], ti->basepath,
542 write(audio.mixer_pipe[1], ti->fullpath,
545 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
546 audio.sound_available = audio.sound_enabled = FALSE;
551 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
553 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
554 &artwork.snd_current : &artwork.mus_current);
555 TreeInfo *ti = *ti_ptr;
556 unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
557 static char *set_identifier = NULL;
558 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
559 &setup.override_level_sounds :
560 &setup.override_level_music);
563 free(set_identifier);
565 set_identifier = checked_malloc(snd_ctrl->data_len);
567 if (leveldir_current == NULL)
568 leveldir_current = checked_calloc(sizeof(TreeInfo));
571 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
572 if (leveldir_current->fullpath != NULL)
573 free(leveldir_current->fullpath);
574 if (leveldir_current->sounds_path != NULL)
575 free(leveldir_current->sounds_path);
576 if (leveldir_current->music_path != NULL)
577 free(leveldir_current->music_path);
578 if (ti->basepath != NULL)
580 if (ti->fullpath != NULL)
583 if (read(audio.mixer_pipe[0], set_identifier,
584 snd_ctrl->data_len) != snd_ctrl->data_len ||
585 read(audio.mixer_pipe[0], override_level_artwork,
586 sizeof(boolean)) != sizeof(boolean) ||
587 read(audio.mixer_pipe[0], leveldir_current,
588 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
589 read(audio.mixer_pipe[0], ti,
590 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
591 read(audio.mixer_pipe[0], &str_size1,
592 sizeof(unsigned long)) != sizeof(unsigned long) ||
593 read(audio.mixer_pipe[0], &str_size2,
594 sizeof(unsigned long)) != sizeof(unsigned long) ||
595 read(audio.mixer_pipe[0], &str_size3,
596 sizeof(unsigned long)) != sizeof(unsigned long) ||
597 read(audio.mixer_pipe[0], &str_size4,
598 sizeof(unsigned long)) != sizeof(unsigned long) ||
599 read(audio.mixer_pipe[0], &str_size5,
600 sizeof(unsigned long)) != sizeof(unsigned long))
601 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
603 leveldir_current->fullpath = checked_calloc(str_size1);
604 leveldir_current->sounds_path = checked_calloc(str_size2);
605 leveldir_current->music_path = checked_calloc(str_size3);
606 ti->basepath = checked_calloc(str_size4);
607 ti->fullpath = checked_calloc(str_size5);
609 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
610 str_size1) != str_size1 ||
611 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
612 str_size2) != str_size2 ||
613 read(audio.mixer_pipe[0], leveldir_current->music_path,
614 str_size3) != str_size3 ||
615 read(audio.mixer_pipe[0], ti->basepath,
616 str_size4) != str_size4 ||
617 read(audio.mixer_pipe[0], ti->fullpath,
618 str_size5) != str_size5)
619 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
621 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
622 artwork.snd_current_identifier = set_identifier;
624 artwork.mus_current_identifier = set_identifier;
627 #endif /* AUDIO_UNIX_NATIVE */
630 /* ------------------------------------------------------------------------- */
631 /* mixer functions */
632 /* ------------------------------------------------------------------------- */
634 void Mixer_InitChannels()
638 for(i=0; i<audio.num_channels; i++)
639 mixer[i].active = FALSE;
640 mixer_active_channels = 0;
643 static void Mixer_ResetChannelExpiration(int channel)
645 mixer[channel].playing_starttime = Counter();
647 #if defined(TARGET_SDL)
648 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
649 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
653 static boolean Mixer_ChannelExpired(int channel)
655 if (!mixer[channel].active)
658 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
659 DelayReached(&mixer[channel].playing_starttime,
660 SOUND_LOOP_EXPIRATION_TIME))
663 #if defined(TARGET_SDL)
665 if (!Mix_Playing(channel))
668 #elif defined(TARGET_ALLEGRO)
670 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
671 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
673 /* sound sample has completed playing or was completely faded out */
674 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
677 #endif /* TARGET_ALLEGRO */
682 static boolean Mixer_AllocateChannel(int channel)
684 #if defined(TARGET_ALLEGRO)
685 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
686 if (mixer[channel].voice < 0)
693 static void Mixer_SetChannelProperties(int channel)
695 #if defined(TARGET_SDL)
696 Mix_Volume(channel, mixer[channel].volume);
697 Mix_SetPanning(channel,
698 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
699 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
700 #elif defined(TARGET_ALLEGRO)
701 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
702 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
706 static void Mixer_StartChannel(int channel)
708 #if defined(TARGET_SDL)
709 Mix_PlayChannel(channel, mixer[channel].data_ptr,
710 IS_LOOP(mixer[channel]) ? -1 : 0);
711 #elif defined(TARGET_ALLEGRO)
712 if (IS_LOOP(mixer[channel]))
713 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
715 voice_start(mixer[channel].voice);
719 static void Mixer_PlayChannel(int channel)
721 /* start with inactive channel in case something goes wrong */
722 mixer[channel].active = FALSE;
724 if (mixer[channel].type != MUS_TYPE_WAV)
727 if (!Mixer_AllocateChannel(channel))
730 Mixer_SetChannelProperties(channel);
731 Mixer_StartChannel(channel);
733 Mixer_ResetChannelExpiration(channel);
735 mixer[channel].playing_pos = 0;
736 mixer[channel].active = TRUE;
737 mixer_active_channels++;
740 static void Mixer_PlayMusicChannel()
742 Mixer_PlayChannel(audio.music_channel);
744 #if defined(TARGET_SDL)
745 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
747 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
748 this looks like a bug in the SDL_mixer library */
749 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
750 Mix_VolumeMusic(SOUND_MAX_VOLUME);
755 static void Mixer_StopChannel(int channel)
757 if (!mixer[channel].active)
760 #if defined(TARGET_SDL)
761 Mix_HaltChannel(channel);
762 #elif defined(TARGET_ALLEGRO)
763 voice_set_volume(mixer[channel].voice, 0);
764 deallocate_voice(mixer[channel].voice);
767 mixer[channel].active = FALSE;
768 mixer_active_channels--;
771 static void Mixer_StopMusicChannel()
773 Mixer_StopChannel(audio.music_channel);
775 #if defined(TARGET_SDL)
780 static void Mixer_FadeChannel(int channel)
782 if (!mixer[channel].active)
785 mixer[channel].state |= SND_CTRL_FADE;
787 #if defined(TARGET_SDL)
788 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
789 #elif defined(TARGET_ALLEGRO)
790 if (voice_check(mixer[channel].voice))
791 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
795 static void Mixer_FadeMusicChannel()
797 Mixer_FadeChannel(audio.music_channel);
799 #if defined(TARGET_SDL)
800 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
804 static void Mixer_UnFadeChannel(int channel)
806 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
809 mixer[channel].state &= ~SND_CTRL_FADE;
810 mixer[channel].volume = SOUND_MAX_VOLUME;
812 #if defined(TARGET_SDL)
813 Mix_ExpireChannel(channel, -1);
814 Mix_Volume(channel, mixer[channel].volume);
815 #elif defined(TARGET_ALLEGRO)
816 voice_stop_volumeramp(mixer[channel].voice);
817 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
818 mixer[channel].volume);
822 static void Mixer_InsertSound(SoundControl snd_ctrl)
826 int num_sounds = getSoundListSize();
829 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
830 snd_ctrl.nr, num_sounds, mixer_active_channels);
833 if (IS_MUSIC(snd_ctrl))
838 snd_ctrl.nr = snd_ctrl.nr % num_music;
840 else if (snd_ctrl.nr >= num_sounds)
844 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
846 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] :
847 getSoundInfoEntryFromSoundID(snd_ctrl.nr));
850 if (snd_info == NULL)
853 /* copy sound sample and format information */
854 snd_ctrl.type = snd_info->type;
855 snd_ctrl.format = snd_info->format;
856 snd_ctrl.data_ptr = snd_info->data_ptr;
857 snd_ctrl.data_len = snd_info->data_len;
858 snd_ctrl.num_channels = snd_info->num_channels;
860 /* play music samples on a dedicated music channel */
861 if (IS_MUSIC(snd_ctrl))
863 Mixer_StopMusicChannel();
865 mixer[audio.music_channel] = snd_ctrl;
866 Mixer_PlayMusicChannel();
871 /* check if (and how often) this sound sample is already playing */
872 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
873 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
877 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
880 /* reset expiration delay for already playing loop sounds */
881 if (k > 0 && IS_LOOP(snd_ctrl))
883 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
885 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
888 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
891 if (IS_FADING(mixer[i]))
892 Mixer_UnFadeChannel(i);
894 /* restore settings like volume and stereo position */
895 mixer[i].volume = snd_ctrl.volume;
896 mixer[i].stereo_position = snd_ctrl.stereo_position;
898 Mixer_SetChannelProperties(i);
899 Mixer_ResetChannelExpiration(i);
902 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
903 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
912 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
915 /* don't play sound more than n times simultaneously (with n == 2 for now) */
918 unsigned long playing_current = Counter();
919 int longest = 0, longest_nr = audio.first_sound_channel;
921 /* look for oldest equal sound */
922 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
924 int playing_time = playing_current - mixer[i].playing_starttime;
927 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
930 actual = 1000 * playing_time / mixer[i].data_len;
932 if (actual >= longest)
939 Mixer_StopChannel(longest_nr);
942 /* If all (non-music) channels are active, stop the channel that has
943 played its sound sample most completely (in percent of the sample
944 length). As we cannot currently get the actual playing position
945 of the channel's sound sample when compiling with the SDL mixer
946 library, we use the current playing time (in milliseconds) instead. */
949 /* channel allocation sanity check -- should not be needed */
950 if (mixer_active_channels ==
951 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
953 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
955 if (!mixer[i].active)
957 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
958 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
960 mixer_active_channels--;
966 if (mixer_active_channels ==
967 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
969 unsigned long playing_current = Counter();
970 int longest = 0, longest_nr = audio.first_sound_channel;
974 /* print some debugging information about audio channel usage */
975 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
977 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
978 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
983 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
985 int playing_time = playing_current - mixer[i].playing_starttime;
986 int actual = 1000 * playing_time / mixer[i].data_len;
988 if (!IS_LOOP(mixer[i]) && actual > longest)
995 Mixer_StopChannel(longest_nr);
998 /* add the new sound to the mixer */
999 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1002 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
1005 if (!mixer[i].active)
1008 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
1011 #if defined(AUDIO_UNIX_NATIVE)
1012 if (snd_info->data_len == 0)
1014 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1018 mixer[i] = snd_ctrl;
1019 Mixer_PlayChannel(i);
1026 static void HandleSoundRequest(SoundControl snd_ctrl)
1030 #if defined(AUDIO_UNIX_NATIVE)
1031 if (IS_PARENT_PROCESS())
1033 SendSoundControlToMixerProcess(&snd_ctrl);
1038 /* deactivate channels that have expired since the last request */
1039 for (i=0; i<audio.num_channels; i++)
1040 if (mixer[i].active && Mixer_ChannelExpired(i))
1041 Mixer_StopChannel(i);
1043 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1045 Mixer_StopMusicChannel();
1046 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1047 Mixer_StopChannel(i);
1049 #if defined(AUDIO_UNIX_NATIVE)
1050 CloseAudioDevice(&audio.device_fd);
1051 ReadReloadInfoFromPipe(&snd_ctrl);
1054 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1055 ReloadCustomSounds();
1057 ReloadCustomMusic();
1059 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1061 if (IS_MUSIC(snd_ctrl))
1063 Mixer_FadeMusicChannel();
1067 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1068 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1069 Mixer_FadeChannel(i);
1071 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1073 if (IS_MUSIC(snd_ctrl))
1075 Mixer_StopMusicChannel();
1079 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1080 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1081 Mixer_StopChannel(i);
1083 #if defined(AUDIO_UNIX_NATIVE)
1084 if (!mixer_active_channels)
1085 CloseAudioDevice(&audio.device_fd);
1088 else if (snd_ctrl.active) /* add new sound to mixer */
1090 Mixer_InsertSound(snd_ctrl);
1094 void StartMixer(void)
1099 SDL_version compile_version;
1100 const SDL_version *link_version;
1101 MIX_VERSION(&compile_version);
1102 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1103 compile_version.major,
1104 compile_version.minor,
1105 compile_version.patch);
1106 link_version = Mix_Linked_Version();
1107 printf("running with SDL_mixer version: %d.%d.%d\n",
1108 link_version->major,
1109 link_version->minor,
1110 link_version->patch);
1113 if (!audio.sound_available)
1116 /* initialize stereo position conversion information */
1117 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1119 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1121 #if defined(AUDIO_UNIX_NATIVE)
1122 if (!ForkAudioProcess())
1123 audio.sound_available = FALSE;
1127 #if defined(AUDIO_UNIX_NATIVE)
1129 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1130 int sample_pos, int sample_size,
1131 short *buffer_base_ptr, int buffer_pos,
1132 int num_output_channels)
1134 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1135 int num_channels = snd_ctrl->num_channels;
1136 int stepsize = num_channels;
1137 int output_stepsize = num_output_channels;
1140 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1142 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1144 for (i=0; i<num_output_channels; i++)
1146 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1148 for (j=0; j<sample_size; j++)
1149 buffer_ptr[output_stepsize * j + i] =
1150 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1153 else /* AUDIO_FORMAT_S16 */
1155 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1157 for (i=0; i<num_output_channels; i++)
1159 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1161 for (j=0; j<sample_size; j++)
1162 buffer_ptr[output_stepsize * j + i] =
1163 sample_ptr[stepsize * j + offset];
1168 #if defined(AUDIO_STREAMING_DSP)
1169 static void Mixer_Main_DSP()
1171 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1172 static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1173 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1177 int max_sample_size;
1178 int num_output_channels;
1181 if (!mixer_active_channels)
1184 if (audio.device_fd < 0)
1186 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1189 InitAudioDevice(&afmt);
1192 stereo = afmt.stereo;
1193 fragment_size = afmt.fragment_size;
1194 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1195 num_output_channels = (stereo ? 2 : 1);
1196 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1198 /* first clear the last premixing buffer */
1199 memset(premix_last_buffer, 0,
1200 max_sample_size * num_output_channels * sizeof(long));
1202 for(i=0; i<audio.num_channels; i++)
1209 if (!mixer[i].active)
1212 if (Mixer_ChannelExpired(i))
1214 Mixer_StopChannel(i);
1218 /* pointer, lenght and actual playing position of sound sample */
1219 sample_ptr = mixer[i].data_ptr;
1220 sample_len = mixer[i].data_len;
1221 sample_pos = mixer[i].playing_pos;
1222 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1223 mixer[i].playing_pos += sample_size;
1225 /* copy original sample to first mixing buffer */
1226 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1227 premix_first_buffer, 0, num_output_channels);
1229 /* are we about to restart a looping sound? */
1230 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1232 while (sample_size < max_sample_size)
1234 int restarted_sample_size =
1235 MIN(max_sample_size - sample_size, sample_len);
1237 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1238 premix_first_buffer, sample_size,
1239 num_output_channels);
1241 mixer[i].playing_pos = restarted_sample_size;
1242 sample_size += restarted_sample_size;
1246 /* decrease volume if sound is fading out */
1247 if (IS_FADING(mixer[i]) &&
1248 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1249 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1251 /* adjust volume of actual sound sample */
1252 if (mixer[i].volume != SOUND_MAX_VOLUME)
1253 for(j=0; j<sample_size * num_output_channels; j++)
1254 premix_first_buffer[j] =
1255 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1257 /* adjust left and right channel volume due to stereo sound position */
1260 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1261 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1263 for(j=0; j<sample_size; j++)
1265 premix_first_buffer[2 * j + 0] =
1266 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1267 premix_first_buffer[2 * j + 1] =
1268 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1272 /* fill the last mixing buffer with stereo or mono sound */
1273 for(j=0; j<sample_size * num_output_channels; j++)
1274 premix_last_buffer[j] += premix_first_buffer[j];
1276 /* delete completed sound entries from the mixer */
1277 if (mixer[i].playing_pos >= mixer[i].data_len)
1279 if (IS_LOOP(mixer[i]))
1280 mixer[i].playing_pos = 0;
1282 Mixer_StopChannel(i);
1284 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1285 Mixer_StopChannel(i);
1288 /* prepare final playing buffer according to system audio format */
1289 for(i=0; i<max_sample_size * num_output_channels; i++)
1291 /* cut off at 17 bit value */
1292 if (premix_last_buffer[i] < -65535)
1293 premix_last_buffer[i] = -65535;
1294 else if (premix_last_buffer[i] > 65535)
1295 premix_last_buffer[i] = 65535;
1297 /* shift to 16 bit value */
1298 premix_last_buffer[i] >>= 1;
1300 if (afmt.format & AUDIO_FORMAT_U8)
1302 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1304 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1306 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1307 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1309 else /* big endian */
1311 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1312 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1316 /* finally play the sound fragment */
1317 write(audio.device_fd, playing_buffer, fragment_size);
1319 if (!mixer_active_channels)
1320 CloseAudioDevice(&audio.device_fd);
1323 #else /* !AUDIO_STREAMING_DSP */
1325 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1327 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1328 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1329 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1330 int num_output_channels = 1;
1339 /* pointer, lenght and actual playing position of sound sample */
1340 sample_ptr = mixer[i].data_ptr;
1341 sample_len = mixer[i].data_len;
1342 sample_pos = mixer[i].playing_pos;
1343 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1344 mixer[i].playing_pos += sample_size;
1346 /* copy original sample to first mixing buffer */
1347 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1348 premix_first_buffer, 0, num_output_channels);
1350 /* adjust volume of actual sound sample */
1351 if (mixer[i].volume != SOUND_MAX_VOLUME)
1352 for(j=0; j<sample_size; j++)
1353 premix_first_buffer[j] =
1354 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1356 /* might be needed for u-law /dev/audio */
1358 for(j=0; j<sample_size; j++)
1360 linear_to_ulaw(premix_first_buffer[j]);
1363 /* delete completed sound entries from the mixer */
1364 if (mixer[i].playing_pos >= mixer[i].data_len)
1365 Mixer_StopChannel(i);
1367 for(i=0; i<sample_size; i++)
1368 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1370 /* finally play the sound fragment */
1371 write(audio.device_fd, playing_buffer, sample_size);
1375 #endif /* !AUDIO_STREAMING_DSP */
1379 SoundControl snd_ctrl;
1382 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1384 Mixer_InitChannels();
1386 #if defined(PLATFORM_HPUX)
1387 InitAudioDevice(&afmt);
1390 FD_ZERO(&mixer_fdset);
1391 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1393 while(1) /* wait for sound playing commands from client */
1395 struct timeval delay = { 0, 0 };
1397 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1398 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1399 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1402 ReadSoundControlFromMainProcess(&snd_ctrl);
1404 HandleSoundRequest(snd_ctrl);
1406 #if defined(AUDIO_STREAMING_DSP)
1408 while (mixer_active_channels &&
1409 select(audio.mixer_pipe[0] + 1,
1410 &mixer_fdset, NULL, NULL, &delay) < 1)
1412 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1417 #else /* !AUDIO_STREAMING_DSP */
1419 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1420 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1423 InitAudioDevice(&afmt);
1428 while (mixer_active_channels &&
1429 select(audio.mixer_pipe[0] + 1,
1430 &mixer_fdset, NULL, NULL, &delay) < 1)
1432 int wait_percent = 90; /* wait 90% of the real playing time */
1435 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1437 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1441 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1444 CloseAudioDevice(&audio.device_fd);
1446 Mixer_InitChannels(); /* remove all sounds from mixer */
1448 #endif /* !AUDIO_STREAMING_DSP */
1451 #endif /* AUDIO_UNIX_NATIVE */
1454 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1456 /* these two are stolen from "sox"... :) */
1459 ** This routine converts from linear to ulaw.
1461 ** Craig Reese: IDA/Supercomputing Research Center
1462 ** Joe Campbell: Department of Defense
1463 ** 29 September 1989
1466 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1467 ** 2) "A New Digital Technique for Implementation of Any
1468 ** Continuous PCM Companding Law," Villeret, Michel,
1469 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1470 ** 1973, pg. 11.12-11.17
1471 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1472 ** for Analog-to_Digital Conversion Techniques,"
1475 ** Input: Signed 16 bit linear sample
1476 ** Output: 8 bit ulaw sample
1479 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1480 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1483 static unsigned char linear_to_ulaw(int sample)
1485 static int exp_lut[256] =
1487 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1488 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1489 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1490 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1491 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1492 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1493 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1494 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1495 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1496 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1497 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1498 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1499 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1500 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1501 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1502 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1505 int sign, exponent, mantissa;
1506 unsigned char ulawbyte;
1508 /* Get the sample into sign-magnitude. */
1509 sign = (sample >> 8) & 0x80; /* set aside the sign */
1511 sample = -sample; /* get magnitude */
1513 sample = CLIP; /* clip the magnitude */
1515 /* Convert from 16 bit linear to ulaw. */
1516 sample = sample + BIAS;
1517 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1518 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1519 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1522 ulawbyte = 0x02; /* optional CCITT trap */
1529 ** This routine converts from ulaw to 16 bit linear.
1531 ** Craig Reese: IDA/Supercomputing Research Center
1532 ** 29 September 1989
1535 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1536 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1537 ** for Analog-to_Digital Conversion Techniques,"
1540 ** Input: 8 bit ulaw sample
1541 ** Output: signed 16 bit linear sample
1544 static int ulaw_to_linear(unsigned char ulawbyte)
1546 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1547 int sign, exponent, mantissa, sample;
1549 ulawbyte = ~ ulawbyte;
1550 sign = ( ulawbyte & 0x80 );
1551 exponent = ( ulawbyte >> 4 ) & 0x07;
1552 mantissa = ulawbyte & 0x0F;
1553 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1559 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1562 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1563 /* ========================================================================= */
1564 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1566 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1567 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1569 static void *Load_WAV(char *filename)
1571 SoundInfo *snd_info;
1572 #if defined(AUDIO_UNIX_NATIVE)
1573 struct SoundHeader_WAV header;
1575 byte sound_header_buffer[WAV_HEADER_SIZE];
1578 char chunk_name[CHUNK_ID_LEN + 1];
1584 if (!audio.sound_available)
1588 printf("loading WAV file '%s'\n", filename);
1591 snd_info = checked_calloc(sizeof(SoundInfo));
1593 #if defined(TARGET_SDL)
1595 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1597 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1602 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1604 #elif defined(TARGET_ALLEGRO)
1606 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1608 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1613 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1615 #else /* AUDIO_UNIX_NATIVE */
1617 if ((file = fopen(filename, MODE_READ)) == NULL)
1619 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1624 /* read chunk id "RIFF" */
1625 getFileChunkLE(file, chunk_name, &chunk_size);
1626 if (strcmp(chunk_name, "RIFF") != 0)
1628 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1634 /* read "RIFF" type id "WAVE" */
1635 getFileChunkLE(file, chunk_name, NULL);
1636 if (strcmp(chunk_name, "WAVE") != 0)
1638 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1644 while (getFileChunkLE(file, chunk_name, &chunk_size))
1646 if (strcmp(chunk_name, "fmt ") == 0)
1648 if (chunk_size < WAV_HEADER_SIZE)
1650 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1656 header.compression_code = getFile16BitLE(file);
1657 header.num_channels = getFile16BitLE(file);
1658 header.sample_rate = getFile32BitLE(file);
1659 header.bytes_per_second = getFile32BitLE(file);
1660 header.block_align = getFile16BitLE(file);
1661 header.bits_per_sample = getFile16BitLE(file);
1663 if (chunk_size > WAV_HEADER_SIZE)
1664 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1666 if (header.compression_code != 1)
1668 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1669 filename, header.compression_code);
1675 if (header.num_channels != 1 &&
1676 header.num_channels != 2)
1678 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1679 filename, header.num_channels);
1685 if (header.bits_per_sample != 8 &&
1686 header.bits_per_sample != 16)
1688 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1689 filename, header.bits_per_sample);
1695 /* warn, but accept wrong sample rate (may be only slightly different) */
1696 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1697 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1698 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1701 printf("WAV file: '%s'\n", filename);
1702 printf(" Compression code: %d'\n", header.compression_code);
1703 printf(" Number of channels: %d'\n", header.num_channels);
1704 printf(" Sample rate: %ld'\n", header.sample_rate);
1705 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1706 printf(" Block align: %d'\n", header.block_align);
1707 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1710 else if (strcmp(chunk_name, "data") == 0)
1712 data_byte_len = chunk_size;
1714 snd_info->data_len = data_byte_len;
1715 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1717 /* read sound data */
1718 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1721 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1723 free(snd_info->data_ptr);
1728 /* check for odd number of data bytes (data chunk is word aligned) */
1729 if ((data_byte_len % 2) == 1)
1730 ReadUnusedBytesFromFile(file, 1);
1732 else /* unknown chunk -- ignore */
1733 ReadUnusedBytesFromFile(file, chunk_size);
1738 if (snd_info->data_ptr == NULL)
1740 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1745 if (header.bits_per_sample == 8)
1746 snd_info->format = AUDIO_FORMAT_U8;
1747 else /* header.bits_per_sample == 16 */
1749 snd_info->format = AUDIO_FORMAT_S16;
1750 snd_info->data_len /= 2; /* correct number of samples */
1753 snd_info->num_channels = header.num_channels;
1754 if (header.num_channels == 2)
1755 snd_info->data_len /= 2; /* correct number of samples */
1758 if (header.num_channels == 1) /* convert mono sound to stereo */
1760 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1761 void *sample_ptr = snd_info->data_ptr;
1762 int sample_size = snd_info->data_len;
1765 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1766 for (i=0; i<sample_size; i++)
1768 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1769 else /* AUDIO_FORMAT_S16 */
1770 for (i=0; i<sample_size; i++)
1772 ((short *)sample_ptr)[i];
1776 #endif /* AUDIO_UNIX_NATIVE */
1778 snd_info->type = SND_TYPE_WAV;
1779 snd_info->source_filename = getStringCopy(filename);
1784 int getSoundListSize()
1786 return (sound_info->num_file_list_entries +
1787 sound_info->num_dynamic_file_list_entries);
1790 struct FileInfo *getSoundListEntry(int pos)
1792 int num_list_entries = sound_info->num_file_list_entries;
1793 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1795 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1796 &sound_info->dynamic_file_list[list_pos]);
1799 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1801 int num_list_entries = sound_info->num_file_list_entries;
1802 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1803 SoundInfo **snd_info =
1804 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
1805 sound_info->dynamic_artwork_list);
1807 return snd_info[list_pos];
1810 int getSoundListPropertyMappingSize()
1812 return sound_info->num_property_mapping_entries;
1815 struct PropertyMapping *getSoundListPropertyMapping()
1817 return sound_info->property_mapping;
1820 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1821 struct ConfigInfo *config_suffix_list,
1822 char **base_prefixes, char **ext1_suffixes,
1823 char **ext2_suffixes, char **ext3_suffixes,
1824 char **ignore_tokens)
1828 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1829 sound_info->type = ARTWORK_TYPE_SOUNDS;
1831 /* ---------- initialize file list and suffix lists ---------- */
1833 sound_info->num_file_list_entries = num_file_list_entries;
1834 sound_info->num_dynamic_file_list_entries = 0;
1836 sound_info->file_list =
1837 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
1838 num_file_list_entries);
1839 sound_info->dynamic_file_list = NULL;
1841 sound_info->num_suffix_list_entries = 0;
1842 for (i=0; config_suffix_list[i].token != NULL; i++)
1843 sound_info->num_suffix_list_entries++;
1845 sound_info->suffix_list = config_suffix_list;
1847 /* ---------- initialize base prefix and suffixes lists ---------- */
1849 sound_info->num_base_prefixes = 0;
1850 for (i=0; base_prefixes[i] != NULL; i++)
1851 sound_info->num_base_prefixes++;
1853 sound_info->num_ext1_suffixes = 0;
1854 for (i=0; ext1_suffixes[i] != NULL; i++)
1855 sound_info->num_ext1_suffixes++;
1857 sound_info->num_ext2_suffixes = 0;
1858 for (i=0; ext2_suffixes[i] != NULL; i++)
1859 sound_info->num_ext2_suffixes++;
1861 sound_info->num_ext3_suffixes = 0;
1862 for (i=0; ext3_suffixes[i] != NULL; i++)
1863 sound_info->num_ext3_suffixes++;
1865 sound_info->num_ignore_tokens = 0;
1866 for (i=0; ignore_tokens[i] != NULL; i++)
1867 sound_info->num_ignore_tokens++;
1869 sound_info->base_prefixes = base_prefixes;
1870 sound_info->ext1_suffixes = ext1_suffixes;
1871 sound_info->ext2_suffixes = ext2_suffixes;
1872 sound_info->ext3_suffixes = ext3_suffixes;
1873 sound_info->ignore_tokens = ignore_tokens;
1875 sound_info->num_property_mapping_entries = 0;
1877 sound_info->property_mapping = NULL;
1879 /* ---------- initialize artwork reference and content lists ---------- */
1881 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
1883 sound_info->artwork_list =
1884 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1885 sound_info->dynamic_artwork_list = NULL;
1887 sound_info->content_list = NULL;
1889 /* ---------- initialize artwork loading/freeing functions ---------- */
1891 sound_info->load_artwork = Load_WAV;
1892 sound_info->free_artwork = FreeSound;
1895 num_sounds = sound_info->num_file_list_entries;
1896 Sound = (SoundInfo **)sound_info->artwork_list;
1900 static MusicInfo *Load_MOD(char *filename)
1902 #if defined(TARGET_SDL)
1903 MusicInfo *mod_info;
1905 if (!audio.sound_available)
1908 mod_info = checked_calloc(sizeof(MusicInfo));
1910 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1912 Error(ERR_WARN, "cannot read music file '%s'", filename);
1917 mod_info->type = MUS_TYPE_MOD;
1918 mod_info->source_filename = getStringCopy(filename);
1926 void LoadCustomMusic(void)
1928 static boolean draw_init_text = TRUE; /* only draw at startup */
1929 static char *last_music_directory = NULL;
1930 char *music_directory = getCustomMusicDirectory();
1932 struct dirent *dir_entry;
1934 if (!audio.sound_available)
1937 if (last_music_directory != NULL &&
1938 strcmp(last_music_directory, music_directory) == 0)
1939 return; /* old and new music directory are the same */
1941 if (last_music_directory != NULL)
1942 free(last_music_directory);
1943 last_music_directory = getStringCopy(music_directory);
1947 if ((dir = opendir(music_directory)) == NULL)
1949 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1950 audio.music_available = FALSE;
1955 DrawInitText("Loading music:", 120, FC_GREEN);
1957 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1959 char *basename = dir_entry->d_name;
1960 char *filename = getPath2(music_directory, basename);
1961 MusicInfo *mus_info = NULL;
1964 printf("DEBUG: loading music '%s' ...\n", basename);
1968 DrawInitText(basename, 150, FC_YELLOW);
1970 if (FileIsSound(basename))
1971 mus_info = Load_WAV(filename);
1972 else if (FileIsMusic(basename))
1973 mus_info = Load_MOD(filename);
1980 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1981 Music[num_music - 1] = mus_info;
1987 draw_init_text = FALSE;
1990 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1994 void PlayMusic(int nr)
1996 if (!audio.music_available)
2002 void PlaySound(int nr)
2004 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2007 void PlaySoundStereo(int nr, int stereo_position)
2009 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2012 void PlaySoundLoop(int nr)
2014 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2017 void PlaySoundMusic(int nr)
2019 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2022 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2024 SoundControl snd_ctrl;
2026 if (!audio.sound_available ||
2027 !audio.sound_enabled ||
2028 audio.sound_deactivated)
2031 if (volume < SOUND_MIN_VOLUME)
2032 volume = SOUND_MIN_VOLUME;
2033 else if (volume > SOUND_MAX_VOLUME)
2034 volume = SOUND_MAX_VOLUME;
2036 if (stereo_position < SOUND_MAX_LEFT)
2037 stereo_position = SOUND_MAX_LEFT;
2038 else if (stereo_position > SOUND_MAX_RIGHT)
2039 stereo_position = SOUND_MAX_RIGHT;
2041 snd_ctrl.active = TRUE;
2043 snd_ctrl.volume = volume;
2044 snd_ctrl.stereo_position = stereo_position;
2045 snd_ctrl.state = state;
2047 HandleSoundRequest(snd_ctrl);
2050 void FadeMusic(void)
2052 if (!audio.music_available)
2055 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2058 void FadeSound(int nr)
2060 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2066 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2069 void StopMusic(void)
2071 if (!audio.music_available)
2074 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2077 void StopSound(int nr)
2079 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2085 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2088 void StopSoundExt(int nr, int state)
2090 SoundControl snd_ctrl;
2092 if (!audio.sound_available)
2095 snd_ctrl.active = FALSE;
2097 snd_ctrl.state = state;
2099 HandleSoundRequest(snd_ctrl);
2102 static void ReloadCustomSounds()
2105 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2108 LoadArtworkConfig(sound_info);
2109 ReloadCustomArtworkList(sound_info);
2112 num_sounds = getSoundListSize();
2116 static void ReloadCustomMusic()
2119 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
2125 void InitReloadCustomSounds(char *set_identifier)
2127 if (!audio.sound_available)
2130 #if defined(AUDIO_UNIX_NATIVE)
2131 LoadArtworkConfig(sound_info); /* also load config on sound client */
2132 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2134 ReloadCustomSounds();
2138 void InitReloadCustomMusic(char *set_identifier)
2140 if (!audio.music_available)
2143 #if defined(AUDIO_UNIX_NATIVE)
2144 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2146 ReloadCustomMusic();
2150 void FreeSound(void *ptr)
2152 SoundInfo *sound = (SoundInfo *)ptr;
2157 if (sound->data_ptr)
2159 #if defined(TARGET_SDL)
2160 Mix_FreeChunk(sound->data_ptr);
2161 #elif defined(TARGET_ALLEGRO)
2162 destroy_sample(sound->data_ptr);
2163 #else /* AUDIO_UNIX_NATIVE */
2164 free(sound->data_ptr);
2168 if (sound->source_filename)
2169 free(sound->source_filename);
2174 void FreeMusic(MusicInfo *music)
2179 if (music->data_ptr)
2181 #if defined(TARGET_SDL)
2182 if (music->type == MUS_TYPE_MOD)
2183 Mix_FreeMusic(music->data_ptr);
2185 Mix_FreeChunk(music->data_ptr);
2186 #elif defined(TARGET_ALLEGRO)
2187 destroy_sample(music->data_ptr);
2188 #else /* AUDIO_UNIX_NATIVE */
2189 free(music->data_ptr);
2196 void FreeAllSounds()
2198 FreeCustomArtworkLists(sound_info);
2208 for(i=0; i<num_music; i++)
2209 FreeMusic(Music[i]);
2217 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2218 /* ========================================================================= */