[xiph-cvs] cvs commit: ao/src/plugins/solaris ao_solaris.c

Jack Moffitt jack at xiph.org
Sun Oct 29 16:46:44 PST 2000



jack        00/10/29 16:46:43

  Modified:    .        Makefile.am configure.in
               include/ao ao.h os_types.h.in
               src      Makefile.am ao_null.c ao_wav.c audio_out.c
  Added:       .        acinclude.m4 ao-config.in ao.m4
               src/plugins Makefile.am
               src/plugins/alsa Makefile.am ao_alsa.c
               src/plugins/esd Makefile.am ao_esd.c
               src/plugins/irix ao_irix.c
               src/plugins/oss Makefile.am ao_oss.c
               src/plugins/solaris ao_solaris.c
  Removed:     src      ao_alsa.c ao_esd.c ao_irix.c ao_oss.c ao_solaris.c
  Log:
  the long awaited ao fixes.  this hasn't been well tested.

Revision  Changes    Path
1.2       +6 -1      ao/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ao/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.am	2000/09/03 09:56:05	1.1
+++ Makefile.am	2000/10/30 00:46:39	1.2
@@ -4,7 +4,12 @@
 
 SUBDIRS = src include doc
 
-EXTRA_DIST = README AUTHORS CHANGES COPYING libao.spec
+bin_SCRIPTS = ao-config
+
+m4datadir = $(datadir)/aclocal
+m4data_DATA = ao.m4
+
+EXTRA_DIST = README AUTHORS CHANGES COPYING libao.spec ao.m4
 
 debug:
         $(MAKE) all CFLAGS="@DEBUG@"

1.4       +26 -130   ao/configure.in

Index: configure.in
===================================================================
RCS file: /usr/local/cvsroot/ao/configure.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- configure.in	2000/10/10 18:22:51	1.3
+++ configure.in	2000/10/30 00:46:39	1.4
@@ -2,6 +2,7 @@
 AC_INIT(src/audio_out.c)
 
 AM_INIT_AUTOMAKE(libao,1.0.0)
+AM_DISABLE_STATIC
 
 dnl Library versioning
 LIB_CURRENT=0
@@ -13,13 +14,15 @@
 
 AC_CANONICAL_HOST
 
+plugindir=$libdir/ao
+AC_SUBST(plugindir)
+
 dnl ====================================
 dnl Check for programs
 dnl ====================================
 
 AC_PROG_CC
 AM_PROG_LIBTOOL
-AC_PROG_CPP
 AC_PROG_RANLIB
 
 AC_SUBST(RANLIB)
@@ -64,6 +67,7 @@
         esac
 fi
 
+
 AC_SUBST(CC)
 AC_SUBST(DEBUG)
 AC_SUBST(PROFILE)
@@ -72,20 +76,10 @@
 dnl Check for libraries
 dnl ==============================
 
-dnl --- if we're on irix, check for -laudio ---
-
-case $host in
-        *-*-irix*)
-                AC_CHECK_LIB(audio, ALwritesamps)
-        ;;
-esac
-
 dnl ==============================
 dnl Checks for header files
 dnl ==============================
 
-AC_HEADER_STDC
-
 dnl ==============================
 dnl Checks for types
 dnl ==============================
@@ -106,144 +100,46 @@
 esac
 
 if test -z "$SIZE16"; then
-        AC_MSG_WARN(No 16 bit type found on this platform!)
+        AC_MSG_ERROR(No 16 bit type found on this platform!)
 fi
 if test -z "$SIZE32"; then
-        AC_MSG_WARN(No 32 bit type found on this platform!)
+        AC_MSG_ERROR(No 32 bit type found on this platform!)
 fi
 
 AC_SUBST(SIZE16)
 AC_SUBST(SIZE32)
-AC_SUBST(SIZE64)
 
-dnl =========================================
-dnl Figure out which ao_* files to compile
-dnl =========================================
-
-AC_ARG_ENABLE(oss,,,enable_oss=yes)
-AC_ARG_ENABLE(irix,,,enable_irix=yes)
-AC_ARG_ENABLE(solaris,,,enable_solaris=yes)
-AC_ARG_ENABLE(alsa,,,enable_alsa=yes)
-AC_ARG_ENABLE(esd,,,enable_esd=yes)
-AC_ARG_ENABLE(default-output,,,enable_default_output=def)
-
 dnl ======================================
 dnl Detect possible output devices 
 dnl ======================================
-
-dnl --- Initialize default variable values ---
-has_oss=no
-has_irix=no
-has_solaris=no
-has_esd=no
-has_alsa=no
-need_libossaudio=no
-
-AC_CHECK_LIB(ossaudio, main, has_libossaudio=yes, has_libossaudio=no)
-
-case $host in
-        *-*-linux*|*-openbsd*|*-freebsd*)
-		has_oss=yes;;
-	*-netbsd*)
-   	  	if test has_libossaudio = "yes"; then
-                   	has_oss=yes
-                      	need_libossaudio=yes
-              	fi;;
-        *-irix*)
-		has_irix=yes;;
-        *-solaris*)
-		has_solaris=yes;;
-esac
-
-AC_CHECK_LIB(esd, esd_play_stream, has_esd=yes)
-AC_CHECK_LIB(asound, snd_pcm_open, has_alsa=yes, has_alsa=no)
 
-dnl -- Set appropriate variables for each driver --
+dnl Check for ESD
 
-AC_MSG_CHECKING("whether to compile OSS driver")
-if test $enable_oss = "yes" && test $has_oss = "yes"; then
-	AC_MSG_RESULT("yes")
-	LIBAO_FILES="$LIBAO_FILES ao_oss.c"
-	LIBAO_FLAGS="$LIBAO_FLAGS -DAO_COMPILE_OSS"
-      	if test need_libossaudio = yes; then
-              	LIBAO_LIBS="$LIBAO_LIBS -lossaudio"
-      	fi
-	ao_default=oss
-else
-	AC_MSG_RESULT("no")
-fi
+AM_PATH_ESD(0.2.8, have_esd=yes, have_esd=no)
+AM_CONDITIONAL(HAVE_ESD,test "x$have_esd" = xyes)
 
-AC_MSG_CHECKING("whether to compile IRIX driver")
-if test $enable_irix = "yes" && test $has_irix = "yes"; then
-	AC_MSG_RESULT("yes")
-	LIBAO_FILES="$LIBAO_FILES ao_irix.c"
-	LIBAO_FLAGS="$LIBAO_FLAGS -DAO_COMPILE_IRIX"
-	ao_default=irix
-else
-	AC_MSG_RESULT("no")
-fi
+dnl Check for OSS
 
-AC_MSG_CHECKING("whether to compile Solaris driver")
-if test $enable_solaris = "yes" && test $has_solaris = "yes"; then
-	LIBAO_FILES="$LIBAO_FILES ao_solaris.c"
-	LIBAO_FLAGS="$LIBAO_FLAGS -DAO_COMPILE_SOLARIS"
-	ao_default=solaris
-else
-	AC_MSG_RESULT("no")
-fi
+AC_CHECK_HEADERS(sys/soundcard.h)
+AC_CHECK_HEADERS(machine/soundcard.h)
+AM_CONDITIONAL(HAVE_OSS,test "${ac_cv_header_sys_soundcard_h}" = "yes" || test "${ac_cv_header_machine_soundcard_h}" = "yes")
 
-AC_MSG_CHECKING("whether to compile ESD driver")
-if test $enable_esd = "yes" && test $has_esd = "yes"; then
-	AC_MSG_RESULT("yes")
-	LIBAO_LIBS="$LIBAO_LIBS -lesd"
-	LIBAO_FLAGS="$LIBAO_FLAGS -DAO_COMPILE_ESD"
-	LIBAO_FILES="$LIBAO_FILES ao_esd.c"
-else
-	AC_MSG_RESULT("no")
-fi
+dnl Check for ALSA
 
-AC_MSG_CHECKING("whether to compile ALSA driver")
-if test $enable_alsa = "yes" && test $has_alsa = "yes"; then
-	AC_MSG_RESULT("yes")
-	LIBAO_FLAGS="$LIBAO_FLAGS -DAO_COMPILE_ALSA"
-	LIBAO_FILES="$LIBAO_FILES ao_alsa.c"
-	LIBAO_LIBS="$LIBAO_LIBS -lasound"
-else
-	AC_MSG_RESULT("no")
-fi
-
-dnl -- Set the default device
+AC_CHECK_LIB(asound, snd_pcm_open, has_alsa=yes, has_alsa=no)
+AM_CONDITIONAL(HAVE_ALSA,test "x$have_alsa" = xyes)
 
-if test $enable_default_output != "def"; then
-	ao_default=$enable_default_output
-fi
+dnl Check for IRIX
 
-case $ao_default in
-	null)
-		AO_DEFAULT_DEF=AO_NULL;;
-	oss)
-		AO_DEFAULT_DEF=AO_OSS;;
-	irix)
-		AO_DEFAULT_DEF=AO_IRIX;;
-	solaris)
-		AO_DEFAULT_DEF=AO_SOLARIS;;
-	esd)
-		AO_DEFAULT_DEF=AO_ESD;;
-	alsa)
-		AO_DEFAULT_DEF=AO_ALSA;;
-	wav)
-		AO_DEFAULT_DEF=AO_WAV;;
-	*)
-		dnl Make the default output device AO_NULL
-		ao_default=null
-		AO_DEFAULT_DEF=AO_NULL;;
+case $host in
+        *-*-irix*)
+                AC_CHECK_LIB(audio, ALwritesamps, have_irix=yes, have_irix=no)
+        ;;
 esac
