From 465b162d1386e94a45699094914045b0ef8e2e0f Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 22 Jul 2013 14:47:34 +0200 Subject: [PATCH] af_scaletempo: use new option API --- audio/filter/af_scaletempo.c | 128 ++++++++++++----------------------- 1 file changed, 44 insertions(+), 84 deletions(-) diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index 5cf0f3b082..b12954f1af 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -36,9 +36,10 @@ #include #include +#include "core/mp_common.h" + #include "af.h" -#include "libavutil/common.h" -#include "core/subopt-helper.h" +#include "core/m_option.h" // Data for specific instances of this filter typedef struct af_scaletempo_s @@ -74,13 +75,14 @@ typedef struct af_scaletempo_s float ms_stride; float percent_overlap; float ms_search; + int speed_opt; short speed_tempo; short speed_pitch; } af_scaletempo_t; static int fill_queue(struct af_instance* af, struct mp_audio* data, int offset) { - af_scaletempo_t* s = af->setup; + af_scaletempo_t* s = af->priv; int bytes_in = data->len - offset; int offset_unchanged = offset; @@ -95,7 +97,7 @@ static int fill_queue(struct af_instance* af, struct mp_audio* data, int offset) } else { int bytes_skip; s->bytes_to_slide -= s->bytes_queued; - bytes_skip = FFMIN(s->bytes_to_slide, bytes_in); + bytes_skip = MPMIN(s->bytes_to_slide, bytes_in); s->bytes_queued = 0; s->bytes_to_slide -= bytes_skip; offset += bytes_skip; @@ -104,7 +106,7 @@ static int fill_queue(struct af_instance* af, struct mp_audio* data, int offset) } if (bytes_in > 0) { - int bytes_copy = FFMIN(s->bytes_queue - s->bytes_queued, bytes_in); + int bytes_copy = MPMIN(s->bytes_queue - s->bytes_queued, bytes_in); assert(bytes_copy >= 0); memcpy(s->buf_queue + s->bytes_queued, (int8_t*)data->audio + offset, @@ -221,7 +223,7 @@ static void output_overlap_s16(af_scaletempo_t* s, void* buf_out, // Filter data through filter static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) { - af_scaletempo_t* s = af->setup; + af_scaletempo_t* s = af->priv; int offset_in; int max_bytes_out; int8_t* pout; @@ -287,7 +289,7 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) // Initialization and runtime control static int control(struct af_instance* af, int cmd, void* arg) { - af_scaletempo_t* s = af->setup; + af_scaletempo_t* s = af->priv; switch(cmd){ case AF_CONTROL_REINIT:{ struct mp_audio* data = (struct mp_audio*)arg; @@ -461,69 +463,6 @@ static int control(struct af_instance* af, int cmd, void* arg) case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_GET: *(float*)arg = s->scale; return AF_OK; - case AF_CONTROL_COMMAND_LINE:{ - strarg_t speed = {}; - opt_t subopts[] = { - {"scale", OPT_ARG_FLOAT, &s->scale_nominal, NULL}, - {"stride", OPT_ARG_FLOAT, &s->ms_stride, NULL}, - {"overlap", OPT_ARG_FLOAT, &s->percent_overlap, NULL}, - {"search", OPT_ARG_FLOAT, &s->ms_search, NULL}, - {"speed", OPT_ARG_STR, &speed, NULL}, - {NULL}, - }; - if (subopt_parse(arg, subopts) != 0) { - return AF_ERROR; - } - if (s->scale_nominal <= 0) { - mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] %s: %s: scale > 0\n", - mp_gtext("error parsing command line"), - mp_gtext("value out of range")); - return AF_ERROR; - } - if (s->ms_stride <= 0) { - mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] %s: %s: stride > 0\n", - mp_gtext("error parsing command line"), - mp_gtext("value out of range")); - return AF_ERROR; - } - if (s->percent_overlap < 0 || s->percent_overlap > 1) { - mp_msg(MSGT_AFILTER, MSGL_ERR, - "[scaletempo] %s: %s: 0 <= overlap <= 1\n", - mp_gtext("error parsing command line"), - mp_gtext("value out of range")); - return AF_ERROR; - } - if (s->ms_search < 0) { - mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] %s: %s: search >= 0\n", - mp_gtext("error parsing command line"), - mp_gtext("value out of range")); - return AF_ERROR; - } - if (speed.len > 0) { - if (strcmp(speed.str, "pitch") == 0) { - s->speed_tempo = 0; - s->speed_pitch = 1; - } else if (strcmp(speed.str, "tempo") == 0) { - s->speed_tempo = 1; - s->speed_pitch = 0; - } else if (strcmp(speed.str, "none") == 0) { - s->speed_tempo = 0; - s->speed_pitch = 0; - } else if (strcmp(speed.str, "both") == 0) { - s->speed_tempo = 1; - s->speed_pitch = 1; - } else { - mp_msg(MSGT_AFILTER, MSGL_ERR, - "[scaletempo] %s: %s: speed=[pitch|tempo|none|both]\n", - mp_gtext("error parsing command line"), - mp_gtext("value out of range")); - return AF_ERROR; - } - } - s->scale = s->speed * s->scale_nominal; - mp_msg(MSGT_AFILTER, MSGL_DBG2, "[scaletempo] %6.3f scale, %6.2f stride, %6.2f overlap, %6.2f search, speed = %s\n", s->scale_nominal, s->ms_stride, s->percent_overlap, s->ms_search, (s->speed_tempo?(s->speed_pitch?"tempo and speed":"tempo"):(s->speed_pitch?"pitch":"none"))); - return AF_OK; - } } return AF_UNKNOWN; } @@ -531,7 +470,7 @@ static int control(struct af_instance* af, int cmd, void* arg) // Deallocate memory static void uninit(struct af_instance* af) { - af_scaletempo_t* s = af->setup; + af_scaletempo_t* s = af->priv; free(af->data->audio); free(af->data); free(s->buf_queue); @@ -539,39 +478,60 @@ static void uninit(struct af_instance* af) free(s->buf_pre_corr); free(s->table_blend); free(s->table_window); - free(af->setup); } +#define SCALE_TEMPO 1 +#define SCALE_PITCH 2 + // Allocate memory and set function pointers static int af_open(struct af_instance* af){ - af_scaletempo_t* s; + af_scaletempo_t *s = af->priv; af->control = control; af->uninit = uninit; af->play = play; af->mul = 1; af->data = calloc(1,sizeof(struct mp_audio)); - af->setup = calloc(1,sizeof(af_scaletempo_t)); - if(af->data == NULL || af->setup == NULL) + if(af->data == NULL) return AF_ERROR; - s = af->setup; - s->scale = s->speed = s->scale_nominal = 1.0; - s->speed_tempo = 1; - s->speed_pitch = 0; - s->ms_stride = 60; - s->percent_overlap = .20; - s->ms_search = 14; + s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO); + s->speed_pitch = !!(s->speed_opt & SCALE_PITCH); + + s->scale = s->speed * s->scale_nominal; + mp_msg(MSGT_AFILTER, MSGL_DBG2, "[scaletempo] %6.3f scale, %6.2f stride, %6.2f overlap, %6.2f search, speed = %s\n", s->scale_nominal, s->ms_stride, s->percent_overlap, s->ms_search, (s->speed_tempo?(s->speed_pitch?"tempo and speed":"tempo"):(s->speed_pitch?"pitch":"none"))); return AF_OK; } -// Description of this filter +#define OPT_BASE_STRUCT af_scaletempo_t + struct af_info af_info_scaletempo = { "Scale audio tempo while maintaining pitch", "scaletempo", "Robert Juliano", "", AF_FLAGS_REENTRANT, - af_open + af_open, + .priv_size = sizeof(af_scaletempo_t), + .priv_defaults = &(const af_scaletempo_t) { + .ms_stride = 60, + .percent_overlap = .20, + .ms_search = 14, + .speed_opt = SCALE_TEMPO, + .speed = 1.0, + .scale_nominal = 1.0, + }, + .options = (const struct m_option[]) { + OPT_FLOAT("scale", scale_nominal, M_OPT_MIN, .min = 0.01), + OPT_FLOAT("stride", ms_stride, M_OPT_MIN, .min = 0.01), + OPT_FLOAT("overlap", percent_overlap, M_OPT_RANGE, .min = 0, .max = 1), + OPT_FLOAT("search", ms_search, M_OPT_MIN, .min = 0), + OPT_CHOICE("speed", speed_opt, 0, + ({"pitch", SCALE_PITCH}, + {"tempo", SCALE_TEMPO}, + {"none", 0}, + {"both", SCALE_TEMPO | SCALE_PITCH})), + {0} + }, };