diff options
author | wm4 <wm4@mplayer2.org> | 2012-01-07 14:10:05 +0100 |
---|---|---|
committer | wm4 <wm4@mplayer2.org> | 2012-01-18 04:21:45 +0100 |
commit | aae97b7e254f312e5c7bfbe940cb8515a25bf11d (patch) | |
tree | 0444ae3fe25edef952757d2d6b2b79a560209cd9 | |
parent | 15a318b2a56766e7bc2dee5d4cc8f514ba21fe39 (diff) | |
download | mpv-aae97b7e254f312e5c7bfbe940cb8515a25bf11d.tar.bz2 mpv-aae97b7e254f312e5c7bfbe940cb8515a25bf11d.tar.xz |
audio: properly restore audio volume on exit when mute is used
When you mute audio, mplayer is supposed to restore the volume controls
on exit. This affects when --softvol isn't used and the audio output
driver volume controls directly affect the system wide volume controls.
This wasn't done in some cases.
-rw-r--r-- | command.c | 3 | ||||
-rw-r--r-- | mixer.c | 36 | ||||
-rw-r--r-- | mixer.h | 2 | ||||
-rw-r--r-- | mplayer.c | 14 |
4 files changed, 42 insertions, 13 deletions
@@ -762,8 +762,7 @@ static int mp_property_mute(m_option_t *prop, int action, void *arg, return M_PROPERTY_DISABLED; if (!arg) return M_PROPERTY_ERROR; - if ((!!*(int *) arg) != mpctx->mixer.muted) - mixer_mute(&mpctx->mixer); + mixer_setmuted(&mpctx->mixer, *(int *) arg); mpctx->user_muted = mpctx->mixer.muted; return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: @@ -45,11 +45,36 @@ void mixer_reinit(mixer_t *mixer) mixer_setvolume(mixer, mixer->restore_vol_l, mixer->restore_vol_r); mixer->muted = muted; } + if (mixer->muted) { + // undo mixer_uninit() + mixer_setvolume(mixer, 0, 0); + mixer->muted = true; + } if (mixer->restore_balance) { mixer_setbalance(mixer, mixer->balance); } } +// Called before the audio output is uninitialized. +// Note that this doesn't necessarily terminate the mixer_t instance, and it's +// possible that mixer_reinit() will be called later. +void mixer_uninit(mixer_t *mixer) +{ + if (!mixer->ao) + return; + // The player is supposed to turn off the mute state when the player + // terminates. No other attempts at restoring the volume are done. + // 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) { + // avoid playing the rest of the audio buffer at restored volume + ao_reset(mixer->ao); + mixer_setmuted(mixer, false); + mixer->muted = true; + } +} + void mixer_getvolume(mixer_t *mixer, float *l, float *r) { ao_control_vol_t vol; @@ -124,7 +149,7 @@ void mixer_setvolume(mixer_t *mixer, float l, float r) mixer->restore_vol_r = r; } } - mixer->muted = 0; + mixer->muted = false; } void mixer_incvolume(mixer_t *mixer) @@ -162,12 +187,19 @@ void mixer_getbothvolume(mixer_t *mixer, float *b) void mixer_mute(mixer_t *mixer) { + mixer_setmuted(mixer, !mixer->muted); +} + +void mixer_setmuted(mixer_t *mixer, bool mute) +{ + if (mute == mixer->muted) + return; if (mixer->muted) { mixer_setvolume(mixer, mixer->last_l, mixer->last_r); } else { mixer_getvolume(mixer, &mixer->last_l, &mixer->last_r); mixer_setvolume(mixer, 0, 0); - mixer->muted = 1; + mixer->muted = true; } } @@ -42,12 +42,14 @@ typedef struct mixer_s { } mixer_t; void mixer_reinit(mixer_t *mixer); +void mixer_uninit(mixer_t *mixer); void mixer_getvolume(mixer_t *mixer, float *l, float *r); void mixer_setvolume(mixer_t *mixer, float l, float r); 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); +void mixer_setmuted(mixer_t *mixer, bool mute); void mixer_getbalance(mixer_t *mixer, float *bal); void mixer_setbalance(mixer_t *mixer, float bal); @@ -714,10 +714,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) if (mask & INITIALIZED_AO) { mpctx->initialized_flags &= ~INITIALIZED_AO; current_module = "uninit_ao"; - if (mpctx->edl_muted) - mixer_mute(&mpctx->mixer); - if (mpctx->ao) + if (mpctx->ao) { + mixer_uninit(&mpctx->mixer); ao_uninit(mpctx->ao, mpctx->stop_play != AT_END_OF_FILE); + } mpctx->ao = NULL; mpctx->mixer.ao = NULL; } @@ -727,8 +727,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc) { - if (mpctx->user_muted && !mpctx->edl_muted) - mixer_mute(&mpctx->mixer); uninit_player(mpctx, INITIALIZED_ALL); #if defined(__MINGW32__) || defined(__CYGWIN__) timeEndPeriod(1); @@ -3124,8 +3122,7 @@ static void edl_seek_reset(MPContext *mpctx) mpctx->edl_muted = !mpctx->edl_muted; next_edl_record = next_edl_record->next; } - if ((mpctx->user_muted | mpctx->edl_muted) != mpctx->mixer.muted) - mixer_mute(&mpctx->mixer); + mixer_setmuted(&mpctx->mixer, mpctx->edl_muted || mpctx->user_muted); } @@ -3153,8 +3150,7 @@ static void edl_update(MPContext *mpctx) next_edl_record->stop_sec, next_edl_record->length_sec); } else if (next_edl_record->action == EDL_MUTE) { mpctx->edl_muted = !mpctx->edl_muted; - if ((mpctx->user_muted | mpctx->edl_muted) != mpctx->mixer.muted) - mixer_mute(&mpctx->mixer); + mixer_setmuted(&mpctx->mixer, mpctx->edl_muted || mpctx->user_muted); mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_MUTE: [%f]\n", next_edl_record->start_sec); } |