-
-AC_MSG_RESULT("setting default output device... $ao_default")
+AM_CONDITIONAL(HAVE_IRIX,test "x$have_irix" = xyes)
 
-CFLAGS="$LIBAO_FLAGS -DAO_DEFAULT=$AO_DEFAULT_DEF"
+AM_CONDITIONAL(HAVE_SOLARIS,test "x$have_solaris" = xyes)
 
-AC_SUBST(LIBAO_FILES)
-AC_SUBST(LIBAO_LIBS)
+CFLAGS="$CFLAGS -DAO_PLUGIN_PATH=\\\"$plugindir\\\""
 
-AC_OUTPUT(Makefile src/Makefile doc/Makefile include/Makefile include/ao/Makefile include/ao/os_types.h include/ao/ao_libs.inc)
+AC_OUTPUT(Makefile src/Makefile doc/Makefile include/Makefile include/ao/Makefile include/ao/os_types.h include/ao/ao_libs.inc src/plugins/Makefile src/plugins/esd/Makefile src/plugins/oss/Makefile src/plugins/alsa/Makefile ao-config)

1.1                  ao/acinclude.m4

Index: acinclude.m4
===================================================================
# Configure paths for ESD
# Manish Singh    98-9-30
# stolen back from Frank Belew
# stolen from Manish Singh
# Shamelessly stolen from Owen Taylor

dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS
dnl
AC_DEFUN(AM_PATH_ESD,
[dnl 
dnl Get the cflags and libraries from the esd-config script
dnl
AC_ARG_WITH(esd-prefix,[  --with-esd-prefix=PFX   Prefix where ESD is installed (optional)],
            esd_prefix="$withval", esd_prefix="")
AC_ARG_WITH(esd-exec-prefix,[  --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)],
            esd_exec_prefix="$withval", esd_exec_prefix="")
AC_ARG_ENABLE(esdtest, [  --disable-esdtest       Do not try to compile and run a test ESD program],
                    , enable_esdtest=yes)

  if test x$esd_exec_prefix != x ; then
     esd_args="$esd_args --exec-prefix=$esd_exec_prefix"
     if test x${ESD_CONFIG+set} != xset ; then
        ESD_CONFIG=$esd_exec_prefix/bin/esd-config
     fi
  fi
  if test x$esd_prefix != x ; then
     esd_args="$esd_args --prefix=$esd_prefix"
     if test x${ESD_CONFIG+set} != xset ; then
        ESD_CONFIG=$esd_prefix/bin/esd-config
     fi
  fi

  AC_PATH_PROG(ESD_CONFIG, esd-config, no)
  min_esd_version=ifelse([$1], ,0.2.7,$1)
  AC_MSG_CHECKING(for ESD - version >= $min_esd_version)
  no_esd=""
  if test "$ESD_CONFIG" = "no" ; then
    no_esd=yes
  else
    ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags`
    ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs`

    esd_major_version=`$ESD_CONFIG $esd_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
    esd_minor_version=`$ESD_CONFIG $esd_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
    esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
    if test "x$enable_esdtest" = "xyes" ; then
      ac_save_CFLAGS="$CFLAGS"
      ac_save_LIBS="$LIBS"
      CFLAGS="$CFLAGS $ESD_CFLAGS"
      LIBS="$LIBS $ESD_LIBS"
dnl
dnl Now check if the installed ESD is sufficiently new. (Also sanity
dnl checks the results of esd-config to some extent
dnl
      rm -f conf.esdtest
      AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <esd.h>

char*
my_strdup (char *str)
{
  char *new_str;
  
  if (str)
    {
      new_str = malloc ((strlen (str) + 1) * sizeof(char));
      strcpy (new_str, str);
    }
  else
    new_str = NULL;
  
  return new_str;
}

int main ()
{
  int major, minor, micro;
  char *tmp_version;

  system ("touch conf.esdtest");

  /* HP/UX 9 (%@#!) writes to sscanf strings */
  tmp_version = my_strdup("$min_esd_version");
  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
     printf("%s, bad version string\n", "$min_esd_version");
     exit(1);
   }

   if (($esd_major_version > major) ||
      (($esd_major_version == major) && ($esd_minor_version > minor)) ||
      (($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro)))
    {
      return 0;
    }
  else
    {
      printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version);
      printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro);
      printf("*** best to upgrade to the required version.\n");
      printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n");
      printf("*** to point to the correct copy of esd-config, and remove the file\n");
      printf("*** config.cache before re-running configure\n");
      return 1;
    }
}

],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
       CFLAGS="$ac_save_CFLAGS"
       LIBS="$ac_save_LIBS"
     fi
  fi
  if test "x$no_esd" = x ; then
     AC_MSG_RESULT(yes)
     ifelse([$2], , :, [$2])     
  else
     AC_MSG_RESULT(no)
     if test "$ESD_CONFIG" = "no" ; then
       echo "*** The esd-config script installed by ESD could not be found"
       echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in"
       echo "*** your path, or set the ESD_CONFIG environment variable to the"
       echo "*** full path to esd-config."
     else
       if test -f conf.esdtest ; then
        :
       else
          echo "*** Could not run ESD test program, checking why..."
          CFLAGS="$CFLAGS $ESD_CFLAGS"
          LIBS="$LIBS $ESD_LIBS"
          AC_TRY_LINK([
#include <stdio.h>
#include <esd.h>
],      [ return 0; ],
        [ echo "*** The test program compiled, but did not run. This usually means"
          echo "*** that the run-time linker is not finding ESD or finding the wrong"
          echo "*** version of ESD. If it is not finding ESD, you'll need to set your"
          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
          echo "*** is required on your system"
          echo "***"
          echo "*** If you have an old version installed, it is best to remove it, although"
          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
        [ echo "*** The test program failed to compile or link. See the file config.log for the"
          echo "*** exact error that occured. This usually means ESD was incorrectly installed"
          echo "*** or that you have moved ESD since it was installed. In the latter case, you"
          echo "*** may want to edit the esd-config script: $ESD_CONFIG" ])
          CFLAGS="$ac_save_CFLAGS"
          LIBS="$ac_save_LIBS"
       fi
     fi
     ESD_CFLAGS=""
     ESD_LIBS=""
     ifelse([$3], , :, [$3])
  fi
  AC_SUBST(ESD_CFLAGS)
  AC_SUBST(ESD_LIBS)
  rm -f conf.esdtest
])

1.1                  ao/ao-config.in

Index: ao-config.in
===================================================================
#!/bin/sh

# ao-config
#
# Tool for retrieving the library/include paths ao was compiled with.
#
# Written 29 October 2000 by Jack Moffitt <jack at icecast.org>
# Based *HEAVILY* on xmms-config from the XMMS package
# which was
# Based *HEAVILY* on gtk-config from the GTK+ library package.
#
# This work is released under the GNU GPL, version 2 or later.

prefix="@prefix@"
exec_prefix="@exec_prefix@"
exec_prefix_set=no
data_dir="@datadir@/@PACKAGE@"

version="@VERSION@"
include_dir="@includedir@"
ao_include_dir="@includedir@/@PACKAGE@"
lib_dir="@libdir@"

esd_cflags="@ESD_CFLAGS@"
esd_libs="@ESD_LIBS@"

plugin_dir="@plugindir@"

usage()
{
    cat <<EOF
Usage: ao-config [OPTIONS]
Options:
    [--prefix[=DIR]]
    [--version]
    [--libs]
    [--cflags]
    [--plugin-dir]

EOF
    exit $1
}

if test $# -eq 0; then
    usage 1 1>&2
fi

while test $# -gt 0; do
    case "$1" in
        -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
        *) optarg= ;;
    esac

    case $1 in
        --prefix=*)
            prefix=$optarg
            ;;

        --prefix)
            echo_prefix=yes
            ;;

        --version)
            echo $version
            ;;

        --cflags)
            echo_cflags=yes
            ;;

        --libs)
            echo_libs=yes
            ;;

        --plugin-dir)
            echo_plugin_dir=yes
            ;;

        *)
            usage 1 1>&2
            ;;
    esac
  shift
done

if test "$echo_prefix" = "yes"; then
    echo $prefix
fi

if test "$echo_exec_prefix" = "yes"; then
    echo $exec_prefix
fi

if test "$include_dir" != "/usr/include"; then
    cflags="-I$include_dir $esd_cflags"
else
    cflags="$esd_cflags"
fi

if test "$lib_dir" != "/usr/lib"; then
    libs="-L$lib_dir $esd_libs -lao"
else
    libs="$esd_libs -lao"
fi

if test "$echo_cflags" = "yes"; then
    echo $cflags
fi

if test "$echo_libs" = "yes"; then
    echo $libs
fi

if test "$echo_plugin_dir" = "yes"; then
    echo $plugin_dir
fi

1.1                  ao/ao.m4

Index: ao.m4
===================================================================
# Configure paths for libao
# Jack Moffitt <jack at icecast.org> 10-21-2000
# Shamelessly stolen from Owen Taylor and Manish Singh

