[AD] ALSA 0.9 Patch

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Alright,

Finally got around to finishing this small patch.

I tested both drivers "a bit", the DIGI one I basically just tested 
with Ben's sekrit projact, and the setup program, and for the MIDI 
driver I had to setup some funky routing with timidity+alsa seq+alsa 
virmidi+alsa rawmidi ;) (I don't have a midi device any more)

It all works as far as I can tell. The configure hackery detects my 
alsa 0.9, and it should hopefully detect and work fine under alsa 0.5 
as well.

patch is attached for your perusal.

-- 
Thomas Fjellstrom
tfjellstrom@xxxxxxxxxx
http://strangesoft.net
diff -u -r allegro-orig/aclocal.m4 allegro/aclocal.m4
--- allegro-orig/aclocal.m4	2003-07-20 04:45:18.000000000 -0600
+++ allegro/aclocal.m4	2003-07-20 04:51:10.000000000 -0600
@@ -325,6 +325,58 @@
 ])
 
 dnl
+dnl Test For ALSA Version
+dnl
+dnl Variables:
+dnl  allegro_alsa_version=(0.5|0.9)
+dnl
+AC_DEFUN(ALLEGRO_ACTEST_ALSAVERSION_CHECK,
+[AC_ARG_ENABLE(alsa_version_check,
+[  --enable-alsa-version-check[=x]   enable checking for ALSAs version [default=yes]],
+test "X$enableval" != "Xno" && allegro_enable_alsa_version_check=yes,
+allegro_enable_alsa_version_check=yes)
+if test -n "$allegro_enable_alsa_version_check"; then
+  AC_MSG_CHECKING(for ALSA version)
+  AC_TRY_RUN([#include <sys/asoundlib.h>
+    #include <string.h>
+	#include <stdio.h>
+    int main(void) { char tmp[255]; snprintf(tmp, 255, "echo %i > alsaver", SND_LIB_MAJOR); system(tmp); return 0; } ],
+  allegro_cv_alsa_version=ummm,
+  allegro_cv_alsa_version=unknown,
+  allegro_cv_alsa_version=unknown)
+  ALLEGRO_ALSA_MAJOR_VER=`cat alsaver`
+  
+  AC_TRY_RUN([#include <sys/asoundlib.h>
+    #include <string.h>
+	#include <stdio.h>
+    int main(void) { char tmp[255]; snprintf(tmp, 255, "echo %i > alsaver", SND_LIB_MINOR); system(tmp); return 0; } ],
+  allegro_cv_alsa_version=ummm,
+  allegro_cv_alsa_version=unknown,
+  allegro_cv_alsa_version=unknown)
+  ALLEGRO_ALSA_MINOR_VER=`cat alsaver`
+  
+  AC_TRY_RUN([#include <sys/asoundlib.h>
+    #include <string.h>
+	#include <stdio.h>
+    int main(void) { char tmp[255]; snprintf(tmp, 255, "echo %i > alsaver", SND_LIB_SUBMINOR); system(tmp); return 0; } ],
+  allegro_cv_alsa_version=ummm,
+  allegro_cv_alsa_version=unknown,
+  allegro_cv_alsa_version=unknown)
+  ALLEGRO_ALSA_SUBMINOR_VER=`cat alsaver`
+  
+  AC_TRY_RUN([#include <sys/asoundlib.h>
+    #include <string.h>
+	#include <stdio.h>
+    int main(void) { char tmp[255]; snprintf(tmp, 255, "echo %i > alsaver", SND_LIB_EXTRAVER); system(tmp); return 0; } ],
+  allegro_cv_alsa_version=ummm,
+  allegro_cv_alsa_version=unknown,
+  allegro_cv_alsa_version=unknown)
+  ALLEGRO_ALSA_EXTRA_VER=`cat alsaver`
+  
+  AC_MSG_RESULT("$ALLEGRO_ALSA_MAJOR_VER.$ALLEGRO_ALSA_MINOR_VER.$ALLEGRO_ALSA_SUBMINOR_VER")
+fi])
+
+dnl
 dnl Test for ALSA DIGI driver.
 dnl
 dnl Variables:
@@ -336,19 +388,24 @@
 [  --enable-alsadigi[=x]   enable building ALSA DIGI driver [default=yes]],
 test "X$enableval" != "Xno" && allegro_enable_alsadigi=yes,
 allegro_enable_alsadigi=yes)
- 
+  
+allegro_cv_support_alsadigi=no
 if test -n "$allegro_enable_alsadigi"; then
