summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-07-17 19:21:28 +0200
committerwm4 <wm4@nowhere>2016-07-17 19:21:28 +0200
commit77e1e8e38e7b8d9318dc1bb437a88d8f13b7a5c9 (patch)
treed64c47c331174f59eeecb9a713ba76aa4b7110cb
parent79974e7ad94e7658c780e3b446a7822a533675e4 (diff)
downloadmpv-77e1e8e38e7b8d9318dc1bb437a88d8f13b7a5c9.tar.bz2
mpv-77e1e8e38e7b8d9318dc1bb437a88d8f13b7a5c9.tar.xz
audio: refactor mixer code and delete mixer.c
mixer.c didn't really deserve to be separate anymore, as half of its contents were unnecessary glue code after recent changes. It also created a weird split between audio.c and af.c due to the fact that mixer.c could insert audio filters. With the code being in audio.c directly, together with other code that unserts filters during runtime, it will be possible to cleanup this code a bit and make it work like the video filter code. As part of this change, make the balance code work like the volume code, and add an option to back the current balance value. Also, since the balance semantics are unexpected for most users (panning between the audio channels, instead of just changing the relative volume), and there are some other volumes, formally deprecate both the old property and the new option.
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/input.rst2
-rw-r--r--DOCS/man/options.rst5
-rw-r--r--audio/mixer.c147
-rw-r--r--audio/mixer.h43
-rw-r--r--options/options.c2
-rw-r--r--options/options.h1
-rw-r--r--player/audio.c72
-rw-r--r--player/command.c35
-rw-r--r--player/core.h10
-rw-r--r--player/loadfile.c1
-rw-r--r--player/main.c2
-rw-r--r--player/playloop.c1
-rw-r--r--wscript_build.py1
14 files changed, 99 insertions, 225 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 7427645214..8789cd943c 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -19,6 +19,8 @@ Interface changes
::
+ --- mpv 0.18.2 ---
+ - deprecate "balance" option/property (no replacement)
--- mpv 0.18.1 ---
- deprecate --heartbeat-cmd
- remove --softvol=no capability:
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 067e1c118d..46dcb36e7d 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1321,6 +1321,8 @@ Property list
It doesn't change the volumes of each channel, but instead sets up a pan
matrix to mix the left and right channels.)
+ Deprecated.
+
``fullscreen`` (RW)
See ``--fullscreen``.
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index ade2c5cb5f..d78588ae78 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1079,6 +1079,11 @@ Audio
Since mpv 0.18.1, this always controls the internal mixer (aka "softvol").
+``--balance=<value>``
+ How much left/right channels contribute to the audio.
+
+ Deprecated.
+
``--audio-delay=<sec>``
Audio delay in seconds (positive or negative float value). Positive values
delay the audio, and negative values delay the video.
diff --git a/audio/mixer.c b/audio/mixer.c
deleted file mode 100644
index 795edfa628..0000000000
--- a/audio/mixer.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <assert.h>
-
-#include <libavutil/common.h>
-
-#include "config.h"
-#include "audio/filter/af.h"
-#include "common/global.h"
-#include "common/msg.h"
-#include "mpv_talloc.h"
-#include "mixer.h"
-
-struct mixer {
- struct mp_log *log;
- struct MPOpts *opts;
- struct af_stream *af;
- // Other stuff
- float balance;
-};
-
-struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global)
-{
- struct mixer *mixer = talloc_ptrtype(talloc_ctx, mixer);
- *mixer = (struct mixer) {
- .log = mp_log_new(mixer, global->log, "mixer"),
- .opts = global->opts,
- };
- return mixer;
-}
-
-bool mixer_audio_initialized(struct mixer *mixer)
-{
- return !!mixer->af;
-}
-
-// Called when opts->softvol_volume or opts->softvol_mute were changed.
-void mixer_update_volume(struct mixer *mixer)
-{
- if (!mixer->af)
- return;
-
- float gain = MPMAX(mixer->opts->softvol_volume / 100.0, 0);
- if (mixer->opts->softvol_mute == 1)
- gain = 0.0;
-
- if (!af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)) {
- if (gain == 1.0)
- return;
- MP_VERBOSE(mixer, "Inserting volume filter.\n");
- if (!(af_add(mixer->af, "volume", "softvol", NULL)
- && af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
- MP_ERR(mixer, "No volume control available.\n");
- }
-}
-
-void mixer_getbalance(struct mixer *mixer, float *val)
-{
- if (mixer->af)
- af_control_any_rev(mixer->af, AF_CONTROL_GET_PAN_BALANCE, &mixer->balance);
- *val = mixer->balance;
-}
-
-/* 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 mixer_setbalance(struct mixer *mixer, float val)
-{
- struct af_instance *af_pan_balance;
-
- mixer->balance = val;
-
- if (!mixer->af)
- return;
-
- if (af_control_any_rev(mixer->af, AF_CONTROL_SET_PAN_BALANCE, &val))
- return;
-
- if (val == 0)
- return;
-
- if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
- MP_ERR(mixer, "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);
-}
-
-// 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 af_stream *af)
-{
- mixer->af = af;
- if (!af)
- return;
-
- if (mixer->opts->softvol == SOFTVOL_NO)
- MP_ERR(mixer, "--softvol=no is not supported anymore.\n");
-
- mixer_update_volume(mixer);
-
- if (mixer->balance != 0)
- mixer_setbalance(mixer, mixer->balance);
-}
-
-/* Called before uninitializing the audio filter chain. The main purpose is to
- * turn off mute, in case it's a global/persistent setting which might
- * otherwise be left enabled even after this player instance exits.
- */
-void mixer_uninit_audio(struct mixer *mixer)
-{
- mixer->af = NULL;
-}
diff --git a/audio/mixer.h b/audio/mixer.h
deleted file mode 100644
index b475c12700..0000000000
--- a/audio/mixer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MPLAYER_MIXER_H
-#define MPLAYER_MIXER_H
-
-#include <stdbool.h>
-
-// Values of MPOpts.softvol
-enum {
- SOFTVOL_NO = 0,
- SOFTVOL_YES = 1,
- SOFTVOL_AUTO = 2,
-};
-
-struct mpv_global;
-struct ao;
-struct af_stream;
-struct mixer;
-
-struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global);
-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_update_volume(struct mixer *mixer);
-void mixer_getbalance(struct mixer *mixer, float *bal);
-void mixer_setbalance(struct mixer *mixer, float bal);
-
-#endif /* MPLAYER_MIXER_H */
diff --git a/options/options.c b/options/options.c
index 89ee24a829..acef3ba6b9 100644
--- a/options/options.c
+++ b/options/options.c
@@ -40,7 +40,6 @@
#include "video/csputils.h"
#include "video/hwdec.h"
#include "sub/osd.h"
-#include "audio/mixer.h"
#include "audio/filter/af.h"
#include "audio/decode/dec_audio.h"
#include "player/core.h"
@@ -424,6 +423,7 @@ const m_option_t mp_opts[] = {
{"weak", -1})),
OPT_DOUBLE("audio-buffer", audio_buffer, M_OPT_MIN | M_OPT_MAX,
.min = 0, .max = 10),
+ OPT_FLOATRANGE("balance", balance, 0, -1, 1),
OPT_GEOMETRY("geometry", vo.geometry, 0),
OPT_SIZE_BOX("autofit", vo.autofit, 0),
diff --git a/options/options.h b/options/options.h
index 3e8474fd75..7690823aab 100644
--- a/options/options.h
+++ b/options/options.h
@@ -90,6 +90,7 @@ typedef struct MPOpts {
int force_vo;
int softvol;
float softvol_volume;
+ float balance;
int softvol_mute;
float softvol_max;
int gapless_audio;
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;
diff --git a/player/command.c b/player/command.c
index a815ae8a1d..d8f4f83529 100644
--- a/player/command.c
+++ b/player/command.c
@@ -54,7 +54,6 @@
#include "video/decode/vd.h"
#include "video/out/vo.h"
#include "video/csputils.h"
-#include "audio/mixer.h"
#include "audio/audio_buffer.h"
#include "audio/out/ao.h"
#include "audio/filter/af.h"
@@ -1561,7 +1560,8 @@ static int mp_property_mixer_active(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
- return m_property_flag_ro(action, arg, mixer_audio_initialized(mpctx->mixer));
+ struct ao_chain *ao_c = mpctx->ao_chain;
+ return m_property_flag_ro(action, arg, ao_c && ao_c->af->initialized > 0);
}
/// Volume (RW)
@@ -1590,7 +1590,7 @@ static int mp_property_volume(void *ctx, struct m_property *prop,
int r = mp_property_generic_option(mpctx, prop, action, arg);
if (action == M_PROPERTY_SET)
- mixer_update_volume(mpctx->mixer);
+ audio_update_volume(mpctx);
return r;
}
@@ -1607,7 +1607,7 @@ static int mp_property_mute(void *ctx, struct m_property *prop,
int r = mp_property_generic_option(mpctx, prop, action, arg);
if (action == M_PROPERTY_SET)
- mixer_update_volume(mpctx->mixer);
+ audio_update_volume(mpctx);
return r;
}
@@ -1841,23 +1841,10 @@ static int mp_property_balance(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
- float bal;
- switch (action) {
- case M_PROPERTY_GET:
- mixer_getbalance(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 = -1,
- .max = 1,
- };
- return M_PROPERTY_OK;
- case M_PROPERTY_PRINT: {
+ if (action == M_PROPERTY_PRINT) {
char **str = arg;
- mixer_getbalance(mpctx->mixer, &bal);
+ float bal = mpctx->opts->balance;
if (bal == 0.f)
*str = talloc_strdup(NULL, "center");
else if (bal == -1.f)
@@ -1871,11 +1858,11 @@ static int mp_property_balance(void *ctx, struct m_property *prop,
}
return M_PROPERTY_OK;
}
- case M_PROPERTY_SET:
- mixer_setbalance(mpctx->mixer, *(float *)arg);
- return M_PROPERTY_OK;
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
+
+ int r = mp_property_generic_option(mpctx, prop, action, arg);
+ if (action == M_PROPERTY_SET)
+ audio_update_balance(mpctx);
+ return r;
}
static struct track* track_next(struct MPContext *mpctx, enum stream_type type,
diff --git a/player/core.h b/player/core.h
index 8afcfbe64d..f2a9f191fa 100644
--- a/player/core.h
+++ b/player/core.h
@@ -287,7 +287,6 @@ typedef struct MPContext {
struct lavfi *lavfi;
- struct mixer *mixer;
struct ao *ao;
struct mp_audio *ao_decoder_fmt; // for weak gapless audio check
struct ao_chain *ao_chain;
@@ -429,6 +428,8 @@ void uninit_audio_out(struct MPContext *mpctx);
void uninit_audio_chain(struct MPContext *mpctx);
int init_audio_decoder(struct MPContext *mpctx, struct track *track);
void reinit_audio_chain_src(struct MPContext *mpctx, struct lavfi_pad *src);
+void audio_update_volume(struct MPContext *mpctx);
+void audio_update_balance(struct MPContext *mpctx);
// configfiles.c
void mp_parse_cfgfiles(struct MPContext *mpctx);
@@ -558,4 +559,11 @@ int init_video_decoder(struct MPContext *mpctx, struct track *track);
int get_deinterlacing(struct MPContext *mpctx);
void set_deinterlacing(struct MPContext *mpctx, bool enable);
+// Values of MPOpts.softvol
+enum {
+ SOFTVOL_NO = 0,
+ SOFTVOL_YES = 1,
+ SOFTVOL_AUTO = 2,
+};
+
#endif /* MPLAYER_MP_CORE_H */
diff --git a/player/loadfile.c b/player/loadfile.c
index 2b88ecfeb0..94d0b2bd5d 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -42,7 +42,6 @@
#include "common/encode.h"
#include "input/input.h"
-#include "audio/mixer.h"
#include "audio/audio.h"
#include "audio/audio_buffer.h"
#include "audio/decode/dec_audio.h"
diff --git a/player/main.c b/player/main.c
index 88b60e1937..78652fe562 100644
--- a/player/main.c
+++ b/player/main.c
@@ -52,7 +52,6 @@
#include "audio/decode/dec_audio.h"
#include "audio/out/ao.h"
-#include "audio/mixer.h"
#include "demux/demux.h"
#include "stream/stream.h"
#include "sub/osd.h"
@@ -360,7 +359,6 @@ struct MPContext *mp_create(void)
mpctx->input = mp_input_init(mpctx->global);
screenshot_init(mpctx);
- mpctx->mixer = mixer_init(mpctx, mpctx->global);
command_init(mpctx);
init_libav(mpctx->global);
mp_clients_init(mpctx);
diff --git a/player/playloop.c b/player/playloop.c
index 0062a30888..fd16c78e68 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -36,7 +36,6 @@
#include "osdep/terminal.h"
#include "osdep/timer.h"
-#include "audio/mixer.h"
#include "audio/decode/dec_audio.h"
#include "audio/filter/af.h"
#include "audio/out/ao.h"
diff --git a/wscript_build.py b/wscript_build.py
index 8f2b85c787..13d89ce6a1 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -105,7 +105,6 @@ def build(ctx):
( "audio/chmap_sel.c" ),
( "audio/fmt-conversion.c" ),
( "audio/format.c" ),
- ( "audio/mixer.c" ),
( "audio/decode/ad_lavc.c" ),
( "audio/decode/ad_spdif.c" ),
( "audio/decode/dec_audio.c" ),