diff options
author | Hector Martin <marcan@marcan.st> | 2016-09-19 21:22:58 +0900 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-09-19 14:55:58 +0200 |
commit | ed8540c38effa1713fb066bab2771e5efae53ba4 (patch) | |
tree | 9da51f7e692ef1f5dcd32c3b0e81024d43c94ed2 | |
parent | 0525f5fa93f9d997fd3d0037be17c3350823704e (diff) | |
download | mpv-ed8540c38effa1713fb066bab2771e5efae53ba4.tar.bz2 mpv-ed8540c38effa1713fb066bab2771e5efae53ba4.tar.xz |
af_pan: add af-command support to change the matrix
This allows for seamless changes in the downmixing matrix without having
to reinitialize the filter chain.
-rw-r--r-- | DOCS/man/af.rst | 7 | ||||
-rw-r--r-- | audio/filter/af_pan.c | 50 |
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; } |