Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst / audioconvert / gstaudioquantize.c
1 /* GStreamer
2  * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
3  *
4  * gstaudioquantize.c: quantizes audio to the target format and optionally
5  *                     applies dithering and noise shaping.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /*
24  * FIXME: When doing dithering with int as intermediate format
25  *        one gets audible harmonics while the noise floor is
26  *        constant for double as intermediate format!
27  */
28
29 /* TODO: - Maybe drop 5-pole noise shaping and use coefficients
30  *         generated by dmaker
31  *         http://shibatch.sf.net
32  */
33
34 #include <gst/gst.h>
35 #include <string.h>
36 #include <math.h>
37 #include "audioconvert.h"
38 #include "gstaudioquantize.h"
39
40 #include "gstfastrandom.h"
41
42 #define MAKE_QUANTIZE_FUNC_NAME(name)                                   \
43 gst_audio_quantize_quantize_##name
44
45 /* Quantize functions for gint32 as intermediate format */
46
47 #define MAKE_QUANTIZE_FUNC_I(name, DITHER_INIT_FUNC, ADD_DITHER_FUNC,   \
48                              ROUND_FUNC)                                \
49 static void                                                             \
50 MAKE_QUANTIZE_FUNC_NAME (name) (AudioConvertCtx *ctx, gint32 *src,      \
51                                 gint32 *dst, gint count)                \
52 {                                                                       \
53   gint scale = ctx->out_scale;                                          \
54   gint channels = ctx->out.channels;                                    \
55   gint chan_pos;                                                        \
56                                                                         \
57   if (scale > 0) {                                                      \
58     gint32 tmp;                                                         \
59     guint32 mask = 0xffffffff & (0xffffffff << scale);                  \
60     guint32 bias = 1U << (scale - 1);                                   \
61     DITHER_INIT_FUNC()                                                  \
62                                                                         \
63     for (;count;count--) {                                              \
64       for (chan_pos = 0; chan_pos < channels; chan_pos++) {             \
65         tmp = *src++;                                                   \
66         ADD_DITHER_FUNC()                                               \
67         ROUND_FUNC()                                                    \
68         *dst = tmp & mask;                                              \
69         dst++;                                                          \
70       }                                                                 \
71     }                                                                   \
72   } else {                                                              \
73     for (;count;count--) {                                              \
74       for (chan_pos = 0; chan_pos < channels; chan_pos++) {             \
75         *dst = *src++;                                                  \
76         dst++;                                                          \
77       }                                                                 \
78     }                                                                   \
79   }                                                                     \
80 }
81
82
83 /* Quantize functions for gdouble as intermediate format with
84  * int as target */
85
86 #define MAKE_QUANTIZE_FUNC_F(name, DITHER_INIT_FUNC, NS_INIT_FUNC,      \
87                              ADD_NS_FUNC, ADD_DITHER_FUNC,              \
88                              UPDATE_ERROR_FUNC)                         \
89 static void                                                             \
90 MAKE_QUANTIZE_FUNC_NAME (name) (AudioConvertCtx *ctx, gdouble *src,     \
91                                 gdouble *dst, gint count)               \
92 {                                                                       \
93   gint scale = ctx->out_scale;                                          \
94   gint channels = ctx->out.channels;                                    \
95   gint chan_pos;                                                        \
96   gdouble factor = (1U<<(32-scale-1)) - 1;                              \
97                                                                         \
98   if (scale > 0) {                                                      \
99     gdouble tmp;                                                        \
100     DITHER_INIT_FUNC()                                                  \
101     NS_INIT_FUNC()                                                      \
102                                                                         \
103     for (;count;count--) {                                              \
104       for (chan_pos = 0; chan_pos < channels; chan_pos++) {             \
105         tmp = *src++;                                                   \
106         ADD_NS_FUNC()                                                   \
107         ADD_DITHER_FUNC()                                               \
108         tmp = floor(tmp * factor + 0.5);                                \
109         *dst = CLAMP (tmp, -factor - 1, factor);                        \
110         UPDATE_ERROR_FUNC()                                             \
111         dst++;                                                          \
112       }                                                                 \
113     }                                                                   \
114   } else {                                                              \
115     for (;count;count--) {                                              \
116       for (chan_pos = 0; chan_pos < channels; chan_pos++) {             \
117         *dst = *src++ * 2147483647.0;                                   \
118         dst++;                                                          \
119       }                                                                 \
120     }                                                                   \
121   }                                                                     \
122 }
123
124 /* Rounding functions for int as intermediate format, only used when
125  * not using dithering. With dithering we include this offset in our
126  * dither noise instead. */
127
128 #define ROUND()                                                         \
129         if (tmp > 0 && G_MAXINT32 - tmp <= bias)                        \
130           tmp = G_MAXINT32;                                             \
131         else                                                            \
132           tmp += bias;
133
134
135 #define NONE_FUNC()
136
137 /* Dithering definitions
138  * See http://en.wikipedia.org/wiki/Dithering or
139  * http://www.cadenzarecording.com/Dither.html for explainations.
140  *
141  * We already add the rounding offset to the dither noise here
142  * to have only one overflow check instead of two. */
143
144 #define INIT_DITHER_RPDF_I()                                            \
145   gint32 rand;                                                          \
146   gint32 dither = (1<<(scale));
147
148 #define ADD_DITHER_RPDF_I()                                             \
149         rand = gst_fast_random_int32_range (bias - dither,              \
150             bias + dither);                                             \
151         if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand)            \
152                 tmp = G_MAXINT32;                                       \
153         else if (rand < 0 && tmp < 0 && G_MININT32 - tmp >= rand)       \
154                 tmp = G_MININT32;                                       \
155         else                                                            \
156                 tmp += rand;
157
158 #define INIT_DITHER_RPDF_F()                                            \
159   gdouble dither = 1.0/(1U<<(32 - scale - 1));
160
161 #define ADD_DITHER_RPDF_F()                                             \
162         tmp += gst_fast_random_double_range (- dither, dither);
163
164 #define INIT_DITHER_TPDF_I()                                            \
165   gint32 rand;                                                          \
166   gint32 dither = (1<<(scale - 1));                                     \
167   bias = bias >> 1;
168
169 #define ADD_DITHER_TPDF_I()                                             \
170         rand = gst_fast_random_int32_range (bias - dither,              \
171                    bias + dither - 1)                                   \
172                + gst_fast_random_int32_range (bias - dither,            \
173                    bias + dither - 1);                                  \
174         if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand)            \
175                 tmp = G_MAXINT32;                                       \
176         else if (rand < 0 && tmp < 0 && G_MININT32 - tmp >= rand)       \
177                 tmp = G_MININT32;                                       \
178         else                                                            \
179                 tmp += rand;
180
181 #define INIT_DITHER_TPDF_F()                                            \
182   gdouble dither = 1.0/(1U<<(32 - scale));
183
184 #define ADD_DITHER_TPDF_F()                                             \
185         tmp += gst_fast_random_double_range (- dither, dither)          \
186                + gst_fast_random_double_range (- dither, dither);
187
188 #define INIT_DITHER_TPDF_HF_I()                                         \
189   gint32 rand;                                                          \
190   gint32 dither = (1<<(scale-1));                                       \
191   gint32 *last_random = (gint32 *) ctx->last_random, tmp_rand;          \
192   bias = bias >> 1;
193
194 #define ADD_DITHER_TPDF_HF_I()                                          \
195         tmp_rand = gst_fast_random_int32_range (bias - dither,          \
196                        bias + dither);                                  \
197         rand = tmp_rand - last_random[chan_pos];                        \
198         last_random[chan_pos] = tmp_rand;                               \
199         if (rand > 0 && tmp > 0 && G_MAXINT32 - tmp <= rand)            \
200                 tmp = G_MAXINT32;                                       \
201         else if (rand < 0 && tmp < 0 && G_MININT32 - tmp >= rand)       \
202                 tmp = G_MININT32;                                       \
203         else                                                            \
204                 tmp += rand;
205
206 /* Like TPDF dither but the dither noise is oriented more to the
207  * higher frequencies */
208
209 #define INIT_DITHER_TPDF_HF_F()                                         \
210   gdouble rand;                                                         \
211   gdouble dither = 1.0/(1U<<(32 - scale));                              \
212   gdouble *last_random = (gdouble *) ctx->last_random, tmp_rand;
213
214 #define ADD_DITHER_TPDF_HF_F()                                          \
215         tmp_rand = gst_fast_random_double_range (- dither, dither);     \
216         rand = tmp_rand - last_random[chan_pos];                        \
217         last_random[chan_pos] = tmp_rand;                               \
218         tmp += rand;
219
220 /* Noise shaping definitions.
221  * See http://en.wikipedia.org/wiki/Noise_shaping for explanations. */
222
223
224 /* Simple error feedback: Just accumulate the dithering and quantization
225  * error and remove it from each sample. */
226
227 #define INIT_NS_ERROR_FEEDBACK()                                        \
228   gdouble orig;                                                         \
229   gdouble *errors = ctx->error_buf;
230
231 #define ADD_NS_ERROR_FEEDBACK()                                         \
232         orig = tmp;                                                     \
233         tmp -= errors[chan_pos];
234
235 #define UPDATE_ERROR_ERROR_FEEDBACK()                                   \
236         errors[chan_pos] += (*dst)/factor - orig;
237
238 /* Same as error feedback but also add 1/2 of the previous error value.
239  * This moves the noise a bit more into the higher frequencies. */
240
241 #define INIT_NS_SIMPLE()                                                \
242   gdouble orig;                                                         \
243   gdouble *errors = ctx->error_buf, cur_error;
244
245 #define ADD_NS_SIMPLE()                                                 \
246         cur_error = errors[chan_pos*2] - 0.5 * errors[chan_pos*2 + 1];  \
247         tmp -= cur_error;                                               \
248         orig = tmp;
249
250 #define UPDATE_ERROR_SIMPLE()                                           \
251         errors[chan_pos*2 + 1] = errors[chan_pos*2];                    \
252         errors[chan_pos*2] = (*dst)/factor - orig;
253
254
255 /* Noise shaping coefficients from[1], moves most power of the
256  * error noise into inaudible frequency ranges.
257  *
258  * [1]
259  * "Minimally Audible Noise Shaping", Stanley P. Lipshitz,
260  * John Vanderkooy, and Robert A. Wannamaker,
261  * J. Audio Eng. Soc., Vol. 39, No. 11, November 1991. */
262
263 static const gdouble ns_medium_coeffs[] = {
264   2.033, -2.165, 1.959, -1.590, 0.6149
265 };
266
267 #define INIT_NS_MEDIUM()                                                \
268   gdouble orig;                                                         \
269   gdouble *errors = ctx->error_buf, cur_error;                          \
270   int j;
271
272 #define ADD_NS_MEDIUM()                                                 \
273         cur_error = 0.0;                                                \
274         for (j = 0; j < 5; j++)                                         \
275           cur_error += errors[chan_pos*5 + j] * ns_medium_coeffs[j];    \
276         tmp -= cur_error;                                               \
277         orig = tmp;
278
279 #define UPDATE_ERROR_MEDIUM()                                           \
280         for (j = 4; j > 0; j--)                                         \
281           errors[chan_pos*5 + j] = errors[chan_pos*5 + j-1];            \
282         errors[chan_pos*5] = (*dst)/factor - orig;
283
284 /* Noise shaping coefficients by David Schleef, moves most power of the
285  * error noise into inaudible frequency ranges */
286
287 static const gdouble ns_high_coeffs[] = {
288   2.08484, -2.92975, 3.27918, -3.31399, 2.61339, -1.72008, 0.876066, -0.340122
289 };
290
291 #define INIT_NS_HIGH()                                                  \
292   gdouble orig;                                                         \
293   gdouble *errors = ctx->error_buf, cur_error;                          \
294   int j;
295
296 #define ADD_NS_HIGH()                                                   \
297         cur_error = 0.0;                                                \
298         for (j = 0; j < 8; j++)                                         \
299           cur_error += errors[chan_pos + j] * ns_high_coeffs[j];          \
300         tmp -= cur_error;                                               \
301         orig = tmp;
302
303 #define UPDATE_ERROR_HIGH()                                             \
304         for (j = 7; j > 0; j--)                                         \
305           errors[chan_pos + j] = errors[chan_pos + j-1];                \
306         errors[chan_pos] = (*dst)/factor - orig;
307
308
309 MAKE_QUANTIZE_FUNC_I (signed_none_none, NONE_FUNC, NONE_FUNC, ROUND);
310 MAKE_QUANTIZE_FUNC_I (signed_rpdf_none, INIT_DITHER_RPDF_I, ADD_DITHER_RPDF_I,
311     NONE_FUNC);
312 MAKE_QUANTIZE_FUNC_I (signed_tpdf_none, INIT_DITHER_TPDF_I, ADD_DITHER_TPDF_I,
313     NONE_FUNC);
314 MAKE_QUANTIZE_FUNC_I (signed_tpdf_hf_none, INIT_DITHER_TPDF_HF_I,
315     ADD_DITHER_TPDF_HF_I, NONE_FUNC);
316
317 MAKE_QUANTIZE_FUNC_I (unsigned_none_none, NONE_FUNC, NONE_FUNC, ROUND);
318 MAKE_QUANTIZE_FUNC_I (unsigned_rpdf_none, INIT_DITHER_RPDF_I, ADD_DITHER_RPDF_I,
319     NONE_FUNC);
320 MAKE_QUANTIZE_FUNC_I (unsigned_tpdf_none, INIT_DITHER_TPDF_I, ADD_DITHER_TPDF_I,
321     NONE_FUNC);
322 MAKE_QUANTIZE_FUNC_I (unsigned_tpdf_hf_none, INIT_DITHER_TPDF_HF_I,
323     ADD_DITHER_TPDF_HF_I, NONE_FUNC);
324
325 MAKE_QUANTIZE_FUNC_F (float_none_error_feedback, NONE_FUNC,
326     INIT_NS_ERROR_FEEDBACK, ADD_NS_ERROR_FEEDBACK, NONE_FUNC,
327     UPDATE_ERROR_ERROR_FEEDBACK);
328 MAKE_QUANTIZE_FUNC_F (float_none_simple, NONE_FUNC, INIT_NS_SIMPLE,
329     ADD_NS_SIMPLE, NONE_FUNC, UPDATE_ERROR_SIMPLE);
330 MAKE_QUANTIZE_FUNC_F (float_none_medium, NONE_FUNC, INIT_NS_MEDIUM,
331     ADD_NS_MEDIUM, NONE_FUNC, UPDATE_ERROR_MEDIUM);
332 MAKE_QUANTIZE_FUNC_F (float_none_high, NONE_FUNC, INIT_NS_HIGH, ADD_NS_HIGH,
333     NONE_FUNC, UPDATE_ERROR_HIGH);
334
335 MAKE_QUANTIZE_FUNC_F (float_rpdf_error_feedback, INIT_DITHER_RPDF_F,
336     INIT_NS_ERROR_FEEDBACK, ADD_NS_ERROR_FEEDBACK, ADD_DITHER_RPDF_F,
337     UPDATE_ERROR_ERROR_FEEDBACK);
338 MAKE_QUANTIZE_FUNC_F (float_rpdf_simple, INIT_DITHER_RPDF_F, INIT_NS_SIMPLE,
339     ADD_NS_SIMPLE, ADD_DITHER_RPDF_F, UPDATE_ERROR_SIMPLE);
340 MAKE_QUANTIZE_FUNC_F (float_rpdf_medium, INIT_DITHER_RPDF_F, INIT_NS_MEDIUM,
341     ADD_NS_MEDIUM, ADD_DITHER_RPDF_F, UPDATE_ERROR_MEDIUM);
342 MAKE_QUANTIZE_FUNC_F (float_rpdf_high, INIT_DITHER_RPDF_F, INIT_NS_HIGH,
343     ADD_NS_HIGH, ADD_DITHER_RPDF_F, UPDATE_ERROR_HIGH);
344
345 MAKE_QUANTIZE_FUNC_F (float_tpdf_error_feedback, INIT_DITHER_TPDF_F,
346     INIT_NS_ERROR_FEEDBACK, ADD_NS_ERROR_FEEDBACK, ADD_DITHER_TPDF_F,
347     UPDATE_ERROR_ERROR_FEEDBACK);
348 MAKE_QUANTIZE_FUNC_F (float_tpdf_simple, INIT_DITHER_TPDF_F, INIT_NS_SIMPLE,
349     ADD_NS_SIMPLE, ADD_DITHER_TPDF_F, UPDATE_ERROR_SIMPLE);
350 MAKE_QUANTIZE_FUNC_F (float_tpdf_medium, INIT_DITHER_TPDF_F, INIT_NS_MEDIUM,
351     ADD_NS_MEDIUM, ADD_DITHER_TPDF_F, UPDATE_ERROR_MEDIUM);
352 MAKE_QUANTIZE_FUNC_F (float_tpdf_high, INIT_DITHER_TPDF_F, INIT_NS_HIGH,
353     ADD_NS_HIGH, ADD_DITHER_TPDF_F, UPDATE_ERROR_HIGH);
354
355 MAKE_QUANTIZE_FUNC_F (float_tpdf_hf_error_feedback, INIT_DITHER_TPDF_HF_F,
356     INIT_NS_ERROR_FEEDBACK, ADD_NS_ERROR_FEEDBACK, ADD_DITHER_TPDF_HF_F,
357     UPDATE_ERROR_ERROR_FEEDBACK);
358 MAKE_QUANTIZE_FUNC_F (float_tpdf_hf_simple, INIT_DITHER_TPDF_HF_F,
359     INIT_NS_SIMPLE, ADD_NS_SIMPLE, ADD_DITHER_TPDF_HF_F, UPDATE_ERROR_SIMPLE);
360 MAKE_QUANTIZE_FUNC_F (float_tpdf_hf_medium, INIT_DITHER_TPDF_HF_F,
361     INIT_NS_MEDIUM, ADD_NS_MEDIUM, ADD_DITHER_TPDF_HF_F, UPDATE_ERROR_MEDIUM);
362 MAKE_QUANTIZE_FUNC_F (float_tpdf_hf_high, INIT_DITHER_TPDF_HF_F, INIT_NS_HIGH,
363     ADD_NS_HIGH, ADD_DITHER_TPDF_HF_F, UPDATE_ERROR_HIGH);
364
365 static AudioConvertQuantize quantize_funcs[] = {
366   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (signed_none_none),
367   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (signed_rpdf_none),
368   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (signed_tpdf_none),
369   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (signed_tpdf_hf_none),
370   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (unsigned_none_none),
371   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (unsigned_rpdf_none),
372   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (unsigned_tpdf_none),
373   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (unsigned_tpdf_hf_none),
374   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_error_feedback),
375   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_simple),
376   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_medium),
377   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_high),
378   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_error_feedback),
379   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_simple),
380   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_medium),
381   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_high),
382   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_error_feedback),
383   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_simple),
384   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_medium),
385   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_high),
386   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_error_feedback),
387   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_simple),
388   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_medium),
389   (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_high)
390 };
391
392 static void
393 gst_audio_quantize_setup_noise_shaping (AudioConvertCtx * ctx)
394 {
395   switch (ctx->ns) {
396     case NOISE_SHAPING_HIGH:{
397       ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 8);
398       break;
399     }
400     case NOISE_SHAPING_MEDIUM:{
401       ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 5);
402       break;
403     }
404     case NOISE_SHAPING_SIMPLE:{
405       ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 2);
406       break;
407     }
408     case NOISE_SHAPING_ERROR_FEEDBACK:
409       ctx->error_buf = g_new0 (gdouble, ctx->out.channels);
410       break;
411     case NOISE_SHAPING_NONE:
412     default:
413       ctx->error_buf = NULL;
414       break;
415   }
416   return;
417 }
418
419 static void
420 gst_audio_quantize_free_noise_shaping (AudioConvertCtx * ctx)
421 {
422   switch (ctx->ns) {
423     case NOISE_SHAPING_HIGH:
424     case NOISE_SHAPING_MEDIUM:
425     case NOISE_SHAPING_SIMPLE:
426     case NOISE_SHAPING_ERROR_FEEDBACK:
427     case NOISE_SHAPING_NONE:
428     default:
429       break;
430   }
431
432   g_free (ctx->error_buf);
433   ctx->error_buf = NULL;
434   return;
435 }
436
437 static void
438 gst_audio_quantize_setup_dither (AudioConvertCtx * ctx)
439 {
440   switch (ctx->dither) {
441     case DITHER_TPDF_HF:
442       if (ctx->out.is_int)
443         ctx->last_random = g_new0 (gint32, ctx->out.channels);
444       else
445         ctx->last_random = g_new0 (gdouble, ctx->out.channels);
446       break;
447     case DITHER_RPDF:
448     case DITHER_TPDF:
449       ctx->last_random = NULL;
450       break;
451     case DITHER_NONE:
452     default:
453       ctx->last_random = NULL;
454       break;
455   }
456   return;
457 }
458
459 static void
460 gst_audio_quantize_free_dither (AudioConvertCtx * ctx)
461 {
462   g_free (ctx->last_random);
463
464   return;
465 }
466
467 static void
468 gst_audio_quantize_setup_quantize_func (AudioConvertCtx * ctx)
469 {
470   gint index = 0;
471
472   if (!ctx->out.is_int) {
473     ctx->quantize = NULL;
474     return;
475   }
476
477   if (ctx->ns == NOISE_SHAPING_NONE) {
478     index += ctx->dither;
479     index += (ctx->out.sign) ? 0 : 4;
480   } else {
481     index += 8 + (4 * ctx->dither);
482     index += ctx->ns - 1;
483   }
484
485   ctx->quantize = quantize_funcs[index];
486 }
487
488 gboolean
489 gst_audio_quantize_setup (AudioConvertCtx * ctx)
490 {
491   gst_audio_quantize_setup_dither (ctx);
492   gst_audio_quantize_setup_noise_shaping (ctx);
493   gst_audio_quantize_setup_quantize_func (ctx);
494
495   return TRUE;
496 }
497
498 void
499 gst_audio_quantize_free (AudioConvertCtx * ctx)
500 {
501   gst_audio_quantize_free_dither (ctx);
502   gst_audio_quantize_free_noise_shaping (ctx);
503 }