1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
25 #if defined(PLATFORM_LINUX)
26 #include <sys/ioctl.h>
27 #include <linux/soundcard.h>
28 #elif defined(PLATFORM_FREEBSD)
29 #include <machine/soundcard.h>
30 #elif defined(PLATFORM_NETBSD)
31 #include <sys/ioctl.h>
32 #include <sys/audioio.h>
33 #elif defined(PLATFORM_HPUX)
34 #include <sys/audio.h>
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME 200
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL 1000
50 #if defined(AUDIO_STREAMING_DSP)
51 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
52 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
55 #define SND_TYPE_NONE 0
56 #define SND_TYPE_WAV 1
58 #define MUS_TYPE_NONE 0
59 #define MUS_TYPE_WAV 1
60 #define MUS_TYPE_MOD 2
62 #define DEVICENAME_DSP "/dev/dsp"
63 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
64 #define DEVICENAME_AUDIO "/dev/audio"
65 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
67 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
68 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
70 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
71 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
74 struct SoundHeader_SUN
77 unsigned long hdr_size;
78 unsigned long data_size;
79 unsigned long encoding;
80 unsigned long sample_rate;
81 unsigned long channels;
84 struct SoundHeader_8SVX
87 unsigned long chunk_size;
92 #if defined(AUDIO_UNIX_NATIVE)
93 struct SoundHeader_WAV
95 unsigned short compression_code;
96 unsigned short num_channels;
97 unsigned long sample_rate;
98 unsigned long bytes_per_second;
99 unsigned short block_align;
100 unsigned short bits_per_sample;
104 struct AudioFormatInfo
106 boolean stereo; /* availability of stereo sound */
107 int format; /* size and endianess of sample data */
108 int sample_rate; /* sample frequency */
109 int fragment_size; /* audio device fragment size in bytes */
114 char *source_filename;
119 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
120 long data_len; /* number of samples, NOT number of bytes */
121 int num_channels; /* mono: 1 channel, stereo: 2 channels */
123 typedef struct SampleInfo SoundInfo;
124 typedef struct SampleInfo MusicInfo;
136 unsigned long playing_starttime;
137 unsigned long playing_pos;
141 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
142 long data_len; /* number of samples, NOT number of bytes */
143 int num_channels; /* mono: 1 channel, stereo: 2 channels */
145 #if defined(TARGET_ALLEGRO)
149 typedef struct SoundControl SoundControl;
151 static struct ArtworkListInfo *sound_info = NULL;
152 static SoundInfo **Sound = NULL;
153 static MusicInfo **Music = NULL;
154 static int num_sounds = 0, num_music = 0;
155 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
158 /* ========================================================================= */
159 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
161 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
162 static int mixer_active_channels = 0;
164 #if defined(AUDIO_UNIX_NATIVE)
165 static struct AudioFormatInfo afmt;
167 static void Mixer_Main(void);
168 #if !defined(AUDIO_STREAMING_DSP)
169 static unsigned char linear_to_ulaw(int);
170 static int ulaw_to_linear(unsigned char);
174 static void ReloadCustomSounds();
175 static void ReloadCustomMusic();
176 static void FreeSound(void *);
179 /* ------------------------------------------------------------------------- */
180 /* functions for native (non-SDL) Unix audio/mixer support */
181 /* ------------------------------------------------------------------------- */
183 #if defined(AUDIO_UNIX_NATIVE)
185 static int OpenAudioDevice(char *audio_device_name)
189 /* check if desired audio device is accessible */
190 if (access(audio_device_name, W_OK) != 0)
193 /* try to open audio device in non-blocking mode */
194 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
195 return audio_device_fd;
197 /* re-open audio device in blocking mode */
198 close(audio_device_fd);
199 audio_device_fd = open(audio_device_name, O_WRONLY);
201 return audio_device_fd;
204 static void CloseAudioDevice(int *audio_device_fd)
206 if (*audio_device_fd == 0)
209 close(*audio_device_fd);
210 *audio_device_fd = -1;
213 static boolean TestAudioDevices(void)
215 static char *audio_device_name[] =
218 DEVICENAME_SOUND_DSP,
221 int audio_device_fd = -1;
224 /* look for available audio devices, starting with preferred ones */
225 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
226 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
229 if (audio_device_fd < 0)
231 Error(ERR_WARN, "cannot open audio device -- no sound");
235 close(audio_device_fd);
237 audio.device_name = audio_device_name[i];
242 static boolean ForkAudioProcess(void)
244 if (pipe(audio.mixer_pipe) < 0)
246 Error(ERR_WARN, "cannot create pipe -- no sounds");
250 if ((audio.mixer_pid = fork()) < 0)
252 Error(ERR_WARN, "cannot create sound server process -- no sounds");
257 printf("PID: %d [%s]\n", getpid(),
258 (IS_CHILD_PROCESS(audio.mixer_pid) ? "child" : "parent"));
262 if (IS_CHILD_PROCESS(audio.mixer_pid))
263 Mixer_Main(); /* this function never returns */
265 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
270 void UnixOpenAudio(void)
272 if (!TestAudioDevices())
275 audio.sound_available = TRUE;
276 audio.sound_enabled = TRUE;
278 #if defined(AUDIO_STREAMING_DSP)
279 audio.music_available = TRUE;
280 audio.loops_available = TRUE;
283 audio.num_channels = NUM_MIXER_CHANNELS;
284 audio.music_channel = MUSIC_CHANNEL;
285 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
288 void UnixCloseAudio(void)
291 close(audio.device_fd);
293 if (IS_PARENT_PROCESS(audio.mixer_pid))
294 kill(audio.mixer_pid, SIGTERM);
298 /* ------------------------------------------------------------------------- */
299 /* functions for platform specific audio device initialization */
300 /* ------------------------------------------------------------------------- */
302 #if defined(AUDIO_LINUX_IOCTL)
303 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
305 /* "ioctl()" expects pointer to 'int' value for stereo flag
306 (boolean is defined as 'char', which will not work here) */
307 unsigned int fragment_spec = 0;
308 int fragment_size_query;
317 /* supported audio format in preferred order */
318 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
319 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
320 { AFMT_U8, AUDIO_FORMAT_U8 },
325 /* determine logarithm (log2) of the fragment size */
326 while ((1 << fragment_spec) < afmt->fragment_size)
329 /* use two fragments (play one fragment, prepare the other);
330 one fragment would result in interrupted audio output, more
331 than two fragments would raise audio output latency to much */
332 fragment_spec |= 0x00020000;
334 /* Example for fragment specification:
335 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
336 - (with stereo the effective buffer size will shrink to 256)
337 => fragment_size = 0x00020009 */
339 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
340 Error(ERR_EXIT_SOUND_SERVER,
341 "cannot set fragment size of audio device -- no sounds");
345 while (formats[i].format_result != -1)
347 unsigned int audio_format = formats[i].format_ioctl;
348 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
350 afmt->format = formats[i].format_result;
355 if (afmt->format == 0) /* no supported audio format found */
356 Error(ERR_EXIT_SOUND_SERVER,
357 "cannot set audio format of audio device -- no sounds");
359 /* try if we can use stereo sound */
361 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
362 afmt->stereo = FALSE;
364 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
365 Error(ERR_EXIT_SOUND_SERVER,
366 "cannot set sample rate of audio device -- no sounds");
368 /* get the real fragmentation size; this should return 512 */
369 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
370 Error(ERR_EXIT_SOUND_SERVER,
371 "cannot get fragment size of audio device -- no sounds");
372 if (fragment_size_query != afmt->fragment_size)
373 Error(ERR_EXIT_SOUND_SERVER,
374 "cannot set fragment size of audio device -- no sounds");
376 #endif /* AUDIO_LINUX_IOCTL */
378 #if defined(PLATFORM_NETBSD)
379 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
382 boolean stereo = TRUE;
384 AUDIO_INITINFO(&a_info);
385 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
386 a_info.play.precision = 8;
387 a_info.play.channels = 2;
388 a_info.play.sample_rate = afmt->sample_rate;
389 a_info.blocksize = afmt->fragment_size;
391 afmt->format = AUDIO_FORMAT_U8;
394 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
396 /* try to disable stereo */
397 a_info.play.channels = 1;
399 afmt->stereo = FALSE;
401 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
402 Error(ERR_EXIT_SOUND_SERVER,
403 "cannot set sample rate of audio device -- no sounds");
406 #endif /* PLATFORM_NETBSD */
408 #if defined(PLATFORM_HPUX)
409 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
411 struct audio_describe ainfo;
414 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
416 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
418 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
419 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
421 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
422 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
424 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
425 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
427 afmt->format = AUDIO_FORMAT_U8;
428 afmt->stereo = FALSE;
429 afmt->sample_rate = 8000;
433 #endif /* PLATFORM_HPUX */
435 static void InitAudioDevice(struct AudioFormatInfo *afmt)
438 afmt->format = AUDIO_FORMAT_UNKNOWN;
439 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
440 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
442 #if defined(AUDIO_LINUX_IOCTL)
443 InitAudioDevice_Linux(afmt);
444 #elif defined(PLATFORM_NETBSD)
445 InitAudioDevice_NetBSD(afmt);
446 #elif defined(PLATFORM_HPUX)
447 InitAudioDevice_HPUX(afmt);
449 /* generic /dev/audio stuff might be placed here */
454 /* ------------------------------------------------------------------------- */
455 /* functions for communication between main process and sound mixer process */
456 /* ------------------------------------------------------------------------- */
458 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
460 if (IS_CHILD_PROCESS(audio.mixer_pid))
463 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
465 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
466 audio.sound_available = audio.sound_enabled = FALSE;
471 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
473 if (IS_PARENT_PROCESS(audio.mixer_pid))
476 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
477 != sizeof(SoundControl))
478 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
481 static void WriteReloadInfoToPipe(char *set_identifier, int type)
483 SoundControl snd_ctrl;
484 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
485 artwork.mus_current);
486 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
487 unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
488 unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
489 unsigned long str_size4 = strlen(ti->basepath) + 1;
490 unsigned long str_size5 = strlen(ti->fullpath) + 1;
491 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
492 setup.override_level_sounds :
493 setup.override_level_music);
495 if (IS_CHILD_PROCESS(audio.mixer_pid))
498 if (leveldir_current == NULL) /* should never happen */
499 Error(ERR_EXIT, "leveldir_current == NULL");
501 snd_ctrl.active = FALSE;
502 snd_ctrl.state = type;
503 snd_ctrl.data_len = strlen(set_identifier) + 1;
505 if (write(audio.mixer_pipe[1], &snd_ctrl,
506 sizeof(snd_ctrl)) < 0 ||
507 write(audio.mixer_pipe[1], set_identifier,
508 snd_ctrl.data_len) < 0 ||
509 write(audio.mixer_pipe[1], &override_level_artwork,
510 sizeof(boolean)) < 0 ||
511 write(audio.mixer_pipe[1], leveldir_current,
512 sizeof(TreeInfo)) < 0 ||
513 write(audio.mixer_pipe[1], ti,
514 sizeof(TreeInfo)) < 0 ||
515 write(audio.mixer_pipe[1], &str_size1,
516 sizeof(unsigned long)) < 0 ||
517 write(audio.mixer_pipe[1], &str_size2,
518 sizeof(unsigned long)) < 0 ||
519 write(audio.mixer_pipe[1], &str_size3,
520 sizeof(unsigned long)) < 0 ||
521 write(audio.mixer_pipe[1], &str_size4,
522 sizeof(unsigned long)) < 0 ||
523 write(audio.mixer_pipe[1], &str_size5,
524 sizeof(unsigned long)) < 0 ||
525 write(audio.mixer_pipe[1], leveldir_current->fullpath,
527 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
529 write(audio.mixer_pipe[1], leveldir_current->music_path,
531 write(audio.mixer_pipe[1], ti->basepath,
533 write(audio.mixer_pipe[1], ti->fullpath,
536 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
537 audio.sound_available = audio.sound_enabled = FALSE;
542 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
544 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
545 &artwork.snd_current : &artwork.mus_current);
546 TreeInfo *ti = *ti_ptr;
547 unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
548 static char *set_identifier = NULL;
549 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
550 &setup.override_level_sounds :
551 &setup.override_level_music);
554 free(set_identifier);
556 set_identifier = checked_malloc(snd_ctrl->data_len);
558 if (leveldir_current == NULL)
559 leveldir_current = checked_calloc(sizeof(TreeInfo));
562 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
563 if (leveldir_current->fullpath != NULL)
564 free(leveldir_current->fullpath);
565 if (leveldir_current->sounds_path != NULL)
566 free(leveldir_current->sounds_path);
567 if (leveldir_current->music_path != NULL)
568 free(leveldir_current->music_path);
569 if (ti->basepath != NULL)
571 if (ti->fullpath != NULL)
574 if (read(audio.mixer_pipe[0], set_identifier,
575 snd_ctrl->data_len) != snd_ctrl->data_len ||
576 read(audio.mixer_pipe[0], override_level_artwork,
577 sizeof(boolean)) != sizeof(boolean) ||
578 read(audio.mixer_pipe[0], leveldir_current,
579 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
580 read(audio.mixer_pipe[0], ti,
581 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
582 read(audio.mixer_pipe[0], &str_size1,
583 sizeof(unsigned long)) != sizeof(unsigned long) ||
584 read(audio.mixer_pipe[0], &str_size2,
585 sizeof(unsigned long)) != sizeof(unsigned long) ||
586 read(audio.mixer_pipe[0], &str_size3,
587 sizeof(unsigned long)) != sizeof(unsigned long) ||
588 read(audio.mixer_pipe[0], &str_size4,
589 sizeof(unsigned long)) != sizeof(unsigned long) ||
590 read(audio.mixer_pipe[0], &str_size5,
591 sizeof(unsigned long)) != sizeof(unsigned long))
592 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
594 leveldir_current->fullpath = checked_calloc(str_size1);
595 leveldir_current->sounds_path = checked_calloc(str_size2);
596 leveldir_current->music_path = checked_calloc(str_size3);
597 ti->basepath = checked_calloc(str_size4);
598 ti->fullpath = checked_calloc(str_size5);
600 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
601 str_size1) != str_size1 ||
602 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
603 str_size2) != str_size2 ||
604 read(audio.mixer_pipe[0], leveldir_current->music_path,
605 str_size3) != str_size3 ||
606 read(audio.mixer_pipe[0], ti->basepath,
607 str_size4) != str_size4 ||
608 read(audio.mixer_pipe[0], ti->fullpath,
609 str_size5) != str_size5)
610 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
612 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
613 artwork.snd_current_identifier = set_identifier;
615 artwork.mus_current_identifier = set_identifier;
618 #endif /* AUDIO_UNIX_NATIVE */
621 /* ------------------------------------------------------------------------- */
622 /* mixer functions */
623 /* ------------------------------------------------------------------------- */
625 void Mixer_InitChannels()
629 for(i=0; i<audio.num_channels; i++)
630 mixer[i].active = FALSE;
631 mixer_active_channels = 0;
634 static void Mixer_ResetChannelExpiration(int channel)
636 mixer[channel].playing_starttime = Counter();
638 #if defined(TARGET_SDL)
639 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
640 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
644 static boolean Mixer_ChannelExpired(int channel)
646 if (!mixer[channel].active)
649 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
650 DelayReached(&mixer[channel].playing_starttime,
651 SOUND_LOOP_EXPIRATION_TIME))
654 #if defined(TARGET_SDL)
656 if (!Mix_Playing(channel))
659 #elif defined(TARGET_ALLEGRO)
661 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
662 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
664 /* sound sample has completed playing or was completely faded out */
665 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
668 #endif /* TARGET_ALLEGRO */
673 static boolean Mixer_AllocateChannel(int channel)
675 #if defined(TARGET_ALLEGRO)
676 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
677 if (mixer[channel].voice < 0)
684 static void Mixer_SetChannelProperties(int channel)
686 #if defined(TARGET_SDL)
687 Mix_Volume(channel, mixer[channel].volume);
688 Mix_SetPanning(channel,
689 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
690 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
691 #elif defined(TARGET_ALLEGRO)
692 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
693 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
697 static void Mixer_StartChannel(int channel)
699 #if defined(TARGET_SDL)
700 Mix_PlayChannel(channel, mixer[channel].data_ptr,
701 IS_LOOP(mixer[channel]) ? -1 : 0);
702 #elif defined(TARGET_ALLEGRO)
703 if (IS_LOOP(mixer[channel]))
704 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
706 voice_start(mixer[channel].voice);
710 static void Mixer_PlayChannel(int channel)
712 /* start with inactive channel in case something goes wrong */
713 mixer[channel].active = FALSE;
715 if (mixer[channel].type != MUS_TYPE_WAV)
718 if (!Mixer_AllocateChannel(channel))
721 Mixer_SetChannelProperties(channel);
722 Mixer_StartChannel(channel);
724 Mixer_ResetChannelExpiration(channel);
726 mixer[channel].playing_pos = 0;
727 mixer[channel].active = TRUE;
728 mixer_active_channels++;
731 static void Mixer_PlayMusicChannel()
733 Mixer_PlayChannel(audio.music_channel);
735 #if defined(TARGET_SDL)
736 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
738 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
739 this looks like a bug in the SDL_mixer library */
740 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
741 Mix_VolumeMusic(SOUND_MAX_VOLUME);
746 static void Mixer_StopChannel(int channel)
748 if (!mixer[channel].active)
751 #if defined(TARGET_SDL)
752 Mix_HaltChannel(channel);
753 #elif defined(TARGET_ALLEGRO)
754 voice_set_volume(mixer[channel].voice, 0);
755 deallocate_voice(mixer[channel].voice);
758 mixer[channel].active = FALSE;
759 mixer_active_channels--;
762 static void Mixer_StopMusicChannel()
764 Mixer_StopChannel(audio.music_channel);
766 #if defined(TARGET_SDL)
771 static void Mixer_FadeChannel(int channel)
773 if (!mixer[channel].active)
776 mixer[channel].state |= SND_CTRL_FADE;
778 #if defined(TARGET_SDL)
779 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
780 #elif defined(TARGET_ALLEGRO)
781 if (voice_check(mixer[channel].voice))
782 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
786 static void Mixer_FadeMusicChannel()
788 Mixer_FadeChannel(audio.music_channel);
790 #if defined(TARGET_SDL)
791 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
795 static void Mixer_UnFadeChannel(int channel)
797 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
800 mixer[channel].state &= ~SND_CTRL_FADE;
801 mixer[channel].volume = SOUND_MAX_VOLUME;
803 #if defined(TARGET_SDL)
804 Mix_ExpireChannel(channel, -1);
805 Mix_Volume(channel, mixer[channel].volume);
806 #elif defined(TARGET_ALLEGRO)
807 voice_stop_volumeramp(mixer[channel].voice);
808 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
809 mixer[channel].volume);
813 static void Mixer_InsertSound(SoundControl snd_ctrl)
819 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
820 snd_ctrl.nr, num_sounds, mixer_active_channels);
823 if (IS_MUSIC(snd_ctrl))
828 snd_ctrl.nr = snd_ctrl.nr % num_music;
830 else if (snd_ctrl.nr >= num_sounds)
833 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
834 if (snd_info == NULL)
837 /* copy sound sample and format information */
838 snd_ctrl.type = snd_info->type;
839 snd_ctrl.format = snd_info->format;
840 snd_ctrl.data_ptr = snd_info->data_ptr;
841 snd_ctrl.data_len = snd_info->data_len;
842 snd_ctrl.num_channels = snd_info->num_channels;
844 /* play music samples on a dedicated music channel */
845 if (IS_MUSIC(snd_ctrl))
847 Mixer_StopMusicChannel();
849 mixer[audio.music_channel] = snd_ctrl;
850 Mixer_PlayMusicChannel();
855 /* check if (and how often) this sound sample is already playing */
856 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
857 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
861 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
864 /* reset expiration delay for already playing loop sounds */
865 if (k > 0 && IS_LOOP(snd_ctrl))
867 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
869 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
872 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
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);
886 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
887 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
896 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
899 /* don't play sound more than n times simultaneously (with n == 2 for now) */
902 unsigned long playing_current = Counter();
903 int longest = 0, longest_nr = audio.first_sound_channel;
905 /* look for oldest equal sound */
906 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
908 int playing_time = playing_current - mixer[i].playing_starttime;
911 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
914 actual = 1000 * playing_time / mixer[i].data_len;
916 if (actual >= longest)
923 Mixer_StopChannel(longest_nr);
926 /* If all (non-music) channels are active, stop the channel that has
927 played its sound sample most completely (in percent of the sample
928 length). As we cannot currently get the actual playing position
929 of the channel's sound sample when compiling with the SDL mixer
930 library, we use the current playing time (in milliseconds) instead. */
933 /* channel allocation sanity check -- should not be needed */
934 if (mixer_active_channels ==
935 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
937 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
939 if (!mixer[i].active)
941 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
942 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
944 mixer_active_channels--;
950 if (mixer_active_channels ==
951 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
953 unsigned long playing_current = Counter();
954 int longest = 0, longest_nr = audio.first_sound_channel;
958 /* print some debugging information about audio channel usage */
959 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
961 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
962 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
967 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
969 int playing_time = playing_current - mixer[i].playing_starttime;
970 int actual = 1000 * playing_time / mixer[i].data_len;
972 if (!IS_LOOP(mixer[i]) && actual > longest)
979 Mixer_StopChannel(longest_nr);
982 /* add the new sound to the mixer */
983 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
986 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
989 if (!mixer[i].active)
992 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
995 #if defined(AUDIO_UNIX_NATIVE)
996 if (snd_info->data_len == 0)
998 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1002 mixer[i] = snd_ctrl;
1003 Mixer_PlayChannel(i);
1010 static void HandleSoundRequest(SoundControl snd_ctrl)
1014 #if defined(AUDIO_UNIX_NATIVE)
1015 if (IS_PARENT_PROCESS(audio.mixer_pid))
1017 SendSoundControlToMixerProcess(&snd_ctrl);
1022 /* deactivate channels that have expired since the last request */
1023 for (i=0; i<audio.num_channels; i++)
1024 if (mixer[i].active && Mixer_ChannelExpired(i))
1025 Mixer_StopChannel(i);
1027 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1029 Mixer_StopMusicChannel();
1030 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1031 Mixer_StopChannel(i);
1033 #if defined(AUDIO_UNIX_NATIVE)
1034 CloseAudioDevice(&audio.device_fd);
1035 ReadReloadInfoFromPipe(&snd_ctrl);
1038 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1039 ReloadCustomSounds();
1041 ReloadCustomMusic();
1043 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1045 if (IS_MUSIC(snd_ctrl))
1047 Mixer_FadeMusicChannel();
1051 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1052 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1053 Mixer_FadeChannel(i);
1055 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1057 if (IS_MUSIC(snd_ctrl))
1059 Mixer_StopMusicChannel();
1063 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1064 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1065 Mixer_StopChannel(i);
1067 #if defined(AUDIO_UNIX_NATIVE)
1068 if (!mixer_active_channels)
1069 CloseAudioDevice(&audio.device_fd);
1072 else if (snd_ctrl.active) /* add new sound to mixer */
1074 Mixer_InsertSound(snd_ctrl);
1078 void StartMixer(void)
1083 SDL_version compile_version;
1084 const SDL_version *link_version;
1085 MIX_VERSION(&compile_version);
1086 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1087 compile_version.major,
1088 compile_version.minor,
1089 compile_version.patch);
1090 link_version = Mix_Linked_Version();
1091 printf("running with SDL_mixer version: %d.%d.%d\n",
1092 link_version->major,
1093 link_version->minor,
1094 link_version->patch);
1097 if (!audio.sound_available)
1100 /* initialize stereo position conversion information */
1101 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1103 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1105 #if defined(AUDIO_UNIX_NATIVE)
1106 if (!ForkAudioProcess())
1107 audio.sound_available = FALSE;
1111 #if defined(AUDIO_UNIX_NATIVE)
1113 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1114 int sample_pos, int sample_size,
1115 short *buffer_base_ptr, int buffer_pos,
1116 int num_output_channels)
1118 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1119 int num_channels = snd_ctrl->num_channels;
1120 int stepsize = num_channels;
1121 int output_stepsize = num_output_channels;
1124 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1126 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1128 for (i=0; i<num_output_channels; i++)
1130 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1132 for (j=0; j<sample_size; j++)
1133 buffer_ptr[output_stepsize * j + i] =
1134 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1137 else /* AUDIO_FORMAT_S16 */
1139 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1141 for (i=0; i<num_output_channels; i++)
1143 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1145 for (j=0; j<sample_size; j++)
1146 buffer_ptr[output_stepsize * j + i] =
1147 sample_ptr[stepsize * j + offset];
1152 #if defined(AUDIO_STREAMING_DSP)
1153 static void Mixer_Main_DSP()
1155 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1156 static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1157 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1161 int max_sample_size;
1162 int num_output_channels;
1165 if (!mixer_active_channels)
1168 if (audio.device_fd < 0)
1170 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1173 InitAudioDevice(&afmt);
1176 stereo = afmt.stereo;
1177 fragment_size = afmt.fragment_size;
1178 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1179 num_output_channels = (stereo ? 2 : 1);
1180 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1182 /* first clear the last premixing buffer */
1183 memset(premix_last_buffer, 0,
1184 max_sample_size * num_output_channels * sizeof(long));
1186 for(i=0; i<audio.num_channels; i++)
1193 if (!mixer[i].active)
1196 if (Mixer_ChannelExpired(i))
1198 Mixer_StopChannel(i);
1202 /* pointer, lenght and actual playing position of sound sample */
1203 sample_ptr = mixer[i].data_ptr;
1204 sample_len = mixer[i].data_len;
1205 sample_pos = mixer[i].playing_pos;
1206 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1207 mixer[i].playing_pos += sample_size;
1209 /* copy original sample to first mixing buffer */
1210 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1211 premix_first_buffer, 0, num_output_channels);
1213 /* are we about to restart a looping sound? */
1214 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1216 while (sample_size < max_sample_size)
1218 int restarted_sample_size =
1219 MIN(max_sample_size - sample_size, sample_len);
1221 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1222 premix_first_buffer, sample_size,
1223 num_output_channels);
1225 mixer[i].playing_pos = restarted_sample_size;
1226 sample_size += restarted_sample_size;
1230 /* decrease volume if sound is fading out */
1231 if (IS_FADING(mixer[i]) &&
1232 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1233 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1235 /* adjust volume of actual sound sample */
1236 if (mixer[i].volume != SOUND_MAX_VOLUME)
1237 for(j=0; j<sample_size * num_output_channels; j++)
1238 premix_first_buffer[j] =
1239 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1241 /* adjust left and right channel volume due to stereo sound position */
1244 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1245 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1247 for(j=0; j<sample_size; j++)
1249 premix_first_buffer[2 * j + 0] =
1250 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1251 premix_first_buffer[2 * j + 1] =
1252 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1256 /* fill the last mixing buffer with stereo or mono sound */
1257 for(j=0; j<sample_size * num_output_channels; j++)
1258 premix_last_buffer[j] += premix_first_buffer[j];
1260 /* delete completed sound entries from the mixer */
1261 if (mixer[i].playing_pos >= mixer[i].data_len)
1263 if (IS_LOOP(mixer[i]))
1264 mixer[i].playing_pos = 0;
1266 Mixer_StopChannel(i);
1268 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1269 Mixer_StopChannel(i);
1272 /* prepare final playing buffer according to system audio format */
1273 for(i=0; i<max_sample_size * num_output_channels; i++)
1275 /* cut off at 17 bit value */
1276 if (premix_last_buffer[i] < -65535)
1277 premix_last_buffer[i] = -65535;
1278 else if (premix_last_buffer[i] > 65535)
1279 premix_last_buffer[i] = 65535;
1281 /* shift to 16 bit value */
1282 premix_last_buffer[i] >>= 1;
1284 if (afmt.format & AUDIO_FORMAT_U8)
1286 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1288 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1290 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1291 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1293 else /* big endian */
1295 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1296 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1300 /* finally play the sound fragment */
1301 write(audio.device_fd, playing_buffer, fragment_size);
1303 if (!mixer_active_channels)
1304 CloseAudioDevice(&audio.device_fd);
1307 #else /* !AUDIO_STREAMING_DSP */
1309 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1311 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1312 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1313 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1314 int num_output_channels = 1;
1323 /* pointer, lenght and actual playing position of sound sample */
1324 sample_ptr = mixer[i].data_ptr;
1325 sample_len = mixer[i].data_len;
1326 sample_pos = mixer[i].playing_pos;
1327 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1328 mixer[i].playing_pos += sample_size;
1330 /* copy original sample to first mixing buffer */
1331 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1332 premix_first_buffer, 0, num_output_channels);
1334 /* adjust volume of actual sound sample */
1335 if (mixer[i].volume != SOUND_MAX_VOLUME)
1336 for(j=0; j<sample_size; j++)
1337 premix_first_buffer[j] =
1338 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1340 /* might be needed for u-law /dev/audio */
1342 for(j=0; j<sample_size; j++)
1344 linear_to_ulaw(premix_first_buffer[j]);
1347 /* delete completed sound entries from the mixer */
1348 if (mixer[i].playing_pos >= mixer[i].data_len)
1349 Mixer_StopChannel(i);
1351 for(i=0; i<sample_size; i++)
1352 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1354 /* finally play the sound fragment */
1355 write(audio.device_fd, playing_buffer, sample_size);
1359 #endif /* !AUDIO_STREAMING_DSP */
1363 SoundControl snd_ctrl;
1366 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1368 Mixer_InitChannels();
1370 #if defined(PLATFORM_HPUX)
1371 InitAudioDevice(&afmt);
1374 FD_ZERO(&mixer_fdset);
1375 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1377 while(1) /* wait for sound playing commands from client */
1379 struct timeval delay = { 0, 0 };
1381 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1382 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1383 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1386 ReadSoundControlFromMainProcess(&snd_ctrl);
1388 HandleSoundRequest(snd_ctrl);
1390 #if defined(AUDIO_STREAMING_DSP)
1392 while (mixer_active_channels &&
1393 select(audio.mixer_pipe[0] + 1,
1394 &mixer_fdset, NULL, NULL, &delay) < 1)
1396 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1401 #else /* !AUDIO_STREAMING_DSP */
1403 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1404 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1407 InitAudioDevice(&afmt);
1412 while (mixer_active_channels &&
1413 select(audio.mixer_pipe[0] + 1,
1414 &mixer_fdset, NULL, NULL, &delay) < 1)
1416 int wait_percent = 90; /* wait 90% of the real playing time */
1419 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1421 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1425 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1428 CloseAudioDevice(&audio.device_fd);
1430 Mixer_InitChannels(); /* remove all sounds from mixer */
1432 #endif /* !AUDIO_STREAMING_DSP */
1435 #endif /* AUDIO_UNIX_NATIVE */
1438 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1440 /* these two are stolen from "sox"... :) */
1443 ** This routine converts from linear to ulaw.
1445 ** Craig Reese: IDA/Supercomputing Research Center
1446 ** Joe Campbell: Department of Defense
1447 ** 29 September 1989
1450 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1451 ** 2) "A New Digital Technique for Implementation of Any
1452 ** Continuous PCM Companding Law," Villeret, Michel,
1453 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1454 ** 1973, pg. 11.12-11.17
1455 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1456 ** for Analog-to_Digital Conversion Techniques,"
1459 ** Input: Signed 16 bit linear sample
1460 ** Output: 8 bit ulaw sample
1463 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1464 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1467 static unsigned char linear_to_ulaw(int sample)
1469 static int exp_lut[256] =
1471 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1472 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1473 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1474 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1475 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1476 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1477 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1478 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1479 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1480 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1481 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1482 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1483 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1484 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1485 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1486 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1489 int sign, exponent, mantissa;
1490 unsigned char ulawbyte;
1492 /* Get the sample into sign-magnitude. */
1493 sign = (sample >> 8) & 0x80; /* set aside the sign */
1495 sample = -sample; /* get magnitude */
1497 sample = CLIP; /* clip the magnitude */
1499 /* Convert from 16 bit linear to ulaw. */
1500 sample = sample + BIAS;
1501 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1502 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1503 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1506 ulawbyte = 0x02; /* optional CCITT trap */
1513 ** This routine converts from ulaw to 16 bit linear.
1515 ** Craig Reese: IDA/Supercomputing Research Center
1516 ** 29 September 1989
1519 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1520 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1521 ** for Analog-to_Digital Conversion Techniques,"
1524 ** Input: 8 bit ulaw sample
1525 ** Output: signed 16 bit linear sample
1528 static int ulaw_to_linear(unsigned char ulawbyte)
1530 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1531 int sign, exponent, mantissa, sample;
1533 ulawbyte = ~ ulawbyte;
1534 sign = ( ulawbyte & 0x80 );
1535 exponent = ( ulawbyte >> 4 ) & 0x07;
1536 mantissa = ulawbyte & 0x0F;
1537 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1543 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1546 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1547 /* ========================================================================= */
1548 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1550 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1551 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1553 static void *Load_WAV(char *filename)
1555 SoundInfo *snd_info;
1556 #if defined(AUDIO_UNIX_NATIVE)
1557 struct SoundHeader_WAV header;
1559 byte sound_header_buffer[WAV_HEADER_SIZE];
1562 char chunk_name[CHUNK_ID_LEN + 1];
1568 if (!audio.sound_available)
1572 printf("loading WAV file '%s'\n", filename);
1575 snd_info = checked_calloc(sizeof(SoundInfo));
1577 #if defined(TARGET_SDL)
1579 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1581 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1586 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1588 #elif defined(TARGET_ALLEGRO)
1590 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1592 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1597 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1599 #else /* AUDIO_UNIX_NATIVE */
1601 if ((file = fopen(filename, MODE_READ)) == NULL)
1603 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1608 /* read chunk id "RIFF" */
1609 getFileChunkLE(file, chunk_name, &chunk_size);
1610 if (strcmp(chunk_name, "RIFF") != 0)
1612 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1618 /* read "RIFF" type id "WAVE" */
1619 getFileChunkLE(file, chunk_name, NULL);
1620 if (strcmp(chunk_name, "WAVE") != 0)
1622 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1628 while (getFileChunkLE(file, chunk_name, &chunk_size))
1630 if (strcmp(chunk_name, "fmt ") == 0)
1632 if (chunk_size < WAV_HEADER_SIZE)
1634 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1640 header.compression_code = getFile16BitLE(file);
1641 header.num_channels = getFile16BitLE(file);
1642 header.sample_rate = getFile32BitLE(file);
1643 header.bytes_per_second = getFile32BitLE(file);
1644 header.block_align = getFile16BitLE(file);
1645 header.bits_per_sample = getFile16BitLE(file);
1647 if (chunk_size > WAV_HEADER_SIZE)
1648 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1650 if (header.compression_code != 1)
1652 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1653 filename, header.compression_code);
1659 if (header.num_channels != 1 &&
1660 header.num_channels != 2)
1662 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1663 filename, header.num_channels);
1669 if (header.bits_per_sample != 8 &&
1670 header.bits_per_sample != 16)
1672 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1673 filename, header.bits_per_sample);
1679 /* warn, but accept wrong sample rate (may be only slightly different) */
1680 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1681 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1682 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1685 printf("WAV file: '%s'\n", filename);
1686 printf(" Compression code: %d'\n", header.compression_code);
1687 printf(" Number of channels: %d'\n", header.num_channels);
1688 printf(" Sample rate: %ld'\n", header.sample_rate);
1689 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1690 printf(" Block align: %d'\n", header.block_align);
1691 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1694 else if (strcmp(chunk_name, "data") == 0)
1696 data_byte_len = chunk_size;
1698 snd_info->data_len = data_byte_len;
1699 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1701 /* read sound data */
1702 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1705 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1707 free(snd_info->data_ptr);
1712 /* check for odd number of data bytes (data chunk is word aligned) */
1713 if ((data_byte_len % 2) == 1)
1714 ReadUnusedBytesFromFile(file, 1);
1716 else /* unknown chunk -- ignore */
1717 ReadUnusedBytesFromFile(file, chunk_size);
1722 if (snd_info->data_ptr == NULL)
1724 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1729 if (header.bits_per_sample == 8)
1730 snd_info->format = AUDIO_FORMAT_U8;
1731 else /* header.bits_per_sample == 16 */
1733 snd_info->format = AUDIO_FORMAT_S16;
1734 snd_info->data_len /= 2; /* correct number of samples */
1737 snd_info->num_channels = header.num_channels;
1738 if (header.num_channels == 2)
1739 snd_info->data_len /= 2; /* correct number of samples */
1742 if (header.num_channels == 1) /* convert mono sound to stereo */
1744 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1745 void *sample_ptr = snd_info->data_ptr;
1746 int sample_size = snd_info->data_len;
1749 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1750 for (i=0; i<sample_size; i++)
1752 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1753 else /* AUDIO_FORMAT_S16 */
1754 for (i=0; i<sample_size; i++)
1756 ((short *)sample_ptr)[i];
1760 #endif /* AUDIO_UNIX_NATIVE */
1762 snd_info->type = SND_TYPE_WAV;
1763 snd_info->source_filename = getStringCopy(filename);
1768 struct FileInfo *getCurrentSoundList()
1770 return sound_info->file_list;
1773 void InitSoundList(struct ConfigInfo *config_list,
1774 struct ConfigInfo *config_suffix_list,
1775 int num_file_list_entries)
1779 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1781 sound_info->type = ARTWORK_TYPE_SOUNDS;
1783 sound_info->num_file_list_entries = num_file_list_entries;
1784 sound_info->num_suffix_list_entries = 0;
1785 for (i=0; config_suffix_list[i].token != NULL; i++)
1786 sound_info->num_suffix_list_entries++;
1788 sound_info->file_list =
1789 getFileListFromConfigList(config_list, config_suffix_list,
1790 num_file_list_entries);
1791 sound_info->suffix_list = config_suffix_list;
1792 sound_info->custom_setup_list = NULL;
1794 sound_info->artwork_list =
1795 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1797 sound_info->content_list = NULL;
1799 sound_info->load_artwork = Load_WAV;
1800 sound_info->free_artwork = FreeSound;
1802 num_sounds = sound_info->num_file_list_entries;
1803 Sound = (SoundInfo **)sound_info->artwork_list;
1806 static MusicInfo *Load_MOD(char *filename)
1808 #if defined(TARGET_SDL)
1809 MusicInfo *mod_info;
1811 if (!audio.sound_available)
1814 mod_info = checked_calloc(sizeof(MusicInfo));
1816 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1818 Error(ERR_WARN, "cannot read music file '%s'", filename);
1823 mod_info->type = MUS_TYPE_MOD;
1824 mod_info->source_filename = getStringCopy(filename);
1832 void LoadCustomMusic(void)
1834 static boolean draw_init_text = TRUE; /* only draw at startup */
1835 static char *last_music_directory = NULL;
1836 char *music_directory = getCustomMusicDirectory();
1838 struct dirent *dir_entry;
1840 if (!audio.sound_available)
1843 if (last_music_directory != NULL &&
1844 strcmp(last_music_directory, music_directory) == 0)
1845 return; /* old and new music directory are the same */
1847 if (last_music_directory != NULL)
1848 free(last_music_directory);
1849 last_music_directory = getStringCopy(music_directory);
1853 if ((dir = opendir(music_directory)) == NULL)
1855 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1856 audio.music_available = FALSE;
1861 DrawInitText("Loading music:", 120, FC_GREEN);
1863 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1865 char *basename = dir_entry->d_name;
1866 char *filename = getPath2(music_directory, basename);
1867 MusicInfo *mus_info = NULL;
1870 printf("DEBUG: loading music '%s' ...\n", basename);
1874 DrawInitText(basename, 150, FC_YELLOW);
1876 if (FileIsSound(basename))
1877 mus_info = Load_WAV(filename);
1878 else if (FileIsMusic(basename))
1879 mus_info = Load_MOD(filename);
1886 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1887 Music[num_music -1] = mus_info;
1893 draw_init_text = FALSE;
1896 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1900 void PlayMusic(int nr)
1902 if (!audio.music_available)
1908 void PlaySound(int nr)
1910 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1913 void PlaySoundStereo(int nr, int stereo_position)
1915 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1918 void PlaySoundLoop(int nr)
1920 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1923 void PlaySoundMusic(int nr)
1925 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1928 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1930 SoundControl snd_ctrl;
1932 if (!audio.sound_available ||
1933 !audio.sound_enabled ||
1934 audio.sound_deactivated)
1937 if (volume < SOUND_MIN_VOLUME)
1938 volume = SOUND_MIN_VOLUME;
1939 else if (volume > SOUND_MAX_VOLUME)
1940 volume = SOUND_MAX_VOLUME;
1942 if (stereo_position < SOUND_MAX_LEFT)
1943 stereo_position = SOUND_MAX_LEFT;
1944 else if (stereo_position > SOUND_MAX_RIGHT)
1945 stereo_position = SOUND_MAX_RIGHT;
1947 snd_ctrl.active = TRUE;
1949 snd_ctrl.volume = volume;
1950 snd_ctrl.stereo_position = stereo_position;
1951 snd_ctrl.state = state;
1953 HandleSoundRequest(snd_ctrl);
1956 void FadeMusic(void)
1958 if (!audio.music_available)
1961 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1964 void FadeSound(int nr)
1966 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1972 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1975 void StopMusic(void)
1977 if (!audio.music_available)
1980 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1983 void StopSound(int nr)
1985 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1991 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1994 void StopSoundExt(int nr, int state)
1996 SoundControl snd_ctrl;
1998 if (!audio.sound_available)
2001 snd_ctrl.active = FALSE;
2003 snd_ctrl.state = state;
2005 HandleSoundRequest(snd_ctrl);
2008 static void ReloadCustomSounds()
2011 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2014 ReloadCustomArtworkList(sound_info);
2017 static void ReloadCustomMusic()
2020 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
2026 void InitReloadSounds(char *set_identifier)
2028 if (!audio.sound_available)
2031 #if defined(AUDIO_UNIX_NATIVE)
2032 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2034 ReloadCustomSounds();
2038 void InitReloadMusic(char *set_identifier)
2040 if (!audio.music_available)
2043 #if defined(AUDIO_UNIX_NATIVE)
2044 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2046 ReloadCustomMusic();
2050 void FreeSound(void *ptr)
2052 SoundInfo *sound = (SoundInfo *)ptr;
2057 if (sound->data_ptr)
2059 #if defined(TARGET_SDL)
2060 Mix_FreeChunk(sound->data_ptr);
2061 #elif defined(TARGET_ALLEGRO)
2062 destroy_sample(sound->data_ptr);
2063 #else /* AUDIO_UNIX_NATIVE */
2064 free(sound->data_ptr);
2068 if (sound->source_filename)
2069 free(sound->source_filename);
2074 void FreeMusic(MusicInfo *music)
2079 if (music->data_ptr)
2081 #if defined(TARGET_SDL)
2082 if (music->type == MUS_TYPE_MOD)
2083 Mix_FreeMusic(music->data_ptr);
2085 Mix_FreeChunk(music->data_ptr);
2086 #elif defined(TARGET_ALLEGRO)
2087 destroy_sample(music->data_ptr);
2088 #else /* AUDIO_UNIX_NATIVE */
2089 free(music->data_ptr);
2096 void FreeAllSounds()
2098 FreeCustomArtworkList(sound_info);
2108 for(i=0; i<num_music; i++)
2109 FreeMusic(Music[i]);
2117 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2118 /* ========================================================================= */