-  AC_CACHE_CHECK(for supported ALSA version for digital sound,
-  allegro_cv_support_alsadigi,
-  AC_TRY_RUN([#include <sys/asoundlib.h>
-    int main (void) { return SND_LIB_MAJOR != 0 || SND_LIB_MINOR != 5; }],
-  allegro_cv_support_alsadigi=yes,
-  allegro_cv_support_alsadigi=no,
-  allegro_cv_support_alsadigi=no))
-  if test "X$allegro_cv_support_alsadigi" = "Xyes" && 
+  AC_MSG_CHECKING(for supported ALSA version for pcm)
+  allegro_cv_support_alsadigi=no
+  if test ALLEGRO_ALSA_MAJOR_VER=0 && ALLEGRO_ALSA_MINOR_VER=5; then
+    allegro_cv_support_alsadigi=yes
+  fi
+  
+  if test ALLEGRO_ALSA_MAJOR_VER=0 && ALLEGRO_ALSA_MINOR_VER=9; then
+    allegro_cv_support_alsadigi=yes
+  fi
+  
+  if test "X$allegro_cv_support_alsadigi" = "Xyes" &&
      test -z "$allegro_support_modules"; then
     LIBS="-lasound $LIBS"
   fi
+  AC_MSG_RESULT($allegro_cv_support_alsadigi)
 fi])
 
 dnl
@@ -363,19 +420,23 @@
 [  --enable-alsamidi[=x]   enable building ALSA MIDI driver [default=yes]],
 test "X$enableval" != "Xno" && allegro_enable_alsamidi=yes,
 allegro_enable_alsamidi=yes)
-
+allegro_cv_support_alsamidi=no
 if test -n "$allegro_enable_alsamidi"; then
-  AC_CACHE_CHECK(for supported ALSA version for MIDI,
-  allegro_cv_support_alsamidi,
-  AC_TRY_RUN([#include <sys/asoundlib.h>
-    int main (void) { return SND_LIB_MAJOR != 0 || SND_LIB_MINOR != 5; }],
-  allegro_cv_support_alsamidi=yes,
-  allegro_cv_support_alsamidi=no,
-  allegro_cv_support_alsamidi=no))
+  AC_MSG_CHECKING(for supported ALSA version for midi)
+  allegro_cv_support_alsamidi=no
+  if test ALLEGRO_ALSA_MAJOR_VER=0 && test ALLEGRO_ALSA_MINOR_VER=5; then
+    allegro_cv_support_alsamidi=yes
+  fi
+  
+  if test ALLEGRO_ALSA_MAJOR_VER=0 && test ALLEGRO_ALSA_MINOR_VER=9; then
+	allegro_cv_support_alsamidi=yes
+  fi
+  
   if test "X$allegro_cv_support_alsamidi" = "Xyes" &&
      test -z "$allegro_support_modules"; then
     LIBS="-lasound $LIBS"
   fi
+  AC_MSG_RESULT($allegro_cv_support_alsamidi)
 fi])
 
 dnl
diff -u -r allegro-orig/allegro.cfg allegro/allegro.cfg
--- allegro-orig/allegro.cfg	2003-07-20 04:45:18.000000000 -0600
+++ allegro/allegro.cfg	2003-07-20 05:22:27.000000000 -0600
@@ -440,15 +440,34 @@
 
 
 
-# Unix only: card number and PCM device for the ALSA driver
+# Unix only: card number and PCM device for the ALSA 0.5 driver
 alsa_card = 
 alsa_pcmdevice = 
 
+# Unix only: Device name for ALSA 0.9 driver
+# default: default
+# format: <driver>[:<card>,<device>]
+# ie: default
+# ie: hw:0,1
 
+alsa_device = 
 
-# Unix only: size of ALSA driver fragments (buffers)
+# Unix only: number of ALSA driver fragments (buffers)
 alsa_numfrags = 
 
+# Unix only: size of ALSA driver fragments (buffers)
+alsa_fragsize = 
+
+# Unix only: mixer element name for ALSA 0.9 driver (default: PCM)
+alsa_mixer_elem =
+
+# Unix only: card number for ALSA 0.5 driver
+alsa_rawmidi_card =
+
+# Unix only: device number for ALSA 0.5 driver
+# Unix only: device name for ALSA 0.9 driver (same format as 'alsa_device')
+alsa_rawmidi_device = 
+
 
 
 # BeOS only: MIDI synthesizer instruments quality (0=low, 1=high)
diff -u -r allegro-orig/configure.in allegro/configure.in
--- allegro-orig/configure.in	2003-07-20 04:45:18.000000000 -0600
+++ allegro/configure.in	2003-07-20 04:50:23.000000000 -0600
@@ -301,6 +301,13 @@
   _disabled_modules="ossdigi $_disabled_modules"
 fi
 
