summaryrefslogtreecommitdiffstats
path: root/player/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/audio.c')
-rw-r--r--player/audio.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/player/audio.c b/player/audio.c
index b61e464090..6c53bdf721 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -31,7 +31,6 @@
#include "common/common.h"
#include "osdep/timer.h"
-#include "audio/mixer.h"
#include "audio/audio.h"
#include "audio/audio_buffer.h"
#include "audio/decode/dec_audio.h"
@@ -120,6 +119,69 @@ fail:
mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL);
}
+// Called when opts->softvol_volume or opts->softvol_mute were changed.
+void audio_update_volume(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = mpctx->opts;
+ struct ao_chain *ao_c = mpctx->ao_chain;
+ if (!ao_c || ao_c->af->initialized < 1)
+ return;
+
+ float gain = MPMAX(opts->softvol_volume / 100.0, 0);
+ if (opts->softvol_mute == 1)
+ gain = 0.0;
+
+ if (!af_control_any_rev(ao_c->af, AF_CONTROL_SET_VOLUME, &gain)) {
+ if (gain == 1.0)
+ return;
+ MP_VERBOSE(mpctx, "Inserting volume filter.\n");
+ if (!(af_add(ao_c->af, "volume", "softvol", NULL)
+ && af_control_any_rev(ao_c->af, AF_CONTROL_SET_VOLUME, &gain)))
+ MP_ERR(mpctx, "No volume control available.\n");
+ }
+}
+
+/* NOTE: Currently the balance code is seriously buggy: it always changes
+ * the af_pan mapping between the first two input channels and first two
+ * output channels to particular values. These values make sense for an
+ * af_pan instance that was automatically inserted for balance control
+ * only and is otherwise an identity transform, but if the filter was
+ * there for another reason, then ignoring and overriding the original
+ * values is completely wrong.
+ */
+void audio_update_balance(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = mpctx->opts;
+ struct ao_chain *ao_c = mpctx->ao_chain;
+ if (!ao_c || ao_c->af->initialized < 1)
+ return;
+
+ float val = opts->balance;
+
+ if (af_control_any_rev(ao_c->af, AF_CONTROL_SET_PAN_BALANCE, &val))
+ return;
+
+ if (val == 0)
+ return;
+
+ struct af_instance *af_pan_balance;
+ if (!(af_pan_balance = af_add(ao_c->af, "pan", "autopan", NULL))) {
+ MP_ERR(mpctx, "No balance control available.\n");
+ return;
+ }
+
+ /* make all other channels pass through since by default pan blocks all */
+ for (int i = 2; i < AF_NCH; i++) {
+ float level[AF_NCH] = {0};
+ level[i] = 1.f;
+ af_control_ext_t arg_ext = { .ch = i, .arg = level };
+ af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_LEVEL,
+ &arg_ext);
+ }
+
+ af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_BALANCE, &val);
+}
+
static int recreate_audio_filters(struct MPContext *mpctx)
{
assert(mpctx->ao_chain);
@@ -132,7 +194,11 @@ static int recreate_audio_filters(struct MPContext *mpctx)
if (afs->initialized < 1 && af_init(afs) < 0)
goto fail;
- mixer_reinit_audio(mpctx->mixer, afs);
+ if (mpctx->opts->softvol == SOFTVOL_NO)
+ MP_ERR(mpctx, "--softvol=no is not supported anymore.\n");
+
+ audio_update_volume(mpctx);
+ audio_update_balance(mpctx);
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
@@ -210,7 +276,6 @@ void uninit_audio_out(struct MPContext *mpctx)
// Note: with gapless_audio, stop_play is not correctly set
if (mpctx->opts->gapless_audio || mpctx->stop_play == AT_END_OF_FILE)
ao_drain(mpctx->ao);
- mixer_uninit_audio(mpctx->mixer);
ao_uninit(mpctx->ao);
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
@@ -243,7 +308,6 @@ static void ao_chain_uninit(struct ao_chain *ao_c)
void uninit_audio_chain(struct MPContext *mpctx)
{
if (mpctx->ao_chain) {
- mixer_uninit_audio(mpctx->mixer);
ao_chain_uninit(mpctx->ao_chain);
mpctx->ao_chain = NULL;