1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 01:22:30 +00:00

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.
This commit is contained in:
Hector Martin 2016-09-20 00:56:10 +09:00 committed by wm4
parent ed8540c38e
commit 57eca14a45
2 changed files with 38 additions and 2 deletions

View File

@ -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.

View File

@ -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}
},
};