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 DCA_CONTEXT_H
20 #define DCA_CONTEXT_H
21 
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 
26 /**@{*/
27 /** Make compact version code that can be compared easily */
28 #define DCADEC_VERSION_CODE(major, minor, patch) \
29     (((major) << 24) | ((minor) << 12) | (patch) | 0U)
30 
31 /**
32  * Version of libdcadec API. Major number gets bumped at each API change that
33  * breaks backward compatibility. Minor number gets bumped at each API change
34  * that remains compatible. Patch is reserved for non-API related changes.
35  */
36 #define DCADEC_API_VERSION_MAJOR    0
37 #define DCADEC_API_VERSION_MINOR    1
38 #define DCADEC_API_VERSION_PATCH    0
39 
40 #define DCADEC_API_VERSION \
41     DCADEC_VERSION_CODE(DCADEC_API_VERSION_MAJOR, \
42                         DCADEC_API_VERSION_MINOR, \
43                         DCADEC_API_VERSION_PATCH)
44 /**@}*/
45 
46 /**@{*/
47 #if (defined _WIN32)
48 #define DCADEC_SHARED_EXPORT    __declspec(dllexport)
49 #define DCADEC_SHARED_IMPORT    __declspec(dllimport)
50 #elif (__GNUC__ >= 4)
51 #define DCADEC_SHARED_EXPORT    __attribute__((visibility("default")))
52 #define DCADEC_SHARED_IMPORT    __attribute__((visibility("default")))
53 #else
54 #define DCADEC_SHARED_EXPORT
55 #define DCADEC_SHARED_IMPORT
56 #endif
57 
58 #ifdef DCADEC_SHARED
59 #ifdef DCADEC_INTERNAL
60 #define DCADEC_API  DCADEC_SHARED_EXPORT
61 #else
62 #define DCADEC_API  DCADEC_SHARED_IMPORT
63 #endif
64 #else
65 #define DCADEC_API
66 #endif
67 /**@}*/
68 
69 /**@{*/
70 #define DCADEC_EINVAL       1   /**< Invalid argument */
71 #define DCADEC_EBADDATA     2   /**< Invalid bitstream format */
72 #define DCADEC_EBADCRC      3   /**< CRC check failed */
73 #define DCADEC_EBADREAD     4   /**< Bitstream navigation error */
74 #define DCADEC_ENOSYNC      5   /**< Synchronization error */
75 #define DCADEC_ENOSUP       6   /**< Unsupported feature */
76 #define DCADEC_ENOMEM       7   /**< Memory allocation error */
77 #define DCADEC_EOVERFLOW    8   /**< PCM output overflow */
78 #define DCADEC_EIO          9   /**< I/O error */
79 #define DCADEC_EOUTCHG     10   /**< PCM output parameters changed */
80 #define DCADEC_EFAIL       32   /**< Unspecified error */
81 /**@}*/
82 
83 /**@{*/
84 #define DCADEC_WCOREAUXFAILED   1   /**< Failed to parse core auxiliary data */
85 #define DCADEC_WCOREEXTFAILED   2   /**< Failed to parse core extension */
86 #define DCADEC_WEXSSFAILED      3   /**< Failed to parse EXSS */
87 #define DCADEC_WXLLFAILED       4   /**< Failed to parse XLL */
88 #define DCADEC_WXLLSYNCERR      5   /**< XLL synchronization error */
89 #define DCADEC_WXLLBANDERR      6   /**< XLL frequency band error */
90 #define DCADEC_WXLLCONFERR      7   /**< XLL configuration error */
91 #define DCADEC_WXLLCLIPPED      8   /**< Clipping detected in XLL output */
92 #define DCADEC_WXLLLOSSY        9   /**< XLL output not lossless */
93 /**@}*/
94 
95 /**@{*/
96 /** Decode DTS core only without extensions */
97 #define DCADEC_FLAG_CORE_ONLY           0x01
98 
99 /** Force bit exact DTS core decoding */
100 #define DCADEC_FLAG_CORE_BIT_EXACT      0x02
101 
102 /**
103  * Force DTS core synthesis using X96 filter, with high frequency subbands set
104  * to zero. If actual X96 data is present, it is discarded when this flag is
105  * set. Effectively doubles output sample rate.
106  */
107 #define DCADEC_FLAG_CORE_SYNTH_X96      0x04
108 
109 /** Use IIR filter for floating point DTS core LFE channel interpolation */
110 #define DCADEC_FLAG_CORE_LFE_IIR        0x08
111 
112 /** Use FIR filter for floating point DTS core LFE channel interpolation */
113 #define DCADEC_FLAG_CORE_LFE_FIR        0x10
114 
115 /**
116  * Extract embedded 2.0 downmix if present (or perform 5.1 to 2.0 downmix if
117  * custom downmixing coefficients are present), otherwise extract 5.1 downmix.
118  */
119 #define DCADEC_FLAG_KEEP_DMIX_2CH       0x20
120 
121 /** Extract embedded 5.1 downmix (always present for 6.1 and 7.1 content) */
122 #define DCADEC_FLAG_KEEP_DMIX_6CH       0x40
123 
124 /** Output native DTS channel layout, not WAVEFORMATEXTENSIBLE layout */
125 #define DCADEC_FLAG_NATIVE_LAYOUT       0x80
126 
127 /** Don't conceal errors */
128 #define DCADEC_FLAG_STRICT              0x100
129 
130 /** Don't clip returned PCM samples to output bit depth */
131 #define DCADEC_FLAG_DONT_CLIP           0x200
132 /**@}*/
133 
134 /**@{*/
135 #define DCADEC_PROFILE_UNKNOWN  0       /**< Unknown Profile */
136 #define DCADEC_PROFILE_DS       0x01    /**< Digital Surround */
137 #define DCADEC_PROFILE_DS_96_24 0x02    /**< Digital Surround 96/24 */
138 #define DCADEC_PROFILE_DS_ES    0x04    /**< Digital Surround ES */
139 #define DCADEC_PROFILE_HD_HRA   0x08    /**< High Resolution Audio */
140 #define DCADEC_PROFILE_HD_MA    0x10    /**< Master Audio */
141 #define DCADEC_PROFILE_EXPRESS  0x20    /**< Express */
142 /**@}*/
143 
144 /**@{*/
145 /** Not matrix encoded */
146 #define DCADEC_MATRIX_ENCODING_NONE         0
147 
148 /**< Encoded for matrix surround decoding */
149 #define DCADEC_MATRIX_ENCODING_SURROUND     1
150 
151 /**< Audio processed for headphone playback */
152 #define DCADEC_MATRIX_ENCODING_HEADPHONE    2
153 /**@}*/
154 
155 /**@{*/
156 #define DCADEC_LOG_ERROR    0
157 #define DCADEC_LOG_WARNING  1
158 #define DCADEC_LOG_INFO     2
159 #define DCADEC_LOG_VERBOSE  3
160 #define DCADEC_LOG_DEBUG    4
161 /**@}*/
162 
163 /**
164  * Size in bytes of empty padding that must be present after the end of input
165  * buffer. libdcadec may overread the input buffer up to this number of bytes.
166  */
167 #define DCADEC_BUFFER_PADDING   8
168 
169 struct dcadec_context;
170 
171 struct dcadec_core_info {
172     int     nchannels;      /**< Number of primary audio channels */
173     int     audio_mode;     /**< Core audio channel arrangement (AMODE) */
174     int     lfe_present;    /**< LFE channel presence flag (can be 0, 1 or 2) */
175     int     sample_rate;    /**< Core audio sample rate in Hz */
176     int     source_pcm_res; /**< Source PCM resolution in bits */
177     bool    es_format;      /**< Extended surround (ES) mastering flag */
178     int     bit_rate;       /**< Core stream bit rate in bytes per second,
179                                  zero or negative if unavailable */
180     int     npcmblocks;     /**< Number of audio sample blocks in a frame */
181     bool    ext_audio_present;  /**< Extended audio present */
182     int     ext_audio_type;     /**< Extended audio type (only meaningful
183                                      when ext_audio_present is true) */
184 };
185 
186 struct dcadec_exss_info {
187     int nchannels;          /**< Number of audio channels encoded among all
188                                  extension sub-streams */
189     int sample_rate;        /**< Maximum encoded audio sample rate in Hz */
190     int bits_per_sample;    /**< Highest encoded PCM resolution in bits */
191     int profile;            /**< Type of DTS profile encoded */
192     bool embedded_stereo;   /**< 2.0 downmix has been embedded into the stream */
193     bool embedded_6ch;      /**< 5.1 downmix has been embedded into the stream */
194     int spkr_mask;          /**< Speaker activity mask, zero if unavailable */
195     int matrix_encoding;    /**< Matrix encoding type */
196 };
197 
198 typedef void (*dcadec_log_cb)(int level, const char *file, int line,
199                               const char *message, void *cbarg);
200 
201 /**
202  * Parse DTS packet. Packet data must be already converted into 16-bit
203  * big-endian format. Caller must have already established byte stream
204  * synchronization. Packet must start with a valid 32-bit sync word. EXSS frame
205  * must be aligned on 4-byte boundary if present in the packet.
206  *
207  * @param dca   Pointer to decoder context.
208  *
209  * @param data  Pointer to packet data buffer. Buffer must be aligned on 4-byte
210  *              boundary and padded at the end with DCADEC_BUFFER_PADDING bytes.
211  *
212  * @param size  Size in bytes of packet data. Size should not include padding.
213  *
214  * @return      0 or positive warning code on success, negative error code on
215  *              failure.
216  */
217 DCADEC_API int dcadec_context_parse(struct dcadec_context *dca, uint8_t *data, size_t size);
218 
219 /**
220  * Get information about DTS core payload of the parsed packet.
221  *
222  * @param dca   Pointer to decoder context.
223  *
224  * @return      Pointer to DTS core information structure on success,
225  *              NULL on failure. Returned data should be freed with
226  *              dcadec_context_free_core_info() function.
227  */
228 DCADEC_API struct dcadec_core_info *dcadec_context_get_core_info(struct dcadec_context *dca);
229 
230 /**
231  * Free DTS core information structure.
232  *
233  * @param info  Pointer to DTS core information structure.
234  */
235 DCADEC_API void dcadec_context_free_core_info(struct dcadec_core_info *info);
236 
237 /**
238  * Get information about extension sub-stream (EXSS) payload of the parsed
239  * packet. When no EXSS is present information about extended audio in core
240  * sub-stream is returned.
241  *
242  * @param dca   Pointer to decoder context.
243  *
244  * @return      Pointer to EXSS information structure on success,
245  *              NULL on failure. Returned data should be freed with
246  *              dcadec_context_free_exss_info() function.
247  */
248 DCADEC_API struct dcadec_exss_info *dcadec_context_get_exss_info(struct dcadec_context *dca);
249 
250 /**
251  * Free EXSS information structure.
252  *
253  * @param info  Pointer to EXSS information structure.
254  */
255 DCADEC_API void dcadec_context_free_exss_info(struct dcadec_exss_info *info);
256 
257 /**
258  * Filter the parsed packet and return per-channel PCM data. All parameters
259  * except decoder context are optional and can be NULL. This function should be
260  * called at least once after each successfull call to dcadec_context_parse().
261  * Multiple calls per packet are allowed and return the same data.
262  *
263  * @param dca       Pointer to decoder context.
264  *
265  * @param samples   Filled with address of array of pointers to planes
266  *                  containing PCM data for active channels. This data is valid
267  *                  until the next call to dcadec_context_parse() or _destroy().
268  *                  Returned array is tightly packed, there are no gaps for
269  *                  missing channels. Use channel_mask to determine total number
270  *                  of channels and size of returned array. By default channels
271  *                  are ordered according to WAVEFORMATEXTENSIBLE specification,
272  *                  but if DCADEC_FLAG_NATIVE_LAYOUT flag was set when creating
273  *                  decoder context, returned channels are in native DTS order.
274  *
275  * @param nsamples  Filled with number of PCM samples in each returned plane.
276  *
277  * @param channel_mask  Filled with bit mask indicating active channels. 1 at
278  *                      the given bit position (counting from the least
279  *                      significant bit) means that the channel is present in
280  *                      the array of pointers to planes, 0 otherwise. Number of
281  *                      bits set to 1 indicates the total number of planes
282  *                      returned.
283  *
284  * @param sample_rate       Filled with decoded audio sample rate in Hz.
285  *
286  * @param bits_per_sample   Filled with decoded audio PCM resolution in bits.
287  *
288  * @param profile           Filled with type of DTS profile actually decoded.
289  *                          This can be different from encoded profile since
290  *                          certain extensions may be not decoded.
291  *
292  * @return                  0 or positive warning code on success, negative
293  *                          error code on failure. Return value of 0 indicates
294  *                          that no errors affecting audio integrity were
295  *                          detected. When profile indicates Master Audio,
296  *                          positive return value indicates that audio has not
297  *                          been losslessly reconstructed for at least some part
298  *                          of this frame.
299  */
300 DCADEC_API int dcadec_context_filter(struct dcadec_context *dca, int ***samples,
301                                      int *nsamples, int *channel_mask,
302                                      int *sample_rate, int *bits_per_sample,
303                                      int *profile);
304 
305 /**
306  * Clear all inter-frame history of the decoder. Call this before parsing
307  * packets out of sequence, e.g. after seeking to the arbitrary position within
308  * the DTS stream.
309  *
310  * @param dca   Pointer to decoder context.
311  */
312 DCADEC_API void dcadec_context_clear(struct dcadec_context *dca);
313 
314 /**
315  * Create DTS decoder context.
316  *
317  * @param flags Any number of DCADEC_FLAG_* constants OR'ed together.
318  *
319  * @return      Pointer to decoder context on success, NULL on failure.
320  */
321 DCADEC_API struct dcadec_context *dcadec_context_create(int flags);
322 
323 /**
324  * Destroy DTS decoder context.
325  *
326  * @param dca   Pointer to decoder context.
327  */
328 DCADEC_API void dcadec_context_destroy(struct dcadec_context *dca);
329 
330 /**
331  * Set or clear logging callback for decoder context.
332  *
333  * @param dca       Pointer to decoder context.
334  *
335  * @param log_cb    Pointer to logging callback function. Pass NULL to disable
336  *                  logging.
337  *
338  * @param log_cbarg Opaque pointer that will be passed through to callback
339  *                  function.
340  */
341 DCADEC_API void dcadec_context_set_log_cb(struct dcadec_context *dca,
342                                           dcadec_log_cb log_cb,
343                                           void *log_cbarg);
344 
345 /**
346  * Convert negative libdcadec error code or positive warning code into string.
347  *
348  * @param errnum    Error or warning code returned by libdcadec function.
349  *
350  * @return          Constant string describing error or warning code.
351  */
352 DCADEC_API const char *dcadec_strerror(int errnum);
353 
354 /**
355  * Get libdcadec API version.
356  *
357  * @return  API version code of the currently running libdcadec.
358  */
359 DCADEC_API unsigned int dcadec_version(void);
360 
361 #endif
362