1 /* GStreamer
2 * Copyright (C) <2012> 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
26 #include "audio-format.h"
27
28 #include "gstaudiopack.h"
29
30 #ifdef HAVE_ORC
31 #include <orc/orcfunctions.h>
32 #else
33 #define orc_memset memset
34 #endif
35
36 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
37 # define audio_orc_unpack_s16le audio_orc_unpack_s16
38 # define audio_orc_unpack_s16le_trunc audio_orc_unpack_s16_trunc
39 # define audio_orc_unpack_s16be audio_orc_unpack_s16_swap
40 # define audio_orc_unpack_s16be_trunc audio_orc_unpack_s16_swap_trunc
41 # define audio_orc_unpack_u16le audio_orc_unpack_u16
42 # define audio_orc_unpack_u16le_trunc audio_orc_unpack_u16_trunc
43 # define audio_orc_unpack_u16be audio_orc_unpack_u16_swap
44 # define audio_orc_unpack_u16be_trunc audio_orc_unpack_u16_swap_trunc
45 # define audio_orc_unpack_s24_32le audio_orc_unpack_s24_32
46 # define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32_swap
47 # define audio_orc_unpack_u24_32le audio_orc_unpack_u24_32
48 # define audio_orc_unpack_u24_32be audio_orc_unpack_u24_32_swap
49 # define audio_orc_unpack_s32le audio_orc_unpack_s32
50 # define audio_orc_unpack_s32be audio_orc_unpack_s32_swap
51 # define audio_orc_unpack_u32le audio_orc_unpack_u32
52 # define audio_orc_unpack_u32be audio_orc_unpack_u32_swap
53 # define audio_orc_unpack_f32le audio_orc_unpack_f32
54 # define audio_orc_unpack_f32be audio_orc_unpack_f32_swap
55 # define audio_orc_unpack_f64le audio_orc_unpack_f64
56 # define audio_orc_unpack_f64be audio_orc_unpack_f64_swap
57 # define audio_orc_pack_s16le audio_orc_pack_s16
58 # define audio_orc_pack_s16be audio_orc_pack_s16_swap
59 # define audio_orc_pack_u16le audio_orc_pack_u16
60 # define audio_orc_pack_u16be audio_orc_pack_u16_swap
61 # define audio_orc_pack_s24_32le audio_orc_pack_s24_32
62 # define audio_orc_pack_s24_32be audio_orc_pack_s24_32_swap
63 # define audio_orc_pack_u24_32le audio_orc_pack_u24_32
64 # define audio_orc_pack_u24_32be audio_orc_pack_u24_32_swap
65 # define audio_orc_pack_s32le audio_orc_pack_s32
66 # define audio_orc_pack_s32be audio_orc_pack_s32_swap
67 # define audio_orc_pack_u32le audio_orc_pack_u32
68 # define audio_orc_pack_u32be audio_orc_pack_u32_swap
69 # define audio_orc_pack_f32le audio_orc_pack_f32
70 # define audio_orc_pack_f32be audio_orc_pack_f32_swap
71 # define audio_orc_pack_f64le audio_orc_pack_f64
72 # define audio_orc_pack_f64be audio_orc_pack_f64_swap
73 #else
74 # define audio_orc_unpack_s16le audio_orc_unpack_s16_swap
75 # define audio_orc_unpack_s16le_trunc audio_orc_unpack_s16_swap_trunc
76 # define audio_orc_unpack_s16be audio_orc_unpack_s16
77 # define audio_orc_unpack_s16be_trunc audio_orc_unpack_s16_trunc
78 # define audio_orc_unpack_u16le audio_orc_unpack_u16_swap
79 # define audio_orc_unpack_u16le_trunc audio_orc_unpack_u16_swap_trunc
80 # define audio_orc_unpack_u16be audio_orc_unpack_u16
81 # define audio_orc_unpack_u16be_trunc audio_orc_unpack_u16_trunc
82 # define audio_orc_unpack_s24_32le audio_orc_unpack_s24_32_swap
83 # define audio_orc_unpack_s24_32be audio_orc_unpack_s24_32
84 # define audio_orc_unpack_u24_32le audio_orc_unpack_u24_32_swap
85 # define audio_orc_unpack_u24_32be audio_orc_unpack_u24_32
86 # define audio_orc_unpack_s32le audio_orc_unpack_s32_swap
87 # define audio_orc_unpack_s32be audio_orc_unpack_s32
88 # define audio_orc_unpack_u32le audio_orc_unpack_u32_swap
89 # define audio_orc_unpack_u32be audio_orc_unpack_u32
90 # define audio_orc_unpack_f32le audio_orc_unpack_f32_swap
91 # define audio_orc_unpack_f32be audio_orc_unpack_f32
92 # define audio_orc_unpack_f64le audio_orc_unpack_f64_swap
93 # define audio_orc_unpack_f64be audio_orc_unpack_f64
94 # define audio_orc_pack_s16le audio_orc_pack_s16_swap
95 # define audio_orc_pack_s16be audio_orc_pack_s16
96 # define audio_orc_pack_u16le audio_orc_pack_u16_swap
97 # define audio_orc_pack_u16be audio_orc_pack_u16
98 # define audio_orc_pack_s24_32le audio_orc_pack_s24_32_swap
99 # define audio_orc_pack_s24_32be audio_orc_pack_s24_32
100 # define audio_orc_pack_u24_32le audio_orc_pack_u24_32_swap
101 # define audio_orc_pack_u24_32be audio_orc_pack_u24_32
102 # define audio_orc_pack_s32le audio_orc_pack_s32_swap
103 # define audio_orc_pack_s32be audio_orc_pack_s32
104 # define audio_orc_pack_u32le audio_orc_pack_u32_swap
105 # define audio_orc_pack_u32be audio_orc_pack_u32
106 # define audio_orc_pack_f32le audio_orc_pack_f32_swap
107 # define audio_orc_pack_f32be audio_orc_pack_f32
108 # define audio_orc_pack_f64le audio_orc_pack_f64_swap
109 # define audio_orc_pack_f64be audio_orc_pack_f64
110 #endif
111
112 #define MAKE_ORC_PACK_UNPACK(fmt,fmt_t) \
113 static void unpack_ ##fmt (const GstAudioFormatInfo *info, \
114 GstAudioPackFlags flags, gpointer dest, \
115 gconstpointer data, gint length) { \
116 if (flags & GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE) \
117 audio_orc_unpack_ ##fmt_t (dest, data, length); \
118 else \
119 audio_orc_unpack_ ##fmt (dest, data, length); \
120 } \
121 static void pack_ ##fmt (const GstAudioFormatInfo *info, \
122 GstAudioPackFlags flags, gconstpointer src, \
123 gpointer data, gint length) { \
124 audio_orc_pack_ ##fmt (data, src, length); \
125 }
126
127 #define PACK_S8 GST_AUDIO_FORMAT_S32, unpack_s8, pack_s8
128 MAKE_ORC_PACK_UNPACK (s8, s8_trunc)
129 #define PACK_U8 GST_AUDIO_FORMAT_S32, unpack_u8, pack_u8
130 MAKE_ORC_PACK_UNPACK (u8, u8_trunc)
131 #define PACK_S16LE GST_AUDIO_FORMAT_S32, unpack_s16le, pack_s16le
132 MAKE_ORC_PACK_UNPACK (s16le, s16le_trunc)
133 #define PACK_S16BE GST_AUDIO_FORMAT_S32, unpack_s16be, pack_s16be
134 MAKE_ORC_PACK_UNPACK (s16be, s16be_trunc)
135 #define PACK_U16LE GST_AUDIO_FORMAT_S32, unpack_u16le, pack_u16le
136 MAKE_ORC_PACK_UNPACK (u16le, u16le_trunc)
137 #define PACK_U16BE GST_AUDIO_FORMAT_S32, unpack_u16be, pack_u16be
138 MAKE_ORC_PACK_UNPACK (u16be, u16be_trunc)
139 #define PACK_S24_32LE GST_AUDIO_FORMAT_S32, unpack_s24_32le, pack_s24_32le
140 MAKE_ORC_PACK_UNPACK (s24_32le, s24_32le)
141 #define PACK_S24_32BE GST_AUDIO_FORMAT_S32, unpack_s24_32be, pack_s24_32be
142 MAKE_ORC_PACK_UNPACK (s24_32be, s24_32be)
143 #define PACK_U24_32LE GST_AUDIO_FORMAT_S32, unpack_u24_32le, pack_u24_32le
144 MAKE_ORC_PACK_UNPACK (u24_32le, u24_32le)
145 #define PACK_U24_32BE GST_AUDIO_FORMAT_S32, unpack_u24_32be, pack_u24_32be
146 MAKE_ORC_PACK_UNPACK (u24_32be, u24_32be)
147 #define PACK_S32LE GST_AUDIO_FORMAT_S32, unpack_s32le, pack_s32le
148 MAKE_ORC_PACK_UNPACK (s32le, s32le)
149 #define PACK_S32BE GST_AUDIO_FORMAT_S32, unpack_s32be, pack_s32be
150 MAKE_ORC_PACK_UNPACK (s32be, s32be)
151 #define PACK_U32LE GST_AUDIO_FORMAT_S32, unpack_u32le, pack_u32le
152 MAKE_ORC_PACK_UNPACK (u32le, u32le)
153 #define PACK_U32BE GST_AUDIO_FORMAT_S32, unpack_u32be, pack_u32be
154 MAKE_ORC_PACK_UNPACK (u32be, u32be)
155 #define SIGNED (1U<<31)
156 /* pack from signed integer 32 to integer */
157 #define WRITE24_TO_LE(p,v) p[0] = v & 0xff; p[1] = (v >> 8) & 0xff; p[2] = (v >> 16) & 0xff
158 #define WRITE24_TO_BE(p,v) p[2] = v & 0xff; p[1] = (v >> 8) & 0xff; p[0] = (v >> 16) & 0xff
159 #define READ24_FROM_LE(p) (p[0] | (p[1] << 8) | (p[2] << 16))
160 #define READ24_FROM_BE(p) (p[2] | (p[1] << 8) | (p[0] << 16))
161 #define MAKE_PACK_UNPACK(name, stride, sign, scale, READ_FUNC, WRITE_FUNC) \
162 static void unpack_ ##name (const GstAudioFormatInfo *info, \
163 GstAudioPackFlags flags, gpointer dest, \
164 gconstpointer data, gint length) \
165 { \
166 guint32 *d = dest; \
167 const guint8 *s = data; \
168 for (;length; length--) { \
169 *d++ = (((gint32) READ_FUNC (s)) << scale) ^ (sign); \
170 s += stride; \
171 } \
172 } \
173 static void pack_ ##name (const GstAudioFormatInfo *info, \
174 GstAudioPackFlags flags, gconstpointer src, \
175 gpointer data, gint length) \
176 { \
177 gint32 tmp; \
178 const guint32 *s = src; \
179 guint8 *d = data; \
180 for (;length; length--) { \
181 tmp = (*s++ ^ (sign)) >> scale; \
182 WRITE_FUNC (d, tmp); \
183 d += stride; \
184 } \
185 }
186 #define PACK_S24LE GST_AUDIO_FORMAT_S32, unpack_s24le, pack_s24le
187 MAKE_PACK_UNPACK (s24le, 3, 0, 8, READ24_FROM_LE, WRITE24_TO_LE)
188 #define PACK_U24LE GST_AUDIO_FORMAT_S32, unpack_u24le, pack_u24le
189 MAKE_PACK_UNPACK (u24le, 3, SIGNED, 8, READ24_FROM_LE, WRITE24_TO_LE)
190 #define PACK_S24BE GST_AUDIO_FORMAT_S32, unpack_s24be, pack_s24be
191 MAKE_PACK_UNPACK (s24be, 3, 0, 8, READ24_FROM_BE, WRITE24_TO_BE)
192 #define PACK_U24BE GST_AUDIO_FORMAT_S32, unpack_u24be, pack_u24be
193 MAKE_PACK_UNPACK (u24be, 3, SIGNED, 8, READ24_FROM_BE, WRITE24_TO_BE)
194 #define PACK_S20LE GST_AUDIO_FORMAT_S32, unpack_s20le, pack_s20le
195 MAKE_PACK_UNPACK (s20le, 3, 0, 12, READ24_FROM_LE, WRITE24_TO_LE)
196 #define PACK_U20LE GST_AUDIO_FORMAT_S32, unpack_u20le, pack_u20le
197 MAKE_PACK_UNPACK (u20le, 3, SIGNED, 12, READ24_FROM_LE, WRITE24_TO_LE)
198 #define PACK_S20BE GST_AUDIO_FORMAT_S32, unpack_s20be, pack_s20be
199 MAKE_PACK_UNPACK (s20be, 3, 0, 12, READ24_FROM_BE, WRITE24_TO_BE)
200 #define PACK_U20BE GST_AUDIO_FORMAT_S32, unpack_u20be, pack_u20be
201 MAKE_PACK_UNPACK (u20be, 3, SIGNED, 12, READ24_FROM_BE, WRITE24_TO_BE)
202 #define PACK_S18LE GST_AUDIO_FORMAT_S32, unpack_s18le, pack_s18le
203 MAKE_PACK_UNPACK (s18le, 3, 0, 14, READ24_FROM_LE, WRITE24_TO_LE)
204 #define PACK_U18LE GST_AUDIO_FORMAT_S32, unpack_u18le, pack_u18le
205 MAKE_PACK_UNPACK (u18le, 3, SIGNED, 14, READ24_FROM_LE, WRITE24_TO_LE)
206 #define PACK_S18BE GST_AUDIO_FORMAT_S32, unpack_s18be, pack_s18be
207 MAKE_PACK_UNPACK (s18be, 3, 0, 14, READ24_FROM_BE, WRITE24_TO_BE)
208 #define PACK_U18BE GST_AUDIO_FORMAT_S32, unpack_u18be, pack_u18be
209 MAKE_PACK_UNPACK (u18be, 3, SIGNED, 14, READ24_FROM_BE, WRITE24_TO_BE)
210 #define PACK_F32LE GST_AUDIO_FORMAT_F64, unpack_f32le, pack_f32le
211 MAKE_ORC_PACK_UNPACK (f32le, f32le)
212 #define PACK_F32BE GST_AUDIO_FORMAT_F64, unpack_f32be, pack_f32be
213 MAKE_ORC_PACK_UNPACK (f32be, f32be)
214 #define PACK_F64LE GST_AUDIO_FORMAT_F64, unpack_f64le, pack_f64le
215 MAKE_ORC_PACK_UNPACK (f64le, f64le)
216 #define PACK_F64BE GST_AUDIO_FORMAT_F64, unpack_f64be, pack_f64be
217 MAKE_ORC_PACK_UNPACK (f64be, f64be)
218 #define SINT (GST_AUDIO_FORMAT_FLAG_INTEGER | GST_AUDIO_FORMAT_FLAG_SIGNED)
219 #define SINT_PACK (SINT | GST_AUDIO_FORMAT_FLAG_UNPACK)
220 #define UINT (GST_AUDIO_FORMAT_FLAG_INTEGER)
221 #define FLOAT (GST_AUDIO_FORMAT_FLAG_FLOAT)
222 #define FLOAT_PACK (FLOAT | GST_AUDIO_FORMAT_FLAG_UNPACK)
223 #define MAKE_FORMAT(str,desc,flags,end,width,depth,silent, pack) \
224 { GST_AUDIO_FORMAT_ ##str, G_STRINGIFY(str), desc, flags, end, width, depth, silent, pack }
225 #define SILENT_0 { 0, 0, 0, 0, 0, 0, 0, 0 }
226 #define SILENT_U8 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }
227 #define SILENT_U16LE { 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80 }
228 #define SILENT_U16BE { 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }
229 #define SILENT_U24_32LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00 }
230 #define SILENT_U24_32BE { 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 }
231 #define SILENT_U32LE { 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 }
232 #define SILENT_U32BE { 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }
233 #define SILENT_U24LE { 0x00, 0x00, 0x80, 0x00, 0x00, 0x80 }
234 #define SILENT_U24BE { 0x80, 0x00, 0x00, 0x80, 0x00, 0x00 }
235 #define SILENT_U20LE { 0x00, 0x00, 0x08, 0x00, 0x00, 0x08 }
236 #define SILENT_U20BE { 0x08, 0x00, 0x00, 0x08, 0x00, 0x00 }
237 #define SILENT_U18LE { 0x00, 0x00, 0x02, 0x00, 0x00, 0x02 }
238 #define SILENT_U18BE { 0x02, 0x00, 0x00, 0x02, 0x00, 0x00 }
239 static const GstAudioFormatInfo formats[] = {
240 {GST_AUDIO_FORMAT_UNKNOWN, "UNKNOWN", "Unknown audio", 0, 0, 0, 0},
241 {GST_AUDIO_FORMAT_ENCODED, "ENCODED", "Encoded audio",
242 GST_AUDIO_FORMAT_FLAG_COMPLEX, 0, 0, 0},
243 /* 8 bit */
244 MAKE_FORMAT (S8, "8-bit signed PCM audio", SINT, 0, 8, 8, SILENT_0,
245 PACK_S8),
246 MAKE_FORMAT (U8, "8-bit unsigned PCM audio", UINT, 0, 8, 8, SILENT_U8,
247 PACK_U8),
248 /* 16 bit */
249 MAKE_FORMAT (S16LE, "16-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 16,
250 16,
251 SILENT_0, PACK_S16LE),
252 MAKE_FORMAT (S16BE, "16-bit signed PCM audio", SINT, G_BIG_ENDIAN, 16,
253 16,
254 SILENT_0, PACK_S16BE),
255 MAKE_FORMAT (U16LE, "16-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN,
256 16,
257 16, SILENT_U16LE, PACK_U16LE),
258 MAKE_FORMAT (U16BE, "16-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 16,
259 16,
260 SILENT_U16BE, PACK_U16BE),
261 /* 24 bit in low 3 bytes of 32 bits */
262 MAKE_FORMAT (S24_32LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN,
263 32,
264 24, SILENT_0, PACK_S24_32LE),
265 MAKE_FORMAT (S24_32BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32,
266 24,
267 SILENT_0, PACK_S24_32BE),
268 MAKE_FORMAT (U24_32LE, "24-bit unsigned PCM audio", UINT,
269 G_LITTLE_ENDIAN, 32,
270 24, SILENT_U24_32LE, PACK_U24_32LE),
271 MAKE_FORMAT (U24_32BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN,
272 32,
273 24, SILENT_U24_32BE, PACK_U24_32BE),
274 /* 32 bit */
275 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
276 MAKE_FORMAT (S32LE, "32-bit signed PCM audio", SINT_PACK,
277 G_LITTLE_ENDIAN, 32,
278 32, SILENT_0, PACK_S32LE),
279 MAKE_FORMAT (S32BE, "32-bit signed PCM audio", SINT, G_BIG_ENDIAN, 32,
280 32,
281 SILENT_0, PACK_S32BE),
282 #else
283 MAKE_FORMAT (S32LE, "32-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 32,
284 32,
285 SILENT_0, PACK_S32LE),
286 MAKE_FORMAT (S32BE, "32-bit signed PCM audio", SINT_PACK, G_BIG_ENDIAN,
287 32,
288 32,
289 SILENT_0, PACK_S32BE),
290 #endif
291 MAKE_FORMAT (U32LE, "32-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN,
292 32,
293 32, SILENT_U32LE, PACK_U32LE),
294 MAKE_FORMAT (U32BE, "32-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 32,
295 32,
296 SILENT_U32BE, PACK_U32BE),
297 /* 24 bit in 3 bytes */
298 MAKE_FORMAT (S24LE, "24-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24,
299 24,
300 SILENT_0, PACK_S24LE),
301 MAKE_FORMAT (S24BE, "24-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24,
302 24,
303 SILENT_0, PACK_S24BE),
304 MAKE_FORMAT (U24LE, "24-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN,
305 24,
306 24, SILENT_U24LE, PACK_U24LE),
307 MAKE_FORMAT (U24BE, "24-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24,
308 24,
309 SILENT_U24BE, PACK_U24BE),
310 /* 20 bit in 3 bytes */
311 MAKE_FORMAT (S20LE, "20-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24,
312 20,
313 SILENT_0, PACK_S20LE),
314 MAKE_FORMAT (S20BE, "20-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24,
315 20,
316 SILENT_0, PACK_S20BE),
317 MAKE_FORMAT (U20LE, "20-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN,
318 24,
319 20, SILENT_U20LE, PACK_U20LE),
320 MAKE_FORMAT (U20BE, "20-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24,
321 20,
322 SILENT_U20BE, PACK_U20BE),
323 /* 18 bit in 3 bytes */
324 MAKE_FORMAT (S18LE, "18-bit signed PCM audio", SINT, G_LITTLE_ENDIAN, 24,
325 18,
326 SILENT_0, PACK_S18LE),
327 MAKE_FORMAT (S18BE, "18-bit signed PCM audio", SINT, G_BIG_ENDIAN, 24,
328 18,
329 SILENT_0, PACK_S18BE),
330 MAKE_FORMAT (U18LE, "18-bit unsigned PCM audio", UINT, G_LITTLE_ENDIAN,
331 24,
332 18, SILENT_U18LE, PACK_U18LE),
333 MAKE_FORMAT (U18BE, "18-bit unsigned PCM audio", UINT, G_BIG_ENDIAN, 24,
334 18,
335 SILENT_U18BE, PACK_U18BE),
336 /* float */
337 MAKE_FORMAT (F32LE, "32-bit floating-point audio",
338 GST_AUDIO_FORMAT_FLAG_FLOAT, G_LITTLE_ENDIAN, 32, 32, SILENT_0,
339 PACK_F32LE),
340 MAKE_FORMAT (F32BE, "32-bit floating-point audio",
341 GST_AUDIO_FORMAT_FLAG_FLOAT, G_BIG_ENDIAN, 32, 32, SILENT_0,
342 PACK_F32BE),
343 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
344 MAKE_FORMAT (F64LE, "64-bit floating-point audio",
345 FLOAT_PACK, G_LITTLE_ENDIAN, 64, 64, SILENT_0, PACK_F64LE),
346 MAKE_FORMAT (F64BE, "64-bit floating-point audio",
347 FLOAT, G_BIG_ENDIAN, 64, 64, SILENT_0, PACK_F64BE)
348 #else
349 MAKE_FORMAT (F64LE, "64-bit floating-point audio",
350 FLOAT, G_LITTLE_ENDIAN, 64, 64, SILENT_0, PACK_F64LE),
351 MAKE_FORMAT (F64BE, "64-bit floating-point audio",
352 FLOAT_PACK, G_BIG_ENDIAN, 64, 64, SILENT_0, PACK_F64BE)
353 #endif
354 };
355
356 G_DEFINE_POINTER_TYPE (GstAudioFormatInfo, gst_audio_format_info);
357
358 /**
359 * gst_audio_format_build_integer:
360 * @sign: signed or unsigned format
361 * @endianness: G_LITTLE_ENDIAN or G_BIG_ENDIAN
362 * @width: amount of bits used per sample
363 * @depth: amount of used bits in @width
364 *
365 * Construct a #GstAudioFormat with given parameters.
366 *
367 * Returns: a #GstAudioFormat or GST_AUDIO_FORMAT_UNKNOWN when no audio format
368 * exists with the given parameters.
369 */
370 GstAudioFormat
gst_audio_format_build_integer(gboolean sign,gint endianness,gint width,gint depth)371 gst_audio_format_build_integer (gboolean sign, gint endianness,
372 gint width, gint depth)
373 {
374 gint i, e;
375
376 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
377 const GstAudioFormatInfo *finfo = &formats[i];
378
379 /* must be int */
380 if (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (finfo))
381 continue;
382
383 /* width and depth must match */
384 if (width != GST_AUDIO_FORMAT_INFO_WIDTH (finfo))
385 continue;
386 if (depth != GST_AUDIO_FORMAT_INFO_DEPTH (finfo))
387 continue;
388
389 /* if there is endianness, it must match */
390 e = GST_AUDIO_FORMAT_INFO_ENDIANNESS (finfo);
391 if (e && e != endianness)
392 continue;
393
394 /* check sign */
395 if ((sign && !GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)) ||
396 (!sign && GST_AUDIO_FORMAT_INFO_IS_SIGNED (finfo)))
397 continue;
398
399 return GST_AUDIO_FORMAT_INFO_FORMAT (finfo);
400 }
401 return GST_AUDIO_FORMAT_UNKNOWN;
402 }
403
404 /**
405 * gst_audio_format_from_string:
406 * @format: a format string
407 *
408 * Convert the @format string to its #GstAudioFormat.
409 *
410 * Returns: the #GstAudioFormat for @format or GST_AUDIO_FORMAT_UNKNOWN when the
411 * string is not a known format.
412 */
413 GstAudioFormat
gst_audio_format_from_string(const gchar * format)414 gst_audio_format_from_string (const gchar * format)
415 {
416 guint i;
417
418 g_return_val_if_fail (format != NULL, GST_AUDIO_FORMAT_UNKNOWN);
419
420 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
421 if (strcmp (GST_AUDIO_FORMAT_INFO_NAME (&formats[i]), format) == 0)
422 return GST_AUDIO_FORMAT_INFO_FORMAT (&formats[i]);
423 }
424 return GST_AUDIO_FORMAT_UNKNOWN;
425 }
426
427 const gchar *
gst_audio_format_to_string(GstAudioFormat format)428 gst_audio_format_to_string (GstAudioFormat format)
429 {
430 g_return_val_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN, NULL);
431
432 if ((gint) format >= G_N_ELEMENTS (formats))
433 return NULL;
434
435 return GST_AUDIO_FORMAT_INFO_NAME (&formats[format]);
436 }
437
438 /**
439 * gst_audio_format_get_info:
440 * @format: a #GstAudioFormat
441 *
442 * Get the #GstAudioFormatInfo for @format
443 *
444 * Returns: The #GstAudioFormatInfo for @format.
445 */
446 const GstAudioFormatInfo *
gst_audio_format_get_info(GstAudioFormat format)447 gst_audio_format_get_info (GstAudioFormat format)
448 {
449 g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
450
451 return &formats[format];
452 }
453
454 /**
455 * gst_audio_format_fill_silence:
456 * @info: a #GstAudioFormatInfo
457 * @dest: (array length=length) (element-type guint8): a destination
458 * to fill
459 * @length: the length to fill
460 *
461 * Fill @length bytes in @dest with silence samples for @info.
462 */
463 void
gst_audio_format_fill_silence(const GstAudioFormatInfo * info,gpointer dest,gsize length)464 gst_audio_format_fill_silence (const GstAudioFormatInfo * info,
465 gpointer dest, gsize length)
466 {
467 guint8 *dptr = dest;
468
469 g_return_if_fail (info != NULL);
470 g_return_if_fail (dest != NULL);
471
472 if (info->flags & GST_AUDIO_FORMAT_FLAG_FLOAT ||
473 info->flags & GST_AUDIO_FORMAT_FLAG_SIGNED) {
474 /* float or signed always 0 */
475 orc_memset (dest, 0, length);
476 } else {
477 gint i, j, bps = info->width >> 3;
478
479 switch (bps) {
480 case 1:
481 orc_memset (dest, info->silence[0], length);
482 break;
483 case 2:{
484 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
485 guint16 silence = GST_READ_UINT16_LE (info->silence);
486 #else
487 guint16 silence = GST_READ_UINT16_BE (info->silence);
488 #endif
489 audio_orc_splat_u16 (dest, silence, length / bps);
490 break;
491 }
492 case 4:{
493 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
494 guint32 silence = GST_READ_UINT32_LE (info->silence);
495 #else
496 guint32 silence = GST_READ_UINT32_BE (info->silence);
497 #endif
498 audio_orc_splat_u32 (dest, silence, length / bps);
499 break;
500 }
501 case 8:{
502 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
503 guint64 silence = GST_READ_UINT64_LE (info->silence);
504 #else
505 guint64 silence = GST_READ_UINT64_BE (info->silence);
506 #endif
507 audio_orc_splat_u64 (dest, silence, length / bps);
508 break;
509 }
510 default:
511 for (i = 0; i < length; i += bps) {
512 for (j = 0; j < bps; j++)
513 *dptr++ = info->silence[j];
514 }
515 break;
516 }
517 }
518 }
519