diff --git a/command.c b/command.c index aee38463fd..414fd1e33b 100644 --- a/command.c +++ b/command.c @@ -763,14 +763,14 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg, if (!arg) return M_PROPERTY_ERROR; mixer_setmuted(&mpctx->mixer, *(int *) arg); - mpctx->user_muted = mpctx->mixer.muted; + mpctx->user_muted = mixer_getmuted(&mpctx->mixer); return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: case M_PROPERTY_STEP_DOWN: if (mpctx->edl_muted) return M_PROPERTY_DISABLED; mixer_mute(&mpctx->mixer); - mpctx->user_muted = mpctx->mixer.muted; + mpctx->user_muted = mixer_getmuted(&mpctx->mixer); return M_PROPERTY_OK; case M_PROPERTY_PRINT: if (!arg) @@ -780,7 +780,8 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg, return M_PROPERTY_OK; } default: - return m_property_flag(prop, action, arg, &mpctx->mixer.muted); + return m_property_flag_ro(prop, action, arg, + mixer_getmuted(&mpctx->mixer)); } } diff --git a/mixer.c b/mixer.c index 4b99a6e967..61dc1dcb13 100644 --- a/mixer.c +++ b/mixer.c @@ -67,7 +67,7 @@ void mixer_uninit(mixer_t *mixer) // One complication is that the mute state should survive audio // reinitialization (e.g. when switching to a new file), so we have to be // sure mixer_reinit() will restore the mute state. - if (mixer->muted) { + if (mixer_getmuted(mixer)) { // avoid playing the rest of the audio buffer at restored volume ao_reset(mixer->ao); mixer_setmuted(mixer, false); @@ -164,11 +164,17 @@ void mixer_getvolume(mixer_t *mixer, float *l, float *r) *l = 0; *r = 0; if (mixer->ao) { + float real_l, real_r; + internal_getvolume(mixer, &real_l, &real_r); + // consider the case when the system mixer volumes change independently + if (real_l != 0 || real_r != 0) + mixer->muted = false; if (mixer->muted) { *l = mixer->last_l; *r = mixer->last_r; } else { - internal_getvolume(mixer, l, r); + *l = real_l; + *r = real_r; } } } @@ -199,14 +205,23 @@ void mixer_getbothvolume(mixer_t *mixer, float *b) void mixer_mute(mixer_t *mixer) { - mixer_setmuted(mixer, !mixer->muted); + mixer_setmuted(mixer, !mixer_getmuted(mixer)); +} + +bool mixer_getmuted(mixer_t *mixer) +{ + // this call will also check whether mute is still active, and "fix" it + float l, r; + mixer_getvolume(mixer, &l, &r); + return mixer->muted; } void mixer_setmuted(mixer_t *mixer, bool mute) { - if (mute == mixer->muted) + bool muted = mixer_getmuted(mixer); + if (mute == muted) return; - if (mixer->muted) { + if (muted) { mixer_setvolume(mixer, mixer->last_l, mixer->last_r); } else { mixer_getvolume(mixer, &mixer->last_l, &mixer->last_r); diff --git a/mixer.h b/mixer.h index f05688bc72..f99e860ff3 100644 --- a/mixer.h +++ b/mixer.h @@ -33,7 +33,7 @@ typedef struct mixer_s { struct ao *ao; af_stream_t *afilter; int volstep; - int muted; + bool muted; float last_l, last_r; float restore_vol_l, restore_vol_r; bool restore_volume; @@ -49,6 +49,7 @@ void mixer_incvolume(mixer_t *mixer); void mixer_decvolume(mixer_t *mixer); void mixer_getbothvolume(mixer_t *mixer, float *b); void mixer_mute(mixer_t *mixer); +bool mixer_getmuted(mixer_t *mixer); void mixer_setmuted(mixer_t *mixer, bool mute); void mixer_getbalance(mixer_t *mixer, float *bal); void mixer_setbalance(mixer_t *mixer, float bal);