summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/af.rst7
-rw-r--r--audio/filter/af_pan.c50
2 files changed, 38 insertions, 19 deletions
diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst
index c52c422299..71b5bbf975 100644
--- a/DOCS/man/af.rst
+++ b/DOCS/man/af.rst
@@ -312,6 +312,13 @@ Available filters are:
``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force
remixing audio to 5.1 and output it like this.
+ This filter supports the following ``af-command`` commands:
+
+ ``set-matrix``
+ Set the ``<matrix>`` argument dynamically. This can be used to change
+ the mixing matrix at runtime, without reinitializing the entire filter
+ chain.
+
``drc[=method:target]``
Applies dynamic range compression. This maximizes the volume by compressing
the audio signal's dynamic range. (Formerly called ``volnorm``.)
diff --git a/audio/filter/af_pan.c b/audio/filter/af_pan.c
index ad4d31df29..c27f4bd07c 100644
--- a/audio/filter/af_pan.c
+++ b/audio/filter/af_pan.c
@@ -43,6 +43,27 @@ static void set_channels(struct mp_audio *mpa, int num)
mp_audio_set_channels(mpa, &map);
}
+static void parse_matrix(struct af_instance *af, const char *cp)
+{
+ af_pan_t *s = af->priv;
+ int j = 0, k = 0, n;
+ while (cp && k < AF_NCH) {
+ sscanf(cp, "%f%n" , &s->level[j][k], &n);
+ MP_VERBOSE(af, "Pan level from channel %i to"
+ " channel %i = %f\n", k, j, s->level[j][k]);
+ cp = &cp[n];
+ j++;
+ if (j >= s->nch) {
+ j = 0;
+ k++;
+ }
+ if (*cp != ',')
+ break;
+ cp++;
+ }
+
+}
+
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
@@ -102,6 +123,15 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_ERROR;
*(float*)arg = s->level[0][1] - s->level[1][0];
return AF_OK;
+ case AF_CONTROL_COMMAND: {
+ char **args = arg;
+ if (!strcmp(args[0], "set-matrix")) {
+ parse_matrix(af, args[1]);
+ return CONTROL_OK;
+ } else {
+ return CONTROL_ERROR;
+ }
+ }
}
return AF_UNKNOWN;
}
@@ -151,30 +181,12 @@ static int af_open(struct af_instance *af)
af->control = control;
af->filter_frame = filter_frame;
af_pan_t *s = af->priv;
- int n = 0;
- int j, k;
-
int nch = s->nch;
if (nch && AF_OK != control(af, AF_CONTROL_SET_PAN_NOUT, &nch))
return AF_ERROR;
// Read pan values
- char *cp = s->matrixstr;
- j = 0; k = 0;
- while (cp && k < AF_NCH) {
- sscanf(cp, "%f%n" , &s->level[j][k], &n);
- MP_VERBOSE(af, "Pan level from channel %i to"
- " channel %i = %f\n", k, j, s->level[j][k]);
- cp = &cp[n];
- j++;
- if (j >= nch) {
- j = 0;
- k++;
- }
- if (*cp != ',')
- break;
- cp++;
- }
+ parse_matrix(af, s->matrixstr);
return AF_OK;
}