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