mirror of https://github.com/mpv-player/mpv
ao_rsound: add new RSound audio output driver
This commit is contained in:
parent
12843385fe
commit
48e8556298
|
@ -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=<name/path>
|
||||
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=<number>
|
||||
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
|
||||
.
|
||||
|
|
1
Makefile
1
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <rsound.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue