mirror of https://github.com/mpv-player/mpv
audio: add pitch-shifting feature
Uses resampling in tandem with a time-stretching audio filter to change the audio's pitch while leaving its tempo intact.
This commit is contained in:
parent
763bcd3e52
commit
88885c0401
|
@ -0,0 +1 @@
|
|||
add `--pitch` option
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue