summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHector Martin <marcan@marcan.st>2016-09-20 00:56:10 +0900
committerwm4 <wm4@nowhere>2016-09-19 18:56:14 +0200
commit57eca14a4537429df498b3b76578ee87debf166c (patch)
treeae881de2d8eca594a5694a1c1e1df7edc5bd6faa
parented8540c38effa1713fb066bab2771e5efae53ba4 (diff)
downloadmpv-57eca14a4537429df498b3b76578ee87debf166c.tar.bz2
mpv-57eca14a4537429df498b3b76578ee87debf166c.tar.xz
af_rubberband: add af-command and option to change the pitch
This allows both fixed and dynamic control over the audio pitch using librubberband, which was previously not exposed to the user.
-rw-r--r--DOCS/man/af.rst15
-rw-r--r--audio/filter/af_rubberband.c25
2 files changed, 38 insertions, 2 deletions
diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst
index 71b5bbf975..31d365722f 100644
--- a/DOCS/man/af.rst
+++ b/DOCS/man/af.rst
@@ -413,9 +413,13 @@ Available filters are:
``rubberband``
High quality pitch correction with librubberband. This can be used in place
of ``scaletempo``, and will be used to adjust audio pitch when playing
- at speed different from normal.
+ at speed different from normal. It can also be used to adjust audio pitch
+ without changing playback speed.
- This filter has a number of sub-options. You can list them with
+ ``<pitch-scale>``
+ Sets the pitch scaling factor. Frequencies are multiplied by this value.
+
+ This filter has a number of additional sub-options. You can list them with
``mpv --af=rubberband=help``. This will also show the default values
for each option. The options are not documented here, because they are
merely passed to librubberband. Look at the librubberband documentation
@@ -424,6 +428,13 @@ Available filters are:
(The mapping of the mpv rubberband filter sub-option names and values to
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
+ This filter supports the following ``af-command`` commands:
+
+ ``set-pitch``
+ Set the ``<pitch-scale>`` argument dynamically. This can be used to
+ change the playback pitch at runtime. Note that speed is controlled
+ using the standard ``speed`` property, not ``af-command``.
+
``lavfi=graph``
Filter audio using FFmpeg's libavfilter.
diff --git a/audio/filter/af_rubberband.c b/audio/filter/af_rubberband.c
index 48bb510679..529c252a12 100644
--- a/audio/filter/af_rubberband.c
+++ b/audio/filter/af_rubberband.c
@@ -26,6 +26,7 @@
struct priv {
RubberBandState rubber;
double speed;
+ double pitch;
struct mp_audio *pending;
bool needs_reset;
// Estimate how much librubberband has buffered internally.
@@ -44,6 +45,14 @@ static void update_speed(struct af_instance *af, double new_speed)
rubberband_set_time_ratio(p->rubber, 1.0 / p->speed);
}
+static void update_pitch(struct af_instance *af, double new_pitch)
+{
+ struct priv *p = af->priv;
+
+ p->pitch = new_pitch;
+ rubberband_set_pitch_scale(p->rubber, p->pitch);
+}
+
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *p = af->priv;
@@ -72,6 +81,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
update_speed(af, p->speed);
+ update_pitch(af, p->pitch);
control(af, AF_CONTROL_RESET, NULL);
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
@@ -87,6 +97,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
p->pending = NULL;
p->rubber_delay = 0;
return AF_OK;
+ case AF_CONTROL_COMMAND: {
+ char **args = arg;
+ if (!strcmp(args[0], "set-pitch")) {
+ char *endptr;
+ double pitch = strtod(args[1], &endptr);
+ if (*endptr || pitch < 0.01 || pitch > 100.0)
+ return CONTROL_ERROR;
+ update_pitch(af, pitch);
+ return CONTROL_OK;
+ } else {
+ return CONTROL_ERROR;
+ }
+ }
}
return AF_UNKNOWN;
}
@@ -187,6 +210,7 @@ const struct af_info af_info_rubberband = {
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.speed = 1.0,
+ .pitch = 1.0,
.opt_pitch = RubberBandOptionPitchHighConsistency,
.opt_transients = RubberBandOptionTransientsMixed,
.opt_formant = RubberBandOptionFormantPreserved,
@@ -220,6 +244,7 @@ const struct af_info af_info_rubberband = {
OPT_CHOICE("channels", opt_channels, 0,
({"apart", RubberBandOptionChannelsApart},
{"together", RubberBandOptionChannelsTogether})),
+ OPT_DOUBLE("pitch-scale", pitch, M_OPT_RANGE, .min = 0.01, .max = 100),
{0}
},
};