vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Wed Feb 1 22:10:39 2012 +0200| [28b099a27b92150402b2e851cc44d14ed99caa4c] | committer: Rémi Denis-Courmont
sndio: add OpenBSD (or RoarAudio emulation) audio output This is untested but at least it compiles with RoarAudio. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=28b099a27b92150402b2e851cc44d14ed99caa4c --- configure.ac | 18 ++++ modules/LIST | 1 + modules/audio_output/Modules.am | 8 ++ modules/audio_output/sndio.c | 206 +++++++++++++++++++++++++++++++++++++++ po/POTFILES.in | 1 + 5 files changed, 234 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index e8c5674..c2ebdc6 100644 --- a/configure.ac +++ b/configure.ac @@ -3435,6 +3435,24 @@ AC_SUBST(OSS_LIBS) AM_CONDITIONAL([HAVE_OSS], [test "${have_oss}" = "yes"]) dnl +dnl OpenBSD sndio module +dnl +AC_ARG_ENABLE([sndio], + [AS_HELP_STRING([--disable-sndio], + [support the OpenBSD sndio (default auto)])],, [ + AS_IF([test "$SYS" = "opensd"], [ + enable_sndio="yes" + ]) +]) +have_sndio="no" +AS_IF([test "$enable_sndio" != "no"], [ + AC_CHECK_HEADER([sndio.h], [ + have_sndio="yes" + ]) +]) +AM_CONDITIONAL([HAVE_SNDIO], [test "${have_sndio}" = "yes"]) + +dnl dnl win32 waveOut plugin dnl AC_ARG_ENABLE(waveout, diff --git a/modules/LIST b/modules/LIST index 297789f..b351e8d 100644 --- a/modules/LIST +++ b/modules/LIST @@ -298,6 +298,7 @@ $Id$ * simple_channel_mixer: channel mixer * skins2: Skinnable interface, new generation * smf: Standard MIDI file demuxer + * sndio: OpenBSD sndio audio output * spatializer: A spatializer audio filter * speex: a speex audio decoder/packetizer using the libspeex library * speex_resampler: audio resampler using the libspeexdsp library diff --git a/modules/audio_output/Modules.am b/modules/audio_output/Modules.am index 2733a18..1c571ee 100644 --- a/modules/audio_output/Modules.am +++ b/modules/audio_output/Modules.am @@ -52,3 +52,11 @@ libkai_plugin_la_DEPENDENCIES = if HAVE_KAI libvlc_LTLIBRARIES += libkai_plugin.la endif + +libsndio_plugin_la_SOURCES = sndio.c +libsndio_plugin_la_CFLAGS = $(AM_CFLAGS) +libsndio_plugin_la_LIBADD = $(AM_LIBADD) -lsndio +libsndio_plugin_la_DEPENDENCIES = +if HAVE_SNDIO +libvlc_LTLIBRARIES += libsndio_plugin.la +endif diff --git a/modules/audio_output/sndio.c b/modules/audio_output/sndio.c new file mode 100644 index 0000000..cf11ad0 --- /dev/null +++ b/modules/audio_output/sndio.c @@ -0,0 +1,206 @@ +/***************************************************************************** + * sndio.c : sndio plugin for VLC + ***************************************************************************** + * Copyright (C) 2012 Rémi Denis-Courmont + * + * This program 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.1 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_aout.h> + +#include <sndio.h> + +static int Open (vlc_object_t *); +static void Close (vlc_object_t *); + +vlc_module_begin () + set_shortname ("sndio") + set_description (N_("OpenBSD sndio audio output")) + set_category (CAT_AUDIO) + set_subcategory (SUBCAT_AUDIO_AOUT) + set_capability ("audio output", 120) + set_callbacks (Open, Close ) +vlc_module_end () + +static void Play (audio_output_t *, block_t *); +static void Pause (audio_output_t *, bool, mtime_t); + +/** Initializes an sndio playback stream */ +static int Open (vlc_object_t *obj) +{ + audio_output_t *aout = (audio_output_t *)obj; + + struct sio_hdl *sio = sio_open (NULL, SIO_PLAY, 0 /* blocking */); + if (sio == NULL) + { + msg_Err (obj, "cannot create audio playback stream"); + return VLC_EGENERIC; + } + + struct sio_par par; + sio_initpar (&par); + par.bits = 16; + par.bps = par.bits >> 3; + par.sig = 1; + par.le = SIO_LE_NATIVE; + par.pchan = aout_FormatNbChannels (&aout->format); + par.rate = aout->format.i_rate; + par.xrun = SIO_SYNC; + + if (!sio_setpar (sio, &par) || !sio_getpar (sio, &par)) + { + msg_Err (obj, "cannot negotiate audio playback parameters"); + goto error; + } + + if (par.bps != par.bits >> 3) + { + msg_Err (obj, "unsupported audio sample format (%u bits in %u bytes)", + par.bits, par.bps); + goto error; + } + + audio_format_t f; + + switch (par.bps) + { + case 8: + f.i_format = par.sig ? VLC_CODEC_S8 : VLC_CODEC_U8; + break; + case 16: + f.i_format = par.sig ? (par.le ? VLC_CODEC_S16L : VLC_CODEC_S16B) + : (par.le ? VLC_CODEC_U16L : VLC_CODEC_U16B); + break; + case 24: + f.i_format = par.sig ? (par.le ? VLC_CODEC_S24L : VLC_CODEC_S24B) + : (par.le ? VLC_CODEC_U24L : VLC_CODEC_U24B); + break; + case 32: + f.i_format = par.sig ? (par.le ? VLC_CODEC_S32L : VLC_CODEC_S32B) + : (par.le ? VLC_CODEC_U32L : VLC_CODEC_U32B); + break; + default: + msg_Err (obj, "unsupported audio sample format (%u bits)", + par.bits); + goto error; + } + + f.i_rate = par.rate; + + /* Channel map */ + unsigned chans; + switch (par.pchan) + { + case 1: + chans = AOUT_CHAN_CENTER; + break; + case 2: + chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + break; + case 4: + chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; + break; + case 6: + chans = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT + | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT + | AOUT_CHAN_CENTER | AOUT_CHAN_LFE; + break; + default: + msg_Err (aout, "unknown %u channels map", par.pchan); + goto error; + } + + f.i_original_channels = f.i_physical_channels = chans; + aout_FormatPrepare (&f); + + aout->format = f; + aout->sys = (void *)sio; + aout->pf_play = Play; + aout->pf_pause = Pause; + aout->pf_flush = NULL; /* sndio sucks! */ + aout_VolumeSoftInit (aout); /* TODO: sio_onvol() */ + + sio_start (sio); + return VLC_SUCCESS; + +error: + sio_close (sio); + return VLC_EGENERIC; +} + +static void Close (vlc_object_t *obj) +{ + audio_output_t *aout = (audio_output_t *)obj; + struct sio_hdl *sio = (void *)aout->sys; + + sio_close (sio); +} + +static void Play (audio_output_t *aout, block_t *block) +{ + struct sio_hdl *sio = (void *)aout->sys; + struct sio_par par; + + if (sio_getpar (sio, &par) == 0) + { + mtime_t delay = par.bufsz * CLOCK_FREQ / aout->format.i_rate; + + delay = block->i_pts - (mdate () - delay); + if (delay > 0) + { + size_t frames = (delay * aout->format.i_rate) / CLOCK_FREQ; + msg_Dbg (aout, "prepending %zu zeroes", frames); + + void *pad = calloc (frames, aout->format.i_bytes_per_frame); + if (likely(pad != NULL)) + { + sio_write (sio, pad, frames * aout->format.i_bytes_per_frame); + free (pad); + } + } + else + aout_TimeReport (aout, block->i_pts - delay); + } + + while (block->i_buffer > 0 && !sio_eof (sio)) + { + size_t bytes = sio_write (sio, block->p_buffer, block->i_buffer); + + block->p_buffer += bytes; + block->i_buffer -= bytes; + /* Note that i_nb_samples and i_pts are corrupted here. */ + } + block_Release (block); +} + +static void Pause (audio_output_t *aout, bool pause, mtime_t date) +{ + struct sio_hdl *sio = (void *)aout->sys; + + if (pause) + sio_stop (sio); + else + sio_start (sio); + (void) date; +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 4932b0c..50b2186 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -339,6 +339,7 @@ modules/audio_output/kai.c modules/audio_output/opensles_android.c modules/audio_output/oss.c modules/audio_output/pulse.c +modules/audio_output/sndio.c modules/audio_output/waveout.c modules/audio_output/windows_audio_common.h modules/codec/a52.c _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
