Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst / audioconvert / audioconvert.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim at fluendo dot com>
3  *
4  * audioconvert.c: Convert audio to different audio formats automatically
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <math.h>
27 #include <string.h>
28
29 #include "gstchannelmix.h"
30 #include "gstaudioquantize.h"
31 #include "audioconvert.h"
32 #include "gst/floatcast/floatcast.h"
33 #include "gstaudioconvertorc.h"
34
35 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
36 #define orc_audio_convert_unpack_u16_le orc_audio_convert_unpack_u16
37 #define orc_audio_convert_unpack_u16_be orc_audio_convert_unpack_u16_swap
38 #define orc_audio_convert_unpack_s16_le orc_audio_convert_unpack_s16
39 #define orc_audio_convert_unpack_s16_be orc_audio_convert_unpack_s16_swap
40 #define orc_audio_convert_unpack_u32_le orc_audio_convert_unpack_u32
41 #define orc_audio_convert_unpack_u32_be orc_audio_convert_unpack_u32_swap
42 #define orc_audio_convert_unpack_s32_le orc_audio_convert_unpack_s32
43 #define orc_audio_convert_unpack_s32_be orc_audio_convert_unpack_s32_swap
44 #define orc_audio_convert_unpack_float_le orc_audio_convert_unpack_float_s32
45 #define orc_audio_convert_unpack_float_be orc_audio_convert_unpack_float_s32_swap
46 #define orc_audio_convert_unpack_double_le orc_audio_convert_unpack_double_s32
47 #define orc_audio_convert_unpack_double_be orc_audio_convert_unpack_double_s32_swap
48 #define orc_audio_convert_unpack_float_hq_le orc_audio_convert_unpack_float_double
49 #define orc_audio_convert_unpack_float_hq_be orc_audio_convert_unpack_float_double_swap
50 #define orc_audio_convert_unpack_double_hq_le orc_audio_convert_unpack_double_double
51 #define orc_audio_convert_unpack_double_hq_be orc_audio_convert_unpack_double_double_swap
52 #define orc_audio_convert_unpack_u8_float orc_audio_convert_unpack_u8_double
53 #define orc_audio_convert_unpack_u16_le_float orc_audio_convert_unpack_u16_double
54 #define orc_audio_convert_unpack_u16_be_float orc_audio_convert_unpack_u16_double_swap
55 #define orc_audio_convert_unpack_u32_le_float orc_audio_convert_unpack_u32_double
56 #define orc_audio_convert_unpack_u32_be_float orc_audio_convert_unpack_u32_double_swap
57 #define orc_audio_convert_unpack_s8_float orc_audio_convert_unpack_s8_double
58 #define orc_audio_convert_unpack_s16_le_float orc_audio_convert_unpack_s16_double
59 #define orc_audio_convert_unpack_s16_be_float orc_audio_convert_unpack_s16_double_swap
60 #define orc_audio_convert_unpack_s32_le_float orc_audio_convert_unpack_s32_double
61 #define orc_audio_convert_unpack_s32_be_float orc_audio_convert_unpack_s32_double_swap
62 #define orc_audio_convert_pack_u8 orc_audio_convert_pack_u8
63 #define orc_audio_convert_pack_u16_le orc_audio_convert_pack_u16
64 #define orc_audio_convert_pack_u16_be orc_audio_convert_pack_u16_swap
65 #define orc_audio_convert_pack_s16_le orc_audio_convert_pack_s16
66 #define orc_audio_convert_pack_s16_be orc_audio_convert_pack_s16_swap
67 #define orc_audio_convert_pack_u32_le orc_audio_convert_pack_u32
68 #define orc_audio_convert_pack_u32_be orc_audio_convert_pack_u32_swap
69 #define orc_audio_convert_pack_s32_le orc_audio_convert_pack_s32
70 #define orc_audio_convert_pack_s32_be orc_audio_convert_pack_s32_swap
71 #define orc_audio_convert_pack_float_le orc_audio_convert_pack_s32_float
72 #define orc_audio_convert_pack_float_be orc_audio_convert_pack_s32_float_swap
73 #define orc_audio_convert_pack_double_le orc_audio_convert_pack_s32_double
74 #define orc_audio_convert_pack_double_be orc_audio_convert_pack_s32_double_swap
75 #define orc_audio_convert_pack_float_hq_le orc_audio_convert_pack_double_float
76 #define orc_audio_convert_pack_float_hq_be orc_audio_convert_pack_double_float_swap
77 #define orc_audio_convert_pack_s8_float orc_audio_convert_pack_double_s8
78 #define orc_audio_convert_pack_s16_le_float orc_audio_convert_pack_double_s16
79 #define orc_audio_convert_pack_s16_be_float orc_audio_convert_pack_double_s16_swap
80 #define orc_audio_convert_pack_s32_le_float orc_audio_convert_pack_double_s32
81 #define orc_audio_convert_pack_s32_be_float orc_audio_convert_pack_double_s32_swap
82 #define orc_audio_convert_pack_u8_float orc_audio_convert_pack_double_u8
83 #define orc_audio_convert_pack_u16_le_float orc_audio_convert_pack_double_u16
84 #define orc_audio_convert_pack_u16_be_float orc_audio_convert_pack_double_u16_swap
85 #define orc_audio_convert_pack_u32_le_float orc_audio_convert_pack_double_u32
86 #define orc_audio_convert_pack_u32_be_float orc_audio_convert_pack_double_u32_swap
87 #else
88 #define orc_audio_convert_unpack_u16_be orc_audio_convert_unpack_u16
89 #define orc_audio_convert_unpack_u16_le orc_audio_convert_unpack_u16_swap
90 #define orc_audio_convert_unpack_s16_be orc_audio_convert_unpack_s16
91 #define orc_audio_convert_unpack_s16_le orc_audio_convert_unpack_s16_swap
92 #define orc_audio_convert_unpack_u32_be orc_audio_convert_unpack_u32
93 #define orc_audio_convert_unpack_u32_le orc_audio_convert_unpack_u32_swap
94 #define orc_audio_convert_unpack_s32_be orc_audio_convert_unpack_s32
95 #define orc_audio_convert_unpack_s32_le orc_audio_convert_unpack_s32_swap
96 #define orc_audio_convert_unpack_float_be orc_audio_convert_unpack_float_s32
97 #define orc_audio_convert_unpack_float_le orc_audio_convert_unpack_float_s32_swap
98 #define orc_audio_convert_unpack_double_be orc_audio_convert_unpack_double_s32
99 #define orc_audio_convert_unpack_double_le orc_audio_convert_unpack_double_s32_swap
100 #define orc_audio_convert_unpack_float_hq_be orc_audio_convert_unpack_float_double
101 #define orc_audio_convert_unpack_float_hq_le orc_audio_convert_unpack_float_double_swap
102 #define orc_audio_convert_unpack_double_hq_be orc_audio_convert_unpack_double_double
103 #define orc_audio_convert_unpack_double_hq_le orc_audio_convert_unpack_double_double_swap
104 #define orc_audio_convert_unpack_u8_float orc_audio_convert_unpack_u8_double
105 #define orc_audio_convert_unpack_u16_be_float orc_audio_convert_unpack_u16_double
106 #define orc_audio_convert_unpack_u16_le_float orc_audio_convert_unpack_u16_double_swap
107 #define orc_audio_convert_unpack_u32_be_float orc_audio_convert_unpack_u32_double
108 #define orc_audio_convert_unpack_u32_le_float orc_audio_convert_unpack_u32_double_swap
109 #define orc_audio_convert_unpack_s8_float orc_audio_convert_unpack_s8_double
110 #define orc_audio_convert_unpack_s16_be_float orc_audio_convert_unpack_s16_double
111 #define orc_audio_convert_unpack_s16_le_float orc_audio_convert_unpack_s16_double_swap
112 #define orc_audio_convert_unpack_s32_be_float orc_audio_convert_unpack_s32_double
113 #define orc_audio_convert_unpack_s32_le_float orc_audio_convert_unpack_s32_double_swap
114 #define orc_audio_convert_pack_u8 orc_audio_convert_pack_u8
115 #define orc_audio_convert_pack_u16_be orc_audio_convert_pack_u16
116 #define orc_audio_convert_pack_u16_le orc_audio_convert_pack_u16_swap
117 #define orc_audio_convert_pack_s16_be orc_audio_convert_pack_s16
118 #define orc_audio_convert_pack_s16_le orc_audio_convert_pack_s16_swap
119 #define orc_audio_convert_pack_u32_be orc_audio_convert_pack_u32
120 #define orc_audio_convert_pack_u32_le orc_audio_convert_pack_u32_swap
121 #define orc_audio_convert_pack_s32_be orc_audio_convert_pack_s32
122 #define orc_audio_convert_pack_s32_le orc_audio_convert_pack_s32_swap
123 #define orc_audio_convert_pack_float_be orc_audio_convert_pack_s32_float
124 #define orc_audio_convert_pack_float_le orc_audio_convert_pack_s32_float_swap
125 #define orc_audio_convert_pack_double_be orc_audio_convert_pack_s32_double
126 #define orc_audio_convert_pack_double_le orc_audio_convert_pack_s32_double_swap
127 #define orc_audio_convert_pack_float_hq_be orc_audio_convert_pack_double_float
128 #define orc_audio_convert_pack_float_hq_le orc_audio_convert_pack_double_float_swap
129 #define orc_audio_convert_pack_s8_float orc_audio_convert_pack_double_s8
130 #define orc_audio_convert_pack_s16_be_float orc_audio_convert_pack_double_s16
131 #define orc_audio_convert_pack_s16_le_float orc_audio_convert_pack_double_s16_swap
132 #define orc_audio_convert_pack_s32_be_float orc_audio_convert_pack_double_s32
133 #define orc_audio_convert_pack_s32_le_float orc_audio_convert_pack_double_s32_swap
134 #define orc_audio_convert_pack_u8_float orc_audio_convert_pack_double_u8
135 #define orc_audio_convert_pack_u16_be_float orc_audio_convert_pack_double_u16
136 #define orc_audio_convert_pack_u16_le_float orc_audio_convert_pack_double_u16_swap
137 #define orc_audio_convert_pack_u32_be_float orc_audio_convert_pack_double_u32
138 #define orc_audio_convert_pack_u32_le_float orc_audio_convert_pack_double_u32_swap
139 #endif
140
141 /* sign bit in the intermediate format */
142 #define SIGNED  (1U<<31)
143
144 /*** 
145  * unpack code
146  */
147 #define MAKE_UNPACK_FUNC_NAME(name)                                     \
148 audio_convert_unpack_##name
149 #define MAKE_ORC_UNPACK_FUNC_NAME(name)                                 \
150 orc_audio_convert_unpack_##name
151
152 /* unpack from integer to signed integer 32 */
153 #define MAKE_UNPACK_FUNC_II(name, stride, sign, READ_FUNC)              \
154 static void                                                             \
155 MAKE_UNPACK_FUNC_NAME (name) (guint8 *src, gint32 *dst,                 \
156         gint scale, gint count)                                         \
157 {                                                                       \
158   for (;count; count--) {                                               \
159     *dst++ = (((gint32) READ_FUNC (src)) << scale) ^ (sign);            \
160     src+=stride;                                                        \
161   }                                                                     \
162 }
163
164 /* unpack from integer to signed integer 32 with orc */
165 #define MAKE_UNPACK_FUNC_ORC_II(name, stride, sign, READ_FUNC)             \
166 static void                                                             \
167 MAKE_UNPACK_FUNC_NAME (name) (guint8 *src, gint32 *dst,                 \
168         gint scale, gint count)                                         \
169 {                                                                       \
170   MAKE_ORC_UNPACK_FUNC_NAME (name) (dst, src, scale, count);            \
171 }
172
173 /* unpack from float to signed integer 32 */
174 #define MAKE_UNPACK_FUNC_FI(name, type, READ_FUNC)                            \
175 static void                                                                   \
176 MAKE_UNPACK_FUNC_NAME (name) (type * src, gint32 * dst, gint s, gint count)   \
177 {                                                                             \
178   gdouble temp;                                                               \
179                                                                               \
180   for (; count; count--) {                                                    \
181     /* blow up to 32 bit */                                                   \
182     temp = floor ((READ_FUNC (*src++) * 2147483647.0) + 0.5);                 \
183     *dst++ = (gint32) CLAMP (temp, G_MININT32, G_MAXINT32);                   \
184   }                                                                           \
185 }
186
187 /* unpack from float to signed integer 32 with orc */
188 #define MAKE_UNPACK_FUNC_ORC_FI(name, type, READ_FUNC)                        \
189 static void                                                                   \
190 MAKE_UNPACK_FUNC_NAME (name) (type * src, gint32 * dst, gint s, gint count)   \
191 {                                                                             \
192   MAKE_ORC_UNPACK_FUNC_NAME (name) ((guint32 *) dst, src, count);                         \
193 }
194
195 /* unpack from float to float 64 (double) */
196 #define MAKE_UNPACK_FUNC_FF(name, type, FUNC)                                 \
197 static void                                                                   \
198 MAKE_UNPACK_FUNC_NAME (name) (type * src, gdouble * dst, gint s,              \
199     gint count)                                                               \
200 {                                                                             \
201   for (; count; count--)                                                      \
202     *dst++ = (gdouble) FUNC (*src++);                                         \
203 }
204
205 /* unpack from float to float 64 (double) with orc */
206 #define MAKE_UNPACK_FUNC_ORC_FF(name, type, FUNC)                                 \
207 static void                                                                   \
208 MAKE_UNPACK_FUNC_NAME (name) (type * src, gdouble * dst, gint s,              \
209     gint count)                                                               \
210 {                                                                             \
211   MAKE_ORC_UNPACK_FUNC_NAME (name) ((gdouble *) dst, src, count);             \
212 }
213
214 /* unpack from int to float 64 (double) */
215 #define MAKE_UNPACK_FUNC_IF(name, stride, sign, READ_FUNC)                    \
216 static void                                                                   \
217 MAKE_UNPACK_FUNC_NAME (name) (guint8 * src, gdouble * dst, gint scale,        \
218     gint count)                                                               \
219 {                                                                             \
220   gdouble tmp;                                                                \
221   for (; count; count--) {                                                    \
222     tmp = (gdouble) ((((gint32) READ_FUNC (src)) << scale) ^ (sign));         \
223     *dst++ = tmp * (1.0 / 2147483647.0);                                      \
224     src += stride;                                                            \
225   }                                                                           \
226 }
227
228 #define MAKE_UNPACK_FUNC_ORC_IF(name, stride, sign, READ_FUNC)          \
229 static void                                                             \
230 MAKE_UNPACK_FUNC_NAME (name) (guint8 *src, gdouble *dst,                \
231         gint scale, gint count)                                         \
232 {                                                                       \
233   MAKE_ORC_UNPACK_FUNC_NAME (name) (dst, src, scale, count);            \
234 }
235
236 #define READ8(p)          GST_READ_UINT8(p)
237 #define READ16_FROM_LE(p) GST_READ_UINT16_LE (p)
238 #define READ16_FROM_BE(p) GST_READ_UINT16_BE (p)
239 #define READ24_FROM_LE(p) (p[0] | (p[1] << 8) | (p[2] << 16))
240 #define READ24_FROM_BE(p) (p[2] | (p[1] << 8) | (p[0] << 16))
241 #define READ32_FROM_LE(p) GST_READ_UINT32_LE (p)
242 #define READ32_FROM_BE(p) GST_READ_UINT32_BE (p)
243
244
245
246 MAKE_UNPACK_FUNC_ORC_II (u8, 1, SIGNED, READ8);
247 MAKE_UNPACK_FUNC_ORC_II (s8, 1, 0, READ8);
248 MAKE_UNPACK_FUNC_ORC_II (u16_le, 2, SIGNED, READ16_FROM_LE);
249 MAKE_UNPACK_FUNC_ORC_II (s16_le, 2, 0, READ16_FROM_LE);
250 MAKE_UNPACK_FUNC_ORC_II (u16_be, 2, SIGNED, READ16_FROM_BE);
251 MAKE_UNPACK_FUNC_ORC_II (s16_be, 2, 0, READ16_FROM_BE);
252 MAKE_UNPACK_FUNC_II (u24_le, 3, SIGNED, READ24_FROM_LE);
253 MAKE_UNPACK_FUNC_II (s24_le, 3, 0, READ24_FROM_LE);
254 MAKE_UNPACK_FUNC_II (u24_be, 3, SIGNED, READ24_FROM_BE);
255 MAKE_UNPACK_FUNC_II (s24_be, 3, 0, READ24_FROM_BE);
256 MAKE_UNPACK_FUNC_ORC_II (u32_le, 4, SIGNED, READ32_FROM_LE);
257 MAKE_UNPACK_FUNC_ORC_II (s32_le, 4, 0, READ32_FROM_LE);
258 MAKE_UNPACK_FUNC_ORC_II (u32_be, 4, SIGNED, READ32_FROM_BE);
259 MAKE_UNPACK_FUNC_ORC_II (s32_be, 4, 0, READ32_FROM_BE);
260 MAKE_UNPACK_FUNC_ORC_FI (float_le, gfloat, GFLOAT_FROM_LE);
261 MAKE_UNPACK_FUNC_ORC_FI (float_be, gfloat, GFLOAT_FROM_BE);
262 MAKE_UNPACK_FUNC_ORC_FI (double_le, gdouble, GDOUBLE_FROM_LE);
263 MAKE_UNPACK_FUNC_ORC_FI (double_be, gdouble, GDOUBLE_FROM_BE);
264 MAKE_UNPACK_FUNC_ORC_FF (float_hq_le, gfloat, GFLOAT_FROM_LE);
265 MAKE_UNPACK_FUNC_ORC_FF (float_hq_be, gfloat, GFLOAT_FROM_BE);
266 MAKE_UNPACK_FUNC_ORC_FF (double_hq_le, gdouble, GDOUBLE_FROM_LE);
267 MAKE_UNPACK_FUNC_ORC_FF (double_hq_be, gdouble, GDOUBLE_FROM_BE);
268 MAKE_UNPACK_FUNC_ORC_IF (u8_float, 1, SIGNED, READ8);
269 MAKE_UNPACK_FUNC_ORC_IF (s8_float, 1, 0, READ8);
270 MAKE_UNPACK_FUNC_ORC_IF (u16_le_float, 2, SIGNED, READ16_FROM_LE);
271 MAKE_UNPACK_FUNC_ORC_IF (s16_le_float, 2, 0, READ16_FROM_LE);
272 MAKE_UNPACK_FUNC_ORC_IF (u16_be_float, 2, SIGNED, READ16_FROM_BE);
273 MAKE_UNPACK_FUNC_ORC_IF (s16_be_float, 2, 0, READ16_FROM_BE);
274 MAKE_UNPACK_FUNC_IF (u24_le_float, 3, SIGNED, READ24_FROM_LE);
275 MAKE_UNPACK_FUNC_IF (s24_le_float, 3, 0, READ24_FROM_LE);
276 MAKE_UNPACK_FUNC_IF (u24_be_float, 3, SIGNED, READ24_FROM_BE);
277 MAKE_UNPACK_FUNC_IF (s24_be_float, 3, 0, READ24_FROM_BE);
278 MAKE_UNPACK_FUNC_ORC_IF (u32_le_float, 4, SIGNED, READ32_FROM_LE);
279 MAKE_UNPACK_FUNC_ORC_IF (s32_le_float, 4, 0, READ32_FROM_LE);
280 MAKE_UNPACK_FUNC_ORC_IF (u32_be_float, 4, SIGNED, READ32_FROM_BE);
281 MAKE_UNPACK_FUNC_ORC_IF (s32_be_float, 4, 0, READ32_FROM_BE);
282
283 /* One of the double_hq_* functions generated above is ineffecient, but it's
284  * never used anyway.  The same is true for one of the s32_* functions. */
285
286 /*** 
287  * packing code
288  */
289 #define MAKE_PACK_FUNC_NAME(name)                                       \
290 audio_convert_pack_##name
291 #define MAKE_PACK_FUNC_NAME_ORC(name)                                       \
292 orc_audio_convert_pack_##name
293
294 /*
295  * These functions convert the signed 32 bit integers to the
296  * target format. For this to work the following steps are done:
297  *
298  * 1) If the output format is unsigned we will XOR the sign bit. This
299  *    will do the same as if we add 1<<31.
300  * 2) Afterwards we shift to the target depth. It's necessary to left-shift
301  *    on signed values here to get arithmetical shifting.
302  * 3) This is then written into our target array by the corresponding write
303  *    function for the target width.
304  */
305
306 /* pack from signed integer 32 to integer using Orc */
307 #define MAKE_PACK_FUNC_ORC_II(name, stride, sign, WRITE_FUNC)           \
308 static void                                                             \
309 MAKE_PACK_FUNC_NAME (name) (gint32 *src, guint8 * dst,                  \
310         gint scale, gint count)                                         \
311 {                                                                       \
312   MAKE_PACK_FUNC_NAME_ORC (name) (dst, src, scale, count);              \
313 }
314
315 /* pack from signed integer 32 to integer */
316 #define MAKE_PACK_FUNC_II(name, stride, sign, WRITE_FUNC)               \
317 static void                                                             \
318 MAKE_PACK_FUNC_NAME (name) (gint32 *src, guint8 * dst,                  \
319         gint scale, gint count)                                         \
320 {                                                                       \
321   gint32 tmp;                                                           \
322   for (;count; count--) {                                               \
323     tmp = (*src++ ^ (sign)) >> scale;                                   \
324     WRITE_FUNC (dst, tmp);                                              \
325     dst += stride;                                                      \
326   }                                                                     \
327 }
328
329 /* pack from signed integer 32 to float using orc */
330 #define MAKE_PACK_FUNC_ORC_IF(name, type, FUNC)                         \
331 static void                                                             \
332 MAKE_PACK_FUNC_NAME (name) (gint32 * src, type * dst, gint scale,       \
333     gint count)                                                         \
334 {                                                                       \
335   MAKE_PACK_FUNC_NAME_ORC (name) (dst, src, count);                     \
336 }
337
338 /* pack from signed integer 32 to float */
339 #define MAKE_PACK_FUNC_IF(name, type, FUNC)                             \
340 static void                                                             \
341 MAKE_PACK_FUNC_NAME (name) (gint32 * src, type * dst, gint scale,       \
342     gint count)                                                         \
343 {                                                                       \
344   for (; count; count--)                                                \
345     *dst++ = FUNC ((type) ((*src++) * (1.0 / 2147483647.0)));           \
346 }
347
348 /* pack from float 64 (double) to float */
349 #define MAKE_PACK_FUNC_FF(name, type, FUNC)                             \
350 static void                                                             \
351 MAKE_PACK_FUNC_NAME (name) (gdouble * src, type * dst, gint s,          \
352     gint count)                                                         \
353 {                                                                       \
354   for (; count; count--)                                                \
355     *dst++ = FUNC ((type) (*src++));                                    \
356 }
357
358 /* pack from float 64 (double) to float with orc */
359 #define MAKE_PACK_FUNC_ORC_FF(name, type, FUNC)                             \
360 static void                                                             \
361 MAKE_PACK_FUNC_NAME (name) (gdouble * src, type * dst, gint s,          \
362     gint count)                                                         \
363 {                                                                       \
364   MAKE_PACK_FUNC_NAME_ORC (name) (dst, src, count);                     \
365 }
366
367 /* pack from float 64 (double) to signed int.
368  * the floats are already in the correct range. Only a cast is needed.
369  */
370 #define MAKE_PACK_FUNC_FI_S(name, stride, WRITE_FUNC)                   \
371 static void                                                             \
372 MAKE_PACK_FUNC_NAME (name) (gdouble * src, guint8 * dst, gint scale,    \
373     gint count)                                                         \
374 {                                                                       \
375   gint32 tmp;                                                           \
376   for (; count; count--) {                                              \
377     tmp = (gint32) (*src);                                              \
378     WRITE_FUNC (dst, tmp);                                              \
379     src++;                                                              \
380     dst += stride;                                                      \
381   }                                                                     \
382 }
383
384 /* pack from float 64 (double) to unsigned int.
385  * the floats are already in the correct range. Only a cast is needed
386  * and an addition of 2^(target_depth-1) to get in the correct unsigned
387  * range. */
388 #define MAKE_PACK_FUNC_FI_U(name, stride, WRITE_FUNC)                   \
389 static void                                                             \
390 MAKE_PACK_FUNC_NAME (name) (gdouble * src, guint8 * dst, gint scale,    \
391     gint count)                                                         \
392 {                                                                       \
393   guint32 tmp;                                                          \
394   gdouble limit = (1U<<(32-scale-1));                                   \
395   for (; count; count--) {                                              \
396     tmp = (guint32) (*src + limit);                                     \
397     WRITE_FUNC (dst, tmp);                                              \
398     src++;                                                              \
399     dst += stride;                                                      \
400   }                                                                     \
401 }
402
403 /* pack from float 64 (double) to signed int with orc.
404  * the floats are already in the correct range. Only a cast is needed.
405  */
406 #define MAKE_PACK_FUNC_ORC_FI_S(name, stride, WRITE_FUNC)               \
407 static void                                                             \
408 MAKE_PACK_FUNC_NAME (name) (gdouble * src, guint8 * dst, gint scale,    \
409     gint count)                                                         \
410 {                                                                       \
411   MAKE_PACK_FUNC_NAME_ORC (name) (dst, src, scale, count);              \
412 }
413
414 /* pack from float 64 (double) to unsigned int with orc.
415  * the floats are already in the correct range. Only a cast is needed.
416  */
417 #define MAKE_PACK_FUNC_ORC_FI_U(name, stride, WRITE_FUNC)               \
418 static void                                                             \
419 MAKE_PACK_FUNC_NAME (name) (gdouble * src, guint8 * dst, gint scale,    \
420     gint count)                                                         \
421 {                                                                       \
422   MAKE_PACK_FUNC_NAME_ORC (name) (dst, src, scale, count);              \
423 }
424
425 #define WRITE8(p, v)       GST_WRITE_UINT8 (p, v)
426 #define WRITE16_TO_LE(p,v) GST_WRITE_UINT16_LE (p, (guint16)(v))
427 #define WRITE16_TO_BE(p,v) GST_WRITE_UINT16_BE (p, (guint16)(v))
428 #define WRITE24_TO_LE(p,v) p[0] = v & 0xff; p[1] = (v >> 8) & 0xff; p[2] = (v >> 16) & 0xff
429 #define WRITE24_TO_BE(p,v) p[2] = v & 0xff; p[1] = (v >> 8) & 0xff; p[0] = (v >> 16) & 0xff
430 #define WRITE32_TO_LE(p,v) GST_WRITE_UINT32_LE (p, (guint32)(v))
431 #define WRITE32_TO_BE(p,v) GST_WRITE_UINT32_BE (p, (guint32)(v))
432
433 MAKE_PACK_FUNC_ORC_II (u8, 1, SIGNED, WRITE8);
434 MAKE_PACK_FUNC_ORC_II (s8, 1, 0, WRITE8);
435 MAKE_PACK_FUNC_ORC_II (u16_le, 2, SIGNED, WRITE16_TO_LE);
436 MAKE_PACK_FUNC_ORC_II (s16_le, 2, 0, WRITE16_TO_LE);
437 MAKE_PACK_FUNC_ORC_II (u16_be, 2, SIGNED, WRITE16_TO_BE);
438 MAKE_PACK_FUNC_ORC_II (s16_be, 2, 0, WRITE16_TO_BE);
439 MAKE_PACK_FUNC_II (u24_le, 3, SIGNED, WRITE24_TO_LE);
440 MAKE_PACK_FUNC_II (s24_le, 3, 0, WRITE24_TO_LE);
441 MAKE_PACK_FUNC_II (u24_be, 3, SIGNED, WRITE24_TO_BE);
442 MAKE_PACK_FUNC_II (s24_be, 3, 0, WRITE24_TO_BE);
443 MAKE_PACK_FUNC_ORC_II (u32_le, 4, SIGNED, WRITE32_TO_LE);
444 MAKE_PACK_FUNC_ORC_II (s32_le, 4, 0, WRITE32_TO_LE);
445 MAKE_PACK_FUNC_ORC_II (u32_be, 4, SIGNED, WRITE32_TO_BE);
446 MAKE_PACK_FUNC_ORC_II (s32_be, 4, 0, WRITE32_TO_BE);
447 MAKE_PACK_FUNC_ORC_IF (float_le, gfloat, GFLOAT_TO_LE);
448 MAKE_PACK_FUNC_ORC_IF (float_be, gfloat, GFLOAT_TO_BE);
449 MAKE_PACK_FUNC_ORC_IF (double_le, gdouble, GDOUBLE_TO_LE);
450 MAKE_PACK_FUNC_ORC_IF (double_be, gdouble, GDOUBLE_TO_BE);
451 MAKE_PACK_FUNC_ORC_FF (float_hq_le, gfloat, GFLOAT_TO_LE);
452 MAKE_PACK_FUNC_ORC_FF (float_hq_be, gfloat, GFLOAT_TO_BE);
453 MAKE_PACK_FUNC_ORC_FI_U (u8_float, 1, WRITE8);
454 MAKE_PACK_FUNC_ORC_FI_S (s8_float, 1, WRITE8);
455 MAKE_PACK_FUNC_ORC_FI_U (u16_le_float, 2, WRITE16_TO_LE);
456 MAKE_PACK_FUNC_ORC_FI_S (s16_le_float, 2, WRITE16_TO_LE);
457 MAKE_PACK_FUNC_ORC_FI_U (u16_be_float, 2, WRITE16_TO_BE);
458 MAKE_PACK_FUNC_ORC_FI_S (s16_be_float, 2, WRITE16_TO_BE);
459 MAKE_PACK_FUNC_FI_U (u24_le_float, 3, WRITE24_TO_LE);
460 MAKE_PACK_FUNC_FI_S (s24_le_float, 3, WRITE24_TO_LE);
461 MAKE_PACK_FUNC_FI_U (u24_be_float, 3, WRITE24_TO_BE);
462 MAKE_PACK_FUNC_FI_S (s24_be_float, 3, WRITE24_TO_BE);
463 MAKE_PACK_FUNC_ORC_FI_U (u32_le_float, 4, WRITE32_TO_LE);
464 MAKE_PACK_FUNC_ORC_FI_S (s32_le_float, 4, WRITE32_TO_LE);
465 MAKE_PACK_FUNC_ORC_FI_U (u32_be_float, 4, WRITE32_TO_BE);
466 MAKE_PACK_FUNC_ORC_FI_S (s32_be_float, 4, WRITE32_TO_BE);
467
468 /* For double_hq, packing and unpacking is the same, so we reuse the unpacking
469  * functions here. */
470 #define audio_convert_pack_double_hq_le MAKE_UNPACK_FUNC_NAME (double_hq_le)
471 #define audio_convert_pack_double_hq_be MAKE_UNPACK_FUNC_NAME (double_hq_be)
472
473 static AudioConvertUnpack unpack_funcs[] = {
474   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u8),
475   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s8),
476   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u8),
477   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s8),
478   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u16_le),
479   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s16_le),
480   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u16_be),
481   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s16_be),
482   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u24_le),
483   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s24_le),
484   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u24_be),
485   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s24_be),
486   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u32_le),
487   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s32_le),
488   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u32_be),
489   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s32_be),
490   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (float_le),
491   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (float_be),
492   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (double_le),
493   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (double_be),
494   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (float_hq_le),
495   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (float_hq_be),
496   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (double_hq_le),
497   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (double_hq_be),
498   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u8_float),
499   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s8_float),
500   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u8_float),
501   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s8_float),
502   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u16_le_float),
503   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s16_le_float),
504   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u16_be_float),
505   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s16_be_float),
506   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u24_le_float),
507   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s24_le_float),
508   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u24_be_float),
509   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s24_be_float),
510   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u32_le_float),
511   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s32_le_float),
512   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (u32_be_float),
513   (AudioConvertUnpack) MAKE_UNPACK_FUNC_NAME (s32_be_float),
514 };
515
516 static AudioConvertPack pack_funcs[] = {
517   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u8),
518   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s8),
519   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u8),
520   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s8),
521   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u16_le),
522   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s16_le),
523   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u16_be),
524   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s16_be),
525   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u24_le),
526   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s24_le),
527   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u24_be),
528   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s24_be),
529   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u32_le),
530   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s32_le),
531   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u32_be),
532   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s32_be),
533   (AudioConvertPack) MAKE_PACK_FUNC_NAME (float_le),
534   (AudioConvertPack) MAKE_PACK_FUNC_NAME (float_be),
535   (AudioConvertPack) MAKE_PACK_FUNC_NAME (double_le),
536   (AudioConvertPack) MAKE_PACK_FUNC_NAME (double_be),
537   (AudioConvertPack) MAKE_PACK_FUNC_NAME (float_hq_le),
538   (AudioConvertPack) MAKE_PACK_FUNC_NAME (float_hq_be),
539   (AudioConvertPack) MAKE_PACK_FUNC_NAME (double_hq_le),
540   (AudioConvertPack) MAKE_PACK_FUNC_NAME (double_hq_be),
541   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u8_float),
542   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s8_float),
543   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u8_float),
544   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s8_float),
545   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u16_le_float),
546   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s16_le_float),
547   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u16_be_float),
548   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s16_be_float),
549   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u24_le_float),
550   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s24_le_float),
551   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u24_be_float),
552   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s24_be_float),
553   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u32_le_float),
554   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s32_le_float),
555   (AudioConvertPack) MAKE_PACK_FUNC_NAME (u32_be_float),
556   (AudioConvertPack) MAKE_PACK_FUNC_NAME (s32_be_float),
557 };
558
559 #define DOUBLE_INTERMEDIATE_FORMAT(ctx)                                 \
560     ((!ctx->in.is_int && !ctx->out.is_int) || (ctx->ns != NOISE_SHAPING_NONE))
561
562 static gint
563 audio_convert_get_func_index (AudioConvertCtx * ctx, AudioConvertFmt * fmt)
564 {
565   gint index = 0;
566
567   if (fmt->is_int) {
568     index += (fmt->width / 8 - 1) * 4;
569     index += fmt->endianness == G_LITTLE_ENDIAN ? 0 : 2;
570     index += fmt->sign ? 1 : 0;
571     index += (ctx->ns == NOISE_SHAPING_NONE) ? 0 : 24;
572   } else {
573     /* this is float/double */
574     index = 16;
575     index += (fmt->width == 32) ? 0 : 2;
576     index += (fmt->endianness == G_LITTLE_ENDIAN) ? 0 : 1;
577     index += (DOUBLE_INTERMEDIATE_FORMAT (ctx)) ? 4 : 0;
578   }
579
580   return index;
581 }
582
583 static inline gboolean
584 check_default (AudioConvertCtx * ctx, AudioConvertFmt * fmt)
585 {
586   if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
587     return (fmt->width == 32 && fmt->depth == 32 &&
588         fmt->endianness == G_BYTE_ORDER && fmt->sign == TRUE);
589   } else {
590     return (fmt->width == 64 && fmt->endianness == G_BYTE_ORDER);
591   }
592 }
593
594 gboolean
595 audio_convert_clean_fmt (AudioConvertFmt * fmt)
596 {
597   g_return_val_if_fail (fmt != NULL, FALSE);
598
599   g_free (fmt->pos);
600   fmt->pos = NULL;
601
602   return TRUE;
603 }
604
605
606 gboolean
607 audio_convert_prepare_context (AudioConvertCtx * ctx, AudioConvertFmt * in,
608     AudioConvertFmt * out, GstAudioConvertDithering dither,
609     GstAudioConvertNoiseShaping ns)
610 {
611   gint idx_in, idx_out;
612
613   g_return_val_if_fail (ctx != NULL, FALSE);
614   g_return_val_if_fail (in != NULL, FALSE);
615   g_return_val_if_fail (out != NULL, FALSE);
616
617   /* first clean the existing context */
618   audio_convert_clean_context (ctx);
619
620   g_return_val_if_fail (in->unpositioned_layout == out->unpositioned_layout,
621       FALSE);
622
623   ctx->in = *in;
624   ctx->out = *out;
625
626   /* Don't dither or apply noise shaping if target depth is bigger than 20 bits
627    * as DA converters only can do a SNR up to 20 bits in reality.
628    * Also don't dither or apply noise shaping if target depth is larger than
629    * source depth. */
630   if (ctx->out.depth <= 20 && (!ctx->in.is_int
631           || ctx->in.depth >= ctx->out.depth)) {
632     ctx->dither = dither;
633     ctx->ns = ns;
634   } else {
635     ctx->dither = DITHER_NONE;
636     ctx->ns = NOISE_SHAPING_NONE;
637   }
638
639   /* Use simple error feedback when output sample rate is smaller than
640    * 32000 as the other methods might move the noise to audible ranges */
641   if (ctx->ns > NOISE_SHAPING_ERROR_FEEDBACK && ctx->out.rate < 32000)
642     ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK;
643
644   gst_channel_mix_setup_matrix (ctx);
645
646   idx_in = audio_convert_get_func_index (ctx, in);
647   ctx->unpack = unpack_funcs[idx_in];
648
649   idx_out = audio_convert_get_func_index (ctx, out);
650   ctx->pack = pack_funcs[idx_out];
651
652   /* if both formats are float/double or we use noise shaping use double as
653    * intermediate format and and switch mixing */
654   if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
655     GST_INFO ("use int mixing");
656     ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_int;
657   } else {
658     GST_INFO ("use float mixing");
659     ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_float;
660   }
661   GST_INFO ("unitsizes: %d -> %d", in->unit_size, out->unit_size);
662
663   /* check if input is in default format */
664   ctx->in_default = check_default (ctx, in);
665   /* check if channel mixer is passthrough */
666   ctx->mix_passthrough = gst_channel_mix_passthrough (ctx);
667   /* check if output is in default format */
668   ctx->out_default = check_default (ctx, out);
669
670   GST_INFO ("in default %d, mix passthrough %d, out default %d",
671       ctx->in_default, ctx->mix_passthrough, ctx->out_default);
672
673   ctx->in_scale = (in->is_int) ? (32 - in->depth) : 0;
674   ctx->out_scale = (out->is_int) ? (32 - out->depth) : 0;
675
676   gst_audio_quantize_setup (ctx);
677
678   return TRUE;
679 }
680
681 gboolean
682 audio_convert_clean_context (AudioConvertCtx * ctx)
683 {
684   g_return_val_if_fail (ctx != NULL, FALSE);
685
686   gst_audio_quantize_free (ctx);
687   audio_convert_clean_fmt (&ctx->in);
688   audio_convert_clean_fmt (&ctx->out);
689   gst_channel_mix_unset_matrix (ctx);
690
691   g_free (ctx->tmpbuf);
692   ctx->tmpbuf = NULL;
693   ctx->tmpbufsize = 0;
694
695   return TRUE;
696 }
697
698 gboolean
699 audio_convert_get_sizes (AudioConvertCtx * ctx, gint samples, gint * srcsize,
700     gint * dstsize)
701 {
702   g_return_val_if_fail (ctx != NULL, FALSE);
703
704   if (srcsize)
705     *srcsize = samples * ctx->in.unit_size;
706   if (dstsize)
707     *dstsize = samples * ctx->out.unit_size;
708
709   return TRUE;
710 }
711
712 gboolean
713 audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
714     gpointer dst, gint samples, gboolean src_writable)
715 {
716   guint insize, outsize, size;
717   gpointer outbuf, tmpbuf;
718   guint intemp = 0, outtemp = 0, biggest;
719
720   g_return_val_if_fail (ctx != NULL, FALSE);
721   g_return_val_if_fail (src != NULL, FALSE);
722   g_return_val_if_fail (dst != NULL, FALSE);
723   g_return_val_if_fail (samples >= 0, FALSE);
724
725   if (samples == 0)
726     return TRUE;
727
728   insize = ctx->in.unit_size * samples;
729   outsize = ctx->out.unit_size * samples;
730
731   /* find biggest temp buffer size */
732   size = (DOUBLE_INTERMEDIATE_FORMAT (ctx)) ? sizeof (gdouble)
733       : sizeof (gint32);
734
735   if (!ctx->in_default)
736     intemp = gst_util_uint64_scale (insize, size * 8, ctx->in.width);
737   if (!ctx->mix_passthrough || !ctx->out_default)
738     outtemp = gst_util_uint64_scale (outsize, size * 8, ctx->out.width);
739   biggest = MAX (intemp, outtemp);
740
741   /* see if one of the buffers can be used as temp */
742   if ((outsize >= biggest) && (ctx->out.unit_size <= size))
743     tmpbuf = dst;
744   else if ((insize >= biggest) && src_writable && (ctx->in.unit_size >= size))
745     tmpbuf = src;
746   else {
747     if (biggest > ctx->tmpbufsize) {
748       ctx->tmpbuf = g_realloc (ctx->tmpbuf, biggest);
749       ctx->tmpbufsize = biggest;
750     }
751     tmpbuf = ctx->tmpbuf;
752   }
753
754   /* start conversion */
755   if (!ctx->in_default) {
756     /* check if final conversion */
757     if (!(ctx->out_default && ctx->mix_passthrough))
758       outbuf = tmpbuf;
759     else
760       outbuf = dst;
761
762     /* unpack to default format */
763     ctx->unpack (src, outbuf, ctx->in_scale, samples * ctx->in.channels);
764
765     src = outbuf;
766   }
767
768   if (!ctx->mix_passthrough) {
769     /* check if final conversion */
770     if (!ctx->out_default)
771       outbuf = tmpbuf;
772     else
773       outbuf = dst;
774
775     /* convert channels */
776     ctx->channel_mix (ctx, src, outbuf, samples);
777
778     src = outbuf;
779   }
780
781   /* we only need to quantize if output format is int */
782   if (ctx->out.is_int) {
783     if (ctx->out_default)
784       outbuf = dst;
785     else
786       outbuf = tmpbuf;
787     ctx->quantize (ctx, src, outbuf, samples);
788   }
789
790   if (!ctx->out_default) {
791     /* pack default format into dst */
792     ctx->pack (src, dst, ctx->out_scale, samples * ctx->out.channels);
793   }
794
795   return TRUE;
796 }