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