rnd-20060407-2-src
[rocksndiamonds.git] / src / libgame / sound.c
1 /***********************************************************
2 * Artsoft Retro-Game Library                               *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment                      *
5 *               Holger Schemel                             *
6 *               Detmolder Strasse 189                      *
7 *               33604 Bielefeld                            *
8 *               Germany                                    *
9 *               e-mail: info@artsoft.org                   *
10 *----------------------------------------------------------*
11 * sound.c                                                  *
12 ***********************************************************/
13
14 #include <sys/types.h>
15 #include <sys/time.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <dirent.h>
20 #include <signal.h>
21 #include <math.h>
22
23 #include "platform.h"
24
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>
35 #endif
36
37 #include "system.h"
38 #include "sound.h"
39 #include "misc.h"
40 #include "setup.h"
41 #include "text.h"
42
43
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME      200
46
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL           1000
49
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)
53 #endif
54
55 #define SND_TYPE_NONE                   0
56 #define SND_TYPE_WAV                    1
57
58 #define MUS_TYPE_NONE                   0
59 #define MUS_TYPE_WAV                    1
60 #define MUS_TYPE_MOD                    2
61
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"
66
67 #define SOUND_VOLUME_LEFT(x)            (stereo_volume[x])
68 #define SOUND_VOLUME_RIGHT(x)           (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
69
70 #define SAME_SOUND_NR(x,y)              ((x).nr == (y).nr)
71 #define SAME_SOUND_DATA(x,y)            ((x).data_ptr == (y).data_ptr)
72
73 #if defined(AUDIO_UNIX_NATIVE)
74 struct SoundHeader_WAV
75 {
76   unsigned short compression_code;
77   unsigned short num_channels;
78   unsigned long  sample_rate;
79   unsigned long  bytes_per_second;
80   unsigned short block_align;
81   unsigned short bits_per_sample;
82 };
83 #endif
84
85 struct AudioFormatInfo
86 {
87   boolean stereo;               /* availability of stereo sound */
88   int format;                   /* size and endianess of sample data */
89   int sample_rate;              /* sample frequency */
90   int fragment_size;            /* audio device fragment size in bytes */
91 };
92
93 struct SampleInfo
94 {
95   char *source_filename;
96   int num_references;
97
98   int type;
99   int format;
100   void *data_ptr;               /* pointer to first sample (8 or 16 bit) */
101   long data_len;                /* number of samples, NOT number of bytes */
102   int num_channels;             /* mono: 1 channel, stereo: 2 channels */
103 };
104 typedef struct SampleInfo SoundInfo;
105 typedef struct SampleInfo MusicInfo;
106
107 struct SoundControl
108 {
109   boolean active;
110
111   int nr;
112   int volume;
113   int stereo_position;
114
115   int state;
116
117   unsigned long playing_starttime;
118   unsigned long playing_pos;
119
120   int type;
121   int format;
122   void *data_ptr;               /* pointer to first sample (8 or 16 bit) */
123   long data_len;                /* number of samples, NOT number of bytes */
124   int num_channels;             /* mono: 1 channel, stereo: 2 channels */
125
126 #if defined(TARGET_ALLEGRO)
127   int voice;
128 #endif
129 };
130 typedef struct SoundControl SoundControl;
131
132 static struct ArtworkListInfo *sound_info = NULL;
133 static struct ArtworkListInfo *music_info = NULL;
134
135 static MusicInfo **Music_NoConf = NULL;
136
137 static int num_music_noconf = 0;
138 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
139
140
141 /* ========================================================================= */
142 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS            */
143
144 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
145 static int mixer_active_channels = 0;
146
147 #if defined(AUDIO_UNIX_NATIVE)
148 static struct AudioFormatInfo afmt;
149
150 static void Mixer_Main(void);
151 #if !defined(AUDIO_STREAMING_DSP)
152 static unsigned char linear_to_ulaw(int);
153 static int ulaw_to_linear(unsigned char);
154 #endif
155 #endif
156
157 static void ReloadCustomSounds();
158 static void ReloadCustomMusic();
159 static void FreeSound(void *);
160 static void FreeMusic(void *);
161 static void FreeAllMusic_NoConf();
162
163 static SoundInfo *getSoundInfoEntryFromSoundID(int);
164 static MusicInfo *getMusicInfoEntryFromMusicID(int);
165
166
167 /* ------------------------------------------------------------------------- */
168 /* functions for native (non-SDL) Unix audio/mixer support                   */
169 /* ------------------------------------------------------------------------- */
170
171 #if defined(AUDIO_UNIX_NATIVE)
172
173 static int OpenAudioDevice(char *audio_device_name)
174 {
175   int audio_device_fd;
176
177   /* check if desired audio device is accessible */
178   if (access(audio_device_name, W_OK) != 0)
179     return -1;
180
181   /* try to open audio device in non-blocking mode */
182   if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
183     return audio_device_fd;
184
185   /* re-open audio device in blocking mode */
186   close(audio_device_fd);
187   audio_device_fd = open(audio_device_name, O_WRONLY);
188
189   return audio_device_fd;
190 }
191
192 static void CloseAudioDevice(int *audio_device_fd)
193 {
194   if (*audio_device_fd == 0)
195     return;
196
197   close(*audio_device_fd);
198   *audio_device_fd = -1;
199 }
200
201 static boolean TestAudioDevices(void)
202 {
203   static char *audio_device_name[] =
204   {
205     DEVICENAME_DSP,
206     DEVICENAME_SOUND_DSP,
207     DEVICENAME_AUDIO
208   };
209   int audio_device_fd = -1;
210   int i;
211
212   /* look for available audio devices, starting with preferred ones */
213   for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
214     if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
215       break;
216
217   if (audio_device_fd < 0)
218   {
219     Error(ERR_WARN, "cannot open audio device -- no sound");
220     return FALSE;
221   }
222
223   close(audio_device_fd);
224
225   audio.device_name = audio_device_name[i];
226
227   return TRUE;
228 }
229
230 static boolean ForkAudioProcess(void)
231 {
232   if (pipe(audio.mixer_pipe) < 0)
233   {
234     Error(ERR_WARN, "cannot create pipe -- no sounds");
235     return FALSE;
236   }
237
238   if ((audio.mixer_pid = fork()) < 0)
239   {       
240     Error(ERR_WARN, "cannot create sound server process -- no sounds");
241     return FALSE;
242   }
243
244   if (audio.mixer_pid == 0)             /* we are the child process */
245     audio.mixer_pid = getpid();
246
247   if (IS_CHILD_PROCESS())
248     Mixer_Main();                       /* this function never returns */
249   else
250     close(audio.mixer_pipe[0]);         /* no reading from pipe needed */
251
252   return TRUE;
253 }
254
255 void UnixOpenAudio(void)
256 {
257   if (!TestAudioDevices())
258     return;
259
260   audio.sound_available = TRUE;
261   audio.sound_enabled = TRUE;
262
263 #if defined(AUDIO_STREAMING_DSP)
264   audio.music_available = TRUE;
265   audio.loops_available = TRUE;
266 #endif
267
268   audio.num_channels = NUM_MIXER_CHANNELS;
269   audio.music_channel = MUSIC_CHANNEL;
270   audio.first_sound_channel = FIRST_SOUND_CHANNEL;
271 }
272
273 void UnixCloseAudio(void)
274 {
275   if (audio.device_fd)
276     close(audio.device_fd);
277
278   if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
279     kill(audio.mixer_pid, SIGTERM);
280 }
281
282
283 /* ------------------------------------------------------------------------- */
284 /* functions for platform specific audio device initialization               */
285 /* ------------------------------------------------------------------------- */
286
287 #if defined(AUDIO_LINUX_IOCTL)
288 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
289 {
290   /* "ioctl()" expects pointer to 'int' value for stereo flag
291      (boolean is defined as 'char', which will not work here) */
292   unsigned int fragment_spec = 0;
293   int fragment_size_query = -1;
294   int stereo = TRUE;
295   struct
296   {
297     int format_ioctl;
298     int format_result;
299   }
300   formats[] =
301   {
302     /* supported audio format in preferred order */
303     { AFMT_S16_LE,      AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
304     { AFMT_S16_BE,      AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
305     { AFMT_U8,          AUDIO_FORMAT_U8                    },
306     { -1,               -1 }
307   };
308   int i;
309
310   /* determine logarithm (log2) of the fragment size */
311   while ((1 << fragment_spec) < afmt->fragment_size)
312     fragment_spec++;
313
314   /* use two fragments (play one fragment, prepare the other);
315      one fragment would result in interrupted audio output, more
316      than two fragments would raise audio output latency to much */
317   fragment_spec |= 0x00020000;
318
319   /* Example for fragment specification:
320      - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
321      - (with stereo the effective buffer size will shrink to 256)
322      => fragment_size = 0x00020009 */
323
324   if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
325     Error(ERR_EXIT_SOUND_SERVER,
326           "cannot set fragment size of audio device -- no sounds");
327
328   i = 0;
329   afmt->format = 0;
330   while (formats[i].format_result != -1)
331   {
332     unsigned int audio_format = formats[i].format_ioctl;
333     if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
334     {
335       afmt->format = formats[i].format_result;
336       break;
337     }
338   }
339
340   if (afmt->format == 0)        /* no supported audio format found */
341     Error(ERR_EXIT_SOUND_SERVER,
342           "cannot set audio format of audio device -- no sounds");
343
344   /* try if we can use stereo sound */
345   afmt->stereo = TRUE;
346   if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
347     afmt->stereo = FALSE;
348
349   if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
350     Error(ERR_EXIT_SOUND_SERVER,
351           "cannot set sample rate of audio device -- no sounds");
352
353   /* get the real fragmentation size; this should return 512 */
354   if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
355     Error(ERR_EXIT_SOUND_SERVER,
356           "cannot get fragment size of audio device -- no sounds");
357   if (fragment_size_query != afmt->fragment_size)
358     Error(ERR_EXIT_SOUND_SERVER,
359           "cannot set fragment size of audio device -- no sounds");
360 }
361 #endif  /* AUDIO_LINUX_IOCTL */
362
363 #if defined(PLATFORM_NETBSD)
364 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
365 {
366   audio_info_t a_info;
367   boolean stereo = TRUE;
368
369   AUDIO_INITINFO(&a_info);
370   a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
371   a_info.play.precision = 8;
372   a_info.play.channels = 2;
373   a_info.play.sample_rate = afmt->sample_rate;
374   a_info.blocksize = afmt->fragment_size;
375
376   afmt->format = AUDIO_FORMAT_U8;
377   afmt->stereo = TRUE;
378
379   if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
380   {
381     /* try to disable stereo */
382     a_info.play.channels = 1;
383
384     afmt->stereo = FALSE;
385
386     if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
387       Error(ERR_EXIT_SOUND_SERVER,
388             "cannot set sample rate of audio device -- no sounds");
389   }
390 }
391 #endif /* PLATFORM_NETBSD */
392
393 #if defined(PLATFORM_HPUX)
394 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
395 {
396   struct audio_describe ainfo;
397   int audio_ctl;
398
399   audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
400   if (audio_ctl == -1)
401     Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
402
403   if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
404     Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
405
406   if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
407     Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
408
409   ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
410   ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
411
412   afmt->format = AUDIO_FORMAT_U8;
413   afmt->stereo = FALSE;
414   afmt->sample_rate = 8000;
415
416   close(audio_ctl);
417 }
418 #endif /* PLATFORM_HPUX */
419
420 static void InitAudioDevice(struct AudioFormatInfo *afmt)
421 {
422   afmt->stereo = TRUE;
423   afmt->format = AUDIO_FORMAT_UNKNOWN;
424   afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
425   afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
426
427 #if defined(AUDIO_LINUX_IOCTL)
428   InitAudioDevice_Linux(afmt);
429 #elif defined(PLATFORM_NETBSD)
430   InitAudioDevice_NetBSD(afmt);
431 #elif defined(PLATFORM_HPUX)
432   InitAudioDevice_HPUX(afmt);
433 #else
434   /* generic /dev/audio stuff might be placed here */
435 #endif
436 }
437
438
439 /* ------------------------------------------------------------------------- */
440 /* functions for communication between main process and sound mixer process  */
441 /* ------------------------------------------------------------------------- */
442
443 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
444 {
445   if (IS_CHILD_PROCESS())
446     return;
447
448   if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
449   {
450     Error(ERR_WARN, "cannot pipe to child process -- no sounds");
451     audio.sound_available = audio.sound_enabled = FALSE;
452     return;
453   }
454 }
455
456 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
457 {
458   if (IS_PARENT_PROCESS())
459     return;
460
461   if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
462       != sizeof(SoundControl))
463     Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
464 }
465
466 static void WriteReloadInfoToPipe(char *set_identifier, int type)
467 {
468   SoundControl snd_ctrl;
469   TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
470                   artwork.mus_current);
471   unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
472   unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
473   unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
474   unsigned long str_size4 = strlen(ti->basepath) + 1;
475   unsigned long str_size5 = strlen(ti->fullpath) + 1;
476   boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
477                                     setup.override_level_sounds :
478                                     setup.override_level_music);
479
480   if (IS_CHILD_PROCESS())
481     return;
482
483   if (leveldir_current == NULL)         /* should never happen */
484     Error(ERR_EXIT, "leveldir_current == NULL");
485
486   memset(&snd_ctrl, 0, sizeof(SoundControl));   /* to make valgrind happy */
487
488   snd_ctrl.active = FALSE;
489   snd_ctrl.state = type;
490   snd_ctrl.data_len = strlen(set_identifier) + 1;
491
492   if (write(audio.mixer_pipe[1], &snd_ctrl,
493             sizeof(snd_ctrl)) < 0 ||
494       write(audio.mixer_pipe[1], set_identifier,
495             snd_ctrl.data_len) < 0 ||
496       write(audio.mixer_pipe[1], &override_level_artwork,
497             sizeof(boolean)) < 0 ||
498       write(audio.mixer_pipe[1], leveldir_current,
499             sizeof(TreeInfo)) < 0 ||
500       write(audio.mixer_pipe[1], ti,
501             sizeof(TreeInfo)) < 0 ||
502       write(audio.mixer_pipe[1], &str_size1,
503             sizeof(unsigned long)) < 0 ||
504       write(audio.mixer_pipe[1], &str_size2,
505             sizeof(unsigned long)) < 0 ||
506       write(audio.mixer_pipe[1], &str_size3,
507             sizeof(unsigned long)) < 0 ||
508       write(audio.mixer_pipe[1], &str_size4,
509             sizeof(unsigned long)) < 0 ||
510       write(audio.mixer_pipe[1], &str_size5,
511             sizeof(unsigned long)) < 0 ||
512       write(audio.mixer_pipe[1], leveldir_current->fullpath,
513             str_size1) < 0 ||
514       write(audio.mixer_pipe[1], leveldir_current->sounds_path,
515             str_size2) < 0 ||
516       write(audio.mixer_pipe[1], leveldir_current->music_path,
517             str_size3) < 0 ||
518       write(audio.mixer_pipe[1], ti->basepath,
519             str_size4) < 0 ||
520       write(audio.mixer_pipe[1], ti->fullpath,
521             str_size5) < 0)
522   {
523     Error(ERR_WARN, "cannot pipe to child process -- no sounds");
524     audio.sound_available = audio.sound_enabled = FALSE;
525     return;
526   }
527 }
528
529 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
530 {
531   TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
532                        &artwork.snd_current : &artwork.mus_current);
533   TreeInfo *ti = *ti_ptr;
534   unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
535   static char *set_identifier = NULL;
536   boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
537                                      &setup.override_level_sounds :
538                                      &setup.override_level_music);
539
540   checked_free(set_identifier);
541
542   set_identifier = checked_malloc(snd_ctrl->data_len);
543
544   if (leveldir_current == NULL)
545     leveldir_current = checked_calloc(sizeof(TreeInfo));
546
547   if (ti == NULL)
548     ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
549
550   checked_free(leveldir_current->fullpath);
551   checked_free(leveldir_current->sounds_path);
552   checked_free(leveldir_current->music_path);
553   checked_free(ti->basepath);
554   checked_free(ti->fullpath);
555
556   if (read(audio.mixer_pipe[0], set_identifier,
557            snd_ctrl->data_len) != snd_ctrl->data_len ||
558       read(audio.mixer_pipe[0], override_level_artwork,
559            sizeof(boolean)) != sizeof(boolean) ||
560       read(audio.mixer_pipe[0], leveldir_current,
561            sizeof(TreeInfo)) != sizeof(TreeInfo) ||
562       read(audio.mixer_pipe[0], ti,
563            sizeof(TreeInfo)) != sizeof(TreeInfo) ||
564       read(audio.mixer_pipe[0], &str_size1,
565            sizeof(unsigned long)) != sizeof(unsigned long) ||
566       read(audio.mixer_pipe[0], &str_size2,
567            sizeof(unsigned long)) != sizeof(unsigned long) ||
568       read(audio.mixer_pipe[0], &str_size3,
569            sizeof(unsigned long)) != sizeof(unsigned long) ||
570       read(audio.mixer_pipe[0], &str_size4,
571            sizeof(unsigned long)) != sizeof(unsigned long) ||
572       read(audio.mixer_pipe[0], &str_size5,
573            sizeof(unsigned long)) != sizeof(unsigned long))
574     Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
575
576   leveldir_current->fullpath = checked_calloc(str_size1);
577   leveldir_current->sounds_path = checked_calloc(str_size2);
578   leveldir_current->music_path = checked_calloc(str_size3);
579   ti->basepath = checked_calloc(str_size4);
580   ti->fullpath = checked_calloc(str_size5);
581
582   if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
583            str_size1) != str_size1 ||
584       read(audio.mixer_pipe[0], leveldir_current->sounds_path,
585            str_size2) != str_size2 ||
586       read(audio.mixer_pipe[0], leveldir_current->music_path,
587            str_size3) != str_size3 ||
588       read(audio.mixer_pipe[0], ti->basepath,
589            str_size4) != str_size4 ||
590       read(audio.mixer_pipe[0], ti->fullpath,
591            str_size5) != str_size5)
592     Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
593
594   if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
595     artwork.snd_current_identifier = set_identifier;
596   else
597     artwork.mus_current_identifier = set_identifier;
598 }
599
600 #endif /* AUDIO_UNIX_NATIVE */
601
602
603 /* ------------------------------------------------------------------------- */
604 /* mixer functions                                                           */
605 /* ------------------------------------------------------------------------- */
606
607 void Mixer_InitChannels()
608 {
609   int i;
610
611   for (i = 0; i < audio.num_channels; i++)
612     mixer[i].active = FALSE;
613   mixer_active_channels = 0;
614 }
615
616 static void Mixer_ResetChannelExpiration(int channel)
617 {
618   mixer[channel].playing_starttime = Counter();
619
620 #if defined(TARGET_SDL)
621   if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
622     Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
623 #endif
624 }
625
626 static boolean Mixer_ChannelExpired(int channel)
627 {
628   if (!mixer[channel].active)
629     return TRUE;
630
631   if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
632       DelayReached(&mixer[channel].playing_starttime,
633                    SOUND_LOOP_EXPIRATION_TIME))
634     return TRUE;
635
636 #if defined(TARGET_SDL)
637
638   if (!Mix_Playing(channel))
639     return TRUE;
640
641 #elif defined(TARGET_ALLEGRO)
642
643   mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
644   mixer[channel].volume = voice_get_volume(mixer[channel].voice);
645
646   /* sound sample has completed playing or was completely faded out */
647   if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
648     return TRUE;
649
650 #endif /* TARGET_ALLEGRO */
651
652   return FALSE;
653 }
654
655 static boolean Mixer_AllocateChannel(int channel)
656 {
657 #if defined(TARGET_ALLEGRO)
658   mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
659   if (mixer[channel].voice < 0)
660     return FALSE;
661 #endif
662
663   return TRUE;
664 }
665
666 static void Mixer_SetChannelProperties(int channel)
667 {
668 #if defined(TARGET_SDL)
669   Mix_Volume(channel, mixer[channel].volume);
670   Mix_SetPanning(channel,
671                  SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
672                  SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
673 #elif defined(TARGET_ALLEGRO)
674   voice_set_volume(mixer[channel].voice, mixer[channel].volume);
675   voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
676 #endif
677 }
678
679 static void Mixer_StartChannel(int channel)
680 {
681 #if defined(TARGET_SDL)
682   Mix_PlayChannel(channel, mixer[channel].data_ptr,
683                   IS_LOOP(mixer[channel]) ? -1 : 0);
684 #elif defined(TARGET_ALLEGRO)
685   if (IS_LOOP(mixer[channel]))
686     voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
687
688   voice_start(mixer[channel].voice);       
689 #endif
690 }
691
692 static void Mixer_PlayChannel(int channel)
693 {
694   /* start with inactive channel in case something goes wrong */
695   mixer[channel].active = FALSE;
696
697   if (mixer[channel].type != MUS_TYPE_WAV)
698     return;
699
700   if (!Mixer_AllocateChannel(channel))
701     return;
702
703   Mixer_SetChannelProperties(channel);
704   Mixer_StartChannel(channel);
705
706   Mixer_ResetChannelExpiration(channel);
707
708   mixer[channel].playing_pos = 0;
709   mixer[channel].active = TRUE;
710   mixer_active_channels++;
711 }
712
713 static void Mixer_PlayMusicChannel()
714 {
715   Mixer_PlayChannel(audio.music_channel);
716
717 #if defined(TARGET_SDL)
718   if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
719   {
720     /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
721        this looks like a bug in the SDL_mixer library */
722     Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
723     Mix_VolumeMusic(SOUND_MAX_VOLUME);
724   }
725 #endif
726 }
727
728 static void Mixer_StopChannel(int channel)
729 {
730   if (!mixer[channel].active)
731     return;
732
733 #if defined(TARGET_SDL)
734   Mix_HaltChannel(channel);
735 #elif defined(TARGET_ALLEGRO)
736   voice_set_volume(mixer[channel].voice, 0);
737   deallocate_voice(mixer[channel].voice);
738 #endif
739
740   mixer[channel].active = FALSE;
741   mixer_active_channels--;
742 }
743
744 static void Mixer_StopMusicChannel()
745 {
746   Mixer_StopChannel(audio.music_channel);
747
748 #if defined(TARGET_SDL)
749   Mix_HaltMusic();
750 #endif
751 }
752
753 static void Mixer_FadeChannel(int channel)
754 {
755   if (!mixer[channel].active)
756     return;
757
758   mixer[channel].state |= SND_CTRL_FADE;
759
760 #if defined(TARGET_SDL)
761   Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
762 #elif defined(TARGET_ALLEGRO)
763   if (voice_check(mixer[channel].voice))
764     voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
765 #endif
766 }
767
768 static void Mixer_FadeMusicChannel()
769 {
770   Mixer_FadeChannel(audio.music_channel);
771
772 #if defined(TARGET_SDL)
773   Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
774 #endif
775 }
776
777 static void Mixer_UnFadeChannel(int channel)
778 {
779   if (!mixer[channel].active || !IS_FADING(mixer[channel]))
780     return;
781
782   mixer[channel].state &= ~SND_CTRL_FADE;
783   mixer[channel].volume = SOUND_MAX_VOLUME;
784
785 #if defined(TARGET_SDL)
786   Mix_ExpireChannel(channel, -1);
787   Mix_Volume(channel, mixer[channel].volume);
788 #elif defined(TARGET_ALLEGRO)
789   voice_stop_volumeramp(mixer[channel].voice);
790   voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
791                     mixer[channel].volume);
792 #endif
793 }
794
795 static void Mixer_InsertSound(SoundControl snd_ctrl)
796 {
797   SoundInfo *snd_info;
798   int i, k;
799   int num_sounds = getSoundListSize();
800   int num_music  = getMusicListSize();
801
802   if (IS_MUSIC(snd_ctrl))
803   {
804     if (snd_ctrl.nr >= num_music)       /* invalid music */
805       return;
806
807     if (snd_ctrl.nr < 0)                /* undefined music */
808     {
809       if (num_music_noconf == 0)        /* no fallback music available */
810         return;
811
812       snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
813       snd_info = Music_NoConf[snd_ctrl.nr];
814     }
815     else
816       snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
817   }
818   else
819   {
820     if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
821       return;
822
823     snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
824   }
825
826   if (snd_info == NULL)
827     return;
828
829   /* copy sound sample and format information */
830   snd_ctrl.type         = snd_info->type;
831   snd_ctrl.format       = snd_info->format;
832   snd_ctrl.data_ptr     = snd_info->data_ptr;
833   snd_ctrl.data_len     = snd_info->data_len;
834   snd_ctrl.num_channels = snd_info->num_channels;
835
836   /* play music samples on a dedicated music channel */
837   if (IS_MUSIC(snd_ctrl))
838   {
839     Mixer_StopMusicChannel();
840
841     mixer[audio.music_channel] = snd_ctrl;
842     Mixer_PlayMusicChannel();
843
844     return;
845   }
846
847   /* check if (and how often) this sound sample is already playing */
848   for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
849     if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
850       k++;
851
852   /* reset expiration delay for already playing loop sounds */
853   if (k > 0 && IS_LOOP(snd_ctrl))
854   {
855     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
856     {
857       if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
858       {
859         if (IS_FADING(mixer[i]))
860           Mixer_UnFadeChannel(i);
861
862         /* restore settings like volume and stereo position */
863         mixer[i].volume = snd_ctrl.volume;
864         mixer[i].stereo_position = snd_ctrl.stereo_position;
865
866         Mixer_SetChannelProperties(i);
867         Mixer_ResetChannelExpiration(i);
868       }
869     }
870
871     return;
872   }
873
874   /* don't play sound more than n times simultaneously (with n == 2 for now) */
875   if (k >= 2)
876   {
877     unsigned long playing_current = Counter();
878     int longest = 0, longest_nr = audio.first_sound_channel;
879
880     /* look for oldest equal sound */
881     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
882     {
883       int playing_time = playing_current - mixer[i].playing_starttime;
884       int actual;
885
886       if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
887         continue;
888
889       actual = 1000 * playing_time / mixer[i].data_len;
890
891       if (actual >= longest)
892       {
893         longest = actual;
894         longest_nr = i;
895       }
896     }
897
898     Mixer_StopChannel(longest_nr);
899   }
900
901   /* If all (non-music) channels are active, stop the channel that has
902      played its sound sample most completely (in percent of the sample
903      length). As we cannot currently get the actual playing position
904      of the channel's sound sample when compiling with the SDL mixer
905      library, we use the current playing time (in milliseconds) instead. */
906
907 #if DEBUG
908   /* channel allocation sanity check -- should not be needed */
909   if (mixer_active_channels ==
910       audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
911   {
912     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
913     {
914       if (!mixer[i].active)
915       {
916         Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
917         Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
918
919         mixer_active_channels--;
920       }
921     }
922   }
923 #endif
924
925   if (mixer_active_channels ==
926       audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
927   {
928     unsigned long playing_current = Counter();
929     int longest = 0, longest_nr = audio.first_sound_channel;
930
931 #if 0
932 #if DEBUG
933     /* print some debugging information about audio channel usage */
934     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
935     {
936       Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
937             i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
938     }
939 #endif
940 #endif
941
942     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
943     {
944       int playing_time = playing_current - mixer[i].playing_starttime;
945       int actual = 1000 * playing_time / mixer[i].data_len;
946
947       if (!IS_LOOP(mixer[i]) && actual > longest)
948       {
949         longest = actual;
950         longest_nr = i;
951       }
952     }
953
954     Mixer_StopChannel(longest_nr);
955   }
956
957   /* add the new sound to the mixer */
958   for (i = audio.first_sound_channel; i < audio.num_channels; i++)
959   {
960     if (!mixer[i].active)
961     {
962 #if defined(AUDIO_UNIX_NATIVE)
963       if (snd_info->data_len == 0)
964       {
965         printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
966       }
967 #endif
968
969       mixer[i] = snd_ctrl;
970       Mixer_PlayChannel(i);
971
972       break;
973     }
974   }
975 }
976
977 static void HandleSoundRequest(SoundControl snd_ctrl)
978 {
979   int i;
980
981 #if defined(AUDIO_UNIX_NATIVE)
982   if (IS_PARENT_PROCESS())
983   {
984     SendSoundControlToMixerProcess(&snd_ctrl);
985     return;
986   }
987 #endif
988
989   /* deactivate channels that have expired since the last request */
990   for (i = 0; i < audio.num_channels; i++)
991     if (mixer[i].active && Mixer_ChannelExpired(i))
992       Mixer_StopChannel(i);
993
994   if (IS_RELOADING(snd_ctrl))           /* load new sound or music files */
995   {
996     Mixer_StopMusicChannel();
997     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
998       Mixer_StopChannel(i);
999
1000 #if defined(AUDIO_UNIX_NATIVE)
1001     CloseAudioDevice(&audio.device_fd);
1002     ReadReloadInfoFromPipe(&snd_ctrl);
1003 #endif
1004
1005     if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1006       ReloadCustomSounds();
1007     else
1008       ReloadCustomMusic();
1009   }
1010   else if (IS_FADING(snd_ctrl))         /* fade out existing sound or music */
1011   {
1012     if (IS_MUSIC(snd_ctrl))
1013     {
1014       Mixer_FadeMusicChannel();
1015       return;
1016     }
1017
1018     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1019       if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1020         Mixer_FadeChannel(i);
1021   }
1022   else if (IS_STOPPING(snd_ctrl))       /* stop existing sound or music */
1023   {
1024     if (IS_MUSIC(snd_ctrl))
1025     {
1026       Mixer_StopMusicChannel();
1027       return;
1028     }
1029
1030     for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1031       if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1032         Mixer_StopChannel(i);
1033
1034 #if defined(AUDIO_UNIX_NATIVE)
1035     if (!mixer_active_channels)
1036       CloseAudioDevice(&audio.device_fd);
1037 #endif
1038   }
1039   else if (snd_ctrl.active)             /* add new sound to mixer */
1040   {
1041     Mixer_InsertSound(snd_ctrl);
1042   }
1043 }
1044
1045 void StartMixer(void)
1046 {
1047   int i;
1048
1049 #if 0
1050   SDL_version compile_version;
1051   const SDL_version *link_version;
1052   MIX_VERSION(&compile_version);
1053   printf("compiled with SDL_mixer version: %d.%d.%d\n", 
1054          compile_version.major,
1055          compile_version.minor,
1056          compile_version.patch);
1057   link_version = Mix_Linked_Version();
1058   printf("running with SDL_mixer version: %d.%d.%d\n", 
1059          link_version->major,
1060          link_version->minor,
1061          link_version->patch);
1062 #endif
1063
1064   if (!audio.sound_available)
1065     return;
1066
1067   /* initialize stereo position conversion information */
1068   for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1069     stereo_volume[i] =
1070       (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1071
1072 #if defined(AUDIO_UNIX_NATIVE)
1073   if (!ForkAudioProcess())
1074     audio.sound_available = FALSE;
1075 #endif
1076 }
1077
1078 #if defined(AUDIO_UNIX_NATIVE)
1079
1080 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1081                                      int sample_pos, int sample_size,
1082                                      short *buffer_base_ptr, int buffer_pos,
1083                                      int num_output_channels)
1084 {
1085   short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1086   int num_channels = snd_ctrl->num_channels;
1087   int stepsize = num_channels;
1088   int output_stepsize = num_output_channels;
1089   int i, j;
1090
1091   if (snd_ctrl->format == AUDIO_FORMAT_U8)
1092   {
1093     byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1094
1095     for (i = 0; i < num_output_channels; i++)
1096     {
1097       int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1098
1099       for (j = 0; j < sample_size; j++)
1100         buffer_ptr[output_stepsize * j + i] =
1101           ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1102     }
1103   }
1104   else  /* AUDIO_FORMAT_S16 */
1105   {
1106     short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1107
1108     for (i = 0; i < num_output_channels; i++)
1109     {
1110       int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1111
1112       for (j = 0; j < sample_size; j++)
1113         buffer_ptr[output_stepsize * j + i] =
1114           sample_ptr[stepsize * j + offset];
1115     }
1116   }
1117 }
1118
1119 #if defined(AUDIO_STREAMING_DSP)
1120 static void Mixer_Main_DSP()
1121 {
1122   static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1123   static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1124   static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1125   boolean stereo;
1126   int fragment_size;
1127   int sample_bytes;
1128   int max_sample_size;
1129   int num_output_channels;
1130   int i, j;
1131
1132   if (!mixer_active_channels)
1133     return;
1134
1135   if (audio.device_fd < 0)
1136   {
1137     if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1138       return;
1139
1140     InitAudioDevice(&afmt);
1141   }
1142
1143   stereo = afmt.stereo;
1144   fragment_size = afmt.fragment_size;
1145   sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1146   num_output_channels = (stereo ? 2 : 1);
1147   max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1148
1149   /* first clear the last premixing buffer */
1150   memset(premix_last_buffer, 0,
1151          max_sample_size * num_output_channels * sizeof(long));
1152
1153   for (i = 0; i < audio.num_channels; i++)
1154   {
1155     void *sample_ptr;
1156     int sample_len;
1157     int sample_pos;
1158     int sample_size;
1159
1160     if (!mixer[i].active)
1161       continue;
1162
1163     if (Mixer_ChannelExpired(i))
1164     {
1165       Mixer_StopChannel(i);
1166       continue;
1167     }
1168
1169     /* pointer, lenght and actual playing position of sound sample */
1170     sample_ptr = mixer[i].data_ptr;
1171     sample_len = mixer[i].data_len;
1172     sample_pos = mixer[i].playing_pos;
1173     sample_size = MIN(max_sample_size, sample_len - sample_pos);
1174     mixer[i].playing_pos += sample_size;
1175
1176     /* copy original sample to first mixing buffer */
1177     CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1178                              premix_first_buffer, 0, num_output_channels);
1179
1180     /* are we about to restart a looping sound? */
1181     if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1182     {
1183       while (sample_size < max_sample_size)
1184       {
1185         int restarted_sample_size =
1186           MIN(max_sample_size - sample_size, sample_len);
1187
1188         CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1189                                  premix_first_buffer, sample_size,
1190                                  num_output_channels);
1191
1192         mixer[i].playing_pos = restarted_sample_size;
1193         sample_size += restarted_sample_size;
1194       }
1195     }
1196
1197     /* decrease volume if sound is fading out */
1198     if (IS_FADING(mixer[i]) &&
1199         mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1200       mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1201
1202     /* adjust volume of actual sound sample */
1203     if (mixer[i].volume != SOUND_MAX_VOLUME)
1204       for (j = 0; j < sample_size * num_output_channels; j++)
1205         premix_first_buffer[j] =
1206           mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1207
1208     /* adjust left and right channel volume due to stereo sound position */
1209     if (stereo)
1210     {
1211       int left_volume  = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1212       int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1213
1214       for (j = 0; j < sample_size; j++)
1215       {
1216         premix_first_buffer[2 * j + 0] =
1217           left_volume  * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1218         premix_first_buffer[2 * j + 1] =
1219           right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1220       }
1221     }
1222
1223     /* fill the last mixing buffer with stereo or mono sound */
1224     for (j = 0; j < sample_size * num_output_channels; j++)
1225       premix_last_buffer[j] += premix_first_buffer[j];
1226
1227     /* delete completed sound entries from the mixer */
1228     if (mixer[i].playing_pos >= mixer[i].data_len)
1229     {
1230       if (IS_LOOP(mixer[i]))
1231         mixer[i].playing_pos = 0;
1232       else
1233         Mixer_StopChannel(i);
1234     }
1235     else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1236       Mixer_StopChannel(i);
1237   }
1238
1239   /* prepare final playing buffer according to system audio format */
1240   for (i = 0; i < max_sample_size * num_output_channels; i++)
1241   {
1242     /* cut off at 17 bit value */
1243     if (premix_last_buffer[i] < -65535)
1244       premix_last_buffer[i] = -65535;
1245     else if (premix_last_buffer[i] > 65535)
1246       premix_last_buffer[i] = 65535;
1247
1248     /* shift to 16 bit value */
1249     premix_last_buffer[i] >>= 1;
1250
1251     if (afmt.format & AUDIO_FORMAT_U8)
1252     {
1253       playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1254     }
1255     else if (afmt.format & AUDIO_FORMAT_LE)     /* 16 bit */
1256     {
1257       playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1258       playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1259     }
1260     else                                        /* big endian */
1261     {
1262       playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1263       playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1264     }
1265   }
1266
1267   /* finally play the sound fragment */
1268   write(audio.device_fd, playing_buffer, fragment_size);
1269
1270   if (!mixer_active_channels)
1271     CloseAudioDevice(&audio.device_fd);
1272 }
1273
1274 #else /* !AUDIO_STREAMING_DSP */
1275
1276 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1277 {
1278   static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1279   static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1280   int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1281   int num_output_channels = 1;
1282   void *sample_ptr;
1283   int sample_len;
1284   int sample_pos;
1285   int sample_size;
1286   int i, j;
1287
1288   i = 1;
1289
1290   /* pointer, lenght and actual playing position of sound sample */
1291   sample_ptr = mixer[i].data_ptr;
1292   sample_len = mixer[i].data_len;
1293   sample_pos = mixer[i].playing_pos;
1294   sample_size = MIN(max_sample_size, sample_len - sample_pos);
1295   mixer[i].playing_pos += sample_size;
1296
1297   /* copy original sample to first mixing buffer */
1298   CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1299                            premix_first_buffer, 0, num_output_channels);
1300
1301   /* adjust volume of actual sound sample */
1302   if (mixer[i].volume != SOUND_MAX_VOLUME)
1303     for (j = 0; j < sample_size; j++)
1304       premix_first_buffer[j] =
1305         mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1306
1307   /* might be needed for u-law /dev/audio */
1308   for (j = 0; j < sample_size; j++)
1309     playing_buffer[j] =
1310       linear_to_ulaw(premix_first_buffer[j]);
1311
1312   /* delete completed sound entries from the mixer */
1313   if (mixer[i].playing_pos >= mixer[i].data_len)
1314     Mixer_StopChannel(i);
1315
1316   for (i = 0; i < sample_size; i++)
1317     playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1318
1319   /* finally play the sound fragment */
1320   write(audio.device_fd, playing_buffer, sample_size);
1321
1322   return sample_size;
1323 }
1324 #endif /* !AUDIO_STREAMING_DSP */
1325
1326 void Mixer_Main()
1327 {
1328   SoundControl snd_ctrl;
1329   fd_set mixer_fdset;
1330
1331   close(audio.mixer_pipe[1]);   /* no writing into pipe needed */
1332
1333   Mixer_InitChannels();
1334
1335 #if defined(PLATFORM_HPUX)
1336   InitAudioDevice(&afmt);
1337 #endif
1338
1339   FD_ZERO(&mixer_fdset); 
1340   FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1341
1342   while (1)     /* wait for sound playing commands from client */
1343   {
1344     struct timeval delay = { 0, 0 };
1345
1346     FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1347     select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1348     if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1349       continue;
1350
1351     ReadSoundControlFromMainProcess(&snd_ctrl);
1352
1353     HandleSoundRequest(snd_ctrl);
1354
1355 #if defined(AUDIO_STREAMING_DSP)
1356
1357     while (mixer_active_channels &&
1358            select(audio.mixer_pipe[0] + 1,
1359                   &mixer_fdset, NULL, NULL, &delay) < 1)
1360     {
1361       FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1362
1363       Mixer_Main_DSP();
1364     }
1365
1366 #else /* !AUDIO_STREAMING_DSP */
1367
1368     if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1369         (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1370       continue;
1371
1372     InitAudioDevice(&afmt);
1373
1374     delay.tv_sec = 0;
1375     delay.tv_usec = 0;
1376
1377     while (mixer_active_channels &&
1378            select(audio.mixer_pipe[0] + 1,
1379                   &mixer_fdset, NULL, NULL, &delay) < 1)
1380     {
1381       int wait_percent = 90;    /* wait 90% of the real playing time */
1382       int sample_size;
1383
1384       FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1385
1386       sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1387
1388       delay.tv_sec = 0;
1389       delay.tv_usec =
1390         ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1391     }
1392
1393     CloseAudioDevice(&audio.device_fd);
1394
1395     Mixer_InitChannels();       /* remove all sounds from mixer */
1396
1397 #endif /* !AUDIO_STREAMING_DSP */
1398   }
1399 }
1400 #endif /* AUDIO_UNIX_NATIVE */
1401
1402
1403 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1404
1405 /* these two are stolen from "sox"... :) */
1406
1407 /*
1408 ** This routine converts from linear to ulaw.
1409 **
1410 ** Craig Reese: IDA/Supercomputing Research Center
1411 ** Joe Campbell: Department of Defense
1412 ** 29 September 1989
1413 **
1414 ** References:
1415 ** 1) CCITT Recommendation G.711  (very difficult to follow)
1416 ** 2) "A New Digital Technique for Implementation of Any
1417 **     Continuous PCM Companding Law," Villeret, Michel,
1418 **     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1419 **     1973, pg. 11.12-11.17
1420 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1421 **     for Analog-to_Digital Conversion Techniques,"
1422 **     17 February 1987
1423 **
1424 ** Input: Signed 16 bit linear sample
1425 ** Output: 8 bit ulaw sample
1426 */
1427
1428 #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
1429 #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
1430 #define CLIP 32635
1431
1432 static unsigned char linear_to_ulaw(int sample)
1433 {
1434   static int exp_lut[256] =
1435   {
1436     0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1437     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1438     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1439     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1440     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1441     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1442     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1443     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1444     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1445     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1446     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1447     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1448     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1449     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1450     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1451     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1452   };
1453
1454   int sign, exponent, mantissa;
1455   unsigned char ulawbyte;
1456
1457   /* Get the sample into sign-magnitude. */
1458   sign = (sample >> 8) & 0x80;          /* set aside the sign */
1459   if (sign != 0)
1460     sample = -sample;                   /* get magnitude */
1461   if (sample > CLIP)
1462     sample = CLIP;                      /* clip the magnitude */
1463
1464   /* Convert from 16 bit linear to ulaw. */
1465   sample = sample + BIAS;
1466   exponent = exp_lut[( sample >> 7 ) & 0xFF];
1467   mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1468   ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1469 #ifdef ZEROTRAP
1470   if (ulawbyte == 0)
1471     ulawbyte = 0x02;                    /* optional CCITT trap */
1472 #endif
1473
1474   return(ulawbyte);
1475 }
1476
1477 /*
1478 ** This routine converts from ulaw to 16 bit linear.
1479 **
1480 ** Craig Reese: IDA/Supercomputing Research Center
1481 ** 29 September 1989
1482 **
1483 ** References:
1484 ** 1) CCITT Recommendation G.711  (very difficult to follow)
1485 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1486 **     for Analog-to_Digital Conversion Techniques,"
1487 **     17 February 1987
1488 **
1489 ** Input: 8 bit ulaw sample
1490 ** Output: signed 16 bit linear sample
1491 */
1492
1493 static int ulaw_to_linear(unsigned char ulawbyte)
1494 {
1495   static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1496   int sign, exponent, mantissa, sample;
1497
1498   ulawbyte = ~ ulawbyte;
1499   sign = ( ulawbyte & 0x80 );
1500   exponent = ( ulawbyte >> 4 ) & 0x07;
1501   mantissa = ulawbyte & 0x0F;
1502   sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1503   if (sign != 0)
1504     sample = -sample;
1505
1506   return(sample);
1507 }
1508 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1509
1510
1511 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS            */
1512 /* ========================================================================= */
1513 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS                          */
1514
1515 #define CHUNK_ID_LEN            4       /* IFF style chunk id length */
1516 #define WAV_HEADER_SIZE         16      /* size of WAV file header */
1517
1518 static void *Load_WAV(char *filename)
1519 {
1520   SoundInfo *snd_info;
1521 #if defined(AUDIO_UNIX_NATIVE)
1522   struct SoundHeader_WAV header;
1523 #if 0
1524   byte sound_header_buffer[WAV_HEADER_SIZE];
1525   int i;
1526 #endif
1527   char chunk_name[CHUNK_ID_LEN + 1];
1528   int chunk_size;
1529   int data_byte_len;
1530   FILE *file;
1531 #endif
1532
1533   if (!audio.sound_available)
1534     return NULL;
1535
1536   snd_info = checked_calloc(sizeof(SoundInfo));
1537
1538 #if defined(TARGET_SDL)
1539
1540   if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1541   {
1542     Error(ERR_WARN, "cannot read sound file '%s'", filename);
1543     free(snd_info);
1544     return NULL;
1545   }
1546
1547   snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1548
1549 #elif defined(TARGET_ALLEGRO)
1550
1551   if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1552   {
1553     Error(ERR_WARN, "cannot read sound file '%s'", filename);
1554     free(snd_info);
1555     return NULL;
1556   }
1557
1558   snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1559
1560 #else /* AUDIO_UNIX_NATIVE */
1561
1562   if ((file = fopen(filename, MODE_READ)) == NULL)
1563   {
1564     Error(ERR_WARN, "cannot open sound file '%s'", filename);
1565     free(snd_info);
1566     return NULL;
1567   }
1568
1569   /* read chunk id "RIFF" */
1570   getFileChunkLE(file, chunk_name, &chunk_size);
1571   if (!strEqual(chunk_name, "RIFF"))
1572   {
1573     Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1574     fclose(file);
1575     free(snd_info);
1576     return NULL;
1577   }
1578
1579   /* read "RIFF" type id "WAVE" */
1580   getFileChunkLE(file, chunk_name, NULL);
1581   if (!strEqual(chunk_name, "WAVE"))
1582   {
1583     Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1584     fclose(file);
1585     free(snd_info);
1586     return NULL;
1587   }
1588
1589   while (getFileChunkLE(file, chunk_name, &chunk_size))
1590   {
1591     if (strEqual(chunk_name, "fmt "))
1592     {
1593       if (chunk_size < WAV_HEADER_SIZE)
1594       {
1595         Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1596         fclose(file);
1597         free(snd_info);
1598         return NULL;
1599       }
1600
1601       header.compression_code = getFile16BitLE(file);
1602       header.num_channels = getFile16BitLE(file);
1603       header.sample_rate = getFile32BitLE(file);
1604       header.bytes_per_second = getFile32BitLE(file);
1605       header.block_align = getFile16BitLE(file);
1606       header.bits_per_sample = getFile16BitLE(file);
1607
1608       if (chunk_size > WAV_HEADER_SIZE)
1609         ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1610
1611       if (header.compression_code != 1)
1612       {
1613         Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1614               filename, header.compression_code);
1615         fclose(file);
1616         free(snd_info);
1617         return NULL;
1618       }
1619
1620       if (header.num_channels != 1 &&
1621           header.num_channels != 2)
1622       {
1623         Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1624               filename, header.num_channels);
1625         fclose(file);
1626         free(snd_info);
1627         return NULL;
1628       }
1629
1630       if (header.bits_per_sample != 8 &&
1631           header.bits_per_sample != 16)
1632       {
1633         Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1634               filename, header.bits_per_sample);
1635         fclose(file);
1636         free(snd_info);
1637         return NULL;
1638       }
1639
1640       /* warn, but accept wrong sample rate (may be only slightly different) */
1641       if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1642         Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1643               filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1644
1645 #if 0
1646       printf("WAV file: '%s'\n", filename);
1647       printf("  Compression code: %d'\n", header.compression_code);
1648       printf("  Number of channels: %d'\n", header.num_channels);
1649       printf("  Sample rate: %ld'\n", header.sample_rate);
1650       printf("  Average bytes per second: %ld'\n", header.bytes_per_second);
1651       printf("  Block align: %d'\n", header.block_align);
1652       printf("  Significant bits per sample: %d'\n", header.bits_per_sample);
1653 #endif
1654     }
1655     else if (strEqual(chunk_name, "data"))
1656     {
1657       data_byte_len = chunk_size;
1658
1659       snd_info->data_len = data_byte_len;
1660       snd_info->data_ptr = checked_malloc(snd_info->data_len);
1661
1662       /* read sound data */
1663       if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1664           snd_info->data_len)
1665       {
1666         Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1667         fclose(file);
1668         free(snd_info->data_ptr);
1669         free(snd_info);
1670         return NULL;
1671       }
1672
1673       /* check for odd number of data bytes (data chunk is word aligned) */
1674       if ((data_byte_len % 2) == 1)
1675         ReadUnusedBytesFromFile(file, 1);
1676     }
1677     else        /* unknown chunk -- ignore */
1678       ReadUnusedBytesFromFile(file, chunk_size);
1679   }
1680
1681   fclose(file);
1682
1683   if (snd_info->data_ptr == NULL)
1684   {
1685     Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1686     free(snd_info);
1687     return NULL;
1688   }
1689
1690   if (header.bits_per_sample == 8)
1691     snd_info->format = AUDIO_FORMAT_U8;
1692   else                                  /* header.bits_per_sample == 16 */
1693   {
1694     snd_info->format = AUDIO_FORMAT_S16;
1695     snd_info->data_len /= 2;            /* correct number of samples */
1696   }
1697
1698   snd_info->num_channels = header.num_channels;
1699   if (header.num_channels == 2)
1700     snd_info->data_len /= 2;            /* correct number of samples */
1701
1702 #if 0
1703   if (header.num_channels == 1)         /* convert mono sound to stereo */
1704   {
1705     void *buffer_ptr = checked_malloc(data_byte_len * 2);
1706     void *sample_ptr = snd_info->data_ptr;
1707     int sample_size = snd_info->data_len;
1708     int i;
1709
1710     if (snd_ctrl->format == AUDIO_FORMAT_U8)
1711       for (i = 0; i < sample_size; i++)
1712         *buffer_ptr++ =
1713           ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1714     else        /* AUDIO_FORMAT_S16 */
1715       for (i = 0; i < sample_size; i++)
1716         *buffer_ptr++ =
1717           ((short *)sample_ptr)[i];
1718   }
1719 #endif
1720
1721 #endif  /* AUDIO_UNIX_NATIVE */
1722
1723   snd_info->type = SND_TYPE_WAV;
1724   snd_info->source_filename = getStringCopy(filename);
1725
1726   return snd_info;
1727 }
1728
1729 static void *Load_MOD(char *filename)
1730 {
1731 #if defined(TARGET_SDL)
1732   MusicInfo *mod_info;
1733
1734   if (!audio.sound_available)
1735     return NULL;
1736
1737   mod_info = checked_calloc(sizeof(MusicInfo));
1738
1739   if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1740   {
1741     Error(ERR_WARN, "cannot read music file '%s'", filename);
1742     free(mod_info);
1743     return NULL;
1744   }
1745
1746   mod_info->type = MUS_TYPE_MOD;
1747   mod_info->source_filename = getStringCopy(filename);
1748
1749   return mod_info;
1750 #else
1751   return NULL;
1752 #endif
1753 }
1754
1755 static void *Load_WAV_or_MOD(char *filename)
1756 {
1757   if (FileIsSound(filename))
1758     return Load_WAV(filename);
1759   else if (FileIsMusic(filename))
1760     return Load_MOD(filename);
1761   else
1762     return NULL;
1763 }
1764
1765 void LoadCustomMusic_NoConf(void)
1766 {
1767   static boolean draw_init_text = TRUE;         /* only draw at startup */
1768   static char *last_music_directory = NULL;
1769   char *music_directory = getCustomMusicDirectory();
1770   DIR *dir;
1771   struct dirent *dir_entry;
1772   int num_music = getMusicListSize();
1773
1774   if (!audio.sound_available)
1775     return;
1776
1777   if (last_music_directory != NULL &&
1778       strEqual(last_music_directory, music_directory))
1779     return;     /* old and new music directory are the same */
1780
1781   if (last_music_directory != NULL)
1782     free(last_music_directory);
1783   last_music_directory = getStringCopy(music_directory);
1784
1785   FreeAllMusic_NoConf();
1786
1787   if ((dir = opendir(music_directory)) == NULL)
1788   {
1789     Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1790     audio.music_available = FALSE;
1791     return;
1792   }
1793
1794   if (draw_init_text)
1795     DrawInitText("Loading music:", 120, FC_GREEN);
1796
1797   while ((dir_entry = readdir(dir)) != NULL)    /* loop until last dir entry */
1798   {
1799     char *basename = dir_entry->d_name;
1800     char *filename = NULL;
1801     MusicInfo *mus_info = NULL;
1802     boolean music_already_used = FALSE;
1803     int i;
1804
1805     /* skip all music files that are configured in music config file */
1806     for (i = 0; i < num_music; i++)
1807     {
1808       struct FileInfo *music = getMusicListEntry(i);
1809
1810       if (strEqual(basename, music->filename))
1811       {
1812         music_already_used = TRUE;
1813         break;
1814       }
1815     }
1816
1817     if (music_already_used)
1818       continue;
1819
1820     if (draw_init_text)
1821       DrawInitText(basename, 150, FC_YELLOW);
1822
1823     filename = getPath2(music_directory, basename);
1824
1825     if (FileIsMusic(basename))
1826       mus_info = Load_WAV_or_MOD(filename);
1827
1828     free(filename);
1829
1830     if (mus_info)
1831     {
1832       num_music_noconf++;
1833       Music_NoConf = checked_realloc(Music_NoConf,
1834                                      num_music_noconf * sizeof(MusicInfo *));
1835       Music_NoConf[num_music_noconf - 1] = mus_info;
1836     }
1837   }
1838
1839   closedir(dir);
1840
1841   draw_init_text = FALSE;
1842 }
1843
1844 int getSoundListSize()
1845 {
1846   return (sound_info->num_file_list_entries +
1847           sound_info->num_dynamic_file_list_entries);
1848 }
1849
1850 int getMusicListSize()
1851 {
1852   return (music_info->num_file_list_entries +
1853           music_info->num_dynamic_file_list_entries);
1854 }
1855
1856 struct FileInfo *getSoundListEntry(int pos)
1857 {
1858   int num_list_entries = sound_info->num_file_list_entries;
1859   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1860
1861   return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1862           &sound_info->dynamic_file_list[list_pos]);
1863 }
1864
1865 struct FileInfo *getMusicListEntry(int pos)
1866 {
1867   int num_list_entries = music_info->num_file_list_entries;
1868   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1869
1870   return (pos < num_list_entries ? &music_info->file_list[list_pos] :
1871           &music_info->dynamic_file_list[list_pos]);
1872 }
1873
1874 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1875 {
1876   int num_list_entries = sound_info->num_file_list_entries;
1877   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1878   SoundInfo **snd_info =
1879     (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
1880                    sound_info->dynamic_artwork_list);
1881
1882   return snd_info[list_pos];
1883 }
1884
1885 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
1886 {
1887   int num_list_entries = music_info->num_file_list_entries;
1888   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1889   MusicInfo **mus_info =
1890     (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
1891                    music_info->dynamic_artwork_list);
1892
1893   return mus_info[list_pos];
1894 }
1895
1896 int getSoundListPropertyMappingSize()
1897 {
1898   return sound_info->num_property_mapping_entries;
1899 }
1900
1901 int getMusicListPropertyMappingSize()
1902 {
1903   return music_info->num_property_mapping_entries;
1904 }
1905
1906 struct PropertyMapping *getSoundListPropertyMapping()
1907 {
1908   return sound_info->property_mapping;
1909 }
1910
1911 struct PropertyMapping *getMusicListPropertyMapping()
1912 {
1913   return music_info->property_mapping;
1914 }
1915
1916 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1917                    struct ConfigTypeInfo *config_suffix_list,
1918                    char **base_prefixes, char **ext1_suffixes,
1919                    char **ext2_suffixes, char **ext3_suffixes,
1920                    char **ignore_tokens)
1921 {
1922   int i;
1923
1924   sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1925   sound_info->type = ARTWORK_TYPE_SOUNDS;
1926
1927   /* ---------- initialize file list and suffix lists ---------- */
1928
1929   sound_info->num_file_list_entries = num_file_list_entries;
1930   sound_info->num_dynamic_file_list_entries = 0;
1931
1932   sound_info->file_list =
1933     getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
1934                               num_file_list_entries);
1935   sound_info->dynamic_file_list = NULL;
1936
1937   sound_info->num_suffix_list_entries = 0;
1938   for (i = 0; config_suffix_list[i].token != NULL; i++)
1939     sound_info->num_suffix_list_entries++;
1940
1941   sound_info->suffix_list = config_suffix_list;
1942
1943   /* ---------- initialize base prefix and suffixes lists ---------- */
1944
1945   sound_info->num_base_prefixes = 0;
1946   for (i = 0; base_prefixes[i] != NULL; i++)
1947     sound_info->num_base_prefixes++;
1948
1949   sound_info->num_ext1_suffixes = 0;
1950   for (i = 0; ext1_suffixes[i] != NULL; i++)
1951     sound_info->num_ext1_suffixes++;
1952
1953   sound_info->num_ext2_suffixes = 0;
1954   for (i = 0; ext2_suffixes[i] != NULL; i++)
1955     sound_info->num_ext2_suffixes++;
1956
1957   sound_info->num_ext3_suffixes = 0;
1958   for (i = 0; ext3_suffixes[i] != NULL; i++)
1959     sound_info->num_ext3_suffixes++;
1960
1961   sound_info->num_ignore_tokens = 0;
1962   for (i = 0; ignore_tokens[i] != NULL; i++)
1963     sound_info->num_ignore_tokens++;
1964
1965   sound_info->base_prefixes = base_prefixes;
1966   sound_info->ext1_suffixes = ext1_suffixes;
1967   sound_info->ext2_suffixes = ext2_suffixes;
1968   sound_info->ext3_suffixes = ext3_suffixes;
1969   sound_info->ignore_tokens = ignore_tokens;
1970
1971   sound_info->num_property_mapping_entries = 0;
1972
1973   sound_info->property_mapping = NULL;
1974
1975   /* ---------- initialize artwork reference and content lists ---------- */
1976
1977   sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
1978
1979   sound_info->artwork_list =
1980     checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1981   sound_info->dynamic_artwork_list = NULL;
1982
1983   sound_info->content_list = NULL;
1984
1985   /* ---------- initialize artwork loading/freeing functions ---------- */
1986
1987   sound_info->load_artwork = Load_WAV;
1988   sound_info->free_artwork = FreeSound;
1989 }
1990
1991 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
1992                    struct ConfigTypeInfo *config_suffix_list,
1993                    char **base_prefixes, char **ext1_suffixes,
1994                    char **ext2_suffixes, char **ext3_suffixes,
1995                    char **ignore_tokens)
1996 {
1997   int i;
1998
1999   music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2000   music_info->type = ARTWORK_TYPE_MUSIC;
2001
2002   /* ---------- initialize file list and suffix lists ---------- */
2003
2004   music_info->num_file_list_entries = num_file_list_entries;
2005   music_info->num_dynamic_file_list_entries = 0;
2006
2007   music_info->file_list =
2008     getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2009                               num_file_list_entries);
2010   music_info->dynamic_file_list = NULL;
2011
2012   music_info->num_suffix_list_entries = 0;
2013   for (i = 0; config_suffix_list[i].token != NULL; i++)
2014     music_info->num_suffix_list_entries++;
2015
2016   music_info->suffix_list = config_suffix_list;
2017
2018   /* ---------- initialize base prefix and suffixes lists ---------- */
2019
2020   music_info->num_base_prefixes = 0;
2021   for (i = 0; base_prefixes[i] != NULL; i++)
2022     music_info->num_base_prefixes++;
2023
2024   music_info->num_ext1_suffixes = 0;
2025   for (i = 0; ext1_suffixes[i] != NULL; i++)
2026     music_info->num_ext1_suffixes++;
2027
2028   music_info->num_ext2_suffixes = 0;
2029   for (i = 0; ext2_suffixes[i] != NULL; i++)
2030     music_info->num_ext2_suffixes++;
2031
2032   music_info->num_ext3_suffixes = 0;
2033   for (i = 0; ext3_suffixes[i] != NULL; i++)
2034     music_info->num_ext3_suffixes++;
2035
2036   music_info->num_ignore_tokens = 0;
2037   for (i = 0; ignore_tokens[i] != NULL; i++)
2038     music_info->num_ignore_tokens++;
2039
2040   music_info->base_prefixes = base_prefixes;
2041   music_info->ext1_suffixes = ext1_suffixes;
2042   music_info->ext2_suffixes = ext2_suffixes;
2043   music_info->ext3_suffixes = ext3_suffixes;
2044   music_info->ignore_tokens = ignore_tokens;
2045
2046   music_info->num_property_mapping_entries = 0;
2047
2048   music_info->property_mapping = NULL;
2049
2050   /* ---------- initialize artwork reference and content lists ---------- */
2051
2052   music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2053
2054   music_info->artwork_list =
2055     checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2056   music_info->dynamic_artwork_list = NULL;
2057
2058   music_info->content_list = NULL;
2059
2060   /* ---------- initialize artwork loading/freeing functions ---------- */
2061
2062   music_info->load_artwork = Load_WAV_or_MOD;
2063   music_info->free_artwork = FreeMusic;
2064 }
2065
2066 void PlayMusic(int nr)
2067 {
2068   if (!audio.music_available)
2069     return;
2070
2071   PlaySoundMusic(nr);
2072 }
2073
2074 void PlaySound(int nr)
2075 {
2076   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2077 }
2078
2079 void PlaySoundStereo(int nr, int stereo_position)
2080 {
2081   PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2082 }
2083
2084 void PlaySoundLoop(int nr)
2085 {
2086   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2087 }
2088
2089 void PlaySoundMusic(int nr)
2090 {
2091   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2092 }
2093
2094 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2095 {
2096   SoundControl snd_ctrl;
2097
2098   if (!audio.sound_available ||
2099       !audio.sound_enabled ||
2100       audio.sound_deactivated)
2101     return;
2102
2103   if (volume < SOUND_MIN_VOLUME)
2104     volume = SOUND_MIN_VOLUME;
2105   else if (volume > SOUND_MAX_VOLUME)
2106     volume = SOUND_MAX_VOLUME;
2107
2108   if (stereo_position < SOUND_MAX_LEFT)
2109     stereo_position = SOUND_MAX_LEFT;
2110   else if (stereo_position > SOUND_MAX_RIGHT)
2111     stereo_position = SOUND_MAX_RIGHT;
2112
2113   memset(&snd_ctrl, 0, sizeof(SoundControl));   /* to make valgrind happy */
2114
2115   snd_ctrl.active = TRUE;
2116   snd_ctrl.nr = nr;
2117   snd_ctrl.volume = volume;
2118   snd_ctrl.stereo_position = stereo_position;
2119   snd_ctrl.state = state;
2120
2121   HandleSoundRequest(snd_ctrl);
2122 }
2123
2124 void FadeMusic(void)
2125 {
2126   if (!audio.music_available)
2127     return;
2128
2129   StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2130 }
2131
2132 void FadeSound(int nr)
2133 {
2134   StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2135 }
2136
2137 void FadeSounds()
2138 {
2139   StopSoundExt(-1, SND_CTRL_FADE_ALL);
2140 }
2141
2142 void FadeSoundsAndMusic()
2143 {
2144   FadeSounds();
2145   FadeMusic();
2146 }
2147
2148 void StopMusic(void)
2149 {
2150   if (!audio.music_available)
2151     return;
2152
2153   StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2154 }
2155
2156 void StopSound(int nr)
2157 {
2158   StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2159 }
2160
2161 void StopSounds()
2162 {
2163   StopMusic();
2164   StopSoundExt(-1, SND_CTRL_STOP_ALL);
2165 }
2166
2167 void StopSoundExt(int nr, int state)
2168 {
2169   SoundControl snd_ctrl;
2170
2171   if (!audio.sound_available)
2172     return;
2173
2174   memset(&snd_ctrl, 0, sizeof(SoundControl));   /* to make valgrind happy */
2175
2176   snd_ctrl.active = FALSE;
2177   snd_ctrl.nr = nr;
2178   snd_ctrl.state = state;
2179
2180   HandleSoundRequest(snd_ctrl);
2181 }
2182
2183 static void ReloadCustomSounds()
2184 {
2185 #if 0
2186   printf("::: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2187 #endif
2188
2189   LoadArtworkConfig(sound_info);
2190   ReloadCustomArtworkList(sound_info);
2191 }
2192
2193 static void ReloadCustomMusic()
2194 {
2195 #if 0
2196   printf("::: reloading music '%s' ...\n", artwork.mus_current_identifier);
2197 #endif
2198
2199   LoadArtworkConfig(music_info);
2200   ReloadCustomArtworkList(music_info);
2201
2202   /* load all music files from directory not defined in "musicinfo.conf" */
2203   LoadCustomMusic_NoConf();
2204 }
2205
2206 void InitReloadCustomSounds(char *set_identifier)
2207 {
2208   if (!audio.sound_available)
2209     return;
2210
2211 #if defined(AUDIO_UNIX_NATIVE)
2212   LoadArtworkConfig(sound_info);        /* also load config on sound client */
2213   WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2214 #else
2215   ReloadCustomSounds();
2216 #endif
2217 }
2218
2219 void InitReloadCustomMusic(char *set_identifier)
2220 {
2221   if (!audio.music_available)
2222     return;
2223
2224 #if defined(AUDIO_UNIX_NATIVE)
2225   LoadArtworkConfig(music_info);        /* also load config on sound client */
2226   WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2227 #else
2228   ReloadCustomMusic();
2229 #endif
2230 }
2231
2232 void FreeSound(void *ptr)
2233 {
2234   SoundInfo *sound = (SoundInfo *)ptr;
2235
2236   if (sound == NULL)
2237     return;
2238
2239   if (sound->data_ptr)
2240   {
2241 #if defined(TARGET_SDL)
2242     Mix_FreeChunk(sound->data_ptr);
2243 #elif defined(TARGET_ALLEGRO)
2244     destroy_sample(sound->data_ptr);
2245 #else /* AUDIO_UNIX_NATIVE */
2246     free(sound->data_ptr);
2247 #endif
2248   }
2249
2250   checked_free(sound->source_filename);
2251
2252   free(sound);
2253 }
2254
2255 void FreeMusic(void *ptr)
2256 {
2257   MusicInfo *music = (MusicInfo *)ptr;
2258
2259   if (music == NULL)
2260     return;
2261
2262   if (music->data_ptr)
2263   {
2264 #if defined(TARGET_SDL)
2265     if (music->type == MUS_TYPE_MOD)
2266       Mix_FreeMusic(music->data_ptr);
2267     else
2268       Mix_FreeChunk(music->data_ptr);
2269 #elif defined(TARGET_ALLEGRO)
2270     destroy_sample(music->data_ptr);
2271 #else /* AUDIO_UNIX_NATIVE */
2272     free(music->data_ptr);
2273 #endif
2274   }
2275
2276   free(music);
2277 }
2278
2279 static void FreeAllMusic_NoConf()
2280 {
2281   int i;
2282
2283   if (Music_NoConf == NULL)
2284     return;
2285
2286   for (i = 0; i < num_music_noconf; i++)
2287     FreeMusic(Music_NoConf[i]);
2288
2289   free(Music_NoConf);
2290
2291   Music_NoConf = NULL;
2292   num_music_noconf = 0;
2293 }
2294
2295 void FreeAllSounds()
2296 {
2297   FreeCustomArtworkLists(sound_info);
2298 }
2299
2300 void FreeAllMusic()
2301 {
2302   FreeCustomArtworkLists(music_info);
2303   FreeAllMusic_NoConf();
2304 }
2305
2306 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS                          */
2307 /* ========================================================================= */