summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-02 02:58:52 +0200
committerwm4 <wm4@nowhere>2014-10-02 02:58:52 +0200
commitae2e2b974077f13c48007635c399918125822286 (patch)
tree2b3fc2c4783024fd6372099de80ec451927d8a27
parentb5942f80de481cabab07ce1cee7a2b6a537b4c93 (diff)
downloadmpv-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.rst8
-rw-r--r--options/options.c3
-rw-r--r--options/options.h1
-rw-r--r--player/audio.c39
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: