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