rnd-20001130-1-src
[rocksndiamonds.git] / src / sound.c
index 185b1822d9bbe3213a927ba37c803a671897107a..91da5d7db44c1cc85f0b78df9c4f5bf1bdbb2ca3 100644 (file)
@@ -26,7 +26,7 @@ static struct SoundControl emptySoundControl =
 #if defined(PLATFORM_UNIX)
 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
 static char premix_first_buffer[SND_BLOCKSIZE];
-#ifdef VOXWARE
+#if defined(AUDIO_STREAMING_DSP)
 static char premix_left_buffer[SND_BLOCKSIZE];
 static char premix_right_buffer[SND_BLOCKSIZE];
 static int premix_last_buffer[SND_BLOCKSIZE];
@@ -35,16 +35,14 @@ static unsigned char playing_buffer[SND_BLOCKSIZE];
 #endif
 
 /* forward declaration of internal functions */
-#ifdef VOXWARE
+#if defined(AUDIO_STREAMING_DSP)
 static void SoundServer_InsertNewSound(struct SoundControl);
-#else
-#if defined(PLATFORM_UNIX)
+#elif defined(PLATFORM_UNIX)
 static unsigned char linear_to_ulaw(int);
 static int ulaw_to_linear(unsigned char);
 #endif
-#endif
 
-#ifdef HPUX_AUDIO
+#if defined(PLATFORM_HPUX)
 static void HPUX_Audio_Control();
 #endif
 
@@ -55,10 +53,14 @@ static void SoundServer_StopAllSounds();
 #endif
 
 #if defined(PLATFORM_UNIX)
-int OpenAudio(char *audio_device_name)
+int OpenAudioDevice(char *audio_device_name)
 {
   int audio_fd;
 
+  /* check if desired audio device is accessible */
+  if (access(sound_device_name, W_OK) != 0)
+    return -1;
+
   /* try to open audio device in non-blocking mode */
   if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
     return audio_fd;
@@ -70,31 +72,42 @@ int OpenAudio(char *audio_device_name)
   return audio_fd;
 }
 
-int CheckAudio(char *audio_device_name)
+void UnixOpenAudio(struct AudioSystemInfo *audio)
 {
+  static char *audio_device_name[] =
+  {
+    DEVICENAME_DSP,
+    DEVICENAME_AUDIO
+  };
   int audio_fd;
+  int i;
 
-  if (access(audio_device_name, W_OK) != 0)
-  {
-    Error(ERR_WARN, "cannot access audio device - no sound");
-    return SOUND_OFF;
-  }
+  /* look for available audio devices, starting with preferred ones */
+  for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
+    if ((audio_fd = OpenAudioDevice(sound_device_name)) >= 0)
+      break;
 
-  if ((audio_fd = OpenAudio(sound_device_name)) < 0)
+  if (audio_fd < 0)
   {
     Error(ERR_WARN, "cannot open audio device - no sound");
-    return SOUND_OFF;
+    return;
   }
 
   close(audio_fd);
 
-  return SOUND_AVAILABLE;
+  audio->sound_available = TRUE;
+
+#if defined(AUDIO_STREAMING_DSP)
+  audio->loops_available = TRUE;
+#endif
 }
 
-boolean UnixInitAudio(void)
+void UnixCloseAudio(struct AudioSystemInfo *audio)
 {
-  return TRUE;
+  if (audio->device_fd)
+    close(audio->device_fd);
 }
+
 #endif /* PLATFORM_UNIX */
 
 void SoundServer()
@@ -104,7 +117,7 @@ void SoundServer()
   struct SoundControl snd_ctrl;
   fd_set sound_fdset;
 
-  close(sysinfo.audio_process_pipe[1]);        /* no writing into pipe needed */
+  close(audio.soundserver_pipe[1]);    /* no writing into pipe needed */
 #endif
 
   for(i=0;i<MAX_SOUNDS_PLAYING;i++)
