summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-07-09 18:31:18 +0200
committerwm4 <wm4@nowhere>2016-07-09 18:31:18 +0200
commit995c47da9afacfcc30d8a17d2f2a2268fbf4fdb9 (patch)
tree0442a9134e89408c2d8a791fefc1559d04d2b76f
parentda9590d3681c8779ac50d7722f8b8ad09a47024a (diff)
downloadmpv-995c47da9afacfcc30d8a17d2f2a2268fbf4fdb9.tar.bz2
mpv-995c47da9afacfcc30d8a17d2f2a2268fbf4fdb9.tar.xz
audio: drop --softvol=no and --softvol=auto
Drop the code for switching the volume options and properties between af_volume and AO volume controls. interface-changes.rst mentions the changes in detail. Do this because this was exceedingly complex and had other problems as well. It was also very hard to test. It's just not worth the trouble. Some leftovers like AOCONTROL_HAS_PER_APP_VOLUME will be removed at a later point. Fixes #3322.
-rw-r--r--DOCS/interface-changes.rst17
-rw-r--r--DOCS/man/input.rst36
-rw-r--r--DOCS/man/options.rst35
-rw-r--r--audio/mixer.c278
-rw-r--r--audio/mixer.h11
-rw-r--r--options/options.c13
-rw-r--r--options/options.h5
-rw-r--r--player/audio.c2
-rw-r--r--player/command.c108
-rw-r--r--player/configfiles.c3
10 files changed, 145 insertions, 363 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 99f426be14..d2e1ee4e7f 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -21,6 +21,23 @@ Interface changes
--- mpv 0.18.1 ---
- deprecate --heartbeat-cmd
+ - remove --softvol=no capability:
+ - deprecate --softvol, it now does nothing
+ - --volume, --mute, and the corrsponding properties now always control
+ softvol, and behave as expected without surprises (e.g. you can set
+ them normally while no audio is initialized)
+ - rename --softvol-max to --volume-max (deprecated alias is added)
+ - the --volume-restore-data option and property are removed without
+ replacement. They were _always_ internal, and used for watch-later
+ resume/restore. Now --volume/--mute are saved directly instead.
+ - the previous point means resuming files with older watch-later configs
+ will print an error about missing --volume-restore-data (which you can
+ ignore), and will not restore the previous value
+ - as a consequence, volume controls will no longer control PulseAudio
+ per-application value, or use the system mixer's per-application
+ volume processing
+ - system or per-application volume can still be controlled with the
+ ao-volume and ao-mute properties (there are no command line options)
--- mpv 0.18.0 ---
- now ab-loops are active even if one of the "ab-loop-a"/"-b" properties is
unset ("no"), in which case the start of the file is used if the A loop
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 74f7815d40..1d8bfe30cd 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1234,29 +1234,31 @@ Property list
See ``--hr-seek``.
``mixer-active``
- Return ``yes`` if the audio mixer is active, ``no`` otherwise. This has
- implications for ``--softvol=no`` mode: if the mixer is inactive, changing
- ``volume`` doesn't actually change anything on the system mixer. If the
- ``--volume`` or ``--mute`` option are used, these might not be applied
- properly until the mixer becomes active either. (The options, if set, will
- just overwrite the mixer state at audio initialization.)
+ Return ``yes`` if the audio mixer is active, ``no`` otherwise.
- While the behavior with ``mixer-active==yes`` is relatively well-defined,
- the ``no`` case will provide possibly wrong or insignificant values.
-
- Note that an active mixer does not necessarily imply active audio output,
- although this is implied in the current implementation.
+ This option is relatively useless. Before mpv 0.18.1, it could be used to
+ infer behavior of the ``volume`` property.
``volume`` (RW)
- Current volume (see ``--volume`` for details). Also see ``mixer-active``
- property.
+ Current volume (see ``--volume`` for details).
-``volume-max``
- Current maximum value the volume property can be set to. (This may depend
- on the ``--softvol-max`` option.)
+``volume-max`` (RW)
+ Current maximum value the volume property can be set to. (Equivalent to the
+ ``--volume-max`` property.)
``mute`` (RW)
- Current mute status (``yes``/``no``). Also see ``mixer-active`` property.
+ Current mute status (``yes``/``no``).
+
+``ao-volume`` (RW)
+ System volume. This property is available only if mpv audio output is
+ currently active, and only if the underlying implementation supports volume
+ control. What this option does depends on the API. For example, on ALSA
+ this usually changes system-wide audio, while with PulseAudio this controls
+ per-application volume.
+
+``ao-mute`` (RW)
+ Similar to ``ao-volume``, but controls the mute state. May be unimplemented
+ even if ``ao-volume`` works.
``audio-delay`` (RW)
See ``--audio-delay``.
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 1a5298f903..f9c32e5a9d 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1072,14 +1072,10 @@ Audio
``--volume=<value>``
Set the startup volume. 0 means silence, 100 means no volume reduction or
- amplification. A value of -1 (the default) will not change the volume. See
- also ``--softvol``.
+ amplification. Negative values can be passed for compatibility, but are
+ treated as 0.
- .. note::
-
- This was changed after the mpv 0.9 release. Before that, 100 actually
- meant maximum volume. At the same time, the volume scale was made cubic,
- so the old values won't match up with the new ones anyway.
+ Since mpv 0.18.1, this always controls the internal mixer (aka "softvol").
``--audio-delay=<sec>``
Audio delay in seconds (positive or negative float value). Positive values
@@ -1094,20 +1090,17 @@ Audio
See also: ``--volume``.
-``--softvol=<mode>``
- Control whether to use the volume controls of the audio output driver or
- the internal mpv volume filter.
+``--softvol=<no|yes|auto>``
+ Deprecated/unfunctional. Before mpv 0.18.1, this used to control whether
+ to use the volume controls of the audio output driver or the internal mpv
+ 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 current behavior is as if this option was set to ``yes``. The other
+ behaviors are not available anymore, although ``auto`` almost matches
+ current behavior in most cases.
- The intention of ``auto`` is to avoid changing system mixer settings from
- within mpv with default settings. mpv is a video player, not a mixer panel.
- On the other hand, mixer controls are enabled for sound servers like
- PulseAudio, which provide per-application volume.
+ The ``no`` behavior is still partially available through the ``ao-volume``
+ and ``ao-mute`` properties. But there are no options to reset these.
``--audio-demuxer=<[+]name>``
Use this audio demuxer type when using ``--audio-file``. Use a '+' before
@@ -1264,10 +1257,12 @@ Audio
their start timestamps differ, and then video timing is gradually adjusted
if necessary to reach correct synchronization later.
-``--softvol-max=<100.0-1000.0>``
+``--volume-max=<100.0-1000.0>``, ``--softvol-max=<...>``
Set the maximum amplification level in percent (default: 130). A value of
130 will allow you to adjust the volume up to about double the normal level.
+ ``--softvol-max`` is a deprecated alias and should not be used.
+
``--audio-file-auto=<no|exact|fuzzy|all>``, ``--no-audio-file-auto``
Load additional audio files matching the video filename. The parameter
specifies how external audio files are matched. ``exact`` is enabled by
diff --git a/audio/mixer.c b/audio/mixer.c
index 01bb4d5088..a251a5aa60 100644
--- a/audio/mixer.c
+++ b/audio/mixer.c
@@ -35,18 +35,6 @@ struct mixer {
struct MPOpts *opts;
struct ao *ao;
struct af_stream *af;
- // Static, dependent on ao/softvol settings
- bool softvol; // use AO (false) or af_volume (true)
- bool persistent_volume; // volume does not need to be restored
- bool emulate_mute; // if true, emulate mute with volume=0
- // Last known values (possibly out of sync with reality)
- float vol_l, vol_r;
- bool muted;
- // Used to decide whether we should unmute on uninit
- bool muted_by_us;
- /* Contains ao driver name or "softvol" if volume is not persistent
- * and needs to be restored after the driver is reinitialized. */
- const char *driver;
// Other stuff
float balance;
};
@@ -57,82 +45,22 @@ struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global)
*mixer = (struct mixer) {
.log = mp_log_new(mixer, global->log, "mixer"),
.opts = global->opts,
- .vol_l = 100,
- .vol_r = 100,
- .driver = "",
};
return mixer;
}
bool mixer_audio_initialized(struct mixer *mixer)
{
- return !!mixer->ao;
+ return !!mixer->af;
}
-float mixer_getmaxvolume(struct mixer *mixer)
+// Called when opts->softvol_volume or opts->softvol_mute were changed.
+void mixer_update_volume(struct mixer *mixer)
{
- // gain == 1
- return mixer->softvol ? mixer->opts->softvol_max : 100;
-}
-
-static void checkvolume(struct mixer *mixer)
-{
- if (!mixer->ao)
- return;
-
- ao_control_vol_t vol = {mixer->vol_l, mixer->vol_r};
- if (mixer->softvol) {
- float gain;
- if (!af_control_any_rev(mixer->af, AF_CONTROL_GET_VOLUME, &gain))
- gain = 1.0;
- vol.left = gain * 100.0;
- vol.right = gain * 100.0;
- } else {
- MP_DBG(mixer, "Reading volume from AO.\n");
- // Rely on the values not changing if the query is not supported
- ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol);
- ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
- }
- float l = mixer->vol_l;
- float r = mixer->vol_r;
- if (mixer->emulate_mute && mixer->muted)
- l = r = 0;
- /* Try to detect cases where the volume has been changed by some external
- * action (such as something else changing a shared system-wide volume).
- * We don't test for exact equality, as some AOs may round the value
- * we last set to some nearby supported value. 3 has been the default
- * volume step for increase/decrease keys, and is apparently big enough
- * to step to the next possible value in most setups.
- */
- if (FFABS(vol.left - l) >= 3 || FFABS(vol.right - r) >= 3) {
- mixer->vol_l = vol.left;
- mixer->vol_r = vol.right;
- if (mixer->emulate_mute)
- mixer->muted = false;
- }
- mixer->muted_by_us &= mixer->muted;
-}
+ float gain = MPMAX(mixer->opts->softvol_volume / 100.0, 0);
+ if (mixer->opts->softvol_mute == 1)
+ gain = 0.0;
-void mixer_getvolume(struct mixer *mixer, float *l, float *r)
-{
- checkvolume(mixer);
- *l = mixer->vol_l;
- *r = mixer->vol_r;
-}
-
-static void setvolume_internal(struct mixer *mixer)
-{
- float l = mixer->vol_l, r = mixer->vol_r;
- if (mixer->emulate_mute && mixer->muted)
- l = r = 0;
- if (!mixer->softvol) {
- MP_DBG(mixer, "Setting volume on AO.\n");
- struct ao_control_vol vol = {.left = l, .right = r};
- if (ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
- MP_ERR(mixer, "Failed to change audio output volume.\n");
- return;
- }
- float gain = (l + r) / 2.0 / 100.0;
if (!af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)) {
if (gain == 1.0)
return;
@@ -143,57 +71,6 @@ static void setvolume_internal(struct mixer *mixer)
}
}
-void mixer_setvolume(struct mixer *mixer, float l, float r)
-{
- checkvolume(mixer); // to check mute status
-
- float max = mixer_getmaxvolume(mixer);
- mixer->vol_l = MPCLAMP(l, 0, max);
- mixer->vol_r = MPCLAMP(r, 0, max);
- if (mixer->ao)
- setvolume_internal(mixer);
-}
-
-void mixer_getbothvolume(struct mixer *mixer, float *b)
-{
- float mixer_l, mixer_r;
- mixer_getvolume(mixer, &mixer_l, &mixer_r);
- *b = (mixer_l + mixer_r) / 2;
-}
-
-void mixer_setmute(struct mixer *mixer, bool mute)
-{
- checkvolume(mixer);
- if (mute == mixer->muted)
- return;
- if (mixer->ao) {
- mixer->muted = mute;
- mixer->muted_by_us = mute;
- if (mixer->emulate_mute) {
- setvolume_internal(mixer);
- } else {
- ao_control(mixer->ao, AOCONTROL_SET_MUTE, &mute);
- }
- checkvolume(mixer);
- } else {
- mixer->muted = mute;
- mixer->muted_by_us = mute;
- }
-}
-
-bool mixer_getmute(struct mixer *mixer)
-{
- checkvolume(mixer);
- return mixer->muted;
-}
-
-void mixer_addvolume(struct mixer *mixer, float step)
-{
- float vol_l, vol_r;
- mixer_getvolume(mixer, &vol_l, &vol_r);
- mixer_setvolume(mixer, vol_l + step, vol_r + step);
-}
-
void mixer_getbalance(struct mixer *mixer, float *val)
{
if (mixer->af)
@@ -242,130 +119,18 @@ void mixer_setbalance(struct mixer *mixer, float val)
af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_BALANCE, &val);
}
-char *mixer_get_volume_restore_data(struct mixer *mixer)
-{
- if (!mixer->driver[0])
- return NULL;
- return talloc_asprintf(NULL, "%s:%f:%f:%d", mixer->driver, mixer->vol_l,
- mixer->vol_r, mixer->muted_by_us);
-}
-
-static void probe_softvol(struct mixer *mixer)
-{
- bool ao_perapp = ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
- bool ao_softvol = ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1;
- assert(!(ao_perapp && ao_softvol));
- mixer->persistent_volume = !ao_softvol;
-
- if (mixer->opts->softvol == SOFTVOL_AUTO) {
- // No system-wide volume => fine with AO volume control.
- mixer->softvol = !ao_softvol && !ao_perapp;
- } else {
- mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
- }
-
- if (mixer->softvol)
- mixer->persistent_volume = false;
-
- MP_DBG(mixer, "Will use af_volume: %s\n", mixer->softvol ? "yes" : "no");
-
- // If we can't use real volume control => force softvol.
- if (!mixer->softvol) {
- ao_control_vol_t vol;
- if (ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol) != CONTROL_OK) {
- mixer->softvol = true;
- MP_WARN(mixer, "Hardware volume control unavailable.\n");
- }
- }
-
- // Probe native mute support.
- mixer->emulate_mute = true;
- if (!mixer->softvol) {
- if (ao_control(mixer->ao, AOCONTROL_GET_MUTE, &(bool){0}) == CONTROL_OK)
- mixer->emulate_mute = false;
- }
-}
-
-static void restore_volume(struct mixer *mixer)
-{
- struct MPOpts *opts = mixer->opts;
- struct ao *ao = mixer->ao;
-
- float force_vol_l = -1, force_vol_r = -1;
- int force_mute = -1;
-
- const char *prev_driver = mixer->driver;
- mixer->driver = mixer->softvol ? "softvol" : ao_get_name(ao);
- if (!prev_driver[0])
- prev_driver = mixer->driver;
-
- // Restore old parameters if volume won't survive reinitialization.
- // But not if volume scale is possibly different.
- if (!mixer->persistent_volume && strcmp(mixer->driver, prev_driver) == 0) {
- force_vol_l = mixer->vol_l;
- force_vol_r = mixer->vol_r;
- }
-
- // Set mute if we disabled it on uninit last time.
- if (mixer->muted_by_us)
- force_mute = 1;
-
- // Set parameters from command line.
- if (opts->mixer_init_volume >= 0)
- force_vol_l = force_vol_r = opts->mixer_init_volume;
- if (opts->mixer_init_mute >= 0)
- force_mute = opts->mixer_init_mute;
-
- // Set parameters from playback resume.
- char *data = mixer->opts->mixer_restore_volume_data;
- if (!mixer->persistent_volume && data && data[0]) {
- char drv[40];
- float v_l, v_r;
- int m;
- if (sscanf(data, "%39[^:]:%f:%f:%d", drv, &v_l, &v_r, &m) == 4) {
- if (strcmp(mixer->driver, drv) == 0) {
- force_vol_l = v_l;
- force_vol_r = v_r;
- force_mute = !!m;
- MP_DBG(mixer, "Restoring volume from resume config.\n");
- }
- }
- talloc_free(mixer->opts->mixer_restore_volume_data);
- mixer->opts->mixer_restore_volume_data = NULL;
- }
-
- // Using --volume should not reset the volume on every file (i.e. reinit),
- // OTOH mpv --{ --volume 10 f1.mkv --} --{ --volume 20 f2.mkv --} must work.
- // Resetting the option volumes to "auto" (-1) is easiest. If file local
- // options (as shown above) are used, the option handler code will reset
- // them to other values, and force the volume to be reset as well.
- opts->mixer_init_volume = -1;
- opts->mixer_init_mute = -1;
-
- checkvolume(mixer);
- if (force_vol_l >= 0 && force_vol_r >= 0) {
- MP_DBG(mixer, "Restoring previous volume.\n");
- mixer_setvolume(mixer, force_vol_l, force_vol_r);
- }
- if (force_mute >= 0) {
- MP_DBG(mixer, "Restoring previous mute toggle.\n");
- mixer_setmute(mixer, force_mute);
- }
-}
-
// Called after the audio filter chain is built or rebuilt.
// (Can be called multiple times, even without mixer_uninit() in-between.)
-void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af)
+void mixer_reinit_audio(struct mixer *mixer, struct af_stream *af)
{
- if (!ao || !af)
- return;
- mixer->ao = ao;
mixer->af = af;
+ if (!af)
+ return;
- MP_DBG(mixer, "Reinit...\n");
+ if (mixer->opts->softvol == SOFTVOL_NO)
+ MP_ERR(mixer, "--softvol=no is not supported anymore.\n");
- probe_softvol(mixer);
- restore_volume(mixer);
+ mixer_update_volume(mixer);
if (mixer->balance != 0)
mixer_setbalance(mixer, mixer->balance);
@@ -380,24 +145,5 @@ void mixer_uninit_audio(struct mixer *mixer)
if (!mixer->ao)
return;
- MP_DBG(mixer, "Uninit...\n");
-
- checkvolume(mixer);
- if (mixer->muted_by_us && mixer->persistent_volume) {
- MP_DBG(mixer, "Draining.\n");
- /* Current audio output API combines playing the remaining buffered
- * audio and uninitializing the AO into one operation, even though
- * ideally unmute would happen between those two steps. We can't do
- * volume changes after uninitialization, but we don't want the
- * remaining audio to play at full volume either. Thus this
- * workaround to drop remaining audio first. */
- ao_reset(mixer->ao);
- mixer_setmute(mixer, false);
- /* We remember mute status and re-enable it if we play more audio
- * in the same process. */
- mixer->muted_by_us = true;
- }
- mixer->ao = NULL;
mixer->af = NULL;
- mixer->softvol = false;
}
diff --git a/audio/mixer.h b/audio/mixer.h
index 4e2ff350ff..b475c12700 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -33,18 +33,11 @@ struct af_stream;
struct mixer;
struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global);
-void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af);
+void mixer_reinit_audio(struct mixer *mixer, struct af_stream *af);
void mixer_uninit_audio(struct mixer *mixer);
bool mixer_audio_initialized(struct mixer *mixer);
-void mixer_getvolume(struct mixer *mixer, float *l, float *r);
-void mixer_setvolume(struct mixer *mixer, float l, float r);
-void mixer_addvolume(struct mixer *mixer, float step);
-void mixer_getbothvolume(struct mixer *mixer, float *b);
-void mixer_setmute(struct mixer *mixer, bool mute);
-bool mixer_getmute(struct mixer *mixer);
+void mixer_update_volume(struct mixer *mixer);
void mixer_getbalance(struct mixer *mixer, float *bal);
void mixer_setbalance(struct mixer *mixer, float bal);
-float mixer_getmaxvolume(struct mixer *mixer);
-char *mixer_get_volume_restore_data(struct mixer *mixer);
#endif /* MPLAYER_MIXER_H */
diff --git a/options/options.c b/options/options.c
index 0304d4e0c7..e58eea1bc9 100644
--- a/options/options.c
+++ b/options/options.c
@@ -410,13 +410,13 @@ const m_option_t mp_opts[] = {
({"no", SOFTVOL_NO},
{"yes", SOFTVOL_YES},
{"auto", SOFTVOL_AUTO})),
- OPT_FLOATRANGE("softvol-max", softvol_max, 0, 100, 1000),
- OPT_FLOATRANGE("volume", mixer_init_volume, 0, -1, 1000),
- OPT_CHOICE("mute", mixer_init_mute, 0,
+ OPT_FLOATRANGE("volume-max", softvol_max, 0, 100, 1000),
+ // values <0 for volume and mute are legacy and ignored
+ OPT_FLOATRANGE("volume", softvol_volume, 0, -1, 1000),
+ OPT_CHOICE("mute", softvol_mute, 0,
({"auto", -1},
{"no", 0},
{"yes", 1})),
- OPT_STRING("volume-restore-data", mixer_restore_volume_data, 0),
OPT_CHOICE("gapless-audio", gapless_audio, 0,
({"no", 0},
{"yes", 1},
@@ -685,6 +685,7 @@ const m_option_t mp_opts[] = {
OPT_REPLACED("ass-use-margins", "sub-use-margins"),
OPT_REPLACED("media-title", "force-media-title"),
OPT_REPLACED("input-unix-socket", "input-ipc-server"),
+ OPT_REPLACED("softvol-max", "volume-max"),
{0}
};
@@ -698,8 +699,8 @@ const struct MPOpts mp_default_opts = {
.deinterlace = -1,
.softvol = SOFTVOL_AUTO,
.softvol_max = 130,
- .mixer_init_volume = -1,
- .mixer_init_mute = -1,
+ .softvol_volume = 100,
+ .softvol_mute = 0,
.gapless_audio = -1,
.audio_buffer = 0.2,
.audio_device = "auto",
diff --git a/options/options.h b/options/options.h
index 5dcc642222..3e8474fd75 100644
--- a/options/options.h
+++ b/options/options.h
@@ -89,9 +89,8 @@ typedef struct MPOpts {
int ao_null_fallback;
int force_vo;
int softvol;
- float mixer_init_volume;
- int mixer_init_mute;
- char *mixer_restore_volume_data;
+ float softvol_volume;
+ int softvol_mute;
float softvol_max;
int gapless_audio;
double audio_buffer;
diff --git a/player/audio.c b/player/audio.c
index 2ce1669366..b61e464090 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -132,7 +132,7 @@ static int recreate_audio_filters(struct MPContext *mpctx)
if (afs->initialized < 1 && af_init(afs) < 0)
goto fail;
- mixer_reinit_audio(mpctx->mixer, mpctx->ao, afs);
+ mixer_reinit_audio(mpctx->mixer, afs);
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
diff --git a/player/command.c b/player/command.c
index 9512e3d10f..3bca64bd5e 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1569,44 +1569,29 @@ static int mp_property_volume(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
+ struct MPOpts *opts = mpctx->opts;
+
switch (action) {
- case M_PROPERTY_GET:
- mixer_getbothvolume(mpctx->mixer, arg);
- return M_PROPERTY_OK;
case M_PROPERTY_GET_TYPE:
*(struct m_option *)arg = (struct m_option){
.type = CONF_TYPE_FLOAT,
.flags = M_OPT_RANGE,
.min = 0,
- .max = mixer_getmaxvolume(mpctx->mixer),
+ .max = opts->softvol_max,
};
return M_PROPERTY_OK;
case M_PROPERTY_GET_NEUTRAL:
*(float *)arg = 100;
return M_PROPERTY_OK;
- case M_PROPERTY_PRINT: {
- float val;
- mixer_getbothvolume(mpctx->mixer, &val);
- *(char **)arg = talloc_asprintf(NULL, "%i", (int)val);
- return M_PROPERTY_OK;
- }
- case M_PROPERTY_SET:
- mixer_setvolume(mpctx->mixer, *(float *) arg, *(float *) arg);
- return M_PROPERTY_OK;
- case M_PROPERTY_SWITCH: {
- struct m_property_switch_arg *sarg = arg;
- mixer_addvolume(mpctx->mixer, sarg->inc);
+ case M_PROPERTY_PRINT:
+ *(char **)arg = talloc_asprintf(NULL, "%i", (int)opts->softvol_volume);
return M_PROPERTY_OK;
}
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
-}
-static int mp_property_volume_max(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- return m_property_float_ro(action, arg, mixer_getmaxvolume(mpctx->mixer));
+ int r = mp_property_generic_option(mpctx, prop, action, arg);
+ if (action == M_PROPERTY_SET)
+ mixer_update_volume(mpctx->mixer);
+ return r;
}
/// Mute (RW)
@@ -1614,34 +1599,76 @@ static int mp_property_mute(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
+
+ if (action == M_PROPERTY_GET_TYPE) {
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLAG};
+ return M_PROPERTY_OK;
+ }
+
+ int r = mp_property_generic_option(mpctx, prop, action, arg);
+ if (action == M_PROPERTY_SET)
+ mixer_update_volume(mpctx->mixer);
+ return r;
+}
+
+static int mp_property_ao_volume(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ struct ao *ao = mpctx->ao;
+ if (!ao)
+ return M_PROPERTY_NOT_IMPLEMENTED;
+
switch (action) {
- case M_PROPERTY_SET:
- mixer_setmute(mpctx->mixer, *(int *) arg);
+ case M_PROPERTY_SET: {
+ float value = *(float *)arg;
+ ao_control_vol_t vol = {value, value};
+ if (ao_control(ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
+ return M_PROPERTY_UNAVAILABLE;
return M_PROPERTY_OK;
- case M_PROPERTY_GET:
- *(int *)arg = mixer_getmute(mpctx->mixer);
+ }
+ case M_PROPERTY_GET: {
+ ao_control_vol_t vol = {0};
+ if (ao_control(ao, AOCONTROL_GET_VOLUME, &vol) != CONTROL_OK)
+ return M_PROPERTY_UNAVAILABLE;
+ *(float *)arg = (vol.left + vol.right) / 2.0f;
return M_PROPERTY_OK;
+ }
case M_PROPERTY_GET_TYPE:
- *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLAG};
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLOAT};
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-static int mp_property_volrestore(void *ctx, struct m_property *prop,
- int action, void *arg)
+
+static int mp_property_ao_mute(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
MPContext *mpctx = ctx;
+ struct ao *ao = mpctx->ao;
+ if (!ao)
+ return M_PROPERTY_NOT_IMPLEMENTED;
+
switch (action) {
+ case M_PROPERTY_SET: {
+ bool value = *(int *)arg;
+ if (ao_control(ao, AOCONTROL_SET_MUTE, &value) != CONTROL_OK)
+ return M_PROPERTY_UNAVAILABLE;
+ return M_PROPERTY_OK;
+ }
case M_PROPERTY_GET: {
- char *s = mixer_get_volume_restore_data(mpctx->mixer);
- *(char **)arg = s;
- return s ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE;
+ bool value = false;
+ if (ao_control(ao, AOCONTROL_GET_MUTE, &value) != CONTROL_OK)
+ return M_PROPERTY_UNAVAILABLE;
+ *(int *)arg = value;
+ return M_PROPERTY_OK;
}
- case M_PROPERTY_SET:
- return M_PROPERTY_NOT_IMPLEMENTED;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLAG};
+ return M_PROPERTY_OK;
}
- return mp_property_generic_option(mpctx, prop, action, arg);
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
static int get_device_entry(int item, int action, void *arg, void *ctx)
@@ -3670,8 +3697,10 @@ static const struct m_property mp_properties[] = {
// Audio
{"mixer-active", mp_property_mixer_active},
{"volume", mp_property_volume},
- {"volume-max", mp_property_volume_max},
+ {"volume-max", mp_property_generic_option},
{"mute", mp_property_mute},
+ {"ao-volume", mp_property_ao_volume},
+ {"ao-mute", mp_property_ao_mute},
{"audio-delay", mp_property_audio_delay},
{"audio-codec-name", mp_property_audio_codec_name},
{"audio-codec", mp_property_audio_codec},
@@ -3681,7 +3710,6 @@ static const struct m_property mp_properties[] = {
M_PROPERTY_DEPRECATED_ALIAS("audio-channels", "audio-params/channel-count"),
{"aid", mp_property_audio},
{"balance", mp_property_balance},
- {"volume-restore-data", mp_property_volrestore},
{"audio-device", mp_property_audio_device},
{"audio-device-list", mp_property_audio_devices},
{"current-ao", mp_property_ao},
@@ -3859,7 +3887,7 @@ static const char *const *const mp_event_property_change[] = {
"colormatrix-output-range", "colormatrix-primaries", "video-aspect"),
E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate",
"samplerate", "channels", "audio", "volume", "mute", "balance",
- "volume-restore-data", "current-ao", "audio-codec-name", "audio-params",
+ "current-ao", "audio-codec-name", "audio-params",
"audio-out-params", "volume-max", "mixer-active"),
E(MPV_EVENT_SEEK, "seeking", "core-idle", "eof-reached"),
E(MPV_EVENT_PLAYBACK_RESTART, "seeking", "core-idle", "eof-reached"),
diff --git a/player/configfiles.c b/player/configfiles.c
index 3c42331de0..7356a9a81b 100644
--- a/player/configfiles.c
+++ b/player/configfiles.c
@@ -208,7 +208,8 @@ static const char *const backup_properties[] = {
"options/speed",
"options/edition",
"options/pause",
- "volume-restore-data",
+ "volume",
+ "mute",
"options/audio-delay",
//"balance",
"options/fullscreen",