ref: 3a0a630a4653a609e6b2674c88cf0c361182ca86
parent: b0022bd56982e62203b7332f0fe579f636682630
author: rrt <rrt>
date: Wed Apr 11 19:53:26 EDT 2007
Add libao handler for playing. Sadly libao only handles output. When available, it's the default output handler, since it can play to a wide range of devices. To cope, make set_device in sox.c take a mode parameter indicating whether we're doing input or output. Thus, libao, if available, is only the default output driver. Rename sox_format_nothing_{read,write}_io to sox_format_nothing_{read,write}. Clarify documentation of ALSA driver slightly.
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,7 @@
rec2wav and sndcmp.
o Added AMR-WB format. (robs)
o Added M3U playlist format [FR# 1667341]. (robs)
+ o Added libao support. (Reuben Thomas)
Effects:
--- a/configure.ac
+++ b/configure.ac
@@ -92,6 +92,17 @@
AC_DEFINE(HAVE_ALSA, 1, [Define to 1 if you have ALSA.])
fi
+dnl Check for libao
+AC_MSG_CHECKING([whether to try building libao sound driver])
+AC_ARG_ENABLE(libao,
+ AC_HELP_STRING([--disable-libao], [Don't build libao sound driver.]),,enable_libao=yes)
+AC_MSG_RESULT($enable_libao)
+if test "$enable_libao" = "yes"; then
+ AC_CHECK_HEADERS(ao/ao.h,
+ AC_CHECK_LIB(ao, ao_play,, enable_libao=no),
+ enable_libao=no)
+fi
+
dnl Check for OSS
AC_MSG_CHECKING([whether to try building OSS sound driver])
AC_ARG_ENABLE(oss,
@@ -228,6 +239,7 @@
echo
echo "Debugging build................... $enable_debug"
echo "ALSA driver....................... $enable_alsa"
+echo "libao driver...................... $enable_libao"
echo "OSS driver........................ $enable_oss"
echo "SUN audio driver.................. $enable_sun_audio"
echo "play and rec symlinks............. $enable_playrec_symlinks"
--- a/sox.1
+++ b/sox.1
@@ -791,7 +791,7 @@
Note: The input file is currently processed as .aiff.
.TP
.B alsa
-ALSA default device driver.
+ALSA device driver.
This is a pseudo-file type and can be optionally compiled into SoX. Run
.EX
sox -h
@@ -817,6 +817,18 @@
option): 0 = 6\*d6 kbit/s, 1 = 8\*d85 kbit/s, 2 = 12\*d65 kbit/s, 3 =
14\*d25 kbit/s, 4 = 15\*d85 kbit/s 5 = 18\*d25 kbit/s, 6 = 19\*d85
kbit/s, 7 = 23\*d05 kbit/s, 8 = 23\*d85 kbit/s
+.TP
+.B ao
+libao device driver.
+This is a pseudo-file type and can be optionally compiled into SoX. Run
+.EX
+ sox -h
+.EE
+to see if you have support for this file type. It works only for
+playing audio files. It can play to a wide range of devices and sound
+systems. See its documentation for the full range. At the moment SoX's
+use of libao cannot be configured directly; you must use libao
+configuration files.
.TP
\&\fB.au\fR, \fB.snd\fR \fB(also with \-t sndfile)\fR
Sun Microsystems AU files.
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,7 @@
lib_LTLIBRARIES = libsox.la
include_HEADERS = sox.h soxstdint.h
-formats = 8svx.c adpcm.c adpcm.h adpcms.c adpcms.h aiff.c au.c auto.c avr.c \
+formats = 8svx.c adpcm.c adpcm.h adpcms.c adpcms.h aiff.c ao.c au.c auto.c avr.c \
cdr.c cvsd.c cvsdfilt.h dat.c flac.c g711.c g711.h g721.c g723_24.c \
g723_40.c g72x.c g72x.h gsm.c hcom.c ima_rw.c ima_rw.h \
maud.c mp3.c nulfile.c prc.c raw.c sf.c sfircam.h skelform.c smp.c \
--- /dev/null
+++ b/src/ao.c
@@ -1,0 +1,110 @@
+/*
+ * libao player support for sox
+ * (c) Reuben Thomas <rrt@sc3d.org> 2007
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, write to the Free Software
+ * Foundation, Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301,
+ * USA. */
+
+#include "sox_i.h"
+
+#ifdef HAVE_AO_AO_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ao/ao.h>
+
+typedef struct ao_priv
+{
+ int driver_id;
+ ao_device *device;
+ ao_sample_format format;
+} *ao_priv_t;
+
+static int startread(UNUSED ft_t ft)
+{
+ sox_fail("Cannot read from libao driver");
+ return SOX_EOF;
+}
+
+static int startwrite(ft_t ft)
+{
+ ao_priv_t ao = (ao_priv_t)ft->priv;
+
+ ao_initialize();
+ if ((ao->driver_id = ao_default_driver_id()) < 0) {
+ sox_fail("Could not find a default driver");
+ return SOX_EOF;
+ }
+
+ ao->format.bits = SOX_SAMPLE_BITS;
+ ao->format.rate = ft->signal.rate;
+ ao->format.channels = ft->signal.channels;
+ ao->format.byte_format = AO_FMT_NATIVE;
+ if ((ao->device = ao_open_live(ao->driver_id, &ao->format, NULL)) == NULL) {
+ sox_fail("Could not open default device: error %d", errno);
+ return SOX_EOF;
+ }
+
+ return SOX_SUCCESS;
+}
+
+static sox_size_t write(ft_t ft, const sox_sample_t *buf, sox_size_t len)
+{
+ ao_priv_t ao = (ao_priv_t)ft->priv;
+
+ if (ao_play(ao->device, (void *)buf, len * sizeof(sox_sample_t)) == 0)
+ return 0;
+
+ return len;
+}
+
+static int stopwrite(ft_t ft)
+{
+ ao_priv_t ao = (ao_priv_t)ft->priv;
+
+ if (ao_close(ao->device) == 0) {
+ sox_fail("Error closing libao output");
+ return SOX_EOF;
+ }
+ ao_shutdown();
+
+ return SOX_SUCCESS;
+}
+
+/* libao player */
+static const char *aonames[] = {
+ "ao",
+ NULL
+};
+
+static sox_format_t sox_ao_format = {
+ aonames,
+ NULL,
+ SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
+ startread,
+ sox_format_nothing_read,
+ sox_format_nothing,
+ startwrite,
+ write,
+ stopwrite,
+ sox_format_nothing_seek
+};
+
+const sox_format_t *sox_ao_format_fn(void)
+{
+ return &sox_ao_format;
+}
+
+#endif
--- a/src/auto.c
+++ b/src/auto.c
@@ -196,10 +196,10 @@
NULL,
SOX_FILE_DEVICE | SOX_FILE_PHONY,
sox_autostartread,
- sox_format_nothing_read_io,
+ sox_format_nothing_read,
sox_format_nothing,
sox_autostartwrite,
- sox_format_nothing_write_io,
+ sox_format_nothing_write,
sox_format_nothing,
sox_format_nothing_seek
};
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -22,6 +22,9 @@
sox_alsa_format_fn,
#endif
sox_amr_wb_format_fn,
+#ifdef HAVE_LIBAO
+ sox_ao_format_fn,
+#endif
sox_au_format_fn,
sox_auto_format_fn,
sox_avr_format_fn,
--- a/src/misc.c
+++ b/src/misc.c
@@ -308,8 +308,8 @@
/* dummy format routines for do-nothing functions */
int sox_format_nothing(ft_t ft UNUSED) { return(SOX_SUCCESS); }
-sox_size_t sox_format_nothing_read_io(ft_t ft UNUSED, sox_sample_t *buf UNUSED, sox_size_t len UNUSED) { return(0); }
-sox_size_t sox_format_nothing_write_io(ft_t ft UNUSED, const sox_sample_t *buf UNUSED, sox_size_t len UNUSED) { return(0); }
+sox_size_t sox_format_nothing_read(ft_t ft UNUSED, sox_sample_t *buf UNUSED, sox_size_t len UNUSED) { return(0); }
+sox_size_t sox_format_nothing_write(ft_t ft UNUSED, const sox_sample_t *buf UNUSED, sox_size_t len UNUSED) { return(0); }
int sox_format_nothing_seek(ft_t ft UNUSED, sox_size_t offset UNUSED) { sox_fail_errno(ft, SOX_ENOTSUP, "operation not supported"); return(SOX_EOF); }
/* dummy effect routine for do-nothing functions */
--- a/src/sox.c
+++ b/src/sox.c
@@ -227,8 +227,15 @@
return f;
}
-static void set_device(file_t f)
+static void set_device(file_t f, sox_bool recording)
{
+#ifdef HAVE_AO_AO_H
+ if (!recording) {
+ f->filetype = "ao";
+ f->filename = xstrdup("default");
+ return;
+ }
+#endif
#if defined(HAVE_ALSA)
f->filetype = "alsa";
f->filename = xstrdup("default");
@@ -412,7 +419,7 @@
}
f = f? f : new_file();
- set_device(f);
+ set_device(f, sox_false);
files[file_count++] = f;
}
else if (f) {
@@ -434,7 +441,7 @@
file_count++;
f = new_file();
- set_device(f);
+ set_device(f, sox_true);
files[0] = f;
}
}
--- a/src/sox.h
+++ b/src/sox.h
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "soxstdint.h"
/* The following is the API version of libSoX. It is not meant
@@ -147,6 +148,7 @@
typedef uint32_t sox_size_t;
/* Maximum value size type can hold. (Minimum is 0). */
#define SOX_SIZE_MAX 0xffffffff
+#define SOX_SAMPLE_BITS (sizeof(sox_size_t) * CHAR_BIT)
typedef int32_t sox_ssize_t;
/* Minimum and maximum value signed size type can hold. */
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -226,6 +226,9 @@
extern const sox_format_t *sox_alsa_format_fn(void);
#endif
extern const sox_format_t *sox_amr_wb_format_fn(void);
+#ifdef HAVE_AO_AO_H
+extern const sox_format_t *sox_ao_format_fn(void);
+#endif
extern const sox_format_t *sox_au_format_fn(void);
extern const sox_format_t *sox_auto_format_fn(void);
extern const sox_format_t *sox_avr_format_fn(void);
@@ -302,8 +305,8 @@
* a file handler or effect doesn't need to do anything special
*/
int sox_format_nothing(ft_t ft);
-sox_size_t sox_format_nothing_read_io(ft_t ft, sox_sample_t *buf, sox_size_t len);
-sox_size_t sox_format_nothing_write_io(ft_t ft, const sox_sample_t *buf, sox_size_t len);
+sox_size_t sox_format_nothing_read(ft_t ft, sox_sample_t *buf, sox_size_t len);
+sox_size_t sox_format_nothing_write(ft_t ft, const sox_sample_t *buf, sox_size_t len);
int sox_format_nothing_seek(ft_t ft, sox_size_t offset);
int sox_effect_nothing(eff_t effp);
int sox_effect_nothing_flow(eff_t effp, const sox_sample_t *ibuf, sox_sample_t *obuf, sox_size_t *isamp, sox_size_t *osamp);