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