diff options
author | wm4 <wm4@nowhere> | 2015-02-10 22:34:07 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-02-10 22:34:07 +0100 |
commit | 81d8c5d519828b1d5de9a30d23ceeb6c4c9a1d15 (patch) | |
tree | 2464a5259a9db73ef66e91449285daa182f2a029 | |
parent | 2a3d19a9dffc2613d491fc4dcd49e1e239e663c9 (diff) |
af_scaletempo: allow changing speed at runtime without reinit
Staring at the code a bit, it turns out that changing speed without
losing state is quite easy. The initialization code is big and
complicated, but most of it is specific only to the configured audio
format, not the speed.
Refactor the code so that changing speed at runtime could work. (It's
not actually used yet - the player code still does a complete reinit.
This will be fixed in the next commit.)
The "if (s->speed_tempo == s->speed_pitch)" looks a bit strange, but
does the same thing as the code did before: speed can be changed only if
exactly one flag is set. If both are set or none, speed can't be
changed.
-rw-r--r-- | audio/filter/af_scaletempo.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index 449ad02dc2..707060578f 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -276,6 +276,22 @@ static int filter(struct af_instance *af, struct mp_audio *data) return 0; } +static void update_speed(struct af_instance *af, float speed) +{ + af_scaletempo_t *s = af->priv; + + s->speed = speed; + + double factor = s->speed_pitch ? 1.0 / s->speed : s->speed; + s->scale = factor * s->scale_nominal; + + s->frames_stride_scaled = s->scale * s->frames_stride; + s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled); + + MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n", + s->speed, s->scale_nominal, s->scale); +} + // Initialization and runtime control static int control(struct af_instance *af, int cmd, void *arg) { @@ -292,9 +308,6 @@ static int control(struct af_instance *af, int cmd, void *arg) return AF_DETACH; } - MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n", - s->speed, s->scale_nominal, s->scale); - mp_audio_force_interleaved_format(data); mp_audio_copy_config(af->data, data); @@ -307,10 +320,10 @@ static int control(struct af_instance *af, int cmd, void *arg) s->frames_stride = srate * s->ms_stride; s->bytes_stride = s->frames_stride * bps * nch; - s->frames_stride_scaled = s->scale * s->frames_stride; - s->frames_stride_error = 0; af->delay = 0; + update_speed(af, s->speed); + int frames_overlap = s->frames_stride * s->percent_overlap; if (frames_overlap <= 0) { s->bytes_standing = s->bytes_stride; @@ -420,18 +433,9 @@ static int control(struct af_instance *af, int cmd, void *arg) return af_test_output(af, (struct mp_audio *)arg); } case AF_CONTROL_SET_PLAYBACK_SPEED: { - if (s->speed_tempo) { - if (s->speed_pitch) - break; - s->speed = *(double *)arg; - s->scale = s->speed * s->scale_nominal; - } else { - if (s->speed_pitch) { - s->speed = 1 / *(double *)arg; - s->scale = s->speed * s->scale_nominal; - break; - } - } + if (s->speed_tempo == s->speed_pitch) + break; // doesn't change speed + update_speed(af, *(double *)arg); return AF_OK; } case AF_CONTROL_RESET: @@ -469,7 +473,6 @@ static int af_open(struct af_instance *af) s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO); s->speed_pitch = !!(s->speed_opt & SCALE_PITCH); - s->scale = s->speed * s->scale_nominal; return AF_OK; } |