mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
4c52f4e625
audioresample is derived from GstBaseTransform, and one of GstBaseTransform's traits is that if the derived element does not produce an output buffer from some input buffer then the first output buffer after that gets flaged as a discontinuity, whether or not the buffer actually is discontinuous from the output buffer that preceded it. When downsampling, the audioresample element requires more than one input sample for each output sample, and if the ratio of input to output sample rates is high enough and the input buffers short enough it can come to pass that the resampler does not receive enough samples on its input to produce any output. Currently the resampler returns GST_BASE_TRANSFORM_FLOW_DROPPED from the transform() method in this case, causing the next buffer to be flagged as a discontinuity. If subsequent elements in the pipeline reset themselves on disconts, this can cause clicks and other undesireable behaviour. Fixes bug #665004. |
||
---|---|---|
.. | ||
arch.h | ||
fixed_arm4.h | ||
fixed_arm5e.h | ||
fixed_bfin.h | ||
fixed_debug.h | ||
fixed_generic.h | ||
gstaudioresample.c | ||
gstaudioresample.h | ||
Makefile.am | ||
README | ||
resample.c | ||
resample_sse.h | ||
speex_resampler.h | ||
speex_resampler_double.c | ||
speex_resampler_float.c | ||
speex_resampler_int.c | ||
speex_resampler_wrapper.h |
arch.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h fixed_generic.h resample.c speex_resampler.h are taken from http://git.xiph.org/speex.git/ as of 2009-11-10. The only changes are: diff -Naur old/arch.h new/arch.h --- old/arch.h 2009-11-10 12:18:29.000000000 +0100 +++ new/arch.h 2009-11-10 12:19:09.000000000 +0100 @@ -78,7 +78,10 @@ #include "../include/speex/speex_types.h" #endif +#ifndef ABS #define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#endif + #define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ #define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ #define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ @@ -134,6 +137,28 @@ #else +#ifdef DOUBLE_PRECISION +typedef double spx_mem_t; +typedef double spx_coef_t; +typedef double spx_lsp_t; +typedef double spx_sig_t; +typedef double spx_word16_t; +typedef double spx_word32_t; + +#define Q15ONE 1.0 +#define LPC_SCALING 1. +#define SIG_SCALING 1. +#define LSP_SCALING 1. +#define GAMMA_SCALING 1. +#define GAIN_SCALING 1. +#define GAIN_SCALING_1 1. + + +#define VERY_SMALL 1e-20 +#define VERY_LARGE32 1e20 +#define VERY_LARGE16 1e20 +#define Q15_ONE ((spx_word16_t)1.) +#else /* !DOUBLE_PRECISION */ typedef float spx_mem_t; typedef float spx_coef_t; typedef float spx_lsp_t; @@ -154,6 +179,7 @@ #define VERY_LARGE32 1e15f #define VERY_LARGE16 1e15f #define Q15_ONE ((spx_word16_t)1.f) +#endif /* DOUBLE_PRECISION */ #define QCONST16(x,bits) (x) #define QCONST32(x,bits) (x) diff -Naur old/resample.c new/resample.c --- old/resample.c 2009-11-10 12:18:51.000000000 +0100 +++ new/resample.c 2009-11-10 12:19:09.000000000 +0100 @@ -63,22 +63,27 @@ #ifdef OUTSIDE_SPEEX #include <stdlib.h> -static void * + +#include <glib.h> + +#define EXPORT G_GNUC_INTERNAL + +static inline void * speex_alloc (int size) { - return calloc (size, 1); + return g_malloc0 (size); } -static void * +static inline void * speex_realloc (void *ptr, int size) { - return realloc (ptr, size); + return g_realloc (ptr, size); } -static void +static inline void speex_free (void *ptr) { - free (ptr); + g_free (ptr); } #include "speex_resampler.h" @@ -90,7 +95,6 @@ #include "os_support.h" #endif /* OUTSIDE_SPEEX */ -#include "stack_alloc.h" #include <math.h> #ifndef M_PI @@ -263,10 +267,17 @@ }; /*8,24,40,56,80,104,128,160,200,256,320*/ +#ifdef DOUBLE_PRECISION +static double +compute_func (double x, struct FuncDef *func) +{ + double y, frac; +#else static double compute_func (float x, struct FuncDef *func) { float y, frac; +#endif double interp[4]; int ind; y = x * func->oversample; @@ -317,11 +328,19 @@ } #else /* The slow way of computing a sinc for the table. Should improve that some day */ +#ifdef DOUBLE_PRECISION +static spx_word16_t +sinc (double cutoff, double x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x); */ + double xx = x * cutoff; +#else static spx_word16_t sinc (float cutoff, float x, int N, struct FuncDef *window_func) { /*fprintf (stderr, "%f ", x); */ float xx = x * cutoff; +#endif if (fabs (x) < 1e-6) return cutoff; else if (fabs (x) > .5 * N) @@ -372,6 +391,7 @@ } #endif +#ifndef DOUBLE_PRECISION static int resampler_basic_direct_single (SpeexResamplerState * st, spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len, @@ -428,6 +448,7 @@ st->samp_frac_num[channel_index] = samp_frac_num; return out_sample; } +#endif #ifdef FIXED_POINT #else @@ -483,6 +504,7 @@ } #endif +#ifndef DOUBLE_PRECISION static int resampler_basic_interpolate_single (SpeexResamplerState * st, spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len, @@ -562,6 +584,7 @@ st->samp_frac_num[channel_index] = samp_frac_num; return out_sample; } +#endif #ifdef FIXED_POINT #else @@ -592,10 +615,16 @@ PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15), st->den_rate); #else +#ifdef DOUBLE_PRECISION + const spx_word16_t frac = + ((double) ((samp_frac_num * st->oversample) % st->den_rate)) / + st->den_rate; +#else const spx_word16_t frac = ((float) ((samp_frac_num * st->oversample) % st->den_rate)) / st->den_rate; #endif +#endif spx_word16_t interp[4]; @@ -696,20 +725,27 @@ spx_int32_t j; for (j = 0; j < st->filt_len; j++) { st->sinc_table[i * st->filt_len + j] = - sinc (st->cutoff, - ((j - (spx_int32_t) st->filt_len / 2 + 1) - + sinc (st->cutoff, ((j - (spx_int32_t) st->filt_len / 2 + 1) - +#ifdef DOUBLE_PRECISION + ((double) i) / st->den_rate), st->filt_len, +#else ((float) i) / st->den_rate), st->filt_len, +#endif quality_map[st->quality].window_func); } } #ifdef FIXED_POINT st->resampler_ptr = resampler_basic_direct_single; #else +#ifdef DOUBLE_PRECISION + st->resampler_ptr = resampler_basic_direct_double; +#else if (st->quality > 8) st->resampler_ptr = resampler_basic_direct_double; else st->resampler_ptr = resampler_basic_direct_single; #endif +#endif /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff); */ } else { spx_int32_t i; @@ -725,16 +761,24 @@ } for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++) st->sinc_table[i + 4] = +#ifdef DOUBLE_PRECISION + sinc (st->cutoff, (i / (double) st->oversample - st->filt_len / 2), +#else sinc (st->cutoff, (i / (float) st->oversample - st->filt_len / 2), +#endif st->filt_len, quality_map[st->quality].window_func); #ifdef FIXED_POINT st->resampler_ptr = resampler_basic_interpolate_single; #else +#ifdef DOUBLE_PRECISION + st->resampler_ptr = resampler_basic_interpolate_double; +#else if (st->quality > 8) st->resampler_ptr = resampler_basic_interpolate_double; else st->resampler_ptr = resampler_basic_interpolate_single; #endif +#endif /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff); */ } st->int_advance = st->num_rate / st->den_rate; @@ -964,11 +1008,18 @@ spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len, spx_int16_t * out, spx_uint32_t * out_len) #else +#ifdef DOUBLE_PRECISION +EXPORT int +speex_resampler_process_float (SpeexResamplerState * st, + spx_uint32_t channel_index, const double *in, spx_uint32_t * in_len, + double *out, spx_uint32_t * out_len) +#else EXPORT int speex_resampler_process_float (SpeexResamplerState * st, spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len, float *out, spx_uint32_t * out_len) #endif +#endif { int j; spx_uint32_t ilen = *in_len; @@ -1086,9 +1137,16 @@ return RESAMPLER_ERR_SUCCESS; } +#ifdef DOUBLE_PRECISION +EXPORT int +speex_resampler_process_interleaved_float (SpeexResamplerState * st, + const double *in, spx_uint32_t * in_len, double *out, + spx_uint32_t * out_len) +#else EXPORT int speex_resampler_process_interleaved_float (SpeexResamplerState * st, const float *in, spx_uint32_t * in_len, float *out, spx_uint32_t * out_len) +#endif { spx_uint32_t i; int istride_save, ostride_save; diff -Naur old/speex_resampler.h new/speex_resampler.h --- old/speex_resampler.h 2009-11-10 12:18:09.000000000 +0100 +++ new/speex_resampler.h 2009-11-10 12:19:09.000000000 +0100 @@ -77,10 +77,10 @@ #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) -#define spx_int16_t short -#define spx_int32_t int -#define spx_uint16_t unsigned short -#define spx_uint32_t unsigned int +#define spx_int16_t gint16 +#define spx_int32_t gint32 +#define spx_uint16_t guint16 +#define spx_uint32_t guint32 #else /* OUTSIDE_SPEEX */ @@ -166,12 +166,21 @@ * @param out Output buffer * @param out_len Size of the output buffer. Returns the number of samples written */ +#ifdef DOUBLE_PRECISION +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const double *in, + spx_uint32_t *in_len, + double *out, + spx_uint32_t *out_len); +#else int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len); +#endif /** Resample an int array. The input and output buffers must *not* overlap. * @param st Resampler state @@ -199,11 +208,19 @@ * @param out_len Size of the output buffer. Returns the number of samples written. * This is all per-channel. */ +#ifdef DOUBLE_PRECISION +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const double *in, + spx_uint32_t *in_len, + double *out, + spx_uint32_t *out_len); +#else int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len); +#endif /** Resample an interleaved int array. The input and output buffers must *not* overlap. * @param st Resampler state