diff --git a/include/config.h.in b/include/config.h.in index 0f67e74..fa21203 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -69,6 +69,9 @@ /* libao win support */ #undef LIBAO_WIN +/* libao sndio support */ +#undef LIBAO_SNDIO + /* Name of package */ #undef PACKAGE diff --git a/libao/Makefile.am b/libao/Makefile.am index 9b1f1cc..3b97b9f 100644 --- a/libao/Makefile.am +++ b/libao/Makefile.am @@ -2,6 +2,6 @@ noinst_LIBRARIES = libao.a libao_a_SOURCES = audio_out.c float2s16.c audio_out_null.c audio_out_float.c \ audio_out_oss.c audio_out_solaris.c audio_out_al.c \ audio_out_win.c audio_out_wav.c audio_out_aif.c \ - audio_out_peak.c + audio_out_peak.c audio_out_sndio.c EXTRA_DIST = configure.incl audio_out_internal.h diff --git a/libao/Makefile.in b/libao/Makefile.in index b80e62a..846021e 100644 --- a/libao/Makefile.in +++ b/libao/Makefile.in @@ -77,7 +77,7 @@ STRIP = @STRIP@ VERSION = @VERSION@ noinst_LIBRARIES = libao.a -libao_a_SOURCES = audio_out.c float2s16.c audio_out_null.c audio_out_float.c audio_out_oss.c audio_out_solaris.c audio_out_al.c audio_out_win.c audio_out_wav.c audio_out_aif.c audio_out_peak.c +libao_a_SOURCES = audio_out.c float2s16.c audio_out_null.c audio_out_float.c audio_out_oss.c audio_out_solaris.c audio_out_al.c audio_out_win.c audio_out_wav.c audio_out_aif.c audio_out_peak.c audio_out_sndio.c EXTRA_DIST = configure.incl audio_out_internal.h @@ -96,7 +96,7 @@ libao_a_OBJECTS = audio_out.$(OBJEXT) float2s16.$(OBJEXT) \ audio_out_null.$(OBJEXT) audio_out_float.$(OBJEXT) \ audio_out_oss.$(OBJEXT) audio_out_solaris.$(OBJEXT) \ audio_out_al.$(OBJEXT) audio_out_win.$(OBJEXT) audio_out_wav.$(OBJEXT) \ -audio_out_aif.$(OBJEXT) audio_out_peak.$(OBJEXT) +audio_out_aif.$(OBJEXT) audio_out_peak.$(OBJEXT) audio_out_sndio.$(OBJEXT) AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -243,6 +243,8 @@ audio_out_solaris.o: audio_out_solaris.c ../include/config.h audio_out_wav.o: audio_out_wav.c ../include/config.h ../include/a52.h \ ../include/audio_out.h audio_out_internal.h audio_out_win.o: audio_out_win.c ../include/config.h +audio_out_sndio.o: audio_out_sndio.c ../include/config.h ../include/a52.h \ + ../include/audio_out.h audio_out_internal.h float2s16.o: float2s16.c ../include/config.h ../include/a52.h \ ../include/audio_out.h diff --git a/libao/audio_out.c b/libao/audio_out.c index bf8aca8..130029e 100644 --- a/libao/audio_out.c +++ b/libao/audio_out.c @@ -33,6 +33,10 @@ extern ao_open_t ao_oss_open; extern ao_open_t ao_ossdolby_open; extern ao_open_t ao_oss4_open; extern ao_open_t ao_oss6_open; +extern ao_open_t ao_sndio_open; +extern ao_open_t ao_sndiodolby_open; +extern ao_open_t ao_sndio4_open; +extern ao_open_t ao_sndio6_open; extern ao_open_t ao_solaris_open; extern ao_open_t ao_solarisdolby_open; extern ao_open_t ao_al_open; @@ -59,6 +63,12 @@ static ao_driver_t audio_out_drivers[] = { {"oss4", ao_oss4_open}, {"oss6", ao_oss6_open}, #endif +#ifdef LIBAO_SNDIO + {"sndio", ao_sndio_open}, + {"sndiodolby", ao_sndiodolby_open}, + {"sndio4", ao_sndio4_open}, + {"sndio6", ao_sndio6_open}, +#endif #ifdef LIBAO_SOLARIS {"solaris", ao_solaris_open}, {"solarisdolby", ao_solarisdolby_open}, diff --git b/libao/audio_out_sndio.c b/libao/audio_out_sndio.c new file mode 100644 index 0000000..27c55cb --- /dev/null +++ b/libao/audio_out_sndio.c @@ -0,0 +1,170 @@ +/* + * audio_out_sndio.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec 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 of the License, or + * (at your option) any later version. + * + * a52dec 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#ifdef LIBAO_SNDIO + +#include +#include +#include +#include + +#include "a52.h" +#include "audio_out.h" +#include "audio_out_internal.h" + +typedef struct sndio_instance_s { + ao_instance_t ao; + struct sio_hdl *hdl; + int sample_rate; + int set_params; + int flags; +} sndio_instance_t; + +static int sndio_setup (ao_instance_t * _instance, int sample_rate, int * flags, + sample_t * level, sample_t * bias) +{ + sndio_instance_t * instance = (sndio_instance_t *) _instance; + + if ((instance->set_params == 0) && (instance->sample_rate != sample_rate)) + return 1; + instance->sample_rate = sample_rate; + + *flags = instance->flags; + *level = 1; + *bias = 384; + + return 0; +} + +static int sndio_play (ao_instance_t * _instance, int flags, sample_t * _samples) +{ + sndio_instance_t * instance = (sndio_instance_t *) _instance; + int16_t int16_samples[256*6]; + int chans = -1; + +#ifdef LIBA52_DOUBLE + float samples[256 * 6]; + int i; + + for (i = 0; i < 256 * 6; i++) + samples[i] = _samples[i]; +#else + float * samples = _samples; +#endif + + chans = channels_multi (flags); + flags &= A52_CHANNEL_MASK | A52_LFE; + + if (instance->set_params) { + struct sio_par par; + + sio_initpar(&par); + par.bits = 16; + par.sig = 1; + par.le = SIO_LE_NATIVE; + par.pchan = chans; + par.rate = instance->sample_rate; + if (!sio_setpar(instance->hdl, &par) || !sio_setpar(instance->hdl, &par)) { + fprintf (stderr, "Can not set audio parameters\n"); + return 1; + } + if (par.bits != 16 || par.sig != 1 || par.le != SIO_LE_NATIVE || + par.pchan != chans || par.rate != instance->sample_rate) { + fprintf (stderr, "Unsupported audio parameters\n"); + return 1; + } + instance->flags = flags; + instance->set_params = 0; + sio_start(instance->hdl); + } else if ((flags == A52_DOLBY) && (instance->flags == A52_STEREO)) { + fprintf (stderr, "Switching from stereo to dolby surround\n"); + instance->flags = A52_DOLBY; + } else if ((flags == A52_STEREO) && (instance->flags == A52_DOLBY)) { + fprintf (stderr, "Switching from dolby surround to stereo\n"); + instance->flags = A52_STEREO; + } else if (flags != instance->flags) + return 1; + + float2s16_multi (samples, int16_samples, flags); + sio_write (instance->hdl, int16_samples, 256 * sizeof (int16_t) * chans); + + return 0; +} + +static void sndio_close (ao_instance_t * _instance) +{ + sndio_instance_t * instance = (sndio_instance_t *) _instance; + + sio_close (instance->hdl); +} + +static ao_instance_t * sndio_open (int flags) +{ + sndio_instance_t * instance; + int format; + + instance = (sndio_instance_t *) malloc (sizeof (sndio_instance_t)); + if (instance == NULL) + return NULL; + + instance->ao.setup = sndio_setup; + instance->ao.play = sndio_play; + instance->ao.close = sndio_close; + + instance->sample_rate = 0; + instance->set_params = 1; + instance->flags = flags; + + instance->hdl = sio_open (SIO_DEVANY, SIO_PLAY, 0); + if (instance->hdl == NULL) { + fprintf (stderr, "Can not open " SIO_DEVANY " device\n"); + free (instance); + return NULL; + } + + return (ao_instance_t *) instance; +} + +ao_instance_t * ao_sndio_open (void) +{ + return sndio_open (A52_STEREO); +} + +ao_instance_t * ao_sndiodolby_open (void) +{ + return sndio_open (A52_DOLBY); +} + +ao_instance_t * ao_sndio4_open (void) +{ + return sndio_open (A52_2F2R); +} + +ao_instance_t * ao_sndio6_open (void) +{ + return sndio_open (A52_3F2R | A52_LFE); +} + +#endif diff --git a/libao/configure.incl b/libao/configure.incl index 6c6ad6b..294713e 100644 --- a/libao/configure.incl +++ b/libao/configure.incl @@ -12,6 +12,15 @@ if test x"$enable_oss" != x"no"; then esac fi +dnl check for sndio +AC_ARG_ENABLE([sndio], + [ --disable-sndio make a version not using sndio]) +if test x"$enable_sndio" != x"no"; then + AC_DEFINE([LIBAO_SNDIO],,[libao SNDIO support]) + AC_CHECK_LIB([sndio],[sio_initpar], + [LIBAO_LIBS="$LIBAO_LIBS -lsndio"]) +fi + dnl check for solaris AC_ARG_ENABLE([solaris-audio], [ --disable-solaris-audio make a version not using solaris audio])