diff options
author | wm4 <wm4@nowhere> | 2014-10-02 02:58:52 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-10-02 02:58:52 +0200 |
commit | ae2e2b974077f13c48007635c399918125822286 (patch) | |
tree | 2b3fc2c4783024fd6372099de80ec451927d8a27 | |
parent | b5942f80de481cabab07ce1cee7a2b6a537b4c93 (diff) | |
download | mpv-ae2e2b974077f13c48007635c399918125822286.tar.bz2 mpv-ae2e2b974077f13c48007635c399918125822286.tar.xz |
audio: enable pitch correction by default when playing fast
Apparently this is what users want. When playing with normal speed,
nothing is done. When playing slower than normal, resampling is used
instead, because scaletempo (which does the pitch correction) adds
too many artifacts.
-rw-r--r-- | DOCS/man/options.rst | 8 | ||||
-rw-r--r-- | options/options.c | 3 | ||||
-rw-r--r-- | options/options.h | 1 | ||||
-rw-r--r-- | player/audio.c | 39 |
4 files changed, 49 insertions, 2 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index e8e41331d6..45f0d7358a 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -95,6 +95,9 @@ Playback Control ``--speed=<0.01-100>`` Slow down or speed up playback by the factor given as parameter. + If ``--audio-pitch-correction`` is used, playing with a speed higher than + normal automatically inserts the ``scaletempo`` audio filter. + ``--loop=<N|inf|no>`` Loops playback ``N`` times. A value of ``1`` plays it one time (default), ``2`` two times, etc. ``inf`` means forever. ``no`` is the same as ``1`` and @@ -755,6 +758,11 @@ Video Audio ----- +``--audio-pitch-correction=<yes|no`` + If this is enabled, playing with a speed higher than normal automatically + inserts the ``scaletempo`` audio filter. For details, see audio filter + section. + ``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>`` Specify a priority list of audio output drivers to be used. For interactive use one would normally specify a single one to use, but in diff --git a/options/options.c b/options/options.c index e76a20d2c8..bc016dfd14 100644 --- a/options/options.c +++ b/options/options.c @@ -249,6 +249,8 @@ const m_option_t mp_opts[] = { OPT_DOUBLE("speed", playback_speed, M_OPT_RANGE | M_OPT_FIXED, .min = 0.01, .max = 100.0), + OPT_FLAG("audio-pitch-correction", pitch_correction, 0), + // set a-v distance OPT_FLOATRANGE("audio-delay", audio_delay, 0, -100.0, 100.0), @@ -639,6 +641,7 @@ const struct MPOpts mp_default_opts = { .audio_output_channels = MP_CHMAP_INIT_STEREO, .audio_output_format = 0, // AF_FORMAT_UNKNOWN .playback_speed = 1., + .pitch_correction = 1, .movie_aspect = -1., .field_dominance = -1, .sub_auto = 0, diff --git a/options/options.h b/options/options.h index eda99a88cb..580a0cc780 100644 --- a/options/options.h +++ b/options/options.h @@ -205,6 +205,7 @@ typedef struct MPOpts { int force_srate; int dtshd; double playback_speed; + int pitch_correction; struct m_obj_settings *vf_settings, *vf_defs; struct m_obj_settings *af_settings, *af_defs; int deinterlace; diff --git a/player/audio.c b/player/audio.c index f532f1167b..969b0ca816 100644 --- a/player/audio.c +++ b/player/audio.c @@ -88,6 +88,23 @@ int reinit_audio_filters(struct MPContext *mpctx) return 1; } +static int try_filter(struct MPContext *mpctx, + char *name, char *label, char **args) +{ + struct dec_audio *d_audio = mpctx->d_audio; + + if (af_find_by_label(d_audio->afilter, label)) + return 0; + + struct af_instance *af = af_add(d_audio->afilter, name, args); + if (!af) + return -1; + + af->label = talloc_strdup(af, label); + + return 1; +} + void set_playback_speed(struct MPContext *mpctx, double new_speed) { struct MPOpts *opts = mpctx->opts; @@ -97,8 +114,23 @@ void set_playback_speed(struct MPContext *mpctx, double new_speed) opts->playback_speed = new_speed; - if (mpctx->d_audio) - recreate_audio_filters(mpctx); + if (!mpctx->d_audio) + return; + + if (new_speed > 1.0 && opts->pitch_correction) { + if (!af_control_any_rev(mpctx->d_audio->afilter, + AF_CONTROL_SET_PLAYBACK_SPEED, + &new_speed)) + { + if (try_filter(mpctx, "scaletempo", "playback-speed", NULL) < 0) + return; + } + } else { + if (af_remove_by_label(mpctx->d_audio->afilter, "playback-speed") < 0) + return; + } + + recreate_audio_filters(mpctx); } void reset_audio_state(struct MPContext *mpctx) @@ -155,6 +187,7 @@ void reinit_audio_chain(struct MPContext *mpctx) return; } + // Weak gapless audio: drain AO on decoder format changes if (mpctx->ao_decoder_fmt && (mpctx->initialized_flags & INITIALIZED_AO) && !mp_audio_config_equals(mpctx->ao_decoder_fmt, &in_format) && opts->gapless_audio < 0) @@ -222,6 +255,8 @@ void reinit_audio_chain(struct MPContext *mpctx) if (recreate_audio_filters(mpctx) < 0) goto init_error; + set_playback_speed(mpctx, opts->playback_speed); + return; init_error: |