From 87fe7d878843688a0f530fc9ce5a1a0775c77b9e Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 15 Jan 2015 20:10:52 +0100 Subject: audio/filter: switch remaining in-place filters to refcounting Adds about 7 lines of boilerplate per filter. This could be avoided by providing a different entrypoint (something like af->filter_inplace), which would basically mirror the old interface exactly for this kind of filter. But I feel like it would just be a hack to support all those old, useless filters better. (The ideal solution would be using a language that can do closures to provide a compat. wrapper, but whatever.) af_bs2b has terribly repetitious code for setting up filter functions for each format (most of them useless, in addition to bs2b being useless), so I did something terrible with macros. af_sinesuppress had commented code for float filtering (maybe it was broken; it has been commented every since it was added in 2006). Remove this code. --- audio/filter/af_bs2b.c | 89 ++++++++++++++++++++---------------------- audio/filter/af_center.c | 12 ++++-- audio/filter/af_delay.c | 13 ++++-- audio/filter/af_extrastereo.c | 38 +++++++++--------- audio/filter/af_karaoke.c | 14 +++++-- audio/filter/af_ladspa.c | 16 ++++++-- audio/filter/af_sinesuppress.c | 53 ++++++------------------- audio/filter/af_sub.c | 13 ++++-- audio/filter/af_sweep.c | 13 ++++-- 9 files changed, 134 insertions(+), 127 deletions(-) diff --git a/audio/filter/af_bs2b.c b/audio/filter/af_bs2b.c index 29d646a9a9..874dbc6786 100644 --- a/audio/filter/af_bs2b.c +++ b/audio/filter/af_bs2b.c @@ -37,26 +37,49 @@ struct af_bs2b { t_bs2bdp filter; ///< instance of a library filter }; -#define FILTER(name, type) \ -static int filter_##name(struct af_instance *af, struct mp_audio *data, int f) \ +#define DEF_FILTER(fmt, name) \ +static int filter_##name(struct af_instance *af, struct mp_audio *data) \ { \ - /* filter is called for all pairs of samples available in the buffer */ \ + if (!data) \ + return 0; \ + if (af_make_writeable(af, data) < 0) { \ + talloc_free(data); \ + return -1; \ + } \ bs2b_cross_feed_##name(((struct af_bs2b*)(af->priv))->filter, \ - (type*)(data->planes[0]), data->samples); \ -\ + (data->planes[0]), data->samples); \ + af_add_output_frame(af, data); \ return 0; \ } -FILTER(f, float) -FILTER(s32, int32_t) -FILTER(u32, uint32_t) -FILTER(s24, bs2b_int24_t) -FILTER(u24, bs2b_uint24_t) -FILTER(s16, int16_t) -FILTER(u16, uint16_t) -FILTER(s8, int8_t) -FILTER(u8, uint8_t) - +#define GET_FILTER(fmt, name) \ + case AF_FORMAT_##fmt: return filter_##name; + +#define FILTERS \ + FILTER(FLOAT, f) \ + FILTER(S32, s32) \ + FILTER(U32, u32) \ + FILTER(S24, s24) \ + FILTER(U24, u24) \ + FILTER(S16, s16) \ + FILTER(U16, u16) \ + FILTER(S8, s8) \ + FILTER(U8, u8) + +#define FILTER DEF_FILTER +FILTERS +#undef FILTER + +typedef int (*filter)(struct af_instance *af, struct mp_audio *d); +static filter get_filter(int fmt) +{ + switch (fmt) { +#define FILTER GET_FILTER +FILTERS +#undef FILTER + default: return NULL; + } +} /// Initialization and runtime control static int control(struct af_instance *af, int cmd, void *arg) @@ -76,38 +99,10 @@ static int control(struct af_instance *af, int cmd, void *arg) /* check for formats supported by libbs2b and assign corresponding handlers */ - switch (format) { - case AF_FORMAT_FLOAT: - af->filter = filter_f; - break; - case AF_FORMAT_S32: - af->filter = filter_s32; - break; - case AF_FORMAT_U32: - af->filter = filter_u32; - break; - case AF_FORMAT_S24: - af->filter = filter_s24; - break; - case AF_FORMAT_U24: - af->filter = filter_u24; - break; - case AF_FORMAT_S16: - af->filter = filter_s16; - break; - case AF_FORMAT_U16: - af->filter = filter_u16; - break; - case AF_FORMAT_S8: - af->filter = filter_s8; - break; - case AF_FORMAT_U8: - af->filter = filter_u8; - break; - default: - af->filter = filter_f; - mp_audio_set_format(af->data, AF_FORMAT_FLOAT); - break; + af->filter_frame = get_filter(format); + if (!af->filter_frame) { + af->filter_frame = filter_f; + mp_audio_set_format(af->data, AF_FORMAT_FLOAT); } // bs2b have srate limits, try to resample if needed diff --git a/audio/filter/af_center.c b/audio/filter/af_center.c index 3039e50302..ff2a37dee9 100644 --- a/audio/filter/af_center.c +++ b/audio/filter/af_center.c @@ -58,9 +58,14 @@ static int control(struct af_instance* af, int cmd, void* arg) return AF_UNKNOWN; } -// Filter data through filter -static int filter(struct af_instance* af, struct mp_audio* data, int flags) +static int filter_frame(struct af_instance* af, struct mp_audio* data) { + if (!data) + return 0; + if (af_make_writeable(af, data) < 0) { + talloc_free(data); + return -1; + } struct mp_audio* c = data; // Current working data af_center_t* s = af->priv; // Setup for this instance float* a = c->planes[0]; // Audio data @@ -75,13 +80,14 @@ static int filter(struct af_instance* af, struct mp_audio* data, int flags) a[i+ch] = (a[i]/2) + (a[i+1]/2); } + af_add_output_frame(af, data); return 0; } // Allocate memory and set function pointers static int af_open(struct af_instance* af){ af->control=control; - af->filter=filter; + af->filter_frame = filter_frame; return AF_OK; } diff --git a/audio/filter/af_delay.c b/audio/filter/af_delay.c index 56013b3270..8de26ece77 100644 --- a/audio/filter/af_delay.c +++ b/audio/filter/af_delay.c @@ -96,15 +96,19 @@ static void uninit(struct af_instance* af) free(((af_delay_t*)(af->priv))->q[i]); } -// Filter data through filter -static int filter(struct af_instance* af, struct mp_audio* data, int flags) +static int filter_frame(struct af_instance *af, struct mp_audio *c) { - struct mp_audio* c = data; // Current working data + if (!c) + return 0; af_delay_t* s = af->priv; // Setup for this instance int nch = c->nch; // Number of channels int len = mp_audio_psize(c)/c->bps; // Number of sample in data chunk int ri = 0; int ch,i; + if (af_make_writeable(af, c) < 0) { + talloc_free(c); + return -1; + } for(ch=0;chbps){ case 1:{ @@ -152,6 +156,7 @@ static int filter(struct af_instance* af, struct mp_audio* data, int flags) } } s->ri = ri; + af_add_output_frame(af, c); return 0; } @@ -159,7 +164,7 @@ static int filter(struct af_instance* af, struct mp_audio* data, int flags) static int af_open(struct af_instance* af){ af->control=control; af->uninit=uninit; - af->filter=filter; + af->filter_frame = filter_frame; af_delay_t *s = af->priv; int n = 1; int i = 0; diff --git a/audio/filter/af_extrastereo.c b/audio/filter/af_extrastereo.c index 4ebe03a228..4b39793e09 100644 --- a/audio/filter/af_extrastereo.c +++ b/audio/filter/af_extrastereo.c @@ -35,9 +35,6 @@ typedef struct af_extrastereo_s float mul; }af_extrastereo_t; -static int play_s16(struct af_instance* af, struct mp_audio* data, int f); -static int play_float(struct af_instance* af, struct mp_audio* data, int f); - // Initialization and runtime control static int control(struct af_instance* af, int cmd, void* arg) { @@ -49,14 +46,8 @@ static int control(struct af_instance* af, int cmd, void* arg) mp_audio_copy_config(af->data, (struct mp_audio*)arg); mp_audio_force_interleaved_format(af->data); mp_audio_set_num_channels(af->data, 2); - if (af->data->format == AF_FORMAT_FLOAT) - { - af->filter = play_float; - }// else - { + if (af->data->format != AF_FORMAT_FLOAT) mp_audio_set_format(af->data, AF_FORMAT_S16); - af->filter = play_s16; - } return af_test_output(af,(struct mp_audio*)arg); } @@ -65,9 +56,8 @@ static int control(struct af_instance* af, int cmd, void* arg) } // Filter data through filter -static int play_s16(struct af_instance* af, struct mp_audio* data, int f) +static void play_s16(af_extrastereo_t *s, struct mp_audio* data) { - af_extrastereo_t *s = af->priv; register int i = 0; int16_t *a = (int16_t*)data->planes[0]; // Audio data int len = data->samples*data->nch; // Number of samples @@ -83,13 +73,10 @@ static int play_s16(struct af_instance* af, struct mp_audio* data, int f) a[i] = MPCLAMP(l, SHRT_MIN, SHRT_MAX); a[i + 1] = MPCLAMP(r, SHRT_MIN, SHRT_MAX); } - - return 0; } -static int play_float(struct af_instance* af, struct mp_audio* data, int f) +static void play_float(af_extrastereo_t *s, struct mp_audio* data) { - af_extrastereo_t *s = af->priv; register int i = 0; float *a = (float*)data->planes[0]; // Audio data int len = data->samples * data->nch; // Number of samples @@ -105,14 +92,29 @@ static int play_float(struct af_instance* af, struct mp_audio* data, int f) a[i] = af_softclip(l); a[i + 1] = af_softclip(r); } +} - return 0; +static int filter_frame(struct af_instance *af, struct mp_audio *data) +{ + if (!data) + return 0; + if (af_make_writeable(af, data) < 0) { + talloc_free(data); + return -1; + } + if (data->format == AF_FORMAT_FLOAT) { + play_float(af->priv, data); + } else { + play_s16(af->priv, data); + } + af_add_output_frame(af, data); + return 0; } // Allocate memory and set function pointers static int af_open(struct af_instance* af){ af->control=control; - af->filter=play_s16; + af->filter_frame = filter_frame; return AF_OK; } diff --git a/audio/filter/af_karaoke.c b/audio/filter/af_karaoke.c index 3187a41f2f..f69b936811 100644 --- a/audio/filter/af_karaoke.c +++ b/audio/filter/af_karaoke.c @@ -41,10 +41,15 @@ static int control(struct af_instance* af, int cmd, void* arg) return AF_UNKNOWN; } -// Filter data through filter -static int play(struct af_instance* af, struct mp_audio* data, int flags) +static int filter_frame(struct af_instance *af, struct mp_audio *c) { - struct mp_audio* c = data; // Current working data + if (!c) + return 0; + if (af_make_writeable(af, c) < 0) { + talloc_free(c); + return 0; + } + float* a = c->planes[0]; // Audio data int nch = c->nch; // Number of channels int len = c->samples*nch; // Number of samples in current audio block @@ -62,13 +67,14 @@ static int play(struct af_instance* af, struct mp_audio* data, int flags) a[i+1]=a[i]; } + af_add_output_frame(af, c); return 0; } // Allocate memory and set function pointers static int af_open(struct af_instance* af){ af->control = control; - af->filter = play; + af->filter_frame = filter_frame; return AF_OK; } diff --git a/audio/filter/af_ladspa.c b/audio/filter/af_ladspa.c index ab76c35fe9..6a8cd802f6 100644 --- a/audio/filter/af_ladspa.c +++ b/audio/filter/af_ladspa.c @@ -565,7 +565,10 @@ static void uninit(struct af_instance *af) { * \return Either AF_ERROR or AF_OK */ -static int filter(struct af_instance *af, struct mp_audio *data, int flags) { +static int filter_frame(struct af_instance *af, struct mp_audio *data) +{ + if (!data) + return 0; af_ladspa_t *setup = af->priv; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; float *audio = (float*)data->planes[0]; @@ -574,8 +577,14 @@ static int filter(struct af_instance *af, struct mp_audio *data, int flags) { int rate = data->rate; int i, p; - if (setup->status !=AF_OK) + if (setup->status !=AF_OK) { + talloc_free(data); + return -1; + } + if (af_make_writeable(af, data) < 0) { + talloc_free(data); return -1; + } /* See if it's the first call. If so, setup inbufs/outbufs, instantiate * plugin, connect ports and activate plugin @@ -721,6 +730,7 @@ static int filter(struct af_instance *af, struct mp_audio *data, int flags) { /* done */ + af_add_output_frame(af, data); return 0; } @@ -737,7 +747,7 @@ static int af_open(struct af_instance *af) { af->control=control; af->uninit=uninit; - af->filter=filter; + af->filter_frame = filter_frame; af_ladspa_t *setup = af->priv; diff --git a/audio/filter/af_sinesuppress.c b/audio/filter/af_sinesuppress.c index 95d2478b7e..32e074d508 100644 --- a/audio/filter/af_sinesuppress.c +++ b/audio/filter/af_sinesuppress.c @@ -41,9 +41,6 @@ typedef struct af_sinesuppress_s double pos; }af_sinesuppress_t; -static int play_s16(struct af_instance* af, struct mp_audio* data, int f); -//static struct mp_audio* play_float(struct af_instance* af, struct mp_audio* data); - // Initialization and runtime control static int control(struct af_instance* af, int cmd, void* arg) { @@ -54,18 +51,7 @@ static int control(struct af_instance* af, int cmd, void* arg) mp_audio_copy_config(af->data, (struct mp_audio*)arg); mp_audio_set_num_channels(af->data, 1); -#if 0 - if (((struct mp_audio*)arg)->format == AF_FORMAT_FLOAT) - { - af->data->format = AF_FORMAT_FLOAT; - af->data->bps = 4; - af->play = play_float; - }// else -#endif - { - mp_audio_set_format(af->data, AF_FORMAT_S16); - af->filter = play_s16; - } + mp_audio_set_format(af->data, AF_FORMAT_S16); return af_test_output(af,(struct mp_audio*)arg); } @@ -73,9 +59,15 @@ static int control(struct af_instance* af, int cmd, void* arg) return AF_UNKNOWN; } -// Filter data through filter -static int play_s16(struct af_instance* af, struct mp_audio* data, int f) +static int play_s16(struct af_instance *af, struct mp_audio *data) { + if (!data) + return 0; + if (af_make_writeable(af, data) < 0) { + talloc_free(data); + return -1; + } + af_sinesuppress_t *s = af->priv; register int i = 0; int16_t *a = (int16_t*)data->planes[0]; // Audio data @@ -101,37 +93,14 @@ static int play_s16(struct af_instance* af, struct mp_audio* data, int f) MP_VERBOSE(af, "f:%8.2f: amp:%8.2f\n", s->freq, sqrt(s->real*s->real + s->imag*s->imag) / s->ref); + af_add_output_frame(af, data); return 0; } -#if 0 -static struct mp_audio* play_float(struct af_instance* af, struct mp_audio* data) -{ - af_sinesuppress_t *s = af->setup; - register int i = 0; - float *a = (float*)data->audio; // Audio data - int len = data->len/4; // Number of samples - float avg, l, r; - - for (i = 0; i < len; i+=2) - { - avg = (a[i] + a[i + 1]) / 2; - -/* l = avg + (s->mul * (a[i] - avg)); - r = avg + (s->mul * (a[i + 1] - avg));*/ - - a[i] = af_softclip(l); - a[i + 1] = af_softclip(r); - } - - return data; -} -#endif - // Allocate memory and set function pointers static int af_open(struct af_instance* af){ af->control=control; - af->filter=play_s16; + af->filter_frame = play_s16; return AF_OK; } diff --git a/audio/filter/af_sub.c b/audio/filter/af_sub.c index 5642c4573d..243c9cef70 100644 --- a/audio/filter/af_sub.c +++ b/audio/filter/af_sub.c @@ -98,9 +98,15 @@ static int control(struct af_instance* af, int cmd, void* arg) } #endif -// Filter data through filter -static int filter(struct af_instance* af, struct mp_audio* data, int flags) +static int filter_frame(struct af_instance *af, struct mp_audio *data) { + if (!data) + return 0; + if (af_make_writeable(af, data) < 0) { + talloc_free(data); + return -1; + } + struct mp_audio* c = data; // Current working data af_sub_t* s = af->priv; // Setup for this instance float* a = c->planes[0]; // Audio data @@ -117,13 +123,14 @@ static int filter(struct af_instance* af, struct mp_audio* data, int flags) IIR(x , s->w[1], s->q[1], a[i+ch]); } + af_add_output_frame(af, data); return 0; } // Allocate memory and set function pointers static int af_open(struct af_instance* af){ af->control=control; - af->filter=filter; + af->filter_frame = filter_frame; return AF_OK; } diff --git a/audio/filter/af_sweep.c b/audio/filter/af_sweep.c index 982cb6210c..854ef1446c 100644 --- a/audio/filter/af_sweep.c +++ b/audio/filter/af_sweep.c @@ -48,9 +48,15 @@ static int control(struct af_instance* af, int cmd, void* arg) return AF_UNKNOWN; } -// Filter data through filter -static int filter(struct af_instance* af, struct mp_audio* data, int f) +static int filter_frame(struct af_instance *af, struct mp_audio *data) { + if (!data) + return 0; + if (af_make_writeable(af, data) < 0) { + talloc_free(data); + return 0; + } + af_sweept *s = af->priv; int i, j; int16_t *in = (int16_t*)data->planes[0]; @@ -64,12 +70,13 @@ static int filter(struct af_instance* af, struct mp_audio* data, int f) if(2*s->x*s->delta >= 3.141592) s->x=0; } + af_add_output_frame(af, data); return 0; } static int af_open(struct af_instance* af){ af->control=control; - af->filter=filter; + af->filter_frame = filter_frame; return AF_OK; } -- cgit v1.2.3