+dnl Test for ALSA version
+ALLEGRO_ACTEST_ALSAVERSION_CHECK
+AC_DEFINE_UNQUOTED(ALLEGRO_ALSA_MAJOR_VER, $ALLEGRO_ALSA_MAJOR_VER, [ALSA Major Version])
+AC_DEFINE_UNQUOTED(ALLEGRO_ALSA_MINOR_VER, $ALLEGRO_ALSA_MINOR_VER, [ALSA Minor Version])
+AC_DEFINE_UNQUOTED(ALLEGRO_ALSA_SUBMINOR_VER, $ALLEGRO_ALSA_SUBMINOR_VER, [ALSA SubMinor Version])
+AC_DEFINE_UNQUOTED(ALLEGRO_ALSA_EXTRA_VER, $ALLEGRO_ALSA_EXTRA_VER, [ALSA Extra Version])
+
 dnl Test for ALSA drivers.
 ALLEGRO_ACTEST_ALSADIGI
 if test "$allegro_cv_support_alsadigi" = yes; then
diff -u -r allegro-orig/docs/src/thanks._tx allegro/docs/src/thanks._tx
--- allegro-orig/docs/src/thanks._tx	2003-07-20 04:45:18.000000000 -0600
+++ allegro/docs/src/thanks._tx	2003-07-20 05:30:03.000000000 -0600
@@ -792,6 +792,10 @@
    Improved the cpu detection for Cyrix chips and made the file selector
    only list valid drive letters.
 
+   Thomas Fjellstrom (<email>tfjellstrom@xxxxxxxxxx</a>).<br>
+   Wrote the ALSA MIDI driver.
+   Wrote the ALSA 0.9 DIGI and MIDI drivers.
+
    Thomas Klausner (<email>wiz@xxxxxxxxxx</a>).<br>
    Added NetBSD detection.
 
@@ -811,9 +815,6 @@
    Tom Breton (<email>tob@xxxxxxxxxx</a>).<br>
    Added the functionality selection #ifndefs to allegro.h.
 
-   Tom Fjellstrom (<email>tfjellstrom@xxxxxxxxxx</a>).<br>
-   Wrote the ALSA MIDI driver.
-
    Tom Novelli (<email>tnovelli@xxxxxxxxxx</a>).<br>
    Wrote the original version of the digital MIDI driver.
 
diff -u -r allegro-orig/src/unix/alsa.c allegro/src/unix/alsa.c
--- allegro-orig/src/unix/alsa.c	2003-07-20 04:45:18.000000000 -0600
+++ allegro/src/unix/alsa.c	2003-07-20 05:54:08.000000000 -0600
@@ -11,6 +11,7 @@
  *      ALSA sound driver.
  *
  *      By Peter Wang (based heavily on uoss.c)
+ *      ALSA 0.9 Support By Thomas Fjellstrom
  *
  *      See readme.txt for copyright information.
  */
@@ -29,10 +30,66 @@
 
 #ifndef SCAN_DEPEND
    #include <string.h>
+	
+#if ALLEGRO_ALSA_MAJOR_VER >= 0 && ALLEGRO_ALSA_MINOR_VER >= 9	
+   #define ALSA_PCM_NEW_HW_PARAMS_API 1
+   #include <alsa/asoundlib.h>
+   #include <math.h>
+   #define ALSA_09 1
+#else
    #include <sys/asoundlib.h>
+   #define ALSA_05 1
+#endif
+
 #endif
 
 
+#define ALSA_DEFAULT_NUMFRAGS   16
+
+static snd_pcm_t *pcm_handle;
+static unsigned char *alsa_bufdata;
+static int alsa_bits, alsa_signed, alsa_rate, alsa_stereo;
+static int alsa_fragments;
+
+static char alsa_desc[256] = EMPTY_STRING;
+
+#if defined ALSA_09
+
+#ifndef SND_PCM_FORMAT_S16_NE
+   #ifdef ALLEGRO_BIG_ENDIAN
+      #define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_BE
+   #else
+      #define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_LE
+   #endif
+#endif
+#ifndef SND_PCM_FORMAT_U16_NE
+   #ifdef ALLEGRO_BIG_ENDIAN
+      #define SND_PCM_FORMAT_U16_NE SND_PCM_FORMAT_U16_BE
+   #else
+      #define SND_PCM_FORMAT_U16_NE SND_PCM_FORMAT_U16_LE
+   #endif
+#endif
+
+#define ALSA9_CHECK(a) do { \
+   int err = (a); \
+   if(err<0) { \
+      snprintf(allegro_error, ALLEGRO_ERROR_SIZE, "ALSA: %s : %s", #a, get_config_text(snd_strerror(err))); \
+   } \
+} while(0)
+
+static char const *alsa_device = "default";
+static snd_pcm_hw_params_t *hwparams = NULL;
+static snd_pcm_sw_params_t *swparams = NULL;
+static snd_pcm_channel_area_t *areas = NULL;
+static snd_output_t *snd_output = NULL;
+static snd_pcm_uframes_t alsa_bufsize;
+static snd_mixer_t *alsa_mixer = NULL;
+static snd_mixer_elem_t *alsa_mixer_elem = NULL;
+static long alsa_mixer_elem_min, alsa_mixer_elem_max;
+static double alsa_mixer_allegro_ratio = 0.0;
+
+#else
+
 #ifndef SND_PCM_SFMT_S16_NE
    #ifdef ALLEGRO_BIG_ENDIAN
       #define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_BE
