ref: c9782198d4a5150abd4eb5114d5d8d31433972fd
parent: e06776c324020ab2668729bacd0c8f04d37a5a04
author: robs <robs>
date: Sat Jan 17 03:27:26 EST 2009
New native OpenBSD audio handler for play/recording
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,7 @@
endif(HAVE_OPENMP)
endif(CMAKE_COMPILER_IS_GNUCC)
optional(HAVE_ID3TAG id3tag.h id3tag id3_file_open "")
+optional(HAVE_SNDIO sndio.h sndio sio_open sndio)
optional(HAVE_LIBAO ao/ao.h ao ao_play ao)
optional(HAVE_FLAC FLAC/all.h FLAC FLAC__stream_encoder_new flac)
optional(HAVE_MAD_H mad.h mad mad_stream_buffer mp3)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,8 @@
This file contains a list of all changes starting after the release of
sox-11gamma, followed by a list of prior authors and features.
-sox-14.x.x 2009-xx-xx
+
+sox-14.3.0 2009-xx-xx
----------
Previously deprecated features that have been removed in this release:
@@ -19,6 +20,13 @@
* But interface retained as an alias for `rate'.
+Newly deprecated features (to be removed in future):
+
+ Deprec- Feature [O(ption)] Removal
+ ated in [F(ormat)] [E(ffect)] Replacement due after
+ ------- ---------------------- ---------------------- -------
+ 14.3.0 F flac: libFLAC 1.1.2,3 libFLAC > 1.1.3 14.3.0 + 6 months
+
Previously deprecated features (to be removed in future):
Deprec- Feature [O(ption)] Removal
@@ -26,9 +34,9 @@
------- ---------------------- ---------------------- -------
14.2.0 E key alias pitch 2009-05-29
14.2.0 E pan ~= mixer/remix 2009-05-29
- 14.1.0 E resample alias rate 14.x.x + 6 months
- 14.1.0 E polyphase alias rate 14.x.x + 6 months
- 14.1.0 E rabbit alias rate 14.x.x + 6 months
+ 14.1.0 E resample alias rate 14.3.0 + 1 year
+ 14.1.0 E polyphase alias rate 14.3.0 + 1 year
+ 14.1.0 E rabbit alias rate 14.3.0 + 1 year
14.1.0 F wve (native) wve (libsndfile) 2009-07-29
14.1.0 Behaviour whereby soxi 2009-07-29
sox -V file(s) -n
@@ -41,12 +49,8 @@
File formats:
- o 24-bit support for ALSA driver. (robs)
- o Warn if ALSA under/overrun. (robs)
o Slight improvement to A-law/u-law conversion accuracy: round LSB
instead of truncating. (robs)
- o New `--ignore-length' option to ignore length in input file
- header (for simple encodings); instead, read to end of file. (robs)
o Fix [2028181] w64 float format incompatibility. (Tim Munro)
o Fix reading AIFF files with pad bytes in COMT chunks. (Joe Holt)
o Fix AIFF file length bug to stop reading trash data on files that
@@ -60,6 +64,7 @@
o New `overdrive' effect. (robs)
o New `pluck' and `tpdf' types for `synth'. (robs)
o Can now set common parameters for multiple `synth' channels. (robs)
+ o Fix [2487589] `dither' clipping detection & handling. (robs)
o Fix `repeat' sometimes stopping repeating too soon. (robs)
o Fix `repeat' sometimes repeating wrong audio segments. (robs)
o Fix [2332343] 'silence' segfault with certain lengths. (cbagwell)
@@ -70,10 +75,15 @@
Other new features:
- o New bitrate, time in seconds, & total options for soxi. (robs)
+ o New native OpenBSD audio handler for play/recording. (Alexandre Ratchov)
+ o 24-bit support for ALSA handler. (robs)
+ o Warn if ALSA under/overrun. (robs)
+ o New `--ignore-length' option to ignore length in input file
+ header (for simple encodings); instead, read to end of file. (robs)
o Added ability to create shared DLL's on cygwin (cbagwell)
o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs)
o New `--temp DIRECTORY' option. (robs)
+ o New bitrate, time in seconds, & total options for soxi. (robs)
Other bug fixes:
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(SoX, 14.2.0, sox-devel@lists.sourceforge.net)
+AC_INIT(SoX, 14.3.0, sox-devel@lists.sourceforge.net)
m4_ifdef([AC_CONFIG_MACRO_DIR], [AC_CONFIG_MACRO_DIR([m4])])
@@ -251,6 +251,23 @@
AM_CONDITIONAL(HAVE_OSS, test x$enable_oss = xyes)
AC_SUBST(OSS_LIBS)
+dnl Check for sndio
+AC_MSG_CHECKING([whether to try building sndio sound driver])
+AC_ARG_ENABLE(sndio,
+ AC_HELP_STRING([--disable-sndio], [Don't build sndio sound driver.]),,enable_sndio=yes)
+AC_MSG_RESULT($enable_sndio)
+if test "$enable_sndio" = "yes"; then
+ AC_CHECK_HEADERS(sndio.h,
+ [AC_CHECK_LIB(sndio, sio_open, SNDIO_LIBS="$SNDIO_LIBS -lsndio")],
+ enable_sndio=no)
+fi
+if test "$enable_sndio" = yes; then
+ AC_DEFINE(HAVE_SNDIO, 1, [Define to 1 if you have sndio.])
+ audio_driver_found=yes
+fi
+AM_CONDITIONAL(HAVE_SNDIO, test x$enable_sndio = xyes)
+AC_SUBST(SNDIO_LIBS)
+
dnl Check for Sun audio
AC_MSG_CHECKING([whether to try building Sun audio driver])
AC_ARG_ENABLE(sun-audio,
@@ -635,6 +652,7 @@
echo "ALSA driver....................... $enable_alsa"
echo "libao driver...................... $enable_libao"
echo "OSS driver........................ $enable_oss"
+echo "sndio driver...................... $enable_sndio"
echo "SUN audio driver.................. $enable_sun_audio"
echo "CoreAudio driver.................. $enable_coreaudio"
echo "Pulse Audio driver................ $enable_pulseaudio"
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -244,6 +244,11 @@
libsox_fmt_oss_la_LIBADD = libsox.la @OSS_LIBS@
pkglib_LTLIBRARIES += libsox_fmt_oss.la
endif
+if HAVE_SNDIO
+libsox_fmt_sndio_la_SOURCES = sndio.c
+libsox_fmt_sndio_la_LIBADD = libsox.la @SNDIO_LIBS@
+pkglib_LTLIBRARIES += libsox_fmt_sndio.la
+endif
if HAVE_SUN_AUDIO
libsox_fmt_sunau_la_SOURCES = sunaudio.c
libsox_fmt_sunau_la_LIBADD = libsox.la
@@ -373,6 +378,11 @@
libsox_la_SOURCES += oss.c
libsox_la_LIBADD += @OSS_LIBS@
sox_LDADD += @OSS_LIBS@
+endif
+if HAVE_SNDIO
+ libsox_la_SOURCES += sndio.c
+ libsox_la_LIBADD += @SNDIO_LIBS@
+ sox_LDADD += @SNDIO_LIBS@
endif
if HAVE_SUN_AUDIO
libsox_la_SOURCES += sunaudio.c
--- a/src/formats.h
+++ b/src/formats.h
@@ -87,6 +87,9 @@
#if defined(HAVE_SYS_SOUNDCARD_H) || defined(HAVE_MACHINE_SOUNDCARD_H)
FORMAT(oss)
#endif
+#if defined HAVE_SNDIO
+ FORMAT(sndio)
+#endif
#if defined HAVE_SNDFILE
FORMAT(sndfile)
#if defined HAVE_SNDFILE_1_0_12
--- /dev/null
+++ b/src/sndio.c
@@ -1,0 +1,242 @@
+/*
+ * libsndio sound handler
+ *
+ * Copyright (c) 2009 Alexandre Ratchov <alex@caoua.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <string.h>
+#include <sndio.h>
+#include "sox_i.h"
+
+struct sndio_priv {
+ struct sio_hdl *hdl; /* handle to speak to libsndio */
+ struct sio_par par; /* current device parameters */
+#define SNDIO_BUFSZ 0x1000
+ unsigned char buf[SNDIO_BUFSZ]; /* temp buffer for converions */
+};
+
+/*
+ * convert ``count'' samples from sox encoding to sndio encoding
+ */
+static void encode(struct sio_par *par,
+ sox_sample_t *idata, unsigned char *odata, unsigned count)
+{
+ int obnext, osnext, s, osigbit;
+ unsigned oshift, obps, i;
+
+ obps = par->bps;
+ osigbit = par->sig ? 0 : 1 << (par->bits - 1);
+ oshift = 32 - (par->msb ? par->bps * 8 : par->bits);
+ if (par->le) {
+ obnext = 1;
+ osnext = 0;
+ } else {
+ odata += par->bps - 1;
+ obnext = -1;
+ osnext = 2 * par->bps;
+ }
+ for (; count > 0; count--) {
+ s = (*idata++ >> oshift) ^ osigbit;
+ for (i = obps; i > 0; i--) {
+ *odata = (unsigned char)s;
+ s >>= 8;
+ odata += obnext;
+ }
+ odata += osnext;
+ }
+}
+
+/*
+ * convert ``count'' samples from sndio encoding to sox encoding
+ */
+static void decode(struct sio_par *par,
+ unsigned char *idata, sox_sample_t *odata, unsigned count)
+{
+ unsigned ishift, ibps, i;
+ int s = 0xdeadbeef, ibnext, isnext, isigbit;
+
+ ibps = par->bps;
+ isigbit = par->sig ? 0 : 1 << (par->bits - 1);
+ ishift = 32 - (par->msb ? par->bps * 8 : par->bits);
+ if (par->le) {
+ idata += par->bps - 1;
+ ibnext = -1;
+ isnext = 2 * par->bps;
+ } else {
+ ibnext = 1;
+ isnext = 0;
+ }
+ for (; count > 0; count--) {
+ for (i = ibps; i > 0; i--) {
+ s <<= 8;
+ s |= *idata;
+ idata += ibnext;
+ }
+ idata += isnext;
+ *odata++ = (s ^ isigbit) << ishift;
+ }
+}
+
+static int startany(struct sox_format *ft, unsigned mode)
+{
+ struct sndio_priv *p = (struct sndio_priv *)ft->priv;
+ struct sio_par reqpar;
+ char *device;
+
+ device = ft->filename;
+ if (strcmp("default", device) == 0)
+ device = NULL;
+
+ p->hdl = sio_open(device, mode, 0);
+ if (p->hdl == NULL)
+ return SOX_EOF;
+ /*
+ * set specified parameters, leaving others to the defaults
+ */
+ sio_initpar(&reqpar);
+ if (ft->signal.rate > 0)
+ reqpar.rate = ft->signal.rate;
+ if (ft->signal.channels > 0) {
+ if (mode == SIO_PLAY)
+ reqpar.pchan = ft->signal.channels;
+ else
+ reqpar.rchan = ft->signal.channels;
+ }
+ if (ft->signal.precision > 0)
+ reqpar.bits = ft->signal.precision;
+ switch (ft->encoding.encoding) {
+ case SOX_ENCODING_SIGN2:
+ reqpar.sig = 1;
+ break;
+ case SOX_ENCODING_UNSIGNED:
+ reqpar.sig = 0;
+ break;
+ default:
+ break; /* use device default */
+ }
+ if (ft->encoding.bits_per_sample > 0)
+ reqpar.bits = ft->encoding.bits_per_sample;
+ if (ft->encoding.reverse_bytes != SOX_OPTION_DEFAULT) {
+ reqpar.le = SIO_LE_NATIVE;
+ if (ft->encoding.reverse_bytes)
+ reqpar.le = !reqpar.le;
+ }
+ if (!sio_setpar(p->hdl, &reqpar) ||
+ !sio_getpar(p->hdl, &p->par))
+ goto failed;
+ ft->signal.channels = (mode == SIO_PLAY) ? p->par.pchan : p->par.rchan;
+ ft->signal.precision = p->par.bits;
+ ft->signal.rate = p->par.rate;
+ ft->encoding.encoding = p->par.sig ? SOX_ENCODING_SIGN2 : SOX_ENCODING_UNSIGNED;
+ ft->encoding.bits_per_sample = p->par.bps * 8;
+ ft->encoding.reverse_bytes = SIO_LE_NATIVE ? !p->par.le : p->par.le;
+ ft->encoding.reverse_nibbles = SOX_OPTION_NO;
+ ft->encoding.reverse_bits = SOX_OPTION_NO;
+
+ if (!sio_start(p->hdl))
+ goto failed;
+ return SOX_SUCCESS;
+ failed:
+ sio_close(p->hdl);
+ return SOX_EOF;
+}
+
+static int stopany(struct sox_format *ft)
+{
+ sio_close(((struct sndio_priv *)ft->priv)->hdl);
+ return SOX_SUCCESS;
+}
+
+static int startread(struct sox_format *ft)
+{
+ return startany(ft, SIO_REC);
+}
+
+static int startwrite(struct sox_format *ft)
+{
+ return startany(ft, SIO_PLAY);
+}
+
+static size_t readsamples(sox_format_t *ft, sox_sample_t *buf, size_t len)
+{
+ struct sndio_priv *p = (struct sndio_priv *)ft->priv;
+ unsigned char partial[4];
+ unsigned cpb, cc, pc;
+ size_t todo, n;
+
+ pc = 0;
+ todo = len * p->par.bps;
+ cpb = SNDIO_BUFSZ - (SNDIO_BUFSZ % p->par.bps);
+ while (todo > 0) {
+ memcpy(p->buf, partial, pc);
+ cc = cpb - pc;
+ if (cc > todo)
+ cc = todo;
+ n = sio_read(p->hdl, p->buf + pc, cc);
+ if (n == 0 && sio_eof(p->hdl))
+ break;
+ n += pc;
+ pc = n % p->par.bps;
+ n -= pc;
+ memcpy(partial, p->buf + n, pc);
+ decode(&p->par, p->buf, buf, n / p->par.bps);
+ buf += n / p->par.bps;
+ todo -= n;
+ }
+ return len - todo / p->par.bps;
+}
+
+static size_t writesamples(sox_format_t *ft, const sox_sample_t *buf, size_t len)
+{
+ struct sndio_priv *p = (struct sndio_priv *)ft->priv;
+ unsigned sc, spb;
+ size_t n, todo;
+
+ todo = len;
+ spb = SNDIO_BUFSZ / p->par.bps;
+ while (todo > 0) {
+ sc = spb;
+ if (sc > todo)
+ sc = todo;
+ encode(&p->par, buf, p->buf, sc);
+ n = sio_write(p->hdl, p->buf, sc * p->par.bps);
+ if (n == 0 && sio_eof(p->hdl))
+ break;
+ n /= p->par.bps;
+ todo -= n;
+ buf += n;
+ }
+ return len - todo;
+}
+
+SOX_FORMAT_HANDLER(sndio)
+{
+ static char const * const names[] = {"sndio", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 32, 24, 16, 8, 0,
+ SOX_ENCODING_UNSIGNED, 32, 24, 16, 8, 0,
+ 0
+ };
+ static sox_format_handler_t const handler = {
+ SOX_LIB_VERSION_CODE,
+ "libsndio device driver",
+ names,
+ SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
+ startread, readsamples, stopany,
+ startwrite, writesamples, stopany,
+ NULL, write_encodings, NULL,
+ sizeof(struct sndio_priv)
+ };
+ return &handler;
+}
--- a/src/sox.c
+++ b/src/sox.c
@@ -2258,9 +2258,15 @@
if (!type)
return NULL;
- if (!strcmp(type, "sunau")) name = "/dev/audio";
- else if (!strcmp(type, "oss" ) || !strcmp(type, "ossdsp")) name = "/dev/dsp";
- else if (!strcmp(type, "alsa") || !strcmp(type, "ao") || !strcmp(type, "coreaudio") || !strcmp(type, "pulseaudio")) name = "default";
+
+ if (!strcmp(type, "sunau"))
+ name = "/dev/audio";
+ else if (!strcmp(type, "oss" ) || !strcmp(type, "ossdsp"))
+ name = "/dev/dsp";
+ else if (!strcmp(type, "alsa") || !strcmp(type, "ao") || !strcmp(type,"sndio")
+ || !strcmp(type, "coreaudio") || !strcmp(type, "pulseaudio"))
+ name = "default";
+
return name? from_env? from_env : name : NULL;
}
@@ -2273,6 +2279,7 @@
if (!f->filetype && sox_find_format("oss" , sox_false)) f->filetype = "oss";
if (!f->filetype && sox_find_format("pulseaudio" , sox_false)) f->filetype = "pulseaudio";
if (!f->filetype && sox_find_format("sunau",sox_false)) f->filetype = "sunau";
+ if (!f->filetype && sox_find_format("sndio", sox_false)) f->filetype = "sndio";
if (!f->filetype && sox_find_format("ao" , sox_false) && file_count) /*!rec*/
f->filetype = "ao";
--- a/src/sox.h
+++ b/src/sox.h
@@ -32,7 +32,7 @@
* Please do not count on these numbers being in sync.
*/
#define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#define SOX_LIB_VERSION_CODE SOX_LIB_VERSION(14, 2, 0)
+#define SOX_LIB_VERSION_CODE SOX_LIB_VERSION(14, 3, 0)
const char *sox_version(void); /* Returns version number */
--- a/src/soxconfig.h.cmake
+++ b/src/soxconfig.h.cmake
@@ -1,4 +1,4 @@
-#define PACKAGE_VERSION "14.2.0"
+#define PACKAGE_VERSION "14.3.0"
#cmakedefine EXTERNAL_GSM 1
#cmakedefine HAVE_ALSA 1
@@ -28,6 +28,7 @@
#cmakedefine HAVE_PNG 1
#cmakedefine HAVE_SNDFILE_1_0_12 1
#cmakedefine HAVE_SNDFILE 1
+#cmakedefine HAVE_SNDIO 1
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STRCASECMP 1
#cmakedefine HAVE_STRINGS_H 1