summaryrefslogtreecommitdiffstats
path: root/player/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/audio.c')
-rw-r--r--player/audio.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/player/audio.c b/player/audio.c
index 5b19e2fc0c..ab4e50b1b9 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -45,9 +45,14 @@
static int update_playback_speed_filters(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- double speed = opts->playback_speed;
+ double speed = mpctx->audio_speed;
struct af_stream *afs = mpctx->d_audio->afilter;
+ // Use pitch correction only for speed adjustments by the user, not minor
+ // sync correction ones.
+ bool use_pitch_correction = opts->pitch_correction &&
+ opts->playback_speed != 1.0;
+
// Make sure only exactly one filter changes speed; resetting them all
// and setting 1 filter is the easiest way to achieve this.
af_control_all(afs, AF_CONTROL_SET_PLAYBACK_SPEED, &(double){1});
@@ -63,7 +68,7 @@ static int update_playback_speed_filters(struct MPContext *mpctx)
return 0;
int method = AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE;
- if (opts->pitch_correction)
+ if (use_pitch_correction)
method = AF_CONTROL_SET_PLAYBACK_SPEED;
if (!af_control_any_rev(afs, method, &speed)) {
@@ -88,6 +93,8 @@ static int recreate_audio_filters(struct MPContext *mpctx)
if (update_playback_speed_filters(mpctx) < 0) {
mpctx->opts->playback_speed = 1.0;
+ mpctx->speed_factor_a = 1.0;
+ mpctx->audio_speed = 1.0;
mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL);
}
@@ -117,11 +124,20 @@ int reinit_audio_filters(struct MPContext *mpctx)
return 1;
}
-void set_playback_speed(struct MPContext *mpctx, double new_speed)
+// Call this if opts->playback_speed or mpctx->speed_correction changes.
+void update_playback_speed(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- opts->playback_speed = new_speed;
+ double old_speed_factor_a = mpctx->speed_factor_a;
+ double old_audio_speed = mpctx->audio_speed;
+
+ mpctx->audio_speed = opts->playback_speed * mpctx->speed_factor_a;
+ mpctx->video_speed = opts->playback_speed * mpctx->speed_factor_v;
+
+ if (mpctx->speed_factor_a == old_speed_factor_a &&
+ mpctx->audio_speed == old_audio_speed)
+ return;
if (!mpctx->d_audio || mpctx->d_audio->afilter->initialized < 1)
return;
@@ -300,7 +316,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
if (recreate_audio_filters(mpctx) < 0)
goto init_error;
- set_playback_speed(mpctx, opts->playback_speed);
+ update_playback_speed(mpctx);
return;
@@ -349,9 +365,9 @@ double written_audio_pts(struct MPContext *mpctx)
// accept everything to internal buffers yet
buffered_output += mp_audio_buffer_seconds(mpctx->ao_buffer);
- // Filters divide audio length by playback_speed, so multiply by it
+ // Filters divide audio length by audio_speed, so multiply by it
// to get the length in original units without speedup or slowdown
- a_pts -= buffered_output * mpctx->opts->playback_speed;
+ a_pts -= buffered_output * mpctx->audio_speed;
return a_pts +
get_track_video_offset(mpctx, mpctx->current_track[0][STREAM_AUDIO]);
@@ -363,7 +379,7 @@ double playing_audio_pts(struct MPContext *mpctx)
double pts = written_audio_pts(mpctx);
if (pts == MP_NOPTS_VALUE || !mpctx->ao)
return pts;
- return pts - mpctx->opts->playback_speed * ao_get_delay(mpctx->ao);
+ return pts - mpctx->audio_speed * ao_get_delay(mpctx->ao);
}
static int write_to_ao(struct MPContext *mpctx, struct mp_audio *data, int flags)
@@ -378,7 +394,7 @@ static int write_to_ao(struct MPContext *mpctx, struct mp_audio *data, int flags
#endif
if (data->samples == 0)
return 0;
- double real_samplerate = out_format.rate / mpctx->opts->playback_speed;
+ double real_samplerate = out_format.rate / mpctx->audio_speed;
int played = ao_play(mpctx->ao, data->planes, data->samples, flags);
assert(played <= data->samples);
if (played > 0) {
@@ -406,7 +422,7 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip)
struct mp_audio out_format = {0};
ao_get_format(mpctx->ao, &out_format);
- double play_samplerate = out_format.rate / opts->playback_speed;
+ double play_samplerate = out_format.rate / mpctx->audio_speed;
if (!opts->initial_audio_sync) {
mpctx->audio_status = STATUS_FILLING;
@@ -483,7 +499,7 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
struct mp_audio out_format = {0};
ao_get_format(mpctx->ao, &out_format);
- double play_samplerate = out_format.rate / opts->playback_speed;
+ double play_samplerate = out_format.rate / mpctx->audio_speed;
// If audio is infinitely fast, somehow try keeping approximate A/V sync.
if (mpctx->audio_status == STATUS_PLAYING && ao_untimed(mpctx->ao) &&