diff options
author | wm4 <wm4@nowhere> | 2014-11-10 20:16:25 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-10 22:02:05 +0100 |
commit | e094e9cb75f9802d8da07eb75cee4d91c9786558 (patch) | |
tree | 84f6ba161fdcb0515c840ca7dd8db60be681dc65 /audio/filter | |
parent | 995a6af78734820007eb8a1ae3b543fd9d9636e1 (diff) | |
download | mpv-e094e9cb75f9802d8da07eb75cee4d91c9786558.tar.bz2 mpv-e094e9cb75f9802d8da07eb75cee4d91c9786558.tar.xz |
audio: change how filters are inserted on playback speed changes
Use a pseudo-filter when changing speed with resampling, instead of
somehow changing a samplerate somewhere. This uses the same underlying
mechanism, but is a bit more structured and cleaner. It also makes some
of the following changes easier.
Since we now always use filters to change audio speed, move most of the
work set_playback_speed() does to recreate_audio_filters().
Diffstat (limited to 'audio/filter')
-rw-r--r-- | audio/filter/af.c | 2 | ||||
-rw-r--r-- | audio/filter/af.h | 1 | ||||
-rw-r--r-- | audio/filter/af_forcespeed.c | 69 |
3 files changed, 72 insertions, 0 deletions
diff --git a/audio/filter/af.c b/audio/filter/af.c index 6a3b4bf0d5..d396a73ce3 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -53,6 +53,7 @@ extern const struct af_info af_info_center; extern const struct af_info af_info_sinesuppress; extern const struct af_info af_info_karaoke; extern const struct af_info af_info_scaletempo; +extern const struct af_info af_info_forcespeed; extern const struct af_info af_info_bs2b; extern const struct af_info af_info_lavfi; extern const struct af_info af_info_convert24; @@ -83,6 +84,7 @@ static const struct af_info *const filter_list[] = { &af_info_center, &af_info_sinesuppress, &af_info_karaoke, + &af_info_forcespeed, &af_info_scaletempo, #if HAVE_LIBBS2B &af_info_bs2b, diff --git a/audio/filter/af.h b/audio/filter/af.h index b95039b4d0..5c7a6c0e7c 100644 --- a/audio/filter/af.h +++ b/audio/filter/af.h @@ -120,6 +120,7 @@ enum af_control { AF_CONTROL_SET_PAN_BALANCE, AF_CONTROL_GET_PAN_BALANCE, AF_CONTROL_SET_PLAYBACK_SPEED, + AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE, }; // Argument for AF_CONTROL_SET_PAN_LEVEL diff --git a/audio/filter/af_forcespeed.c b/audio/filter/af_forcespeed.c new file mode 100644 index 0000000000..d2d2f9abb7 --- /dev/null +++ b/audio/filter/af_forcespeed.c @@ -0,0 +1,69 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "af.h" + +struct priv { + double speed; +}; + +static int control(struct af_instance *af, int cmd, void *arg) +{ + struct priv *priv = af->priv; + + switch (cmd) { + case AF_CONTROL_REINIT: { + struct mp_audio *in = arg; + struct mp_audio orig_in = *in; + struct mp_audio *out = af->data; + + mp_audio_copy_config(out, in); + out->rate = in->rate * priv->speed; + + return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE; + } + case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: { + priv->speed = *(double *)arg; + return AF_OK; + } + } + return AF_UNKNOWN; +} + +static int filter(struct af_instance *af, struct mp_audio *data, int flags) +{ + mp_audio_copy_config(data, af->data); + return 0; +} + +static int af_open(struct af_instance *af) +{ + struct priv *priv = af->priv; + af->control = control; + af->filter = filter; + priv->speed = 1.0; + return AF_OK; +} + +#define OPT_BASE_STRUCT struct priv + +const struct af_info af_info_forcespeed = { + .info = "Force audio speed", + .name = "forcespeed", + .open = af_open, + .priv_size = sizeof(struct priv), +}; |