121e2a710a5831c60830709352436f21424d094a
[platform/upstream/gst-plugins-base.git] / gst-libs / gst / audio / audio-resampler.c
1 /* GStreamer
2  * Copyright (C) <2015> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <string.h>
25 #include <stdio.h>
26 #include <math.h>
27
28 #ifdef HAVE_ORC
29 #include <orc/orc.h>
30 #endif
31
32 #include "audio-resampler.h"
33
34 typedef struct _Tap
35 {
36   gpointer taps;
37
38   gint sample_inc;
39   gint next_phase;
40   gint size;
41 } Tap;
42
43 typedef void (*MakeTapsFunc) (GstAudioResampler * resampler, Tap * t, gint j);
44 typedef void (*ResampleFunc) (GstAudioResampler * resampler, gpointer in[],
45     gsize in_len, gpointer out[], gsize out_len, gsize * consumed);
46 typedef void (*DeinterleaveFunc) (GstAudioResampler * resampler,
47     gpointer * sbuf, gpointer in[], gsize in_frames);
48
49 #define MEM_ALIGN(m,a) ((gint8 *)((guintptr)((gint8 *)(m) + ((a)-1)) & ~((a)-1)))
50 #define ALIGN 16
51 #define TAPS_OVERREAD 16
52
53 struct _GstAudioResampler
54 {
55   GstAudioResamplerMethod method;
56   GstAudioResamplerFlags flags;
57   GstAudioFormat format;
58   GstStructure *options;
59   gint channels;
60   gint in_rate;
61   gint out_rate;
62   gint bps;
63   gint ostride;
64
65   gdouble cutoff;
66   gdouble kaiser_beta;
67   /* for cubic */
68   gdouble b, c;
69
70   guint n_taps;
71   Tap *taps;
72   gpointer coeff;
73   gpointer coeffmem;
74   gsize cstride;
75   gpointer tmpcoeff;
76
77   DeinterleaveFunc deinterleave;
78   ResampleFunc resample;
79
80   guint blocks;
81   guint inc;
82   gint samp_inc;
83   gint samp_frac;
84   gint samp_index;
85   gint samp_phase;
86   gint skip;
87
88   gpointer samples;
89   gsize samples_len;
90   gsize samples_avail;
91   gpointer *sbuf;
92 };
93
94 GST_DEBUG_CATEGORY_STATIC (audio_resampler_debug);
95 #define GST_CAT_DEFAULT audio_resampler_debug
96
97 /**
98  * SECTION:gstaudioresampler
99  * @short_description: Utility structure for resampler information
100  *
101  * #GstAudioResampler is a structure which holds the information
102  * required to perform various kinds of resampling filtering.
103  *
104  */
105
106 typedef struct
107 {
108   gdouble cutoff;
109   gdouble downsample_cutoff_factor;
110   gdouble stopband_attenuation;
111   gdouble transition_bandwidth;
112 } KaiserQualityMap;
113
114 static const KaiserQualityMap kaiser_qualities[] = {
115   {0.860, 0.96511, 60, 0.7},    /* 8 taps */
116   {0.880, 0.96591, 65, 0.29},   /* 16 taps */
117   {0.910, 0.96923, 70, 0.145},  /* 32 taps */
118   {0.920, 0.97600, 80, 0.105},  /* 48 taps */
119   {0.940, 0.97979, 85, 0.087},  /* 64 taps default quality */
120   {0.940, 0.98085, 95, 0.077},  /* 80 taps */
121   {0.945, 0.99471, 100, 0.068}, /* 96 taps */
122   {0.950, 1.0, 105, 0.055},     /* 128 taps */
123   {0.960, 1.0, 110, 0.045},     /* 160 taps */
124   {0.968, 1.0, 115, 0.039},     /* 192 taps */
125   {0.975, 1.0, 120, 0.0305}     /* 256 taps */
126 };
127
128 typedef struct
129 {
130   guint n_taps;
131   gdouble cutoff;
132 } BlackmanQualityMap;
133
134 static const BlackmanQualityMap blackman_qualities[] = {
135   {8, 0.5,},
136   {16, 0.6,},
137   {24, 0.72,},
138   {32, 0.8,},
139   {48, 0.85,},                  /* default */
140   {64, 0.90,},
141   {80, 0.92,},
142   {96, 0.933,},
143   {128, 0.950,},
144   {148, 0.955,},
145   {160, 0.960,}
146 };
147
148 #define DEFAULT_QUALITY GST_AUDIO_RESAMPLER_QUALITY_DEFAULT
149 #define DEFAULT_OPT_CUBIC_B 1.0
150 #define DEFAULT_OPT_CUBIC_C 0.0
151
152 static gdouble
153 get_opt_double (GstStructure * options, const gchar * name, gdouble def)
154 {
155   gdouble res;
156   if (!options || !gst_structure_get_double (options, name, &res))
157     res = def;
158   return res;
159 }
160
161 static gint
162 get_opt_int (GstStructure * options, const gchar * name, gint def)
163 {
164   gint res;
165   if (!options || !gst_structure_get_int (options, name, &res))
166     res = def;
167   return res;
168 }
169
170 #define GET_OPT_CUTOFF(options,def) get_opt_double(options, \
171     GST_AUDIO_RESAMPLER_OPT_CUTOFF,def)
172 #define GET_OPT_DOWN_CUTOFF_FACTOR(options,def) get_opt_double(options, \
173     GST_AUDIO_RESAMPLER_OPT_DOWN_CUTOFF_FACTOR, def)
174 #define GET_OPT_STOP_ATTENUATION(options,def) get_opt_double(options, \
175     GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUATION, def)
176 #define GET_OPT_TRANSITION_BANDWIDTH(options,def) get_opt_double(options, \
177     GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH, def)
178 #define GET_OPT_CUBIC_B(options) get_opt_double(options, \
179     GST_AUDIO_RESAMPLER_OPT_CUBIC_B, DEFAULT_OPT_CUBIC_B)
180 #define GET_OPT_CUBIC_C(options) get_opt_double(options, \
181     GST_AUDIO_RESAMPLER_OPT_CUBIC_C, DEFAULT_OPT_CUBIC_C)
182 #define GET_OPT_N_TAPS(options,def) get_opt_int(options, \
183     GST_AUDIO_RESAMPLER_OPT_N_TAPS, def)
184
185 #include "dbesi0.c"
186 #define bessel dbesi0
187
188 static inline gdouble
189 get_nearest_tap (GstAudioResampler * resampler, gdouble x)
190 {
191   gdouble a = fabs (x);
192
193   if (a < 0.5)
194     return 1.0;
195   else
196     return 0.0;
197 }
198
199 static inline gdouble
200 get_linear_tap (GstAudioResampler * resampler, gdouble x)
201 {
202   gdouble a;
203
204   a = fabs (x) / resampler->n_taps;
205
206   if (a < 1.0)
207     return 1.0 - a;
208   else
209     return 0.0;
210 }
211
212 static inline gdouble
213 get_cubic_tap (GstAudioResampler * resampler, gdouble x)
214 {
215   gdouble a, a2, a3, b, c;
216
217   a = fabs (x * 4.0) / resampler->n_taps;
218   a2 = a * a;
219   a3 = a2 * a;
220
221   b = resampler->b;
222   c = resampler->c;
223
224   if (a <= 1.0)
225     return ((12.0 - 9.0 * b - 6.0 * c) * a3 +
226         (-18.0 + 12.0 * b + 6.0 * c) * a2 + (6.0 - 2.0 * b)) / 6.0;
227   else if (a <= 2.0)
228     return ((-b - 6.0 * c) * a3 +
229         (6.0 * b + 30.0 * c) * a2 +
230         (-12.0 * b - 48.0 * c) * a + (8.0 * b + 24.0 * c)) / 6.0;
231   else
232     return 0.0;
233 }
234
235 static inline gdouble
236 get_blackman_nuttall_tap (GstAudioResampler * resampler, gdouble x)
237 {
238   gdouble s, y, w, Fc = resampler->cutoff;
239
240   y = G_PI * x;
241   s = (y == 0.0 ? Fc : sin (y * Fc) / y);
242
243   w = 2.0 * y / resampler->n_taps + G_PI;
244   return s * (0.3635819 - 0.4891775 * cos (w) + 0.1365995 * cos (2 * w) -
245       0.0106411 * cos (3 * w));
246 }
247
248 static inline gdouble
249 get_kaiser_tap (GstAudioResampler * resampler, gdouble x)
250 {
251   gdouble s, y, w, Fc = resampler->cutoff;
252
253   y = G_PI * x;
254   s = (y == 0.0 ? Fc : sin (y * Fc) / y);
255
256   w = 2.0 * x / resampler->n_taps;
257   return s * bessel (resampler->kaiser_beta * sqrt (MAX (1 - w * w, 0)));
258 }
259
260 #define CONVERT_TAPS(type, precision)                                   \
261 G_STMT_START {                                                          \
262   type *taps = res = (type *) ((gint8*)resampler->coeff + j * resampler->cstride);        \
263   gdouble multiplier = (1 << precision);                                \
264   gint i, j;                                                            \
265   gdouble offset, l_offset, h_offset;                                   \
266   gboolean exact = FALSE;                                               \
267   /* Round to integer, but with an adjustable bias that we use to */    \
268   /* eliminate the DC error. */                                         \
269   l_offset = 0.0;                                                       \
270   h_offset = 1.0;                                                       \
271   offset = 0.5;                                                         \
272   for (i = 0; i < 32; i++) {                                            \
273     gint64 sum = 0;                                                     \
274     for (j = 0; j < n_taps; j++)                                        \
275       sum += taps[j] = floor (offset + tmpcoeff[j] * multiplier / weight); \
276     if (sum == (1 << precision)) {                                      \
277       exact = TRUE;                                                     \
278       break;                                                            \
279     }                                                                   \
280     if (l_offset == h_offset)                                           \
281       break;                                                            \
282     if (sum < (1 << precision)) {                                       \
283       if (offset > l_offset)                                            \
284         l_offset = offset;                                              \
285       offset += (h_offset - l_offset) / 2;                              \
286     } else {                                                            \
287       if (offset < h_offset)                                            \
288         h_offset = offset;                                              \
289       offset -= (h_offset - l_offset) / 2;                              \
290     }                                                                   \
291   }                                                                     \
292   if (!exact)                                                           \
293     GST_WARNING ("can't find exact taps");                              \
294 } G_STMT_END
295
296 #define PRECISION_S16 15
297 #define PRECISION_S32 30
298
299 static gpointer
300 make_taps (GstAudioResampler * resampler, Tap * t, gint j)
301 {
302   gpointer res;
303   gint n_taps = resampler->n_taps;
304   gdouble x, weight = 0.0;
305   gdouble *tmpcoeff = resampler->tmpcoeff;
306   gint tap_offs = n_taps / 2;
307   gint in_rate = resampler->in_rate;
308   gint out_rate = resampler->out_rate;
309   gint l;
310
311   x = ((double) (1.0 - tap_offs) - (double) j / out_rate);
312
313   switch (resampler->method) {
314     case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
315       for (l = 0; l < n_taps; l++, x += 1.0)
316         weight += tmpcoeff[l] = get_nearest_tap (resampler, x);
317       break;
318
319     case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
320       for (l = 0; l < n_taps; l++, x += 1.0)
321         weight += tmpcoeff[l] = get_linear_tap (resampler, x);
322       break;
323
324     case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
325       for (l = 0; l < n_taps; l++, x += 1.0)
326         weight += tmpcoeff[l] = get_cubic_tap (resampler, x);
327       break;
328
329     case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
330       for (l = 0; l < n_taps; l++, x += 1.0)
331         weight += tmpcoeff[l] = get_blackman_nuttall_tap (resampler, x);
332       break;
333
334     case GST_AUDIO_RESAMPLER_METHOD_KAISER:
335       for (l = 0; l < n_taps; l++, x += 1.0)
336         weight += tmpcoeff[l] = get_kaiser_tap (resampler, x);
337       break;
338
339     default:
340       break;
341   }
342
343   switch (resampler->format) {
344     case GST_AUDIO_FORMAT_F64:
345     {
346       gdouble *taps = res =
347           (gdouble *) ((gint8 *) resampler->coeff + j * resampler->cstride);
348       for (l = 0; l < n_taps; l++)
349         taps[l] = tmpcoeff[l] / weight;
350       break;
351     }
352     case GST_AUDIO_FORMAT_F32:
353     {
354       gfloat *taps = res =
355           (gfloat *) ((gint8 *) resampler->coeff + j * resampler->cstride);
356       for (l = 0; l < n_taps; l++)
357         taps[l] = tmpcoeff[l] / weight;
358       break;
359     }
360     case GST_AUDIO_FORMAT_S32:
361       CONVERT_TAPS (gint32, PRECISION_S32);
362       break;
363     case GST_AUDIO_FORMAT_S16:
364       CONVERT_TAPS (gint16, PRECISION_S16);
365       break;
366     default:
367       g_assert_not_reached ();
368       break;
369   }
370   if (t) {
371     t->taps = res;
372     t->sample_inc = (j + in_rate) / out_rate;
373     t->next_phase = (j + in_rate) % out_rate;
374   }
375   return res;
376 }
377
378 static inline void
379 inner_product_gint16_1_c (gint16 * o, const gint16 * a, const gint16 * b,
380     gint len)
381 {
382   gint i;
383   gint32 res = 0;
384
385   for (i = 0; i < len; i++)
386     res += (gint32) a[i] * (gint32) b[i];
387
388   res = (res + (1 << (PRECISION_S16 - 1))) >> PRECISION_S16;
389   *o = CLAMP (res, -(1L << 15), (1L << 15) - 1);
390 }
391
392 static inline void
393 inner_product_gint32_1_c (gint32 * o, const gint32 * a, const gint32 * b,
394     gint len)
395 {
396   gint i;
397   gint64 res = 0;
398
399   for (i = 0; i < len; i++)
400     res += (gint64) a[i] * (gint64) b[i];
401
402   res = (res + (1 << (PRECISION_S32 - 1))) >> PRECISION_S32;
403   *o = CLAMP (res, -(1L << 31), (1L << 31) - 1);
404 }
405
406 static inline void
407 inner_product_gfloat_1_c (gfloat * o, const gfloat * a, const gfloat * b,
408     gint len)
409 {
410   gint i;
411   gfloat res = 0.0;
412
413   for (i = 0; i < len; i++)
414     res += a[i] * b[i];
415
416   *o = res;
417 }
418
419 static inline void
420 inner_product_gdouble_1_c (gdouble * o, const gdouble * a, const gdouble * b,
421     gint len)
422 {
423   gint i;
424   gdouble res = 0.0;
425
426   for (i = 0; i < len; i++)
427     res += a[i] * b[i];
428
429   *o = res;
430 }
431
432 #define MAKE_RESAMPLE_FUNC(type,channels,arch)                                  \
433 static void                                                                     \
434 resample_ ##type## _ ##channels## _ ##arch (GstAudioResampler * resampler,      \
435     gpointer in[], gsize in_len,  gpointer out[], gsize out_len,                \
436     gsize * consumed)                                                           \
437 {                                                                               \
438   gint c, di = 0;                                                               \
439   gint n_taps = resampler->n_taps;                                              \
440   gint blocks = resampler->blocks;                                              \
441   gint ostride = resampler->ostride;                                            \
442   gint samp_index = 0;                                                          \
443   gint samp_phase = 0;                                                          \
444                                                                                 \
445   for (c = 0; c < blocks; c++) {                                                \
446     type *ip = in[c];                                                           \
447     type *op = ostride == 1 ? out[c] : (type *)out[0] + c;                      \
448                                                                                 \
449     samp_index = resampler->samp_index;                                         \
450     samp_phase = resampler->samp_phase;                                         \
451                                                                                 \
452     for (di = 0; di < out_len; di++) {                                          \
453       Tap *t = &resampler->taps[samp_phase];                                    \
454       type *ipp = &ip[samp_index * channels];                                   \
455       gpointer taps;                                                            \
456                                                                                 \
457       if (G_UNLIKELY ((taps = t->taps) == NULL))                                \
458         taps = make_taps (resampler, t, samp_phase);                            \
459                                                                                 \
460       inner_product_ ##type## _##channels##_##arch (op, ipp, taps, n_taps);     \
461       op += ostride;                                                            \
462                                                                                 \
463       samp_phase = t->next_phase;                                               \
464       samp_index += t->sample_inc;                                              \
465     }                                                                           \
466     memmove (ip, &ip[samp_index * channels],                                    \
467         (in_len - samp_index) * sizeof(type) * channels);                       \
468   }                                                                             \
469   *consumed = samp_index - resampler->samp_index;                               \
470                                                                                 \
471   resampler->samp_index = 0;                                                    \
472   resampler->samp_phase = samp_phase;                                           \
473 }
474
475 MAKE_RESAMPLE_FUNC (gint16, 1, c);
476 MAKE_RESAMPLE_FUNC (gint32, 1, c);
477 MAKE_RESAMPLE_FUNC (gfloat, 1, c);
478 MAKE_RESAMPLE_FUNC (gdouble, 1, c);
479
480 static ResampleFunc resample_funcs[] = {
481   resample_gint16_1_c,
482   resample_gint32_1_c,
483   resample_gfloat_1_c,
484   resample_gdouble_1_c,
485   NULL,
486   NULL,
487   NULL,
488   NULL,
489 };
490
491 #define resample_gint16_1 resample_funcs[0]
492 #define resample_gint32_1 resample_funcs[1]
493 #define resample_gfloat_1 resample_funcs[2]
494 #define resample_gdouble_1 resample_funcs[3]
495 #define resample_gint16_2 resample_funcs[4]
496 #define resample_gint32_2 resample_funcs[5]
497 #define resample_gfloat_2 resample_funcs[6]
498 #define resample_gdouble_2 resample_funcs[7]
499
500 #if defined HAVE_ORC && !defined DISABLE_ORC
501 # if defined (__i386__) || defined (__x86_64__)
502 #  define CHECK_X86
503 #  include "audio-resampler-x86.h"
504 # endif
505 #endif
506
507 static void
508 audio_resampler_init (void)
509 {
510   static gsize init_gonce = 0;
511
512   if (g_once_init_enter (&init_gonce)) {
513
514     GST_DEBUG_CATEGORY_INIT (audio_resampler_debug, "audio-resampler", 0,
515         "audio-resampler object");
516
517 #if defined HAVE_ORC && !defined DISABLE_ORC
518     orc_init ();
519     {
520       OrcTarget *target = orc_target_get_default ();
521       gint i;
522
523       if (target) {
524         unsigned int flags = orc_target_get_default_flags (target);
525         const gchar *name;
526
527         name = orc_target_get_name (target);
528         GST_DEBUG ("target %s, default flags %08x", name, flags);
529
530         for (i = 0; i < 32; ++i) {
531           if (flags & (1U << i)) {
532             name = orc_target_get_flag_name (target, i);
533             GST_DEBUG ("target flag %s", name);
534 #ifdef CHECK_X86
535             audio_resampler_check_x86 (name);
536 #endif
537           }
538         }
539       }
540     }
541 #endif
542     g_once_init_leave (&init_gonce, 1);
543   }
544 }
545
546 #define MAKE_DEINTERLEAVE_FUNC(type)                                    \
547 static void                                                             \
548 deinterleave_ ##type (GstAudioResampler * resampler, gpointer sbuf[],   \
549     gpointer in[], gsize in_frames)                                     \
550 {                                                                       \
551   guint i, c, channels = resampler->channels;                           \
552   gsize samples_avail = resampler->samples_avail;                       \
553   for (c = 0; c < channels; c++) {                                      \
554     type *s = (type *) sbuf[c] + samples_avail;                         \
555     if (G_UNLIKELY (in == NULL)) {                                      \
556       for (i = 0; i < in_frames; i++)                                   \
557         s[i] = 0;                                                       \
558     } else {                                                            \
559       type *ip = (type *) in[0] + c;                                    \
560       for (i = 0; i < in_frames; i++, ip += channels)                   \
561         s[i] = *ip;                                                     \
562     }                                                                   \
563   }                                                                     \
564 }
565
566 MAKE_DEINTERLEAVE_FUNC (gdouble);
567 MAKE_DEINTERLEAVE_FUNC (gfloat);
568 MAKE_DEINTERLEAVE_FUNC (gint32);
569 MAKE_DEINTERLEAVE_FUNC (gint16);
570
571 static void
572 deinterleave_copy (GstAudioResampler * resampler, gpointer sbuf[],
573     gpointer in[], gsize in_frames)
574 {
575   guint c, blocks = resampler->blocks;
576   gsize bytes_avail, in_bytes, bpf;
577
578   bpf = resampler->bps * resampler->inc;
579   bytes_avail = resampler->samples_avail * bpf;
580   in_bytes = in_frames * bpf;
581
582   for (c = 0; c < blocks; c++) {
583     if (G_UNLIKELY (in == NULL))
584       memset ((guint8 *) sbuf[c] + bytes_avail, 0, in_bytes);
585     else
586       memcpy ((guint8 *) sbuf[c] + bytes_avail, in[c], in_bytes);
587   }
588 }
589
590 static void
591 calculate_kaiser_params (GstAudioResampler * resampler)
592 {
593   gdouble A, B, dw, tr_bw, Fc;
594   gint n;
595   const KaiserQualityMap *q = &kaiser_qualities[DEFAULT_QUALITY];
596
597   /* default cutoff */
598   Fc = q->cutoff;
599   if (resampler->out_rate < resampler->in_rate)
600     Fc *= q->downsample_cutoff_factor;
601
602   Fc = GET_OPT_CUTOFF (resampler->options, Fc);
603   A = GET_OPT_STOP_ATTENUATION (resampler->options, q->stopband_attenuation);
604   tr_bw =
605       GET_OPT_TRANSITION_BANDWIDTH (resampler->options,
606       q->transition_bandwidth);
607
608   GST_LOG ("Fc %f, A %f, tr_bw %f", Fc, A, tr_bw);
609
610   /* calculate Beta */
611   if (A > 50)
612     B = 0.1102 * (A - 8.7);
613   else if (A >= 21)
614     B = 0.5842 * pow (A - 21, 0.4) + 0.07886 * (A - 21);
615   else
616     B = 0.0;
617   /* calculate transition width in radians */
618   dw = 2 * G_PI * (tr_bw);
619   /* order of the filter */
620   n = (A - 8.0) / (2.285 * dw);
621
622   resampler->kaiser_beta = B;
623   resampler->n_taps = n + 1;
624   resampler->cutoff = Fc;
625
626   GST_LOG ("using Beta %f n_taps %d cutoff %f", resampler->kaiser_beta,
627       resampler->n_taps, resampler->cutoff);
628 }
629
630 static void
631 resampler_calculate_taps (GstAudioResampler * resampler)
632 {
633   gint bps;
634   gint j;
635   gint n_taps;
636   gint out_rate;
637   gint in_rate;
638   gboolean non_interleaved;
639   DeinterleaveFunc deinterleave;
640   ResampleFunc resample, resample_2;
641
642   switch (resampler->method) {
643     case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
644       resampler->n_taps = 2;
645       break;
646     case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
647       resampler->n_taps = GET_OPT_N_TAPS (resampler->options, 2);
648       break;
649     case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
650       resampler->n_taps = GET_OPT_N_TAPS (resampler->options, 4);
651       resampler->b = GET_OPT_CUBIC_B (resampler->options);
652       resampler->c = GET_OPT_CUBIC_C (resampler->options);;
653       break;
654     case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
655     {
656       const BlackmanQualityMap *q = &blackman_qualities[DEFAULT_QUALITY];
657       resampler->n_taps = GET_OPT_N_TAPS (resampler->options, q->n_taps);
658       resampler->cutoff = GET_OPT_CUTOFF (resampler->options, q->cutoff);
659       break;
660     }
661     case GST_AUDIO_RESAMPLER_METHOD_KAISER:
662       calculate_kaiser_params (resampler);
663       break;
664   }
665
666   in_rate = resampler->in_rate;
667   out_rate = resampler->out_rate;
668
669   if (out_rate < in_rate) {
670     resampler->cutoff = resampler->cutoff * out_rate / in_rate;
671     resampler->n_taps =
672         gst_util_uint64_scale_int (resampler->n_taps, in_rate, out_rate);
673   }
674   /* only round up for bigger taps, the small taps are used for nearest,
675    * linear and cubic and we want to use less taps for those. */
676   if (resampler->n_taps > 4)
677     resampler->n_taps = GST_ROUND_UP_8 (resampler->n_taps);
678
679   n_taps = resampler->n_taps;
680   bps = resampler->bps;
681
682   GST_LOG ("using n_taps %d cutoff %f", n_taps, resampler->cutoff);
683
684   resampler->taps = g_realloc_n (resampler->taps, out_rate, sizeof (Tap));
685
686   resampler->cstride = GST_ROUND_UP_32 (bps * (n_taps + TAPS_OVERREAD));
687   g_free (resampler->coeffmem);
688   resampler->coeffmem = g_malloc0 (out_rate * resampler->cstride + ALIGN - 1);
689   resampler->coeff = MEM_ALIGN (resampler->coeffmem, ALIGN);
690
691   resampler->tmpcoeff =
692       g_realloc_n (resampler->tmpcoeff, n_taps, sizeof (gdouble));
693
694   resampler->samp_inc = in_rate / out_rate;
695   resampler->samp_frac = in_rate % out_rate;
696
697   for (j = 0; j < out_rate; j++) {
698     Tap *t = &resampler->taps[j];
699     t->taps = NULL;
700   }
701
702   non_interleaved =
703       (resampler->flags & GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED);
704
705   resampler->ostride = non_interleaved ? 1 : resampler->channels;
706
707   /* we resample each channel separately */
708   resampler->blocks = resampler->channels;
709   resampler->inc = 1;
710
711   switch (resampler->format) {
712     case GST_AUDIO_FORMAT_S16:
713       resample = resample_gint16_1;
714       resample_2 = resample_gint16_2;
715       deinterleave = deinterleave_gint16;
716       break;
717     case GST_AUDIO_FORMAT_S32:
718       resample = resample_gint32_1;
719       resample_2 = resample_gint32_2;
720       deinterleave = deinterleave_gint32;
721       break;
722     case GST_AUDIO_FORMAT_F32:
723       resample = resample_gfloat_1;
724       resample_2 = resample_gfloat_2;
725       deinterleave = deinterleave_gfloat;
726       break;
727     case GST_AUDIO_FORMAT_F64:
728       resample = resample_gdouble_1;
729       resample_2 = resample_gdouble_2;
730       deinterleave = deinterleave_gdouble;
731       break;
732     default:
733       g_assert_not_reached ();
734       break;
735   }
736   if (!non_interleaved && resampler->channels == 2 && n_taps >= 4 && resample_2) {
737     resampler->resample = resample_2;
738     resampler->deinterleave = deinterleave_copy;
739     resampler->blocks = 1;
740     resampler->inc = resampler->channels;;
741   } else {
742     resampler->resample = resample;
743     resampler->deinterleave = deinterleave;
744   }
745 }
746
747 #define PRINT_TAPS(type,print)                  \
748 G_STMT_START {                                  \
749   type sum = 0.0, *taps;                        \
750                                                 \
751   if ((taps = t->taps) == NULL)                 \
752     taps = make_taps (resampler, t, i);         \
753                                                 \
754   for (j = 0; j < n_taps; j++) {                \
755     type tap = taps[j];                         \
756     fprintf (stderr, "\t%" print " ", tap);     \
757     sum += tap;                                 \
758   }                                             \
759   fprintf (stderr, "\t: sum %" print "\n", sum);\
760 } G_STMT_END
761
762 static void
763 resampler_dump (GstAudioResampler * resampler)
764 {
765 #if 0
766   gint i, n_taps, out_rate;
767   gint64 a;
768
769   out_rate = resampler->out_rate;
770   n_taps = resampler->n_taps;
771
772   fprintf (stderr, "out size %d, max taps %d\n", out_rate, n_taps);
773
774   a = g_get_monotonic_time ();
775
776   for (i = 0; i < out_rate; i++) {
777     gint j;
778     Tap *t = &resampler->taps[i];
779
780     fprintf (stderr, "%u: %d %d\t ", i, t->sample_inc, t->next_phase);
781     switch (resampler->format) {
782       case GST_AUDIO_FORMAT_F64:
783         PRINT_TAPS (gdouble, "f");
784         break;
785       case GST_AUDIO_FORMAT_F32:
786         PRINT_TAPS (gfloat, "f");
787         break;
788       case GST_AUDIO_FORMAT_S32:
789         PRINT_TAPS (gint32, "d");
790         break;
791       case GST_AUDIO_FORMAT_S16:
792         PRINT_TAPS (gint16, "d");
793         break;
794       default:
795         break;
796     }
797   }
798   fprintf (stderr, "time %" G_GUINT64_FORMAT "\n", g_get_monotonic_time () - a);
799 #endif
800 }
801
802 /**
803  * gst_audio_resampler_options_set_quality:
804  * @method: a #GstAudioResamplerMethod
805  * @quality: the quality
806  * @in_rate: the input rate
807  * @out_rate: the output rate
808  * @options: a #GstStructure
809  *
810  * Set the parameters for resampling from @in_rate to @out_rate using @method
811  * for @quality in @options.
812  */
813 void
814 gst_audio_resampler_options_set_quality (GstAudioResamplerMethod method,
815     guint quality, gint in_rate, gint out_rate, GstStructure * options)
816 {
817   g_return_if_fail (options != NULL);
818   g_return_if_fail (quality <= GST_AUDIO_RESAMPLER_QUALITY_MAX);
819   g_return_if_fail (in_rate > 0 && out_rate > 0);
820
821   switch (method) {
822     case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
823       break;
824     case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
825       gst_structure_set (options,
826           GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, 2, NULL);
827       break;
828     case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
829       gst_structure_set (options,
830           GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, 4,
831           GST_AUDIO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, DEFAULT_OPT_CUBIC_B,
832           GST_AUDIO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, DEFAULT_OPT_CUBIC_C,
833           NULL);
834       break;
835     case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
836     {
837       const BlackmanQualityMap *map = &blackman_qualities[quality];
838       gst_structure_set (options,
839           GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, map->n_taps,
840           GST_AUDIO_RESAMPLER_OPT_CUTOFF, G_TYPE_DOUBLE, map->cutoff, NULL);
841       break;
842     }
843     case GST_AUDIO_RESAMPLER_METHOD_KAISER:
844     {
845       const KaiserQualityMap *map = &kaiser_qualities[quality];
846       gdouble cutoff;
847
848       cutoff = map->cutoff;
849       if (out_rate < in_rate)
850         cutoff *= map->downsample_cutoff_factor;
851
852       gst_structure_set (options,
853           GST_AUDIO_RESAMPLER_OPT_CUTOFF, G_TYPE_DOUBLE, cutoff,
854           GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUATION, G_TYPE_DOUBLE,
855           map->stopband_attenuation,
856           GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH, G_TYPE_DOUBLE,
857           map->transition_bandwidth, NULL);
858       break;
859     }
860   }
861 }
862
863 /**
864  * gst_audio_resampler_new:
865  * @resampler: a #GstAudioResampler
866  * @method: a #GstAudioResamplerMethod
867  * @flags: #GstAudioResamplerFlags
868  * @in_rate: input rate
869  * @out_rate: output rate
870  * @options: extra options
871  *
872  * Make a new resampler.
873  *
874  * Returns: %TRUE on success
875  */
876 GstAudioResampler *
877 gst_audio_resampler_new (GstAudioResamplerMethod method,
878     GstAudioResamplerFlags flags,
879     GstAudioFormat format, gint channels,
880     gint in_rate, gint out_rate, GstStructure * options)
881 {
882   GstAudioResampler *resampler;
883   const GstAudioFormatInfo *info;
884
885   g_return_val_if_fail (channels > 0, FALSE);
886   g_return_val_if_fail (in_rate > 0, FALSE);
887   g_return_val_if_fail (out_rate > 0, FALSE);
888
889   audio_resampler_init ();
890
891   resampler = g_slice_new0 (GstAudioResampler);
892   resampler->method = method;
893   resampler->flags = flags;
894   resampler->format = format;
895   resampler->channels = channels;
896
897   info = gst_audio_format_get_info (format);
898   resampler->bps = GST_AUDIO_FORMAT_INFO_WIDTH (info) / 8;
899   resampler->sbuf = g_malloc0 (sizeof (gpointer) * channels);
900
901   GST_DEBUG ("method %d, bps %d, channels %d", method, resampler->bps,
902       resampler->channels);
903
904   gst_audio_resampler_update (resampler, in_rate, out_rate, options);
905
906   /* half of the filter is filled with 0 */
907   resampler->samp_index = 0;
908   resampler->samples_avail = resampler->n_taps / 2 - 1;
909
910   return resampler;
911 }
912
913 /* make the buffers to hold the (deinterleaved) samples */
914 static inline gpointer *
915 get_sample_bufs (GstAudioResampler * resampler, gsize need)
916 {
917   if (G_LIKELY (resampler->samples_len < need)) {
918     guint c, blocks = resampler->blocks;
919     gsize bytes, to_move = 0;
920     gint8 *ptr, *samples;
921
922     GST_LOG ("realloc %d -> %d", (gint) resampler->samples_len, (gint) need);
923
924     bytes = GST_ROUND_UP_N (need * resampler->bps * resampler->inc, ALIGN);
925
926     samples = g_malloc0 (blocks * bytes + ALIGN - 1);
927     ptr = MEM_ALIGN (samples, ALIGN);
928
929     /* if we had some data, move history */
930     if (resampler->samples_len > 0)
931       to_move = resampler->samples_avail * resampler->bps * resampler->inc;
932
933     /* set up new pointers */
934     for (c = 0; c < blocks; c++) {
935       memcpy (ptr + (c * bytes), resampler->sbuf[c], to_move);
936       resampler->sbuf[c] = ptr + (c * bytes);
937     }
938     g_free (resampler->samples);
939     resampler->samples = samples;
940     resampler->samples_len = need;
941   }
942   return resampler->sbuf;
943 }
944
945 /**
946  * gst_audio_resampler_reset:
947  * @resampler: a #GstAudioResampler
948  *
949  * Reset @resampler to the state it was when it was first created, discarding
950  * all sample history.
951  */
952 void
953 gst_audio_resampler_reset (GstAudioResampler * resampler)
954 {
955   g_return_if_fail (resampler != NULL);
956
957   if (resampler->samples) {
958     gsize bytes;
959     gint c, blocks, bpf;
960
961     bpf = resampler->bps * resampler->inc;
962     bytes = (resampler->n_taps / 2) * bpf;
963     blocks = resampler->blocks;
964
965     for (c = 0; c < blocks; c++)
966       memset (resampler->sbuf[c], 0, bytes);
967   }
968   /* half of the filter is filled with 0 */
969   resampler->samp_index = 0;
970   resampler->samples_avail = resampler->n_taps / 2 - 1;
971 }
972
973 /**
974  * gst_audio_resampler_update:
975  * @resampler: a #GstAudioResampler
976  * @in_rate: new input rate
977  * @out_rate: new output rate
978  * @options: new options or %NULL
979  *
980  * Update the resampler parameters for @resampler. This function should
981  * not be called concurrently with any other function on @resampler.
982  *
983  * When @in_rate or @out_rate is 0, its value is unchanged.
984  *
985  * When @options is %NULL, the previously configured options are reused.
986  *
987  * Returns: %TRUE if the new parameters could be set
988  */
989 gboolean
990 gst_audio_resampler_update (GstAudioResampler * resampler,
991     gint in_rate, gint out_rate, GstStructure * options)
992 {
993   gint gcd, samp_phase, old_n_taps;
994
995   g_return_val_if_fail (resampler != NULL, FALSE);
996
997   if (in_rate <= 0)
998     in_rate = resampler->in_rate;
999   if (out_rate <= 0)
1000     out_rate = resampler->out_rate;
1001
1002   if (resampler->out_rate > 0)
1003     samp_phase =
1004         gst_util_uint64_scale_int (resampler->samp_phase, out_rate,
1005         resampler->out_rate);
1006   else
1007     samp_phase = 0;
1008
1009   gcd = gst_util_greatest_common_divisor (in_rate, out_rate);
1010
1011   if (gcd > 1) {
1012     gdouble ph1 = (gdouble) samp_phase / out_rate;
1013     gint factor = 2;
1014
1015     /* reduce the factor until we have a phase error of less than 10% */
1016     do {
1017       gdouble ph2 = (gdouble) (samp_phase / gcd) / (out_rate / gcd);
1018
1019       if (fabs (ph1 - ph2) < 0.1)
1020         break;
1021
1022       while (gcd % factor != 0)
1023         factor++;
1024       gcd /= factor;
1025
1026       GST_INFO ("divide by factor %d, gcd %d", factor, gcd);
1027
1028     } while (gcd > 1);
1029   }
1030
1031   GST_INFO ("phase %d, out_rate %d, in_rate %d, gcd %d", samp_phase, out_rate,
1032       in_rate, gcd);
1033
1034   resampler->samp_phase = samp_phase / gcd;
1035   resampler->in_rate = in_rate / gcd;
1036   resampler->out_rate = out_rate / gcd;
1037
1038   if (options) {
1039     if (resampler->options)
1040       gst_structure_free (resampler->options);
1041     resampler->options = gst_structure_copy (options);
1042   }
1043
1044   old_n_taps = resampler->n_taps;
1045
1046   resampler_calculate_taps (resampler);
1047   resampler_dump (resampler);
1048
1049   GST_DEBUG ("rate %u->%u, taps %d->%d", resampler->in_rate,
1050       resampler->out_rate, old_n_taps, resampler->n_taps);
1051
1052   if (old_n_taps > 0) {
1053     gpointer *sbuf;
1054     gint i, bpf, bytes, soff, doff, diff;
1055
1056     sbuf = get_sample_bufs (resampler, resampler->n_taps);
1057
1058     bpf = resampler->bps * resampler->inc;
1059     bytes = resampler->samples_avail * bpf;
1060     soff = doff = resampler->samp_index * bpf;
1061
1062     diff = ((gint) resampler->n_taps - old_n_taps) / 2;
1063
1064     if (diff < 0) {
1065       /* diff < 0, decrease taps, adjust source */
1066       soff += -diff * bpf;
1067       bytes -= -diff * bpf;
1068     } else {
1069       /* diff > 0, increase taps, adjust dest */
1070       doff += diff * bpf;
1071     }
1072
1073     /* now shrink or enlarge the history buffer, when we enlarge we
1074      * just leave the old samples in there. FIXME, probably do something better
1075      * like mirror or fill with zeroes. */
1076     for (i = 0; i < resampler->blocks; i++)
1077       memmove ((gint8 *) sbuf[i] + doff, (gint8 *) sbuf[i] + soff, bytes);
1078
1079     resampler->samples_avail += diff;
1080   }
1081   return TRUE;
1082 }
1083
1084 /**
1085  * gst_audio_resampler_free:
1086  * @resampler: a #GstAudioResampler
1087  *
1088  * Free a previously allocated #GstAudioResampler @resampler.
1089  *
1090  * Since: 1.6
1091  */
1092 void
1093 gst_audio_resampler_free (GstAudioResampler * resampler)
1094 {
1095   g_return_if_fail (resampler != NULL);
1096
1097   g_free (resampler->taps);
1098   g_free (resampler->coeffmem);
1099   g_free (resampler->tmpcoeff);
1100   g_free (resampler->samples);
1101   g_free (resampler->sbuf);
1102   if (resampler->options)
1103     gst_structure_free (resampler->options);
1104   g_slice_free (GstAudioResampler, resampler);
1105 }
1106
1107 static inline gsize
1108 calc_out (GstAudioResampler * resampler, gsize in)
1109 {
1110   gsize out;
1111
1112   out = in * resampler->out_rate;
1113   if (out < resampler->samp_phase)
1114     return 0;
1115
1116   out = ((out - resampler->samp_phase) / resampler->in_rate) + 1;
1117   GST_LOG ("out %d = ((%d * %d - %d) / %d) + 1", (gint) out,
1118       (gint) in, resampler->out_rate, resampler->samp_phase,
1119       resampler->in_rate);
1120
1121   return out;
1122 }
1123
1124 /**
1125  * gst_audio_resampler_get_out_frames:
1126  * @resampler: a #GstAudioResampler
1127  * @in_frames: number of input frames
1128  *
1129  * Get the number of output frames that would be currently available when
1130  * @in_frames are given to @resampler.
1131  *
1132  * Returns: The number of frames that would be availabe after giving
1133  * @in_frames as input to @resampler.
1134  */
1135 gsize
1136 gst_audio_resampler_get_out_frames (GstAudioResampler * resampler,
1137     gsize in_frames)
1138 {
1139   gsize need, avail;
1140
1141   g_return_val_if_fail (resampler != NULL, 0);
1142
1143   need = resampler->n_taps + resampler->samp_index + resampler->skip;
1144   avail = resampler->samples_avail + in_frames;
1145   GST_LOG ("need %d = %d + %d + %d, avail %d = %d + %d", (gint) need,
1146       resampler->n_taps, resampler->samp_index, resampler->skip,
1147       (gint) avail, (gint) resampler->samples_avail, (gint) in_frames);
1148   if (avail < need)
1149     return 0;
1150
1151   return calc_out (resampler, avail - need);
1152 }
1153
1154 /**
1155  * gst_audio_resampler_get_in_frames:
1156  * @resampler: a #GstAudioResampler
1157  * @out_frames: number of input frames
1158  *
1159  * Get the number of input frames that would currently be needed
1160  * to produce @out_frames from @resampler.
1161  *
1162  * Returns: The number of input frames needed for producing
1163  * @out_frames of data from @resampler.
1164  */
1165 gsize
1166 gst_audio_resampler_get_in_frames (GstAudioResampler * resampler,
1167     gsize out_frames)
1168 {
1169   gsize in_frames;
1170
1171   g_return_val_if_fail (resampler != NULL, 0);
1172
1173   in_frames =
1174       (resampler->samp_phase +
1175       out_frames * resampler->samp_frac) / resampler->out_rate;
1176   in_frames += out_frames * resampler->samp_inc;
1177
1178   return in_frames;
1179 }
1180
1181 /**
1182  * gst_audio_resampler_get_max_latency:
1183  * @resampler: a #GstAudioResampler
1184  *
1185  * Get the maximum number of input samples that the resampler would
1186  * need before producing output.
1187  *
1188  * Returns: the latency of @resampler as expressed in the number of
1189  * frames.
1190  */
1191 gsize
1192 gst_audio_resampler_get_max_latency (GstAudioResampler * resampler)
1193 {
1194   g_return_val_if_fail (resampler != NULL, 0);
1195
1196   return resampler->n_taps / 2;
1197 }
1198
1199 /**
1200  * gst_audio_resampler_resample:
1201  * @resampler: a #GstAudioResampler
1202  * @in: input samples
1203  * @in_frames: number of input frames
1204  * @out: output samples
1205  * @out_frames: number of output frames
1206  *
1207  * Perform resampling on @in_frames frames in @in and write @out_frames to @out.
1208  *
1209  * In case the samples are interleaved, @in and @out must point to an
1210  * array with a single element pointing to a block of interleaved samples.
1211  *
1212  * If non-interleaved samples are used, @in and @out must point to an
1213  * array with pointers to memory blocks, one for each channel.
1214  *
1215  * @in may be %NULL, in which case @in_frames of silence samples are pushed
1216  * into the resampler.
1217  *
1218  * This function always produces @out_frames of output and consumes @in_frames of
1219  * input. Use gst_audio_resampler_get_out_frames() and
1220  * gst_audio_resampler_get_in_frames() to make sure @in_frames and @out_frames
1221  * are matching and @in and @out point to enough memory.
1222  */
1223 void
1224 gst_audio_resampler_resample (GstAudioResampler * resampler,
1225     gpointer in[], gsize in_frames, gpointer out[], gsize out_frames)
1226 {
1227   gsize samples_avail;
1228   gsize need, consumed;
1229   gpointer *sbuf;
1230
1231   /* do sample skipping */
1232   if (G_UNLIKELY (resampler->skip >= in_frames)) {
1233     /* we need tp skip all input */
1234     resampler->skip -= in_frames;
1235     return;
1236   }
1237   /* skip the last samples by advancing the sample index */
1238   resampler->samp_index += resampler->skip;
1239
1240   samples_avail = resampler->samples_avail;
1241
1242   /* make sure we have enough space to copy our samples */
1243   sbuf = get_sample_bufs (resampler, in_frames + samples_avail);
1244
1245   /* copy/deinterleave the samples */
1246   resampler->deinterleave (resampler, sbuf, in, in_frames);
1247
1248   /* update new amount of samples in our buffer */
1249   resampler->samples_avail = samples_avail += in_frames;
1250
1251   need = resampler->n_taps + resampler->samp_index;
1252   if (G_UNLIKELY (samples_avail < need)) {
1253     /* not enough samples to start */
1254     return;
1255   }
1256
1257   /* resample all channels */
1258   resampler->resample (resampler, sbuf, samples_avail, out, out_frames,
1259       &consumed);
1260
1261   GST_LOG ("in %" G_GSIZE_FORMAT ", avail %" G_GSIZE_FORMAT ", consumed %"
1262       G_GSIZE_FORMAT, in_frames, samples_avail, consumed);
1263
1264   /* update pointers */
1265   if (G_LIKELY (consumed > 0)) {
1266     gssize left = samples_avail - consumed;
1267     if (left > 0) {
1268       /* we consumed part of our samples */
1269       resampler->samples_avail = left;
1270     } else {
1271       /* we consumed all our samples, empty our buffers */
1272       resampler->samples_avail = 0;
1273       resampler->skip = -left;
1274     }
1275   }
1276 }