diff --git a/DOCS/interface-changes/pitch-shift.txt b/DOCS/interface-changes/pitch-shift.txt new file mode 100644 index 0000000000..7b58bd57cc --- /dev/null +++ b/DOCS/interface-changes/pitch-shift.txt @@ -0,0 +1 @@ +add `--pitch` option diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 6b220ac88f..9192b93cb3 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -237,6 +237,11 @@ Playback Control speed higher than normal automatically inserts the ``scaletempo2`` audio filter. +``--pitch=<0.01-100>`` + Raise or lower the audio's pitch by the factor given as parameter. Does not + affect playback speed. Playing with an altered pitch automatically inserts + the ``scaletempo2`` audio filter. + ``--pause`` Start the player in paused state. diff --git a/options/options.c b/options/options.c index b087e619f5..805648a07c 100644 --- a/options/options.c +++ b/options/options.c @@ -675,6 +675,7 @@ static const m_option_t mp_opts[] = { {"audio-channels", OPT_CHANNELS(audio_output_channels), .flags = UPDATE_AUDIO}, {"audio-format", OPT_AUDIOFORMAT(audio_output_format), .flags = UPDATE_AUDIO}, {"speed", OPT_DOUBLE(playback_speed), M_RANGE(0.01, 100.0)}, + {"pitch", OPT_DOUBLE(playback_pitch), M_RANGE(0.01, 100.0)}, {"audio-pitch-correction", OPT_BOOL(pitch_correction)}, @@ -1036,6 +1037,7 @@ static const struct MPOpts mp_default_opts = { .audio_display = 1, .audio_output_format = 0, // AF_FORMAT_UNKNOWN .playback_speed = 1., + .playback_pitch = 1., .pitch_correction = true, .audiofile_auto = -1, .osd_bar_visible = true, @@ -1127,6 +1129,7 @@ static const struct MPOpts mp_default_opts = { .watch_later_options = (char *[]){ "start", "speed", + "pitch", "edition", "volume", "mute", diff --git a/options/options.h b/options/options.h index 9125c3d650..6ee7cb4209 100644 --- a/options/options.h +++ b/options/options.h @@ -323,6 +323,7 @@ typedef struct MPOpts { int audio_output_format; int force_srate; double playback_speed; + double playback_pitch; bool pitch_correction; struct m_obj_settings *vf_settings; struct m_obj_settings *af_settings; diff --git a/player/audio.c b/player/audio.c index b6e8118612..e86547c30e 100644 --- a/player/audio.c +++ b/player/audio.c @@ -54,6 +54,7 @@ static void update_speed_filters(struct MPContext *mpctx) if (!ao_c) return; + double pitch = mpctx->opts->playback_pitch; double speed = mpctx->opts->playback_speed; double resample = mpctx->speed_factor_a; double drop = 1.0; @@ -63,17 +64,22 @@ static void update_speed_filters(struct MPContext *mpctx) speed = 1.0; } - if (mpctx->display_sync_active) { - switch (mpctx->video_out->opts->video_sync) { - case VS_DISP_ADROP: - drop *= speed * resample; - resample = speed = 1.0; - break; - case VS_DISP_TEMPO: - speed = mpctx->audio_speed; - resample = 1.0; - break; - } + int video_sync = mpctx->display_sync_active ? + mpctx->video_out->opts->video_sync : VS_NONE; + switch (video_sync) { + case VS_DISP_ADROP: + drop *= speed * resample / pitch; + resample = pitch; + speed = 1.0; + break; + case VS_DISP_TEMPO: + speed = mpctx->audio_speed / pitch; + resample = pitch; + break; + default: + resample *= pitch; + speed /= pitch; + break; } mp_output_chain_set_audio_speed(ao_c->filter, speed, resample, drop); diff --git a/player/command.c b/player/command.c index cebb19b5b1..6700aaf635 100644 --- a/player/command.c +++ b/player/command.c @@ -431,6 +431,19 @@ static int mp_property_playback_speed(void *ctx, struct m_property *prop, return mp_property_generic_option(mpctx, prop, action, arg); } +/// Playback pitch (RW) +static int mp_property_playback_pitch(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + if (action == M_PROPERTY_PRINT || action == M_PROPERTY_FIXED_LEN_PRINT) { + *(char **)arg = mp_format_double(NULL, mpctx->opts->playback_pitch, 2, + false, false, action != M_PROPERTY_FIXED_LEN_PRINT); + return M_PROPERTY_OK; + } + return mp_property_generic_option(mpctx, prop, action, arg); +} + static int mp_property_av_speed_correction(void *ctx, struct m_property *prop, int action, void *arg) { @@ -3983,6 +3996,7 @@ static const struct m_property mp_properties_base[] = { // General {"pid", mp_property_pid}, {"speed", mp_property_playback_speed}, + {"pitch", mp_property_playback_pitch}, {"audio-speed-correction", mp_property_av_speed_correction, .priv = "a"}, {"video-speed-correction", mp_property_av_speed_correction, .priv = "v"}, {"display-sync-active", mp_property_display_sync_active}, @@ -4402,6 +4416,7 @@ static const struct property_osd_display { .seek_bar = OSD_SEEK_INFO_BAR}, {"hr-seek", "hr-seek"}, {"speed", "Speed"}, + {"pitch", "Pitch"}, {"clock", "Clock"}, {"edition", "Edition"}, // audio @@ -7438,7 +7453,7 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags, run_command_opts(mpctx); } - if (opt_ptr == &opts->playback_speed) { + if (opt_ptr == &opts->playback_speed || opt_ptr == &opts->playback_pitch) { update_playback_speed(mpctx); mp_wakeup_core(mpctx); }