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