This gets rid of multiple entries of a implementation in the init table. --- src/pulsecore/resampler.c | 192 ++++++++++++++++++++++------------------------ src/pulsecore/resampler.h | 1 + 2 files changed, 94 insertions(+), 99 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 35342af..c297188 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -77,115 +77,117 @@ struct pa_resampler { pa_resampler_implementation implementation; }; -struct trivial { /* data specific to the trivial resampler */ - unsigned o_counter; - unsigned i_counter; +static int copy_init(pa_resampler *r); + +static pa_resampler_implementation copy_impl = { + .init = copy_init, }; -struct peaks{ /* data specific to the peak finder pseudo resampler */ +static int trivial_init(pa_resampler*r); +static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames); +static void trivial_update_rates_or_reset(pa_resampler *r); + +struct trivial { /* data specific to the trivial resampler */ unsigned o_counter; unsigned i_counter; - - float max_f[PA_CHANNELS_MAX]; - int16_t max_i[PA_CHANNELS_MAX]; }; -#ifdef HAVE_LIBSAMPLERATE -struct src{ /* data specific to libsamplerate */ - SRC_STATE *state; +static pa_resampler_implementation trivial_impl = { + .init = trivial_init, + .resample = trivial_resample, + .update_rates = trivial_update_rates_or_reset, + .reset = trivial_update_rates_or_reset, }; -#endif #ifdef HAVE_SPEEX +static int speex_init(pa_resampler*r); +static void speex_free(pa_resampler *r); +static void speex_update_rates(pa_resampler *r); +static void speex_reset(pa_resampler *r); + struct speex{ /* data specific to speex */ SpeexResamplerState* state; }; + +static pa_resampler_implementation speex_impl = { + .init = speex_init, + .free = speex_free, + .update_rates = speex_update_rates, + .reset = speex_reset, +}; #endif +static int ffmpeg_init(pa_resampler*r); +static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames); +static void ffmpeg_free(pa_resampler *r); + struct ffmpeg { /* data specific to ffmpeg */ struct AVResampleContext *state; pa_memchunk buf[PA_CHANNELS_MAX]; }; -static int copy_init(pa_resampler *r); -static int trivial_init(pa_resampler*r); -#ifdef HAVE_SPEEX -static int speex_init(pa_resampler*r); -#endif -static int ffmpeg_init(pa_resampler*r); +static pa_resampler_implementation ffmpeg_impl = { + .init = ffmpeg_init, + .free = ffmpeg_free, + .resample = ffmpeg_resample, +}; + static int peaks_init(pa_resampler*r); +static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames); +static void peaks_update_rates_or_reset(pa_resampler *r); + +static pa_resampler_implementation peaks_impl = { + .init = peaks_init, + .resample = peaks_resample, + .update_rates = peaks_update_rates_or_reset, + .reset = peaks_update_rates_or_reset, +}; + +struct peaks{ /* data specific to the peak finder pseudo resampler */ + unsigned o_counter; + unsigned i_counter; + + float max_f[PA_CHANNELS_MAX]; + int16_t max_i[PA_CHANNELS_MAX]; +}; + #ifdef HAVE_LIBSAMPLERATE static int libsamplerate_init(pa_resampler*r); +static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames); +static void libsamplerate_update_rates(pa_resampler *r); +static void libsamplerate_reset(pa_resampler *r); +static void libsamplerate_free(pa_resampler *r); + +struct src{ /* data specific to libsamplerate */ + SRC_STATE *state; +}; + +static pa_resampler_implementation libsamplerate_impl = { + .init = libsamplerate_init, + .free = libsamplerate_free, + .resample = libsamplerate_resample, + .update_rates = libsamplerate_update_rates, + .reset = libsamplerate_reset, +}; #endif static void calc_map_table(pa_resampler *r); -static int (* const init_table[])(pa_resampler*r) = { +static pa_resampler_implementation *impl_table[] = { #ifdef HAVE_LIBSAMPLERATE - [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init, - [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init, - [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init, - [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init, - [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init, + [PA_RESAMPLER_SRC_LINEAR] = &libsamplerate_impl, #else - [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL, - [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL, - [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL, - [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL, - [PA_RESAMPLER_SRC_LINEAR] = NULL, + [PA_RESAMPLER_SRC_LINEAR] = NULL, #endif - [PA_RESAMPLER_TRIVIAL] = trivial_init, + [PA_RESAMPLER_TRIVIAL] = &trivial_impl, #ifdef HAVE_SPEEX - [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init, - [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE] = &speex_impl, #else - [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = NULL, - [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = NULL, - [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = NULL, + [PA_RESAMPLER_SPEEX_FIXED_BASE] = NULL, #endif - [PA_RESAMPLER_FFMPEG] = ffmpeg_init, - [PA_RESAMPLER_AUTO] = NULL, - [PA_RESAMPLER_COPY] = copy_init, - [PA_RESAMPLER_PEAKS] = peaks_init, + [PA_RESAMPLER_FFMPEG] = &ffmpeg_impl, + [PA_RESAMPLER_COPY] = ©_impl, + [PA_RESAMPLER_PEAKS] = &peaks_impl, }; static pa_resample_method_t pa_resampler_fix_method( @@ -366,6 +368,15 @@ pa_resampler* pa_resampler_new( r = pa_xnew0(pa_resampler, 1); r->mempool = pool; r->method = method; + if (method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + r->implementation = *impl_table[PA_RESAMPLER_SPEEX_FIXED_BASE]; + else if (method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && method <= PA_RESAMPLER_SPEEX_FLOAT_MAX) { + r->implementation = *impl_table[PA_RESAMPLER_SPEEX_FIXED_BASE]; + } else if (method <= PA_RESAMPLER_SRC_LINEAR) + r->implementation = *impl_table[PA_RESAMPLER_SRC_LINEAR]; + else + r->implementation = *impl_table[method]; + r->flags = flags; /* Fill sample specs */ @@ -423,7 +434,7 @@ pa_resampler* pa_resampler_new( } /* initialize implementation */ - if (init_table[method](r) < 0) + if (r->implementation.init(r) < 0) goto fail; return r; @@ -1419,15 +1430,11 @@ static int libsamplerate_init(pa_resampler *r) { pa_assert(r); libsamplerate_data = pa_xnew(struct src, 1); + r->implementation.data = libsamplerate_data; if (!(libsamplerate_data->state = src_new(r->method, r->o_ss.channels, &err))) return -1; - r->implementation.free = libsamplerate_free; - r->implementation.update_rates = libsamplerate_update_rates; - r->implementation.resample = libsamplerate_resample; - r->implementation.reset = libsamplerate_reset; - r->implementation.data = libsamplerate_data; return 0; } @@ -1520,10 +1527,6 @@ static int speex_init(pa_resampler *r) { pa_assert(r); speex_data = pa_xnew(struct speex, 1); - - r->implementation.free = speex_free; - r->implementation.update_rates = speex_update_rates; - r->implementation.reset = speex_reset; r->implementation.data = speex_data; if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX) { @@ -1610,9 +1613,6 @@ static int trivial_init(pa_resampler*r) { trivial_data = pa_xnew0(struct trivial, 1); - r->implementation.resample = trivial_resample; - r->implementation.update_rates = trivial_update_rates_or_reset; - r->implementation.reset = trivial_update_rates_or_reset; r->implementation.data = trivial_data; return 0; @@ -1735,15 +1735,12 @@ static int peaks_init(pa_resampler*r) { pa_assert(r->work_format == PA_SAMPLE_S16NE || r->work_format == PA_SAMPLE_FLOAT32NE); peaks_data = pa_xnew(struct peaks, 1); + r->implementation.data = peaks_data; + peaks_data->o_counter = peaks_data->i_counter = 0; memset(peaks_data->max_i, 0, sizeof(peaks_data->max_i)); memset(peaks_data->max_f, 0, sizeof(peaks_data->max_f)); - r->implementation.resample = peaks_resample; - r->implementation.update_rates = peaks_update_rates_or_reset; - r->implementation.reset = peaks_update_rates_or_reset; - r->implementation.data = peaks_data; - return 0; } @@ -1844,6 +1841,7 @@ static int ffmpeg_init(pa_resampler *r) { pa_assert(r); ffmpeg_data = pa_xnew(struct ffmpeg, 1); + r->implementation.data = (void *) ffmpeg_data; /* We could probably implement different quality levels by * adjusting the filter parameters here. However, ffmpeg @@ -1853,10 +1851,6 @@ static int ffmpeg_init(pa_resampler *r) { if (!(ffmpeg_data->state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8))) return -1; - r->implementation.free = ffmpeg_free; - r->implementation.resample = ffmpeg_resample; - r->implementation.data = (void *) ffmpeg_data; - for (c = 0; c < PA_ELEMENTSOF(ffmpeg_data->buf); c++) pa_memchunk_reset(&ffmpeg_data->buf[c]); diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index 7dbafa8..dbe7478 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -31,6 +31,7 @@ typedef struct pa_resampler pa_resampler; typedef struct pa_resampler_implementation pa_resampler_implementation; struct pa_resampler_implementation { + int (*init)(pa_resampler *r); void (*free)(pa_resampler *r); void (*update_rates)(pa_resampler *r); void (*resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples); -- 1.8.3.2