1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020           *
9  * by the Xiph.Org Foundation and contributors https://xiph.org/    *
10  *                                                                  *
11  ********************************************************************/
12 #if !defined(_opusfile_internal_h)
13 # define _opusfile_internal_h (1)
14 
15 # if !defined(_REENTRANT)
16 #  define _REENTRANT
17 # endif
18 # if !defined(_GNU_SOURCE)
19 #  define _GNU_SOURCE
20 # endif
21 # if !defined(_LARGEFILE_SOURCE)
22 #  define _LARGEFILE_SOURCE
23 # endif
24 # if !defined(_LARGEFILE64_SOURCE)
25 #  define _LARGEFILE64_SOURCE
26 # endif
27 # if !defined(_FILE_OFFSET_BITS)
28 #  define _FILE_OFFSET_BITS 64
29 # endif
30 
31 # include "opusfile.h"
32 
33 typedef struct OggOpusLink OggOpusLink;
34 
35 # if defined(OP_FIXED_POINT)
36 
37 typedef opus_int16 op_sample;
38 
39 # else
40 
41 typedef float      op_sample;
42 
43 /*We're using this define to test for libopus 1.1 or later until libopus
44    provides a better mechanism.*/
45 #  if defined(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST)
46 /*Enable soft clipping prevention in 16-bit decodes.*/
47 #   define OP_SOFT_CLIP (1)
48 #  endif
49 
50 # endif
51 
52 # if OP_GNUC_PREREQ(4,2)
53 /*Disable excessive warnings about the order of operations.*/
54 #  pragma GCC diagnostic ignored "-Wparentheses"
55 # elif defined(_MSC_VER)
56 /*Disable excessive warnings about the order of operations.*/
57 #  pragma warning(disable:4554)
58 /*Disable warnings about "deprecated" POSIX functions.*/
59 #  pragma warning(disable:4996)
60 # endif
61 
62 # if OP_GNUC_PREREQ(3,0)
63 /*Another alternative is
64     (__builtin_constant_p(_x)?!!(_x):__builtin_expect(!!(_x),1))
65    but that evaluates _x multiple times, which may be bad.*/
66 #  define OP_LIKELY(_x) (__builtin_expect(!!(_x),1))
67 #  define OP_UNLIKELY(_x) (__builtin_expect(!!(_x),0))
68 # else
69 #  define OP_LIKELY(_x)   (!!(_x))
70 #  define OP_UNLIKELY(_x) (!!(_x))
71 # endif
72 
73 # if defined(OP_ENABLE_ASSERTIONS)
74 #  if OP_GNUC_PREREQ(2,5)||__SUNPRO_C>=0x590
75 __attribute__((noreturn))
76 #  endif
77 void op_fatal_impl(const char *_str,const char *_file,int _line);
78 
79 #  define OP_FATAL(_str) (op_fatal_impl(_str,__FILE__,__LINE__))
80 
81 #  define OP_ASSERT(_cond) \
82   do{ \
83     if(OP_UNLIKELY(!(_cond)))OP_FATAL("assertion failed: " #_cond); \
84   } \
85   while(0)
86 #  define OP_ALWAYS_TRUE(_cond) OP_ASSERT(_cond)
87 
88 # else
89 #  define OP_FATAL(_str) abort()
90 #  define OP_ASSERT(_cond)
91 #  define OP_ALWAYS_TRUE(_cond) ((void)(_cond))
92 # endif
93 
94 # define OP_INT64_MAX (2*(((ogg_int64_t)1<<62)-1)|1)
95 # define OP_INT64_MIN (-OP_INT64_MAX-1)
96 # define OP_INT32_MAX (2*(((ogg_int32_t)1<<30)-1)|1)
97 # define OP_INT32_MIN (-OP_INT32_MAX-1)
98 
99 # define OP_MIN(_a,_b)        ((_a)<(_b)?(_a):(_b))
100 # define OP_MAX(_a,_b)        ((_a)>(_b)?(_a):(_b))
101 # define OP_CLAMP(_lo,_x,_hi) (OP_MAX(_lo,OP_MIN(_x,_hi)))
102 
103 /*Advance a file offset by the given amount, clamping against OP_INT64_MAX.
104   This is used to advance a known offset by things like OP_CHUNK_SIZE or
105    OP_PAGE_SIZE_MAX, while making sure to avoid signed overflow.
106   It assumes that both _offset and _amount are non-negative.*/
107 #define OP_ADV_OFFSET(_offset,_amount) \
108  (OP_MIN(_offset,OP_INT64_MAX-(_amount))+(_amount))
109 
110 /*The maximum channel count for any mapping we'll actually decode.*/
111 # define OP_NCHANNELS_MAX (8)
112 
113 /*Initial state.*/
114 # define  OP_NOTOPEN   (0)
115 /*We've found the first Opus stream in the first link.*/
116 # define  OP_PARTOPEN  (1)
117 # define  OP_OPENED    (2)
118 /*We've found the first Opus stream in the current link.*/
119 # define  OP_STREAMSET (3)
120 /*We've initialized the decoder for the chosen Opus stream in the current
121    link.*/
122 # define  OP_INITSET   (4)
123 
124 /*Information cached for a single link in a chained Ogg Opus file.
125   We choose the first Opus stream encountered in each link to play back (and
126    require at least one).*/
127 struct OggOpusLink{
128   /*The byte offset of the first header page in this link.*/
129   opus_int64   offset;
130   /*The byte offset of the first data page from the chosen Opus stream in this
131      link (after the headers).*/
132   opus_int64   data_offset;
133   /*The byte offset of the last page from the chosen Opus stream in this link.
134     This is used when seeking to ensure we find a page before the last one, so
135      that end-trimming calculations work properly.
136     This is only valid for seekable sources.*/
137   opus_int64   end_offset;
138   /*The total duration of all prior links.
139     This is always zero for non-seekable sources.*/
140   ogg_int64_t  pcm_file_offset;
141   /*The granule position of the last sample.
142     This is only valid for seekable sources.*/
143   ogg_int64_t  pcm_end;
144   /*The granule position before the first sample.*/
145   ogg_int64_t  pcm_start;
146   /*The serial number.*/
147   ogg_uint32_t serialno;
148   /*The contents of the info header.*/
149   OpusHead     head;
150   /*The contents of the comment header.*/
151   OpusTags     tags;
152 };
153 
154 struct OggOpusFile{
155   /*The callbacks used to access the stream.*/
156   OpusFileCallbacks  callbacks;
157   /*A FILE *, memory buffer, etc.*/
158   void              *stream;
159   /*Whether or not we can seek with this stream.*/
160   int                seekable;
161   /*The number of links in this chained Ogg Opus file.*/
162   int                nlinks;
163   /*The cached information from each link in a chained Ogg Opus file.
164     If stream isn't seekable (e.g., it's a pipe), only the current link
165      appears.*/
166   OggOpusLink       *links;
167   /*The number of serial numbers from a single link.*/
168   int                nserialnos;
169   /*The capacity of the list of serial numbers from a single link.*/
170   int                cserialnos;
171   /*Storage for the list of serial numbers from a single link.
172     This is a scratch buffer used when scanning the BOS pages at the start of
173      each link.*/
174   ogg_uint32_t      *serialnos;
175   /*This is the current offset of the data processed by the ogg_sync_state.
176     After a seek, this should be set to the target offset so that we can track
177      the byte offsets of subsequent pages.
178     After a call to op_get_next_page(), this will point to the first byte after
179      that page.*/
180   opus_int64         offset;
181   /*The total size of this stream, or -1 if it's unseekable.*/
182   opus_int64         end;
183   /*Used to locate pages in the stream.*/
184   ogg_sync_state     oy;
185   /*One of OP_NOTOPEN, OP_PARTOPEN, OP_OPENED, OP_STREAMSET, OP_INITSET.*/
186   int                ready_state;
187   /*The current link being played back.*/
188   int                cur_link;
189   /*The number of decoded samples to discard from the start of decoding.*/
190   opus_int32         cur_discard_count;
191   /*The granule position of the previous packet (current packet start time).*/
192   ogg_int64_t        prev_packet_gp;
193   /*The stream offset of the most recent page with completed packets, or -1.
194     This is only needed to recover continued packet data in the seeking logic,
195      when we use the current position as one of our bounds, only to later
196      discover it was the correct starting point.*/
197   opus_int64         prev_page_offset;
198   /*The number of bytes read since the last bitrate query, including framing.*/
199   opus_int64         bytes_tracked;
200   /*The number of samples decoded since the last bitrate query.*/
201   ogg_int64_t        samples_tracked;
202   /*Takes physical pages and welds them into a logical stream of packets.*/
203   ogg_stream_state   os;
204   /*Re-timestamped packets from a single page.
205     Buffering these relies on the undocumented libogg behavior that ogg_packet
206      pointers remain valid until the next page is submitted to the
207      ogg_stream_state they came from.*/
208   ogg_packet         op[255];
209   /*The index of the next packet to return.*/
210   int                op_pos;
211   /*The total number of packets available.*/
212   int                op_count;
213   /*Central working state for the packet-to-PCM decoder.*/
214   OpusMSDecoder     *od;
215   /*The application-provided packet decode callback.*/
216   op_decode_cb_func  decode_cb;
217   /*The application-provided packet decode callback context.*/
218   void              *decode_cb_ctx;
219   /*The stream count used to initialize the decoder.*/
220   int                od_stream_count;
221   /*The coupled stream count used to initialize the decoder.*/
222   int                od_coupled_count;
223   /*The channel count used to initialize the decoder.*/
224   int                od_channel_count;
225   /*The channel mapping used to initialize the decoder.*/
226   unsigned char      od_mapping[OP_NCHANNELS_MAX];
227   /*The buffered data for one decoded packet.*/
228   op_sample         *od_buffer;
229   /*The current position in the decoded buffer.*/
230   int                od_buffer_pos;
231   /*The number of valid samples in the decoded buffer.*/
232   int                od_buffer_size;
233   /*The type of gain offset to apply.
234     One of OP_HEADER_GAIN, OP_ALBUM_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/
235   int                gain_type;
236   /*The offset to apply to the gain.*/
237   opus_int32         gain_offset_q8;
238   /*Internal state for soft clipping and dithering float->short output.*/
239 #if !defined(OP_FIXED_POINT)
240 # if defined(OP_SOFT_CLIP)
241   float              clip_state[OP_NCHANNELS_MAX];
242 # endif
243   float              dither_a[OP_NCHANNELS_MAX*4];
244   float              dither_b[OP_NCHANNELS_MAX*4];
245   opus_uint32        dither_seed;
246   int                dither_mute;
247   int                dither_disabled;
248   /*The number of channels represented by the internal state.
249     This gets set to 0 whenever anything that would prevent state propagation
250      occurs (switching between the float/short APIs, or between the
251      stereo/multistream APIs).*/
252   int                state_channel_count;
253 #endif
254 };
255 
256 int op_strncasecmp(const char *_a,const char *_b,int _n);
257 
258 #endif
259