audio-resampler: combine functions

This commit is contained in:
Wim Taymans 2016-01-12 10:23:53 +01:00
parent d5d1ac6f56
commit 819c4c26c7
2 changed files with 28 additions and 66 deletions

View file

@ -26,7 +26,7 @@
#endif #endif
static inline void static inline void
inner_product_gdouble (gdouble * o, const gdouble * a, const gdouble * b, inner_product_gdouble_1 (gdouble * o, const gdouble * a, const gdouble * b,
gint len) gint len)
{ {
gint i = 0; gint i = 0;
@ -61,7 +61,7 @@ inner_product_gdouble (gdouble * o, const gdouble * a, const gdouble * b,
} }
static inline void static inline void
inner_product_gfloat (gfloat * o, const gfloat * a, const gfloat * b, gint len) inner_product_gfloat_1 (gfloat * o, const gfloat * a, const gfloat * b, gint len)
{ {
gint i = 0; gint i = 0;
gfloat res; gfloat res;
@ -90,7 +90,7 @@ inner_product_gfloat (gfloat * o, const gfloat * a, const gfloat * b, gint len)
} }
static inline void static inline void
inner_product_gint32 (gint32 * o, const gint32 * a, const gint32 * b, gint len) inner_product_gint32_1 (gint32 * o, const gint32 * a, const gint32 * b, gint len)
{ {
gint i = 0; gint i = 0;
gint64 res = 0; gint64 res = 0;
@ -103,7 +103,7 @@ inner_product_gint32 (gint32 * o, const gint32 * a, const gint32 * b, gint len)
} }
static inline void static inline void
inner_product_gint16 (gint16 * o, const gint16 * a, const gint16 * b, gint len) inner_product_gint16_1 (gint16 * o, const gint16 * a, const gint16 * b, gint len)
{ {
gint i = 0; gint i = 0;
gint32 res = 0; gint32 res = 0;

View file

@ -70,6 +70,7 @@ struct _GstAudioResampler
MirrorFunc mirror; MirrorFunc mirror;
ResampleFunc resample; ResampleFunc resample;
guint blocks;
gboolean filling; gboolean filling;
gint samp_inc; gint samp_inc;
gint samp_frac; gint samp_frac;
@ -374,19 +375,19 @@ make_taps (GstAudioResampler * resampler, Tap * t, gint j)
} }
} }
#define MAKE_RESAMPLE_FUNC(type) \ #define MAKE_RESAMPLE_FUNC(type,channels) \
static void \ static void \
resample_ ##type (GstAudioResampler * resampler, gpointer in[], gsize in_len, \ resample_ ##type## _ ##channels (GstAudioResampler * resampler, gpointer in[], gsize in_len, \
gpointer out[], gsize out_len, gsize * consumed, gboolean move) \ gpointer out[], gsize out_len, gsize * consumed, gboolean move) \
{ \ { \
gint c, di = 0; \ gint c, di = 0; \
gint n_taps = resampler->n_taps; \ gint n_taps = resampler->n_taps; \
gint channels = resampler->channels; \ gint blocks = resampler->blocks; \
gint ostride = resampler->ostride; \ gint ostride = resampler->ostride; \
gint samp_index = 0; \ gint samp_index = 0; \
gint samp_phase = 0; \ gint samp_phase = 0; \
\ \
for (c = 0; c < channels; c++) { \ for (c = 0; c < blocks; c++) { \
type *ip = in[c]; \ type *ip = in[c]; \
type *op = ostride == 1 ? out[c] : (type *)out[0] + c; \ type *op = ostride == 1 ? out[c] : (type *)out[0] + c; \
\ \
@ -395,19 +396,20 @@ resample_ ##type (GstAudioResampler * resampler, gpointer in[], gsize in_len,
\ \
for (di = 0; di < out_len; di++) { \ for (di = 0; di < out_len; di++) { \
Tap *t = &resampler->taps[samp_phase]; \ Tap *t = &resampler->taps[samp_phase]; \
type *ipp = &ip[samp_index]; \ type *ipp = &ip[samp_index * channels]; \
\ \
if (t->taps == NULL) \ if (t->taps == NULL) \
make_taps (resampler, t, samp_phase); \ make_taps (resampler, t, samp_phase); \
\ \
inner_product_ ##type (op, ipp, t->taps, n_taps); \ inner_product_ ##type## _##channels (op, ipp, t->taps, n_taps); \
op += ostride; \ op += ostride; \
\ \
samp_phase = t->next_phase; \ samp_phase = t->next_phase; \
samp_index += t->sample_inc; \ samp_index += t->sample_inc; \
} \ } \
if (move) \ if (move) \
memmove (ip, &ip[samp_index], (in_len - samp_index) * sizeof(type)); \ memmove (ip, &ip[samp_index * channels], \
(in_len - samp_index) * sizeof(type) * channels); \
} \ } \
*consumed = samp_index - resampler->samp_index; \ *consumed = samp_index - resampler->samp_index; \
\ \
@ -415,55 +417,12 @@ resample_ ##type (GstAudioResampler * resampler, gpointer in[], gsize in_len,
resampler->samp_phase = samp_phase; \ resampler->samp_phase = samp_phase; \
} }
MAKE_RESAMPLE_FUNC (gdouble); MAKE_RESAMPLE_FUNC (gdouble, 1);
MAKE_RESAMPLE_FUNC (gfloat); MAKE_RESAMPLE_FUNC (gfloat, 1);
MAKE_RESAMPLE_FUNC (gint32); MAKE_RESAMPLE_FUNC (gint32, 1);
MAKE_RESAMPLE_FUNC (gint16); MAKE_RESAMPLE_FUNC (gint16, 1);
MAKE_RESAMPLE_FUNC (gdouble, 2);
#define MAKE_RESAMPLE_INTERLEAVED_FUNC(type,channels) \ MAKE_RESAMPLE_FUNC (gint16, 2);
static void \
resample_interleaved_ ##type##_##channels (GstAudioResampler * resampler, gpointer in[],\
gsize in_len, gpointer out[], gsize out_len, gsize * consumed, gboolean move) \
{ \
gint di = 0; \
gint n_taps = resampler->n_taps; \
gint ostride = resampler->ostride; \
gint samp_index = 0; \
gint samp_phase = 0; \
\
{ \
type *ip = in[0]; \
type *op = out[0]; \
\
samp_index = resampler->samp_index; \
samp_phase = resampler->samp_phase; \
\
for (di = 0; di < out_len; di++) { \
Tap *t = &resampler->taps[samp_phase]; \
type *ipp = &ip[samp_index * channels]; \
\
if (t->taps == NULL) \
make_taps (resampler, t, samp_phase); \
\
inner_product_ ##type## _##channels (op, ipp, t->taps, n_taps); \
\
op += ostride; \
samp_phase = t->next_phase; \
samp_index += t->sample_inc; \
} \
if (move) \
memmove (ip, &ip[samp_index * channels], \
(in_len - samp_index) * sizeof(type) * channels); \
} \
*consumed = samp_index - resampler->samp_index; \
\
resampler->samp_index = move ? 0 : samp_index; \
resampler->samp_phase = samp_phase; \
}
MAKE_RESAMPLE_INTERLEAVED_FUNC (gdouble, 2);
MAKE_RESAMPLE_INTERLEAVED_FUNC (gint16, 2);
#define MAKE_DEINTERLEAVE_FUNC(type) \ #define MAKE_DEINTERLEAVE_FUNC(type) \
static void \ static void \
@ -644,33 +603,36 @@ resampler_calculate_taps (GstAudioResampler * resampler)
t->next_phase = (j + in_rate) % out_rate; t->next_phase = (j + in_rate) % out_rate;
} }
resampler->blocks = resampler->channels;
switch (resampler->format) { switch (resampler->format) {
case GST_AUDIO_FORMAT_F64: case GST_AUDIO_FORMAT_F64:
if (resampler->channels == 2 && n_taps >= 4) { if (resampler->channels == 2 && n_taps >= 4) {
resampler->resample = resample_interleaved_gdouble_2; resampler->resample = resample_gdouble_2;
resampler->deinterleave = deinterleave_copy; resampler->deinterleave = deinterleave_copy;
resampler->blocks = 1;
} else { } else {
resampler->resample = resample_gdouble; resampler->resample = resample_gdouble_1;
resampler->deinterleave = deinterleave_gdouble; resampler->deinterleave = deinterleave_gdouble;
} }
resampler->mirror = mirror_gdouble; resampler->mirror = mirror_gdouble;
break; break;
case GST_AUDIO_FORMAT_F32: case GST_AUDIO_FORMAT_F32:
resampler->resample = resample_gfloat; resampler->resample = resample_gfloat_1;
resampler->deinterleave = deinterleave_gfloat; resampler->deinterleave = deinterleave_gfloat;
resampler->mirror = mirror_gfloat; resampler->mirror = mirror_gfloat;
break; break;
case GST_AUDIO_FORMAT_S32: case GST_AUDIO_FORMAT_S32:
resampler->resample = resample_gint32; resampler->resample = resample_gint32_1;
resampler->deinterleave = deinterleave_gint32; resampler->deinterleave = deinterleave_gint32;
resampler->mirror = mirror_gint32; resampler->mirror = mirror_gint32;
break; break;
case GST_AUDIO_FORMAT_S16: case GST_AUDIO_FORMAT_S16:
if (resampler->channels == 2 && n_taps >= 4) { if (resampler->channels == 2 && n_taps >= 4) {
resampler->resample = resample_interleaved_gint16_2; resampler->resample = resample_gint16_2;
resampler->deinterleave = deinterleave_copy; resampler->deinterleave = deinterleave_copy;
resampler->blocks = 1;
} else { } else {
resampler->resample = resample_gint16; resampler->resample = resample_gint16_1;
resampler->deinterleave = deinterleave_gint16; resampler->deinterleave = deinterleave_gint16;
} }
resampler->mirror = mirror_gint16; resampler->mirror = mirror_gint16;