summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/af.rst6
-rw-r--r--audio/filter/af_rubberband.c22
2 files changed, 22 insertions, 6 deletions
diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst
index 5a13bb4495..eb139bc833 100644
--- a/DOCS/man/af.rst
+++ b/DOCS/man/af.rst
@@ -225,6 +225,12 @@ Available filters are:
change the playback pitch at runtime. Note that speed is controlled
using the standard ``speed`` property, not ``af-command``.
+ ``multiply-pitch <factor>``
+ Multiply the current value of ``<pitch-scale>`` dynamically. For
+ example: 0.5 to go down by an octave, 1.5 to go up by a perfect fifth.
+ If you want to go up or down by semi-tones, use 1.059463094352953 and
+ 0.9438743126816935
+
``lavfi=graph``
Filter audio using FFmpeg's libavfilter.
diff --git a/audio/filter/af_rubberband.c b/audio/filter/af_rubberband.c
index a4deb3d48c..58cf077d8b 100644
--- a/audio/filter/af_rubberband.c
+++ b/audio/filter/af_rubberband.c
@@ -45,12 +45,16 @@ 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)
+static bool update_pitch(struct af_instance *af, double new_pitch)
{
+ if (new_pitch < 0.01 || new_pitch > 100.0)
+ return false;
+
struct priv *p = af->priv;
p->pitch = new_pitch;
rubberband_set_pitch_scale(p->rubber, p->pitch);
+ return true;
}
static int control(struct af_instance *af, int cmd, void *arg)
@@ -99,13 +103,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_OK;
case AF_CONTROL_COMMAND: {
char **args = arg;
+ char *endptr;
+ double pitch = p->pitch;
if (!strcmp(args[0], "set-pitch")) {
- char *endptr;
- double pitch = strtod(args[1], &endptr);
- if (*endptr || pitch < 0.01 || pitch > 100.0)
+ pitch = strtod(args[1], &endptr);
+ if (*endptr)
+ return CONTROL_ERROR;
+ return update_pitch(af, pitch) ? CONTROL_OK : CONTROL_ERROR;
+ } else if (!strcmp(args[0], "multiply-pitch")) {
+ double mult = strtod(args[1], &endptr);
+ if (*endptr || mult <= 0)
return CONTROL_ERROR;
- update_pitch(af, pitch);
- return CONTROL_OK;
+ pitch *= mult;
+ return update_pitch(af, pitch) ? CONTROL_OK : CONTROL_ERROR;
} else {
return CONTROL_ERROR;
}