1 /*
2  * This file is part of libdcadec.
3  *
4  * This library is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by the
6  * Free Software Foundation; either version 2.1 of the License, or (at your
7  * option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #ifndef COMMON_H
20 #define COMMON_H
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <stdint.h>
25 #include <stdbool.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <math.h>
29 #include <errno.h>
30 #include <assert.h>
31 #include <limits.h>
32 
33 #include "compiler.h"
34 #include "dca_context.h"
35 #include "ta.h"
36 
37 #if AT_LEAST_GCC(3, 4)
38 #define dca_clz(x)  __builtin_clz(x)
39 #else
dca_clz(uint32_t x)40 static inline int dca_clz(uint32_t x)
41 {
42     int r = 0;
43 
44     assert(x);
45     if (x & 0xffff0000) { x >>= 16; r |= 16; }
46     if (x & 0x0000ff00) { x >>=  8; r |=  8; }
47     if (x & 0x000000f0) { x >>=  4; r |=  4; }
48     if (x & 0x0000000c) { x >>=  2; r |=  2; }
49     if (x & 0x00000002) { x >>=  1; r |=  1; }
50 
51     return 31 - r;
52 }
53 #endif
54 
55 #if (defined __GNUC__) && (defined __POPCNT__)
56 #define dca_popcount(x) __builtin_popcount(x)
57 #else
dca_popcount(uint32_t x)58 static inline int dca_popcount(uint32_t x)
59 {
60     x -= (x >> 1) & 0x55555555;
61     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
62     x = (x + (x >> 4)) & 0x0f0f0f0f;
63     x += x >> 8;
64     return (x + (x >> 16)) & 0x3f;
65 }
66 #endif
67 
68 #define dca_countof(x)  (sizeof(x) / sizeof((x)[0]))
69 
70 #if AT_LEAST_GCC(4, 8)
71 #define dca_bswap16(x)  __builtin_bswap16(x)
72 #else
dca_bswap16(uint16_t x)73 static inline uint16_t dca_bswap16(uint16_t x)
74 {
75     return (x << 8) | (x >> 8);
76 }
77 #endif
78 
79 #if AT_LEAST_GCC(4, 3)
80 #define dca_bswap32(x)  __builtin_bswap32(x)
81 #define dca_bswap64(x)  __builtin_bswap64(x)
82 #else
dca_bswap32(uint32_t x)83 static inline uint32_t dca_bswap32(uint32_t x)
84 {
85     x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
86     return (x << 16) | (x >> 16);
87 }
88 
dca_bswap64(uint64_t x)89 static inline uint64_t dca_bswap64(uint64_t x)
90 {
91     x = ((x & 0x00ff00ff00ff00ff) <<  8) | ((x & 0xff00ff00ff00ff00) >>  8);
92     x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
93     return (x << 32) | (x >> 32);
94 }
95 #endif
96 
97 #define DCA_BSWAP16_C(x)    ((((x) & 0x00ff)   <<  8) | (((x) & 0xff00)  >>  8))
98 #define DCA_BSWAP32_C(x)    ((DCA_BSWAP16_C(x) << 16) | (DCA_BSWAP16_C(x >> 16)))
99 #define DCA_BSWAP64_C(x)    ((DCA_BSWAP32_C(x) << 32) | (DCA_BSWAP32_C(x >> 32)))
100 
101 #if HAVE_BIGENDIAN
102 #define DCA_16LE(x) dca_bswap16(x)
103 #define DCA_32LE(x) dca_bswap32(x)
104 #define DCA_64LE(x) dca_bswap64(x)
105 #define DCA_16BE(x) ((uint16_t)(x))
106 #define DCA_32BE(x) ((uint32_t)(x))
107 #define DCA_64BE(x) ((uint64_t)(x))
108 #define DCA_16LE_C(x)   DCA_BSWAP16_C(x)
109 #define DCA_32LE_C(x)   DCA_BSWAP32_C(x)
110 #define DCA_64LE_C(x)   DCA_BSWAP64_C(x)
111 #define DCA_16BE_C(x)   (x)
112 #define DCA_32BE_C(x)   (x)
113 #define DCA_64BE_C(x)   (x)
114 #else
115 #define DCA_16LE(x) ((uint16_t)(x))
116 #define DCA_32LE(x) ((uint32_t)(x))
117 #define DCA_64LE(x) ((uint64_t)(x))
118 #define DCA_16BE(x) dca_bswap16(x)
119 #define DCA_32BE(x) dca_bswap32(x)
120 #define DCA_64BE(x) dca_bswap64(x)
121 #define DCA_16LE_C(x)   (x)
122 #define DCA_32LE_C(x)   (x)
123 #define DCA_64LE_C(x)   (x)
124 #define DCA_16BE_C(x)   DCA_BSWAP16_C(x)
125 #define DCA_32BE_C(x)   DCA_BSWAP32_C(x)
126 #define DCA_64BE_C(x)   DCA_BSWAP64_C(x)
127 #endif
128 
129 #define DCA_MIN(a, b)   ((a) < (b) ? (a) : (b))
130 #define DCA_MAX(a, b)   ((a) > (b) ? (a) : (b))
131 
132 #define DCA_ALIGN(value, align) \
133     (((value) + (align) - 1) & ~((align) - 1))
134 
135 #define DCA_MEM16BE(data) \
136     (((uint32_t)(data)[0] <<  8) | (data)[1])
137 
138 #define DCA_MEM24BE(data) \
139     (((uint32_t)(data)[0] << 16) | DCA_MEM16BE(&(data)[1]))
140 
141 #define DCA_MEM32BE(data) \
142     (((uint32_t)(data)[0] << 24) | DCA_MEM24BE(&(data)[1]))
143 
144 #define DCA_MEM40BE(data) \
145     (((uint64_t)(data)[0] << 32) | DCA_MEM32BE(&(data)[1]))
146 
DCA_MEM32NE(const void * data)147 static inline uint32_t DCA_MEM32NE(const void *data)
148 {
149     uint32_t res;
150     memcpy(&res, data, sizeof(res));
151     return res;
152 }
153 
154 void dca_format_log(struct dcadec_context *dca, int level,
155                     const char *file, int line, const char *fmt, ...)
156     __attribute__((format(printf, 5, 6)));
157 
158 #define DCADEC_LOG_ONCE     0x80000000
159 
160 #define dca_log(obj, lvl, ...) \
161     dca_format_log((obj)->ctx, DCADEC_LOG_##lvl, __FILE__, __LINE__, __VA_ARGS__)
162 
163 #define dca_log_once(obj, lvl, ...) \
164     dca_format_log((obj)->ctx, DCADEC_LOG_##lvl | DCADEC_LOG_ONCE, __FILE__, __LINE__, __VA_ARGS__)
165 
166 #define DCADEC_FLAG_KEEP_DMIX_MASK  \
167     (DCADEC_FLAG_KEEP_DMIX_2CH | DCADEC_FLAG_KEEP_DMIX_6CH)
168 
169 #define SPEAKER_LAYOUT_MONO         (SPEAKER_MASK_C)
170 #define SPEAKER_LAYOUT_STEREO       (SPEAKER_MASK_L | SPEAKER_MASK_R)
171 #define SPEAKER_LAYOUT_2POINT1      (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_LFE1)
172 #define SPEAKER_LAYOUT_3_0          (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_C)
173 #define SPEAKER_LAYOUT_2_1          (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_Cs)
174 #define SPEAKER_LAYOUT_3_1          (SPEAKER_LAYOUT_3_0 | SPEAKER_MASK_Cs)
175 #define SPEAKER_LAYOUT_2_2          (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_Ls | SPEAKER_MASK_Rs)
176 #define SPEAKER_LAYOUT_5POINT0      (SPEAKER_LAYOUT_3_0 | SPEAKER_MASK_Ls | SPEAKER_MASK_Rs)
177 #define SPEAKER_LAYOUT_7POINT0_WIDE (SPEAKER_LAYOUT_5POINT0 | SPEAKER_MASK_Lw | SPEAKER_MASK_Rw)
178 #define SPEAKER_LAYOUT_7POINT1_WIDE (SPEAKER_LAYOUT_7POINT0_WIDE | SPEAKER_MASK_LFE1)
179 
180 enum WaveTag {
181     TAG_RIFF    = 0x46464952,
182     TAG_WAVE    = 0x45564157,
183     TAG_data    = 0x61746164,
184     TAG_fmt     = 0x20746d66
185 };
186 
187 // WAVEFORMATEXTENSIBLE speakers
188 enum WaveSpeaker {
189     WAVESPKR_FL,  WAVESPKR_FR,  WAVESPKR_FC,  WAVESPKR_LFE,
190     WAVESPKR_BL,  WAVESPKR_BR,  WAVESPKR_FLC, WAVESPKR_FRC,
191     WAVESPKR_BC,  WAVESPKR_SL,  WAVESPKR_SR,  WAVESPKR_TC,
192     WAVESPKR_TFL, WAVESPKR_TFC, WAVESPKR_TFR, WAVESPKR_TBL,
193     WAVESPKR_TBC, WAVESPKR_TBR,
194 
195     WAVESPKR_COUNT
196 };
197 
198 // Table 6-22: Loudspeaker masks
199 enum SpeakerMask {
200     SPEAKER_MASK_C      = 0x00000001,
201     SPEAKER_MASK_L      = 0x00000002,
202     SPEAKER_MASK_R      = 0x00000004,
203     SPEAKER_MASK_Ls     = 0x00000008,
204     SPEAKER_MASK_Rs     = 0x00000010,
205     SPEAKER_MASK_LFE1   = 0x00000020,
206     SPEAKER_MASK_Cs     = 0x00000040,
207     SPEAKER_MASK_Lsr    = 0x00000080,
208     SPEAKER_MASK_Rsr    = 0x00000100,
209     SPEAKER_MASK_Lss    = 0x00000200,
210     SPEAKER_MASK_Rss    = 0x00000400,
211     SPEAKER_MASK_Lc     = 0x00000800,
212     SPEAKER_MASK_Rc     = 0x00001000,
213     SPEAKER_MASK_Lh     = 0x00002000,
214     SPEAKER_MASK_Ch     = 0x00004000,
215     SPEAKER_MASK_Rh     = 0x00008000,
216     SPEAKER_MASK_LFE2   = 0x00010000,
217     SPEAKER_MASK_Lw     = 0x00020000,
218     SPEAKER_MASK_Rw     = 0x00040000,
219     SPEAKER_MASK_Oh     = 0x00080000,
220     SPEAKER_MASK_Lhs    = 0x00100000,
221     SPEAKER_MASK_Rhs    = 0x00200000,
222     SPEAKER_MASK_Chr    = 0x00400000,
223     SPEAKER_MASK_Lhr    = 0x00800000,
224     SPEAKER_MASK_Rhr    = 0x01000000,
225     SPEAKER_MASK_Cl     = 0x02000000,
226     SPEAKER_MASK_Ll     = 0x04000000,
227     SPEAKER_MASK_Rl     = 0x08000000,
228     SPEAKER_MASK_RSV1   = 0x10000000,
229     SPEAKER_MASK_RSV2   = 0x20000000,
230     SPEAKER_MASK_RSV3   = 0x40000000,
231     SPEAKER_MASK_RSV4   = 0x80000000
232 };
233 
234 // Table 6-22: Loudspeaker masks
235 enum Speaker {
236     SPEAKER_C,    SPEAKER_L,    SPEAKER_R,    SPEAKER_Ls,
237     SPEAKER_Rs,   SPEAKER_LFE1, SPEAKER_Cs,   SPEAKER_Lsr,
238     SPEAKER_Rsr,  SPEAKER_Lss,  SPEAKER_Rss,  SPEAKER_Lc,
239     SPEAKER_Rc,   SPEAKER_Lh,   SPEAKER_Ch,   SPEAKER_Rh,
240     SPEAKER_LFE2, SPEAKER_Lw,   SPEAKER_Rw,   SPEAKER_Oh,
241     SPEAKER_Lhs,  SPEAKER_Rhs,  SPEAKER_Chr,  SPEAKER_Lhr,
242     SPEAKER_Rhr,  SPEAKER_Cl,   SPEAKER_Ll,   SPEAKER_Rl,
243     SPEAKER_RSV1, SPEAKER_RSV2, SPEAKER_RSV3, SPEAKER_RSV4,
244 
245     SPEAKER_COUNT
246 };
247 
248 // Table 7-1: Sync words
249 enum SyncWord {
250     SYNC_WORD_CORE      = 0x7ffe8001,
251     SYNC_WORD_CORE_LE   = 0xfe7f0180,
252     SYNC_WORD_CORE_LE14 = 0xff1f00e8,
253     SYNC_WORD_CORE_BE14 = 0x1fffe800,
254     SYNC_WORD_REV1AUX   = 0x9a1105a0,
255     SYNC_WORD_REV2AUX   = 0x7004c070,
256     SYNC_WORD_XCH       = 0x5a5a5a5a,
257     SYNC_WORD_XXCH      = 0x47004a03,
258     SYNC_WORD_X96       = 0x1d95f262,
259     SYNC_WORD_XBR       = 0x655e315e,
260     SYNC_WORD_LBR       = 0x0a801921,
261     SYNC_WORD_XLL       = 0x41a29547,
262     SYNC_WORD_EXSS      = 0x64582025,
263     SYNC_WORD_EXSS_LE   = 0x58642520,
264     SYNC_WORD_CORE_EXSS = 0x02b09261,
265 };
266 
267 // Table 7-10: Loudspeaker bit mask for speaker activity
268 enum SpeakerPair {
269     SPEAKER_PAIR_C      = 0x0001,
270     SPEAKER_PAIR_LR     = 0x0002,
271     SPEAKER_PAIR_LsRs   = 0x0004,
272     SPEAKER_PAIR_LFE1   = 0x0008,
273     SPEAKER_PAIR_Cs     = 0x0010,
274     SPEAKER_PAIR_LhRh   = 0x0020,
275     SPEAKER_PAIR_LsrRsr = 0x0040,
276     SPEAKER_PAIR_Ch     = 0x0080,
277     SPEAKER_PAIR_Oh     = 0x0100,
278     SPEAKER_PAIR_LcRc   = 0x0200,
279     SPEAKER_PAIR_LwRw   = 0x0400,
280     SPEAKER_PAIR_LssRss = 0x0800,
281     SPEAKER_PAIR_LFE2   = 0x1000,
282     SPEAKER_PAIR_LhsRhs = 0x2000,
283     SPEAKER_PAIR_Chr    = 0x4000,
284     SPEAKER_PAIR_LhrRhr = 0x8000,
285     SPEAKER_PAIR_ALL_1  = 0x5199,
286     SPEAKER_PAIR_ALL_2  = 0xae66
287 };
288 
289 // Table 7-11: Representation type
290 enum RepresentationType {
291     REPR_TYPE_LtRt  = 2,
292     REPR_TYPE_LhRh  = 3
293 };
294 
295 // Table 7-15: Core/extension mask
296 enum ExtensionMask {
297     CSS_CORE    = 0x001,
298     CSS_XXCH    = 0x002,
299     CSS_X96     = 0x004,
300     CSS_XCH     = 0x008,
301     EXSS_CORE   = 0x010,
302     EXSS_XBR    = 0x020,
303     EXSS_XXCH   = 0x040,
304     EXSS_X96    = 0x080,
305     EXSS_LBR    = 0x100,
306     EXSS_XLL    = 0x200,
307     EXSS_RSV1   = 0x400,
308     EXSS_RSV2   = 0x800
309 };
310 
311 // Table 8-8: Downmix type
312 enum DownMixType {
313     DMIX_TYPE_1_0,
314     DMIX_TYPE_LoRo,
315     DMIX_TYPE_LtRt,
316     DMIX_TYPE_3_0,
317     DMIX_TYPE_2_1,
318     DMIX_TYPE_2_2,
319     DMIX_TYPE_3_1,
320 
321     DMIX_TYPE_COUNT
322 };
323 
324 #endif
325