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