From 425ac31a3b07cbef79891d01a3655b9c6d7efa32 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 21:41:22 +0200 Subject: [PATCH] softvol, ao_pulse: prefer ao_pulse volume control by default --softvol is enabled by default. For most audio outputs, this is a good thing, as they have either their own (bad) soft volume implementation, or control the system mixer. With ao_pulse, the situation is a bit different: it supports per-application volume (i.e. volume control is not really global). More importantly, ao_pulse uses a rather large audio buffer, and changing the volume with mplayer's volume filter has a large delay. With the native ao_pulse volume control, it's instant, because PulseAudio's audio filtering happens at a later stage in its processing pipeline (inaccessible for mplayer). This means native volume control should really be allowed for ao_pulse, while it's the reverse for other audio outputs. Make --softvol a choice option, and add a new "auto" choice. This is default and will use PA's volume control with ao_pulse, and mplayer's volume filter otherwise (i.e. the old softvol behavior). --- DOCS/man/en/options.rst | 16 +++++++++++++--- cfg-mplayer.h | 5 ++++- defaultopts.c | 3 ++- libao2/ao_pulse.c | 2 ++ libao2/audio_out.h | 1 + mixer.c | 7 ++++++- mixer.h | 8 +++++++- 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index 431ff1a7de..653cac9737 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1741,9 +1741,19 @@ timing is imprecise and you cannot use the RTC either. Comes at the price of higher CPU consumption. ---no-softvol - Try to use the sound card mixer (if available), instead of using the volume - audio filter. +--softvol= + Control whether to use the volume controls of the audio output driver, or + the internal mplayer volume filter. + + :no: prefer audio driver controls, use the volume filter only if + absolutely needed + :yes: always use the volume filter + :auto: prefer the volume filter if the audio driver uses the system mixer (default) + + The intention with ``auto`` is to avoid changing system mixer settings with + default settings. mplayer is a video player, not a mixer panel. On the other + hand, mixer controls should be used for sound servers like PulseAudio, which + provide per-application volume. --softvol-max=<10.0-10000.0> Set the maximum amplification level in percent (default: 200). A value of diff --git a/cfg-mplayer.h b/cfg-mplayer.h index ed3fef7304..a6b8e93647 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -587,7 +587,10 @@ const m_option_t mplayer_opts[]={ OPT_STRING("mixer", mixer_device, 0), OPT_STRING("mixer-channel", mixer_channel, 0), - OPT_MAKE_FLAGS("softvol", softvol, 0), + OPT_CHOICE("softvol", softvol, 0, + ({"no", SOFTVOL_NO}, + {"yes", SOFTVOL_YES}, + {"auto", SOFTVOL_AUTO})), OPT_FLOATRANGE("softvol-max", softvol_max, 0, 10, 10000), {"volstep", &volstep, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL}, {"volume", &start_volume, CONF_TYPE_FLOAT, CONF_RANGE, -1, 10000, NULL}, diff --git a/defaultopts.c b/defaultopts.c index 672dbd5f5c..422841ad65 100644 --- a/defaultopts.c +++ b/defaultopts.c @@ -3,6 +3,7 @@ #include "config.h" #include "defaultopts.h" #include "options.h" +#include "mixer.h" void set_default_mplayer_options(struct MPOpts *opts) { @@ -10,7 +11,7 @@ void set_default_mplayer_options(struct MPOpts *opts) .audio_driver_list = NULL, .video_driver_list = NULL, .fixed_vo = 1, - .softvol = 1, + .softvol = SOFTVOL_AUTO, .softvol_max = 200, .ao_buffersize = -1, .vo_wintitle = "mplayer - ${filename}", diff --git a/libao2/ao_pulse.c b/libao2/ao_pulse.c index 0b1f22ff8d..d1282cb2dc 100644 --- a/libao2/ao_pulse.c +++ b/libao2/ao_pulse.c @@ -184,6 +184,8 @@ static int init(struct ao *ao, char *params) struct priv *priv = talloc_zero(ao, struct priv); ao->priv = priv; + ao->per_application_mixer = true; + if (params) { devarg = strdup(params); sink = strchr(devarg, ':'); diff --git a/libao2/audio_out.h b/libao2/audio_out.h index 129c815bc3..9e172fd06c 100644 --- a/libao2/audio_out.h +++ b/libao2/audio_out.h @@ -104,6 +104,7 @@ struct ao { bool initialized; bool untimed; bool no_persistent_volume; + bool per_application_mixer; const struct ao_driver *driver; void *priv; struct encode_lavc_context *encode_lavc_ctx; diff --git a/mixer.c b/mixer.c index d01cab8b71..8b52145d62 100644 --- a/mixer.c +++ b/mixer.c @@ -32,10 +32,15 @@ static void checkvolume(struct mixer *mixer) if (!mixer->ao) return; + if (mixer->softvol == SOFTVOL_AUTO) { + mixer->softvol = mixer->ao->per_application_mixer + ? SOFTVOL_NO : SOFTVOL_YES; + } + ao_control_vol_t vol; if (mixer->softvol || CONTROL_OK != ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol)) { - mixer->softvol = true; + mixer->softvol = SOFTVOL_YES; if (!mixer->afilter) return; float db_vals[AF_NCH]; diff --git a/mixer.h b/mixer.h index efeb62856f..3ba44ad0df 100644 --- a/mixer.h +++ b/mixer.h @@ -24,11 +24,17 @@ #include "libaf/af.h" #include "libao2/audio_out.h" +enum { + SOFTVOL_NO = 0, + SOFTVOL_YES = 1, + SOFTVOL_AUTO = 2, +}; + typedef struct mixer { struct ao *ao; af_stream_t *afilter; int volstep; - bool softvol; + int softvol; float softvol_max; bool muted; bool muted_by_us;