@@ -48,18 +105,9 @@
    #endif
 #endif
 
-
-#define ALSA_DEFAULT_NUMFRAGS   16
-
-
-static snd_pcm_t *pcm_handle;
 static int alsa_bufsize;
-static unsigned char *alsa_bufdata;
-static int alsa_bits, alsa_signed, alsa_rate, alsa_stereo;
-static int alsa_fragments;
-
-static char alsa_desc[256] = EMPTY_STRING;
 
+#endif
 
 
 static int alsa_detect(int input);
@@ -135,7 +183,267 @@
    return alsa_bufsize * alsa_fragments / (alsa_bits / 8) / (alsa_stereo ? 2 : 1);
 }
 
+#ifdef ALSA_09
+/*
+ *   Underrun and suspend recovery
+ */
+ 
+static int xrun_recovery(snd_pcm_t *handle, int err)
+{
+   if (err == -EPIPE) {    /* under-run */
+      err = snd_pcm_prepare(pcm_handle);
+      if (err < 0)
+         printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
+      return 0;
+   } else if (err == -ESTRPIPE) {
+      while ((err = snd_pcm_resume(pcm_handle)) == -EAGAIN)
+         sleep(1);       /* wait until the suspend flag is released */
+      if (err < 0) {
+         err = snd_pcm_prepare(pcm_handle);
+         if (err < 0)
+            printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
+      }
+      return 0;
+   }
+   return err;
+}
 
+static void alsa_update(int threaded)
+{
+   int i;
+
+   for(i = 0; i < alsa_fragments; i++) {		
+      int ret = 0;
+      while((ret = snd_pcm_writei(pcm_handle, alsa_bufdata, alsa_bufsize / (alsa_bits / 8) / (alsa_stereo ? 2 : 1))) < 0) {
+         if (ret == -EAGAIN)
+            continue;
+         if (ret < 0) {
+            if (xrun_recovery(pcm_handle, ret) < 0) {
+               fprintf(stderr, "Write error: %s\n", snd_strerror(ret));
+               exit(EXIT_FAILURE);
+            }
+            break;  /* skip */
+         }
+      }
+      _mix_some_samples((unsigned long) alsa_bufdata, 0, alsa_signed);
+   }
+}
+
+/* alsa_detect:
+ *  Detect driver presence.
+ */
+static int alsa_detect(int input)
+{
+   int ret = FALSE;
+   char tmp1[128], tmp2[128];
+	
+   alsa_device = get_config_string(uconvert_ascii("sound", tmp1),
+         uconvert_ascii("alsa_device", tmp2),
+         alsa_device);
+	
+   ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+     if(ret < 0) {
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device"));
+      return FALSE;
+   }
+	
+   snd_pcm_close(pcm_handle);
+   pcm_handle = NULL;
+	
+   return TRUE;	
+}
+
+/* alsa_init:
+ *  ALSA init routine.
+ */
+static int alsa_init(int input, int voices)
+{
+   int ret = 0;
+   char tmp1[128], tmp2[128];
+   unsigned int dir=0;
+   int format=0, bps=0, fragsize=0, numfrags=0;
+	
+   if (input) {
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported"));
+      return -1;
+   }
+	
+   ALSA9_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0));
+	
+   alsa_device = get_config_string(uconvert_ascii("sound", tmp1),
+         uconvert_ascii("alsa_device", tmp2),
+         "default");
+	
+   fragsize = get_config_int(uconvert_ascii("sound", tmp1),
+         uconvert_ascii("alsa_fragsize", tmp2),
+         -1);
+
+   numfrags = get_config_int(uconvert_ascii("sound", tmp1),
+              uconvert_ascii("alsa_numfrags", tmp2),
+              ALSA_DEFAULT_NUMFRAGS);
+	
+   ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+   if(ret < 0) {
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device"));
+      return -1;
+   }
+	
+   snd_mixer_open(&alsa_mixer, 0);
+   if(alsa_mixer && snd_mixer_attach(alsa_mixer, alsa_device) >= 0 &&
+      snd_mixer_selem_register (alsa_mixer, NULL, NULL) >= 0 &&
+      snd_mixer_load(alsa_mixer) >= 0) {
+		
+      const char *alsa_mixer_elem_name = get_config_string(uconvert_ascii("sound", tmp1),
+               uconvert_ascii("alsa_mixer_elem", tmp2),
+               "PCM");
+
+      alsa_mixer_elem = snd_mixer_first_elem(alsa_mixer);
+			
+      while(alsa_mixer_elem) {
+         const char *name = snd_mixer_selem_get_name(alsa_mixer_elem);
+		
+         if(strcasecmp(name, alsa_mixer_elem_name) == 0) {
+            snd_mixer_selem_get_playback_volume_range(alsa_mixer_elem, &alsa_mixer_elem_min, &alsa_mixer_elem_max);
+            alsa_mixer_allegro_ratio = (double) (alsa_mixer_elem_max - alsa_mixer_elem_min) / (double) 255;
+            break;
+         }
+			
+         alsa_mixer_elem = snd_mixer_elem_next(alsa_mixer_elem);
+      }	
+   }
+	
+	
+   /* Set format variables.  */
+   alsa_bits = (_sound_bits == 8) ? 8 : 16;
+   alsa_stereo = (_sound_stereo) ? 1 : 0;
+   alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100;
+	
+   format = ((alsa_bits == 16) ? SND_PCM_FORMAT_S16_NE : SND_PCM_FORMAT_U8);
+
+   alsa_signed = 0;
+   bps = alsa_rate * (alsa_stereo ? 2 : 1);
+   switch (format) {
+      case SND_PCM_FORMAT_U8:
+         alsa_bits = 8;
+         break;
+		
+      case SND_PCM_FORMAT_S16_LE:
+         alsa_signed = 1;
+         bps <<= 1;
+         if (sizeof(short) != 2) {
+            ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format"));
+            goto error;
+         }
+         break;
+
+      default:
+         ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format"));
+         goto error;
+   }
+
+   if (fragsize < 0) {
+      bps >>= 9;
+      if (bps < 16)
+         bps = 16;
+		
+      fragsize = 1;
+      while ((fragsize << 1) < bps)
+         fragsize <<= 1;
+   }
+   else {
+      fragsize = fragsize * (alsa_bits / 8) * (alsa_stereo ? 2 : 1);
+   }
+	
+   snd_pcm_hw_params_malloc(&hwparams);
+   snd_pcm_sw_params_malloc(&swparams);
+	
+   ALSA9_CHECK(snd_pcm_hw_params_any(pcm_handle, hwparams));
+   ALSA9_CHECK(snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED));
+   ALSA9_CHECK(snd_pcm_hw_params_set_format(pcm_handle, hwparams, format));
+   ALSA9_CHECK(snd_pcm_hw_params_set_channels(pcm_handle, hwparams, alsa_stereo+1));
+	
+   snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &alsa_rate, &dir);
+	
+   ALSA9_CHECK(snd_pcm_hw_params_set_period_size(pcm_handle, hwparams, fragsize, dir));
+   ALSA9_CHECK(snd_pcm_hw_params_set_periods(pcm_handle, hwparams, numfrags, dir));
+	
+   ALSA9_CHECK(snd_pcm_hw_params(pcm_handle, hwparams));
+	
+   ALSA9_CHECK(snd_pcm_hw_params_get_period_size(hwparams, &alsa_bufsize, &dir));
+   ALSA9_CHECK(snd_pcm_hw_params_get_periods(hwparams, &alsa_fragments, &dir));
+	
+   /* Allocate mixing buffer.  */
+   alsa_bufdata = malloc(alsa_bufsize);
+   if (!alsa_bufdata) {
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer"));
+      goto error;
+   }
+
+   /* Initialise mixer.  */
+   digi_alsa.voices = voices;
+
+   if (_mixer_init(alsa_bufsize / (alsa_bits / 8), alsa_rate,
+       alsa_stereo, ((alsa_bits == 16) ? 1 : 0),
+		 &digi_alsa.voices) != 0) {
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer"));
+      goto error;
+   }
+
+   snd_pcm_prepare(pcm_handle);
+	
+   _mix_some_samples((unsigned long) alsa_bufdata, 0, alsa_signed);
+
+   /* Add audio interrupt.  */
+   _unix_bg_man->register_func(alsa_update);
+
+   uszprintf(alsa_desc, sizeof(alsa_desc),
+	    get_config_text("Device '%s': %d bits, %s, %d bps, %s"),
+	    alsa_device, alsa_bits,
+	    uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1),
+	    alsa_rate,
+	    uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2));
+
+   digi_driver->desc = alsa_desc;
+
+   return 0;
+
+  error:
+
+   if (pcm_handle) {
+      snd_pcm_close(pcm_handle);
+      pcm_handle = NULL;
+   }
+	
+   return -1; /* error */
+}
+
+/* alsa_exit:
+ *  Shutdown ALSA driver.
+ */
+static void alsa_exit(int input)
+{
+   if (input) {
+      return;
+   }
+
+   _unix_bg_man->unregister_func(alsa_update);
+
+   free(alsa_bufdata);
+   alsa_bufdata = NULL;
+
+   _mixer_exit();
+
+   if(alsa_mixer)
+      snd_mixer_close(alsa_mixer);
+
+   snd_pcm_close(pcm_handle);
+	
+   snd_pcm_hw_params_free(hwparams);
+   snd_pcm_sw_params_free(swparams);
+}
+
+
+#else
 
 /* alsa_update:
  *  Update data.
@@ -146,13 +454,11 @@
 
    for (i = 0;  i < alsa_fragments; i++) {
       if (snd_pcm_write(pcm_handle, alsa_bufdata, alsa_bufsize) != alsa_bufsize)
-	 break;
+        break;
       _mix_some_samples((unsigned long) alsa_bufdata, 0, alsa_signed);
    }
 }
 
-
-
 /* alsa_detect:
  *  Detect driver presence.
  */
