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