diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 5bc798bd38..3ccaef84b8 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -27,6 +27,8 @@ Interface changes :: --- mpv 0.38.0 --- + - add `--ao-volume` option + - change `ao-volume` property to read only property `current-ao-volume` - add `--volume-gain`, `--volume-gain-min`, and `--volume-gain-max` options - add `current-gpu-context` property - add `--secondary-sub-ass-override` option diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 0479cf9830..6ac9fb2bd5 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2329,16 +2329,15 @@ Property list This option is relatively useless. Before mpv 0.18.1, it could be used to infer behavior of the ``volume`` property. -``ao-volume`` (RW) +``current-ao-volume`` 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. + control. What this option shows depends on the API. For example, on ALSA + this usually shows system-wide audio, while on PulseAudio per-application volume. ``ao-mute`` (RW) - Similar to ``ao-volume``, but controls the mute state. May be unimplemented - even if ``ao-volume`` works. + Similar to ``current-ao-volume``, but controls the mute state. May be unimplemented + even if ``current-ao-volume`` works. ``audio-codec`` Audio codec selected for decoding. diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 32e69af7e5..cf65957850 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1996,6 +1996,13 @@ Audio Since mpv 0.18.1, this always controls the internal mixer (aka "softvol"). +``--ao-volume=`` + Set the startup system volume. This option works only if mpv audio + output is currently active, and 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. Negative values will be ignored. + ``--volume-max=<100.0-1000.0>`` 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. diff --git a/options/options.c b/options/options.c index 7d1babc749..c380bce808 100644 --- a/options/options.c +++ b/options/options.c @@ -707,6 +707,7 @@ static const m_option_t mp_opts[] = { // values <0 for volume and mute are legacy and ignored {"volume", OPT_FLOAT(softvol_volume), .flags = UPDATE_VOL, M_RANGE(-1, 1000)}, + {"ao-volume", OPT_FLOAT(ao_volume), M_RANGE(-1, 100)}, {"volume-gain-max", OPT_FLOAT(softvol_gain_max), M_RANGE(0, 150)}, {"volume-gain-min", OPT_FLOAT(softvol_gain_min), M_RANGE(-150, 0)}, {"volume-gain", OPT_FLOAT(softvol_gain), .flags = UPDATE_VOL, @@ -934,6 +935,7 @@ static const struct MPOpts mp_default_opts = { .msg_color = true, .softvol_max = 130, .softvol_volume = 100, + .ao_volume = -1, .softvol_gain_max = 12, .softvol_gain_min = -96, .softvol_gain = 0, diff --git a/options/options.h b/options/options.h index 9dce3f609c..d9f1f99d1b 100644 --- a/options/options.h +++ b/options/options.h @@ -181,6 +181,7 @@ typedef struct MPOpts { float audio_wait_open; int force_vo; float softvol_volume; + float ao_volume; int rgain_mode; float rgain_preamp; // Set replaygain pre-amplification bool rgain_clip; // Enable/disable clipping prevention diff --git a/player/audio.c b/player/audio.c index 344fbdb744..c697142012 100644 --- a/player/audio.c +++ b/player/audio.c @@ -182,6 +182,19 @@ void audio_update_volume(struct MPContext *mpctx) ao_set_gain(ao_c->ao, gain); } +// Called when opts->ao_volume were changed. +void audio_update_ao_volume(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + struct ao *ao = mpctx->ao; + float vol = opts->ao_volume; + if (!ao || vol < 0) + return; + + ao_control(ao, AOCONTROL_SET_VOLUME, &vol); +} + + // Call this if opts->playback_speed or mpctx->speed_factor_* change. void update_playback_speed(struct MPContext *mpctx) { @@ -335,6 +348,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao) // Make sure filtering never stops with frames stuck in access filter. mp_filter_set_high_priority(ao_c->queue_filter, true); audio_update_volume(ao_c->mpctx); + audio_update_ao_volume(ao_c->mpctx); } if (ao_c->filter->ao_needs_update) @@ -593,8 +607,10 @@ void reinit_audio_chain_src(struct MPContext *mpctx, struct track *track) if (recreate_audio_filters(mpctx) < 0) goto init_error; - if (mpctx->ao) + if (mpctx->ao) { audio_update_volume(mpctx); + audio_update_ao_volume(mpctx); + } mp_wakeup_core(mpctx); return; diff --git a/player/command.c b/player/command.c index a286dc2d4a..3eecdd3915 100644 --- a/player/command.c +++ b/player/command.c @@ -1669,12 +1669,6 @@ static int mp_property_ao_volume(void *ctx, struct m_property *prop, return M_PROPERTY_NOT_IMPLEMENTED; switch (action) { - case M_PROPERTY_SET: { - float vol = *(float *)arg; - if (ao_control(ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK) - return M_PROPERTY_UNAVAILABLE; - return M_PROPERTY_OK; - } case M_PROPERTY_GET: { if (ao_control(ao, AOCONTROL_GET_VOLUME, arg) != CONTROL_OK) return M_PROPERTY_UNAVAILABLE; @@ -3935,7 +3929,7 @@ static const struct m_property mp_properties_base[] = { {"mixer-active", mp_property_mixer_active}, {"volume", mp_property_volume}, {"volume-gain", mp_property_volume_gain}, - {"ao-volume", mp_property_ao_volume}, + {"current-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}, @@ -4286,8 +4280,8 @@ static const struct property_osd_display { {"volume-gain", "Volume gain", .msg = "Volume gain: ${?volume-gain:${volume-gain} dB ${?mute==yes:(Muted)}}${!volume-gain:${volume-gain}}", .osd_progbar = OSD_VOLUME, .marker = 0}, - {"ao-volume", "AO Volume", - .msg = "AO Volume: ${?ao-volume:${ao-volume}% ${?ao-mute==yes:(Muted)}}${!ao-volume:${ao-volume}}", + {"current-ao-volume", "AO Volume", + .msg = "AO Volume: ${?current-ao-volume:${current-ao-volume}% ${?ao-mute==yes:(Muted)}}${!current-ao-volume:${currene-ao-volume}}", .osd_progbar = OSD_VOLUME, .marker = 100}, {"mute", "Mute"}, {"ao-mute", "AO Mute"}, @@ -7198,6 +7192,9 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags, mp_wakeup_core(mpctx); } + if (opt_ptr == &opts->ao_volume) + audio_update_ao_volume(mpctx); + if (flags & UPDATE_HWDEC) { struct track *track = mpctx->current_track[0][STREAM_VIDEO]; struct mp_decoder_wrapper *dec = track ? track->dec : NULL; diff --git a/player/core.h b/player/core.h index d995a88366..2fc3c45700 100644 --- a/player/core.h +++ b/player/core.h @@ -487,6 +487,7 @@ void uninit_audio_out(struct MPContext *mpctx); void uninit_audio_chain(struct MPContext *mpctx); void reinit_audio_chain_src(struct MPContext *mpctx, struct track *track); void audio_update_volume(struct MPContext *mpctx); +void audio_update_ao_volume(struct MPContext *mpctx); void reload_audio_output(struct MPContext *mpctx); void audio_start_ao(struct MPContext *mpctx);