@@ -165,18 +471,18 @@
    int ret = FALSE;
 
    card = get_config_int(uconvert_ascii("sound", tmp1),
-			 uconvert_ascii("alsa_card", tmp2),
-			 snd_defaults_card());
+          uconvert_ascii("alsa_card", tmp2),
+          snd_defaults_card());
 
    device = get_config_int(uconvert_ascii("sound", tmp1),
 			   uconvert_ascii("alsa_pcmdevice", tmp2),
 			   snd_defaults_pcm_device());
 
    if (snd_pcm_open(&handle, card, device, (SND_PCM_OPEN_PLAYBACK
-					    | SND_PCM_OPEN_NONBLOCK)) == 0) {
+                   | SND_PCM_OPEN_NONBLOCK)) == 0) {
       if ((snd_pcm_info(handle, &info) == 0)
-	  && (info.flags & SND_PCM_INFO_PLAYBACK))
-	 ret = TRUE;
+          && (info.flags & SND_PCM_INFO_PLAYBACK))
+         ret = TRUE;
       
       snd_pcm_close(handle);
    }
@@ -204,20 +510,20 @@
 
    /* Load config.  */
    card = get_config_int(uconvert_ascii("sound", tmp1),
-			 uconvert_ascii("alsadigi_card", tmp2),
-			 snd_defaults_card());
+          uconvert_ascii("alsadigi_card", tmp2),
+          snd_defaults_card());
 
    device = get_config_int(uconvert_ascii("sound", tmp1),
-			   uconvert_ascii("alsadigi_pcmdevice", tmp2),
-			   snd_defaults_pcm_device());
+            uconvert_ascii("alsadigi_pcmdevice", tmp2),
+            snd_defaults_pcm_device());
 
    fragsize = get_config_int(uconvert_ascii("sound", tmp1),
-			     uconvert_ascii("alsa_fragsize", tmp2),
-			     -1);
+              uconvert_ascii("alsa_fragsize", tmp2),
+              -1);
 
    numfrags = get_config_int(uconvert_ascii("sound", tmp1),
-			     uconvert_ascii("alsa_numfrags", tmp2),
-			     ALSA_DEFAULT_NUMFRAGS);
+              uconvert_ascii("alsa_numfrags", tmp2),
+              ALSA_DEFAULT_NUMFRAGS);
 
    /* Open PCM device.  */
    if (snd_pcm_open(&pcm_handle, card, device, (SND_PCM_OPEN_PLAYBACK
@@ -366,7 +672,7 @@
    snd_pcm_close(pcm_handle);
 }
 
-
+#endif /* ALSA_05 */
 
 /* alsa_mixer_volume:
  *  Set mixer volume (0-255)
@@ -386,12 +692,21 @@
 
    return -1;
 #else
+#if defined ALSA_09
+   unsigned long left_vol = 0, right_vol = 0;
+	
+   if(alsa_mixer && alsa_mixer_elem) {
+      snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 0, &left_vol);
+      snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 1, &right_vol);
+      snd_mixer_selem_set_playback_volume(alsa_mixer_elem, 0, (int)floor(left_vol+0.5) * alsa_mixer_allegro_ratio);
+      snd_mixer_selem_set_playback_volume(alsa_mixer_elem, 1, (int)floor(right_vol+0.5) * alsa_mixer_allegro_ratio);
+   }
+#endif
+	
    return 0;
 #endif
 }
 
-
-
 #ifdef ALLEGRO_MODULE
 
 /* _module_init:
@@ -405,4 +720,3 @@
 #endif
 
 #endif
-
diff -u -r allegro-orig/src/unix/alsamidi.c allegro/src/unix/alsamidi.c
--- allegro-orig/src/unix/alsamidi.c	2003-07-20 04:45:18.000000000 -0600
+++ allegro/src/unix/alsamidi.c	2003-07-20 05:37:24.000000000 -0600
@@ -10,7 +10,7 @@
  *
  *      ALSA RawMIDI Sound driver.
  *
- *      By Tom Fjellstrom.
+ *      By Thomas Fjellstrom.
  *
  *      See readme.txt for copyright information.
  */
@@ -31,9 +31,21 @@
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
+
+#if ALLEGRO_ALSA_MAJOR_VER >= 0 && ALLEGRO_ALSA_MINOR_VER >= 9 \
+   && ALLEGRO_ALSA_SUBMINOR_VER >= 0
+	
+   #include <alsa/asoundlib.h>
+   #define ALSA_09 1
+#else
    #include <sys/asoundlib.h>
+   #define ALSA_05 1
+#endif
+
 #endif
 
+
+
 /* external interface to the ALSA rawmidi driver */
 static int alsa_rawmidi_detect(int input);
 static int alsa_rawmidi_init(int input, int voices);
@@ -71,55 +83,51 @@
  */
 static int alsa_rawmidi_detect(int input)
 {
-	int card = -1;
-	int device = -1;
-	int ret = FALSE, err;
-	char tmp1[128], tmp2[128], temp[256];
-	snd_rawmidi_t *handle = NULL;
-
-	if(input) {
-		/* Input not supported.
-		card = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_input_card", tmp2),
-				snd_defaults_rawmidi_card());
-
-		device = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_input_device", tmp2),
-				snd_defaults_rawmidi_device());
-
-		if ((err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_INPUT)) < 0) {
-			snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
-			ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
-			ret = FALSE;
-		}
-
-		snd_rawmidi_close(handle);
-		*/
-		ret = FALSE;
-
-	}
-	else {
-
-		card = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_card", tmp2),
-				snd_defaults_rawmidi_card());
-
-		device = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_device", tmp2),
-				snd_defaults_rawmidi_device());
-
-		if ((err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND)) < 0) {
-			snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
-			ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
-			ret = FALSE;
-		}
+   int ret = FALSE, err;
+   char tmp1[128], tmp2[128], temp[256];
+   snd_rawmidi_t *handle = NULL;
+#ifdef ALSA_09
+   const char *device = NULL;
+#else
+   int device = -1;
+   int card = -1;
+#endif
+	
+   if(input) {
+      ret = FALSE;
+   }
+   else {
+
+#ifdef ALSA_05
+      card = get_config_int(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_card", tmp2),
+            0);
+
+      device = get_config_int(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_device", tmp2),
+            0);
+
+      err = snd_rawmidi_open(&handle, card, device, 0);
+#else
+      device = get_config_string(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_device", tmp2),
+            "default");
+		
+      err = snd_rawmidi_open(NULL, &handle, device, 0);		
+#endif
+		
+      if (err) {
+         snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
+         ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
+         return FALSE;
+      }
       
-		snd_rawmidi_close(handle);
+      snd_rawmidi_close(handle);
 
-		ret = TRUE;
-	}
+      ret = TRUE;
+   }
 
