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