From 2d590414e3270d9245479b8d4cdf83c8a68603b3 Mon Sep 17 00:00:00 2001 From: Jack Moffitt <jack@xiph.org> Date: Mon, 30 Oct 2000 00:46:43 +0000 Subject: [PATCH] the long awaited ao fixes. this hasn't been well tested. git-svn-id: http://svn.xiph.org/trunk/ao@772 0101bb08-14d6-0310-b084-bc0e0c8e3800 --- Makefile.am | 7 +- acinclude.m4 | 164 +++++++++++++ ao-config.in | 116 ++++++++++ ao.m4 | 110 +++++++++ configure.in | 156 +++---------- include/ao/ao.h | 74 +++--- include/ao/os_types.h.in | 4 +- src/Makefile.am | 6 +- src/ao_null.c | 40 ++-- src/ao_wav.c | 95 +++----- src/audio_out.c | 308 +++++++++++++++---------- src/plugins/Makefile.am | 4 + src/plugins/alsa/Makefile.am | 27 +++ src/{ => plugins/alsa}/ao_alsa.c | 0 src/plugins/esd/Makefile.am | 28 +++ src/{ => plugins/esd}/ao_esd.c | 2 +- src/{ => plugins/irix}/ao_irix.c | 0 src/plugins/oss/Makefile.am | 27 +++ src/{ => plugins/oss}/ao_oss.c | 0 src/{ => plugins/solaris}/ao_solaris.c | 0 20 files changed, 781 insertions(+), 387 deletions(-) create mode 100644 acinclude.m4 create mode 100644 ao-config.in create mode 100644 ao.m4 create mode 100644 src/plugins/Makefile.am create mode 100644 src/plugins/alsa/Makefile.am rename src/{ => plugins/alsa}/ao_alsa.c (100%) create mode 100644 src/plugins/esd/Makefile.am rename src/{ => plugins/esd}/ao_esd.c (99%) rename src/{ => plugins/irix}/ao_irix.c (100%) create mode 100644 src/plugins/oss/Makefile.am rename src/{ => plugins/oss}/ao_oss.c (100%) rename src/{ => plugins/solaris}/ao_solaris.c (100%) diff --git a/Makefile.am b/Makefile.am index 99d7d1c..de996fc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,12 @@ AUTOMAKE_OPTIONS = foreign dist-zip 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@" diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..39b3789 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,164 @@ +# 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, µ) != 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 +]) diff --git a/ao-config.in b/ao-config.in new file mode 100644 index 0000000..592f9e0 --- /dev/null +++ b/ao-config.in @@ -0,0 +1,116 @@ +#!/bin/sh + +# ao-config +# +# Tool for retrieving the library/include paths ao was compiled with. +# +# Written 29 October 2000 by Jack Moffitt <jack@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 diff --git a/ao.m4 b/ao.m4 new file mode 100644 index 0000000..e651e55 --- /dev/null +++ b/ao.m4 @@ -0,0 +1,110 @@ +# Configure paths for libao +# Jack Moffitt <jack@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 +]) diff --git a/configure.in b/configure.in index 59a7ea7..126e7f7 100644 --- a/configure.in +++ b/configure.in @@ -2,6 +2,7 @@ dnl Process this file with autoconf to produce a configure script. 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_SUBST(LIB_AGE) 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 @@ else esac fi + AC_SUBST(CC) AC_SUBST(DEBUG) AC_SUBST(PROFILE) @@ -72,20 +76,10 @@ dnl ============================== 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 @@ case 4 in 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 -- - -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 +dnl Check for ESD -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 +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 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 +dnl Check for OSS -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 +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 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 Check for ALSA -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 +AM_CONDITIONAL(HAVE_IRIX,test "x$have_irix" = xyes) -AC_MSG_RESULT("setting default output device... $ao_default") - -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) diff --git a/include/ao/ao.h b/include/ao/ao.h index b9835b6..b276fe6 100644 --- a/include/ao/ao.h +++ b/include/ao/ao.h @@ -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 @@ typedef struct ao_option_s { 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 struct ao_info_s 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); +/* library init/shutdown */ +void ao_initialize(void); +void ao_shutdown(void); -void ao_play (ao_device_t *device, void* output_samples, uint_32 num_bytes); +/* driver information */ +int ao_get_driver_id(const char *short_name); +ao_info_t *ao_get_driver_info(int driver_id); -void ao_close (ao_device_t *device); +/* driver options */ +int ao_append_options(ao_option_t **options, const char *op_str); +void ao_free_options(ao_option_t *options); -/* Returns 1 if options successfully appended, 0 if error */ -int ao_append_option (ao_option_t **options, const char* op_str); +/* 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__ */ diff --git a/include/ao/os_types.h.in b/include/ao/os_types.h.in index bb2378b..3907c7c 100644 --- a/include/ao/os_types.h.in +++ b/include/ao/os_types.h.in @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 9a9034e..e12d5a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,17 +1,15 @@ ## 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: $(MAKE) all CFLAGS="@DEBUG@" diff --git a/src/ao_null.c b/src/ao_null.c index e7d1ccf..1ffe6b7 100644 --- a/src/ao_null.c +++ b/src/ao_null.c @@ -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@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 }; - diff --git a/src/ao_wav.c b/src/ao_wav.c index 0d2167b..97af8bd 100644 --- a/src/ao_wav.c +++ b/src/ao_wav.c @@ -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 @@ static ao_info_t ao_wav_info = "WAV file output", "wav", "Aaron Holtzman <aholtzma@ess.engr.uvic.ca>", - "" + "Sends output to a .wav file" }; typedef struct ao_wav_internal_s @@ -118,13 +116,11 @@ static void (*old_sig)(int); 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 @@ ao_wav_parse_options(ao_wav_internal_t *state, ao_option_t *options) 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 @@ ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options) 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 @@ ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options) // 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 @@ ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options) 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 @@ ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options) 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 @@ ao_wav_open(uint_32 bits, uint_32 rate, uint_32 channels, ao_option_t *options) return state; - ERR: if(state->fd >= 0) { close(state->fd); } return NULL; @@ -215,44 +201,39 @@ ERR: /* * 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 @@ ao_wav_close(ao_internal_t *state) /* 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 @@ ao_wav_close(ao_internal_t *state) 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 @@ ERR: 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; diff --git a/src/audio_out.c b/src/audio_out.c index 4812cd8..93395e6 100644 --- a/src/audio_out.c +++ b/src/audio_out.c @@ -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 -#endif - -#ifdef AO_COMPILE_IRIX -extern ao_functions_t ao_irix; -#define AO_FUNC_IRIX &ao_irix -#else -#define AO_FUNC_IRIX NULL -#endif - -#ifdef AO_COMPILE_SOLARIS -extern ao_functions_t ao_solaris; -#define AO_FUNC_SOLARIS &ao_solaris -#else -#define AO_FUNC_SOLARIS NULL +/* These should have been set by the Makefile */ +#ifndef AO_DEFAULT +#define AO_DEFAULT AO_NULL #endif - -#ifdef AO_COMPILE_WIN32 -extern ao_functions_t ao_win32; -#define AO_FUNC_WIN32 &ao_win32 -#else -#define AO_FUNC_WIN32 NULL +#ifndef AO_PLUGIN_PATH +#define AO_PLUGIN_PATH "/usr/local/lib/ao" #endif - -#ifdef AO_COMPILE_BEOS -extern ao_functions_t ao_beos; -#define AO_FUNC_BEOS &ao_beos -#else -#define AO_FUNC_BEOS NULL +#ifndef SHARED_LIB_EXT +#define SHARED_LIB_EXT ".so" #endif -#ifdef AO_COMPILE_ESD -extern ao_functions_t ao_esd; -#define AO_FUNC_ESD &ao_esd -#else -#define AO_FUNC_ESD NULL -#endif +/* --- Driver Table --- */ -#ifdef AO_COMPILE_ALSA -extern ao_functions_t ao_alsa; -#define AO_FUNC_ALSA &ao_alsa -#else -#define AO_FUNC_ALSA NULL -#endif +typedef struct driver_tree_s { + ao_functions_t *functions; + void *handle; + struct driver_tree_s *next; +} driver_tree_t; +extern ao_functions_t ao_null; extern ao_functions_t ao_wav; +driver_tree_t *driver_head = NULL; +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; -/* --- Driver Table --- */ + dt->handle = handle; + + dt->functions = (ao_functions_t *)malloc(sizeof(ao_functions_t)); + if (!(dt->functions)) { + free(dt); + return NULL; + } -ao_functions_t* ao_drivers[AO_DRIVERS] = -{ - &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 */ -}; + 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; + } + return dt; +} +void ao_initialize(void) +{ + 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); + } + } +} -/* --- Driver Functions --- */ +void ao_shutdown(void) +{ + driver_tree_t *driver = driver_head; + driver_tree_t *next_driver; + + if (!driver_head) return; + + /* 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 @@ int ao_get_driver_id (const char *short_name) } } +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; + } + + if (i == driver_id) + return driver; + + return NULL; +} -int ao_check_driver_id (int driver_id) +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 @@ ao_info_t *ao_get_driver_info (int driver_id) /* -- 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 @@ ao_device_t* ao_open (int driver_id, uint_32 bits, uint_32 rate, uint_32 channel 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 @@ void ao_close (ao_device_t *device) /* --- 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 @@ ao_option_t* ao_parse_option (const char* op_str) 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 @@ ao_option_t* ao_parse_option (const char* op_str) } -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 @@ int ao_append_option (ao_option_t **options, const char *op_str) } -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 @@ void ao_free_options (ao_option_t* options) } } -/* 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; } diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am new file mode 100644 index 0000000..8d2b180 --- /dev/null +++ b/src/plugins/Makefile.am @@ -0,0 +1,4 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = oss esd alsa # solaris irix diff --git a/src/plugins/alsa/Makefile.am b/src/plugins/alsa/Makefile.am new file mode 100644 index 0000000..5485bf8 --- /dev/null +++ b/src/plugins/alsa/Makefile.am @@ -0,0 +1,27 @@ +## 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 diff --git a/src/ao_alsa.c b/src/plugins/alsa/ao_alsa.c similarity index 100% rename from src/ao_alsa.c rename to src/plugins/alsa/ao_alsa.c diff --git a/src/plugins/esd/Makefile.am b/src/plugins/esd/Makefile.am new file mode 100644 index 0000000..ab1a567 --- /dev/null +++ b/src/plugins/esd/Makefile.am @@ -0,0 +1,28 @@ +## 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 diff --git a/src/ao_esd.c b/src/plugins/esd/ao_esd.c similarity index 99% rename from src/ao_esd.c rename to src/plugins/esd/ao_esd.c index 0e3b66d..fad7193 100644 --- a/src/ao_esd.c +++ b/src/plugins/esd/ao_esd.c @@ -31,7 +31,7 @@ #include <string.h> #include <esd.h> -#include "audio_out.h" +#include <ao/ao.h> typedef struct ao_esd_internal_s { diff --git a/src/ao_irix.c b/src/plugins/irix/ao_irix.c similarity index 100% rename from src/ao_irix.c rename to src/plugins/irix/ao_irix.c diff --git a/src/plugins/oss/Makefile.am b/src/plugins/oss/Makefile.am new file mode 100644 index 0000000..3703a23 --- /dev/null +++ b/src/plugins/oss/Makefile.am @@ -0,0 +1,27 @@ +## 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 diff --git a/src/ao_oss.c b/src/plugins/oss/ao_oss.c similarity index 100% rename from src/ao_oss.c rename to src/plugins/oss/ao_oss.c diff --git a/src/ao_solaris.c b/src/plugins/solaris/ao_solaris.c similarity index 100% rename from src/ao_solaris.c rename to src/plugins/solaris/ao_solaris.c -- GitLab