dnl AM_PATH_AO([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for libao, and define AO_CFLAGS and AO_LIBS
dnl
AC_DEFUN(AM_PATH_AO,
[dnl 
dnl Get the cflags and libraries from the ao-config script
dnl
AC_ARG_WITH(ao-prefix,[  --with-ao-prefix=PFX   Prefix where libao is installed (optional)], ao_prefix="$withval", ao_prefix="")
AC_ARG_ENABLE(aotest, [  --disable-aotest       Do not try to compile and run a test ao program],, enable_aotest=yes)

  if test x$ao_prefix != x ; then
     ao_args="$ao_args --prefix=$ao_prefix"
     if test x${AO_CONFIG+set} != xset ; then
        AO_CONFIG=$ao_prefix/bin/ao-config
     fi
  fi

  AC_PATH_PROG(AO_CONFIG, ao-config, no)
  min_ao_version=ifelse([$1], ,1.0.0,$1)
  AC_MSG_CHECKING(for ao - version >= $min_ao_version)
  no_ao=""
  if test "$AO_CONFIG" = "no" ; then
    no_ao=yes
  else
    AO_CFLAGS=`$AO_CONFIG $aoconf_args --cflags`
    AO_LIBS=`$AO_CONFIG $aoconf_args --libs`

    ao_major_version=`$AO_CONFIG $ao_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
    ao_minor_version=`$AO_CONFIG $ao_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
    ao_micro_version=`$AO_CONFIG $ao_config_args --version | \
           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
    if test "x$enable_aotest" = "xyes" ; then
      ac_save_CFLAGS="$CFLAGS"
      ac_save_LIBS="$LIBS"
      CFLAGS="$CFLAGS $AO_CFLAGS"
      LIBS="$LIBS $AO_LIBS"
dnl
dnl Now check if the installed ao is sufficiently new. (Also sanity
dnl checks the results of ao-config to some extent
dnl
      rm -f conf.aotest
      AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ao/ao.h>

int main ()
{
  system("touch conf.aotest");
  return 0;
}

],, no_ao=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
       CFLAGS="$ac_save_CFLAGS"
       LIBS="$ac_save_LIBS"
     fi
  fi
  if test "x$no_ao" = x ; then
     AC_MSG_RESULT(yes)
     ifelse([$2], , :, [$2])     
  else
     AC_MSG_RESULT(no)
     if test "$AO_CONFIG" = "no" ; then
       echo "*** The ao-config script installed by ao could not be found"
       echo "*** If ao was installed in PREFIX, make sure PREFIX/bin is in"
       echo "*** your path, or set the AO_CONFIG environment variable to the"
       echo "*** full path to ao-config."
     else
       if test -f conf.aotest ; then
        :
       else
          echo "*** Could not run ao test program, checking why..."
          CFLAGS="$CFLAGS $AO_CFLAGS"
          LIBS="$LIBS $AO_LIBS"
          AC_TRY_LINK([
#include <stdio.h>
#include <ao/ao.h>
],      [ return 0; ],
        [ echo "*** The test program compiled, but did not run. This usually means"
          echo "*** that the run-time linker is not finding ao or finding the wrong"
          echo "*** version of ao. If it is not finding ao, you'll need to set your"
          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
          echo "*** is required on your system"
          echo "***"
          echo "*** If you have an old version installed, it is best to remove it, although"
          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
        [ echo "*** The test program failed to compile or link. See the file config.log for the"
          echo "*** exact error that occured. This usually means ao was incorrectly installed"
          echo "*** or that you have moved ao since it was installed. In the latter case, you"
          echo "*** may want to edit the ao-config script: $AO_CONFIG" ])
          CFLAGS="$ac_save_CFLAGS"
          LIBS="$ac_save_LIBS"
       fi
     fi
     AO_CFLAGS=""
     AO_LIBS=""
     ifelse([$3], , :, [$3])
  fi
  AC_SUBST(AO_CFLAGS)
  AC_SUBST(AO_LIBS)
  rm -f conf.aotest
])

1.5       +34 -46    ao/include/ao/ao.h

Index: ao.h
===================================================================
RCS file: /usr/local/cvsroot/ao/include/ao/ao.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ao.h	2000/10/10 18:22:52	1.4
+++ ao.h	2000/10/30 00:46:40	1.5
@@ -1,11 +1,12 @@
 /*
  *
- *  audio_out.h 
+ *  ao.h 
  *    
  *	Original Copyright (C) Aaron Holtzman - May 1999
  *      Modifications Copyright (C) Stan Seibert - July 2000
+ *      More Modifications Copyright (C) Jack Moffitt - October 2000
  *
- *  This file is part of libao, a cross-platform library.  See
+ *  This file is part of libao, a cross-platform audio outputlibrary.  See
  *  README for a history of this source code.
  *
  *  libao is free software; you can redistribute it and/or modify
@@ -23,9 +24,10 @@
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.	
  *
  */
+#ifndef __AO_H__
+#define __AO_H__
 
 #include <stdlib.h>
-
 #include "os_types.h"
 
 /* --- Structures --- */
@@ -36,8 +38,7 @@
         struct ao_option_s *next;
 } ao_option_t;
 
-typedef struct ao_info_s
-{
+typedef struct ao_info_s {
         /* driver name (Ex: "OSS Audio driver") */
         const char *name;
         /* short name (for config strings) (Ex: "oss") */
@@ -50,59 +51,46 @@
 
 typedef void ao_internal_t;
 
-typedef struct ao_functions_s
-{
-	ao_info_t* (*get_driver_info) (void);
-	ao_internal_t*     (*open)  (uint_32 bits, uint_32 rate, 
-				     uint_32 channels, ao_option_t *options);
-	void             (*play)  (ao_internal_t *state, 
-				   void* output_samples, uint_32 num_bytes);
-	void             (*close) (ao_internal_t *state);
+typedef struct ao_functions_s {
+	ao_info_t *(*get_driver_info)(void);
+	ao_internal_t *(*open)(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options);
+	void (*play)(ao_internal_t *state, void* output_samples, uint_32 num_bytes);
+	void (*close)(ao_internal_t *state);
 } ao_functions_t;
 
-typedef struct ao_device_s
-{
+typedef struct ao_device_s {
         ao_functions_t *funcs;
         ao_internal_t *state;
 } ao_device_t;
 
 
 
-/* --- Driver id numbers --- */
+/* --- Standard driver_id numbers --- */
 
 #define AO_NULL     0
-
-#define AO_OSS      1
-#define AO_IRIX     2
-#define AO_SOLARIS  3
-#define AO_WIN32    4
-#define AO_BEOS     5
-#define AO_ESD      6
-#define AO_ALSA     7
-
-#define AO_WAV      10
-#define AO_RAW      11
-
-/* Total number of drivers */
-#define AO_DRIVERS 12
-
+#define AO_RAW      1
+#define AO_WAV      2
 
 /* --- Functions --- */
-
-int ao_get_driver_id (const char *short_name);
-
-ao_info_t *ao_get_driver_info (int driver_id);
-
-ao_device_t *ao_open (int driver_id, uint_32 bits, uint_32 rate, uint_32 channels, 
-	     ao_option_t *options);
-
-void ao_play (ao_device_t *device, void* output_samples, uint_32 num_bytes);
-
-void ao_close (ao_device_t *device);
 
-/* Returns 1 if options successfully appended, 0 if error */
-int ao_append_option (ao_option_t **options, const char* op_str);
+/* library init/shutdown */
+void ao_initialize(void);
+void ao_shutdown(void);
+
+/* driver information */
+int ao_get_driver_id(const char *short_name);
+ao_info_t *ao_get_driver_info(int driver_id);
+
+/* driver options */
+int ao_append_options(ao_option_t **options, const char *op_str);
+void ao_free_options(ao_option_t *options);
+
+/* the meat: open/play/close */
+ao_device_t *ao_open(int driver_id, uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options);
+void ao_play(ao_device_t *device, void* output_samples, uint_32 num_bytes);
+void ao_close(ao_device_t *device);
 
-void ao_free_options (ao_option_t* options);
+/* misc functions */
+int ao_is_big_endian(void);
 
-int ao_is_big_endian();
+#endif  /* __AO_H__ */

1.2       +2 -2      ao/include/ao/os_types.h.in

Index: os_types.h.in
===================================================================
RCS file: /usr/local/cvsroot/ao/include/ao/os_types.h.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- os_types.h.in	2000/09/03 09:56:05	1.1
+++ os_types.h.in	2000/10/30 00:46:40	1.2
@@ -1,11 +1,11 @@
 /*
  *
- *  config.h
+ *  os_types.h
  *
  *      Original Copyright (C) Aaron Holtzman - May 1999
  *      Modifications Copyright (C) Stan Seibert - July 2000
  *
- *  This file is part of libao, a cross-platform library.  See
+ *  This file is part of libao, a cross-platform audio output library.  See
  *  README for a history of this source code.
  *
  *  libao is free software; you can redistribute it and/or modify

1.4       +2 -4      ao/src/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ao/src/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Makefile.am	2000/09/30 01:16:14	1.3
+++ Makefile.am	2000/10/30 00:46:41	1.4
@@ -1,16 +1,14 @@
 ## Process this file with automake to produce Makefile.in
 
 AUTOMAKE_OPTIONS = foreign
+SUBDIRS = plugins
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include
 
 lib_LTLIBRARIES = libao.la
 
-#libao_la_SOURCES = audio_out.c @LIBAO_FILES@
-libao_la_SOURCES = audio_out.c ao_oss.c ao_wav.c ao_null.c
+libao_la_SOURCES = audio_out.c ao_wav.c ao_null.c
 libao_la_LDFLAGS = -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@
-
-EXTRA_libao_la_SOURCES = ao_alsa.c ao_irix.c ao_oss.c ao_wav.c ao_esd.c ao_null.c ao_solaris.c audio_out.c
 
 
 debug:

1.2       +18 -22    ao/src/ao_null.c

Index: ao_null.c
===================================================================
RCS file: /usr/local/cvsroot/ao/src/ao_null.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ao_null.c	2000/09/03 09:56:05	1.1
+++ ao_null.c	2000/10/30 00:46:41	1.2
@@ -5,7 +5,7 @@
  *      Original Copyright (C) Aaron Holtzman - May 1999
  *      Modifications Copyright (C) Stan Seibert - July 2000
  *
- *  This file is part of libao, a cross-platform library.  See
+ *  This file is part of libao, a cross-platform audio output library.  See
  *  README for a history of this source code.
  *
  *  libao is free software; you can redistribute it and/or modify
@@ -27,59 +27,55 @@
 #include <stdio.h>
 #include <ao/ao.h>
 
-typedef struct ao_null_internal_s
-{
+typedef struct ao_null_internal_s {
         unsigned long byte_counter;
 } ao_null_internal_t;
 
-static ao_info_t ao_null_info =
-{
+static ao_info_t ao_null_info = {
         "Null output",
         "null",
         "Aaron Holtzman <aholtzma at ess.engr.uvic.ca>",
-	""
+	"This plugin does nothing"
 };
 
-static ao_internal_t*
-ao_null_open (uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
+static ao_internal_t *ao_null_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
 {
         ao_null_internal_t *state;
 
         state = malloc(sizeof(ao_null_internal_t));
 
-	if (state != NULL)
-	{
+	if (state != NULL) {
                 state->byte_counter = 0;
                 return state;
-	}
-	else
+	} else {
                 return NULL;
+	}
+
+	return NULL;
 }
 
-static void
-ao_null_close (ao_internal_t *state)
+static void ao_null_close(ao_internal_t *state)
 {
+        /* why would we print in a lib :)
         fprintf(stderr, "ao_null: %ld bytes sent to null device.\n",
                 ((ao_null_internal_t *) state)->byte_counter);
+	*/
+	if (state) free(state);
 }
 
-static void
-ao_null_play (ao_internal_t *state, void* output_samples, uint_32 num_bytes)
+static void ao_null_play(ao_internal_t *state, void* output_samples, uint_32 num_bytes)
 {
-	((ao_null_internal_t *) state)->byte_counter += num_bytes;
+	((ao_null_internal_t *)state)->byte_counter += num_bytes;
 }
 
-static ao_info_t*
-ao_null_get_driver_info (void)
+static ao_info_t *ao_null_get_driver_info(void)
 {
         return &ao_null_info;
 }
 
-ao_functions_t ao_null = 
-{
+ao_functions_t ao_null = {
         ao_null_get_driver_info,
         ao_null_open,
         ao_null_play,
         ao_null_close
 };
-

1.4       +35 -60    ao/src/ao_wav.c

Index: ao_wav.c
===================================================================
RCS file: /usr/local/cvsroot/ao/src/ao_wav.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ao_wav.c	2000/09/30 01:16:15	1.3
+++ ao_wav.c	2000/10/30 00:46:41	1.4
@@ -5,7 +5,7 @@
  *      Original Copyright (C) Aaron Holtzman - May 1999
  *      Modifications Copyright (C) Stan Seibert - July 2000
  *
- *  This file is part of libao, a cross-platform library.  See
+ *  This file is part of libao, a cross-platform audio output library.  See
  *  README for a history of this source code.
  *
  *  libao is free software; you can redistribute it and/or modify
@@ -31,7 +31,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <signal.h>
-
 #include <ao/ao.h>
 
 #define WAVE_FORMAT_PCM  0x0001
@@ -51,11 +50,10 @@
 
 #define DEFAULT_SWAP_BUFFER_SIZE 2048
 
-struct riff_struct 
-{
-  unsigned char id[4];   /* RIFF */
-  unsigned int len;
-  unsigned char wave_id[4]; /* WAVE */
+struct riff_struct {
+	unsigned char id[4];   /* RIFF */
+	unsigned int len;
+	unsigned char wave_id[4]; /* WAVE */
 };
 
 
@@ -89,7 +87,7 @@
         "WAV file output",
         "wav",
         "Aaron Holtzman <aholtzma at ess.engr.uvic.ca>",
-	""
+	"Sends output to a .wav file"
 };
 
 typedef struct ao_wav_internal_s
@@ -118,13 +116,11 @@
 static void signal_handler(int sig);
 
 
-static void
-ao_wav_parse_options(ao_wav_internal_t *state, ao_option_t *options)
+static void ao_wav_parse_options(ao_wav_internal_t *state, ao_option_t *options)
 {
         state->output_file = NULL;
 
-	while (options)
-	{
+	while (options) {
                 if (!strcmp(options->key, "file"))
                         state->output_file = strdup(options->value);
                 
@@ -135,8 +131,7 @@
                 state->output_file = strdup("output.wav");
 }
 
-static ao_internal_t*
-ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
+static ao_internal_t *ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
 {
         ao_wav_internal_t *state;
         unsigned char buf[WAV_HEADER_LEN];
@@ -144,8 +139,7 @@
         memset(buf, 0, WAV_HEADER_LEN);
 
         state = malloc(sizeof(ao_wav_internal_t));
-	if (state == NULL)
-	{
+	if (state == NULL) {
                 fprintf(stderr, "ao_wav: Could not allocate state memory.\n");
                 goto ERR;
         }
@@ -153,13 +147,11 @@
         // Grab options here
         ao_wav_parse_options(state, options);
         state->byte_swap = (bits == 16) && (ao_is_big_endian());
-	if (state->byte_swap)
-	{
+	if (state->byte_swap) {
                 state->buffer_size = DEFAULT_SWAP_BUFFER_SIZE;
                 state->swap_buffer = calloc(sizeof(char), state->buffer_size);
                
-		if (state->swap_buffer == NULL)
-		{
+		if (state->swap_buffer == NULL) {
                         fprintf(stderr, "ao_wav: Could not allocate byte-swapping buffer.\n");
                         goto ERR;
                 }
@@ -167,8 +159,7 @@
                 
         state->fd=open(state->output_file,O_WRONLY | O_TRUNC | O_CREAT, 0644);
 
-	if(state->fd < 0) 
-	{
+	if(state->fd < 0) {
                 fprintf(stderr,"%s: Opening audio output %s\n", strerror(errno), state->output_file);
                 goto ERR;
         }
@@ -181,21 +172,17 @@
         state->wave.common.wBitsPerSample = bits;
         state->wave.common.dwSamplesPerSec = rate;
 
-	if (write(state->fd, buf, WAV_HEADER_LEN) != WAV_HEADER_LEN) 
-	{
+	if (write(state->fd, buf, WAV_HEADER_LEN) != WAV_HEADER_LEN) {
                 fprintf(stderr,"failed to write wav-header: %s\n", strerror(errno));
                 goto ERR;
         }
 
-	if (last == NULL) 
-	{
+	if (last == NULL) {
                 // Empty list, install our signal handler only once
                 old_sig = signal(SIGINT,signal_handler);		
 
                 last = states = malloc(sizeof(ao_wav_state_list_t));
-	}
-	else
-	{
+	} else {
                 last->next = malloc(sizeof(ao_wav_state_list_t));
                 last = last->next;
         }
@@ -205,7 +192,6 @@
 
         return state;
 
-
 ERR:
         if(state->fd >= 0) { close(state->fd); }
         return NULL;
@@ -215,44 +201,39 @@
 /*
  * play the sample to the already opened file descriptor
  */
-static void
-ao_wav_play(ao_internal_t *state, void *output_samples, uint_32 num_bytes)
+static void ao_wav_play(ao_internal_t *state, void *output_samples, uint_32 num_bytes)
 {
         int i;
-	ao_wav_internal_t *s = (ao_wav_internal_t *) state;
+	ao_wav_internal_t *s = (ao_wav_internal_t *)state;
 
         /* Swap all of the bytes if things are not little_endian */
-	if (s->byte_swap)
-	{
+	if (s->byte_swap) {
                 /* Resize buffer larger if needed */
-		if (num_bytes > s->buffer_size)
-		{
+		if (num_bytes > s->buffer_size) {
                         s->swap_buffer = realloc(s->swap_buffer, sizeof(char)*num_bytes);
                         if (s->swap_buffer == NULL) {
                                 fprintf(stderr, "ao_wav: Could not resize swap buffer.\n");
                                 return;
-			}
-			else
+			} else {
                                 s->buffer_size = num_bytes;
+			}
                 }
 
                 /* Swap the bytes into the swap buffer (so we don't
                  mess up the output_samples buffer) */
-		for(i = 0; i < num_bytes/2; i+=2)
-		{
+		for(i = 0; i < num_bytes/2; i+=2) {
                         s->swap_buffer[i]   = ((char *) output_samples)[i+1];
                         s->swap_buffer[i+1] = ((char *) output_samples)[i];
                 }
 
                 write(s->fd, s->swap_buffer, num_bytes );
-	}
-	else    /* Otherwise just write the output buffer directly */
+	} else {
+		/* Otherwise just write the output buffer directly */
                 write(s->fd, output_samples, num_bytes );
+	}
 }
-
 
-static void
-ao_wav_close(ao_internal_t *state)
+static void ao_wav_close(ao_internal_t *state)
 {
         unsigned char buf[WAV_HEADER_LEN];
 
@@ -263,20 +244,18 @@
         /* Find how long our file is in total, including header */
         size = lseek(s->fd, 0, SEEK_CUR);
 
-  if (size < 0) 
-	{
+	if (size < 0) {
                 fprintf(stderr,"lseek failed - wav-header is corrupt\n");
                 goto ERR;
         }
 
-  /* Rewind file */
-	if (lseek(s->fd, 0, SEEK_SET) < 0) 
-	{
+	/* Rewind file */
+	if (lseek(s->fd, 0, SEEK_SET) < 0) {
                 fprintf(stderr,"rewind failed - wav-header is corrupt\n");
                 goto ERR;
         }
 
-	// Fill out our wav-header with some information. 
+	/* Fill out our wav-header with some information. */
 
         strncpy(s->wave.riff.id, "RIFF",4);
         s->wave.riff.len = size - 8;
@@ -311,8 +290,7 @@
         strncpy(buf+36, s->wave.data.id, 4);
         WRITE_U32(buf+40, s->wave.data.len);
 
-	if (write(s->fd, buf, WAV_HEADER_LEN) < WAV_HEADER_LEN) 
-	{
+	if (write(s->fd, buf, WAV_HEADER_LEN) < WAV_HEADER_LEN) {
                 fprintf(stderr,"wav-header write failed -- file is corrupt\n");
                 goto ERR;
         }
@@ -322,20 +300,17 @@
         free(s);
 }
 
-static ao_info_t*
-ao_wav_get_driver_info(void)
+static ao_info_t *ao_wav_get_driver_info(void)
 {
         return &ao_wav_info;
 }
 
 
-static 
-void signal_handler(int sig)
+static void signal_handler(int sig)
 {
         ao_wav_state_list_t *temp = states;
         
-	while (states)
-	{
+	while (states) {
                 ao_wav_close(states->state);
                 temp = states;
                 states = states->next;

1.4       +182 -122  ao/src/audio_out.c

Index: audio_out.c
===================================================================
RCS file: /usr/local/cvsroot/ao/src/audio_out.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- audio_out.c	2000/09/30 01:16:15	1.3
+++ audio_out.c	2000/10/30 00:46:41	1.4
@@ -5,7 +5,7 @@
  *      Original Copyright (C) Aaron Holtzman - May 1999
  *      Modifications Copyright (C) Stan Seibert - July 2000
  *
- *  This file is part of libao, a cross-platform library.  See
+ *  This file is part of libao, a cross-platform audio output library.  See
  *  README for a history of this source code.
  *
  *  libao is free software; you can redistribute it and/or modify
@@ -27,113 +27,154 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
 #include <ao/ao.h>
 
-/* --- Function Tables --- */
-
-extern ao_functions_t ao_null;
-
-/* Okay, so this is messy.  I'm open to ideas of how to clean this
-   up.  - Stan */
-
-#ifdef AO_COMPILE_OSS
-extern ao_functions_t ao_oss;
-#define AO_FUNC_OSS &ao_oss
-#else
-#define AO_FUNC_OSS NULL
+/* These should have been set by the Makefile */
+#ifndef AO_DEFAULT
+#define AO_DEFAULT AO_NULL
 #endif
-
-#ifdef AO_COMPILE_IRIX
-extern ao_functions_t ao_irix;
-#define AO_FUNC_IRIX &ao_irix
-#else
-#define AO_FUNC_IRIX NULL
+#ifndef AO_PLUGIN_PATH
+#define AO_PLUGIN_PATH "/usr/local/lib/ao"
 #endif
-
-#ifdef AO_COMPILE_SOLARIS
-extern ao_functions_t ao_solaris;
-#define AO_FUNC_SOLARIS &ao_solaris
-#else
-#define AO_FUNC_SOLARIS NULL
+#ifndef SHARED_LIB_EXT
+#define SHARED_LIB_EXT ".so"
 #endif
 
-#ifdef AO_COMPILE_WIN32
-extern ao_functions_t ao_win32;
-#define AO_FUNC_WIN32 &ao_win32
-#else
-#define AO_FUNC_WIN32 NULL
-#endif
+/* --- Driver Table --- */
 
-#ifdef AO_COMPILE_BEOS
-extern ao_functions_t ao_beos;
-#define AO_FUNC_BEOS &ao_beos
-#else
-#define AO_FUNC_BEOS NULL
-#endif
+typedef struct driver_tree_s {
+	ao_functions_t *functions;
+	void *handle;
+	struct driver_tree_s *next;
+} driver_tree_t;
 
-#ifdef AO_COMPILE_ESD
-extern ao_functions_t ao_esd;
-#define AO_FUNC_ESD &ao_esd
-#else
-#define AO_FUNC_ESD NULL
-#endif
+extern ao_functions_t ao_null;
+extern ao_functions_t ao_wav;
 
-#ifdef AO_COMPILE_ALSA
-extern ao_functions_t ao_alsa;
-#define AO_FUNC_ALSA &ao_alsa
-#else
-#define AO_FUNC_ALSA NULL
-#endif
+driver_tree_t *driver_head = NULL;
 
-extern ao_functions_t ao_wav;
+driver_tree_t *_get_plugin(char *plugin_file)
+{
+	driver_tree_t *dt;
+	void *handle;
+	
+	handle = dlopen(plugin_file, RTLD_NOW);
+	if (handle) {
+		dt = (driver_tree_t *)malloc(sizeof(driver_tree_t));
+		if (!dt) return NULL;
 
+		dt->handle = handle;
+		
+		dt->functions = (ao_functions_t *)malloc(sizeof(ao_functions_t));
+		if (!(dt->functions)) {
+			free(dt);
+			return NULL;
+		}
 
+		dt->functions->get_driver_info = dlsym(dt->handle, "get_driver_info");
+		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
+		dt->functions->open = dlsym(dt->handle, "open");
+		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
+		dt->functions->play = dlsym(dt->handle, "play");
+		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
+		dt->functions->close = dlsym(dt->handle, "close");
+		if (dlerror()) { free(dt->functions); free(dt); return NULL; }
+	} else {
+		return NULL;
+	}
 
-/* --- Driver Table --- */
+	return dt;
+}
 
-ao_functions_t* ao_drivers[AO_DRIVERS] = 
+void ao_initialize(void)
 {
-	&ao_null,        /* 0: Null Device */
-        AO_FUNC_OSS,     /* 1: Linux, *BSD */ 
-	AO_FUNC_IRIX,    /* 2: IRIX */
-	AO_FUNC_SOLARIS, /* 3: Solaris */
-	AO_FUNC_WIN32,   /* 4: Win32 */
-	AO_FUNC_BEOS,    /* 5: BeOS */
-	AO_FUNC_ESD,     /* 6: EsounD */
-	AO_FUNC_ALSA,    /* 7: ALSA */
-	NULL,            /* 8: Unassigned */
-	NULL,            /* 9: Unassigned */
-	&ao_wav,         /* 10: .WAV output */
-	NULL,            /* 11: RAW output */
-};
+	driver_tree_t *dnull;
+	driver_tree_t *dwav;
+	driver_tree_t *plugin;
+	driver_tree_t *driver;
+	DIR *plugindir;
+	struct dirent *plugin_dirent;
+	char *ext;
+	struct stat statbuf;
+	void *plughand;
+	char fullpath[NAME_MAX];
+
+	if (driver_head == NULL) {
+		/* insert the null and wav drivers into the tree */
+		dnull = (driver_tree_t *)malloc(sizeof(driver_tree_t));
+		dnull->functions = &ao_null;
+		dnull->handle = NULL;
+		dwav = (driver_tree_t *)malloc(sizeof(driver_tree_t));
+		dwav->functions = &ao_wav;
+		dwav->handle = NULL;
+		
+		dnull->next = dwav;
+		dwav->next = NULL;
+
+		driver_head = dnull;		
+		driver = dwav;
+
+		/* now insert any plugins we find */
+		plugindir = opendir(AO_PLUGIN_PATH);
+		if (plugindir != NULL) {
+			while ((plugin_dirent = readdir(plugindir)) != NULL) {
+				snprintf(fullpath, NAME_MAX, "%s/%s", AO_PLUGIN_PATH, plugin_dirent->d_name);
+				if (!stat(fullpath, &statbuf) && S_ISREG(statbuf.st_mode) && (ext = strrchr(plugin_dirent->d_name, '.')) != NULL) {
+					if (strcmp(ext, SHARED_LIB_EXT) == 0) {
+						plugin = _get_plugin(fullpath);
+						if (plugin) {
+							driver->next = plugin;
+							plugin->next = NULL;
+						}
+					}
+				}
+			}
+			
+			closedir(plugindir);
+		}
+	}
+}
 
+void ao_shutdown(void)
+{
+	driver_tree_t *driver = driver_head;
+	driver_tree_t *next_driver;
 
+	if (!driver_head) return;
 
-/* --- Driver Functions --- */
+	/* unload and free all the plugins */
+	driver = driver->next->next;
+	while (driver) {
+		if (driver->functions) free(driver->functions);
+		if (driver->handle) dlclose(driver->handle);
+		next_driver = driver->next;
+		free(driver);
+		driver = next_driver;
+	}
 
-/* This should have been set by the Makefile */
-#ifndef AO_DEFAULT
-#define AO_DEFAULT AO_NULL
-#endif
+	/* free the standard drivers */
+	if (driver_head->next) free(driver_head->next);
+	if (driver_head->next) free(driver_head);
+}
 
-int ao_get_driver_id (const char *short_name)
+int ao_get_driver_id(const char *short_name)
 {
         int i;
+	driver_tree_t *driver = driver_head;
 
-	if (short_name == NULL) 
-		return AO_DEFAULT;
-	else 
-	{
+	if (short_name == NULL) {
+		return AO_NULL;
+	} else {
                 i = 0;
-		while (i < AO_DRIVERS)
-		{
-			/* Skip empty driver slots */
-			if (ao_drivers[i] != NULL
-			    && !strcmp(short_name, 
-				       ao_drivers[i]->get_driver_info()->short_name))
+		while (driver) {
+			if (strcmp(short_name, driver->functions->get_driver_info()->short_name) == 0)
                                 return i;
-
+			driver = driver->next;
                         i++;
                 }
                 
@@ -141,17 +182,47 @@
         }
 }
 
+driver_tree_t *_get_driver(int driver_id) {
+	int i = 0;
+	driver_tree_t *driver = driver_head;
+
+	if (driver_id < 0) return NULL;
+
+	while (driver && (i < driver_id)) {
+		i++;
+		driver = driver->next;
+	}
 
-int ao_check_driver_id (int driver_id)
+	if (i == driver_id) 
+		return driver;
+
+	return NULL;
+}
+
+int _check_driver_id(int driver_id)
 {
-	return driver_id >= 0 && driver_id < AO_DRIVERS && 
-		ao_drivers[driver_id] != NULL;	
+	int i = 0;
+	driver_tree_t *driver = driver_head;
+
+	if (driver_id < 0) return 0;
+
+	while (driver && (i <= driver_id)) {
+		driver = driver->next;
+		i++;
+	}
+	
+	if (i == (driver_id + 1))
+		return 1;
+
+	return 0;
 }	
 
-ao_info_t *ao_get_driver_info (int driver_id)
+ao_info_t *ao_get_driver_info(int driver_id)
 {
-	if (ao_check_driver_id(driver_id))
-		return ao_drivers[driver_id]->get_driver_info();
+	driver_tree_t *driver;
+
+	if (driver = _get_driver(driver_id))
+		return driver->functions->get_driver_info();
         else
                 return NULL;
 }
@@ -160,19 +231,17 @@
 
 /* -- Audio Functions --- */
 
-ao_device_t* ao_open (int driver_id, uint_32 bits, uint_32 rate, uint_32 channels, 
-	     ao_option_t *options)
+ao_device_t* ao_open(int driver_id, uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
 {
         ao_functions_t *funcs;
         ao_internal_t *state;
         ao_device_t *device;
+	driver_tree_t *driver = driver_head;
 
-	if (ao_check_driver_id(driver_id))
-	{
-		funcs = ao_drivers[driver_id];
+	if (driver = _get_driver(driver_id)) {
+		funcs = driver->functions;
                 state = funcs->open(bits, rate, channels, options);
-		if (state != NULL)
-		{
+		if (state != NULL) {
                         device = malloc(sizeof(ao_device_t));
                         device->funcs = funcs;
                         device->state = state;
@@ -183,14 +252,13 @@
         return NULL;
 }	
 
-void ao_play (ao_device_t *device, void* output_samples, uint_32 num_bytes)
+void ao_play(ao_device_t *device, void* output_samples, uint_32 num_bytes)
 {
-  device->funcs->play(device->state, output_samples,
-		      num_bytes);
+	device->funcs->play(device->state, output_samples, num_bytes);
 }
 
 
-void ao_close (ao_device_t *device)
+void ao_close(ao_device_t *device)
 {
         device->funcs->close(device->state);
         free(device);
@@ -200,7 +268,7 @@
 
 /* --- Option Functions --- */
 
-ao_option_t* ao_parse_option (const char* op_str)
+ao_option_t* _parse_option(const char* op_str)
 {
         char *copy;
         char *value_ptr;
@@ -210,15 +278,13 @@
         copy = strdup(op_str);
         
         colon = strchr(copy, ':');
-        if (colon != NULL) 
-        {
+        if (colon != NULL) {
                 value_ptr = colon + 1;
                 *colon = 0x00; // Null terminate the key part
                 
-                // Allocate the option structure
+                /* Allocate the option structure */
                 op = malloc(sizeof(ao_option_t));
-                if (op != NULL)
-                {
+                if (op != NULL) {
                         op->key = strdup(copy);
                         op->value = strdup(value_ptr);
                         op->next = NULL;
@@ -230,25 +296,20 @@
 }
 
 
-int ao_append_option (ao_option_t **options, const char *op_str)
+int ao_append_option(ao_option_t **options, const char *op_str)
 {
         ao_option_t *temp;
 
-	temp = ao_parse_option(op_str);
+	temp = _parse_option(op_str);
 
         if (temp == NULL)
                 return 0; //Bad option format
 
-	if (*options != NULL)
-	{
+	if (*options != NULL) {
                 while ((*options)->next != NULL)
-		{
                         *options = (*options)->next;
-		}
                 (*options)->next = temp;
-	}
-	else
-	{
+	} else {
                 *options = temp;
         }
 
@@ -256,12 +317,11 @@
 }
 
 
-void ao_free_options (ao_option_t* options)
+void ao_free_options(ao_option_t *options)
 {
         ao_option_t *rest;
 
-	while (options != NULL)
-	{
+	while (options != NULL) {
                 rest = options->next;
                 free(options->key);
                 free(options->value);
@@ -270,12 +330,12 @@
         }
 }
 
-/* Helper function lifted from lib/vorbisfile.c */
-int ao_is_big_endian() {
+/* Helper function lifted from Vorbis' lib/vorbisfile.c */
+int ao_is_big_endian(void) 
+{
         uint_16 pattern = 0xbabe;
         unsigned char *bytewise = (unsigned char *)&pattern;
+
         if (bytewise[0] == 0xba) return 1;
-	
-	assert(bytewise[0] == 0xbe);
         return 0;
 }

1.1                  ao/src/plugins/Makefile.am

Index: Makefile.am
===================================================================
## Process this file with automake to produce Makefile.in

AUTOMAKE_OPTIONS = foreign
SUBDIRS = oss esd alsa # solaris irix

1.1                  ao/src/plugins/alsa/Makefile.am

Index: Makefile.am
===================================================================
## Process this file with automake to produce Makefile.in

AUTOMAKE_OPTIONS = foreign

if HAVE_ALSA

alsaltlibs = libalsa.la
alsaldflags = -export-dynamic -avoid-version
alsasources = ao_alsa.c

else

alsaltlibs =
alsaldflags =
alsasources =

endif

INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include

libdir = $(plugindir)
lib_LTLIBRARIES = $(alsaltlibs)

libalsa_la_LDFLAGS = $(alsaldflags)
libalsa_la_SOURCES = $(alsasources)

EXTRA_DIST = ao_alsa.c

1.1                  ao/src/plugins/alsa/ao_alsa.c

Index: ao_alsa.c
===================================================================
/*
 *
 *  ao_alsa.c
 *
 *      Copyright (C) Stan Seibert - July 2000
 *
 *  This file is part of libao, a cross-platform library.  See
 *  README for a history of this source code.
 *
 *  libao is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  libao is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

#include <sys/asoundlib.h>
#include <ao/ao.h>

#define AO_ALSA_BUF_SIZE 32768

typedef struct ao_alsa_internal_s
{
        snd_pcm_t *pcm_handle;
        char *buf;
        int buf_size;
        int buf_end;
        int card;
        int dev;
} ao_alsa_internal_t;

tatic ao_info_t ao_alsa_info =
{
        "Advanced Linux Sound Architecture (ALSA) output",
        "alsa",
        "Stan Seibert <volsung at asu.edu>",
        ""
};

tatic void
ao_alsa_parse_options(ao_alsa_internal_t *state, ao_option_t *options)
{
        state->card = 0;
        state->dev = 0;
        state->buf_size = AO_ALSA_BUF_SIZE;

        while (options)
        {
                if (!strcmp(options->key, "card"))
                        state->card = atoi(options->value);
                else if (!strcmp(options->key, "dev"))
                        state->dev = atoi(options->value);
                else if (!strcmp(options->key, "buf_size"))
                        state->buf_size = atoi(options->value);
                
                options = options->next;
        }
}

tatic ao_internal_t*
ao_alsa_open (uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
{
        ao_alsa_internal_t *state;
        snd_pcm_channel_params_t param;
        int err;

        memset(&param, 0, sizeof(param));

        param.channel = SND_PCM_CHANNEL_PLAYBACK;
        param.mode = SND_PCM_MODE_BLOCK;

        param.format.interleave = 1;

        switch (bits)
        {
        case 8  : param.format.format = SND_PCM_SFMT_S8;
                  break;
        case 16 : param.format.format = ao_is_big_endian() ?
                    SND_PCM_SFMT_S16_BE : SND_PCM_SFMT_S16_LE;
                  break;
        default : return NULL;
        }

        if (channels > 0 && channels < 3)
                param.format.voices = channels;
        else
                return NULL;

        // Allocate the state structure and parse the options
        state = malloc(sizeof(ao_alsa_internal_t));

        if (state == NULL)
                return NULL;

        ao_alsa_parse_options(state, options);

        // Finish filling in the parameter structure
        param.format.rate = rate;

        param.start_mode = SND_PCM_START_FULL;
        
        param.stop_mode = SND_PCM_STOP_STOP;

        param.buf.block.frag_size = state->buf_size;
        param.buf.block.frags_min = 1;
        param.buf.block.frags_max = 8;

        err = snd_pcm_open(&(state->pcm_handle), 
                           state->card, 
                           state->dev,
                           SND_PCM_OPEN_PLAYBACK | SND_PCM_OPEN_NONBLOCK);
        if ( err < 0 )
        {
                free(state);
                return NULL;
        }

        err = snd_pcm_channel_params(state->pcm_handle, &param);

        if (err < 0 )
        {
                snd_pcm_close(state->pcm_handle);
                free(state);
                return NULL;
        }

        state->buf = malloc(state->buf_size);
        state->buf_end = 0;

        snd_pcm_nonblock_mode(state->pcm_handle, 0);
        snd_pcm_channel_prepare(state->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);

        return state;
}

tatic void
ao_alsa_close (ao_internal_t *state)
{
        ao_alsa_internal_t *s = (ao_alsa_internal_t *) state;
        snd_pcm_close(s->pcm_handle);
        free(s);
}

tatic void
ao_alsa_write_buffer (ao_alsa_internal_t *s)
{
        snd_pcm_channel_status_t status;
        snd_pcm_t *pcm_handle = s->pcm_handle;
        int len = s->buf_end;

        s->buf_end = 0;
        snd_pcm_write(pcm_handle, s->buf, len);
        memset(&status, 0, sizeof(status));
        if (snd_pcm_channel_status(pcm_handle, &status) < 0) {
                fprintf(stderr, "ALSA: could not get channel status\n");
                return;
        }       
        if (status.underrun) {
                fprintf(stderr, "ALSA: underrun. resetting channel\n");
                snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
                snd_pcm_playback_prepare(pcm_handle);
                snd_pcm_write(pcm_handle, s->buf, len);
                if (snd_pcm_channel_status(pcm_handle, &status) < 0) {
                        fprintf(stderr, "ALSA: could not get channel status. giving up\n");
                        return;
                }
                if (status.underrun) {
                        fprintf(stderr, "ALSA: write error. giving up\n");
                                        return;
                }               
        }
}	

tatic void
ao_alsa_play (ao_internal_t *state, void* output_samples, uint_32 num_bytes)
{
        ao_alsa_internal_t *s = (ao_alsa_internal_t *) state;
        int packed = 0;
        int copy_len;
        char *samples = (char *) output_samples;

        while (packed < num_bytes)
        {
                /* Pack the buffer */
                if (num_bytes-packed < s->buf_size-s->buf_end)
                        copy_len = num_bytes - packed;
                else
                        copy_len = s->buf_size-s->buf_end;

                memcpy(s->buf + s->buf_end, samples + packed, copy_len); 
                packed += copy_len;
                s->buf_end += copy_len;

                if(s->buf_end == s->buf_size)
                {
                        ao_alsa_write_buffer(s);
                }
        }
}

tatic ao_info_t*
ao_alsa_get_driver_info (void)
{
        return &ao_alsa_info;
}

ao_functions_t ao_alsa = 
{
        ao_alsa_get_driver_info,
        ao_alsa_open,
        ao_alsa_play,
        ao_alsa_close
};

1.1                  ao/src/plugins/esd/Makefile.am

Index: Makefile.am
===================================================================
## Process this file with automake to produce Makefile.in

AUTOMAKE_OPTIONS = foreign

if HAVE_ESD

esdltlibs = libesd.la
esdldflags = -export-dynamic -avoid-version
esdsources = ao_esd.c

else

esdltlibs =
esdldflags =
esdsources =

endif

INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include @ESD_CFLAGS@

libdir = $(plugindir)
lib_LTLIBRARIES = $(esdltlibs)

libesd_la_LDFLAGS = $(esdldflags)
libesd_la_LIBADD = @ESD_LIBS@
libesd_la_SOURCES = $(esdsources)

EXTRA_DIST = ao_esd.c

1.1                  ao/src/plugins/esd/ao_esd.c

Index: ao_esd.c
===================================================================
/*
 *
 *  ao_esd.c
 *
 *      Copyright (C) Stan Seibert - July 2000
 *
 *  This file is part of libao, a cross-platform library.  See
 *  README for a history of this source code.
 *
 *  libao is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  libao is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

#include <esd.h>
#include <ao/ao.h>

typedef struct ao_esd_internal_s
{
        int sock;
        char *host;
} ao_esd_internal_t;

tatic ao_info_t ao_esd_info =
{
        "ESounD output",
        "esd",
        "Stan Seibert <volsung at asu.edu>",
        ""
};

tatic void
ao_esd_parse_options(ao_esd_internal_t *state, ao_option_t *options)
{
        state->host = NULL;

        while (options)
        {
                if (!strcmp(options->key, "host"))
                        state->host = strdup(options->value);
                
                options = options->next;
        }
}

tatic ao_internal_t*
ao_esd_open (uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
{
        ao_esd_internal_t *state;
        int esd_bits;
        int esd_channels;
        int esd_mode = ESD_STREAM;
        int esd_func = ESD_PLAY;
        int esd_format;

        switch (bits)
        {
        case 8  : esd_bits = ESD_BITS8;
                  break;
        case 16 : esd_bits = ESD_BITS16;
                  break;
        default : return NULL;
        }

        switch (channels)
        {
        case 1 : esd_channels = ESD_MONO;
                 break;
        case 2 : esd_channels = ESD_STEREO;
                 break;
        default: return NULL;
        }
        
        esd_format = esd_bits | esd_channels | esd_mode | esd_func;

        state = malloc(sizeof(ao_esd_internal_t));

        if (state == NULL)
                return NULL;

        ao_esd_parse_options(state, options);

        state->sock = esd_play_stream(esd_format, rate, state->host,
                                      "libao output");
        if ( state->sock <= 0 ) {
                free(state->host);
                free(state);
                return NULL;
        }

        return state;
}

tatic void
ao_esd_close (ao_internal_t *state)
{
        ao_esd_internal_t *s = (ao_esd_internal_t *) state;
        close(s->sock);
        free(s->host);
        free(s);
}

tatic void
ao_esd_play (ao_internal_t *state, void* output_samples, uint_32 num_bytes)
{
        write( ((ao_esd_internal_t *) state)->sock, output_samples, 
               num_bytes );
}

tatic ao_info_t*
ao_esd_get_driver_info (void)
{
        return &ao_esd_info;
}

ao_functions_t ao_esd = 
{
        ao_esd_get_driver_info,
        ao_esd_open,
        ao_esd_play,
        ao_esd_close
};

1.1                  ao/src/plugins/irix/ao_irix.c

Index: ao_irix.c
===================================================================
/*
 *
 *  ao_irix.h
 *
 *      Original Copyright (C) Aaron Holtzman - May 1999
 *      Port to IRIX by Jim Miller, SGI - Nov 1999
 *      Modifications Copyright (C) Stan Seibert - July 2000
 *
 *  This file is part of libao, a cross-platform library.  See
 *  README for a history of this source code.
 *
 *  libao is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  libao is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>

#include <audio.h>

#include <ao/ao.h>

typedef struct ao_irix_internal_s {
        static ALport alport = 0;
        static ALconfig alconfig = 0;
        static int bytesPerWord = 1;
        static int nChannels = 2;
} ao_irix_internal_t;

static ao_info_t ao_irix_info =
{
        "Irix audio output ",
        "irix",
        "Jim Miller <???@sgi.com>",
        "WARNING: This driver is untested!"
};

/*
 * open the audio device for writing to
 */
static ao_internal_t*
ao_irix_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
{
        ALpv params[2];
        int  dev = AL_DEFAULT_OUTPUT;
        int  wsize = AL_SAMPLE_16;
        ao_irix_internal_t *state;

        state = malloc(sizeof(ao_irix_internal_t));
        if (state == NULL)
                return NULL;
        

        state->nChannels = channels;

        state->alconfig = alNewConfig();

        if (alSetQueueSize(state->alconfig, BUFFER_SIZE) < 0) 
        {
                fprintf(stderr, "alSetQueueSize failed: %s\n", 
                        alGetErrorString(oserror()));
                return 0;
        }

        if (alSetChannels(state->alconfig, channels) < 0) 
        {
                fprintf(stderr, "alSetChannels(%d) failed: %s\n", 
                        channels, alGetErrorString(oserror()));
                return 0;
        }
        
        if (alSetDevice(state->alconfig, dev) < 0) 
        {
                fprintf(stderr, "alSetDevice failed: %s\n", 
                        alGetErrorString(oserror()));
                return 0;
        }
        
        if (alSetSampFmt(state->alconfig, AL_SAMPFMT_TWOSCOMP) < 0) 
        {
                fprintf(stderr, "alSetSampFmt failed: %s\n", 
                        alGetErrorString(oserror()));
                return 0;
        }

        state->alport = alOpenPort("AC3Decode", "w", 0);

        if (!state->alport) 
        {
                fprintf(stderr, "alOpenPort failed: %s\n", 
                        alGetErrorString(oserror()));
                return 0;
        }

        switch (bits) 
        {
        case 8:         
                state->bytesPerWord = 1;
                wsize = AL_SAMPLE_8;
                break;
                
        case 16: 
                state->bytesPerWord = 2;
                wsize = AL_SAMPLE_16;
                break;
                
        case 24:
                state->bytesPerWord = 4;
                wsize = AL_SAMPLE_24;
                break;
                
        default:
                fprintf(stderr,"Irix audio: unsupported bit with %d\n", bits);
                break;
        }

        if (alSetWidth(state->alconfig, wsize) < 0) 
        {
                fprintf(stderr, "alSetWidth failed: %s\n", alGetErrorString(oserror()));
                return 0;
        }
        
        params[0].param = AL_RATE;
        params[0].value.ll = alDoubleToFixed((double)rate);
        params[1].param = AL_MASTER_CLOCK;
        params[1].value.i = AL_CRYSTAL_MCLK_TYPE;
        if ( alSetParams(dev, params, 1) < 0) {
                printf("alSetParams() failed: %s\n", alGetErrorString(oserror()));
                return 0;
        }
        
        return state;
}

/*
 * play the sample to the already opened file descriptor
 */

tatic void 
ao_irix_play(ao_internal_t *state, void* output_samples, uint_32 num_bytes)
{
        alWriteFrames( ((ao_irix_internal_t *) state)->alport, 
                       output_samples, num_bytes); 
}

tatic void
ao_irix_close(ao_internal_t *state)
{
        ao_irix_internal_t *s = (ao_irix_internal_t *) state;

        alClosePort(s->alport);
        alFreeConfig(s->alconfig);

        free(state);
}

tatic ao_info_t*
ao_irix_get_driver_info(void)
{
        return &ao_irix_info;
}

ao_functions_t ao_irix =
{
        ao_irix_get_driver_info,
        ao_irix_open,
        ao_irix_play,
        ao_irix_close
};

1.1                  ao/src/plugins/oss/Makefile.am

Index: Makefile.am
===================================================================
## Process this file with automake to produce Makefile.in

AUTOMAKE_OPTIONS = foreign

if HAVE_OSS

ossltlibs = liboss.la
ossldflags = -export-dynamic -avoid-version
osssources = ao_oss.c

else

ossltlibs =
ossldflags =
osssources =

endif

INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include

libdir = $(plugindir)
lib_LTLIBRARIES = $(ossltlibs)

liboss_la_LDFLAGS = $(ossldflags)
liboss_la_SOURCES = $(osssources)

EXTRA_DIST = ao_oss.c

1.1                  ao/src/plugins/oss/ao_oss.c

Index: ao_oss.c
===================================================================
/*
 *
 *  ao_oss.c
 *
 *      Original Copyright (C) Aaron Holtzman - May 1999
 *      Modifications Copyright (C) Stan Seibert - July 2000
 *
 *  This file is part of libao, a cross-platform library.  See
 *  README for a history of this source code.
 *
 *  libao is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  libao is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#if defined(__OpenBSD__) || defined(__NetBSD__)
#include <soundcard.h>
#elif defined(__FreeBSD__)
#include <machine/soundcard.h>
#else
#include <sys/soundcard.h>
#endif
#include <sys/ioctl.h>

#include <ao/ao.h>

tatic ao_info_t ao_oss_info =
{
        "OSS audio driver output ",
        "oss",
        "Aaron Holtzman <aholtzma at ess.engr.uvic.ca>",
        ""
};

typedef struct ao_oss_internal_s {
        char *dev;
        int fd;
} ao_oss_internal_t;

tatic void
ao_oss_parse_options(ao_oss_internal_t *state, ao_option_t *options)
{
        state->dev = NULL;

        while (options)
        {
                if (!strcmp(options->key, "dsp"))
                        state->dev = strdup(options->value);
                
                options = options->next;
        }

        if (state->dev == NULL)
                state->dev = strdup("/dev/dsp");
}

/*
 * open the audio device for writing to
 */
static ao_internal_t*
ao_oss_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
{
        ao_oss_internal_t *state;
        int tmp;
        
        /* Allocate a state structure to hold instance
           information.  (Long live C++!) */
        state = malloc(sizeof(ao_oss_internal_t));

        if (state == NULL)	
        {
                fprintf(stderr,"libao - %s: Allocating state memory.\n",
                        strerror(errno));
                goto ERR;
        }

        ao_oss_parse_options(state, options);

        /* Open the device driver */
        
        state->fd=open(state->dev,O_WRONLY);
        if(state->fd < 0) 
        {
                fprintf(stderr,"libao - %s: Opening audio device %s\n",
                        strerror(errno), state->dev);
                goto ERR;
        }

        switch (channels)
        {
        case 1: tmp = 0;
                break;
        case 2: tmp = 1;
                break;
        default:fprintf(stderr,"libao - Unsupported number of channels: %d.",
                        channels);
                goto ERR;
        }
        ioctl(state->fd,SNDCTL_DSP_STEREO,&tmp);
        
        switch (bits)
        {
        case 8: tmp = AFMT_S8;
                break;
        case 16: tmp = ao_is_big_endian() ? AFMT_S16_BE : AFMT_S16_LE;
                break;
        default:fprintf(stderr,"libao - Unsupported number of bits: %d.",
                        bits);
                goto ERR;
        }
        ioctl(state->fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
        
        tmp = rate;
        ioctl(state->fd,SNDCTL_DSP_SPEED, &tmp);
        
        return state;
        

 ERR:
        if(state != NULL)
        { 
                if (state->fd >= 0) { close(state->fd); }
                free(state);
        }

        return NULL;
}

/*
 * play the sample to the already opened file descriptor
 */
static void 
ao_oss_play(ao_internal_t *state, void *output_samples, uint_32 num_bytes)
{
        
        write( ((ao_oss_internal_t *)state)->fd, output_samples, num_bytes);
}

static void
ao_oss_close(ao_internal_t *state)
{
        ao_oss_internal_t *s = (ao_oss_internal_t *) state;
        close(s->fd);
        free(s->dev);
        free(s);
}

static ao_info_t*
ao_oss_get_driver_info(void)
{
        return &ao_oss_info;
}

ao_functions_t ao_oss =
{
        ao_oss_get_driver_info,
        ao_oss_open,
        ao_oss_play,
        ao_oss_close
};

1.1                  ao/src/plugins/solaris/ao_solaris.c

Index: ao_solaris.c
===================================================================
/*
 *
 *  ao_null.c
 *
 *      Original Copyright (C) Aaron Holtzman - May 1999
 *      Modifications Copyright (C) Stan Seibert - July 2000
 *
 *  This file is part of libao, a cross-platform library.  See
 *  README for a history of this source code.
 *
 *  libao is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  libao is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/audioio.h>
#include <sys/ioctl.h>
#include <stropts.h>
#include <signal.h>
#include <math.h>

//FIXME broken solaris headers!
int usleep(unsigned int useconds);

#include <ao/ao.h>

static ao_info_t ao_solaris_info =
{
        "Solaris audio output ",
        "solaris",
        "Aaron Holtzman <aholtzma at ess.engr.uvic.ca>",
        "WARNING: This driver is untested."
};

typedef struct ao_solaris_internal_s  {
 /* Global to keep track of old state */
        static audio_info_t info;
        static char *dev;
        static int fd;
} ao_solaris_internal_t;

/*
 * open the audio device for writing to
 */
static ao_internal_t*
ao_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options)
{

        ao_solaris_internal_t *state;

        state = malloc(sizeof(ao_solaris_internal_t));
        if (state == NULL)
                return NULL;

        state->dev = strdup("/dev/audio");

        /*
         * Open the device driver
         */

        state->fd=open(state->dev,O_WRONLY);
        if(state->fd < 0) 
        {
                fprintf(stderr,"%s: Opening audio device %s\n",
                                strerror(errno), state->dev);
                goto ERR;
        }

        /* Setup our parameters */
        AUDIO_INITINFO(&(state->info));

        state->info.play.sample_rate = rate;
        state->info.play.precision = bits;
        state->info.play.channels = channels;
        state->info.play.buffer_size = 1024;
        state->info.play.encoding = AUDIO_ENCODING_LINEAR;
        //state->info.play.port = AUDIO_SPEAKER;
        //state->info.play.gain = 110;

        /* Write our configuration */
        /* An implicit GETINFO is also performed so we can get
         * the buffer_size */

        if(ioctl(state->fd, AUDIO_SETINFO, &(state->info)) < 0)
        {
                fprintf(stderr, "%s: Writing audio config block\n",strerror(errno));
                goto ERR;
        }

        return state;

ERR:
        if(fd >= 0) { close(fd); }
        return NULL;
}

/*
 * play the sample to the already opened file descriptor
 */
static void 
ao_solaris_play(ao_internal_t *state, void *output_samples, uint_32 num_bytes)
{
        write( ((ao_solaris_internal_t *) state)->fd,
               output_samples, num_bytes);
}

static void
ao_solaris_close(ao_internal_t *state)
{
        close(((ao_solaris_internal_t *) state)->fd);
        free(state);
}

tatic const ao_info_t*
ao_solaris_get_driver_info(void)
{
        return &ao_solaris_info;
}

ao_functions_t ao_solaris =
{
        ao_solaris_get_driver_info,
        ao_solaris_open,
        ao_solaris_play,
        ao_solaris_close
};

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list