diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst index ffb6c03e98..fa8335c1ac 100644 --- a/DOCS/man/af.rst +++ b/DOCS/man/af.rst @@ -605,6 +605,15 @@ Available filters are: of ``scaletempo``, and will be used to adjust audio pitch when playing at speed different from normal. + This filter has a number of 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 + to learn what each option does: + http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html + (The mapping of the mpv rubberband filter sub-option names and values to + those of librubberband follows a simple pattern: ``"Option" + Name + Value``.) + ``lavfi=graph`` Filter audio using FFmpeg's libavfilter. diff --git a/audio/filter/af_rubberband.c b/audio/filter/af_rubberband.c index 4863c2282d..76dced3990 100644 --- a/audio/filter/af_rubberband.c +++ b/audio/filter/af_rubberband.c @@ -31,6 +31,9 @@ struct priv { // Estimate how much librubberband has buffered internally. // I could not find a way to do this with the librubberband API. double rubber_delay; + // command line options + int opt_stretch, opt_transients, opt_detector, opt_phase, opt_window, + opt_smoothing, opt_formant, opt_pitch, opt_channels; }; static void update_speed(struct af_instance *af, double new_speed) @@ -57,10 +60,9 @@ static int control(struct af_instance *af, int cmd, void *arg) if (p->rubber) rubberband_delete(p->rubber); - int opts = RubberBandOptionProcessRealTime - | RubberBandOptionStretchPrecise - | RubberBandOptionSmoothingOn - | RubberBandOptionPitchHighConsistency; + int opts = p->opt_stretch | p->opt_transients | p->opt_detector | + p->opt_phase | p->opt_window | p->opt_smoothing | + p->opt_formant | p->opt_pitch | p-> opt_channels; p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0); if (!p->rubber) { @@ -176,6 +178,7 @@ static int af_open(struct af_instance *af) return AF_OK; } +#define OPT_BASE_STRUCT struct priv const struct af_info af_info_rubberband = { .info = "Pitch conversion with librubberband", .name = "rubberband", @@ -183,5 +186,41 @@ const struct af_info af_info_rubberband = { .priv_size = sizeof(struct priv), .priv_defaults = &(const struct priv) { .speed = 1.0, + .opt_stretch = RubberBandOptionStretchPrecise, + .opt_pitch = RubberBandOptionPitchHighConsistency, + }, + .options = (const struct m_option[]) { + OPT_CHOICE("stretch", opt_stretch, 0, + ({"elastic", RubberBandOptionStretchElastic}, + {"precise", RubberBandOptionStretchPrecise})), + OPT_CHOICE("transients", opt_transients, 0, + ({"crisp", RubberBandOptionTransientsCrisp}, + {"mixed", RubberBandOptionTransientsMixed}, + {"smooth", RubberBandOptionTransientsSmooth})), + OPT_CHOICE("detector", opt_detector, 0, + ({"compound", RubberBandOptionDetectorCompound}, + {"percussive", RubberBandOptionDetectorPercussive}, + {"soft", RubberBandOptionDetectorSoft})), + OPT_CHOICE("phase", opt_phase, 0, + ({"laminar", RubberBandOptionPhaseLaminar}, + {"independent", RubberBandOptionPhaseIndependent})), + OPT_CHOICE("window", opt_window, 0, + ({"standard", RubberBandOptionWindowStandard}, + {"short", RubberBandOptionWindowShort}, + {"long", RubberBandOptionWindowLong})), + OPT_CHOICE("smoothing", opt_smoothing, 0, + ({"off", RubberBandOptionSmoothingOff}, + {"on", RubberBandOptionSmoothingOn})), + OPT_CHOICE("formant", opt_formant, 0, + ({"shifted", RubberBandOptionFormantShifted}, + {"preserved", RubberBandOptionFormantPreserved})), + OPT_CHOICE("pitch", opt_pitch, 0, + ({"quality", RubberBandOptionPitchHighQuality}, + {"speed", RubberBandOptionPitchHighSpeed}, + {"consistency", RubberBandOptionPitchHighConsistency})), + OPT_CHOICE("channels", opt_channels, 0, + ({"apart", RubberBandOptionChannelsApart}, + {"together", RubberBandOptionChannelsTogether})), + {0} }, };