From 48e85562982aee72f055b5ca523ff73bfe34cc43 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 24 Jun 2011 15:56:43 +0200 Subject: [PATCH] ao_rsound: add new RSound audio output driver --- DOCS/man/en/mplayer.1 | 15 +++ Makefile | 1 + configure | 22 +++++ libao2/ao_rsound.c | 214 ++++++++++++++++++++++++++++++++++++++++++ libao2/audio_out.c | 4 + 5 files changed, 256 insertions(+) create mode 100644 libao2/ao_rsound.c diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index 3ca8ff01f5..dc9a936632 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -3022,6 +3022,21 @@ If nowaveheader is specified, the default is audiodump.pcm. .PD 1 . .TP +.B "rsound\ \ \ \ " +audio output to an RSound daemon +.PD 0 +.RSs +.IPs host= +Set the address of the server (default: localhost). +Can be either a network hostname for TCP connections or a Unix domain +socket path starting with '/'. +.IPs port= +Set the TCP port used for connecting to the server (default: 12345). +Not used if connecting to a Unix domain socket. +.RE +.PD 1 +. +.TP .B "plugin\ \ " plugin audio output driver . diff --git a/Makefile b/Makefile index 1b0b68c719..51c522aeb0 100644 --- a/Makefile +++ b/Makefile @@ -490,6 +490,7 @@ SRCS_MPLAYER-$(OSS) += libao2/ao_oss.c SRCS_MPLAYER-$(PNM) += libvo/vo_pnm.c SRCS_MPLAYER-$(PULSE) += libao2/ao_pulse.c SRCS_MPLAYER-$(QUARTZ) += libvo/vo_quartz.c libvo/osx_common.c +SRCS_MPLAYER-$(RSOUND) += libao2/ao_rsound.c SRCS_MPLAYER-$(S3FB) += libvo/vo_s3fb.c SRCS_MPLAYER-$(SDL) += libao2/ao_sdl.c libvo/vo_sdl.c libvo/sdl_common.c SRCS_MPLAYER-$(SGIAUDIO) += libao2/ao_sgi.c diff --git a/configure b/configure index 4a01a855b8..4fe5f6805e 100755 --- a/configure +++ b/configure @@ -428,6 +428,7 @@ Audio output: --disable-ossaudio disable OSS audio output [autodetect] --disable-arts disable aRts audio output [autodetect] --disable-esd disable esd audio output [autodetect] + --disable-rsound disable RSound audio output [autodetect] --disable-pulse disable Pulseaudio audio output [autodetect] --disable-jack disable JACK audio output [autodetect] --enable-openal enable OpenAL audio output [disable] @@ -591,6 +592,7 @@ _rtc=auto _ossaudio=auto _arts=auto _esd=auto +_rsound=auto _pulse=auto _jack=auto _kai=auto @@ -919,6 +921,8 @@ for ac_option do --disable-arts) _arts=no ;; --enable-esd) _esd=yes ;; --disable-esd) _esd=no ;; + --enable-rsound) _rsound=yes ;; + --disable-rsound) _rsound=no ;; --enable-pulse) _pulse=yes ;; --disable-pulse) _pulse=no ;; --enable-jack) _jack=yes ;; @@ -4859,6 +4863,22 @@ else noaomodules="esd $noaomodules" fi +echocheck "RSound" +if test "$_rsound" = auto ; then + _rsound=no + statement_check rsound.h 'rsd_init(NULL);' -lrsound && _rsound=yes +fi +echores "$_rsound" + +if test "$_rsound" = yes ; then + def_rsound='#define CONFIG_RSOUND 1' + aomodules="rsound $aomodules" + libs_mplayer="$libs_mplayer -lrsound" +else + def_rsound='#undef CONFIG_RSOUND' + noaomodules="rsound $noaomodules" +fi + echocheck "NAS" if test "$_nas" = auto ; then @@ -6777,6 +6797,7 @@ QUARTZ = $_quartz RADIO=$_radio RADIO_CAPTURE=$_radio_capture REAL_CODECS = $_real +RSOUND = $_rsound S3FB = $_s3fb SDL = $_sdl SPEEX = $_speex @@ -7058,6 +7079,7 @@ $def_ossaudio $def_ossaudio_devdsp $def_ossaudio_devmixer $def_pulse +$def_rsound $def_sgiaudio $def_sunaudio $def_win32waveout diff --git a/libao2/ao_rsound.c b/libao2/ao_rsound.c new file mode 100644 index 0000000000..9a8b8cb4fc --- /dev/null +++ b/libao2/ao_rsound.c @@ -0,0 +1,214 @@ +/* + * RSound audio output driver + * + * Copyright (C) 2011 Hans-Kristian Arntzen + * + * This file is part of mplayer2. + * + * mplayer2 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. + * + * mplayer2 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 mplayer2; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "talloc.h" + +#include "subopt-helper.h" +#include "osdep/timer.h" +#include "libaf/af_format.h" +#include "audio_out.h" + +struct priv { + rsound_t *rd; +}; + +static int set_format(struct ao *ao) +{ + int rsd_format; + + switch (ao->format) { + case AF_FORMAT_U8: + rsd_format = RSD_U8; + break; + case AF_FORMAT_S8: + rsd_format = RSD_S8; + break; + case AF_FORMAT_S16_LE: + rsd_format = RSD_S16_LE; + break; + case AF_FORMAT_S16_BE: + rsd_format = RSD_S16_BE; + break; + case AF_FORMAT_U16_LE: + rsd_format = RSD_U16_LE; + break; + case AF_FORMAT_U16_BE: + rsd_format = RSD_U16_BE; + break; + case AF_FORMAT_S24_LE: + case AF_FORMAT_S24_BE: + case AF_FORMAT_U24_LE: + case AF_FORMAT_U24_BE: + rsd_format = RSD_S32_LE; + ao->format = AF_FORMAT_S32_LE; + break; + case AF_FORMAT_S32_LE: + rsd_format = RSD_S32_LE; + break; + case AF_FORMAT_S32_BE: + rsd_format = RSD_S32_BE; + break; + case AF_FORMAT_U32_LE: + rsd_format = RSD_U32_LE; + break; + case AF_FORMAT_U32_BE: + rsd_format = RSD_U32_BE; + break; + case AF_FORMAT_A_LAW: + rsd_format = RSD_ALAW; + break; + case AF_FORMAT_MU_LAW: + rsd_format = RSD_MULAW; + break; + default: + rsd_format = RSD_S16_LE; + ao->format = AF_FORMAT_S16_LE; + } + + return rsd_format; +} + +static int init(struct ao *ao, char *params) +{ + struct priv *priv = talloc_zero(ao, struct priv); + ao->priv = priv; + + char *host = NULL; + char *port = NULL; + + const opt_t subopts[] = { + {"host", OPT_ARG_MSTRZ, &host, NULL}, + {"port", OPT_ARG_MSTRZ, &port, NULL}, + {NULL} + }; + + if (subopt_parse(params, subopts) != 0) + return -1; + + if (rsd_init(&priv->rd) < 0) { + free(host); + free(port); + return -1; + } + + if (host) { + rsd_set_param(priv->rd, RSD_HOST, host); + free(host); + } + + if (port) { + rsd_set_param(priv->rd, RSD_PORT, port); + free(port); + } + + rsd_set_param(priv->rd, RSD_SAMPLERATE, &ao->samplerate); + rsd_set_param(priv->rd, RSD_CHANNELS, &ao->channels); + + int rsd_format = set_format(ao); + rsd_set_param(priv->rd, RSD_FORMAT, &rsd_format); + + if (rsd_start(priv->rd) < 0) { + rsd_free(priv->rd); + return -1; + } + + ao->bps = ao->channels * ao->samplerate * af_fmt2bits(ao->format) / 8; + + return 0; +} + +static void uninit(struct ao *ao, bool cut_audio) +{ + struct priv *priv = ao->priv; + /* The API does not provide a direct way to explicitly wait until + * the last byte has been played server-side as this cannot be + * guaranteed by backend drivers, so we approximate this behavior. + */ + if (!cut_audio) + usec_sleep(rsd_delay_ms(priv->rd) * 1000); + + rsd_stop(priv->rd); + rsd_free(priv->rd); +} + +static void reset(struct ao *ao) +{ + struct priv *priv = ao->priv; + rsd_stop(priv->rd); + rsd_start(priv->rd); +} + +static void audio_pause(struct ao *ao) +{ + struct priv *priv = ao->priv; + rsd_pause(priv->rd, 1); +} + +static void audio_resume(struct ao *ao) +{ + struct priv *priv = ao->priv; + rsd_pause(priv->rd, 0); +} + +static int get_space(struct ao *ao) +{ + struct priv *priv = ao->priv; + return rsd_get_avail(priv->rd); +} + +static int play(struct ao *ao, void *data, int len, int flags) +{ + struct priv *priv = ao->priv; + return rsd_write(priv->rd, data, len); +} + +static float get_delay(struct ao *ao) +{ + struct priv *priv = ao->priv; + return rsd_delay_ms(priv->rd) / 1000.0; +} + +const struct ao_driver audio_out_rsound = { + .is_new = true, + .info = &(const struct ao_info) { + .name = "RSound output driver", + .short_name = "rsound", + .author = "Hans-Kristian Arntzen", + .comment = "", + }, + .init = init, + .uninit = uninit, + .reset = reset, + .get_space = get_space, + .play = play, + .get_delay = get_delay, + .pause = audio_pause, + .resume = audio_resume, +}; + diff --git a/libao2/audio_out.c b/libao2/audio_out.c index 2ad147d8a5..14cab9b285 100644 --- a/libao2/audio_out.c +++ b/libao2/audio_out.c @@ -35,6 +35,7 @@ char *ao_subdevice = NULL; extern const struct ao_driver audio_out_oss; extern const struct ao_driver audio_out_coreaudio; extern const struct ao_driver audio_out_arts; +extern const struct ao_driver audio_out_rsound; extern const struct ao_driver audio_out_esd; extern const struct ao_driver audio_out_pulse; extern const struct ao_driver audio_out_jack; @@ -120,6 +121,9 @@ static const struct ao_driver * const audio_out_drivers[] = { &audio_out_null, // should not be auto-selected: &audio_out_pcm, +#ifdef CONFIG_RSOUND + &audio_out_rsound, +#endif NULL };