[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, µ) != 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(¶m, 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, ¶m);
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