summaryrefslogtreecommitdiffstats
path: root/audio
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 /audio
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.
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af_rubberband.c25
1 files changed, 25 insertions, 0 deletions
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}
},
};