-	return ret;	
+   return ret;	
 }
 
 /* alsa_rawmidi_init:
@@ -127,64 +135,68 @@
  */
 static int alsa_rawmidi_init(int input, int voices)
 {
-	int card = -1;
-	int device = -1;
-	int ret = -1, err;
-	char tmp1[128], tmp2[128], temp[256];
-	snd_rawmidi_info_t info;
-
-	if(input) {
-		/* Input not supported
-		card = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_input_card", tmp2),
-				snd_defaults_rawmidi_card());
-
-		device = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_input_device", tmp2),
-				snd_defaults_rawmidi_device());
-
-		if ((err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_INPUT)) < 0) {
-			snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
-			ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
-			ret = -1;
-		}
-		*/
-		ret = -1;
-
-	}
-	else {
-
-		card = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_card", tmp2),
-				snd_defaults_rawmidi_card());
-
-		device = get_config_int(uconvert_ascii("sound", tmp1),
-				uconvert_ascii("alsa_rawmidi_device", tmp2),
-				snd_defaults_rawmidi_device());
-
-		if ((err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND)) < 0) {
-			snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
-			ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
-			ret = -1;
-		}
-
-		ret = 0;
-	}
-
-	if(rawmidi_handle) {
-		snd_rawmidi_block_mode(rawmidi_handle, 1);
-		snd_rawmidi_info(rawmidi_handle, &info);
+   int ret = -1, err;
+   char tmp1[128], tmp2[128], temp[256];
+#ifdef ALSA_09
+   snd_rawmidi_info_t *info;
+   const char *device = NULL;
+#else
+   snd_rawmidi_info_t info;
+   int card = -1;
+   int device = -1;
+#endif
+
+   if(input) {
+      ret = -1;
+   }
+   else {
+
+#ifdef ALSA_09
+      device = get_config_string(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_device", tmp2),
+            0);
+		
+      err = snd_rawmidi_open(NULL, &rawmidi_handle, device, 0);
+#else
+      card = get_config_int(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_card", tmp2),
+            0);
+
+      device = get_config_int(uconvert_ascii("sound", tmp1),
+            uconvert_ascii("alsa_rawmidi_device", tmp2),
+            0);
+      err = snd_rawmidi_open(&rawmidi_handle, card, device, 0);
+#endif		
+      if (err) {
+         snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
+         ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
+         ret = -1;
+      }
+
+      ret = 0;
+   }
+
+   if(rawmidi_handle) {
+#ifdef ALSA_09
+      snd_rawmidi_nonblock(rawmidi_handle, 0);
+      snd_rawmidi_info_malloc(&info);
+      snd_rawmidi_info(rawmidi_handle, info);
+      strcpy(alsa_rawmidi_desc, snd_rawmidi_info_get_name(info));
+#else
+      snd_rawmidi_block_mode(rawmidi_handle, 1);
+      snd_rawmidi_info(rawmidi_handle, &info);
+      strcpy(alsa_rawmidi_desc, info.name);
+#endif
 
-		strcpy(alsa_rawmidi_desc, info.name);
-		midi_alsa.desc = alsa_rawmidi_desc;
+      midi_alsa.desc = alsa_rawmidi_desc;
 		
-		LOCK_VARIABLE(alsa_rawmidi_desc);
-		LOCK_VARIABLE(rawmidi_handle);
-		LOCK_VARIABLE(midi_alsa);
-		LOCK_FUNCTION(alsa_rawmidi_output);
-	}
+      LOCK_VARIABLE(alsa_rawmidi_desc);
+      LOCK_VARIABLE(rawmidi_handle);
+      LOCK_VARIABLE(midi_alsa);
+      LOCK_FUNCTION(alsa_rawmidi_output);
+   }
 	
