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:
Mike Will
2024-03-27 06:14:57 -04:00
committed by Kacper Michajłow
parent 763bcd3e52
commit 88885c0401
6 changed files with 43 additions and 12 deletions

View File

@@ -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);

View File

@@ -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);
}