@@ -117,24 +130,24 @@ void SoundServer()
     stereo_volume[i] =
       (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
 
-#ifdef HPUX_AUDIO
+#if defined(PLATFORM_HPUX)
   HPUX_Audio_Control();
 #endif
 
   FD_ZERO(&sound_fdset); 
-  FD_SET(sysinfo.audio_process_pipe[0], &sound_fdset);
+  FD_SET(audio.soundserver_pipe[0], &sound_fdset);
 
   while(1)     /* wait for sound playing commands from client */
   {
-    FD_SET(sysinfo.audio_process_pipe[0], &sound_fdset);
-    select(sysinfo.audio_process_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
-    if (!FD_ISSET(sysinfo.audio_process_pipe[0], &sound_fdset))
+    FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+    select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
+    if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
       continue;
-    if (read(sysinfo.audio_process_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
+    if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
        != sizeof(snd_ctrl))
       Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
 
-#ifdef VOXWARE
+#if defined(AUDIO_STREAMING_DSP)
 
     if (snd_ctrl.fade_sound)
     {
@@ -154,7 +167,7 @@ void SoundServer()
        playlist[i]=emptySoundControl;
       playing_sounds=0;
 
-      close(sysinfo.audio_fd);
+      close(audio.device_fd);
     }
     else if (snd_ctrl.stop_sound)
     {
@@ -169,7 +182,7 @@ void SoundServer()
        }
 
       if (!playing_sounds)
-       close(sysinfo.audio_fd);
+       close(audio.device_fd);
     }
 
     if (playing_sounds || snd_ctrl.active)
@@ -189,7 +202,7 @@ void SoundServer()
 #endif
 
       if (playing_sounds ||
-         (sysinfo.audio_fd = OpenAudio(sound_device_name)) >= 0)
+         (audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
       {
        if (!playing_sounds)    /* we just opened the audio device */
        {
@@ -197,13 +210,12 @@ void SoundServer()
          /* (with stereo the effective buffer size will shrink to 256) */
          fragment_size = 0x00020009;
 
-         if (ioctl(sysinfo.audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_size)
-             < 0)
+         if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
            Error(ERR_EXIT_SOUND_SERVER,
                  "cannot set fragment size of /dev/dsp - no sounds");
 
          /* try if we can use stereo sound */
-         if (ioctl(sysinfo.audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
+         if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
          {
 #ifdef DEBUG
            static boolean reported = FALSE;
@@ -217,13 +229,12 @@ void SoundServer()
            stereo = FALSE;
          }
 
-         if (ioctl(sysinfo.audio_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
+         if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
            Error(ERR_EXIT_SOUND_SERVER,
                  "cannot set sample rate of /dev/dsp - no sounds");
 
          /* get the real fragmentation size; this should return 512 */
-         if (ioctl(sysinfo.audio_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size)
-             < 0)
+         if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
            Error(ERR_EXIT_SOUND_SERVER,
                  "cannot get fragment size of /dev/dsp - no sounds");
 
@@ -234,10 +245,10 @@ void SoundServer()
          SoundServer_InsertNewSound(snd_ctrl);
 
        while(playing_sounds &&
-             select(sysinfo.audio_process_pipe[0] + 1,
+             select(audio.soundserver_pipe[0] + 1,
                     &sound_fdset, NULL, NULL, &delay) < 1)
        {       
-         FD_SET(sysinfo.audio_process_pipe[0], &sound_fdset);
+         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
 
          /* first clear the last premixing buffer */
          memset(premix_last_buffer,0,fragment_size*sizeof(int));
@@ -334,16 +345,16 @@ void SoundServer()
          }
 
          /* finally play the sound fragment */
-         write(sysinfo.audio_fd, playing_buffer,fragment_size);
+         write(audio.device_fd, playing_buffer,fragment_size);
        }
 
        /* if no sounds playing, free device for other sound programs */
        if (!playing_sounds)
-         close(sysinfo.audio_fd);
+         close(audio.device_fd);
       }
     }
 
-#else /* !VOXWARE */
+#else /* !AUDIO_STREAMING_DSP */
 
     if (snd_ctrl.active && !snd_ctrl.loop)
     {
@@ -354,15 +365,15 @@ void SoundServer()
       int wait_percent = 90;   /* wait 90% of the real playing time */
       int i;
 
-      if ((sysinfo.audio_fd = OpenAudio(sound_device_name)) >= 0)
+      if ((audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
       {
        playing_sounds = 1;
 
        while(playing_sounds &&
-             select(sysinfo.audio_process_pipe[0] + 1,
+             select(audio.soundserver_pipe[0] + 1,
                     &sound_fdset, NULL, NULL, &delay) < 1)
        {       
-         FD_SET(sysinfo.audio_process_pipe[0], &sound_fdset);
+         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
 
          /* get pointer and size of the actual sound sample */
          sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
@@ -389,16 +400,16 @@ void SoundServer()
            playing_sounds = 0;
 
          /* finally play the sound fragment */
-         write(sysinfo.audio_fd,playing_buffer,sample_size);
+         write(audio.device_fd,playing_buffer,sample_size);
 
          delay.tv_sec = 0;
          delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
        }
-       close(sysinfo.audio_fd);
+       close(audio.device_fd);
       }
     }
 
-#endif /* !VOXWARE */
+#endif /* !AUDIO_STREAMING_DSP */
 
   }
 
@@ -608,7 +619,7 @@ static void SoundServer_StopSound(int nr)
 
 #if !defined(PLATFORM_MSDOS)
   if (!playing_sounds)
-    close(sysinfo.audio_fd);
+    close(audio.device_fd);
 #endif
 }
 
@@ -627,13 +638,13 @@ static void SoundServer_StopAllSounds()
   playing_sounds = 0;
 
 #if !defined(PLATFORM_MSDOS)
-  close(sysinfo.audio_fd);
+  close(audio.device_fd);
 #endif
 }
 #endif /* PLATFORM_MSDOS */
 #endif /* !PLATFORM_WIN32 */
 
-#ifdef HPUX_AUDIO
+#if defined(PLATFORM_HPUX)
 static void HPUX_Audio_Control()
 {
   struct audio_describe ainfo;
@@ -654,9 +665,9 @@ static void HPUX_Audio_Control()
 
   close(audio_ctl);
 }
-#endif /* HPUX_AUDIO */
+#endif /* PLATFORM_HPUX */
 
-#if !defined(VOXWARE) && defined(PLATFORM_UNIX)
+#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
 
 /* these two are stolen from "sox"... :) */
 
@@ -761,7 +772,7 @@ static int ulaw_to_linear(unsigned char ulawbyte)
 
   return(sample);
 }
-#endif /* !VOXWARE && PLATFORM_UNIX */
+#endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
 
 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
 
@@ -891,7 +902,7 @@ void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
 {
   struct SoundControl snd_ctrl = emptySoundControl;
 
-  if (!sysinfo.audio_available || !setup.sound)
+  if (!audio.sound_available || !setup.sound)
     return;
 
   if (volume<PSND_MIN_VOLUME)
@@ -921,10 +932,10 @@ void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
 
 #else
 #if !defined(PLATFORM_MSDOS)
-  if (write(sysinfo.audio_process_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
+  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
   {
     Error(ERR_WARN, "cannot pipe to child process - no sounds");
-    sysinfo.audio_available = FALSE;
+    audio.sound_available = FALSE;
     return;
   }
 #else
@@ -957,7 +968,7 @@ void StopSoundExt(int nr, int method)
 {
   struct SoundControl snd_ctrl = emptySoundControl;
 
-  if (!sysinfo.audio_available)
+  if (!audio.sound_available)
     return;
 
   if (SSND_FADING(method))
@@ -986,10 +997,10 @@ void StopSoundExt(int nr, int method)
 
 #else
 #if !defined(PLATFORM_MSDOS)
-  if (write(sysinfo.audio_process_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
+  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
   {
     Error(ERR_WARN, "cannot pipe to child process - no sounds");
-    sysinfo.audio_available = FALSE;
+    audio.sound_available = FALSE;
     return;
   }
 #else
@@ -1002,7 +1013,7 @@ void FreeSounds(int num_sounds)
 {
   int i;
 
-  if (!sysinfo.audio_available)
+  if (!audio.sound_available)
     return;
 
   for(i=0; i<num_sounds; i++)