1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
24 #if defined(PLATFORM_LINUX)
25 #include <sys/ioctl.h>
26 #include <linux/soundcard.h>
27 #elif defined(PLATFORM_FREEBSD)
28 #include <machine/soundcard.h>
29 #elif defined(PLATFORM_NETBSD)
30 #include <sys/ioctl.h>
31 #include <sys/audioio.h>
32 #elif defined(PLATFORM_HPUX)
33 #include <sys/audio.h>
43 /* expiration time (in milliseconds) for sound loops */
44 #define SOUND_LOOP_EXPIRATION_TIME 200
46 /* one second fading interval == 1000 ticks (milliseconds) */
47 #define SOUND_FADING_INTERVAL 1000
49 #if defined(AUDIO_STREAMING_DSP)
50 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
51 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
54 #if !defined(PLATFORM_HPUX)
55 #define SND_BLOCKSIZE 4096
57 #define SND_BLOCKSIZE 32768
60 #define SND_TYPE_NONE 0
61 #define SND_TYPE_WAV 1
63 #define MUS_TYPE_NONE 0
64 #define MUS_TYPE_WAV 1
65 #define MUS_TYPE_MOD 2
67 #define DEVICENAME_DSP "/dev/dsp"
68 #define DEVICENAME_AUDIO "/dev/audio"
69 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
71 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
72 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
74 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
75 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
78 struct SoundHeader_SUN
81 unsigned long hdr_size;
82 unsigned long data_size;
83 unsigned long encoding;
84 unsigned long sample_rate;
85 unsigned long channels;
88 struct SoundHeader_8SVX
91 unsigned long chunk_size;
96 #if defined(AUDIO_UNIX_NATIVE)
97 struct SoundHeader_WAV
99 unsigned short compression_code;
100 unsigned short num_channels;
101 unsigned long sample_rate;
102 unsigned long bytes_per_second;
103 unsigned short block_align;
104 unsigned short bits_per_sample;
108 struct AudioFormatInfo
110 boolean stereo; /* availability of stereo sound */
111 int format; /* size and endianess of sample data */
112 int sample_rate; /* sample frequency */
113 int fragment_size; /* audio device fragment size in bytes */
118 char *source_filename;
123 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
124 long data_len; /* number of samples, NOT number of bytes */
126 typedef struct SampleInfo SoundInfo;
127 typedef struct SampleInfo MusicInfo;
139 unsigned long playing_starttime;
140 unsigned long playing_pos;
144 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
145 long data_len; /* number of samples, NOT number of bytes */
147 #if defined(TARGET_ALLEGRO)
151 typedef struct SoundControl SoundControl;
157 struct ListNode *next;
159 typedef struct ListNode ListNode;
161 static ListNode *newListNode(void);
162 static void addNodeToList(ListNode **, char *, void *);
163 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
164 static ListNode *getNodeFromKey(ListNode *, char *);
165 static int getNumNodes(ListNode *);
168 static struct SoundEffectInfo *sound_effect;
169 static ListNode *SoundFileList = NULL;
170 static SoundInfo **Sound = NULL;
171 static MusicInfo **Music = NULL;
172 static int num_sounds = 0, num_music = 0;
173 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
176 /* ========================================================================= */
177 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
179 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
180 static int mixer_active_channels = 0;
182 #if defined(AUDIO_UNIX_NATIVE)
183 static struct AudioFormatInfo afmt;
185 static void Mixer_Main(void);
186 #if !defined(AUDIO_STREAMING_DSP)
187 static unsigned char linear_to_ulaw(int);
188 static int ulaw_to_linear(unsigned char);
192 static void ReloadCustomSounds();
193 static void ReloadCustomMusic();
194 static void FreeSound(void *);
197 /* ------------------------------------------------------------------------- */
198 /* functions for native (non-SDL) Unix audio/mixer support */
199 /* ------------------------------------------------------------------------- */
201 #if defined(AUDIO_UNIX_NATIVE)
203 static int OpenAudioDevice(char *audio_device_name)
207 /* check if desired audio device is accessible */
208 if (access(audio_device_name, W_OK) != 0)
211 /* try to open audio device in non-blocking mode */
212 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
213 return audio_device_fd;
215 /* re-open audio device in blocking mode */
216 close(audio_device_fd);
217 audio_device_fd = open(audio_device_name, O_WRONLY);
219 return audio_device_fd;
222 static void CloseAudioDevice(int *audio_device_fd)
224 if (*audio_device_fd == 0)
227 close(*audio_device_fd);
228 *audio_device_fd = -1;
231 static boolean TestAudioDevices(void)
233 static char *audio_device_name[] =
238 int audio_device_fd = -1;
241 /* look for available audio devices, starting with preferred ones */
242 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
243 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
246 if (audio_device_fd < 0)
248 Error(ERR_WARN, "cannot open audio device -- no sound");
252 close(audio_device_fd);
254 audio.device_name = audio_device_name[i];
259 static boolean ForkAudioProcess(void)
261 if (pipe(audio.mixer_pipe) < 0)
263 Error(ERR_WARN, "cannot create pipe -- no sounds");
267 if ((audio.mixer_pid = fork()) < 0)
269 Error(ERR_WARN, "cannot create sound server process -- no sounds");
273 if (IS_CHILD_PROCESS(audio.mixer_pid))
274 Mixer_Main(); /* this function never returns */
276 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
281 void UnixOpenAudio(void)
283 if (!TestAudioDevices())
286 audio.sound_available = TRUE;
287 audio.sound_enabled = TRUE;
289 #if defined(AUDIO_STREAMING_DSP)
290 audio.music_available = TRUE;
291 audio.loops_available = TRUE;
294 audio.num_channels = NUM_MIXER_CHANNELS;
295 audio.music_channel = MUSIC_CHANNEL;
296 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
299 void UnixCloseAudio(void)
302 close(audio.device_fd);
304 if (IS_PARENT_PROCESS(audio.mixer_pid))
305 kill(audio.mixer_pid, SIGTERM);
309 /* ------------------------------------------------------------------------- */
310 /* functions for platform specific audio device initialization */
311 /* ------------------------------------------------------------------------- */
313 #if defined(AUDIO_LINUX_IOCTL)
314 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
316 /* "ioctl()" expects pointer to 'int' value for stereo flag
317 (boolean is defined as 'char', which will not work here) */
318 unsigned int fragment_spec = 0;
319 int fragment_size_query;
328 /* supported audio format in preferred order */
329 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
330 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
331 { AFMT_U8, AUDIO_FORMAT_U8 },
336 /* determine logarithm (log2) of the fragment size */
337 while ((1 << fragment_spec) < afmt->fragment_size)
340 /* use two fragments (play one fragment, prepare the other);
341 one fragment would result in interrupted audio output, more
342 than two fragments would raise audio output latency to much */
343 fragment_spec |= 0x00020000;
345 /* Example for fragment specification:
346 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
347 - (with stereo the effective buffer size will shrink to 256)
348 => fragment_size = 0x00020009 */
350 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
351 Error(ERR_EXIT_SOUND_SERVER,
352 "cannot set fragment size of /dev/dsp -- no sounds");
356 while (formats[i].format_result != -1)
358 unsigned int audio_format = formats[i].format_ioctl;
359 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
361 afmt->format = formats[i].format_result;
366 if (afmt->format == 0) /* no supported audio format found */
367 Error(ERR_EXIT_SOUND_SERVER,
368 "cannot set audio format of /dev/dsp -- no sounds");
370 /* try if we can use stereo sound */
372 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
373 afmt->stereo = FALSE;
375 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
376 Error(ERR_EXIT_SOUND_SERVER,
377 "cannot set sample rate of /dev/dsp -- no sounds");
379 /* get the real fragmentation size; this should return 512 */
380 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
381 Error(ERR_EXIT_SOUND_SERVER,
382 "cannot get fragment size of /dev/dsp -- no sounds");
383 if (fragment_size_query != afmt->fragment_size)
384 Error(ERR_EXIT_SOUND_SERVER,
385 "cannot set fragment size of /dev/dsp -- no sounds");
387 #endif /* AUDIO_LINUX_IOCTL */
389 #if defined(PLATFORM_NETBSD)
390 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
393 boolean stereo = TRUE;
395 AUDIO_INITINFO(&a_info);
396 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
397 a_info.play.precision = 8;
398 a_info.play.channels = 2;
399 a_info.play.sample_rate = sample_rate;
400 a_info.blocksize = fragment_size;
402 afmt->format = AUDIO_FORMAT_U8;
405 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
407 /* try to disable stereo */
408 a_info.play.channels = 1;
410 afmt->stereo = FALSE;
412 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
413 Error(ERR_EXIT_SOUND_SERVER,
414 "cannot set sample rate of /dev/audio -- no sounds");
417 #endif /* PLATFORM_NETBSD */
419 #if defined(PLATFORM_HPUX)
420 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
422 struct audio_describe ainfo;
425 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
427 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
429 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
430 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
432 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
433 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
435 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
436 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
438 afmt->format = AUDIO_FORMAT_U8;
439 afmt->stereo = FALSE;
440 afmt->sample_rate = 8000;
444 #endif /* PLATFORM_HPUX */
446 static void InitAudioDevice(struct AudioFormatInfo *afmt)
449 afmt->format = AUDIO_FORMAT_UNKNOWN;
450 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
451 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
453 #if defined(AUDIO_LINUX_IOCTL)
454 InitAudioDevice_Linux(afmt);
455 #elif defined(PLATFORM_NETBSD)
456 InitAudioDevice_NetBSD(afmt);
457 #elif defined(PLATFORM_HPUX)
458 InitAudioDevice_HPUX(afmt);
460 /* generic /dev/audio stuff might be placed here */
465 /* ------------------------------------------------------------------------- */
466 /* functions for communication between main process and sound mixer process */
467 /* ------------------------------------------------------------------------- */
469 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
471 if (IS_CHILD_PROCESS(audio.mixer_pid))
474 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
476 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
477 audio.sound_available = audio.sound_enabled = FALSE;
482 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
484 if (IS_PARENT_PROCESS(audio.mixer_pid))
487 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
488 != sizeof(SoundControl))
489 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
492 static void WriteReloadInfoToPipe(char *set_name, int type)
494 SoundControl snd_ctrl;
495 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
496 artwork.mus_current);
497 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
498 unsigned long str_size2 = strlen(ti->basepath) + 1;
499 unsigned long str_size3 = strlen(ti->fullpath) + 1;
501 if (IS_CHILD_PROCESS(audio.mixer_pid))
504 if (leveldir_current == NULL) /* should never happen */
505 Error(ERR_EXIT, "leveldir_current == NULL");
507 snd_ctrl.active = FALSE;
508 snd_ctrl.state = type;
509 snd_ctrl.data_len = strlen(set_name) + 1;
511 if (write(audio.mixer_pipe[1], &snd_ctrl,
512 sizeof(snd_ctrl)) < 0 ||
513 write(audio.mixer_pipe[1], set_name,
514 snd_ctrl.data_len) < 0 ||
515 write(audio.mixer_pipe[1], leveldir_current,
516 sizeof(TreeInfo)) < 0 ||
517 write(audio.mixer_pipe[1], ti,
518 sizeof(TreeInfo)) < 0 ||
519 write(audio.mixer_pipe[1], &str_size1,
520 sizeof(unsigned long)) < 0 ||
521 write(audio.mixer_pipe[1], &str_size2,
522 sizeof(unsigned long)) < 0 ||
523 write(audio.mixer_pipe[1], &str_size3,
524 sizeof(unsigned long)) < 0 ||
525 write(audio.mixer_pipe[1], leveldir_current->fullpath,
527 write(audio.mixer_pipe[1], ti->basepath,
529 write(audio.mixer_pipe[1], ti->fullpath,
532 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
533 audio.sound_available = audio.sound_enabled = FALSE;
538 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
540 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
541 &artwork.snd_current : &artwork.mus_current);
542 TreeInfo *ti = *ti_ptr;
543 unsigned long str_size1, str_size2, str_size3;
544 static char *set_name = NULL;
549 set_name = checked_malloc(snd_ctrl->data_len);
551 if (leveldir_current == NULL)
552 leveldir_current = checked_calloc(sizeof(TreeInfo));
554 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
555 if (leveldir_current->fullpath != NULL)
556 free(leveldir_current->fullpath);
557 if (ti->basepath != NULL)
559 if (ti->fullpath != NULL)
562 if (read(audio.mixer_pipe[0], set_name,
563 snd_ctrl->data_len) != snd_ctrl->data_len ||
564 read(audio.mixer_pipe[0], leveldir_current,
565 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
566 read(audio.mixer_pipe[0], ti,
567 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
568 read(audio.mixer_pipe[0], &str_size1,
569 sizeof(unsigned long)) != sizeof(unsigned long) ||
570 read(audio.mixer_pipe[0], &str_size2,
571 sizeof(unsigned long)) != sizeof(unsigned long) ||
572 read(audio.mixer_pipe[0], &str_size3,
573 sizeof(unsigned long)) != sizeof(unsigned long))
574 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
576 leveldir_current->fullpath = checked_calloc(str_size1);
577 ti->basepath = checked_calloc(str_size2);
578 ti->fullpath = checked_calloc(str_size3);
580 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
581 str_size1) != str_size1 ||
582 read(audio.mixer_pipe[0], ti->basepath,
583 str_size2) != str_size2 ||
584 read(audio.mixer_pipe[0], ti->fullpath,
585 str_size3) != str_size3)
586 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
588 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
589 artwork.sounds_set_current = set_name;
591 artwork.music_set_current = set_name;
594 #endif /* AUDIO_UNIX_NATIVE */
597 /* ------------------------------------------------------------------------- */
598 /* mixer functions */
599 /* ------------------------------------------------------------------------- */
601 void Mixer_InitChannels()
605 for(i=0; i<audio.num_channels; i++)
606 mixer[i].active = FALSE;
607 mixer_active_channels = 0;
610 static void Mixer_ResetChannelExpiration(int channel)
612 mixer[channel].playing_starttime = Counter();
614 #if defined(TARGET_SDL)
615 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
616 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
620 static boolean Mixer_ChannelExpired(int channel)
622 if (!mixer[channel].active)
625 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
626 DelayReached(&mixer[channel].playing_starttime,
627 SOUND_LOOP_EXPIRATION_TIME))
630 #if defined(TARGET_SDL)
632 if (!Mix_Playing(channel))
635 #elif defined(TARGET_ALLEGRO)
637 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
638 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
640 /* sound sample has completed playing or was completely faded out */
641 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
644 #endif /* TARGET_ALLEGRO */
649 static boolean Mixer_AllocateChannel(int channel)
651 #if defined(TARGET_ALLEGRO)
652 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
653 if (mixer[channel].voice < 0)
660 static void Mixer_SetChannelProperties(int channel)
662 #if defined(TARGET_SDL)
663 Mix_Volume(channel, mixer[channel].volume);
664 Mix_SetPanning(channel,
665 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
666 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
667 #elif defined(TARGET_ALLEGRO)
668 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
669 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
673 static void Mixer_StartChannel(int channel)
675 #if defined(TARGET_SDL)
676 Mix_PlayChannel(channel, mixer[channel].data_ptr,
677 IS_LOOP(mixer[channel]) ? -1 : 0);
678 #elif defined(TARGET_ALLEGRO)
679 if (IS_LOOP(mixer[channel]))
680 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
682 voice_start(mixer[channel].voice);
686 static void Mixer_PlayChannel(int channel)
688 /* start with inactive channel in case something goes wrong */
689 mixer[channel].active = FALSE;
691 if (mixer[channel].type != MUS_TYPE_WAV)
694 if (!Mixer_AllocateChannel(channel))
697 Mixer_SetChannelProperties(channel);
698 Mixer_StartChannel(channel);
700 Mixer_ResetChannelExpiration(channel);
702 mixer[channel].playing_pos = 0;
703 mixer[channel].active = TRUE;
704 mixer_active_channels++;
707 static void Mixer_PlayMusicChannel()
709 Mixer_PlayChannel(audio.music_channel);
711 #if defined(TARGET_SDL)
712 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
714 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
715 this looks like a bug in the SDL_mixer library */
716 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
717 Mix_VolumeMusic(SOUND_MAX_VOLUME);
722 static void Mixer_StopChannel(int channel)
724 if (!mixer[channel].active)
727 #if defined(TARGET_SDL)
728 Mix_HaltChannel(channel);
729 #elif defined(TARGET_ALLEGRO)
730 voice_set_volume(mixer[channel].voice, 0);
731 deallocate_voice(mixer[channel].voice);
734 mixer[channel].active = FALSE;
735 mixer_active_channels--;
738 static void Mixer_StopMusicChannel()
740 Mixer_StopChannel(audio.music_channel);
742 #if defined(TARGET_SDL)
747 static void Mixer_FadeChannel(int channel)
749 if (!mixer[channel].active)
752 mixer[channel].state |= SND_CTRL_FADE;
754 #if defined(TARGET_SDL)
755 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
756 #elif defined(TARGET_ALLEGRO)
757 if (voice_check(mixer[channel].voice))
758 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
762 static void Mixer_FadeMusicChannel()
764 Mixer_FadeChannel(audio.music_channel);
766 #if defined(TARGET_SDL)
767 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
771 static void Mixer_UnFadeChannel(int channel)
773 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
776 mixer[channel].state &= ~SND_CTRL_FADE;
777 mixer[channel].volume = SOUND_MAX_VOLUME;
779 #if defined(TARGET_SDL)
780 Mix_ExpireChannel(channel, -1);
781 Mix_Volume(channel, mixer[channel].volume);
782 #elif defined(TARGET_ALLEGRO)
783 voice_stop_volumeramp(mixer[channel].voice);
784 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
785 mixer[channel].volume);
789 static void Mixer_InsertSound(SoundControl snd_ctrl)
795 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
799 printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
802 if (IS_MUSIC(snd_ctrl))
803 snd_ctrl.nr = snd_ctrl.nr % num_music;
804 else if (snd_ctrl.nr >= num_sounds)
807 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
808 if (snd_info == NULL)
811 /* copy sound sample and format information */
812 snd_ctrl.type = snd_info->type;
813 snd_ctrl.format = snd_info->format;
814 snd_ctrl.data_ptr = snd_info->data_ptr;
815 snd_ctrl.data_len = snd_info->data_len;
817 /* play music samples on a dedicated music channel */
818 if (IS_MUSIC(snd_ctrl))
821 printf("PLAY MUSIC WITH VOLUME/STEREO %d/%d\n",
822 snd_ctrl.volume, snd_ctrl.stereo_position);
825 mixer[audio.music_channel] = snd_ctrl;
826 Mixer_PlayMusicChannel();
831 /* check if (and how often) this sound sample is already playing */
832 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
833 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
837 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
840 /* reset expiration delay for already playing loop sounds */
841 if (k > 0 && IS_LOOP(snd_ctrl))
843 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
845 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
848 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
851 if (IS_FADING(mixer[i]))
852 Mixer_UnFadeChannel(i);
854 /* restore settings like volume and stereo position */
855 mixer[i].volume = snd_ctrl.volume;
856 mixer[i].stereo_position = snd_ctrl.stereo_position;
858 Mixer_SetChannelProperties(i);
859 Mixer_ResetChannelExpiration(i);
862 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
863 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
872 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
875 /* don't play sound more than n times simultaneously (with n == 2 for now) */
878 unsigned long playing_current = Counter();
879 int longest = 0, longest_nr = audio.first_sound_channel;
881 /* look for oldest equal sound */
882 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
884 int playing_time = playing_current - mixer[i].playing_starttime;
887 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
890 actual = 1000 * playing_time / mixer[i].data_len;
892 if (actual >= longest)
899 Mixer_StopChannel(longest_nr);
902 /* If all (non-music) channels are active, stop the channel that has
903 played its sound sample most completely (in percent of the sample
904 length). As we cannot currently get the actual playing position
905 of the channel's sound sample when compiling with the SDL mixer
906 library, we use the current playing time (in milliseconds) instead. */
908 if (mixer_active_channels ==
909 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
911 unsigned long playing_current = Counter();
912 int longest = 0, longest_nr = audio.first_sound_channel;
914 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
916 int playing_time = playing_current - mixer[i].playing_starttime;
917 int actual = 1000 * playing_time / mixer[i].data_len;
919 if (!IS_LOOP(mixer[i]) && actual > longest)
926 Mixer_StopChannel(longest_nr);
929 /* add the new sound to the mixer */
930 for(i=0; i<audio.num_channels; i++)
933 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
937 if (!mixer[i].active ||
938 (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
940 if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
941 (i != audio.music_channel && !mixer[i].active))
944 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
948 #if defined(AUDIO_UNIX_NATIVE)
949 if (snd_info->data_len == 0)
951 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
957 if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
959 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
962 Mixer_StopChannel(i);
968 Mixer_PlayChannel(i);
975 static void HandleSoundRequest(SoundControl snd_ctrl)
979 #if defined(AUDIO_UNIX_NATIVE)
980 if (IS_PARENT_PROCESS(audio.mixer_pid))
982 SendSoundControlToMixerProcess(&snd_ctrl);
987 /* deactivate channels that have expired since the last request */
988 for (i=0; i<audio.num_channels; i++)
989 if (mixer[i].active && Mixer_ChannelExpired(i))
990 Mixer_StopChannel(i);
992 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
994 Mixer_StopMusicChannel();
995 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
996 Mixer_StopChannel(i);
998 #if defined(AUDIO_UNIX_NATIVE)
999 CloseAudioDevice(&audio.device_fd);
1000 ReadReloadInfoFromPipe(&snd_ctrl);
1003 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1004 ReloadCustomSounds();
1006 ReloadCustomMusic();
1008 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1010 if (IS_MUSIC(snd_ctrl))
1012 Mixer_FadeMusicChannel();
1016 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1017 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1018 Mixer_FadeChannel(i);
1020 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1022 if (IS_MUSIC(snd_ctrl))
1024 Mixer_StopMusicChannel();
1028 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1029 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1030 Mixer_StopChannel(i);
1032 #if defined(AUDIO_UNIX_NATIVE)
1033 if (!mixer_active_channels)
1034 CloseAudioDevice(&audio.device_fd);
1037 else if (snd_ctrl.active) /* add new sound to mixer */
1039 Mixer_InsertSound(snd_ctrl);
1043 void StartMixer(void)
1048 SDL_version compile_version;
1049 const SDL_version *link_version;
1050 MIX_VERSION(&compile_version);
1051 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1052 compile_version.major,
1053 compile_version.minor,
1054 compile_version.patch);
1055 link_version = Mix_Linked_Version();
1056 printf("running with SDL_mixer version: %d.%d.%d\n",
1057 link_version->major,
1058 link_version->minor,
1059 link_version->patch);
1062 if (!audio.sound_available)
1065 /* initialize stereo position conversion information */
1066 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1068 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1070 #if defined(AUDIO_UNIX_NATIVE)
1071 if (!ForkAudioProcess())
1072 audio.sound_available = FALSE;
1076 #if defined(AUDIO_UNIX_NATIVE)
1078 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1079 int sample_pos, int sample_size,
1082 void *sample_ptr = snd_ctrl->data_ptr;
1085 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1086 for (i=0; i<sample_size; i++)
1088 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1089 else /* AUDIO_FORMAT_S16 */
1090 for (i=0; i<sample_size; i++)
1092 ((short *)sample_ptr)[sample_pos + i];
1095 #if defined(AUDIO_STREAMING_DSP)
1096 static void Mixer_Main_DSP()
1098 static short premix_first_buffer[SND_BLOCKSIZE];
1099 static short premix_left_buffer[SND_BLOCKSIZE];
1100 static short premix_right_buffer[SND_BLOCKSIZE];
1101 static long premix_last_buffer[SND_BLOCKSIZE];
1102 static byte playing_buffer[SND_BLOCKSIZE];
1106 int max_sample_size;
1109 if (!mixer_active_channels)
1112 if (audio.device_fd < 0)
1114 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1117 InitAudioDevice(&afmt);
1120 stereo = afmt.stereo;
1121 fragment_size = afmt.fragment_size;
1122 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1123 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1125 /* first clear the last premixing buffer */
1126 memset(premix_last_buffer, 0,
1127 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1129 for(i=0; i<audio.num_channels; i++)
1136 if (!mixer[i].active)
1139 if (Mixer_ChannelExpired(i))
1141 Mixer_StopChannel(i);
1145 /* pointer, lenght and actual playing position of sound sample */
1146 sample_ptr = mixer[i].data_ptr;
1147 sample_len = mixer[i].data_len;
1148 sample_pos = mixer[i].playing_pos;
1149 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1150 mixer[i].playing_pos += sample_size;
1152 /* copy original sample to first mixing buffer */
1153 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1154 premix_first_buffer);
1156 /* are we about to restart a looping sound? */
1157 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1159 while (sample_size < max_sample_size)
1161 int restarted_sample_size =
1162 MIN(max_sample_size - sample_size, sample_len);
1164 if (mixer[i].format == AUDIO_FORMAT_U8)
1165 for (j=0; j<restarted_sample_size; j++)
1166 premix_first_buffer[sample_size + j] =
1167 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1169 for (j=0; j<restarted_sample_size; j++)
1170 premix_first_buffer[sample_size + j] =
1171 ((short *)sample_ptr)[j];
1173 mixer[i].playing_pos = restarted_sample_size;
1174 sample_size += restarted_sample_size;
1178 /* decrease volume if sound is fading out */
1179 if (IS_FADING(mixer[i]) &&
1180 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1181 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1183 /* adjust volume of actual sound sample */
1184 if (mixer[i].volume != SOUND_MAX_VOLUME)
1185 for(j=0; j<sample_size; j++)
1186 premix_first_buffer[j] =
1187 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1189 /* fill the last mixing buffer with stereo or mono sound */
1192 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1193 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1195 for(j=0; j<sample_size; j++)
1197 premix_left_buffer[j] =
1198 left_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1199 premix_right_buffer[j] =
1200 right_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1202 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1203 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1208 for(j=0; j<sample_size; j++)
1209 premix_last_buffer[j] += premix_first_buffer[j];
1212 /* delete completed sound entries from the mixer */
1213 if (mixer[i].playing_pos >= mixer[i].data_len)
1215 if (IS_LOOP(mixer[i]))
1216 mixer[i].playing_pos = 0;
1218 Mixer_StopChannel(i);
1220 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1221 Mixer_StopChannel(i);
1224 /* prepare final playing buffer according to system audio format */
1225 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1227 /* cut off at 17 bit value */
1228 if (premix_last_buffer[i] < -65535)
1229 premix_last_buffer[i] = -65535;
1230 else if (premix_last_buffer[i] > 65535)
1231 premix_last_buffer[i] = 65535;
1233 /* shift to 16 bit value */
1234 premix_last_buffer[i] >>= 1;
1236 if (afmt.format & AUDIO_FORMAT_U8)
1238 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1240 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1242 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1243 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1245 else /* big endian */
1247 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1248 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1252 /* finally play the sound fragment */
1253 write(audio.device_fd, playing_buffer, fragment_size);
1255 if (!mixer_active_channels)
1256 CloseAudioDevice(&audio.device_fd);
1259 #else /* !AUDIO_STREAMING_DSP */
1261 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1263 static short premix_first_buffer[SND_BLOCKSIZE];
1264 static byte playing_buffer[SND_BLOCKSIZE];
1265 int max_sample_size = SND_BLOCKSIZE;
1274 /* pointer, lenght and actual playing position of sound sample */
1275 sample_ptr = mixer[i].data_ptr;
1276 sample_len = mixer[i].data_len;
1277 sample_pos = mixer[i].playing_pos;
1278 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1279 mixer[i].playing_pos += sample_size;
1281 /* copy original sample to first mixing buffer */
1282 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1283 premix_first_buffer);
1285 /* adjust volume of actual sound sample */
1286 if (mixer[i].volume != SOUND_MAX_VOLUME)
1287 for(j=0; j<sample_size; j++)
1288 premix_first_buffer[j] =
1289 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1291 /* might be needed for u-law /dev/audio */
1293 for(j=0; j<sample_size; j++)
1295 linear_to_ulaw(premix_first_buffer[j]);
1298 /* delete completed sound entries from the mixer */
1299 if (mixer[i].playing_pos >= mixer[i].data_len)
1300 Mixer_StopChannel(i);
1302 for(i=0; i<sample_size; i++)
1303 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1305 /* finally play the sound fragment */
1306 write(audio.device_fd, playing_buffer, sample_size);
1310 #endif /* !AUDIO_STREAMING_DSP */
1314 SoundControl snd_ctrl;
1317 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1319 Mixer_InitChannels();
1321 #if defined(PLATFORM_HPUX)
1322 InitAudioDevice(&afmt);
1325 FD_ZERO(&mixer_fdset);
1326 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1328 while(1) /* wait for sound playing commands from client */
1330 struct timeval delay = { 0, 0 };
1332 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1333 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1334 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1337 ReadSoundControlFromMainProcess(&snd_ctrl);
1339 HandleSoundRequest(snd_ctrl);
1341 #if defined(AUDIO_STREAMING_DSP)
1343 while (mixer_active_channels &&
1344 select(audio.mixer_pipe[0] + 1,
1345 &mixer_fdset, NULL, NULL, &delay) < 1)
1347 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1352 #else /* !AUDIO_STREAMING_DSP */
1354 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1355 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1358 InitAudioDevice(&afmt);
1363 while (mixer_active_channels &&
1364 select(audio.mixer_pipe[0] + 1,
1365 &mixer_fdset, NULL, NULL, &delay) < 1)
1367 int wait_percent = 90; /* wait 90% of the real playing time */
1370 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1372 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1376 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1379 CloseAudioDevice(&audio.device_fd);
1381 Mixer_InitChannels(); /* remove all sounds from mixer */
1383 #endif /* !AUDIO_STREAMING_DSP */
1386 #endif /* AUDIO_UNIX_NATIVE */
1389 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1391 /* these two are stolen from "sox"... :) */
1394 ** This routine converts from linear to ulaw.
1396 ** Craig Reese: IDA/Supercomputing Research Center
1397 ** Joe Campbell: Department of Defense
1398 ** 29 September 1989
1401 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1402 ** 2) "A New Digital Technique for Implementation of Any
1403 ** Continuous PCM Companding Law," Villeret, Michel,
1404 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1405 ** 1973, pg. 11.12-11.17
1406 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1407 ** for Analog-to_Digital Conversion Techniques,"
1410 ** Input: Signed 16 bit linear sample
1411 ** Output: 8 bit ulaw sample
1414 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1415 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1418 static unsigned char linear_to_ulaw(int sample)
1420 static int exp_lut[256] =
1422 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1423 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1424 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1425 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1426 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1427 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1428 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1429 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1430 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1431 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1432 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1433 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1434 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1435 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1436 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1437 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1440 int sign, exponent, mantissa;
1441 unsigned char ulawbyte;
1443 /* Get the sample into sign-magnitude. */
1444 sign = (sample >> 8) & 0x80; /* set aside the sign */
1446 sample = -sample; /* get magnitude */
1448 sample = CLIP; /* clip the magnitude */
1450 /* Convert from 16 bit linear to ulaw. */
1451 sample = sample + BIAS;
1452 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1453 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1454 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1457 ulawbyte = 0x02; /* optional CCITT trap */
1464 ** This routine converts from ulaw to 16 bit linear.
1466 ** Craig Reese: IDA/Supercomputing Research Center
1467 ** 29 September 1989
1470 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1471 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1472 ** for Analog-to_Digital Conversion Techniques,"
1475 ** Input: 8 bit ulaw sample
1476 ** Output: signed 16 bit linear sample
1479 static int ulaw_to_linear(unsigned char ulawbyte)
1481 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1482 int sign, exponent, mantissa, sample;
1484 ulawbyte = ~ ulawbyte;
1485 sign = ( ulawbyte & 0x80 );
1486 exponent = ( ulawbyte >> 4 ) & 0x07;
1487 mantissa = ulawbyte & 0x0F;
1488 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1494 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1497 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1498 /* ========================================================================= */
1499 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1501 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1502 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1504 static SoundInfo *Load_WAV(char *filename)
1506 SoundInfo *snd_info;
1507 #if defined(AUDIO_UNIX_NATIVE)
1508 struct SoundHeader_WAV header;
1510 byte sound_header_buffer[WAV_HEADER_SIZE];
1513 char chunk_name[CHUNK_ID_LEN + 1];
1518 if (!audio.sound_available)
1522 printf("loading WAV file '%s'\n", filename);
1525 snd_info = checked_calloc(sizeof(SoundInfo));
1527 #if defined(TARGET_SDL)
1529 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1531 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1536 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1538 #elif defined(TARGET_ALLEGRO)
1540 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1542 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1547 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1549 #else /* AUDIO_UNIX_NATIVE */
1551 if ((file = fopen(filename, MODE_READ)) == NULL)
1553 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1558 /* read chunk id "RIFF" */
1559 getFileChunkLE(file, chunk_name, &chunk_size);
1560 if (strcmp(chunk_name, "RIFF") != 0)
1562 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1568 /* read "RIFF" type id "WAVE" */
1569 getFileChunkLE(file, chunk_name, NULL);
1570 if (strcmp(chunk_name, "WAVE") != 0)
1572 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1578 while (getFileChunkLE(file, chunk_name, &chunk_size))
1580 if (strcmp(chunk_name, "fmt ") == 0)
1582 if (chunk_size < WAV_HEADER_SIZE)
1584 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1590 header.compression_code = getFile16BitLE(file);
1591 header.num_channels = getFile16BitLE(file);
1592 header.sample_rate = getFile32BitLE(file);
1593 header.bytes_per_second = getFile32BitLE(file);
1594 header.block_align = getFile16BitLE(file);
1595 header.bits_per_sample = getFile16BitLE(file);
1597 if (chunk_size > WAV_HEADER_SIZE)
1598 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1600 if (header.compression_code != 1)
1602 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1603 filename, header.compression_code);
1609 if (header.num_channels != 1)
1611 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1612 filename, header.num_channels);
1618 if (header.bits_per_sample != 8 && header.bits_per_sample != 16)
1620 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1621 filename, header.bits_per_sample);
1627 /* warn, but accept wrong sample rate (may be only slightly different) */
1628 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1629 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1630 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1633 printf("WAV file: '%s'\n", filename);
1634 printf(" Compression code: %d'\n", header.compression_code);
1635 printf(" Number of channels: %d'\n", header.num_channels);
1636 printf(" Sample rate: %ld'\n", header.sample_rate);
1637 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1638 printf(" Block align: %d'\n", header.block_align);
1639 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1642 else if (strcmp(chunk_name, "data") == 0)
1644 snd_info->data_len = chunk_size;
1645 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1647 /* read sound data */
1648 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1651 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1653 free(snd_info->data_ptr);
1658 /* check for odd number of sample bytes (data chunk is word aligned) */
1659 if ((chunk_size % 2) == 1)
1660 ReadUnusedBytesFromFile(file, 1);
1662 else /* unknown chunk -- ignore */
1663 ReadUnusedBytesFromFile(file, chunk_size);
1668 if (snd_info->data_ptr == NULL)
1670 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1675 if (header.bits_per_sample == 8)
1676 snd_info->format = AUDIO_FORMAT_U8;
1677 else /* header.bits_per_sample == 16 */
1679 snd_info->format = AUDIO_FORMAT_S16;
1680 snd_info->data_len /= 2; /* correct number of samples */
1683 #endif /* AUDIO_UNIX_NATIVE */
1685 snd_info->type = SND_TYPE_WAV;
1686 snd_info->source_filename = getStringCopy(filename);
1691 static void deleteSoundEntry(SoundInfo **snd_info)
1695 char *filename = (*snd_info)->source_filename;
1698 printf("[decrementing reference counter of sound '%s']\n", filename);
1701 if (--(*snd_info)->num_references <= 0)
1704 printf("[deleting sound '%s']\n", filename);
1708 FreeSound(*snd_info);
1710 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1717 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1721 /* check if the old and the new sound file are the same */
1722 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1724 /* The old and new sound are the same (have the same filename and path).
1725 This usually means that this sound does not exist in this sound set
1726 and a fallback to the existing sound is done. */
1729 printf("[sound '%s' already exists (same list entry)]\n", filename);
1735 /* delete existing sound file entry */
1736 deleteSoundEntry(snd_info);
1738 /* check if the new sound file already exists in the list of sounds */
1739 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1742 printf("[sound '%s' already exists (other list entry)]\n", filename);
1745 *snd_info = (SoundInfo *)node->content;
1746 (*snd_info)->num_references++;
1748 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1750 (*snd_info)->num_references = 1;
1751 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1755 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1757 char *filename = getCustomSoundFilename(basename);
1760 printf("GOT CUSTOM SOUND FILE '%s'\n", filename);
1763 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1765 deleteSoundEntry(snd_info);
1769 if (filename == NULL)
1771 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1775 replaceSoundEntry(snd_info, filename);
1778 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1781 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1783 sound_effect = sounds_list;
1784 num_sounds = num_list_entries;
1787 void LoadSoundToList(char *basename, int list_pos)
1789 if (Sound == NULL || list_pos >= num_sounds)
1793 printf("loading sound '%s' ... [%d]\n",
1794 basename, getNumNodes(SoundFileList));
1797 LoadCustomSound(&Sound[list_pos], basename);
1800 printf("loading sound '%s' done [%d]\n",
1801 basename, getNumNodes(SoundFileList));
1805 static MusicInfo *Load_MOD(char *filename)
1807 #if defined(TARGET_SDL)
1808 MusicInfo *mod_info;
1810 if (!audio.sound_available)
1813 mod_info = checked_calloc(sizeof(MusicInfo));
1815 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1817 Error(ERR_WARN, "cannot read music file '%s'", filename);
1822 mod_info->type = MUS_TYPE_MOD;
1823 mod_info->source_filename = getStringCopy(filename);
1831 void LoadCustomMusic(void)
1833 static boolean draw_init_text = TRUE; /* only draw at startup */
1834 char *music_directory = getCustomMusicDirectory();
1836 struct dirent *dir_entry;
1838 if (!audio.sound_available)
1841 if ((dir = opendir(music_directory)) == NULL)
1843 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1844 audio.music_available = FALSE;
1849 DrawInitText("Loading music:", 120, FC_GREEN);
1851 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1853 char *basename = dir_entry->d_name;
1854 char *filename = getPath2(music_directory, basename);
1855 MusicInfo *mus_info = NULL;
1858 DrawInitText(basename, 150, FC_YELLOW);
1860 if (FileIsSound(basename))
1861 mus_info = Load_WAV(filename);
1862 else if (FileIsMusic(basename))
1863 mus_info = Load_MOD(filename);
1870 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1871 Music[num_music -1] = mus_info;
1877 draw_init_text = FALSE;
1880 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1884 void PlayMusic(int nr)
1886 if (!audio.music_available)
1892 void PlaySound(int nr)
1894 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1897 void PlaySoundStereo(int nr, int stereo_position)
1899 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1902 void PlaySoundLoop(int nr)
1904 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1907 void PlaySoundMusic(int nr)
1909 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1912 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1914 SoundControl snd_ctrl;
1916 if (!audio.sound_available ||
1917 !audio.sound_enabled ||
1918 audio.sound_deactivated)
1921 if (volume < SOUND_MIN_VOLUME)
1922 volume = SOUND_MIN_VOLUME;
1923 else if (volume > SOUND_MAX_VOLUME)
1924 volume = SOUND_MAX_VOLUME;
1926 if (stereo_position < SOUND_MAX_LEFT)
1927 stereo_position = SOUND_MAX_LEFT;
1928 else if (stereo_position > SOUND_MAX_RIGHT)
1929 stereo_position = SOUND_MAX_RIGHT;
1931 snd_ctrl.active = TRUE;
1933 snd_ctrl.volume = volume;
1934 snd_ctrl.stereo_position = stereo_position;
1935 snd_ctrl.state = state;
1937 HandleSoundRequest(snd_ctrl);
1940 void FadeMusic(void)
1942 if (!audio.music_available)
1945 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1948 void FadeSound(int nr)
1950 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1956 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1959 void StopMusic(void)
1961 if (!audio.music_available)
1964 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1967 void StopSound(int nr)
1969 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1975 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1978 void StopSoundExt(int nr, int state)
1980 SoundControl snd_ctrl;
1982 if (!audio.sound_available)
1985 snd_ctrl.active = FALSE;
1987 snd_ctrl.state = state;
1989 HandleSoundRequest(snd_ctrl);
1992 ListNode *newListNode()
1994 return checked_calloc(sizeof(ListNode));
1997 void addNodeToList(ListNode **node_first, char *key, void *content)
1999 ListNode *node_new = newListNode();
2002 printf("LIST: adding node with key '%s'\n", key);
2005 node_new->key = getStringCopy(key);
2006 node_new->content = content;
2007 node_new->next = *node_first;
2008 *node_first = node_new;
2011 void deleteNodeFromList(ListNode **node_first, char *key,
2012 void (*destructor_function)(void *))
2014 if (node_first == NULL || *node_first == NULL)
2018 printf("[CHECKING LIST KEY '%s' == '%s']\n",
2019 (*node_first)->key, key);
2022 if (strcmp((*node_first)->key, key) == 0)
2025 printf("[DELETING LIST ENTRY]\n");
2028 free((*node_first)->key);
2029 if (destructor_function)
2030 destructor_function((*node_first)->content);
2031 *node_first = (*node_first)->next;
2034 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
2037 ListNode *getNodeFromKey(ListNode *node_first, char *key)
2039 if (node_first == NULL)
2042 if (strcmp(node_first->key, key) == 0)
2045 return getNodeFromKey(node_first->next, key);
2048 int getNumNodes(ListNode *node_first)
2050 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
2053 void dumpList(ListNode *node_first)
2055 ListNode *node = node_first;
2059 printf("['%s' (%d)]\n", node->key,
2060 ((SoundInfo *)node->content)->num_references);
2064 printf("[%d nodes]\n", getNumNodes(node_first));
2067 static void LoadSoundsInfo()
2069 char *filename = getCustomSoundConfigFilename();
2070 struct SetupFileList *setup_file_list;
2074 printf("GOT CUSTOM SOUND CONFIG FILE '%s'\n", filename);
2077 /* always start with reliable default values */
2078 for (i=0; i<num_sounds; i++)
2079 sound_effect[i].filename = NULL;
2081 if (filename == NULL)
2084 if ((setup_file_list = loadSetupFileList(filename)))
2086 for (i=0; i<num_sounds; i++)
2087 sound_effect[i].filename =
2088 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
2090 freeSetupFileList(setup_file_list);
2093 for (i=0; i<num_sounds; i++)
2095 printf("'%s' ", sound_effect[i].text);
2096 if (sound_effect[i].filename)
2097 printf("-> '%s'\n", sound_effect[i].filename);
2099 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
2105 static void ReloadCustomSounds()
2107 static boolean draw_init_text = TRUE; /* only draw at startup */
2111 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
2117 DrawInitText("Loading sounds:", 120, FC_GREEN);
2120 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
2123 for(i=0; i<num_sounds; i++)
2126 DrawInitText(sound_effect[i].text, 150, FC_YELLOW);
2128 if (sound_effect[i].filename)
2129 LoadSoundToList(sound_effect[i].filename, i);
2131 LoadSoundToList(sound_effect[i].default_filename, i);
2134 draw_init_text = FALSE;
2137 printf("list size == %d\n", getNumNodes(SoundFileList));
2141 dumpList(SoundFileList);
2145 static void ReloadCustomMusic()
2148 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
2156 void InitReloadSounds(char *set_name)
2158 if (!audio.sound_available)
2161 #if defined(AUDIO_UNIX_NATIVE)
2162 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
2164 ReloadCustomSounds();
2168 void InitReloadMusic(char *set_name)
2170 if (!audio.music_available)
2173 #if defined(AUDIO_UNIX_NATIVE)
2174 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
2176 ReloadCustomMusic();
2180 void FreeSound(void *ptr)
2182 SoundInfo *sound = (SoundInfo *)ptr;
2187 if (sound->data_ptr)
2189 #if defined(TARGET_SDL)
2190 Mix_FreeChunk(sound->data_ptr);
2191 #elif defined(TARGET_ALLEGRO)
2192 destroy_sample(sound->data_ptr);
2193 #else /* AUDIO_UNIX_NATIVE */
2194 free(sound->data_ptr);
2198 if (sound->source_filename)
2199 free(sound->source_filename);
2204 void FreeMusic(MusicInfo *music)
2209 if (music->data_ptr)
2211 #if defined(TARGET_SDL)
2212 if (music->type == MUS_TYPE_MOD)
2213 Mix_FreeMusic(music->data_ptr);
2215 Mix_FreeChunk(music->data_ptr);
2216 #elif defined(TARGET_ALLEGRO)
2217 destroy_sample(music->data_ptr);
2218 #else /* AUDIO_UNIX_NATIVE */
2219 free(music->data_ptr);
2226 void FreeAllSounds()
2234 printf("%s: FREEING SOUNDS ...\n",
2235 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2238 for(i=0; i<num_sounds; i++)
2239 deleteSoundEntry(&Sound[i]);
2241 FreeSound(Sound[i]);
2245 printf("%s: FREEING SOUNDS -- DONE\n",
2246 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2262 for(i=0; i<num_music; i++)
2263 FreeMusic(Music[i]);
2271 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2272 /* ========================================================================= */