From 57eca14a4537429df498b3b76578ee87debf166c Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 20 Sep 2016 00:56:10 +0900 Subject: 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. --- audio/filter/af_rubberband.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'audio') 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} }, }; -- cgit v1.2.3