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