-	return ret;	
+   return ret;	
 }
 
 /* alsa_rawmidi_exit:
@@ -192,12 +204,17 @@
  */
 static void alsa_rawmidi_exit(int input)
 {
-	if(rawmidi_handle) {
-		snd_rawmidi_output_drain(rawmidi_handle);
-		snd_rawmidi_close(rawmidi_handle);
-	}
+   if(rawmidi_handle) {
+#ifdef ALSA_09
+      snd_rawmidi_drain(rawmidi_handle);
+#else
+      snd_rawmidi_output_drain(rawmidi_handle);
+#endif
+
+      snd_rawmidi_close(rawmidi_handle);
+   }
 	
-	rawmidi_handle = NULL;
+   rawmidi_handle = NULL;
 }
 
 /* alsa_rawmidi_output:
@@ -205,27 +222,18 @@
  */
 static void alsa_rawmidi_output(int data)
 {
-	int err;
-	
-	err = snd_rawmidi_write(rawmidi_handle, &data, sizeof(char));
+   int err;
+   char temp[256];
 
+   err = snd_rawmidi_write(rawmidi_handle, &data, sizeof(char));
+   if(err) {
+      snprintf(temp, sizeof(temp), "Could not write to rawmidi port: %s", snd_strerror(err));
+      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
+   } //else
+      //snd_rawmidi_drain(rawmidi_handle);
 }
 END_OF_STATIC_FUNCTION(alsa_rawmidi_output);
 
-/* alsa_rawmidi_input:
- *		Reads MIDI data.
- * not supported...
-static INLINE int alsa_rawmidi_input(void)
-{
-	char data = 0;
-
-	if(snd_rawmidi_read(rawmidi_handle, &data, sizeof(char)) > 0)
-		return data;
-	else
-		return 0;
-}
-*/
-
 #ifdef ALLEGRO_MODULE
 
 /* _module_init:
@@ -239,4 +247,3 @@
 #endif /* ALLEGRO_MODULE */
 
 #endif /* MIDI_ALSA */
-


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/