Skip to content

Commit

Permalink
add pitch-shifting feature
Browse files Browse the repository at this point in the history
Uses resampling in tandem with a time-stretching audio filter to
change the audio's pitch while leaving its tempo intact.

Curly braces have been repurposed to increase/decrease the pitch,
and backspace will now reset the pitch and speed simultaneously.
  • Loading branch information
myQwil committed Mar 4, 2023
1 parent 291e05e commit f0d6eea
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 8 deletions.
5 changes: 5 additions & 0 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,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.

Expand Down
6 changes: 3 additions & 3 deletions etc/input.conf
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@
#Shift+PGDWN seek -600 # seek 10 minutes backward
#[ multiply speed 1/1.1 # decrease the playback speed
#] multiply speed 1.1 # increase the playback speed
#{ multiply speed 0.5 # halve the playback speed
#} multiply speed 2.0 # double the playback speed
#BS set speed 1.0 # reset the speed to normal
#{ multiply pitch 1/1.1 # decrease the playback pitch
#} multiply pitch 1.1 # increase the playback pitch
#BS set pitch 1.0 ; set speed 1.0 # reset the pitch & speed to normal
#Shift+BS revert-seek # undo the previous (or marked) seek
#Shift+Ctrl+BS revert-seek mark # mark the position for revert-seek
#q quit
Expand Down
6 changes: 3 additions & 3 deletions etc/mplayer-input.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ SHARP cycle audio # switch audio streams
- add audio-delay -0.100
[ multiply speed 0.9091 # scale playback speed
] multiply speed 1.1
{ multiply speed 0.5
} multiply speed 2.0
BS set speed 1.0 # reset speed to normal
{ multiply pitch 0.9091 # scale playback pitch
} multiply pitch 1.1
BS set pitch 1.0 ; set speed 1.0 # reset pitch & speed to normal
q quit
ESC quit
ENTER playlist-next force # skip to next file
Expand Down
2 changes: 2 additions & 0 deletions options/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,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)},

Expand Down Expand Up @@ -1032,6 +1033,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,
.coverart_whitelist = true,
Expand Down
1 change: 1 addition & 0 deletions options/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,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, *vf_defs;
struct m_obj_settings *af_settings, *af_defs;
Expand Down
4 changes: 3 additions & 1 deletion player/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@ static void update_speed_filters(struct MPContext *mpctx)
return;

double speed = mpctx->opts->playback_speed;
double resample = mpctx->speed_factor_a;
double resample = mpctx->speed_factor_a * mpctx->opts->playback_pitch;
double drop = 1.0;

if (!mpctx->opts->pitch_correction) {
resample *= speed;
speed = 1.0;
}

speed /= mpctx->opts->playback_pitch;

if (mpctx->display_sync_active) {
switch (mpctx->video_out->opts->video_sync) {
case VS_DISP_ADROP:
Expand Down
18 changes: 17 additions & 1 deletion player/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,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) {
double pitch = mpctx->opts->playback_pitch;
*(char **)arg = talloc_asprintf(NULL, "%.2f", pitch);
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)
{
Expand Down Expand Up @@ -3746,6 +3759,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},
Expand Down Expand Up @@ -4158,6 +4172,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
Expand Down Expand Up @@ -6895,7 +6910,8 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
vo_control(mpctx->video_out, VOCTRL_EXTERNAL_RESIZE, NULL);
}

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);
}
Expand Down

0 comments on commit f0d6eea

Please sign in to comment.