porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h
Go to the documentation of this file.
1 /*
2 FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
3 dr_flac - v0.12.6 - 2020-03-07
4 
5 David Reid - mackron@gmail.com
6 */
7 
8 /*
9 RELEASE NOTES - v0.12.0
10 =======================
11 Version 0.12.0 has breaking API changes including changes to the existing API and the removal of deprecated APIs.
12 
13 
14 Improved Client-Defined Memory Allocation
15 -----------------------------------------
16 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
17 existing system of DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE are still in place and will be used by default when no custom
18 allocation callbacks are specified.
19 
20 To use the new system, you pass in a pointer to a drflac_allocation_callbacks object to drflac_open() and family, like this:
21 
22  void* my_malloc(size_t sz, void* pUserData)
23  {
24  return malloc(sz);
25  }
26  void* my_realloc(void* p, size_t sz, void* pUserData)
27  {
28  return realloc(p, sz);
29  }
30  void my_free(void* p, void* pUserData)
31  {
32  free(p);
33  }
34 
35  ...
36 
37  drflac_allocation_callbacks allocationCallbacks;
38  allocationCallbacks.pUserData = &myData;
39  allocationCallbacks.onMalloc = my_malloc;
40  allocationCallbacks.onRealloc = my_realloc;
41  allocationCallbacks.onFree = my_free;
42  drflac* pFlac = drflac_open_file("my_file.flac", &allocationCallbacks);
43 
44 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
45 
46 Passing in null for the allocation callbacks object will cause dr_flac to use defaults which is the same as DRFLAC_MALLOC,
47 DRFLAC_REALLOC and DRFLAC_FREE and the equivalent of how it worked in previous versions.
48 
49 Every API that opens a drflac object now takes this extra parameter. These include the following:
50 
51  drflac_open()
52  drflac_open_relaxed()
53  drflac_open_with_metadata()
54  drflac_open_with_metadata_relaxed()
55  drflac_open_file()
56  drflac_open_file_with_metadata()
57  drflac_open_memory()
58  drflac_open_memory_with_metadata()
59  drflac_open_and_read_pcm_frames_s32()
60  drflac_open_and_read_pcm_frames_s16()
61  drflac_open_and_read_pcm_frames_f32()
62  drflac_open_file_and_read_pcm_frames_s32()
63  drflac_open_file_and_read_pcm_frames_s16()
64  drflac_open_file_and_read_pcm_frames_f32()
65  drflac_open_memory_and_read_pcm_frames_s32()
66  drflac_open_memory_and_read_pcm_frames_s16()
67  drflac_open_memory_and_read_pcm_frames_f32()
68 
69 
70 
71 Optimizations
72 -------------
73 Seeking performance has been greatly improved. A new binary search based seeking algorithm has been introduced which significantly
74 improves performance over the brute force method which was used when no seek table was present. Seek table based seeking also takes
75 advantage of the new binary search seeking system to further improve performance there as well. Note that this depends on CRC which
76 means it will be disabled when DR_FLAC_NO_CRC is used.
77 
78 The SSE4.1 pipeline has been cleaned up and optimized. You should see some improvements with decoding speed of 24-bit files in
79 particular. 16-bit streams should also see some improvement.
80 
81 drflac_read_pcm_frames_s16() has been optimized. Previously this sat on top of drflac_read_pcm_frames_s32() and performed it's s32
82 to s16 conversion in a second pass. This is now all done in a single pass. This includes SSE2 and ARM NEON optimized paths.
83 
84 A minor optimization has been implemented for drflac_read_pcm_frames_s32(). This will now use an SSE2 optimized pipeline for stereo
85 channel reconstruction which is the last part of the decoding process.
86 
87 The ARM build has seen a few improvements. The CLZ (count leading zeroes) and REV (byte swap) instructions are now used when
88 compiling with GCC and Clang which is achieved using inline assembly. The CLZ instruction requires ARM architecture version 5 at
89 compile time and the REV instruction requires ARM architecture version 6.
90 
91 An ARM NEON optimized pipeline has been implemented. To enable this you'll need to add -mfpu=neon to the command line when compiling.
92 
93 
94 Removed APIs
95 ------------
96 The following APIs were deprecated in version 0.11.0 and have been completely removed in version 0.12.0:
97 
98  drflac_read_s32() -> drflac_read_pcm_frames_s32()
99  drflac_read_s16() -> drflac_read_pcm_frames_s16()
100  drflac_read_f32() -> drflac_read_pcm_frames_f32()
101  drflac_seek_to_sample() -> drflac_seek_to_pcm_frame()
102  drflac_open_and_decode_s32() -> drflac_open_and_read_pcm_frames_s32()
103  drflac_open_and_decode_s16() -> drflac_open_and_read_pcm_frames_s16()
104  drflac_open_and_decode_f32() -> drflac_open_and_read_pcm_frames_f32()
105  drflac_open_and_decode_file_s32() -> drflac_open_file_and_read_pcm_frames_s32()
106  drflac_open_and_decode_file_s16() -> drflac_open_file_and_read_pcm_frames_s16()
107  drflac_open_and_decode_file_f32() -> drflac_open_file_and_read_pcm_frames_f32()
108  drflac_open_and_decode_memory_s32() -> drflac_open_memory_and_read_pcm_frames_s32()
109  drflac_open_and_decode_memory_s16() -> drflac_open_memory_and_read_pcm_frames_s16()
110  drflac_open_and_decode_memory_f32() -> drflac_open_memroy_and_read_pcm_frames_f32()
111 
112 Prior versions of dr_flac operated on a per-sample basis whereas now it operates on PCM frames. The removed APIs all relate
113 to the old per-sample APIs. You now need to use the "pcm_frame" versions.
114 */
115 
116 
117 /*
118 USAGE
119 =====
120 dr_flac is a single-file library. To use it, do something like the following in one .c file.
121 
122  #define DR_FLAC_IMPLEMENTATION
123  #include "dr_flac.h"
124 
125 You can then #include this file in other parts of the program as you would with any other header file. To decode audio data,
126 do something like the following:
127 
128  drflac* pFlac = drflac_open_file("MySong.flac", NULL);
129  if (pFlac == NULL) {
130  // Failed to open FLAC file
131  }
132 
133  drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32));
134  drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples);
135 
136 The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of
137 channels and the bits per sample, should be directly accessible - just make sure you don't change their values. Samples are
138 always output as interleaved signed 32-bit PCM. In the example above a native FLAC stream was opened, however dr_flac has
139 seamless support for Ogg encapsulated FLAC streams as well.
140 
141 You do not need to decode the entire stream in one go - you just specify how many samples you'd like at any given time and
142 the decoder will give you as many samples as it can, up to the amount requested. Later on when you need the next batch of
143 samples, just call it again. Example:
144 
145  while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) {
146  do_something();
147  }
148 
149 You can seek to a specific sample with drflac_seek_to_sample(). The given sample is based on interleaving. So for example,
150 if you were to seek to the sample at index 0 in a stereo stream, you'll be seeking to the first sample of the left channel.
151 The sample at index 1 will be the first sample of the right channel. The sample at index 2 will be the second sample of the
152 left channel, etc.
153 
154 
155 If you just want to quickly decode an entire FLAC file in one go you can do something like this:
156 
157  unsigned int channels;
158  unsigned int sampleRate;
159  drflac_uint64 totalPCMFrameCount;
160  drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount, NULL);
161  if (pSampleData == NULL) {
162  // Failed to open and decode FLAC file.
163  }
164 
165  ...
166 
167  drflac_free(pSampleData);
168 
169 
170 You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs
171 respectively, but note that these should be considered lossy.
172 
173 
174 If you need access to metadata (album art, etc.), use drflac_open_with_metadata(), drflac_open_file_with_metdata() or
175 drflac_open_memory_with_metadata(). The rationale for keeping these APIs separate is that they're slightly slower than the
176 normal versions and also just a little bit harder to use.
177 
178 dr_flac reports metadata to the application through the use of a callback, and every metadata block is reported before
179 drflac_open_with_metdata() returns.
180 
181 
182 The main opening APIs (drflac_open(), etc.) will fail if the header is not present. The presents a problem in certain
183 scenarios such as broadcast style streams or internet radio where the header may not be present because the user has
184 started playback mid-stream. To handle this, use the relaxed APIs: drflac_open_relaxed() and drflac_open_with_metadata_relaxed().
185 
186 It is not recommended to use these APIs for file based streams because a missing header would usually indicate a
187 corrupt or perverse file. In addition, these APIs can take a long time to initialize because they may need to spend
188 a lot of time finding the first frame.
189 
190 
191 
192 OPTIONS
193 =======
194 #define these options before including this file.
195 
196 #define DR_FLAC_NO_STDIO
197  Disable drflac_open_file() and family.
198 
199 #define DR_FLAC_NO_OGG
200  Disables support for Ogg/FLAC streams.
201 
202 #define DR_FLAC_BUFFER_SIZE <number>
203  Defines the size of the internal buffer to store data from onRead(). This buffer is used to reduce the number of calls
204  back to the client for more data. Larger values means more memory, but better performance. My tests show diminishing
205  returns after about 4KB (which is the default). Consider reducing this if you have a very efficient implementation of
206  onRead(), or increase it if it's very inefficient. Must be a multiple of 8.
207 
208 #define DR_FLAC_NO_CRC
209  Disables CRC checks. This will offer a performance boost when CRC is unnecessary. This will disable binary search seeking.
210  When seeking, the seek table will be used if available. Otherwise the seek will be performed using brute force.
211 
212 #define DR_FLAC_NO_SIMD
213  Disables SIMD optimizations (SSE on x86/x64 architectures, NEON on ARM architectures). Use this if you are having
214  compatibility issues with your compiler.
215 
216 
217 
218 QUICK NOTES
219 ===========
220 - dr_flac does not currently support changing the sample rate nor channel count mid stream.
221 - This has not been tested on big-endian architectures.
222 - dr_flac is not thread-safe, but its APIs can be called from any thread so long as you do your own synchronization.
223 - When using Ogg encapsulation, a corrupted metadata block will result in drflac_open_with_metadata() and drflac_open()
224  returning inconsistent samples.
225 */
226 
227 #ifndef dr_flac_h
228 #define dr_flac_h
229 
230 #include <stddef.h>
231 
232 #if defined(_MSC_VER) && _MSC_VER < 1600
233 typedef signed char drflac_int8;
234 typedef unsigned char drflac_uint8;
235 typedef signed short drflac_int16;
236 typedef unsigned short drflac_uint16;
237 typedef signed int drflac_int32;
238 typedef unsigned int drflac_uint32;
239 typedef signed __int64 drflac_int64;
240 typedef unsigned __int64 drflac_uint64;
241 #else
242 #include <stdint.h>
243 typedef int8_t drflac_int8;
244 typedef uint8_t drflac_uint8;
245 typedef int16_t drflac_int16;
246 typedef uint16_t drflac_uint16;
247 typedef int32_t drflac_int32;
248 typedef uint32_t drflac_uint32;
249 typedef int64_t drflac_int64;
250 typedef uint64_t drflac_uint64;
251 #endif
254 #define DRFLAC_TRUE 1
255 #define DRFLAC_FALSE 0
256 
257 #if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */
258  #define DRFLAC_DEPRECATED __declspec(deprecated)
259 #elif (defined(__GNUC__) && __GNUC__ >= 4) /* GCC 4 */
260  #define DRFLAC_DEPRECATED __attribute__((deprecated))
261 #elif defined(__has_feature) /* Clang */
262  #if __has_feature(attribute_deprecated)
263  #define DRFLAC_DEPRECATED __attribute__((deprecated))
264  #else
265  #define DRFLAC_DEPRECATED
266  #endif
267 #else
268  #define DRFLAC_DEPRECATED
269 #endif
270 
271 /*
272 As data is read from the client it is placed into an internal buffer for fast access. This controls the
273 size of that buffer. Larger values means more speed, but also more memory. In my testing there is diminishing
274 returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8.
275 */
276 #ifndef DR_FLAC_BUFFER_SIZE
277 #define DR_FLAC_BUFFER_SIZE 4096
278 #endif
279 
280 #ifdef __cplusplus
281 extern "C" {
282 #endif
283 
284 /* Check if we can enable 64-bit optimizations. */
285 #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
286 #define DRFLAC_64BIT
287 #endif
288 
289 #ifdef DRFLAC_64BIT
291 #else
293 #endif
294 
295 /* The various metadata block types. */
296 #define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO 0
297 #define DRFLAC_METADATA_BLOCK_TYPE_PADDING 1
298 #define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION 2
299 #define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3
300 #define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4
301 #define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET 5
302 #define DRFLAC_METADATA_BLOCK_TYPE_PICTURE 6
303 #define DRFLAC_METADATA_BLOCK_TYPE_INVALID 127
304 
305 /* The various picture types specified in the PICTURE block. */
306 #define DRFLAC_PICTURE_TYPE_OTHER 0
307 #define DRFLAC_PICTURE_TYPE_FILE_ICON 1
308 #define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON 2
309 #define DRFLAC_PICTURE_TYPE_COVER_FRONT 3
310 #define DRFLAC_PICTURE_TYPE_COVER_BACK 4
311 #define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE 5
312 #define DRFLAC_PICTURE_TYPE_MEDIA 6
313 #define DRFLAC_PICTURE_TYPE_LEAD_ARTIST 7
314 #define DRFLAC_PICTURE_TYPE_ARTIST 8
315 #define DRFLAC_PICTURE_TYPE_CONDUCTOR 9
316 #define DRFLAC_PICTURE_TYPE_BAND 10
317 #define DRFLAC_PICTURE_TYPE_COMPOSER 11
318 #define DRFLAC_PICTURE_TYPE_LYRICIST 12
319 #define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION 13
320 #define DRFLAC_PICTURE_TYPE_DURING_RECORDING 14
321 #define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE 15
322 #define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE 16
323 #define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17
324 #define DRFLAC_PICTURE_TYPE_ILLUSTRATION 18
325 #define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE 19
326 #define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20
327 
328 typedef enum
329 {
334 
335 typedef enum
336 {
340 
341 /* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */
342 #pragma pack(2)
343 typedef struct
344 {
345  drflac_uint64 firstPCMFrame;
346  drflac_uint64 flacFrameOffset; /* The offset from the first byte of the header of the first frame. */
347  drflac_uint16 pcmFrameCount;
349 #pragma pack()
350 
351 typedef struct
352 {
353  drflac_uint16 minBlockSizeInPCMFrames;
354  drflac_uint16 maxBlockSizeInPCMFrames;
355  drflac_uint32 minFrameSizeInPCMFrames;
356  drflac_uint32 maxFrameSizeInPCMFrames;
357  drflac_uint32 sampleRate;
358  drflac_uint8 channels;
359  drflac_uint8 bitsPerSample;
360  drflac_uint64 totalPCMFrameCount;
361  drflac_uint8 md5[16];
363 
364 typedef struct
365 {
366  /* The metadata type. Use this to know how to interpret the data below. */
367  drflac_uint32 type;
368 
369  /*
370  A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
371  not modify the contents of this buffer. Use the structures below for more meaningful and structured
372  information about the metadata. It's possible for this to be null.
373  */
374  const void* pRawData;
375 
376  /* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
377  drflac_uint32 rawDataSize;
378 
379  union
380  {
381  drflac_streaminfo streaminfo;
382 
383  struct
384  {
385  int unused;
386  } padding;
387 
388  struct
389  {
390  drflac_uint32 id;
391  const void* pData;
392  drflac_uint32 dataSize;
393  } application;
394 
395  struct
396  {
397  drflac_uint32 seekpointCount;
398  const drflac_seekpoint* pSeekpoints;
399  } seektable;
400 
401  struct
402  {
403  drflac_uint32 vendorLength;
404  const char* vendor;
405  drflac_uint32 commentCount;
406  const void* pComments;
407  } vorbis_comment;
408 
409  struct
410  {
411  char catalog[128];
412  drflac_uint64 leadInSampleCount;
413  drflac_bool32 isCD;
414  drflac_uint8 trackCount;
415  const void* pTrackData;
416  } cuesheet;
417 
418  struct
419  {
420  drflac_uint32 type;
421  drflac_uint32 mimeLength;
422  const char* mime;
423  drflac_uint32 descriptionLength;
424  const char* description;
425  drflac_uint32 width;
426  drflac_uint32 height;
427  drflac_uint32 colorDepth;
428  drflac_uint32 indexColorCount;
429  drflac_uint32 pictureDataSize;
430  const drflac_uint8* pPictureData;
431  } picture;
432  } data;
434 
435 
436 /*
437 Callback for when data needs to be read from the client.
438 
439 pUserData [in] The user data that was passed to drflac_open() and family.
440 pBufferOut [out] The output buffer.
441 bytesToRead [in] The number of bytes to read.
442 
443 Returns the number of bytes actually read.
444 
445 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
446 either the entire bytesToRead is filled or you have reached the end of the stream.
447 */
448 typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
449 
450 /*
451 Callback for when data needs to be seeked.
452 
453 pUserData [in] The user data that was passed to drflac_open() and family.
454 offset [in] The number of bytes to move, relative to the origin. Will never be negative.
455 origin [in] The origin of the seek - the current position or the start of the stream.
456 
457 Returns whether or not the seek was successful.
458 
459 The offset will never be negative. Whether or not it is relative to the beginning or current position is determined
460 by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current.
461 
462 When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of
463 the FLAC stream. This needs to be detected and handled by returning DRFLAC_FALSE.
464 */
465 typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
466 
467 /*
468 Callback for when a metadata block is read.
469 
470 pUserData [in] The user data that was passed to drflac_open() and family.
471 pMetadata [in] A pointer to a structure containing the data of the metadata block.
472 
473 Use pMetadata->type to determine which metadata block is being handled and how to read the data.
474 */
475 typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
476 
477 
478 typedef struct
479 {
480  void* pUserData;
481  void* (* onMalloc)(size_t sz, void* pUserData);
482  void* (* onRealloc)(void* p, size_t sz, void* pUserData);
483  void (* onFree)(void* p, void* pUserData);
485 
486 /* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
487 typedef struct
488 {
489  const drflac_uint8* data;
490  size_t dataSize;
491  size_t currentReadPos;
493 
494 /* Structure for internal use. Used for bit streaming. */
495 typedef struct
496 {
497  /* The function to call when more data needs to be read. */
498  drflac_read_proc onRead;
499 
500  /* The function to call when the current read position needs to be moved. */
501  drflac_seek_proc onSeek;
502 
503  /* The user data to pass around to onRead and onSeek. */
504  void* pUserData;
505 
506 
507  /*
508  The number of unaligned bytes in the L2 cache. This will always be 0 until the end of the stream is hit. At the end of the
509  stream there will be a number of bytes that don't cleanly fit in an L1 cache line, so we use this variable to know whether
510  or not the bistreamer needs to run on a slower path to read those last bytes. This will never be more than sizeof(drflac_cache_t).
511  */
512  size_t unalignedByteCount;
513 
514  /* The content of the unaligned bytes. */
515  drflac_cache_t unalignedCache;
516 
517  /* The index of the next valid cache line in the "L2" cache. */
518  drflac_uint32 nextL2Line;
519 
520  /* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */
521  drflac_uint32 consumedBits;
522 
523  /*
524  The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
525  Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
526  */
528  drflac_cache_t cache;
529 
530  /*
531  CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
532  is reset to 0 at the beginning of each frame.
533  */
534  drflac_uint16 crc16;
535  drflac_cache_t crc16Cache; /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
536  drflac_uint32 crc16CacheIgnoredBytes; /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
537 } drflac_bs;
538 
539 typedef struct
540 {
541  /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
542  drflac_uint8 subframeType;
543 
544  /* The number of wasted bits per sample as specified by the sub-frame header. */
545  drflac_uint8 wastedBitsPerSample;
546 
547  /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
548  drflac_uint8 lpcOrder;
549 
550  /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
551  drflac_int32* pSamplesS32;
553 
554 typedef struct
555 {
556  /*
557  If the stream uses variable block sizes, this will be set to the index of the first PCM frame. If fixed block sizes are used, this will
558  always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
559  */
560  drflac_uint64 pcmFrameNumber;
561 
562  /*
563  If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. This
564  is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
565  */
566  drflac_uint32 flacFrameNumber;
567 
568  /* The sample rate of this frame. */
569  drflac_uint32 sampleRate;
570 
571  /* The number of PCM frames in each sub-frame within this frame. */
572  drflac_uint16 blockSizeInPCMFrames;
573 
574  /*
575  The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
576  will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
577  */
578  drflac_uint8 channelAssignment;
579 
580  /* The number of bits per sample within this frame. */
581  drflac_uint8 bitsPerSample;
582 
583  /* The frame's CRC. */
584  drflac_uint8 crc8;
586 
587 typedef struct
588 {
589  /* The header. */
591 
592  /*
593  The number of PCM frames left to be read in this FLAC frame. This is initially set to the block size. As PCM frames are read,
594  this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
595  */
596  drflac_uint32 pcmFramesRemaining;
597 
598  /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */
599  drflac_subframe subframes[8];
600 } drflac_frame;
601 
602 typedef struct
603 {
604  /* The function to call when a metadata block is read. */
605  drflac_meta_proc onMeta;
606 
607  /* The user data posted to the metadata callback function. */
608  void* pUserDataMD;
609 
610  /* Memory allocation callbacks. */
611  drflac_allocation_callbacks allocationCallbacks;
612 
613 
614  /* The sample rate. Will be set to something like 44100. */
615  drflac_uint32 sampleRate;
616 
617  /*
618  The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. Maximum 8. This is set based on the
619  value specified in the STREAMINFO block.
620  */
621  drflac_uint8 channels;
622 
623  /* The bits per sample. Will be set to something like 16, 24, etc. */
624  drflac_uint8 bitsPerSample;
625 
626  /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */
627  drflac_uint16 maxBlockSizeInPCMFrames;
628 
629  /*
630  The total number of PCM Frames making up the stream. Can be 0 in which case it's still a valid stream, but just means
631  the total PCM frame count is unknown. Likely the case with streams like internet radio.
632  */
633  drflac_uint64 totalPCMFrameCount;
634 
635 
636  /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */
637  drflac_container container;
638 
639  /* The number of seekpoints in the seektable. */
640  drflac_uint32 seekpointCount;
641 
642 
643  /* Information about the frame the decoder is currently sitting on. */
644  drflac_frame currentFLACFrame;
645 
646 
647  /* The index of the PCM frame the decoder is currently sitting on. This is only used for seeking. */
648  drflac_uint64 currentPCMFrame;
649 
650  /* The position of the first FLAC frame in the stream. This is only ever used for seeking. */
651  drflac_uint64 firstFLACFramePosInBytes;
652 
653 
654  /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */
655  drflac__memory_stream memoryStream;
656 
657 
658  /* A pointer to the decoded sample data. This is an offset of pExtraData. */
659  drflac_int32* pDecodedSamples;
660 
661  /* A pointer to the seek table. This is an offset of pExtraData, or NULL if there is no seek table. */
662  drflac_seekpoint* pSeekpoints;
663 
664  /* Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData. */
665  void* _oggbs;
666 
667  /* Internal use only. Used for profiling and testing different seeking modes. */
668  drflac_bool32 _noSeekTableSeek : 1;
669  drflac_bool32 _noBinarySearchSeek : 1;
670  drflac_bool32 _noBruteForceSeek : 1;
671 
672  /* The bit streamer. The raw FLAC data is fed through this object. */
673  drflac_bs bs;
674 
675  /* Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs. */
676  drflac_uint8 pExtraData[1];
677 } drflac;
678 
679 /*
680 Opens a FLAC decoder.
681 
682 onRead [in] The function to call when data needs to be read from the client.
683 onSeek [in] The function to call when the read position of the client data needs to move.
684 pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
685 pAllocationCallbacks [in, optional] A pointer to application defined callbacks for managing memory allocations.
686 
687 Returns a pointer to an object representing the decoder.
688 
689 Close the decoder with drflac_close().
690 
691 pAllocationCallbacks can be NULL in which case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
692 
693 This function will automatically detect whether or not you are attempting to open a native or Ogg encapsulated
694 FLAC, both of which should work seamlessly without any manual intervention. Ogg encapsulation also works with
695 multiplexed streams which basically means it can play FLAC encoded audio tracks in videos.
696 
697 This is the lowest level function for opening a FLAC stream. You can also use drflac_open_file() and drflac_open_memory()
698 to open the stream from a file or from a block of memory respectively.
699 
700 The STREAMINFO block must be present for this to succeed. Use drflac_open_relaxed() to open a FLAC stream where
701 the header may not be present.
702 
703 See also: drflac_open_file(), drflac_open_memory(), drflac_open_with_metadata(), drflac_close()
704 */
705 drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
706 
707 /*
708 The same as drflac_open(), except attempts to open the stream even when a header block is not present.
709 
710 Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do
711 not set this to drflac_container_unknown - that is for internal use only.
712 
713 Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never
714 found it will continue forever. To abort, force your onRead callback to return 0, which dr_flac will use as an
715 indicator that the end of the stream was found.
716 */
717 drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
718 
719 /*
720 Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
721 
722 onRead [in] The function to call when data needs to be read from the client.
723 onSeek [in] The function to call when the read position of the client data needs to move.
724 onMeta [in] The function to call for every metadata block.
725 pUserData [in, optional] A pointer to application defined data that will be passed to onRead, onSeek and onMeta.
726 pAllocationCallbacks [in, optional] A pointer to application defined callbacks for managing memory allocations.
727 
728 Returns a pointer to an object representing the decoder.
729 
730 Close the decoder with drflac_close().
731 
732 pAllocationCallbacks can be NULL in which case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
733 
734 This is slower than drflac_open(), so avoid this one if you don't need metadata. Internally, this will allocate and free
735 memory on the heap for every metadata block except for STREAMINFO and PADDING blocks.
736 
737 The caller is notified of the metadata via the onMeta callback. All metadata blocks will be handled before the function
738 returns.
739 
740 The STREAMINFO block must be present for this to succeed. Use drflac_open_with_metadata_relaxed() to open a FLAC
741 stream where the header may not be present.
742 
743 Note that this will behave inconsistently with drflac_open() if the stream is an Ogg encapsulated stream and a metadata
744 block is corrupted. This is due to the way the Ogg stream recovers from corrupted pages. When drflac_open_with_metadata()
745 is being used, the open routine will try to read the contents of the metadata block, whereas drflac_open() will simply
746 seek past it (for the sake of efficiency). This inconsistency can result in different samples being returned depending on
747 whether or not the stream is being opened with metadata.
748 
749 See also: drflac_open_file_with_metadata(), drflac_open_memory_with_metadata(), drflac_open(), drflac_close()
750 */
751 drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
752 
753 /*
754 The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present.
755 
756 See also: drflac_open_with_metadata(), drflac_open_relaxed()
757 */
758 drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
759 
760 /*
761 Closes the given FLAC decoder.
762 
763 pFlac [in] The decoder to close.
764 
765 This will destroy the decoder object.
766 */
767 void drflac_close(drflac* pFlac);
768 
769 
770 /*
771 Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM.
772 
773 pFlac [in] The decoder.
774 framesToRead [in] The number of PCM frames to read.
775 pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples.
776 
777 Returns the number of PCM frames actually read.
778 
779 pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames
780 seeked.
781 */
783 
784 /*
785 Same as drflac_read_pcm_frames_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit.
786 
787 Note that this is lossy for streams where the bits per sample is larger than 16.
788 */
790 
791 /*
792 Same as drflac_read_pcm_frames_s32(), except outputs samples as 32-bit floating-point PCM.
793 
794 Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly
795 represent every possible number.
796 */
797 drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
798 
799 /*
800 Seeks to the PCM frame at the given index.
801 
802 pFlac [in] The decoder.
803 pcmFrameIndex [in] The index of the PCM frame to seek to. See notes below.
804 
805 Returns DRFLAC_TRUE if successful; DRFLAC_FALSE otherwise.
806 */
808 
809 
810 
811 #ifndef DR_FLAC_NO_STDIO
812 /*
813 Opens a FLAC decoder from the file at the given path.
814 
815 filename [in] The path of the file to open, either absolute or relative to the current directory.
816 pAllocationCallbacks [in, optional] A pointer to application defined callbacks for managing memory allocations.
817 
818 Returns a pointer to an object representing the decoder.
819 
820 Close the decoder with drflac_close().
821 
822 This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the
823 number of files a process can have open at any given time, so keep this mind if you have many decoders open at the
824 same time.
825 
826 See also: drflac_open(), drflac_open_file_with_metadata(), drflac_close()
827 */
828 drflac* drflac_open_file(const char* filename, const drflac_allocation_callbacks* pAllocationCallbacks);
829 
830 /*
831 Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.)
832 
833 Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
834 */
835 drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
836 #endif
837 
838 /*
839 Opens a FLAC decoder from a pre-allocated block of memory
840 
841 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
842 the lifetime of the decoder.
843 */
844 drflac* drflac_open_memory(const void* data, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
845 
846 /*
847 Opens a FLAC decoder from a pre-allocated block of memory and notifies the caller of the metadata chunks (album art, etc.)
848 
849 Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
850 */
851 drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
852 
853 
854 
855 /* High Level APIs */
856 
857 /*
858 Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a
859 pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().
860 
861 You can pass in custom memory allocation callbacks via the pAllocationCallbacks parameter. This can be NULL in which
862 case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
863 
864 Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
865 read samples into a dynamically sized buffer on the heap until no samples are left.
866 
867 Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
868 */
869 drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
870 
871 /* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
872 drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
873 
874 /* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
875 float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
876 
877 #ifndef DR_FLAC_NO_STDIO
878 /* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
879 drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
880 
881 /* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
882 drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
883 
884 /* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
885 float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
886 #endif
887 
888 /* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
889 drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
890 
891 /* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
892 drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
893 
894 /* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
895 float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
896 
897 /*
898 Frees memory that was allocated internally by dr_flac.
899 
900 Set pAllocationCallbacks to the same object that was passed to drflac_open_*_and_read_pcm_frames_*(). If you originally passed in NULL, pass in NULL for this.
901 */
902 void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
903 
904 
905 /* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */
906 typedef struct
907 {
908  drflac_uint32 countRemaining;
909  const char* pRunningData;
911 
912 /*
913 Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT
914 metadata block.
915 */
916 void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
917 
918 /*
919 Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The
920 returned string is NOT null terminated.
921 */
922 const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
923 
924 
925 /* Structure representing an iterator for cuesheet tracks in a CUESHEET metadata block. */
926 typedef struct
927 {
928  drflac_uint32 countRemaining;
929  const char* pRunningData;
931 
932 /* Packing is important on this structure because we map this directly to the raw data within the CUESHEET metadata block. */
933 #pragma pack(4)
934 typedef struct
935 {
936  drflac_uint64 offset;
937  drflac_uint8 index;
938  drflac_uint8 reserved[3];
940 #pragma pack()
941 
942 typedef struct
943 {
944  drflac_uint64 offset;
945  drflac_uint8 trackNumber;
946  char ISRC[12];
947  drflac_bool8 isAudio;
948  drflac_bool8 preEmphasis;
949  drflac_uint8 indexCount;
950  const drflac_cuesheet_track_index* pIndexPoints;
952 
953 /*
954 Initializes a cuesheet track iterator. This can be used for iterating over the cuesheet tracks in a CUESHEET metadata
955 block.
956 */
957 void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData);
958 
959 /* Goes to the next cuesheet track in the given iterator. If DRFLAC_FALSE is returned it means there are no more comments. */
961 
962 
963 #ifdef __cplusplus
964 }
965 #endif
966 #endif /* dr_flac_h */
967 
968 
969 /************************************************************************************************************************************************************
970  ************************************************************************************************************************************************************
971 
972  IMPLEMENTATION
973 
974  ************************************************************************************************************************************************************
975  ************************************************************************************************************************************************************/
976 #ifdef DR_FLAC_IMPLEMENTATION
977 
978 /* Disable some annoying warnings. */
979 #if defined(__GNUC__)
980  #pragma GCC diagnostic push
981  #if __GNUC__ >= 7
982  #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
983  #endif
984 #endif
985 
986 #ifdef __linux__
987  #ifndef _BSD_SOURCE
988  #define _BSD_SOURCE
989  #endif
990  #ifndef __USE_BSD
991  #define __USE_BSD
992  #endif
993  #include <endian.h>
994 #endif
995 
996 #include <stdlib.h>
997 #include <string.h>
998 
999 #ifdef _MSC_VER
1000  #define DRFLAC_INLINE __forceinline
1001 #elif defined(__GNUC__)
1002  /*
1003  I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
1004  the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
1005  case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
1006  command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
1007  I am using "__inline__" only when we're compiling in strict ANSI mode.
1008  */
1009  #if defined(__STRICT_ANSI__)
1010  #define DRFLAC_INLINE __inline__ __attribute__((always_inline))
1011  #else
1012  #define DRFLAC_INLINE inline __attribute__((always_inline))
1013  #endif
1014 #else
1015  #define DRFLAC_INLINE
1016 #endif
1017 
1018 /* CPU architecture. */
1019 #if defined(__x86_64__) || defined(_M_X64)
1020  #define DRFLAC_X64
1021 #elif defined(__i386) || defined(_M_IX86)
1022  #define DRFLAC_X86
1023 #elif defined(__arm__) || defined(_M_ARM)
1024  #define DRFLAC_ARM
1025 #endif
1026 
1027 /* Intrinsics Support */
1028 #if !defined(DR_FLAC_NO_SIMD)
1029  #if defined(DRFLAC_X64) || defined(DRFLAC_X86)
1030  #if defined(_MSC_VER) && !defined(__clang__)
1031  /* MSVC. */
1032  #if _MSC_VER >= 1400 && !defined(DRFLAC_NO_SSE2) /* 2005 */
1033  #define DRFLAC_SUPPORT_SSE2
1034  #endif
1035  #if _MSC_VER >= 1600 && !defined(DRFLAC_NO_SSE41) /* 2010 */
1036  #define DRFLAC_SUPPORT_SSE41
1037  #endif
1038  #else
1039  /* Assume GNUC-style. */
1040  #if defined(__SSE2__) && !defined(DRFLAC_NO_SSE2)
1041  #define DRFLAC_SUPPORT_SSE2
1042  #endif
1043  #if defined(__SSE4_1__) && !defined(DRFLAC_NO_SSE41)
1044  #define DRFLAC_SUPPORT_SSE41
1045  #endif
1046  #endif
1047 
1048  /* If at this point we still haven't determined compiler support for the intrinsics just fall back to __has_include. */
1049  #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include)
1050  #if !defined(DRFLAC_SUPPORT_SSE2) && !defined(DRFLAC_NO_SSE2) && __has_include(<emmintrin.h>)
1051  #define DRFLAC_SUPPORT_SSE2
1052  #endif
1053  #if !defined(DRFLAC_SUPPORT_SSE41) && !defined(DRFLAC_NO_SSE41) && __has_include(<smmintrin.h>)
1054  #define DRFLAC_SUPPORT_SSE41
1055  #endif
1056  #endif
1057 
1058  #if defined(DRFLAC_SUPPORT_SSE41)
1059  #include <smmintrin.h>
1060  #elif defined(DRFLAC_SUPPORT_SSE2)
1061  #include <emmintrin.h>
1062  #endif
1063  #endif
1064 
1065  #if defined(DRFLAC_ARM)
1066  #if !defined(DRFLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1067  #define DRFLAC_SUPPORT_NEON
1068  #endif
1069 
1070  /* Fall back to looking for the #include file. */
1071  #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include)
1072  #if !defined(DRFLAC_SUPPORT_NEON) && !defined(DRFLAC_NO_NEON) && __has_include(<arm_neon.h>)
1073  #define DRFLAC_SUPPORT_NEON
1074  #endif
1075  #endif
1076 
1077  #if defined(DRFLAC_SUPPORT_NEON)
1078  #include <arm_neon.h>
1079  #endif
1080  #endif
1081 #endif
1082 
1083 /* Compile-time CPU feature support. */
1084 #if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
1085  #if defined(_MSC_VER) && !defined(__clang__)
1086  #if _MSC_VER >= 1400
1087  #include <intrin.h>
1088  static void drflac__cpuid(int info[4], int fid)
1089  {
1090  __cpuid(info, fid);
1091  }
1092  #else
1093  #define DRFLAC_NO_CPUID
1094  #endif
1095  #else
1096  #if defined(__GNUC__) || defined(__clang__)
1097  static void drflac__cpuid(int info[4], int fid)
1098  {
1099  /*
1100  It looks like the -fPIC option uses the ebx register which GCC complains about. We can work around this by just using a different register, the
1101  specific register of which I'm letting the compiler decide on. The "k" prefix is used to specify a 32-bit register. The {...} syntax is for
1102  supporting different assembly dialects.
1103 
1104  What's basically happening is that we're saving and restoring the ebx register manually.
1105  */
1106  #if defined(DRFLAC_X86) && defined(__PIC__)
1107  __asm__ __volatile__ (
1108  "xchg{l} {%%}ebx, %k1;"
1109  "cpuid;"
1110  "xchg{l} {%%}ebx, %k1;"
1111  : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1112  );
1113  #else
1114  __asm__ __volatile__ (
1115  "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1116  );
1117  #endif
1118  }
1119  #else
1120  #define DRFLAC_NO_CPUID
1121  #endif
1122  #endif
1123 #else
1124  #define DRFLAC_NO_CPUID
1125 #endif
1126 
1128 {
1129 #if defined(DRFLAC_SUPPORT_SSE2)
1130  #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE2)
1131  #if defined(DRFLAC_X64)
1132  return DRFLAC_TRUE; /* 64-bit targets always support SSE2. */
1133  #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)
1134  return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE2 code we can assume support. */
1135  #else
1136  #if defined(DRFLAC_NO_CPUID)
1137  return DRFLAC_FALSE;
1138  #else
1139  int info[4];
1140  drflac__cpuid(info, 1);
1141  return (info[3] & (1 << 26)) != 0;
1142  #endif
1143  #endif
1144  #else
1145  return DRFLAC_FALSE; /* SSE2 is only supported on x86 and x64 architectures. */
1146  #endif
1147 #else
1148  return DRFLAC_FALSE; /* No compiler support. */
1149 #endif
1150 }
1151 
1153 {
1154 #if defined(DRFLAC_SUPPORT_SSE41)
1155  #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41)
1156  #if defined(DRFLAC_X64)
1157  return DRFLAC_TRUE; /* 64-bit targets always support SSE4.1. */
1158  #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE4_1__)
1159  return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE41 code we can assume support. */
1160  #else
1161  #if defined(DRFLAC_NO_CPUID)
1162  return DRFLAC_FALSE;
1163  #else
1164  int info[4];
1165  drflac__cpuid(info, 1);
1166  return (info[2] & (1 << 19)) != 0;
1167  #endif
1168  #endif
1169  #else
1170  return DRFLAC_FALSE; /* SSE41 is only supported on x86 and x64 architectures. */
1171  #endif
1172 #else
1173  return DRFLAC_FALSE; /* No compiler support. */
1174 #endif
1175 }
1176 
1177 
1178 #if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
1179  #define DRFLAC_HAS_LZCNT_INTRINSIC
1180 #elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
1181  #define DRFLAC_HAS_LZCNT_INTRINSIC
1182 #elif defined(__clang__)
1183  #if defined(__has_builtin)
1184  #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl)
1185  #define DRFLAC_HAS_LZCNT_INTRINSIC
1186  #endif
1187  #endif
1188 #endif
1189 
1190 #if defined(_MSC_VER) && _MSC_VER >= 1400
1191  #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1192  #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1193  #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1194 #elif defined(__clang__)
1195  #if defined(__has_builtin)
1196  #if __has_builtin(__builtin_bswap16)
1197  #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1198  #endif
1199  #if __has_builtin(__builtin_bswap32)
1200  #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1201  #endif
1202  #if __has_builtin(__builtin_bswap64)
1203  #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1204  #endif
1205  #endif
1206 #elif defined(__GNUC__)
1207  #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
1208  #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1209  #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1210  #endif
1211  #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
1212  #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1213  #endif
1214 #endif
1215 
1216 
1217 /* Standard library stuff. */
1218 #ifndef DRFLAC_ASSERT
1219 #include <assert.h>
1220 #define DRFLAC_ASSERT(expression) assert(expression)
1221 #endif
1222 #ifndef DRFLAC_MALLOC
1223 #define DRFLAC_MALLOC(sz) malloc((sz))
1224 #endif
1225 #ifndef DRFLAC_REALLOC
1226 #define DRFLAC_REALLOC(p, sz) realloc((p), (sz))
1227 #endif
1228 #ifndef DRFLAC_FREE
1229 #define DRFLAC_FREE(p) free((p))
1230 #endif
1231 #ifndef DRFLAC_COPY_MEMORY
1232 #define DRFLAC_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
1233 #endif
1234 #ifndef DRFLAC_ZERO_MEMORY
1235 #define DRFLAC_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
1236 #endif
1237 
1238 #define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
1239 
1240 typedef drflac_int32 drflac_result;
1241 #define DRFLAC_SUCCESS 0
1242 #define DRFLAC_ERROR -1 /* A generic error. */
1243 #define DRFLAC_INVALID_ARGS -2
1244 #define DRFLAC_END_OF_STREAM -128
1245 #define DRFLAC_CRC_MISMATCH -129
1246 
1247 #define DRFLAC_SUBFRAME_CONSTANT 0
1248 #define DRFLAC_SUBFRAME_VERBATIM 1
1249 #define DRFLAC_SUBFRAME_FIXED 8
1250 #define DRFLAC_SUBFRAME_LPC 32
1251 #define DRFLAC_SUBFRAME_RESERVED 255
1252 
1253 #define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0
1254 #define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1
1255 
1256 #define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0
1257 #define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8
1258 #define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9
1259 #define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
1260 
1261 #define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
1262 
1263 
1264 /* CPU caps. */
1265 #if defined(__has_feature)
1266  #if __has_feature(thread_sanitizer)
1267  #define DRFLAC_NO_THREAD_SANITIZE __attribute__((no_sanitize("thread")))
1268  #else
1269  #define DRFLAC_NO_THREAD_SANITIZE
1270  #endif
1271 #else
1272  #define DRFLAC_NO_THREAD_SANITIZE
1273 #endif
1274 
1275 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1276 static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE;
1277 #endif
1278 
1279 #ifndef DRFLAC_NO_CPUID
1280 static drflac_bool32 drflac__gIsSSE2Supported = DRFLAC_FALSE;
1281 static drflac_bool32 drflac__gIsSSE41Supported = DRFLAC_FALSE;
1282 
1283 /*
1284 I've had a bug report that Clang's ThreadSanitizer presents a warning in this function. Having reviewed this, this does
1285 actually make sense. However, since CPU caps should never differ for a running process, I don't think the trade off of
1286 complicating internal API's by passing around CPU caps versus just disabling the warnings is worthwhile. I'm therefore
1287 just going to disable these warnings. This is disabled via the DRFLAC_NO_THREAD_SANITIZE attribute.
1288 */
1290 {
1291  static drflac_bool32 isCPUCapsInitialized = DRFLAC_FALSE;
1292 
1293  if (!isCPUCapsInitialized) {
1294  int info[4] = {0};
1295 
1296  /* LZCNT */
1297 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1298  drflac__cpuid(info, 0x80000001);
1299  drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0;
1300 #endif
1301 
1302  /* SSE2 */
1303  drflac__gIsSSE2Supported = drflac_has_sse2();
1304 
1305  /* SSE4.1 */
1306  drflac__gIsSSE41Supported = drflac_has_sse41();
1307 
1308  /* Initialized. */
1309  isCPUCapsInitialized = DRFLAC_TRUE;
1310  }
1311 }
1312 #else
1314 
1316 {
1317 #if defined(DRFLAC_SUPPORT_NEON)
1318  #if defined(DRFLAC_ARM) && !defined(DRFLAC_NO_NEON)
1319  #if (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1320  return DRFLAC_TRUE; /* If the compiler is allowed to freely generate NEON code we can assume support. */
1321  #else
1322  /* TODO: Runtime check. */
1323  return DRFLAC_FALSE;
1324  #endif
1325  #else
1326  return DRFLAC_FALSE; /* NEON is only supported on ARM architectures. */
1327  #endif
1328 #else
1329  return DRFLAC_FALSE; /* No compiler support. */
1330 #endif
1331 }
1332 
1334 {
1336 
1337 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
1338  drflac__gIsLZCNTSupported = DRFLAC_TRUE;
1339 #endif
1340 }
1341 #endif
1342 
1343 
1344 /* Endian Management */
1346 {
1347 #if defined(DRFLAC_X86) || defined(DRFLAC_X64)
1348  return DRFLAC_TRUE;
1349 #elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
1350  return DRFLAC_TRUE;
1351 #else
1352  int n = 1;
1353  return (*(char*)&n) == 1;
1354 #endif
1355 }
1356 
1358 {
1359 #ifdef DRFLAC_HAS_BYTESWAP16_INTRINSIC
1360  #if defined(_MSC_VER)
1361  return _byteswap_ushort(n);
1362  #elif defined(__GNUC__) || defined(__clang__)
1363  return __builtin_bswap16(n);
1364  #else
1365  #error "This compiler does not support the byte swap intrinsic."
1366  #endif
1367 #else
1368  return ((n & 0xFF00) >> 8) |
1369  ((n & 0x00FF) << 8);
1370 #endif
1371 }
1372 
1374 {
1375 #ifdef DRFLAC_HAS_BYTESWAP32_INTRINSIC
1376  #if defined(_MSC_VER)
1377  return _byteswap_ulong(n);
1378  #elif defined(__GNUC__) || defined(__clang__)
1379  #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
1380  /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
1381  drflac_uint32 r;
1382  __asm__ __volatile__ (
1383  #if defined(DRFLAC_64BIT)
1384  "rev %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(n) /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
1385  #else
1386  "rev %[out], %[in]" : [out]"=r"(r) : [in]"r"(n)
1387  #endif
1388  );
1389  return r;
1390  #else
1391  return __builtin_bswap32(n);
1392  #endif
1393  #else
1394  #error "This compiler does not support the byte swap intrinsic."
1395  #endif
1396 #else
1397  return ((n & 0xFF000000) >> 24) |
1398  ((n & 0x00FF0000) >> 8) |
1399  ((n & 0x0000FF00) << 8) |
1400  ((n & 0x000000FF) << 24);
1401 #endif
1402 }
1403 
1405 {
1406 #ifdef DRFLAC_HAS_BYTESWAP64_INTRINSIC
1407  #if defined(_MSC_VER)
1408  return _byteswap_uint64(n);
1409  #elif defined(__GNUC__) || defined(__clang__)
1410  return __builtin_bswap64(n);
1411  #else
1412  #error "This compiler does not support the byte swap intrinsic."
1413  #endif
1414 #else
1415  return ((n & (drflac_uint64)0xFF00000000000000) >> 56) |
1416  ((n & (drflac_uint64)0x00FF000000000000) >> 40) |
1417  ((n & (drflac_uint64)0x0000FF0000000000) >> 24) |
1418  ((n & (drflac_uint64)0x000000FF00000000) >> 8) |
1419  ((n & (drflac_uint64)0x00000000FF000000) << 8) |
1420  ((n & (drflac_uint64)0x0000000000FF0000) << 24) |
1421  ((n & (drflac_uint64)0x000000000000FF00) << 40) |
1422  ((n & (drflac_uint64)0x00000000000000FF) << 56);
1423 #endif
1424 }
1425 
1426 
1428 {
1429  if (drflac__is_little_endian()) {
1430  return drflac__swap_endian_uint16(n);
1431  }
1432 
1433  return n;
1434 }
1435 
1437 {
1438  if (drflac__is_little_endian()) {
1439  return drflac__swap_endian_uint32(n);
1440  }
1441 
1442  return n;
1443 }
1444 
1446 {
1447  if (drflac__is_little_endian()) {
1448  return drflac__swap_endian_uint64(n);
1449  }
1450 
1451  return n;
1452 }
1453 
1454 
1456 {
1457  if (!drflac__is_little_endian()) {
1458  return drflac__swap_endian_uint32(n);
1459  }
1460 
1461  return n;
1462 }
1463 
1464 
1466 {
1467  drflac_uint32 result = 0;
1468  result |= (n & 0x7F000000) >> 3;
1469  result |= (n & 0x007F0000) >> 2;
1470  result |= (n & 0x00007F00) >> 1;
1471  result |= (n & 0x0000007F) >> 0;
1472 
1473  return result;
1474 }
1475 
1476 
1477 
1478 /* The CRC code below is based on this document: http://zlib.net/crc_v3.txt */
1479 static drflac_uint8 drflac__crc8_table[] = {
1480  0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
1481  0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
1482  0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
1483  0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
1484  0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
1485  0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
1486  0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
1487  0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
1488  0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
1489  0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
1490  0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
1491  0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
1492  0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
1493  0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
1494  0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
1495  0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
1496 };
1497 
1499  0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
1500  0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
1501  0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
1502  0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
1503  0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
1504  0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
1505  0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
1506  0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
1507  0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
1508  0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
1509  0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
1510  0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
1511  0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
1512  0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
1513  0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
1514  0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
1515  0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
1516  0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
1517  0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
1518  0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
1519  0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
1520  0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
1521  0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
1522  0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
1523  0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
1524  0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
1525  0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
1526  0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
1527  0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
1528  0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
1529  0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
1530  0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
1531 };
1532 
1534 {
1535  return drflac__crc8_table[crc ^ data];
1536 }
1537 
1539 {
1540 #ifdef DR_FLAC_NO_CRC
1541  (void)crc;
1542  (void)data;
1543  (void)count;
1544  return 0;
1545 #else
1546 #if 0
1547  /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */
1548  drflac_uint8 p = 0x07;
1549  for (int i = count-1; i >= 0; --i) {
1550  drflac_uint8 bit = (data & (1 << i)) >> i;
1551  if (crc & 0x80) {
1552  crc = ((crc << 1) | bit) ^ p;
1553  } else {
1554  crc = ((crc << 1) | bit);
1555  }
1556  }
1557  return crc;
1558 #else
1559  drflac_uint32 wholeBytes;
1560  drflac_uint32 leftoverBits;
1561  drflac_uint64 leftoverDataMask;
1562 
1563  static drflac_uint64 leftoverDataMaskTable[8] = {
1564  0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
1565  };
1566 
1567  DRFLAC_ASSERT(count <= 32);
1568 
1569  wholeBytes = count >> 3;
1570  leftoverBits = count - (wholeBytes*8);
1571  leftoverDataMask = leftoverDataMaskTable[leftoverBits];
1572 
1573  switch (wholeBytes) {
1574  case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
1575  case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
1576  case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
1577  case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
1578  case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)];
1579  }
1580  return crc;
1581 #endif
1582 #endif
1583 }
1584 
1586 {
1587  return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data];
1588 }
1589 
1591 {
1592 #ifdef DRFLAC_64BIT
1593  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
1594  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
1595  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
1596  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
1597 #endif
1598  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
1599  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
1600  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
1601  crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
1602 
1603  return crc;
1604 }
1605 
1607 {
1608  switch (byteCount)
1609  {
1610 #ifdef DRFLAC_64BIT
1611  case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
1612  case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
1613  case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
1614  case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
1615 #endif
1616  case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
1617  case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
1618  case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
1619  case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
1620  }
1621 
1622  return crc;
1623 }
1624 
1625 #if 0
1626 static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count)
1627 {
1628 #ifdef DR_FLAC_NO_CRC
1629  (void)crc;
1630  (void)data;
1631  (void)count;
1632  return 0;
1633 #else
1634 #if 0
1635  /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */
1636  drflac_uint16 p = 0x8005;
1637  for (int i = count-1; i >= 0; --i) {
1638  drflac_uint16 bit = (data & (1ULL << i)) >> i;
1639  if (r & 0x8000) {
1640  r = ((r << 1) | bit) ^ p;
1641  } else {
1642  r = ((r << 1) | bit);
1643  }
1644  }
1645 
1646  return crc;
1647 #else
1648  drflac_uint32 wholeBytes;
1649  drflac_uint32 leftoverBits;
1650  drflac_uint64 leftoverDataMask;
1651 
1652  static drflac_uint64 leftoverDataMaskTable[8] = {
1653  0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
1654  };
1655 
1656  DRFLAC_ASSERT(count <= 64);
1657 
1658  wholeBytes = count >> 3;
1659  leftoverBits = count & 7;
1660  leftoverDataMask = leftoverDataMaskTable[leftoverBits];
1661 
1662  switch (wholeBytes) {
1663  default:
1664  case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
1665  case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
1666  case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
1667  case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
1668  case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
1669  }
1670  return crc;
1671 #endif
1672 #endif
1673 }
1674 
1675 static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count)
1676 {
1677 #ifdef DR_FLAC_NO_CRC
1678  (void)crc;
1679  (void)data;
1680  (void)count;
1681  return 0;
1682 #else
1683  drflac_uint32 wholeBytes;
1684  drflac_uint32 leftoverBits;
1685  drflac_uint64 leftoverDataMask;
1686 
1687  static drflac_uint64 leftoverDataMaskTable[8] = {
1688  0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
1689  };
1690 
1691  DRFLAC_ASSERT(count <= 64);
1692 
1693  wholeBytes = count >> 3;
1694  leftoverBits = count & 7;
1695  leftoverDataMask = leftoverDataMaskTable[leftoverBits];
1696 
1697  switch (wholeBytes) {
1698  default:
1699  case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits))); /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
1700  case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
1701  case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
1702  case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
1703  case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits)));
1704  case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits)));
1705  case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits)));
1706  case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits)));
1707  case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
1708  }
1709  return crc;
1710 #endif
1711 }
1712 
1713 
1715 {
1716 #ifdef DRFLAC_64BIT
1717  return drflac_crc16__64bit(crc, data, count);
1718 #else
1719  return drflac_crc16__32bit(crc, data, count);
1720 #endif
1721 }
1722 #endif
1723 
1724 
1725 #ifdef DRFLAC_64BIT
1726 #define drflac__be2host__cache_line drflac__be2host_64
1727 #else
1728 #define drflac__be2host__cache_line drflac__be2host_32
1729 #endif
1730 
1731 /*
1732 BIT READING ATTEMPT #2
1733 
1734 This uses a 32- or 64-bit bit-shifted cache - as bits are read, the cache is shifted such that the first valid bit is sitting
1735 on the most significant bit. It uses the notion of an L1 and L2 cache (borrowed from CPU architecture), where the L1 cache
1736 is a 32- or 64-bit unsigned integer (depending on whether or not a 32- or 64-bit build is being compiled) and the L2 is an
1737 array of "cache lines", with each cache line being the same size as the L1. The L2 is a buffer of about 4KB and is where data
1738 from onRead() is read into.
1739 */
1740 #define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache))
1741 #define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
1742 #define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
1743 #define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(drflac_cache_t)0) >> (_bitCount)))
1744 #define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
1745 #define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
1746 #define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
1747 #define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1)))
1748 #define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
1749 #define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
1750 #define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
1751 
1752 
1753 #ifndef DR_FLAC_NO_CRC
1755 {
1756  bs->crc16 = 0;
1757  bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
1758 }
1759 
1761 {
1762  if (bs->crc16CacheIgnoredBytes == 0) {
1763  bs->crc16 = drflac_crc16_cache(bs->crc16, bs->crc16Cache);
1764  } else {
1766  bs->crc16CacheIgnoredBytes = 0;
1767  }
1768 }
1769 
1771 {
1772  /* We should never be flushing in a situation where we are not aligned on a byte boundary. */
1774 
1775  /*
1776  The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined
1777  by the number of bits that have been consumed.
1778  */
1779  if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
1781  } else {
1782  /* We only accumulate the consumed bits. */
1784 
1785  /*
1786  The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated
1787  so we can handle that later.
1788  */
1789  bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
1790  }
1791 
1792  return bs->crc16;
1793 }
1794 #endif
1795 
1797 {
1798  size_t bytesRead;
1799  size_t alignedL1LineCount;
1800 
1801  /* Fast path. Try loading straight from L2. */
1802  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
1803  bs->cache = bs->cacheL2[bs->nextL2Line++];
1804  return DRFLAC_TRUE;
1805  }
1806 
1807  /*
1808  If we get here it means we've run out of data in the L2 cache. We'll need to fetch more from the client, if there's
1809  any left.
1810  */
1811  if (bs->unalignedByteCount > 0) {
1812  return DRFLAC_FALSE; /* If we have any unaligned bytes it means there's no more aligned bytes left in the client. */
1813  }
1814 
1815  bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs));
1816 
1817  bs->nextL2Line = 0;
1818  if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) {
1819  bs->cache = bs->cacheL2[bs->nextL2Line++];
1820  return DRFLAC_TRUE;
1821  }
1822 
1823 
1824  /*
1825  If we get here it means we were unable to retrieve enough data to fill the entire L2 cache. It probably
1826  means we've just reached the end of the file. We need to move the valid data down to the end of the buffer
1827  and adjust the index of the next line accordingly. Also keep in mind that the L2 cache must be aligned to
1828  the size of the L1 so we'll need to seek backwards by any misaligned bytes.
1829  */
1830  alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs);
1831 
1832  /* We need to keep track of any unaligned bytes for later use. */
1833  bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs));
1834  if (bs->unalignedByteCount > 0) {
1835  bs->unalignedCache = bs->cacheL2[alignedL1LineCount];
1836  }
1837 
1838  if (alignedL1LineCount > 0) {
1839  size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount;
1840  size_t i;
1841  for (i = alignedL1LineCount; i > 0; --i) {
1842  bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1];
1843  }
1844 
1845  bs->nextL2Line = (drflac_uint32)offset;
1846  bs->cache = bs->cacheL2[bs->nextL2Line++];
1847  return DRFLAC_TRUE;
1848  } else {
1849  /* If we get into this branch it means we weren't able to load any L1-aligned data. */
1851  return DRFLAC_FALSE;
1852  }
1853 }
1854 
1856 {
1857  size_t bytesRead;
1858 
1859 #ifndef DR_FLAC_NO_CRC
1861 #endif
1862 
1863  /* Fast path. Try just moving the next value in the L2 cache to the L1 cache. */
1866  bs->consumedBits = 0;
1867 #ifndef DR_FLAC_NO_CRC
1868  bs->crc16Cache = bs->cache;
1869 #endif
1870  return DRFLAC_TRUE;
1871  }
1872 
1873  /* Slow path. */
1874 
1875  /*
1876  If we get here it means we have failed to load the L1 cache from the L2. Likely we've just reached the end of the stream and the last
1877  few bytes did not meet the alignment requirements for the L2 cache. In this case we need to fall back to a slower path and read the
1878  data from the unaligned cache.
1879  */
1880  bytesRead = bs->unalignedByteCount;
1881  if (bytesRead == 0) {
1882  bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- The stream has been exhausted, so marked the bits as consumed. */
1883  return DRFLAC_FALSE;
1884  }
1885 
1886  DRFLAC_ASSERT(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
1887  bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
1888 
1890  bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_BITS_REMAINING(bs)); /* <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property. */
1891  bs->unalignedByteCount = 0; /* <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes. */
1892 
1893 #ifndef DR_FLAC_NO_CRC
1894  bs->crc16Cache = bs->cache >> bs->consumedBits;
1895  bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
1896 #endif
1897  return DRFLAC_TRUE;
1898 }
1899 
1900 static void drflac__reset_cache(drflac_bs* bs)
1901 {
1902  bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); /* <-- This clears the L2 cache. */
1903  bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- This clears the L1 cache. */
1904  bs->cache = 0;
1905  bs->unalignedByteCount = 0; /* <-- This clears the trailing unaligned bytes. */
1906  bs->unalignedCache = 0;
1907 
1908 #ifndef DR_FLAC_NO_CRC
1909  bs->crc16Cache = 0;
1910  bs->crc16CacheIgnoredBytes = 0;
1911 #endif
1912 }
1913 
1914 
1915 static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut)
1916 {
1917  DRFLAC_ASSERT(bs != NULL);
1918  DRFLAC_ASSERT(pResultOut != NULL);
1919  DRFLAC_ASSERT(bitCount > 0);
1920  DRFLAC_ASSERT(bitCount <= 32);
1921 
1922  if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
1923  if (!drflac__reload_cache(bs)) {
1924  return DRFLAC_FALSE;
1925  }
1926  }
1927 
1928  if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
1929  /*
1930  If we want to load all 32-bits from a 32-bit cache we need to do it slightly differently because we can't do
1931  a 32-bit shift on a 32-bit integer. This will never be the case on 64-bit caches, so we can have a slightly
1932  more optimal solution for this.
1933  */
1934 #ifdef DRFLAC_64BIT
1935  *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
1936  bs->consumedBits += bitCount;
1937  bs->cache <<= bitCount;
1938 #else
1939  if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
1940  *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
1941  bs->consumedBits += bitCount;
1942  bs->cache <<= bitCount;
1943  } else {
1944  /* Cannot shift by 32-bits, so need to do it differently. */
1945  *pResultOut = (drflac_uint32)bs->cache;
1947  bs->cache = 0;
1948  }
1949 #endif
1950 
1951  return DRFLAC_TRUE;
1952  } else {
1953  /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */
1955  drflac_uint32 bitCountLo = bitCount - bitCountHi;
1956  drflac_uint32 resultHi = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
1957 
1958  if (!drflac__reload_cache(bs)) {
1959  return DRFLAC_FALSE;
1960  }
1961 
1962  *pResultOut = (resultHi << bitCountLo) | (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo);
1963  bs->consumedBits += bitCountLo;
1964  bs->cache <<= bitCountLo;
1965  return DRFLAC_TRUE;
1966  }
1967 }
1968 
1969 static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult)
1970 {
1971  drflac_uint32 result;
1972  drflac_uint32 signbit;
1973 
1974  DRFLAC_ASSERT(bs != NULL);
1975  DRFLAC_ASSERT(pResult != NULL);
1976  DRFLAC_ASSERT(bitCount > 0);
1977  DRFLAC_ASSERT(bitCount <= 32);
1978 
1979  if (!drflac__read_uint32(bs, bitCount, &result)) {
1980  return DRFLAC_FALSE;
1981  }
1982 
1983  signbit = ((result >> (bitCount-1)) & 0x01);
1984  result |= (~signbit + 1) << bitCount;
1985 
1986  *pResult = (drflac_int32)result;
1987  return DRFLAC_TRUE;
1988 }
1989 
1990 #ifdef DRFLAC_64BIT
1991 static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut)
1992 {
1993  drflac_uint32 resultHi;
1994  drflac_uint32 resultLo;
1995 
1996  DRFLAC_ASSERT(bitCount <= 64);
1997  DRFLAC_ASSERT(bitCount > 32);
1998 
1999  if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
2000  return DRFLAC_FALSE;
2001  }
2002 
2003  if (!drflac__read_uint32(bs, 32, &resultLo)) {
2004  return DRFLAC_FALSE;
2005  }
2006 
2007  *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo);
2008  return DRFLAC_TRUE;
2009 }
2010 #endif
2011 
2012 /* Function below is unused, but leaving it here in case I need to quickly add it again. */
2013 #if 0
2014 static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut)
2015 {
2016  drflac_uint64 result;
2017  drflac_uint64 signbit;
2018 
2019  DRFLAC_ASSERT(bitCount <= 64);
2020 
2021  if (!drflac__read_uint64(bs, bitCount, &result)) {
2022  return DRFLAC_FALSE;
2023  }
2024 
2025  signbit = ((result >> (bitCount-1)) & 0x01);
2026  result |= (~signbit + 1) << bitCount;
2027 
2028  *pResultOut = (drflac_int64)result;
2029  return DRFLAC_TRUE;
2030 }
2031 #endif
2032 
2033 static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult)
2034 {
2035  drflac_uint32 result;
2036 
2037  DRFLAC_ASSERT(bs != NULL);
2038  DRFLAC_ASSERT(pResult != NULL);
2039  DRFLAC_ASSERT(bitCount > 0);
2040  DRFLAC_ASSERT(bitCount <= 16);
2041 
2042  if (!drflac__read_uint32(bs, bitCount, &result)) {
2043  return DRFLAC_FALSE;
2044  }
2045 
2046  *pResult = (drflac_uint16)result;
2047  return DRFLAC_TRUE;
2048 }
2049 
2050 #if 0
2051 static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult)
2052 {
2053  drflac_int32 result;
2054 
2055  DRFLAC_ASSERT(bs != NULL);
2056  DRFLAC_ASSERT(pResult != NULL);
2057  DRFLAC_ASSERT(bitCount > 0);
2058  DRFLAC_ASSERT(bitCount <= 16);
2059 
2060  if (!drflac__read_int32(bs, bitCount, &result)) {
2061  return DRFLAC_FALSE;
2062  }
2063 
2064  *pResult = (drflac_int16)result;
2065  return DRFLAC_TRUE;
2066 }
2067 #endif
2068 
2069 static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult)
2070 {
2071  drflac_uint32 result;
2072 
2073  DRFLAC_ASSERT(bs != NULL);
2074  DRFLAC_ASSERT(pResult != NULL);
2075  DRFLAC_ASSERT(bitCount > 0);
2076  DRFLAC_ASSERT(bitCount <= 8);
2077 
2078  if (!drflac__read_uint32(bs, bitCount, &result)) {
2079  return DRFLAC_FALSE;
2080  }
2081 
2082  *pResult = (drflac_uint8)result;
2083  return DRFLAC_TRUE;
2084 }
2085 
2086 static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult)
2087 {
2088  drflac_int32 result;
2089 
2090  DRFLAC_ASSERT(bs != NULL);
2091  DRFLAC_ASSERT(pResult != NULL);
2092  DRFLAC_ASSERT(bitCount > 0);
2093  DRFLAC_ASSERT(bitCount <= 8);
2094 
2095  if (!drflac__read_int32(bs, bitCount, &result)) {
2096  return DRFLAC_FALSE;
2097  }
2098 
2099  *pResult = (drflac_int8)result;
2100  return DRFLAC_TRUE;
2101 }
2102 
2103 
2104 static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
2105 {
2106  if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2107  bs->consumedBits += (drflac_uint32)bitsToSeek;
2108  bs->cache <<= bitsToSeek;
2109  return DRFLAC_TRUE;
2110  } else {
2111  /* It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here. */
2112  bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2114  bs->cache = 0;
2115 
2116  /* Simple case. Seek in groups of the same number as bits that fit within a cache line. */
2117 #ifdef DRFLAC_64BIT
2118  while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2119  drflac_uint64 bin;
2120  if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2121  return DRFLAC_FALSE;
2122  }
2123  bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2124  }
2125 #else
2126  while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2127  drflac_uint32 bin;
2128  if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2129  return DRFLAC_FALSE;
2130  }
2131  bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2132  }
2133 #endif
2134 
2135  /* Whole leftover bytes. */
2136  while (bitsToSeek >= 8) {
2137  drflac_uint8 bin;
2138  if (!drflac__read_uint8(bs, 8, &bin)) {
2139  return DRFLAC_FALSE;
2140  }
2141  bitsToSeek -= 8;
2142  }
2143 
2144  /* Leftover bits. */
2145  if (bitsToSeek > 0) {
2146  drflac_uint8 bin;
2147  if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) {
2148  return DRFLAC_FALSE;
2149  }
2150  bitsToSeek = 0; /* <-- Necessary for the assert below. */
2151  }
2152 
2153  DRFLAC_ASSERT(bitsToSeek == 0);
2154  return DRFLAC_TRUE;
2155  }
2156 }
2157 
2158 
2159 /* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */
2161 {
2162  DRFLAC_ASSERT(bs != NULL);
2163 
2164  /*
2165  The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
2166  thing to do is align to the next byte.
2167  */
2169  return DRFLAC_FALSE;
2170  }
2171 
2172  for (;;) {
2173  drflac_uint8 hi;
2174 
2175 #ifndef DR_FLAC_NO_CRC
2176  drflac__reset_crc16(bs);
2177 #endif
2178 
2179  if (!drflac__read_uint8(bs, 8, &hi)) {
2180  return DRFLAC_FALSE;
2181  }
2182 
2183  if (hi == 0xFF) {
2184  drflac_uint8 lo;
2185  if (!drflac__read_uint8(bs, 6, &lo)) {
2186  return DRFLAC_FALSE;
2187  }
2188 
2189  if (lo == 0x3E) {
2190  return DRFLAC_TRUE;
2191  } else {
2193  return DRFLAC_FALSE;
2194  }
2195  }
2196  }
2197  }
2198 
2199  /* Should never get here. */
2200  /*return DRFLAC_FALSE;*/
2201 }
2202 
2203 
2204 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
2205 #define DRFLAC_IMPLEMENT_CLZ_LZCNT
2206 #endif
2207 #if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86))
2208 #define DRFLAC_IMPLEMENT_CLZ_MSVC
2209 #endif
2210 
2212 {
2213  drflac_uint32 n;
2214  static drflac_uint32 clz_table_4[] = {
2215  0,
2216  4,
2217  3, 3,
2218  2, 2, 2, 2,
2219  1, 1, 1, 1, 1, 1, 1, 1
2220  };
2221 
2222  if (x == 0) {
2223  return sizeof(x)*8;
2224  }
2225 
2226  n = clz_table_4[x >> (sizeof(x)*8 - 4)];
2227  if (n == 0) {
2228 #ifdef DRFLAC_64BIT
2229  if ((x & ((drflac_uint64)0xFFFFFFFF << 32)) == 0) { n = 32; x <<= 32; }
2230  if ((x & ((drflac_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; }
2231  if ((x & ((drflac_uint64)0xFF000000 << 32)) == 0) { n += 8; x <<= 8; }
2232  if ((x & ((drflac_uint64)0xF0000000 << 32)) == 0) { n += 4; x <<= 4; }
2233 #else
2234  if ((x & 0xFFFF0000) == 0) { n = 16; x <<= 16; }
2235  if ((x & 0xFF000000) == 0) { n += 8; x <<= 8; }
2236  if ((x & 0xF0000000) == 0) { n += 4; x <<= 4; }
2237 #endif
2238  n += clz_table_4[x >> (sizeof(x)*8 - 4)];
2239  }
2240 
2241  return n - 1;
2242 }
2243 
2244 #ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2245 static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported()
2246 {
2247  /* Fast compile time check for ARM. */
2248 #if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
2249  return DRFLAC_TRUE;
2250 #else
2251  /* If the compiler itself does not support the intrinsic then we'll need to return false. */
2252  #ifdef DRFLAC_HAS_LZCNT_INTRINSIC
2253  return drflac__gIsLZCNTSupported;
2254  #else
2255  return DRFLAC_FALSE;
2256  #endif
2257 #endif
2258 }
2259 
2260 static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
2261 {
2262 #if defined(_MSC_VER) && !defined(__clang__)
2263  #ifdef DRFLAC_64BIT
2264  return (drflac_uint32)__lzcnt64(x);
2265  #else
2266  return (drflac_uint32)__lzcnt(x);
2267  #endif
2268 #else
2269  #if defined(__GNUC__) || defined(__clang__)
2270  #if defined(DRFLAC_X64)
2271  {
2272  drflac_uint64 r;
2273  __asm__ __volatile__ (
2274  "lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x)
2275  );
2276 
2277  return (drflac_uint32)r;
2278  }
2279  #elif defined(DRFLAC_X86)
2280  {
2281  drflac_uint32 r;
2282  __asm__ __volatile__ (
2283  "lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x)
2284  );
2285 
2286  return r;
2287  }
2288  #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
2289  {
2290  unsigned int r;
2291  __asm__ __volatile__ (
2292  #if defined(DRFLAC_64BIT)
2293  "clz %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(x) /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
2294  #else
2295  "clz %[out], %[in]" : [out]"=r"(r) : [in]"r"(x)
2296  #endif
2297  );
2298 
2299  return r;
2300  }
2301  #else
2302  if (x == 0) {
2303  return sizeof(x)*8;
2304  }
2305  #ifdef DRFLAC_64BIT
2306  return (drflac_uint32)__builtin_clzll((drflac_uint64)x);
2307  #else
2308  return (drflac_uint32)__builtin_clzl((drflac_uint32)x);
2309  #endif
2310  #endif
2311  #else
2312  /* Unsupported compiler. */
2313  #error "This compiler does not support the lzcnt intrinsic."
2314  #endif
2315 #endif
2316 }
2317 #endif
2318 
2319 #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2320 #include <intrin.h> /* For BitScanReverse(). */
2321 
2322 static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
2323 {
2324  drflac_uint32 n;
2325 
2326  if (x == 0) {
2327  return sizeof(x)*8;
2328  }
2329 
2330 #ifdef DRFLAC_64BIT
2331  _BitScanReverse64((unsigned long*)&n, x);
2332 #else
2333  _BitScanReverse((unsigned long*)&n, x);
2334 #endif
2335  return sizeof(x)*8 - n - 1;
2336 }
2337 #endif
2338 
2340 {
2341 #ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2342  if (drflac__is_lzcnt_supported()) {
2343  return drflac__clz_lzcnt(x);
2344  } else
2345 #endif
2346  {
2347 #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2348  return drflac__clz_msvc(x);
2349 #else
2350  return drflac__clz_software(x);
2351 #endif
2352  }
2353 }
2354 
2355 
2356 static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut)
2357 {
2358  drflac_uint32 zeroCounter = 0;
2359  drflac_uint32 setBitOffsetPlus1;
2360 
2361  while (bs->cache == 0) {
2362  zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2363  if (!drflac__reload_cache(bs)) {
2364  return DRFLAC_FALSE;
2365  }
2366  }
2367 
2368  setBitOffsetPlus1 = drflac__clz(bs->cache);
2369  setBitOffsetPlus1 += 1;
2370 
2371  bs->consumedBits += setBitOffsetPlus1;
2372  bs->cache <<= setBitOffsetPlus1;
2373 
2374  *pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1;
2375  return DRFLAC_TRUE;
2376 }
2377 
2378 
2379 
2380 static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart)
2381 {
2382  DRFLAC_ASSERT(bs != NULL);
2383  DRFLAC_ASSERT(offsetFromStart > 0);
2384 
2385  /*
2386  Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which
2387  is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit.
2388  To resolve we just need to do an initial seek from the start, and then a series of offset seeks to make up the remainder.
2389  */
2390  if (offsetFromStart > 0x7FFFFFFF) {
2391  drflac_uint64 bytesRemaining = offsetFromStart;
2392  if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
2393  return DRFLAC_FALSE;
2394  }
2395  bytesRemaining -= 0x7FFFFFFF;
2396 
2397  while (bytesRemaining > 0x7FFFFFFF) {
2398  if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
2399  return DRFLAC_FALSE;
2400  }
2401  bytesRemaining -= 0x7FFFFFFF;
2402  }
2403 
2404  if (bytesRemaining > 0) {
2405  if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) {
2406  return DRFLAC_FALSE;
2407  }
2408  }
2409  } else {
2410  if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) {
2411  return DRFLAC_FALSE;
2412  }
2413  }
2414 
2415  /* The cache should be reset to force a reload of fresh data from the client. */
2416  drflac__reset_cache(bs);
2417  return DRFLAC_TRUE;
2418 }
2419 
2420 
2422 {
2423  drflac_uint8 crc;
2424  drflac_uint64 result;
2425  unsigned char utf8[7] = {0};
2426  int byteCount;
2427  int i;
2428 
2429  DRFLAC_ASSERT(bs != NULL);
2430  DRFLAC_ASSERT(pNumberOut != NULL);
2431  DRFLAC_ASSERT(pCRCOut != NULL);
2432 
2433  crc = *pCRCOut;
2434 
2435  if (!drflac__read_uint8(bs, 8, utf8)) {
2436  *pNumberOut = 0;
2437  return DRFLAC_END_OF_STREAM;
2438  }
2439  crc = drflac_crc8(crc, utf8[0], 8);
2440 
2441  if ((utf8[0] & 0x80) == 0) {
2442  *pNumberOut = utf8[0];
2443  *pCRCOut = crc;
2444  return DRFLAC_SUCCESS;
2445  }
2446 
2447  /*byteCount = 1;*/
2448  if ((utf8[0] & 0xE0) == 0xC0) {
2449  byteCount = 2;
2450  } else if ((utf8[0] & 0xF0) == 0xE0) {
2451  byteCount = 3;
2452  } else if ((utf8[0] & 0xF8) == 0xF0) {
2453  byteCount = 4;
2454  } else if ((utf8[0] & 0xFC) == 0xF8) {
2455  byteCount = 5;
2456  } else if ((utf8[0] & 0xFE) == 0xFC) {
2457  byteCount = 6;
2458  } else if ((utf8[0] & 0xFF) == 0xFE) {
2459  byteCount = 7;
2460  } else {
2461  *pNumberOut = 0;
2462  return DRFLAC_CRC_MISMATCH; /* Bad UTF-8 encoding. */
2463  }
2464 
2465  /* Read extra bytes. */
2466  DRFLAC_ASSERT(byteCount > 1);
2467 
2468  result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1)));
2469  for (i = 1; i < byteCount; ++i) {
2470  if (!drflac__read_uint8(bs, 8, utf8 + i)) {
2471  *pNumberOut = 0;
2472  return DRFLAC_END_OF_STREAM;
2473  }
2474  crc = drflac_crc8(crc, utf8[i], 8);
2475 
2476  result = (result << 6) | (utf8[i] & 0x3F);
2477  }
2478 
2479  *pNumberOut = result;
2480  *pCRCOut = crc;
2481  return DRFLAC_SUCCESS;
2482 }
2483 
2484 
2485 
2486 /*
2487 The next two functions are responsible for calculating the prediction.
2488 
2489 When the bits per sample is >16 we need to use 64-bit integer arithmetic because otherwise we'll run out of precision. It's
2490 safe to assume this will be slower on 32-bit platforms so we use a more optimal solution when the bits per sample is <=16.
2491 */
2492 static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
2493 {
2494  drflac_int32 prediction = 0;
2495 
2496  DRFLAC_ASSERT(order <= 32);
2497 
2498  /* 32-bit version. */
2499 
2500  /* VC++ optimizes this to a single jmp. I've not yet verified this for other compilers. */
2501  switch (order)
2502  {
2503  case 32: prediction += coefficients[31] * pDecodedSamples[-32];
2504  case 31: prediction += coefficients[30] * pDecodedSamples[-31];
2505  case 30: prediction += coefficients[29] * pDecodedSamples[-30];
2506  case 29: prediction += coefficients[28] * pDecodedSamples[-29];
2507  case 28: prediction += coefficients[27] * pDecodedSamples[-28];
2508  case 27: prediction += coefficients[26] * pDecodedSamples[-27];
2509  case 26: prediction += coefficients[25] * pDecodedSamples[-26];
2510  case 25: prediction += coefficients[24] * pDecodedSamples[-25];
2511  case 24: prediction += coefficients[23] * pDecodedSamples[-24];
2512  case 23: prediction += coefficients[22] * pDecodedSamples[-23];
2513  case 22: prediction += coefficients[21] * pDecodedSamples[-22];
2514  case 21: prediction += coefficients[20] * pDecodedSamples[-21];
2515  case 20: prediction += coefficients[19] * pDecodedSamples[-20];
2516  case 19: prediction += coefficients[18] * pDecodedSamples[-19];
2517  case 18: prediction += coefficients[17] * pDecodedSamples[-18];
2518  case 17: prediction += coefficients[16] * pDecodedSamples[-17];
2519  case 16: prediction += coefficients[15] * pDecodedSamples[-16];
2520  case 15: prediction += coefficients[14] * pDecodedSamples[-15];
2521  case 14: prediction += coefficients[13] * pDecodedSamples[-14];
2522  case 13: prediction += coefficients[12] * pDecodedSamples[-13];
2523  case 12: prediction += coefficients[11] * pDecodedSamples[-12];
2524  case 11: prediction += coefficients[10] * pDecodedSamples[-11];
2525  case 10: prediction += coefficients[ 9] * pDecodedSamples[-10];
2526  case 9: prediction += coefficients[ 8] * pDecodedSamples[- 9];
2527  case 8: prediction += coefficients[ 7] * pDecodedSamples[- 8];
2528  case 7: prediction += coefficients[ 6] * pDecodedSamples[- 7];
2529  case 6: prediction += coefficients[ 5] * pDecodedSamples[- 6];
2530  case 5: prediction += coefficients[ 4] * pDecodedSamples[- 5];
2531  case 4: prediction += coefficients[ 3] * pDecodedSamples[- 4];
2532  case 3: prediction += coefficients[ 2] * pDecodedSamples[- 3];
2533  case 2: prediction += coefficients[ 1] * pDecodedSamples[- 2];
2534  case 1: prediction += coefficients[ 0] * pDecodedSamples[- 1];
2535  }
2536 
2537  return (drflac_int32)(prediction >> shift);
2538 }
2539 
2540 static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
2541 {
2542  drflac_int64 prediction;
2543 
2544  DRFLAC_ASSERT(order <= 32);
2545 
2546  /* 64-bit version. */
2547 
2548  /* This method is faster on the 32-bit build when compiling with VC++. See note below. */
2549 #ifndef DRFLAC_64BIT
2550  if (order == 8)
2551  {
2552  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2553  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2554  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2555  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2556  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2557  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2558  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2559  prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
2560  }
2561  else if (order == 7)
2562  {
2563  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2564  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2565  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2566  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2567  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2568  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2569  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2570  }
2571  else if (order == 3)
2572  {
2573  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2574  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2575  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2576  }
2577  else if (order == 6)
2578  {
2579  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2580  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2581  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2582  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2583  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2584  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2585  }
2586  else if (order == 5)
2587  {
2588  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2589  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2590  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2591  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2592  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2593  }
2594  else if (order == 4)
2595  {
2596  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2597  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2598  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2599  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2600  }
2601  else if (order == 12)
2602  {
2603  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2604  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2605  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2606  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2607  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2608  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2609  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2610  prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
2611  prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
2612  prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
2613  prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
2614  prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
2615  }
2616  else if (order == 2)
2617  {
2618  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2619  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2620  }
2621  else if (order == 1)
2622  {
2623  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2624  }
2625  else if (order == 10)
2626  {
2627  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2628  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2629  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2630  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2631  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2632  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2633  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2634  prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
2635  prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
2636  prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
2637  }
2638  else if (order == 9)
2639  {
2640  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2641  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2642  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2643  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2644  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2645  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2646  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2647  prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
2648  prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
2649  }
2650  else if (order == 11)
2651  {
2652  prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
2653  prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
2654  prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
2655  prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
2656  prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
2657  prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
2658  prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
2659  prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
2660  prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
2661  prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
2662  prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
2663  }
2664  else
2665  {
2666  int j;
2667 
2668  prediction = 0;
2669  for (j = 0; j < (int)order; ++j) {
2670  prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1];
2671  }
2672  }
2673 #endif
2674 
2675  /*
2676  VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some
2677  reason. The ugly version above is faster so we'll just switch between the two depending on the target platform.
2678  */
2679 #ifdef DRFLAC_64BIT
2680  prediction = 0;
2681  switch (order)
2682  {
2683  case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
2684  case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
2685  case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
2686  case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
2687  case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
2688  case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
2689  case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
2690  case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
2691  case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
2692  case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
2693  case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
2694  case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
2695  case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
2696  case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
2697  case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
2698  case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
2699  case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
2700  case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
2701  case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
2702  case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
2703  case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
2704  case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
2705  case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
2706  case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
2707  case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
2708  case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
2709  case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
2710  case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
2711  case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
2712  case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
2713  case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
2714  case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
2715  }
2716 #endif
2717 
2718  return (drflac_int32)(prediction >> shift);
2719 }
2720 
2721 
2722 #if 0
2723 /*
2724 Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the
2725 sake of readability and should only be used as a reference.
2726 */
2727 static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
2728 {
2729  drflac_uint32 i;
2730 
2731  DRFLAC_ASSERT(bs != NULL);
2732  DRFLAC_ASSERT(count > 0);
2733  DRFLAC_ASSERT(pSamplesOut != NULL);
2734 
2735  for (i = 0; i < count; ++i) {
2736  drflac_uint32 zeroCounter = 0;
2737  for (;;) {
2738  drflac_uint8 bit;
2739  if (!drflac__read_uint8(bs, 1, &bit)) {
2740  return DRFLAC_FALSE;
2741  }
2742 
2743  if (bit == 0) {
2744  zeroCounter += 1;
2745  } else {
2746  break;
2747  }
2748  }
2749 
2750  drflac_uint32 decodedRice;
2751  if (riceParam > 0) {
2752  if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
2753  return DRFLAC_FALSE;
2754  }
2755  } else {
2756  decodedRice = 0;
2757  }
2758 
2759  decodedRice |= (zeroCounter << riceParam);
2760  if ((decodedRice & 0x01)) {
2761  decodedRice = ~(decodedRice >> 1);
2762  } else {
2763  decodedRice = (decodedRice >> 1);
2764  }
2765 
2766 
2767  if (bitsPerSample+shift >= 32) {
2768  pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
2769  } else {
2770  pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
2771  }
2772  }
2773 
2774  return DRFLAC_TRUE;
2775 }
2776 #endif
2777 
2778 #if 0
2779 static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
2780 {
2781  drflac_uint32 zeroCounter = 0;
2782  drflac_uint32 decodedRice;
2783 
2784  for (;;) {
2785  drflac_uint8 bit;
2786  if (!drflac__read_uint8(bs, 1, &bit)) {
2787  return DRFLAC_FALSE;
2788  }
2789 
2790  if (bit == 0) {
2791  zeroCounter += 1;
2792  } else {
2793  break;
2794  }
2795  }
2796 
2797  if (riceParam > 0) {
2798  if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
2799  return DRFLAC_FALSE;
2800  }
2801  } else {
2802  decodedRice = 0;
2803  }
2804 
2805  *pZeroCounterOut = zeroCounter;
2806  *pRiceParamPartOut = decodedRice;
2807  return DRFLAC_TRUE;
2808 }
2809 #endif
2810 
2811 #if 0
2812 static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
2813 {
2814  drflac_cache_t riceParamMask;
2815  drflac_uint32 zeroCounter;
2816  drflac_uint32 setBitOffsetPlus1;
2817  drflac_uint32 riceParamPart;
2818  drflac_uint32 riceLength;
2819 
2820  DRFLAC_ASSERT(riceParam > 0); /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */
2821 
2822  riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
2823 
2824  zeroCounter = 0;
2825  while (bs->cache == 0) {
2826  zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2827  if (!drflac__reload_cache(bs)) {
2828  return DRFLAC_FALSE;
2829  }
2830  }
2831 
2832  setBitOffsetPlus1 = drflac__clz(bs->cache);
2833  zeroCounter += setBitOffsetPlus1;
2834  setBitOffsetPlus1 += 1;
2835 
2836  riceLength = setBitOffsetPlus1 + riceParam;
2837  if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2838  riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
2839 
2840  bs->consumedBits += riceLength;
2841  bs->cache <<= riceLength;
2842  } else {
2843  drflac_uint32 bitCountLo;
2844  drflac_cache_t resultHi;
2845 
2846  bs->consumedBits += riceLength;
2847  bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1); /* <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }" */
2848 
2849  /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */
2850  bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
2851  resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam); /* <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0. */
2852 
2853  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
2854 #ifndef DR_FLAC_NO_CRC
2856 #endif
2858  bs->consumedBits = 0;
2859 #ifndef DR_FLAC_NO_CRC
2860  bs->crc16Cache = bs->cache;
2861 #endif
2862  } else {
2863  /* Slow path. We need to fetch more data from the client. */
2864  if (!drflac__reload_cache(bs)) {
2865  return DRFLAC_FALSE;
2866  }
2867  }
2868 
2869  riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
2870 
2871  bs->consumedBits += bitCountLo;
2872  bs->cache <<= bitCountLo;
2873  }
2874 
2875  pZeroCounterOut[0] = zeroCounter;
2876  pRiceParamPartOut[0] = riceParamPart;
2877 
2878  return DRFLAC_TRUE;
2879 }
2880 #endif
2881 
2882 static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
2883 {
2884  drflac_uint32 riceParamPlus1 = riceParam + 1;
2885  /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/
2886  drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
2887  drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
2888 
2889  /*
2890  The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
2891  no idea how this will work in practice...
2892  */
2893  drflac_cache_t bs_cache = bs->cache;
2894  drflac_uint32 bs_consumedBits = bs->consumedBits;
2895 
2896  /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
2897  drflac_uint32 lzcount = drflac__clz(bs_cache);
2898  if (lzcount < sizeof(bs_cache)*8) {
2899  pZeroCounterOut[0] = lzcount;
2900 
2901  /*
2902  It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
2903  this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
2904  outside of this function at a higher level.
2905  */
2906  extract_rice_param_part:
2907  bs_cache <<= lzcount;
2908  bs_consumedBits += lzcount;
2909 
2910  if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
2911  /* Getting here means the rice parameter part is wholly contained within the current cache line. */
2912  pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
2913  bs_cache <<= riceParamPlus1;
2914  bs_consumedBits += riceParamPlus1;
2915  } else {
2916  drflac_uint32 riceParamPartHi;
2917  drflac_uint32 riceParamPartLo;
2918  drflac_uint32 riceParamPartLoBitCount;
2919 
2920  /*
2921  Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
2922  line, reload the cache, and then combine it with the head of the next cache line.
2923  */
2924 
2925  /* Grab the high part of the rice parameter part. */
2926  riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
2927 
2928  /* Before reloading the cache we need to grab the size in bits of the low part. */
2929  riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
2930  DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
2931 
2932  /* Now reload the cache. */
2933  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
2934  #ifndef DR_FLAC_NO_CRC
2936  #endif
2937  bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
2938  bs_consumedBits = riceParamPartLoBitCount;
2939  #ifndef DR_FLAC_NO_CRC
2940  bs->crc16Cache = bs_cache;
2941  #endif
2942  } else {
2943  /* Slow path. We need to fetch more data from the client. */
2944  if (!drflac__reload_cache(bs)) {
2945  return DRFLAC_FALSE;
2946  }
2947 
2948  bs_cache = bs->cache;
2949  bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
2950  }
2951 
2952  /* We should now have enough information to construct the rice parameter part. */
2953  riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount)));
2954  pRiceParamPartOut[0] = riceParamPartHi | riceParamPartLo;
2955 
2956  bs_cache <<= riceParamPartLoBitCount;
2957  }
2958  } else {
2959  /*
2960  Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
2961  to drflac__clz() and we need to reload the cache.
2962  */
2963  drflac_uint32 zeroCounter = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs_consumedBits);
2964  for (;;) {
2965  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
2966  #ifndef DR_FLAC_NO_CRC
2968  #endif
2969  bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
2970  bs_consumedBits = 0;
2971  #ifndef DR_FLAC_NO_CRC
2972  bs->crc16Cache = bs_cache;
2973  #endif
2974  } else {
2975  /* Slow path. We need to fetch more data from the client. */
2976  if (!drflac__reload_cache(bs)) {
2977  return DRFLAC_FALSE;
2978  }
2979 
2980  bs_cache = bs->cache;
2981  bs_consumedBits = bs->consumedBits;
2982  }
2983 
2984  lzcount = drflac__clz(bs_cache);
2985  zeroCounter += lzcount;
2986 
2987  if (lzcount < sizeof(bs_cache)*8) {
2988  break;
2989  }
2990  }
2991 
2992  pZeroCounterOut[0] = zeroCounter;
2993  goto extract_rice_param_part;
2994  }
2995 
2996  /* Make sure the cache is restored at the end of it all. */
2997  bs->cache = bs_cache;
2998  bs->consumedBits = bs_consumedBits;
2999 
3000  return DRFLAC_TRUE;
3001 }
3002 
3004 {
3005  drflac_uint32 riceParamPlus1 = riceParam + 1;
3006  drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
3007 
3008  /*
3009  The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
3010  no idea how this will work in practice...
3011  */
3012  drflac_cache_t bs_cache = bs->cache;
3013  drflac_uint32 bs_consumedBits = bs->consumedBits;
3014 
3015  /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
3016  drflac_uint32 lzcount = drflac__clz(bs_cache);
3017  if (lzcount < sizeof(bs_cache)*8) {
3018  /*
3019  It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
3020  this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
3021  outside of this function at a higher level.
3022  */
3023  extract_rice_param_part:
3024  bs_cache <<= lzcount;
3025  bs_consumedBits += lzcount;
3026 
3027  if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
3028  /* Getting here means the rice parameter part is wholly contained within the current cache line. */
3029  bs_cache <<= riceParamPlus1;
3030  bs_consumedBits += riceParamPlus1;
3031  } else {
3032  /*
3033  Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
3034  line, reload the cache, and then combine it with the head of the next cache line.
3035  */
3036 
3037  /* Before reloading the cache we need to grab the size in bits of the low part. */
3038  drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
3039  DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
3040 
3041  /* Now reload the cache. */
3042  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3043  #ifndef DR_FLAC_NO_CRC
3045  #endif
3046  bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3047  bs_consumedBits = riceParamPartLoBitCount;
3048  #ifndef DR_FLAC_NO_CRC
3049  bs->crc16Cache = bs_cache;
3050  #endif
3051  } else {
3052  /* Slow path. We need to fetch more data from the client. */
3053  if (!drflac__reload_cache(bs)) {
3054  return DRFLAC_FALSE;
3055  }
3056 
3057  bs_cache = bs->cache;
3058  bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
3059  }
3060 
3061  bs_cache <<= riceParamPartLoBitCount;
3062  }
3063  } else {
3064  /*
3065  Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
3066  to drflac__clz() and we need to reload the cache.
3067  */
3068  for (;;) {
3069  if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3070  #ifndef DR_FLAC_NO_CRC
3072  #endif
3073  bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3074  bs_consumedBits = 0;
3075  #ifndef DR_FLAC_NO_CRC
3076  bs->crc16Cache = bs_cache;
3077  #endif
3078  } else {
3079  /* Slow path. We need to fetch more data from the client. */
3080  if (!drflac__reload_cache(bs)) {
3081  return DRFLAC_FALSE;
3082  }
3083 
3084  bs_cache = bs->cache;
3085  bs_consumedBits = bs->consumedBits;
3086  }
3087 
3088  lzcount = drflac__clz(bs_cache);
3089  if (lzcount < sizeof(bs_cache)*8) {
3090  break;
3091  }
3092  }
3093 
3094  goto extract_rice_param_part;
3095  }
3096 
3097  /* Make sure the cache is restored at the end of it all. */
3098  bs->cache = bs_cache;
3099  bs->consumedBits = bs_consumedBits;
3100 
3101  return DRFLAC_TRUE;
3102 }
3103 
3104 
3106 {
3107  drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3108  drflac_uint32 zeroCountPart0;
3109  drflac_uint32 riceParamPart0;
3110  drflac_uint32 riceParamMask;
3111  drflac_uint32 i;
3112 
3113  DRFLAC_ASSERT(bs != NULL);
3114  DRFLAC_ASSERT(count > 0);
3115  DRFLAC_ASSERT(pSamplesOut != NULL);
3116 
3117  (void)bitsPerSample;
3118  (void)order;
3119  (void)shift;
3120  (void)coefficients;
3121 
3122  riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3123 
3124  i = 0;
3125  while (i < count) {
3126  /* Rice extraction. */
3127  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3128  return DRFLAC_FALSE;
3129  }
3130 
3131  /* Rice reconstruction. */
3132  riceParamPart0 &= riceParamMask;
3133  riceParamPart0 |= (zeroCountPart0 << riceParam);
3134  riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3135 
3136  pSamplesOut[i] = riceParamPart0;
3137 
3138  i += 1;
3139  }
3140 
3141  return DRFLAC_TRUE;
3142 }
3143 
3145 {
3146  drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3147  drflac_uint32 zeroCountPart0 = 0;
3148  drflac_uint32 zeroCountPart1 = 0;
3149  drflac_uint32 zeroCountPart2 = 0;
3150  drflac_uint32 zeroCountPart3 = 0;
3151  drflac_uint32 riceParamPart0 = 0;
3152  drflac_uint32 riceParamPart1 = 0;
3153  drflac_uint32 riceParamPart2 = 0;
3154  drflac_uint32 riceParamPart3 = 0;
3155  drflac_uint32 riceParamMask;
3156  const drflac_int32* pSamplesOutEnd;
3157  drflac_uint32 i;
3158 
3159  DRFLAC_ASSERT(bs != NULL);
3160  DRFLAC_ASSERT(count > 0);
3161  DRFLAC_ASSERT(pSamplesOut != NULL);
3162 
3163  if (order == 0) {
3164  return drflac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
3165  }
3166 
3167  riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3168  pSamplesOutEnd = pSamplesOut + (count & ~3);
3169 
3170  if (bitsPerSample+shift > 32) {
3171  while (pSamplesOut < pSamplesOutEnd) {
3172  /*
3173  Rice extraction. It's faster to do this one at a time against local variables than it is to use the x4 version
3174  against an array. Not sure why, but perhaps it's making more efficient use of registers?
3175  */
3176  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3177  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3178  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3179  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3180  return DRFLAC_FALSE;
3181  }
3182 
3183  riceParamPart0 &= riceParamMask;
3184  riceParamPart1 &= riceParamMask;
3185  riceParamPart2 &= riceParamMask;
3186  riceParamPart3 &= riceParamMask;
3187 
3188  riceParamPart0 |= (zeroCountPart0 << riceParam);
3189  riceParamPart1 |= (zeroCountPart1 << riceParam);
3190  riceParamPart2 |= (zeroCountPart2 << riceParam);
3191  riceParamPart3 |= (zeroCountPart3 << riceParam);
3192 
3193  riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3194  riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3195  riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3196  riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3197 
3198  pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0);
3199  pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 1);
3200  pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 2);
3201  pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 3);
3202 
3203  pSamplesOut += 4;
3204  }
3205  } else {
3206  while (pSamplesOut < pSamplesOutEnd) {
3207  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3208  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3209  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3210  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3211  return DRFLAC_FALSE;
3212  }
3213 
3214  riceParamPart0 &= riceParamMask;
3215  riceParamPart1 &= riceParamMask;
3216  riceParamPart2 &= riceParamMask;
3217  riceParamPart3 &= riceParamMask;
3218 
3219  riceParamPart0 |= (zeroCountPart0 << riceParam);
3220  riceParamPart1 |= (zeroCountPart1 << riceParam);
3221  riceParamPart2 |= (zeroCountPart2 << riceParam);
3222  riceParamPart3 |= (zeroCountPart3 << riceParam);
3223 
3224  riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3225  riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3226  riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3227  riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3228 
3229  pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
3230  pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 1);
3231  pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 2);
3232  pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 3);
3233 
3234  pSamplesOut += 4;
3235  }
3236  }
3237 
3238  i = (count & ~3);
3239  while (i < count) {
3240  /* Rice extraction. */
3241  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3242  return DRFLAC_FALSE;
3243  }
3244 
3245  /* Rice reconstruction. */
3246  riceParamPart0 &= riceParamMask;
3247  riceParamPart0 |= (zeroCountPart0 << riceParam);
3248  riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3249  /*riceParamPart0 = (riceParamPart0 >> 1) ^ (~(riceParamPart0 & 0x01) + 1);*/
3250 
3251  /* Sample reconstruction. */
3252  if (bitsPerSample+shift > 32) {
3253  pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0);
3254  } else {
3255  pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
3256  }
3257 
3258  i += 1;
3259  pSamplesOut += 1;
3260  }
3261 
3262  return DRFLAC_TRUE;
3263 }
3264 
3265 #if defined(DRFLAC_SUPPORT_SSE2)
3266 static DRFLAC_INLINE __m128i drflac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
3267 {
3268  __m128i r;
3269 
3270  /* Pack. */
3271  r = _mm_packs_epi32(a, b);
3272 
3273  /* a3a2 a1a0 b3b2 b1b0 -> a3a2 b3b2 a1a0 b1b0 */
3274  r = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 1, 2, 0));
3275 
3276  /* a3a2 b3b2 a1a0 b1b0 -> a3b3 a2b2 a1b1 a0b0 */
3277  r = _mm_shufflehi_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3278  r = _mm_shufflelo_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3279 
3280  return r;
3281 }
3282 #endif
3283 
3284 #if defined(DRFLAC_SUPPORT_SSE41)
3285 static DRFLAC_INLINE __m128i drflac__mm_not_si128(__m128i a)
3286 {
3287  return _mm_xor_si128(a, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()));
3288 }
3289 
3290 static DRFLAC_INLINE __m128i drflac__mm_hadd_epi32(__m128i x)
3291 {
3292  __m128i x64 = _mm_add_epi32(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3293  __m128i x32 = _mm_shufflelo_epi16(x64, _MM_SHUFFLE(1, 0, 3, 2));
3294  return _mm_add_epi32(x64, x32);
3295 }
3296 
3297 static DRFLAC_INLINE __m128i drflac__mm_hadd_epi64(__m128i x)
3298 {
3299  return _mm_add_epi64(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3300 }
3301 
3302 static DRFLAC_INLINE __m128i drflac__mm_srai_epi64(__m128i x, int count)
3303 {
3304  /*
3305  To simplify this we are assuming count < 32. This restriction allows us to work on a low side and a high side. The low side
3306  is shifted with zero bits, whereas the right side is shifted with sign bits.
3307  */
3308  __m128i lo = _mm_srli_epi64(x, count);
3309  __m128i hi = _mm_srai_epi32(x, count);
3310 
3311  hi = _mm_and_si128(hi, _mm_set_epi32(0xFFFFFFFF, 0, 0xFFFFFFFF, 0)); /* The high part needs to have the low part cleared. */
3312 
3313  return _mm_or_si128(lo, hi);
3314 }
3315 
3316 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3317 {
3318  int i;
3319  drflac_uint32 riceParamMask;
3320  drflac_int32* pDecodedSamples = pSamplesOut;
3321  drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
3322  drflac_uint32 zeroCountParts0 = 0;
3323  drflac_uint32 zeroCountParts1 = 0;
3324  drflac_uint32 zeroCountParts2 = 0;
3325  drflac_uint32 zeroCountParts3 = 0;
3326  drflac_uint32 riceParamParts0 = 0;
3327  drflac_uint32 riceParamParts1 = 0;
3328  drflac_uint32 riceParamParts2 = 0;
3329  drflac_uint32 riceParamParts3 = 0;
3330  __m128i coefficients128_0;
3331  __m128i coefficients128_4;
3332  __m128i coefficients128_8;
3333  __m128i samples128_0;
3334  __m128i samples128_4;
3335  __m128i samples128_8;
3336  __m128i riceParamMask128;
3337 
3338  const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3339 
3340  riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3341  riceParamMask128 = _mm_set1_epi32(riceParamMask);
3342 
3343  /* Pre-load. */
3344  coefficients128_0 = _mm_setzero_si128();
3345  coefficients128_4 = _mm_setzero_si128();
3346  coefficients128_8 = _mm_setzero_si128();
3347 
3348  samples128_0 = _mm_setzero_si128();
3349  samples128_4 = _mm_setzero_si128();
3350  samples128_8 = _mm_setzero_si128();
3351 
3352  /*
3353  Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
3354  what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
3355  in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
3356  so I think there's opportunity for this to be simplified.
3357  */
3358 #if 1
3359  {
3360  int runningOrder = order;
3361 
3362  /* 0 - 3. */
3363  if (runningOrder >= 4) {
3364  coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
3365  samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
3366  runningOrder -= 4;
3367  } else {
3368  switch (runningOrder) {
3369  case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
3370  case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
3371  case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
3372  }
3373  runningOrder = 0;
3374  }
3375 
3376  /* 4 - 7 */
3377  if (runningOrder >= 4) {
3378  coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
3379  samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
3380  runningOrder -= 4;
3381  } else {
3382  switch (runningOrder) {
3383  case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
3384  case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
3385  case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
3386  }
3387  runningOrder = 0;
3388  }
3389 
3390  /* 8 - 11 */
3391  if (runningOrder == 4) {
3392  coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
3393  samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
3394  runningOrder -= 4;
3395  } else {
3396  switch (runningOrder) {
3397  case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
3398  case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
3399  case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
3400  }
3401  runningOrder = 0;
3402  }
3403 
3404  /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
3405  coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
3406  coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
3407  coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
3408  }
3409 #else
3410  /* This causes strict-aliasing warnings with GCC. */
3411  switch (order)
3412  {
3413  case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
3414  case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
3415  case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
3416  case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
3417  case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
3418  case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
3419  case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
3420  case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
3421  case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
3422  case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
3423  case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
3424  case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
3425  }
3426 #endif
3427 
3428  /* For this version we are doing one sample at a time. */
3429  while (pDecodedSamples < pDecodedSamplesEnd) {
3430  __m128i prediction128;
3431  __m128i zeroCountPart128;
3432  __m128i riceParamPart128;
3433 
3434  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
3435  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
3436  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
3437  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
3438  return DRFLAC_FALSE;
3439  }
3440 
3441  zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
3442  riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
3443 
3444  riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
3445  riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
3446  riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01))), _mm_set1_epi32(0x01))); /* <-- SSE2 compatible */
3447  /*riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_mullo_epi32(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01)), _mm_set1_epi32(0xFFFFFFFF)));*/ /* <-- Only supported from SSE4.1 and is slower in my testing... */
3448 
3449  if (order <= 4) {
3450  for (i = 0; i < 4; i += 1) {
3451  prediction128 = _mm_mullo_epi32(coefficients128_0, samples128_0);
3452 
3453  /* Horizontal add and shift. */
3454  prediction128 = drflac__mm_hadd_epi32(prediction128);
3455  prediction128 = _mm_srai_epi32(prediction128, shift);
3456  prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
3457 
3458  samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
3459  riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
3460  }
3461  } else if (order <= 8) {
3462  for (i = 0; i < 4; i += 1) {
3463  prediction128 = _mm_mullo_epi32(coefficients128_4, samples128_4);
3464  prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
3465 
3466  /* Horizontal add and shift. */
3467  prediction128 = drflac__mm_hadd_epi32(prediction128);
3468  prediction128 = _mm_srai_epi32(prediction128, shift);
3469  prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
3470 
3471  samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
3472  samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
3473  riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
3474  }
3475  } else {
3476  for (i = 0; i < 4; i += 1) {
3477  prediction128 = _mm_mullo_epi32(coefficients128_8, samples128_8);
3478  prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_4, samples128_4));
3479  prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
3480 
3481  /* Horizontal add and shift. */
3482  prediction128 = drflac__mm_hadd_epi32(prediction128);
3483  prediction128 = _mm_srai_epi32(prediction128, shift);
3484  prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
3485 
3486  samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
3487  samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
3488  samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
3489  riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
3490  }
3491  }
3492 
3493  /* We store samples in groups of 4. */
3494  _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
3495  pDecodedSamples += 4;
3496  }
3497 
3498  /* Make sure we process the last few samples. */
3499  i = (count & ~3);
3500  while (i < (int)count) {
3501  /* Rice extraction. */
3502  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
3503  return DRFLAC_FALSE;
3504  }
3505 
3506  /* Rice reconstruction. */
3507  riceParamParts0 &= riceParamMask;
3508  riceParamParts0 |= (zeroCountParts0 << riceParam);
3509  riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
3510 
3511  /* Sample reconstruction. */
3512  pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
3513 
3514  i += 1;
3515  pDecodedSamples += 1;
3516  }
3517 
3518  return DRFLAC_TRUE;
3519 }
3520 
3521 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3522 {
3523  int i;
3524  drflac_uint32 riceParamMask;
3525  drflac_int32* pDecodedSamples = pSamplesOut;
3526  drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
3527  drflac_uint32 zeroCountParts0 = 0;
3528  drflac_uint32 zeroCountParts1 = 0;
3529  drflac_uint32 zeroCountParts2 = 0;
3530  drflac_uint32 zeroCountParts3 = 0;
3531  drflac_uint32 riceParamParts0 = 0;
3532  drflac_uint32 riceParamParts1 = 0;
3533  drflac_uint32 riceParamParts2 = 0;
3534  drflac_uint32 riceParamParts3 = 0;
3535  __m128i coefficients128_0;
3536  __m128i coefficients128_4;
3537  __m128i coefficients128_8;
3538  __m128i samples128_0;
3539  __m128i samples128_4;
3540  __m128i samples128_8;
3541  __m128i prediction128;
3542  __m128i riceParamMask128;
3543 
3544  const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3545 
3546  DRFLAC_ASSERT(order <= 12);
3547 
3548  riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
3549  riceParamMask128 = _mm_set1_epi32(riceParamMask);
3550 
3551  prediction128 = _mm_setzero_si128();
3552 
3553  /* Pre-load. */
3554  coefficients128_0 = _mm_setzero_si128();
3555  coefficients128_4 = _mm_setzero_si128();
3556  coefficients128_8 = _mm_setzero_si128();
3557 
3558  samples128_0 = _mm_setzero_si128();
3559  samples128_4 = _mm_setzero_si128();
3560  samples128_8 = _mm_setzero_si128();
3561 
3562 #if 1
3563  {
3564  int runningOrder = order;
3565 
3566  /* 0 - 3. */
3567  if (runningOrder >= 4) {
3568  coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
3569  samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
3570  runningOrder -= 4;
3571  } else {
3572  switch (runningOrder) {
3573  case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
3574  case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
3575  case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
3576  }
3577  runningOrder = 0;
3578  }
3579 
3580  /* 4 - 7 */
3581  if (runningOrder >= 4) {
3582  coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
3583  samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
3584  runningOrder -= 4;
3585  } else {
3586  switch (runningOrder) {
3587  case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
3588  case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
3589  case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
3590  }
3591  runningOrder = 0;
3592  }
3593 
3594  /* 8 - 11 */
3595  if (runningOrder == 4) {
3596  coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
3597  samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
3598  runningOrder -= 4;
3599  } else {
3600  switch (runningOrder) {
3601  case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
3602  case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
3603  case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
3604  }
3605  runningOrder = 0;
3606  }
3607 
3608  /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
3609  coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
3610  coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
3611  coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
3612  }
3613 #else
3614  switch (order)
3615  {
3616  case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
3617  case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
3618  case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
3619  case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
3620  case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
3621  case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
3622  case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
3623  case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
3624  case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
3625  case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
3626  case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
3627  case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
3628  }
3629 #endif
3630 
3631  /* For this version we are doing one sample at a time. */
3632  while (pDecodedSamples < pDecodedSamplesEnd) {
3633  __m128i zeroCountPart128;
3634  __m128i riceParamPart128;
3635 
3636  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
3637  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
3638  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
3639  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
3640  return DRFLAC_FALSE;
3641  }
3642 
3643  zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
3644  riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
3645 
3646  riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
3647  riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
3648  riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(1))), _mm_set1_epi32(1)));
3649 
3650  for (i = 0; i < 4; i += 1) {
3651  prediction128 = _mm_xor_si128(prediction128, prediction128); /* Reset to 0. */
3652 
3653  switch (order)
3654  {
3655  case 12:
3656  case 11: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(1, 1, 0, 0))));
3657  case 10:
3658  case 9: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(3, 3, 2, 2))));
3659  case 8:
3660  case 7: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(1, 1, 0, 0))));
3661  case 6:
3662  case 5: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(3, 3, 2, 2))));
3663  case 4:
3664  case 3: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(1, 1, 0, 0))));
3665  case 2:
3666  case 1: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(3, 3, 2, 2))));
3667  }
3668 
3669  /* Horizontal add and shift. */
3670  prediction128 = drflac__mm_hadd_epi64(prediction128);
3671  prediction128 = drflac__mm_srai_epi64(prediction128, shift);
3672  prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
3673 
3674  /* Our value should be sitting in prediction128[0]. We need to combine this with our SSE samples. */
3675  samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
3676  samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
3677  samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
3678 
3679  /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
3680  riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
3681  }
3682 
3683  /* We store samples in groups of 4. */
3684  _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
3685  pDecodedSamples += 4;
3686  }
3687 
3688  /* Make sure we process the last few samples. */
3689  i = (count & ~3);
3690  while (i < (int)count) {
3691  /* Rice extraction. */
3692  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
3693  return DRFLAC_FALSE;
3694  }
3695 
3696  /* Rice reconstruction. */
3697  riceParamParts0 &= riceParamMask;
3698  riceParamParts0 |= (zeroCountParts0 << riceParam);
3699  riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
3700 
3701  /* Sample reconstruction. */
3702  pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
3703 
3704  i += 1;
3705  pDecodedSamples += 1;
3706  }
3707 
3708  return DRFLAC_TRUE;
3709 }
3710 
3711 static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3712 {
3713  DRFLAC_ASSERT(bs != NULL);
3714  DRFLAC_ASSERT(count > 0);
3715  DRFLAC_ASSERT(pSamplesOut != NULL);
3716 
3717  /* In my testing the order is rarely > 12, so in this case I'm going to simplify the SSE implementation by only handling order <= 12. */
3718  if (order > 0 && order <= 12) {
3719  if (bitsPerSample+shift > 32) {
3720  return drflac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
3721  } else {
3722  return drflac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
3723  }
3724  } else {
3725  return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
3726  }
3727 }
3728 #endif
3729 
3730 #if defined(DRFLAC_SUPPORT_NEON)
3731 static DRFLAC_INLINE void drflac__vst2q_s32(drflac_int32* p, int32x4x2_t x)
3732 {
3733  vst1q_s32(p+0, x.val[0]);
3734  vst1q_s32(p+4, x.val[1]);
3735 }
3736 
3737 static DRFLAC_INLINE void drflac__vst2q_f32(float* p, float32x4x2_t x)
3738 {
3739  vst1q_f32(p+0, x.val[0]);
3740  vst1q_f32(p+4, x.val[1]);
3741 }
3742 
3743 static DRFLAC_INLINE void drflac__vst2q_s16(drflac_int16* p, int16x4x2_t x)
3744 {
3745  vst1q_s16(p, vcombine_s16(x.val[0], x.val[1]));
3746 }
3747 
3748 static DRFLAC_INLINE int32x4_t drflac__vdupq_n_s32x4(drflac_int32 x3, drflac_int32 x2, drflac_int32 x1, drflac_int32 x0)
3749 {
3750  drflac_int32 x[4];
3751  x[3] = x3;
3752  x[2] = x2;
3753  x[1] = x1;
3754  x[0] = x0;
3755  return vld1q_s32(x);
3756 }
3757 
3758 static DRFLAC_INLINE int32x4_t drflac__valignrq_s32_1(int32x4_t a, int32x4_t b)
3759 {
3760  /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
3761 
3762  /* Reference */
3763  /*return drflac__vdupq_n_s32x4(
3764  vgetq_lane_s32(a, 0),
3765  vgetq_lane_s32(b, 3),
3766  vgetq_lane_s32(b, 2),
3767  vgetq_lane_s32(b, 1)
3768  );*/
3769 
3770  return vextq_s32(b, a, 1);
3771 }
3772 
3773 static DRFLAC_INLINE uint32x4_t drflac__valignrq_u32_1(uint32x4_t a, uint32x4_t b)
3774 {
3775  /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
3776 
3777  /* Reference */
3778  /*return drflac__vdupq_n_s32x4(
3779  vgetq_lane_s32(a, 0),
3780  vgetq_lane_s32(b, 3),
3781  vgetq_lane_s32(b, 2),
3782  vgetq_lane_s32(b, 1)
3783  );*/
3784 
3785  return vextq_u32(b, a, 1);
3786 }
3787 
3788 static DRFLAC_INLINE int32x2_t drflac__vhaddq_s32(int32x4_t x)
3789 {
3790  /* The sum must end up in position 0. */
3791 
3792  /* Reference */
3793  /*return vdupq_n_s32(
3794  vgetq_lane_s32(x, 3) +
3795  vgetq_lane_s32(x, 2) +
3796  vgetq_lane_s32(x, 1) +
3797  vgetq_lane_s32(x, 0)
3798  );*/
3799 
3800  int32x2_t r = vadd_s32(vget_high_s32(x), vget_low_s32(x));
3801  return vpadd_s32(r, r);
3802 }
3803 
3804 static DRFLAC_INLINE int64x1_t drflac__vhaddq_s64(int64x2_t x)
3805 {
3806  return vadd_s64(vget_high_s64(x), vget_low_s64(x));
3807 }
3808 
3809 static DRFLAC_INLINE int32x4_t drflac__vrevq_s32(int32x4_t x)
3810 {
3811  /* Reference */
3812  /*return drflac__vdupq_n_s32x4(
3813  vgetq_lane_s32(x, 0),
3814  vgetq_lane_s32(x, 1),
3815  vgetq_lane_s32(x, 2),
3816  vgetq_lane_s32(x, 3)
3817  );*/
3818 
3819  return vrev64q_s32(vcombine_s32(vget_high_s32(x), vget_low_s32(x)));
3820 }
3821 
3822 static DRFLAC_INLINE int32x4_t drflac__vnotq_s32(int32x4_t x)
3823 {
3824  return veorq_s32(x, vdupq_n_s32(0xFFFFFFFF));
3825 }
3826 
3827 static DRFLAC_INLINE uint32x4_t drflac__vnotq_u32(uint32x4_t x)
3828 {
3829  return veorq_u32(x, vdupq_n_u32(0xFFFFFFFF));
3830 }
3831 
3832 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3833 {
3834  int i;
3835  drflac_uint32 riceParamMask;
3836  drflac_int32* pDecodedSamples = pSamplesOut;
3837  drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
3838  drflac_uint32 zeroCountParts[4];
3839  drflac_uint32 riceParamParts[4];
3840  int32x4_t coefficients128_0;
3841  int32x4_t coefficients128_4;
3842  int32x4_t coefficients128_8;
3843  int32x4_t samples128_0;
3844  int32x4_t samples128_4;
3845  int32x4_t samples128_8;
3846  uint32x4_t riceParamMask128;
3847  int32x4_t riceParam128;
3848  int32x2_t shift64;
3849  uint32x4_t one128;
3850 
3851  const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3852 
3853  riceParamMask = ~((~0UL) << riceParam);
3854  riceParamMask128 = vdupq_n_u32(riceParamMask);
3855 
3856  riceParam128 = vdupq_n_s32(riceParam);
3857  shift64 = vdup_n_s32(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
3858  one128 = vdupq_n_u32(1);
3859 
3860  /*
3861  Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
3862  what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
3863  in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
3864  so I think there's opportunity for this to be simplified.
3865  */
3866  {
3867  int runningOrder = order;
3868  drflac_int32 tempC[4] = {0, 0, 0, 0};
3869  drflac_int32 tempS[4] = {0, 0, 0, 0};
3870 
3871  /* 0 - 3. */
3872  if (runningOrder >= 4) {
3873  coefficients128_0 = vld1q_s32(coefficients + 0);
3874  samples128_0 = vld1q_s32(pSamplesOut - 4);
3875  runningOrder -= 4;
3876  } else {
3877  switch (runningOrder) {
3878  case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
3879  case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
3880  case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
3881  }
3882 
3883  coefficients128_0 = vld1q_s32(tempC);
3884  samples128_0 = vld1q_s32(tempS);
3885  runningOrder = 0;
3886  }
3887 
3888  /* 4 - 7 */
3889  if (runningOrder >= 4) {
3890  coefficients128_4 = vld1q_s32(coefficients + 4);
3891  samples128_4 = vld1q_s32(pSamplesOut - 8);
3892  runningOrder -= 4;
3893  } else {
3894  switch (runningOrder) {
3895  case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
3896  case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
3897  case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
3898  }
3899 
3900  coefficients128_4 = vld1q_s32(tempC);
3901  samples128_4 = vld1q_s32(tempS);
3902  runningOrder = 0;
3903  }
3904 
3905  /* 8 - 11 */
3906  if (runningOrder == 4) {
3907  coefficients128_8 = vld1q_s32(coefficients + 8);
3908  samples128_8 = vld1q_s32(pSamplesOut - 12);
3909  runningOrder -= 4;
3910  } else {
3911  switch (runningOrder) {
3912  case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
3913  case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
3914  case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
3915  }
3916 
3917  coefficients128_8 = vld1q_s32(tempC);
3918  samples128_8 = vld1q_s32(tempS);
3919  runningOrder = 0;
3920  }
3921 
3922  /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
3923  coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
3924  coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
3925  coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
3926  }
3927 
3928  /* For this version we are doing one sample at a time. */
3929  while (pDecodedSamples < pDecodedSamplesEnd) {
3930  int32x4_t prediction128;
3931  int32x2_t prediction64;
3932  uint32x4_t zeroCountPart128;
3933  uint32x4_t riceParamPart128;
3934 
3935  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
3936  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
3937  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
3938  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
3939  return DRFLAC_FALSE;
3940  }
3941 
3942  zeroCountPart128 = vld1q_u32(zeroCountParts);
3943  riceParamPart128 = vld1q_u32(riceParamParts);
3944 
3945  riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
3946  riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
3947  riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
3948 
3949  if (order <= 4) {
3950  for (i = 0; i < 4; i += 1) {
3951  prediction128 = vmulq_s32(coefficients128_0, samples128_0);
3952 
3953  /* Horizontal add and shift. */
3954  prediction64 = drflac__vhaddq_s32(prediction128);
3955  prediction64 = vshl_s32(prediction64, shift64);
3956  prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
3957 
3958  samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
3959  riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
3960  }
3961  } else if (order <= 8) {
3962  for (i = 0; i < 4; i += 1) {
3963  prediction128 = vmulq_s32(coefficients128_4, samples128_4);
3964  prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
3965 
3966  /* Horizontal add and shift. */
3967  prediction64 = drflac__vhaddq_s32(prediction128);
3968  prediction64 = vshl_s32(prediction64, shift64);
3969  prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
3970 
3971  samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
3972  samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
3973  riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
3974  }
3975  } else {
3976  for (i = 0; i < 4; i += 1) {
3977  prediction128 = vmulq_s32(coefficients128_8, samples128_8);
3978  prediction128 = vmlaq_s32(prediction128, coefficients128_4, samples128_4);
3979  prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
3980 
3981  /* Horizontal add and shift. */
3982  prediction64 = drflac__vhaddq_s32(prediction128);
3983  prediction64 = vshl_s32(prediction64, shift64);
3984  prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
3985 
3986  samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
3987  samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
3988  samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
3989  riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
3990  }
3991  }
3992 
3993  /* We store samples in groups of 4. */
3994  vst1q_s32(pDecodedSamples, samples128_0);
3995  pDecodedSamples += 4;
3996  }
3997 
3998  /* Make sure we process the last few samples. */
3999  i = (count & ~3);
4000  while (i < (int)count) {
4001  /* Rice extraction. */
4002  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4003  return DRFLAC_FALSE;
4004  }
4005 
4006  /* Rice reconstruction. */
4007  riceParamParts[0] &= riceParamMask;
4008  riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4009  riceParamParts[0] = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4010 
4011  /* Sample reconstruction. */
4012  pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
4013 
4014  i += 1;
4015  pDecodedSamples += 1;
4016  }
4017 
4018  return DRFLAC_TRUE;
4019 }
4020 
4021 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4022 {
4023  int i;
4024  drflac_uint32 riceParamMask;
4025  drflac_int32* pDecodedSamples = pSamplesOut;
4026  drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4027  drflac_uint32 zeroCountParts[4];
4028  drflac_uint32 riceParamParts[4];
4029  int32x4_t coefficients128_0;
4030  int32x4_t coefficients128_4;
4031  int32x4_t coefficients128_8;
4032  int32x4_t samples128_0;
4033  int32x4_t samples128_4;
4034  int32x4_t samples128_8;
4035  uint32x4_t riceParamMask128;
4036  int32x4_t riceParam128;
4037  int64x1_t shift64;
4038  uint32x4_t one128;
4039 
4040  const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4041 
4042  riceParamMask = ~((~0UL) << riceParam);
4043  riceParamMask128 = vdupq_n_u32(riceParamMask);
4044 
4045  riceParam128 = vdupq_n_s32(riceParam);
4046  shift64 = vdup_n_s64(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
4047  one128 = vdupq_n_u32(1);
4048 
4049  /*
4050  Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
4051  what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
4052  in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
4053  so I think there's opportunity for this to be simplified.
4054  */
4055  {
4056  int runningOrder = order;
4057  drflac_int32 tempC[4] = {0, 0, 0, 0};
4058  drflac_int32 tempS[4] = {0, 0, 0, 0};
4059 
4060  /* 0 - 3. */
4061  if (runningOrder >= 4) {
4062  coefficients128_0 = vld1q_s32(coefficients + 0);
4063  samples128_0 = vld1q_s32(pSamplesOut - 4);
4064  runningOrder -= 4;
4065  } else {
4066  switch (runningOrder) {
4067  case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
4068  case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
4069  case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
4070  }
4071 
4072  coefficients128_0 = vld1q_s32(tempC);
4073  samples128_0 = vld1q_s32(tempS);
4074  runningOrder = 0;
4075  }
4076 
4077  /* 4 - 7 */
4078  if (runningOrder >= 4) {
4079  coefficients128_4 = vld1q_s32(coefficients + 4);
4080  samples128_4 = vld1q_s32(pSamplesOut - 8);
4081  runningOrder -= 4;
4082  } else {
4083  switch (runningOrder) {
4084  case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
4085  case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
4086  case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
4087  }
4088 
4089  coefficients128_4 = vld1q_s32(tempC);
4090  samples128_4 = vld1q_s32(tempS);
4091  runningOrder = 0;
4092  }
4093 
4094  /* 8 - 11 */
4095  if (runningOrder == 4) {
4096  coefficients128_8 = vld1q_s32(coefficients + 8);
4097  samples128_8 = vld1q_s32(pSamplesOut - 12);
4098  runningOrder -= 4;
4099  } else {
4100  switch (runningOrder) {
4101  case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
4102  case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
4103  case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
4104  }
4105 
4106  coefficients128_8 = vld1q_s32(tempC);
4107  samples128_8 = vld1q_s32(tempS);
4108  runningOrder = 0;
4109  }
4110 
4111  /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4112  coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
4113  coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
4114  coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
4115  }
4116 
4117  /* For this version we are doing one sample at a time. */
4118  while (pDecodedSamples < pDecodedSamplesEnd) {
4119  int64x2_t prediction128;
4120  uint32x4_t zeroCountPart128;
4121  uint32x4_t riceParamPart128;
4122 
4123  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
4124  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
4125  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
4126  !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
4127  return DRFLAC_FALSE;
4128  }
4129 
4130  zeroCountPart128 = vld1q_u32(zeroCountParts);
4131  riceParamPart128 = vld1q_u32(riceParamParts);
4132 
4133  riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
4134  riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
4135  riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
4136 
4137  for (i = 0; i < 4; i += 1) {
4138  int64x1_t prediction64;
4139 
4140  prediction128 = veorq_s64(prediction128, prediction128); /* Reset to 0. */
4141  switch (order)
4142  {
4143  case 12:
4144  case 11: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_8), vget_low_s32(samples128_8)));
4145  case 10:
4146  case 9: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_8), vget_high_s32(samples128_8)));
4147  case 8:
4148  case 7: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_4), vget_low_s32(samples128_4)));
4149  case 6:
4150  case 5: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_4), vget_high_s32(samples128_4)));
4151  case 4:
4152  case 3: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_0), vget_low_s32(samples128_0)));
4153  case 2:
4154  case 1: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_0), vget_high_s32(samples128_0)));
4155  }
4156 
4157  /* Horizontal add and shift. */
4158  prediction64 = drflac__vhaddq_s64(prediction128);
4159  prediction64 = vshl_s64(prediction64, shift64);
4160  prediction64 = vadd_s64(prediction64, vdup_n_s64(vgetq_lane_u32(riceParamPart128, 0)));
4161 
4162  /* Our value should be sitting in prediction64[0]. We need to combine this with our SSE samples. */
4163  samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
4164  samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4165  samples128_0 = drflac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
4166 
4167  /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
4168  riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4169  }
4170 
4171  /* We store samples in groups of 4. */
4172  vst1q_s32(pDecodedSamples, samples128_0);
4173  pDecodedSamples += 4;
4174  }
4175 
4176  /* Make sure we process the last few samples. */
4177  i = (count & ~3);
4178  while (i < (int)count) {
4179  /* Rice extraction. */
4180  if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4181  return DRFLAC_FALSE;
4182  }
4183 
4184  /* Rice reconstruction. */
4185  riceParamParts[0] &= riceParamMask;
4186  riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4187  riceParamParts[0] = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4188 
4189  /* Sample reconstruction. */
4190  pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
4191 
4192  i += 1;
4193  pDecodedSamples += 1;
4194  }
4195 
4196  return DRFLAC_TRUE;
4197 }
4198 
4199 static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4200 {
4201  DRFLAC_ASSERT(bs != NULL);
4202  DRFLAC_ASSERT(count > 0);
4203  DRFLAC_ASSERT(pSamplesOut != NULL);
4204 
4205  /* In my testing the order is rarely > 12, so in this case I'm going to simplify the NEON implementation by only handling order <= 12. */
4206  if (order > 0 && order <= 12) {
4207  if (bitsPerSample+shift > 32) {
4208  return drflac__decode_samples_with_residual__rice__neon_64(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
4209  } else {
4210  return drflac__decode_samples_with_residual__rice__neon_32(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
4211  }
4212  } else {
4213  return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
4214  }
4215 }
4216 #endif
4217 
4218 static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4219 {
4220 #if defined(DRFLAC_SUPPORT_SSE41)
4221  if (drflac__gIsSSE41Supported) {
4222  return drflac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
4223  } else
4224 #elif defined(DRFLAC_SUPPORT_NEON)
4226  return drflac__decode_samples_with_residual__rice__neon(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
4227  } else
4228 #endif
4229  {
4230  /* Scalar fallback. */
4231  #if 0
4232  return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
4233  #else
4234  return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
4235  #endif
4236  }
4237 }
4238 
4239 /* Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. */
4241 {
4242  drflac_uint32 i;
4243 
4244  DRFLAC_ASSERT(bs != NULL);
4245  DRFLAC_ASSERT(count > 0);
4246 
4247  for (i = 0; i < count; ++i) {
4248  if (!drflac__seek_rice_parts(bs, riceParam)) {
4249  return DRFLAC_FALSE;
4250  }
4251  }
4252 
4253  return DRFLAC_TRUE;
4254 }
4255 
4256 static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4257 {
4258  drflac_uint32 i;
4259 
4260  DRFLAC_ASSERT(bs != NULL);
4261  DRFLAC_ASSERT(count > 0);
4262  DRFLAC_ASSERT(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
4263  DRFLAC_ASSERT(pSamplesOut != NULL);
4264 
4265  for (i = 0; i < count; ++i) {
4266  if (unencodedBitsPerSample > 0) {
4267  if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
4268  return DRFLAC_FALSE;
4269  }
4270  } else {
4271  pSamplesOut[i] = 0;
4272  }
4273 
4274  if (bitsPerSample >= 24) {
4275  pSamplesOut[i] += drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
4276  } else {
4277  pSamplesOut[i] += drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
4278  }
4279  }
4280 
4281  return DRFLAC_TRUE;
4282 }
4283 
4284 
4285 /*
4286 Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
4287 when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be ignored. The
4288 <blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4289 */
4290 static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
4291 {
4292  drflac_uint8 residualMethod;
4293  drflac_uint8 partitionOrder;
4294  drflac_uint32 samplesInPartition;
4295  drflac_uint32 partitionsRemaining;
4296 
4297  DRFLAC_ASSERT(bs != NULL);
4298  DRFLAC_ASSERT(blockSize != 0);
4299  DRFLAC_ASSERT(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */
4300 
4301  if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4302  return DRFLAC_FALSE;
4303  }
4304 
4306  return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */
4307  }
4308 
4309  /* Ignore the first <order> values. */
4310  pDecodedSamples += order;
4311 
4312  if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4313  return DRFLAC_FALSE;
4314  }
4315 
4316  /*
4317  From the FLAC spec:
4318  The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4319  */
4320  if (partitionOrder > 8) {
4321  return DRFLAC_FALSE;
4322  }
4323 
4324  /* Validation check. */
4325  if ((blockSize / (1 << partitionOrder)) <= order) {
4326  return DRFLAC_FALSE;
4327  }
4328 
4329  samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
4330  partitionsRemaining = (1 << partitionOrder);
4331  for (;;) {
4332  drflac_uint8 riceParam = 0;
4333  if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
4334  if (!drflac__read_uint8(bs, 4, &riceParam)) {
4335  return DRFLAC_FALSE;
4336  }
4337  if (riceParam == 15) {
4338  riceParam = 0xFF;
4339  }
4340  } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4341  if (!drflac__read_uint8(bs, 5, &riceParam)) {
4342  return DRFLAC_FALSE;
4343  }
4344  if (riceParam == 31) {
4345  riceParam = 0xFF;
4346  }
4347  }
4348 
4349  if (riceParam != 0xFF) {
4350  if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) {
4351  return DRFLAC_FALSE;
4352  }
4353  } else {
4354  unsigned char unencodedBitsPerSample = 0;
4355  if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
4356  return DRFLAC_FALSE;
4357  }
4358 
4359  if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, order, shift, coefficients, pDecodedSamples)) {
4360  return DRFLAC_FALSE;
4361  }
4362  }
4363 
4364  pDecodedSamples += samplesInPartition;
4365 
4366  if (partitionsRemaining == 1) {
4367  break;
4368  }
4369 
4370  partitionsRemaining -= 1;
4371 
4372  if (partitionOrder != 0) {
4373  samplesInPartition = blockSize / (1 << partitionOrder);
4374  }
4375  }
4376 
4377  return DRFLAC_TRUE;
4378 }
4379 
4380 /*
4381 Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
4382 when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be set to 0. The
4383 <blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4384 */
4386 {
4387  drflac_uint8 residualMethod;
4388  drflac_uint8 partitionOrder;
4389  drflac_uint32 samplesInPartition;
4390  drflac_uint32 partitionsRemaining;
4391 
4392  DRFLAC_ASSERT(bs != NULL);
4393  DRFLAC_ASSERT(blockSize != 0);
4394 
4395  if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4396  return DRFLAC_FALSE;
4397  }
4398 
4400  return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */
4401  }
4402 
4403  if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4404  return DRFLAC_FALSE;
4405  }
4406 
4407  /*
4408  From the FLAC spec:
4409  The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4410  */
4411  if (partitionOrder > 8) {
4412  return DRFLAC_FALSE;
4413  }
4414 
4415  /* Validation check. */
4416  if ((blockSize / (1 << partitionOrder)) <= order) {
4417  return DRFLAC_FALSE;
4418  }
4419 
4420  samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
4421  partitionsRemaining = (1 << partitionOrder);
4422  for (;;)
4423  {
4424  drflac_uint8 riceParam = 0;
4425  if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
4426  if (!drflac__read_uint8(bs, 4, &riceParam)) {
4427  return DRFLAC_FALSE;
4428  }
4429  if (riceParam == 15) {
4430  riceParam = 0xFF;
4431  }
4432  } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4433  if (!drflac__read_uint8(bs, 5, &riceParam)) {
4434  return DRFLAC_FALSE;
4435  }
4436  if (riceParam == 31) {
4437  riceParam = 0xFF;
4438  }
4439  }
4440 
4441  if (riceParam != 0xFF) {
4442  if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) {
4443  return DRFLAC_FALSE;
4444  }
4445  } else {
4446  unsigned char unencodedBitsPerSample = 0;
4447  if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
4448  return DRFLAC_FALSE;
4449  }
4450 
4451  if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) {
4452  return DRFLAC_FALSE;
4453  }
4454  }
4455 
4456 
4457  if (partitionsRemaining == 1) {
4458  break;
4459  }
4460 
4461  partitionsRemaining -= 1;
4462  samplesInPartition = blockSize / (1 << partitionOrder);
4463  }
4464 
4465  return DRFLAC_TRUE;
4466 }
4467 
4468 
4469 static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
4470 {
4471  drflac_uint32 i;
4472 
4473  /* Only a single sample needs to be decoded here. */
4474  drflac_int32 sample;
4475  if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
4476  return DRFLAC_FALSE;
4477  }
4478 
4479  /*
4480  We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
4481  we'll want to look at a more efficient way.
4482  */
4483  for (i = 0; i < blockSize; ++i) {
4484  pDecodedSamples[i] = sample;
4485  }
4486 
4487  return DRFLAC_TRUE;
4488 }
4489 
4490 static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
4491 {
4492  drflac_uint32 i;
4493 
4494  for (i = 0; i < blockSize; ++i) {
4495  drflac_int32 sample;
4496  if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
4497  return DRFLAC_FALSE;
4498  }
4499 
4500  pDecodedSamples[i] = sample;
4501  }
4502 
4503  return DRFLAC_TRUE;
4504 }
4505 
4506 static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
4507 {
4508  drflac_uint32 i;
4509 
4510  static drflac_int32 lpcCoefficientsTable[5][4] = {
4511  {0, 0, 0, 0},
4512  {1, 0, 0, 0},
4513  {2, -1, 0, 0},
4514  {3, -3, 1, 0},
4515  {4, -6, 4, -1}
4516  };
4517 
4518  /* Warm up samples and coefficients. */
4519  for (i = 0; i < lpcOrder; ++i) {
4520  drflac_int32 sample;
4521  if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
4522  return DRFLAC_FALSE;
4523  }
4524 
4525  pDecodedSamples[i] = sample;
4526  }
4527 
4528  if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
4529  return DRFLAC_FALSE;
4530  }
4531 
4532  return DRFLAC_TRUE;
4533 }
4534 
4535 static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
4536 {
4537  drflac_uint8 i;
4538  drflac_uint8 lpcPrecision;
4539  drflac_int8 lpcShift;
4540  drflac_int32 coefficients[32];
4541 
4542  /* Warm up samples. */
4543  for (i = 0; i < lpcOrder; ++i) {
4544  drflac_int32 sample;
4545  if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
4546  return DRFLAC_FALSE;
4547  }
4548 
4549  pDecodedSamples[i] = sample;
4550  }
4551 
4552  if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
4553  return DRFLAC_FALSE;
4554  }
4555  if (lpcPrecision == 15) {
4556  return DRFLAC_FALSE; /* Invalid. */
4557  }
4558  lpcPrecision += 1;
4559 
4560  if (!drflac__read_int8(bs, 5, &lpcShift)) {
4561  return DRFLAC_FALSE;
4562  }
4563 
4564  DRFLAC_ZERO_MEMORY(coefficients, sizeof(coefficients));
4565  for (i = 0; i < lpcOrder; ++i) {
4566  if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
4567  return DRFLAC_FALSE;
4568  }
4569  }
4570 
4571  if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) {
4572  return DRFLAC_FALSE;
4573  }
4574 
4575  return DRFLAC_TRUE;
4576 }
4577 
4578 
4580 {
4581  const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
4582  const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; /* -1 = reserved. */
4583 
4584  DRFLAC_ASSERT(bs != NULL);
4585  DRFLAC_ASSERT(header != NULL);
4586 
4587  /* Keep looping until we find a valid sync code. */
4588  for (;;) {
4589  drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */
4590  drflac_uint8 reserved = 0;
4591  drflac_uint8 blockingStrategy = 0;
4592  drflac_uint8 blockSize = 0;
4593  drflac_uint8 sampleRate = 0;
4594  drflac_uint8 channelAssignment = 0;
4595  drflac_uint8 bitsPerSample = 0;
4596  drflac_bool32 isVariableBlockSize;
4597 
4599  return DRFLAC_FALSE;
4600  }
4601 
4602  if (!drflac__read_uint8(bs, 1, &reserved)) {
4603  return DRFLAC_FALSE;
4604  }
4605  if (reserved == 1) {
4606  continue;
4607  }
4608  crc8 = drflac_crc8(crc8, reserved, 1);
4609 
4610  if (!drflac__read_uint8(bs, 1, &blockingStrategy)) {
4611  return DRFLAC_FALSE;
4612  }
4613  crc8 = drflac_crc8(crc8, blockingStrategy, 1);
4614 
4615  if (!drflac__read_uint8(bs, 4, &blockSize)) {
4616  return DRFLAC_FALSE;
4617  }
4618  if (blockSize == 0) {
4619  continue;
4620  }
4621  crc8 = drflac_crc8(crc8, blockSize, 4);
4622 
4623  if (!drflac__read_uint8(bs, 4, &sampleRate)) {
4624  return DRFLAC_FALSE;
4625  }
4626  crc8 = drflac_crc8(crc8, sampleRate, 4);
4627 
4628  if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
4629  return DRFLAC_FALSE;
4630  }
4631  if (channelAssignment > 10) {
4632  continue;
4633  }
4634  crc8 = drflac_crc8(crc8, channelAssignment, 4);
4635 
4636  if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
4637  return DRFLAC_FALSE;
4638  }
4639  if (bitsPerSample == 3 || bitsPerSample == 7) {
4640  continue;
4641  }
4642  crc8 = drflac_crc8(crc8, bitsPerSample, 3);
4643 
4644 
4645  if (!drflac__read_uint8(bs, 1, &reserved)) {
4646  return DRFLAC_FALSE;
4647  }
4648  if (reserved == 1) {
4649  continue;
4650  }
4651  crc8 = drflac_crc8(crc8, reserved, 1);
4652 
4653 
4654  isVariableBlockSize = blockingStrategy == 1;
4655  if (isVariableBlockSize) {
4656  drflac_uint64 pcmFrameNumber;
4657  drflac_result result = drflac__read_utf8_coded_number(bs, &pcmFrameNumber, &crc8);
4658  if (result != DRFLAC_SUCCESS) {
4659  if (result == DRFLAC_END_OF_STREAM) {
4660  return DRFLAC_FALSE;
4661  } else {
4662  continue;
4663  }
4664  }
4665  header->flacFrameNumber = 0;
4666  header->pcmFrameNumber = pcmFrameNumber;
4667  } else {
4668  drflac_uint64 flacFrameNumber = 0;
4669  drflac_result result = drflac__read_utf8_coded_number(bs, &flacFrameNumber, &crc8);
4670  if (result != DRFLAC_SUCCESS) {
4671  if (result == DRFLAC_END_OF_STREAM) {
4672  return DRFLAC_FALSE;
4673  } else {
4674  continue;
4675  }
4676  }
4677  header->flacFrameNumber = (drflac_uint32)flacFrameNumber; /* <-- Safe cast. */
4678  header->pcmFrameNumber = 0;
4679  }
4680 
4681 
4682  DRFLAC_ASSERT(blockSize > 0);
4683  if (blockSize == 1) {
4684  header->blockSizeInPCMFrames = 192;
4685  } else if (blockSize >= 2 && blockSize <= 5) {
4686  header->blockSizeInPCMFrames = 576 * (1 << (blockSize - 2));
4687  } else if (blockSize == 6) {
4688  if (!drflac__read_uint16(bs, 8, &header->blockSizeInPCMFrames)) {
4689  return DRFLAC_FALSE;
4690  }
4691  crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 8);
4692  header->blockSizeInPCMFrames += 1;
4693  } else if (blockSize == 7) {
4694  if (!drflac__read_uint16(bs, 16, &header->blockSizeInPCMFrames)) {
4695  return DRFLAC_FALSE;
4696  }
4697  crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 16);
4698  header->blockSizeInPCMFrames += 1;
4699  } else {
4700  DRFLAC_ASSERT(blockSize >= 8);
4701  header->blockSizeInPCMFrames = 256 * (1 << (blockSize - 8));
4702  }
4703 
4704 
4705  if (sampleRate <= 11) {
4706  header->sampleRate = sampleRateTable[sampleRate];
4707  } else if (sampleRate == 12) {
4708  if (!drflac__read_uint32(bs, 8, &header->sampleRate)) {
4709  return DRFLAC_FALSE;
4710  }
4711  crc8 = drflac_crc8(crc8, header->sampleRate, 8);
4712  header->sampleRate *= 1000;
4713  } else if (sampleRate == 13) {
4714  if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
4715  return DRFLAC_FALSE;
4716  }
4717  crc8 = drflac_crc8(crc8, header->sampleRate, 16);
4718  } else if (sampleRate == 14) {
4719  if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
4720  return DRFLAC_FALSE;
4721  }
4722  crc8 = drflac_crc8(crc8, header->sampleRate, 16);
4723  header->sampleRate *= 10;
4724  } else {
4725  continue; /* Invalid. Assume an invalid block. */
4726  }
4727 
4728 
4729  header->channelAssignment = channelAssignment;
4730 
4731  header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
4732  if (header->bitsPerSample == 0) {
4733  header->bitsPerSample = streaminfoBitsPerSample;
4734  }
4735 
4736  if (!drflac__read_uint8(bs, 8, &header->crc8)) {
4737  return DRFLAC_FALSE;
4738  }
4739 
4740 #ifndef DR_FLAC_NO_CRC
4741  if (header->crc8 != crc8) {
4742  continue; /* CRC mismatch. Loop back to the top and find the next sync code. */
4743  }
4744 #endif
4745  return DRFLAC_TRUE;
4746  }
4747 }
4748 
4750 {
4752  int type;
4753 
4754  if (!drflac__read_uint8(bs, 8, &header)) {
4755  return DRFLAC_FALSE;
4756  }
4757 
4758  /* First bit should always be 0. */
4759  if ((header & 0x80) != 0) {
4760  return DRFLAC_FALSE;
4761  }
4762 
4763  type = (header & 0x7E) >> 1;
4764  if (type == 0) {
4766  } else if (type == 1) {
4768  } else {
4769  if ((type & 0x20) != 0) {
4770  pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
4771  pSubframe->lpcOrder = (type & 0x1F) + 1;
4772  } else if ((type & 0x08) != 0) {
4773  pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
4774  pSubframe->lpcOrder = (type & 0x07);
4775  if (pSubframe->lpcOrder > 4) {
4777  pSubframe->lpcOrder = 0;
4778  }
4779  } else {
4781  }
4782  }
4783 
4784  if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
4785  return DRFLAC_FALSE;
4786  }
4787 
4788  /* Wasted bits per sample. */
4789  pSubframe->wastedBitsPerSample = 0;
4790  if ((header & 0x01) == 1) {
4791  unsigned int wastedBitsPerSample;
4792  if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
4793  return DRFLAC_FALSE;
4794  }
4795  pSubframe->wastedBitsPerSample = (unsigned char)wastedBitsPerSample + 1;
4796  }
4797 
4798  return DRFLAC_TRUE;
4799 }
4800 
4801 static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
4802 {
4803  drflac_subframe* pSubframe;
4804  drflac_uint32 subframeBitsPerSample;
4805 
4806  DRFLAC_ASSERT(bs != NULL);
4807  DRFLAC_ASSERT(frame != NULL);
4808 
4809  pSubframe = frame->subframes + subframeIndex;
4810  if (!drflac__read_subframe_header(bs, pSubframe)) {
4811  return DRFLAC_FALSE;
4812  }
4813 
4814  /* Side channels require an extra bit per sample. Took a while to figure that one out... */
4815  subframeBitsPerSample = frame->header.bitsPerSample;
4817  subframeBitsPerSample += 1;
4818  } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
4819  subframeBitsPerSample += 1;
4820  }
4821 
4822  /* Need to handle wasted bits per sample. */
4823  if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
4824  return DRFLAC_FALSE;
4825  }
4826  subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
4827 
4828  pSubframe->pSamplesS32 = pDecodedSamplesOut;
4829 
4830  switch (pSubframe->subframeType)
4831  {
4833  {
4834  drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
4835  } break;
4836 
4838  {
4839  drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
4840  } break;
4841 
4842  case DRFLAC_SUBFRAME_FIXED:
4843  {
4844  drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
4845  } break;
4846 
4847  case DRFLAC_SUBFRAME_LPC:
4848  {
4849  drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
4850  } break;
4851 
4852  default: return DRFLAC_FALSE;
4853  }
4854 
4855  return DRFLAC_TRUE;
4856 }
4857 
4858 static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
4859 {
4860  drflac_subframe* pSubframe;
4861  drflac_uint32 subframeBitsPerSample;
4862 
4863  DRFLAC_ASSERT(bs != NULL);
4864  DRFLAC_ASSERT(frame != NULL);
4865 
4866  pSubframe = frame->subframes + subframeIndex;
4867  if (!drflac__read_subframe_header(bs, pSubframe)) {
4868  return DRFLAC_FALSE;
4869  }
4870 
4871  /* Side channels require an extra bit per sample. Took a while to figure that one out... */
4872  subframeBitsPerSample = frame->header.bitsPerSample;
4874  subframeBitsPerSample += 1;
4875  } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
4876  subframeBitsPerSample += 1;
4877  }
4878 
4879  /* Need to handle wasted bits per sample. */
4880  if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
4881  return DRFLAC_FALSE;
4882  }
4883  subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
4884 
4885  pSubframe->pSamplesS32 = NULL;
4886 
4887  switch (pSubframe->subframeType)
4888  {
4890  {
4891  if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
4892  return DRFLAC_FALSE;
4893  }
4894  } break;
4895 
4897  {
4898  unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
4899  if (!drflac__seek_bits(bs, bitsToSeek)) {
4900  return DRFLAC_FALSE;
4901  }
4902  } break;
4903 
4904  case DRFLAC_SUBFRAME_FIXED:
4905  {
4906  unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
4907  if (!drflac__seek_bits(bs, bitsToSeek)) {
4908  return DRFLAC_FALSE;
4909  }
4910 
4911  if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
4912  return DRFLAC_FALSE;
4913  }
4914  } break;
4915 
4916  case DRFLAC_SUBFRAME_LPC:
4917  {
4918  unsigned char lpcPrecision;
4919 
4920  unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
4921  if (!drflac__seek_bits(bs, bitsToSeek)) {
4922  return DRFLAC_FALSE;
4923  }
4924 
4925  if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
4926  return DRFLAC_FALSE;
4927  }
4928  if (lpcPrecision == 15) {
4929  return DRFLAC_FALSE; /* Invalid. */
4930  }
4931  lpcPrecision += 1;
4932 
4933 
4934  bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; /* +5 for shift. */
4935  if (!drflac__seek_bits(bs, bitsToSeek)) {
4936  return DRFLAC_FALSE;
4937  }
4938 
4939  if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
4940  return DRFLAC_FALSE;
4941  }
4942  } break;
4943 
4944  default: return DRFLAC_FALSE;
4945  }
4946 
4947  return DRFLAC_TRUE;
4948 }
4949 
4950 
4952 {
4953  drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
4954 
4955  DRFLAC_ASSERT(channelAssignment <= 10);
4956  return lookup[channelAssignment];
4957 }
4958 
4960 {
4961  int channelCount;
4962  int i;
4963  drflac_uint8 paddingSizeInBits;
4964  drflac_uint16 desiredCRC16;
4965 #ifndef DR_FLAC_NO_CRC
4966  drflac_uint16 actualCRC16;
4967 #endif
4968 
4969  /* This function should be called while the stream is sitting on the first byte after the frame header. */
4971 
4972  /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
4974  return DRFLAC_ERROR;
4975  }
4976 
4977  /* The number of channels in the frame must match the channel count from the STREAMINFO block. */
4979  if (channelCount != (int)pFlac->channels) {
4980  return DRFLAC_ERROR;
4981  }
4982 
4983  for (i = 0; i < channelCount; ++i) {
4984  if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
4985  return DRFLAC_ERROR;
4986  }
4987  }
4988 
4989  paddingSizeInBits = DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7;
4990  if (paddingSizeInBits > 0) {
4991  drflac_uint8 padding = 0;
4992  if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
4993  return DRFLAC_END_OF_STREAM;
4994  }
4995  }
4996 
4997 #ifndef DR_FLAC_NO_CRC
4998  actualCRC16 = drflac__flush_crc16(&pFlac->bs);
4999 #endif
5000  if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5001  return DRFLAC_END_OF_STREAM;
5002  }
5003 
5004 #ifndef DR_FLAC_NO_CRC
5005  if (actualCRC16 != desiredCRC16) {
5006  return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */
5007  }
5008 #endif
5009 
5011 
5012  return DRFLAC_SUCCESS;
5013 }
5014 
5016 {
5017  int channelCount;
5018  int i;
5019  drflac_uint16 desiredCRC16;
5020 #ifndef DR_FLAC_NO_CRC
5021  drflac_uint16 actualCRC16;
5022 #endif
5023 
5025  for (i = 0; i < channelCount; ++i) {
5026  if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
5027  return DRFLAC_ERROR;
5028  }
5029  }
5030 
5031  /* Padding. */
5032  if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
5033  return DRFLAC_ERROR;
5034  }
5035 
5036  /* CRC. */
5037 #ifndef DR_FLAC_NO_CRC
5038  actualCRC16 = drflac__flush_crc16(&pFlac->bs);
5039 #endif
5040  if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5041  return DRFLAC_END_OF_STREAM;
5042  }
5043 
5044 #ifndef DR_FLAC_NO_CRC
5045  if (actualCRC16 != desiredCRC16) {
5046  return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */
5047  }
5048 #endif
5049 
5050  return DRFLAC_SUCCESS;
5051 }
5052 
5054 {
5055  DRFLAC_ASSERT(pFlac != NULL);
5056 
5057  for (;;) {
5058  drflac_result result;
5059 
5061  return DRFLAC_FALSE;
5062  }
5063 
5064  result = drflac__decode_flac_frame(pFlac);
5065  if (result != DRFLAC_SUCCESS) {
5066  if (result == DRFLAC_CRC_MISMATCH) {
5067  continue; /* CRC mismatch. Skip to the next frame. */
5068  } else {
5069  return DRFLAC_FALSE;
5070  }
5071  }
5072 
5073  return DRFLAC_TRUE;
5074  }
5075 }
5076 
5077 static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
5078 {
5079  drflac_uint64 firstPCMFrame;
5080  drflac_uint64 lastPCMFrame;
5081 
5082  DRFLAC_ASSERT(pFlac != NULL);
5083 
5084  firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
5085  if (firstPCMFrame == 0) {
5087  }
5088 
5089  lastPCMFrame = firstPCMFrame + pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
5090  if (lastPCMFrame > 0) {
5091  lastPCMFrame -= 1; /* Needs to be zero based. */
5092  }
5093 
5094  if (pFirstPCMFrame) {
5095  *pFirstPCMFrame = firstPCMFrame;
5096  }
5097  if (pLastPCMFrame) {
5098  *pLastPCMFrame = lastPCMFrame;
5099  }
5100 }
5101 
5103 {
5104  drflac_bool32 result;
5105 
5106  DRFLAC_ASSERT(pFlac != NULL);
5107 
5108  result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
5109 
5110  DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5111  pFlac->currentPCMFrame = 0;
5112 
5113  return result;
5114 }
5115 
5117 {
5118  /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
5119  DRFLAC_ASSERT(pFlac != NULL);
5120  return drflac__seek_flac_frame(pFlac);
5121 }
5122 
5123 
5125 {
5126  drflac_uint64 pcmFramesRead = 0;
5127  while (pcmFramesToSeek > 0) {
5128  if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5130  break; /* Couldn't read the next frame, so just break from the loop and return. */
5131  }
5132  } else {
5133  if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
5134  pcmFramesRead += pcmFramesToSeek;
5135  pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek; /* <-- Safe cast. Will always be < currentFrame.pcmFramesRemaining < 65536. */
5136  pcmFramesToSeek = 0;
5137  } else {
5138  pcmFramesRead += pFlac->currentFLACFrame.pcmFramesRemaining;
5139  pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
5141  }
5142  }
5143  }
5144 
5145  pFlac->currentPCMFrame += pcmFramesRead;
5146  return pcmFramesRead;
5147 }
5148 
5149 
5151 {
5152  drflac_bool32 isMidFrame = DRFLAC_FALSE;
5153  drflac_uint64 runningPCMFrameCount;
5154 
5155  DRFLAC_ASSERT(pFlac != NULL);
5156 
5157  /* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */
5158  if (pcmFrameIndex >= pFlac->currentPCMFrame) {
5159  /* Seeking forward. Need to seek from the current position. */
5160  runningPCMFrameCount = pFlac->currentPCMFrame;
5161 
5162  /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
5163  if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5165  return DRFLAC_FALSE;
5166  }
5167  } else {
5168  isMidFrame = DRFLAC_TRUE;
5169  }
5170  } else {
5171  /* Seeking backwards. Need to seek from the start of the file. */
5172  runningPCMFrameCount = 0;
5173 
5174  /* Move back to the start. */
5175  if (!drflac__seek_to_first_frame(pFlac)) {
5176  return DRFLAC_FALSE;
5177  }
5178 
5179  /* Decode the first frame in preparation for sample-exact seeking below. */
5181  return DRFLAC_FALSE;
5182  }
5183  }
5184 
5185  /*
5186  We need to as quickly as possible find the frame that contains the target sample. To do this, we iterate over each frame and inspect its
5187  header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame.
5188  */
5189  for (;;) {
5190  drflac_uint64 pcmFrameCountInThisFLACFrame;
5191  drflac_uint64 firstPCMFrameInFLACFrame = 0;
5192  drflac_uint64 lastPCMFrameInFLACFrame = 0;
5193 
5194  drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
5195 
5196  pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
5197  if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
5198  /*
5199  The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
5200  it never existed and keep iterating.
5201  */
5202  drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
5203 
5204  if (!isMidFrame) {
5205  drflac_result result = drflac__decode_flac_frame(pFlac);
5206  if (result == DRFLAC_SUCCESS) {
5207  /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
5208  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
5209  } else {
5210  if (result == DRFLAC_CRC_MISMATCH) {
5211  goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5212  } else {
5213  return DRFLAC_FALSE;
5214  }
5215  }
5216  } else {
5217  /* We started seeking mid-frame which means we need to skip the frame decoding part. */
5218  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
5219  }
5220  } else {
5221  /*
5222  It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
5223  frame never existed and leave the running sample count untouched.
5224  */
5225  if (!isMidFrame) {
5227  if (result == DRFLAC_SUCCESS) {
5228  runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
5229  } else {
5230  if (result == DRFLAC_CRC_MISMATCH) {
5231  goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5232  } else {
5233  return DRFLAC_FALSE;
5234  }
5235  }
5236  } else {
5237  /*
5238  We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
5239  drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
5240  */
5241  runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
5243  isMidFrame = DRFLAC_FALSE;
5244  }
5245 
5246  /* If we are seeking to the end of the file and we've just hit it, we're done. */
5247  if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
5248  return DRFLAC_TRUE;
5249  }
5250  }
5251 
5252  next_iteration:
5253  /* Grab the next frame in preparation for the next iteration. */
5255  return DRFLAC_FALSE;
5256  }
5257  }
5258 }
5259 
5260 
5261 #if !defined(DR_FLAC_NO_CRC)
5262 /*
5263 We use an average compression ratio to determine our approximate start location. FLAC files are generally about 50%-70% the size of their
5264 uncompressed counterparts so we'll use this as a basis. I'm going to split the middle and use a factor of 0.6 to determine the starting
5265 location.
5266 */
5267 #define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
5268 
5269 static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
5270 {
5271  DRFLAC_ASSERT(pFlac != NULL);
5272  DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
5273  DRFLAC_ASSERT(targetByte >= rangeLo);
5274  DRFLAC_ASSERT(targetByte <= rangeHi);
5275 
5276  *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
5277 
5278  for (;;) {
5279  /* When seeking to a byte, failure probably means we've attempted to seek beyond the end of the stream. To counter this we just halve it each attempt. */
5280  if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
5281  /* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
5282  if (targetByte == 0) {
5283  drflac__seek_to_first_frame(pFlac); /* Try to recover. */
5284  return DRFLAC_FALSE;
5285  }
5286 
5287  /* Halve the byte location and continue. */
5288  targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5289  rangeHi = targetByte;
5290  } else {
5291  /* Getting here should mean that we have seeked to an appropriate byte. */
5292 
5293  /* Clear the details of the FLAC frame so we don't misreport data. */
5294  DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5295 
5296  /*
5297  Now seek to the next FLAC frame. We need to decode the entire frame (not just the header) because it's possible for the header to incorrectly pass the
5298  CRC check and return bad data. We need to decode the entire frame to be more certain. Although this seems unlikely, this has happened to me in testing
5299  to it needs to stay this way for now.
5300  */
5301 #if 1
5303  /* Halve the byte location and continue. */
5304  targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5305  rangeHi = targetByte;
5306  } else {
5307  break;
5308  }
5309 #else
5311  /* Halve the byte location and continue. */
5312  targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5313  rangeHi = targetByte;
5314  } else {
5315  break;
5316  }
5317 #endif
5318  }
5319  }
5320 
5321  /* The current PCM frame needs to be updated based on the frame we just seeked to. */
5323 
5324  DRFLAC_ASSERT(targetByte <= rangeHi);
5325 
5326  *pLastSuccessfulSeekOffset = targetByte;
5327  return DRFLAC_TRUE;
5328 }
5329 
5331 {
5332  /* This section of code would be used if we were only decoding the FLAC frame header when calling drflac__seek_to_approximate_flac_frame_to_byte(). */
5333 #if 0
5334  if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
5335  /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
5337  return DRFLAC_FALSE;
5338  }
5339  }
5340 #endif
5341 
5342  return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
5343 }
5344 
5345 
5347 {
5348  /* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */
5349 
5350  drflac_uint64 targetByte;
5351  drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
5352  drflac_uint64 pcmRangeHi = 0;
5353  drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
5354  drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
5355  drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
5356 
5357  targetByte = byteRangeLo + (drflac_uint64)(((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
5358  if (targetByte > byteRangeHi) {
5359  targetByte = byteRangeHi;
5360  }
5361 
5362  for (;;) {
5363  if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
5364  /* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
5365  drflac_uint64 newPCMRangeLo;
5366  drflac_uint64 newPCMRangeHi;
5367  drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
5368 
5369  /* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
5370  if (pcmRangeLo == newPCMRangeLo) {
5371  if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
5372  break; /* Failed to seek to closest frame. */
5373  }
5374 
5376  return DRFLAC_TRUE;
5377  } else {
5378  break; /* Failed to seek forward. */
5379  }
5380  }
5381 
5382  pcmRangeLo = newPCMRangeLo;
5383  pcmRangeHi = newPCMRangeHi;
5384 
5385  if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
5386  /* The target PCM frame is in this FLAC frame. */
5387  if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
5388  return DRFLAC_TRUE;
5389  } else {
5390  break; /* Failed to seek to FLAC frame. */
5391  }
5392  } else {
5393  const float approxCompressionRatio = (lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / (pcmRangeLo * pFlac->channels * pFlac->bitsPerSample/8.0f);
5394 
5395  if (pcmRangeLo > pcmFrameIndex) {
5396  /* We seeked too far forward. We need to move our target byte backward and try again. */
5397  byteRangeHi = lastSuccessfulSeekOffset;
5398  if (byteRangeLo > byteRangeHi) {
5399  byteRangeLo = byteRangeHi;
5400  }
5401 
5402  targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
5403  if (targetByte < byteRangeLo) {
5404  targetByte = byteRangeLo;
5405  }
5406  } else /*if (pcmRangeHi < pcmFrameIndex)*/ {
5407  /* We didn't seek far enough. We need to move our target byte forward and try again. */
5408 
5409  /* If we're close enough we can just seek forward. */
5410  if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
5412  return DRFLAC_TRUE;
5413  } else {
5414  break; /* Failed to seek to FLAC frame. */
5415  }
5416  } else {
5417  byteRangeLo = lastSuccessfulSeekOffset;
5418  if (byteRangeHi < byteRangeLo) {
5419  byteRangeHi = byteRangeLo;
5420  }
5421 
5422  targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample/8.0f) * approxCompressionRatio);
5423  if (targetByte > byteRangeHi) {
5424  targetByte = byteRangeHi;
5425  }
5426 
5427  if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
5428  closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
5429  }
5430  }
5431  }
5432  }
5433  } else {
5434  /* Getting here is really bad. We just recover as best we can, but moving to the first frame in the stream, and then abort. */
5435  break;
5436  }
5437  }
5438 
5439  drflac__seek_to_first_frame(pFlac); /* <-- Try to recover. */
5440  return DRFLAC_FALSE;
5441 }
5442 
5444 {
5445  drflac_uint64 byteRangeLo;
5446  drflac_uint64 byteRangeHi;
5447  drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
5448 
5449  /* Our algorithm currently assumes the PCM frame */
5450  if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
5451  return DRFLAC_FALSE;
5452  }
5453 
5454  /* If we're close enough to the start, just move to the start and seek forward. */
5455  if (pcmFrameIndex < seekForwardThreshold) {
5456  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
5457  }
5458 
5459  /*
5460  Our starting byte range is the byte position of the first FLAC frame and the approximate end of the file as if it were completely uncompressed. This ensures
5461  the entire file is included, even though most of the time it'll exceed the end of the actual stream. This is OK as the frame searching logic will handle it.
5462  */
5463  byteRangeLo = pFlac->firstFLACFramePosInBytes;
5464  byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample/8.0f);
5465 
5466  return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
5467 }
5468 #endif /* !DR_FLAC_NO_CRC */
5469 
5471 {
5472  drflac_uint32 iClosestSeekpoint = 0;
5473  drflac_bool32 isMidFrame = DRFLAC_FALSE;
5474  drflac_uint64 runningPCMFrameCount;
5475  drflac_uint32 iSeekpoint;
5476 
5477 
5478  DRFLAC_ASSERT(pFlac != NULL);
5479 
5480  if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
5481  return DRFLAC_FALSE;
5482  }
5483 
5484  for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
5485  if (pFlac->pSeekpoints[iSeekpoint].firstPCMFrame >= pcmFrameIndex) {
5486  break;
5487  }
5488 
5489  iClosestSeekpoint = iSeekpoint;
5490  }
5491 
5492 #if !defined(DR_FLAC_NO_CRC)
5493  /* At this point we should know the closest seek point. We can use a binary search for this. We need to know the total sample count for this. */
5494  if (pFlac->totalPCMFrameCount > 0) {
5495  drflac_uint64 byteRangeLo;
5496  drflac_uint64 byteRangeHi;
5497 
5498  byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample/8.0f);
5499  byteRangeLo = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset;
5500 
5501  if (iClosestSeekpoint < pFlac->seekpointCount-1) {
5502  if (pFlac->pSeekpoints[iClosestSeekpoint+1].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Is it a placeholder seekpoint. */
5503  byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint+1].flacFrameOffset-1; /* Must be zero based. */
5504  }
5505  }
5506 
5507  if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
5510 
5511  if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
5512  return DRFLAC_TRUE;
5513  }
5514  }
5515  }
5516  }
5517 #endif /* !DR_FLAC_NO_CRC */
5518 
5519  /* Getting here means we need to use a slower algorithm because the binary search method failed or cannot be used. */
5520 
5521  /*
5522  If we are seeking forward and the closest seekpoint is _before_ the current sample, we just seek forward from where we are. Otherwise we start seeking
5523  from the seekpoint's first sample.
5524  */
5525  if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
5526  /* Optimized case. Just seek forward from where we are. */
5527  runningPCMFrameCount = pFlac->currentPCMFrame;
5528 
5529  /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
5530  if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5532  return DRFLAC_FALSE;
5533  }
5534  } else {
5535  isMidFrame = DRFLAC_TRUE;
5536  }
5537  } else {
5538  /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */
5539  runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;
5540 
5541  if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
5542  return DRFLAC_FALSE;
5543  }
5544 
5545  /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */
5547  return DRFLAC_FALSE;
5548  }
5549  }
5550 
5551  for (;;) {
5552  drflac_uint64 pcmFrameCountInThisFLACFrame;
5553  drflac_uint64 firstPCMFrameInFLACFrame = 0;
5554  drflac_uint64 lastPCMFrameInFLACFrame = 0;
5555 
5556  drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
5557 
5558  pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
5559  if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
5560  /*
5561  The sample should be in this frame. We need to fully decode it, but if it's an invalid frame (a CRC mismatch) we need to pretend
5562  it never existed and keep iterating.
5563  */
5564  drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
5565 
5566  if (!isMidFrame) {
5567  drflac_result result = drflac__decode_flac_frame(pFlac);
5568  if (result == DRFLAC_SUCCESS) {
5569  /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
5570  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
5571  } else {
5572  if (result == DRFLAC_CRC_MISMATCH) {
5573  goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5574  } else {
5575  return DRFLAC_FALSE;
5576  }
5577  }
5578  } else {
5579  /* We started seeking mid-frame which means we need to skip the frame decoding part. */
5580  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
5581  }
5582  } else {
5583  /*
5584  It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
5585  frame never existed and leave the running sample count untouched.
5586  */
5587  if (!isMidFrame) {
5589  if (result == DRFLAC_SUCCESS) {
5590  runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
5591  } else {
5592  if (result == DRFLAC_CRC_MISMATCH) {
5593  goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */
5594  } else {
5595  return DRFLAC_FALSE;
5596  }
5597  }
5598  } else {
5599  /*
5600  We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
5601  drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
5602  */
5603  runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
5605  isMidFrame = DRFLAC_FALSE;
5606  }
5607 
5608  /* If we are seeking to the end of the file and we've just hit it, we're done. */
5609  if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
5610  return DRFLAC_TRUE;
5611  }
5612  }
5613 
5614  next_iteration:
5615  /* Grab the next frame in preparation for the next iteration. */
5617  return DRFLAC_FALSE;
5618  }
5619  }
5620 }
5621 
5622 
5623 #ifndef DR_FLAC_NO_OGG
5624 typedef struct
5625 {
5626  drflac_uint8 capturePattern[4]; /* Should be "OggS" */
5627  drflac_uint8 structureVersion; /* Always 0. */
5628  drflac_uint8 headerType;
5629  drflac_uint64 granulePosition;
5630  drflac_uint32 serialNumber;
5631  drflac_uint32 sequenceNumber;
5632  drflac_uint32 checksum;
5633  drflac_uint8 segmentCount;
5634  drflac_uint8 segmentTable[255];
5636 #endif
5637 
5638 typedef struct
5639 {
5640  drflac_read_proc onRead;
5641  drflac_seek_proc onSeek;
5642  drflac_meta_proc onMeta;
5643  drflac_container container;
5644  void* pUserData;
5645  void* pUserDataMD;
5646  drflac_uint32 sampleRate;
5647  drflac_uint8 channels;
5648  drflac_uint8 bitsPerSample;
5649  drflac_uint64 totalPCMFrameCount;
5650  drflac_uint16 maxBlockSizeInPCMFrames;
5651  drflac_uint64 runningFilePos;
5652  drflac_bool32 hasStreamInfoBlock;
5653  drflac_bool32 hasMetadataBlocks;
5654  drflac_bs bs; /* <-- A bit streamer is required for loading data during initialization. */
5655  drflac_frame_header firstFrameHeader; /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */
5656 
5657 #ifndef DR_FLAC_NO_OGG
5658  drflac_uint32 oggSerial;
5659  drflac_uint64 oggFirstBytePos;
5660  drflac_ogg_page_header oggBosHeader;
5661 #endif
5663 
5664 static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
5665 {
5666  blockHeader = drflac__be2host_32(blockHeader);
5667  *isLastBlock = (blockHeader & 0x80000000UL) >> 31;
5668  *blockType = (blockHeader & 0x7F000000UL) >> 24;
5669  *blockSize = (blockHeader & 0x00FFFFFFUL);
5670 }
5671 
5672 static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
5673 {
5674  drflac_uint32 blockHeader;
5675 
5676  *blockSize = 0;
5677  if (onRead(pUserData, &blockHeader, 4) != 4) {
5678  return DRFLAC_FALSE;
5679  }
5680 
5681  drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
5682  return DRFLAC_TRUE;
5683 }
5684 
5685 drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
5686 {
5687  drflac_uint32 blockSizes;
5688  drflac_uint64 frameSizes = 0;
5689  drflac_uint64 importantProps;
5690  drflac_uint8 md5[16];
5691 
5692  /* min/max block size. */
5693  if (onRead(pUserData, &blockSizes, 4) != 4) {
5694  return DRFLAC_FALSE;
5695  }
5696 
5697  /* min/max frame size. */
5698  if (onRead(pUserData, &frameSizes, 6) != 6) {
5699  return DRFLAC_FALSE;
5700  }
5701 
5702  /* Sample rate, channels, bits per sample and total sample count. */
5703  if (onRead(pUserData, &importantProps, 8) != 8) {
5704  return DRFLAC_FALSE;
5705  }
5706 
5707  /* MD5 */
5708  if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
5709  return DRFLAC_FALSE;
5710  }
5711 
5712  blockSizes = drflac__be2host_32(blockSizes);
5713  frameSizes = drflac__be2host_64(frameSizes);
5714  importantProps = drflac__be2host_64(importantProps);
5715 
5716  pStreamInfo->minBlockSizeInPCMFrames = (blockSizes & 0xFFFF0000) >> 16;
5717  pStreamInfo->maxBlockSizeInPCMFrames = (blockSizes & 0x0000FFFF);
5718  pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
5719  pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 0)) >> 16);
5720  pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
5721  pStreamInfo->channels = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
5722  pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
5723  pStreamInfo->totalPCMFrameCount = ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
5724  DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
5725 
5726  return DRFLAC_TRUE;
5727 }
5728 
5729 
5730 static void* drflac__malloc_default(size_t sz, void* pUserData)
5731 {
5732  (void)pUserData;
5733  return DRFLAC_MALLOC(sz);
5734 }
5735 
5736 static void* drflac__realloc_default(void* p, size_t sz, void* pUserData)
5737 {
5738  (void)pUserData;
5739  return DRFLAC_REALLOC(p, sz);
5740 }
5741 
5742 static void drflac__free_default(void* p, void* pUserData)
5743 {
5744  (void)pUserData;
5745  DRFLAC_FREE(p);
5746 }
5747 
5748 
5749 static void* drflac__malloc_from_callbacks(size_t sz, const drflac_allocation_callbacks* pAllocationCallbacks)
5750 {
5751  if (pAllocationCallbacks == NULL) {
5752  return NULL;
5753  }
5754 
5755  if (pAllocationCallbacks->onMalloc != NULL) {
5756  return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
5757  }
5758 
5759  /* Try using realloc(). */
5760  if (pAllocationCallbacks->onRealloc != NULL) {
5761  return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
5762  }
5763 
5764  return NULL;
5765 }
5766 
5767 static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drflac_allocation_callbacks* pAllocationCallbacks)
5768 {
5769  if (pAllocationCallbacks == NULL) {
5770  return NULL;
5771  }
5772 
5773  if (pAllocationCallbacks->onRealloc != NULL) {
5774  return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
5775  }
5776 
5777  /* Try emulating realloc() in terms of malloc()/free(). */
5778  if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
5779  void* p2;
5780 
5781  p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
5782  if (p2 == NULL) {
5783  return NULL;
5784  }
5785 
5786  if (p != NULL) {
5787  DRFLAC_COPY_MEMORY(p2, p, szOld);
5788  pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
5789  }
5790 
5791  return p2;
5792  }
5793 
5794  return NULL;
5795 }
5796 
5797 static void drflac__free_from_callbacks(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
5798 {
5799  if (p == NULL || pAllocationCallbacks == NULL) {
5800  return;
5801  }
5802 
5803  if (pAllocationCallbacks->onFree != NULL) {
5804  pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
5805  }
5806 }
5807 
5808 
5809 drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeektableSize, drflac_allocation_callbacks* pAllocationCallbacks)
5810 {
5811  /*
5812  We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
5813  we'll be sitting on byte 42.
5814  */
5815  drflac_uint64 runningFilePos = 42;
5816  drflac_uint64 seektablePos = 0;
5817  drflac_uint32 seektableSize = 0;
5818 
5819  for (;;) {
5820  drflac_metadata metadata;
5821  drflac_uint8 isLastBlock = 0;
5822  drflac_uint8 blockType;
5823  drflac_uint32 blockSize;
5824  if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
5825  return DRFLAC_FALSE;
5826  }
5827  runningFilePos += 4;
5828 
5829  metadata.type = blockType;
5830  metadata.pRawData = NULL;
5831  metadata.rawDataSize = 0;
5832 
5833  switch (blockType)
5834  {
5836  {
5837  if (blockSize < 4) {
5838  return DRFLAC_FALSE;
5839  }
5840 
5841  if (onMeta) {
5842  void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
5843  if (pRawData == NULL) {
5844  return DRFLAC_FALSE;
5845  }
5846 
5847  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
5848  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5849  return DRFLAC_FALSE;
5850  }
5851 
5852  metadata.pRawData = pRawData;
5853  metadata.rawDataSize = blockSize;
5854  metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData);
5855  metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32));
5856  metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32);
5857  onMeta(pUserDataMD, &metadata);
5858 
5859  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5860  }
5861  } break;
5862 
5864  {
5865  seektablePos = runningFilePos;
5866  seektableSize = blockSize;
5867 
5868  if (onMeta) {
5869  drflac_uint32 iSeekpoint;
5870  void* pRawData;
5871 
5872  pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
5873  if (pRawData == NULL) {
5874  return DRFLAC_FALSE;
5875  }
5876 
5877  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
5878  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5879  return DRFLAC_FALSE;
5880  }
5881 
5882  metadata.pRawData = pRawData;
5883  metadata.rawDataSize = blockSize;
5884  metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint);
5885  metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
5886 
5887  /* Endian swap. */
5888  for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
5889  drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
5890  pSeekpoint->firstPCMFrame = drflac__be2host_64(pSeekpoint->firstPCMFrame);
5891  pSeekpoint->flacFrameOffset = drflac__be2host_64(pSeekpoint->flacFrameOffset);
5892  pSeekpoint->pcmFrameCount = drflac__be2host_16(pSeekpoint->pcmFrameCount);
5893  }
5894 
5895  onMeta(pUserDataMD, &metadata);
5896 
5897  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5898  }
5899  } break;
5900 
5902  {
5903  if (blockSize < 8) {
5904  return DRFLAC_FALSE;
5905  }
5906 
5907  if (onMeta) {
5908  void* pRawData;
5909  const char* pRunningData;
5910  const char* pRunningDataEnd;
5911  drflac_uint32 i;
5912 
5913  pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
5914  if (pRawData == NULL) {
5915  return DRFLAC_FALSE;
5916  }
5917 
5918  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
5919  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5920  return DRFLAC_FALSE;
5921  }
5922 
5923  metadata.pRawData = pRawData;
5924  metadata.rawDataSize = blockSize;
5925 
5926  pRunningData = (const char*)pRawData;
5927  pRunningDataEnd = (const char*)pRawData + blockSize;
5928 
5929  metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
5930 
5931  /* Need space for the rest of the block */
5932  if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
5933  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5934  return DRFLAC_FALSE;
5935  }
5936  metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
5937  metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
5938 
5939  /* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */
5940  if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) { /* <-- Note the order of operations to avoid overflow to a valid value */
5941  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5942  return DRFLAC_FALSE;
5943  }
5944  metadata.data.vorbis_comment.pComments = pRunningData;
5945 
5946  /* Check that the comments section is valid before passing it to the callback */
5947  for (i = 0; i < metadata.data.vorbis_comment.commentCount; ++i) {
5948  drflac_uint32 commentLength;
5949 
5950  if (pRunningDataEnd - pRunningData < 4) {
5951  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5952  return DRFLAC_FALSE;
5953  }
5954 
5955  commentLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
5956  if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
5957  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5958  return DRFLAC_FALSE;
5959  }
5960  pRunningData += commentLength;
5961  }
5962 
5963  onMeta(pUserDataMD, &metadata);
5964 
5965  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5966  }
5967  } break;
5968 
5970  {
5971  if (blockSize < 396) {
5972  return DRFLAC_FALSE;
5973  }
5974 
5975  if (onMeta) {
5976  void* pRawData;
5977  const char* pRunningData;
5978  const char* pRunningDataEnd;
5979  drflac_uint8 iTrack;
5980  drflac_uint8 iIndex;
5981 
5982  pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
5983  if (pRawData == NULL) {
5984  return DRFLAC_FALSE;
5985  }
5986 
5987  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
5988  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
5989  return DRFLAC_FALSE;
5990  }
5991 
5992  metadata.pRawData = pRawData;
5993  metadata.rawDataSize = blockSize;
5994 
5995  pRunningData = (const char*)pRawData;
5996  pRunningDataEnd = (const char*)pRawData + blockSize;
5997 
5998  DRFLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
5999  metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
6000  metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259;
6001  metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
6002  metadata.data.cuesheet.pTrackData = pRunningData;
6003 
6004  /* Check that the cuesheet tracks are valid before passing it to the callback */
6005  for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
6006  drflac_uint8 indexCount;
6007  drflac_uint32 indexPointSize;
6008 
6009  if (pRunningDataEnd - pRunningData < 36) {
6010  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6011  return DRFLAC_FALSE;
6012  }
6013 
6014  /* Skip to the index point count */
6015  pRunningData += 35;
6016  indexCount = pRunningData[0]; pRunningData += 1;
6017  indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index);
6018  if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
6019  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6020  return DRFLAC_FALSE;
6021  }
6022 
6023  /* Endian swap. */
6024  for (iIndex = 0; iIndex < indexCount; ++iIndex) {
6026  pRunningData += sizeof(drflac_cuesheet_track_index);
6027  pTrack->offset = drflac__be2host_64(pTrack->offset);
6028  }
6029  }
6030 
6031  onMeta(pUserDataMD, &metadata);
6032 
6033  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6034  }
6035  } break;
6036 
6038  {
6039  if (blockSize < 32) {
6040  return DRFLAC_FALSE;
6041  }
6042 
6043  if (onMeta) {
6044  void* pRawData;
6045  const char* pRunningData;
6046  const char* pRunningDataEnd;
6047 
6048  pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6049  if (pRawData == NULL) {
6050  return DRFLAC_FALSE;
6051  }
6052 
6053  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6054  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6055  return DRFLAC_FALSE;
6056  }
6057 
6058  metadata.pRawData = pRawData;
6059  metadata.rawDataSize = blockSize;
6060 
6061  pRunningData = (const char*)pRawData;
6062  pRunningDataEnd = (const char*)pRawData + blockSize;
6063 
6064  metadata.data.picture.type = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6065  metadata.data.picture.mimeLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6066 
6067  /* Need space for the rest of the block */
6068  if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6069  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6070  return DRFLAC_FALSE;
6071  }
6072  metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
6073  metadata.data.picture.descriptionLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6074 
6075  /* Need space for the rest of the block */
6076  if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6077  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6078  return DRFLAC_FALSE;
6079  }
6080  metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
6081  metadata.data.picture.width = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6082  metadata.data.picture.height = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6083  metadata.data.picture.colorDepth = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6084  metadata.data.picture.indexColorCount = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6085  metadata.data.picture.pictureDataSize = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
6086  metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
6087 
6088  /* Need space for the picture after the block */
6089  if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { /* <-- Note the order of operations to avoid overflow to a valid value */
6090  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6091  return DRFLAC_FALSE;
6092  }
6093 
6094  onMeta(pUserDataMD, &metadata);
6095 
6096  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6097  }
6098  } break;
6099 
6101  {
6102  if (onMeta) {
6103  metadata.data.padding.unused = 0;
6104 
6105  /* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */
6106  if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6107  isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
6108  } else {
6109  onMeta(pUserDataMD, &metadata);
6110  }
6111  }
6112  } break;
6113 
6115  {
6116  /* Invalid chunk. Just skip over this one. */
6117  if (onMeta) {
6118  if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6119  isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
6120  }
6121  }
6122  } break;
6123 
6124  default:
6125  {
6126  /*
6127  It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we
6128  can at the very least report the chunk to the application and let it look at the raw data.
6129  */
6130  if (onMeta) {
6131  void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6132  if (pRawData == NULL) {
6133  return DRFLAC_FALSE;
6134  }
6135 
6136  if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6137  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6138  return DRFLAC_FALSE;
6139  }
6140 
6141  metadata.pRawData = pRawData;
6142  metadata.rawDataSize = blockSize;
6143  onMeta(pUserDataMD, &metadata);
6144 
6145  drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6146  }
6147  } break;
6148  }
6149 
6150  /* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */
6151  if (onMeta == NULL && blockSize > 0) {
6152  if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
6153  isLastBlock = DRFLAC_TRUE;
6154  }
6155  }
6156 
6157  runningFilePos += blockSize;
6158  if (isLastBlock) {
6159  break;
6160  }
6161  }
6162 
6163  *pSeektablePos = seektablePos;
6164  *pSeektableSize = seektableSize;
6165  *pFirstFramePos = runningFilePos;
6166 
6167  return DRFLAC_TRUE;
6168 }
6169 
6170 drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
6171 {
6172  /* Pre Condition: The bit stream should be sitting just past the 4-byte id header. */
6173 
6174  drflac_uint8 isLastBlock;
6175  drflac_uint8 blockType;
6176  drflac_uint32 blockSize;
6177 
6178  (void)onSeek;
6179 
6181 
6182  /* The first metadata block should be the STREAMINFO block. */
6183  if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
6184  return DRFLAC_FALSE;
6185  }
6186 
6187  if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
6188  if (!relaxed) {
6189  /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */
6190  return DRFLAC_FALSE;
6191  } else {
6192  /*
6193  Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
6194  for that frame.
6195  */
6198 
6199  if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
6200  return DRFLAC_FALSE; /* Couldn't find a frame. */
6201  }
6202 
6203  if (pInit->firstFrameHeader.bitsPerSample == 0) {
6204  return DRFLAC_FALSE; /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */
6205  }
6206 
6207  pInit->sampleRate = pInit->firstFrameHeader.sampleRate;
6210  pInit->maxBlockSizeInPCMFrames = 65535; /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */
6211  return DRFLAC_TRUE;
6212  }
6213  } else {
6214  drflac_streaminfo streaminfo;
6215  if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
6216  return DRFLAC_FALSE;
6217  }
6218 
6220  pInit->sampleRate = streaminfo.sampleRate;
6221  pInit->channels = streaminfo.channels;
6222  pInit->bitsPerSample = streaminfo.bitsPerSample;
6223  pInit->totalPCMFrameCount = streaminfo.totalPCMFrameCount;
6224  pInit->maxBlockSizeInPCMFrames = streaminfo.maxBlockSizeInPCMFrames; /* Don't care about the min block size - only the max (used for determining the size of the memory allocation). */
6225  pInit->hasMetadataBlocks = !isLastBlock;
6226 
6227  if (onMeta) {
6228  drflac_metadata metadata;
6230  metadata.pRawData = NULL;
6231  metadata.rawDataSize = 0;
6232  metadata.data.streaminfo = streaminfo;
6233  onMeta(pUserDataMD, &metadata);
6234  }
6235 
6236  return DRFLAC_TRUE;
6237  }
6238 }
6239 
6240 #ifndef DR_FLAC_NO_OGG
6241 #define DRFLAC_OGG_MAX_PAGE_SIZE 65307
6242 #define DRFLAC_OGG_CAPTURE_PATTERN_CRC32 1605413199 /* CRC-32 of "OggS". */
6243 
6244 typedef enum
6245 {
6249 
6250 #ifndef DR_FLAC_NO_CRC
6252  0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
6253  0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
6254  0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
6255  0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
6256  0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
6257  0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
6258  0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
6259  0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
6260  0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
6261  0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
6262  0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
6263  0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
6264  0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
6265  0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
6266  0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
6267  0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
6268  0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
6269  0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
6270  0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
6271  0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
6272  0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
6273  0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
6274  0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
6275  0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
6276  0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
6277  0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
6278  0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
6279  0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
6280  0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
6281  0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
6282  0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
6283  0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
6284  0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
6285  0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
6286  0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
6287  0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
6288  0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
6289  0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
6290  0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
6291  0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
6292  0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
6293  0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
6294  0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
6295  0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
6296  0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
6297  0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
6298  0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
6299  0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
6300  0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
6301  0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
6302  0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
6303  0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
6304  0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
6305  0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
6306  0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
6307  0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
6308  0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
6309  0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
6310  0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
6311  0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
6312  0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
6313  0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
6314  0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
6315  0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
6316 };
6317 #endif
6318 
6320 {
6321 #ifndef DR_FLAC_NO_CRC
6322  return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data];
6323 #else
6324  (void)data;
6325  return crc32;
6326 #endif
6327 }
6328 
6329 #if 0
6330 static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data)
6331 {
6332  crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
6333  crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
6334  crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF));
6335  crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF));
6336  return crc32;
6337 }
6338 
6339 static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data)
6340 {
6341  crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
6342  crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF));
6343  return crc32;
6344 }
6345 #endif
6346 
6348 {
6349  /* This can be optimized. */
6350  drflac_uint32 i;
6351  for (i = 0; i < dataSize; ++i) {
6352  crc32 = drflac_crc32_byte(crc32, pData[i]);
6353  }
6354  return crc32;
6355 }
6356 
6357 
6359 {
6360  return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S';
6361 }
6362 
6364 {
6365  return 27 + pHeader->segmentCount;
6366 }
6367 
6369 {
6370  drflac_uint32 pageBodySize = 0;
6371  int i;
6372 
6373  for (i = 0; i < pHeader->segmentCount; ++i) {
6374  pageBodySize += pHeader->segmentTable[i];
6375  }
6376 
6377  return pageBodySize;
6378 }
6379 
6381 {
6382  drflac_uint8 data[23];
6383  drflac_uint32 i;
6384 
6386 
6387  if (onRead(pUserData, data, 23) != 23) {
6388  return DRFLAC_END_OF_STREAM;
6389  }
6390  *pBytesRead += 23;
6391 
6392  /*
6393  It's not actually used, but set the capture pattern to 'OggS' for completeness. Not doing this will cause static analysers to complain about
6394  us trying to access uninitialized data. We could alternatively just comment out this member of the drflac_ogg_page_header structure, but I
6395  like to have it map to the structure of the underlying data.
6396  */
6397  pHeader->capturePattern[0] = 'O';
6398  pHeader->capturePattern[1] = 'g';
6399  pHeader->capturePattern[2] = 'g';
6400  pHeader->capturePattern[3] = 'S';
6401 
6402  pHeader->structureVersion = data[0];
6403  pHeader->headerType = data[1];
6404  DRFLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
6405  DRFLAC_COPY_MEMORY(&pHeader->serialNumber, &data[10], 4);
6406  DRFLAC_COPY_MEMORY(&pHeader->sequenceNumber, &data[14], 4);
6407  DRFLAC_COPY_MEMORY(&pHeader->checksum, &data[18], 4);
6408  pHeader->segmentCount = data[22];
6409 
6410  /* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */
6411  data[18] = 0;
6412  data[19] = 0;
6413  data[20] = 0;
6414  data[21] = 0;
6415 
6416  for (i = 0; i < 23; ++i) {
6417  *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]);
6418  }
6419 
6420 
6421  if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
6422  return DRFLAC_END_OF_STREAM;
6423  }
6424  *pBytesRead += pHeader->segmentCount;
6425 
6426  for (i = 0; i < pHeader->segmentCount; ++i) {
6427  *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]);
6428  }
6429 
6430  return DRFLAC_SUCCESS;
6431 }
6432 
6434 {
6435  drflac_uint8 id[4];
6436 
6437  *pBytesRead = 0;
6438 
6439  if (onRead(pUserData, id, 4) != 4) {
6440  return DRFLAC_END_OF_STREAM;
6441  }
6442  *pBytesRead += 4;
6443 
6444  /* We need to read byte-by-byte until we find the OggS capture pattern. */
6445  for (;;) {
6447  drflac_result result;
6448 
6450 
6451  result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
6452  if (result == DRFLAC_SUCCESS) {
6453  return DRFLAC_SUCCESS;
6454  } else {
6455  if (result == DRFLAC_CRC_MISMATCH) {
6456  continue;
6457  } else {
6458  return result;
6459  }
6460  }
6461  } else {
6462  /* The first 4 bytes did not equal the capture pattern. Read the next byte and try again. */
6463  id[0] = id[1];
6464  id[1] = id[2];
6465  id[2] = id[3];
6466  if (onRead(pUserData, &id[3], 1) != 1) {
6467  return DRFLAC_END_OF_STREAM;
6468  }
6469  *pBytesRead += 1;
6470  }
6471  }
6472 }
6473 
6474 
6475 /*
6476 The main part of the Ogg encapsulation is the conversion from the physical Ogg bitstream to the native FLAC bitstream. It works
6477 in three general stages: Ogg Physical Bitstream -> Ogg/FLAC Logical Bitstream -> FLAC Native Bitstream. dr_flac is designed
6478 in such a way that the core sections assume everything is delivered in native format. Therefore, for each encapsulation type
6479 dr_flac is supporting there needs to be a layer sitting on top of the onRead and onSeek callbacks that ensures the bits read from
6480 the physical Ogg bitstream are converted and delivered in native FLAC format.
6481 */
6482 typedef struct
6483 {
6484  drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */
6485  drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */
6486  void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */
6487  drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */
6488  drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */
6489  drflac_uint32 serialNumber; /* The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization. */
6490  drflac_ogg_page_header bosPageHeader; /* Used for seeking. */
6491  drflac_ogg_page_header currentPageHeader;
6492  drflac_uint32 bytesRemainingInPage;
6493  drflac_uint32 pageDataSize;
6495 } drflac_oggbs; /* oggbs = Ogg Bitstream */
6496 
6497 static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
6498 {
6499  size_t bytesActuallyRead = oggbs->onRead(oggbs->pUserData, bufferOut, bytesToRead);
6500  oggbs->currentBytePos += bytesActuallyRead;
6501 
6502  return bytesActuallyRead;
6503 }
6504 
6506 {
6507  if (origin == drflac_seek_origin_start) {
6508  if (offset <= 0x7FFFFFFF) {
6509  if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) {
6510  return DRFLAC_FALSE;
6511  }
6512  oggbs->currentBytePos = offset;
6513 
6514  return DRFLAC_TRUE;
6515  } else {
6516  if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
6517  return DRFLAC_FALSE;
6518  }
6519  oggbs->currentBytePos = offset;
6520 
6521  return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current);
6522  }
6523  } else {
6524  while (offset > 0x7FFFFFFF) {
6525  if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
6526  return DRFLAC_FALSE;
6527  }
6528  oggbs->currentBytePos += 0x7FFFFFFF;
6529  offset -= 0x7FFFFFFF;
6530  }
6531 
6532  if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) { /* <-- Safe cast thanks to the loop above. */
6533  return DRFLAC_FALSE;
6534  }
6535  oggbs->currentBytePos += offset;
6536 
6537  return DRFLAC_TRUE;
6538  }
6539 }
6540 
6542 {
6544  for (;;) {
6545  drflac_uint32 crc32 = 0;
6546  drflac_uint32 bytesRead;
6547  drflac_uint32 pageBodySize;
6548 #ifndef DR_FLAC_NO_CRC
6549  drflac_uint32 actualCRC32;
6550 #endif
6551 
6552  if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
6553  return DRFLAC_FALSE;
6554  }
6555  oggbs->currentBytePos += bytesRead;
6556 
6557  pageBodySize = drflac_ogg__get_page_body_size(&header);
6558  if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) {
6559  continue; /* Invalid page size. Assume it's corrupted and just move to the next page. */
6560  }
6561 
6562  if (header.serialNumber != oggbs->serialNumber) {
6563  /* It's not a FLAC page. Skip it. */
6564  if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) {
6565  return DRFLAC_FALSE;
6566  }
6567  continue;
6568  }
6569 
6570 
6571  /* We need to read the entire page and then do a CRC check on it. If there's a CRC mismatch we need to skip this page. */
6572  if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) {
6573  return DRFLAC_FALSE;
6574  }
6575  oggbs->pageDataSize = pageBodySize;
6576 
6577 #ifndef DR_FLAC_NO_CRC
6578  actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize);
6579  if (actualCRC32 != header.checksum) {
6580  if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) {
6581  continue; /* CRC mismatch. Skip this page. */
6582  } else {
6583  /*
6584  Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we
6585  go to the next valid page to ensure we're in a good state, but return false to let the caller know that the
6586  seek did not fully complete.
6587  */
6589  return DRFLAC_FALSE;
6590  }
6591  }
6592 #else
6593  (void)recoveryMethod; /* <-- Silence a warning. */
6594 #endif
6595 
6596  oggbs->currentPageHeader = header;
6597  oggbs->bytesRemainingInPage = pageBodySize;
6598  return DRFLAC_TRUE;
6599  }
6600 }
6601 
6602 /* Function below is unused at the moment, but I might be re-adding it later. */
6603 #if 0
6604 static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg)
6605 {
6607  drflac_uint8 iSeg = 0;
6608  drflac_uint32 iByte = 0;
6609  while (iByte < bytesConsumedInPage) {
6610  drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
6611  if (iByte + segmentSize > bytesConsumedInPage) {
6612  break;
6613  } else {
6614  iSeg += 1;
6615  iByte += segmentSize;
6616  }
6617  }
6618 
6619  *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte);
6620  return iSeg;
6621 }
6622 
6623 static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
6624 {
6625  /* The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. */
6626  for (;;) {
6627  drflac_bool32 atEndOfPage = DRFLAC_FALSE;
6628 
6629  drflac_uint8 bytesRemainingInSeg;
6630  drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
6631 
6632  drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
6633  for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
6634  drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
6635  if (segmentSize < 255) {
6636  if (iSeg == oggbs->currentPageHeader.segmentCount-1) {
6637  atEndOfPage = DRFLAC_TRUE;
6638  }
6639 
6640  break;
6641  }
6642 
6643  bytesToEndOfPacketOrPage += segmentSize;
6644  }
6645 
6646  /*
6647  At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
6648  want to load the next page and keep searching for the end of the packet.
6649  */
6650  drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current);
6651  oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
6652 
6653  if (atEndOfPage) {
6654  /*
6655  We're potentially at the next packet, but we need to check the next page first to be sure because the packet may
6656  straddle pages.
6657  */
6658  if (!drflac_oggbs__goto_next_page(oggbs)) {
6659  return DRFLAC_FALSE;
6660  }
6661 
6662  /* If it's a fresh packet it most likely means we're at the next packet. */
6663  if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
6664  return DRFLAC_TRUE;
6665  }
6666  } else {
6667  /* We're at the next packet. */
6668  return DRFLAC_TRUE;
6669  }
6670  }
6671 }
6672 
6673 static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
6674 {
6675  /* The bitstream should be sitting on the first byte just after the header of the frame. */
6676 
6677  /* What we're actually doing here is seeking to the start of the next packet. */
6678  return drflac_oggbs__seek_to_next_packet(oggbs);
6679 }
6680 #endif
6681 
6682 static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
6683 {
6684  drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
6685  drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
6686  size_t bytesRead = 0;
6687 
6688  DRFLAC_ASSERT(oggbs != NULL);
6689  DRFLAC_ASSERT(pRunningBufferOut != NULL);
6690 
6691  /* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */
6692  while (bytesRead < bytesToRead) {
6693  size_t bytesRemainingToRead = bytesToRead - bytesRead;
6694 
6695  if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) {
6696  DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
6697  bytesRead += bytesRemainingToRead;
6698  oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead;
6699  break;
6700  }
6701 
6702  /* If we get here it means some of the requested data is contained in the next pages. */
6703  if (oggbs->bytesRemainingInPage > 0) {
6704  DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
6705  bytesRead += oggbs->bytesRemainingInPage;
6706  pRunningBufferOut += oggbs->bytesRemainingInPage;
6707  oggbs->bytesRemainingInPage = 0;
6708  }
6709 
6710  DRFLAC_ASSERT(bytesRemainingToRead > 0);
6712  break; /* Failed to go to the next page. Might have simply hit the end of the stream. */
6713  }
6714  }
6715 
6716  return bytesRead;
6717 }
6718 
6719 static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin)
6720 {
6721  drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
6722  int bytesSeeked = 0;
6723 
6724  DRFLAC_ASSERT(oggbs != NULL);
6725  DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
6726 
6727  /* Seeking is always forward which makes things a lot simpler. */
6728  if (origin == drflac_seek_origin_start) {
6730  return DRFLAC_FALSE;
6731  }
6732 
6734  return DRFLAC_FALSE;
6735  }
6736 
6737  return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current);
6738  }
6739 
6741 
6742  while (bytesSeeked < offset) {
6743  int bytesRemainingToSeek = offset - bytesSeeked;
6744  DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
6745 
6746  if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
6747  bytesSeeked += bytesRemainingToSeek;
6748  (void)bytesSeeked; /* <-- Silence a dead store warning emitted by Clang Static Analyzer. */
6749  oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
6750  break;
6751  }
6752 
6753  /* If we get here it means some of the requested data is contained in the next pages. */
6754  if (oggbs->bytesRemainingInPage > 0) {
6755  bytesSeeked += (int)oggbs->bytesRemainingInPage;
6756  oggbs->bytesRemainingInPage = 0;
6757  }
6758 
6759  DRFLAC_ASSERT(bytesRemainingToSeek > 0);
6761  /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
6762  return DRFLAC_FALSE;
6763  }
6764  }
6765 
6766  return DRFLAC_TRUE;
6767 }
6768 
6769 
6771 {
6772  drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
6773  drflac_uint64 originalBytePos;
6774  drflac_uint64 runningGranulePosition;
6775  drflac_uint64 runningFrameBytePos;
6776  drflac_uint64 runningPCMFrameCount;
6777 
6778  DRFLAC_ASSERT(oggbs != NULL);
6779 
6780  originalBytePos = oggbs->currentBytePos; /* For recovery. Points to the OggS identifier. */
6781 
6782  /* First seek to the first frame. */
6783  if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
6784  return DRFLAC_FALSE;
6785  }
6786  oggbs->bytesRemainingInPage = 0;
6787 
6788  runningGranulePosition = 0;
6789  for (;;) {
6791  drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
6792  return DRFLAC_FALSE; /* Never did find that sample... */
6793  }
6794 
6795  runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
6796  if (oggbs->currentPageHeader.granulePosition >= pcmFrameIndex) {
6797  break; /* The sample is somewhere in the previous page. */
6798  }
6799 
6800  /*
6801  At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
6802  disregard any pages that do not begin a fresh packet.
6803  */
6804  if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { /* <-- Is it a fresh page? */
6805  if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
6806  drflac_uint8 firstBytesInPage[2];
6807  firstBytesInPage[0] = oggbs->pageData[0];
6808  firstBytesInPage[1] = oggbs->pageData[1];
6809 
6810  if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) { /* <-- Does the page begin with a frame's sync code? */
6811  runningGranulePosition = oggbs->currentPageHeader.granulePosition;
6812  }
6813 
6814  continue;
6815  }
6816  }
6817  }
6818 
6819  /*
6820  We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the
6821  start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of
6822  a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
6823  we find the one containing the target sample.
6824  */
6825  if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
6826  return DRFLAC_FALSE;
6827  }
6829  return DRFLAC_FALSE;
6830  }
6831 
6832  /*
6833  At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
6834  looping over these frames until we find the one containing the sample we're after.
6835  */
6836  runningPCMFrameCount = runningGranulePosition;
6837  for (;;) {
6838  /*
6839  There are two ways to find the sample and seek past irrelevant frames:
6840  1) Use the native FLAC decoder.
6841  2) Use Ogg's framing system.
6842 
6843  Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
6844  do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
6845  duplication for the decoding of frame headers.
6846 
6847  Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
6848  bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
6849  standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks
6850  the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
6851  using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to
6852  avoid the use of the drflac_bs object.
6853 
6854  Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
6855  1) Seeking is already partially accelerated using Ogg's paging system in the code block above.
6856  2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
6857  3) Simplicity.
6858  */
6859  drflac_uint64 firstPCMFrameInFLACFrame = 0;
6860  drflac_uint64 lastPCMFrameInFLACFrame = 0;
6861  drflac_uint64 pcmFrameCountInThisFrame;
6862 
6864  return DRFLAC_FALSE;
6865  }
6866 
6867  drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
6868 
6869  pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
6870 
6871  /* If we are seeking to the end of the file and we've just hit it, we're done. */
6872  if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
6873  drflac_result result = drflac__decode_flac_frame(pFlac);
6874  if (result == DRFLAC_SUCCESS) {
6875  pFlac->currentPCMFrame = pcmFrameIndex;
6877  return DRFLAC_TRUE;
6878  } else {
6879  return DRFLAC_FALSE;
6880  }
6881  }
6882 
6883  if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
6884  /*
6885  The sample should be in this FLAC frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend
6886  it never existed and keep iterating.
6887  */
6888  drflac_result result = drflac__decode_flac_frame(pFlac);
6889  if (result == DRFLAC_SUCCESS) {
6890  /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
6891  drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */
6892  if (pcmFramesToDecode == 0) {
6893  return DRFLAC_TRUE;
6894  }
6895 
6896  pFlac->currentPCMFrame = runningPCMFrameCount;
6897 
6898  return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */
6899  } else {
6900  if (result == DRFLAC_CRC_MISMATCH) {
6901  continue; /* CRC mismatch. Pretend this frame never existed. */
6902  } else {
6903  return DRFLAC_FALSE;
6904  }
6905  }
6906  } else {
6907  /*
6908  It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this
6909  frame never existed and leave the running sample count untouched.
6910  */
6912  if (result == DRFLAC_SUCCESS) {
6913  runningPCMFrameCount += pcmFrameCountInThisFrame;
6914  } else {
6915  if (result == DRFLAC_CRC_MISMATCH) {
6916  continue; /* CRC mismatch. Pretend this frame never existed. */
6917  } else {
6918  return DRFLAC_FALSE;
6919  }
6920  }
6921  }
6922  }
6923 }
6924 
6925 
6926 
6927 drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
6928 {
6931  drflac_uint32 bytesRead = 0;
6932 
6933  /* Pre Condition: The bit stream should be sitting just past the 4-byte OggS capture pattern. */
6934  (void)relaxed;
6935 
6937  pInit->oggFirstBytePos = 0;
6938 
6939  /*
6940  We'll get here if the first 4 bytes of the stream were the OggS capture pattern, however it doesn't necessarily mean the
6941  stream includes FLAC encoded audio. To check for this we need to scan the beginning-of-stream page markers and check if
6942  any match the FLAC specification. Important to keep in mind that the stream may be multiplexed.
6943  */
6944  if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
6945  return DRFLAC_FALSE;
6946  }
6947  pInit->runningFilePos += bytesRead;
6948 
6949  for (;;) {
6950  int pageBodySize;
6951 
6952  /* Break if we're past the beginning of stream page. */
6953  if ((header.headerType & 0x02) == 0) {
6954  return DRFLAC_FALSE;
6955  }
6956 
6957  /* Check if it's a FLAC header. */
6958  pageBodySize = drflac_ogg__get_page_body_size(&header);
6959  if (pageBodySize == 51) { /* 51 = the lacing value of the FLAC header packet. */
6960  /* It could be a FLAC page... */
6961  drflac_uint32 bytesRemainingInPage = pageBodySize;
6962  drflac_uint8 packetType;
6963 
6964  if (onRead(pUserData, &packetType, 1) != 1) {
6965  return DRFLAC_FALSE;
6966  }
6967 
6968  bytesRemainingInPage -= 1;
6969  if (packetType == 0x7F) {
6970  /* Increasingly more likely to be a FLAC page... */
6971  drflac_uint8 sig[4];
6972  if (onRead(pUserData, sig, 4) != 4) {
6973  return DRFLAC_FALSE;
6974  }
6975 
6976  bytesRemainingInPage -= 4;
6977  if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') {
6978  /* Almost certainly a FLAC page... */
6979  drflac_uint8 mappingVersion[2];
6980  if (onRead(pUserData, mappingVersion, 2) != 2) {
6981  return DRFLAC_FALSE;
6982  }
6983 
6984  if (mappingVersion[0] != 1) {
6985  return DRFLAC_FALSE; /* Only supporting version 1.x of the Ogg mapping. */
6986  }
6987 
6988  /*
6989  The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
6990  be handling it in a generic way based on the serial number and packet types.
6991  */
6992  if (!onSeek(pUserData, 2, drflac_seek_origin_current)) {
6993  return DRFLAC_FALSE;
6994  }
6995 
6996  /* Expecting the native FLAC signature "fLaC". */
6997  if (onRead(pUserData, sig, 4) != 4) {
6998  return DRFLAC_FALSE;
6999  }
7000 
7001  if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') {
7002  /* The remaining data in the page should be the STREAMINFO block. */
7003  drflac_streaminfo streaminfo;
7004  drflac_uint8 isLastBlock;
7005  drflac_uint8 blockType;
7006  drflac_uint32 blockSize;
7007  if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
7008  return DRFLAC_FALSE;
7009  }
7010 
7011  if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
7012  return DRFLAC_FALSE; /* Invalid block type. First block must be the STREAMINFO block. */
7013  }
7014 
7015  if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
7016  /* Success! */
7018  pInit->sampleRate = streaminfo.sampleRate;
7019  pInit->channels = streaminfo.channels;
7020  pInit->bitsPerSample = streaminfo.bitsPerSample;
7021  pInit->totalPCMFrameCount = streaminfo.totalPCMFrameCount;
7023  pInit->hasMetadataBlocks = !isLastBlock;
7024 
7025  if (onMeta) {
7026  drflac_metadata metadata;
7028  metadata.pRawData = NULL;
7029  metadata.rawDataSize = 0;
7030  metadata.data.streaminfo = streaminfo;
7031  onMeta(pUserDataMD, &metadata);
7032  }
7033 
7034  pInit->runningFilePos += pageBodySize;
7035  pInit->oggFirstBytePos = pInit->runningFilePos - 79; /* Subtracting 79 will place us right on top of the "OggS" identifier of the FLAC bos page. */
7036  pInit->oggSerial = header.serialNumber;
7037  pInit->oggBosHeader = header;
7038  break;
7039  } else {
7040  /* Failed to read STREAMINFO block. Aww, so close... */
7041  return DRFLAC_FALSE;
7042  }
7043  } else {
7044  /* Invalid file. */
7045  return DRFLAC_FALSE;
7046  }
7047  } else {
7048  /* Not a FLAC header. Skip it. */
7049  if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
7050  return DRFLAC_FALSE;
7051  }
7052  }
7053  } else {
7054  /* Not a FLAC header. Seek past the entire page and move on to the next. */
7055  if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
7056  return DRFLAC_FALSE;
7057  }
7058  }
7059  } else {
7060  if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) {
7061  return DRFLAC_FALSE;
7062  }
7063  }
7064 
7065  pInit->runningFilePos += pageBodySize;
7066 
7067 
7068  /* Read the header of the next page. */
7069  if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7070  return DRFLAC_FALSE;
7071  }
7072  pInit->runningFilePos += bytesRead;
7073  }
7074 
7075  /*
7076  If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next
7077  packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialization phase for Ogg is to create the
7078  Ogg bistream object.
7079  */
7080  pInit->hasMetadataBlocks = DRFLAC_TRUE; /* <-- Always have at least VORBIS_COMMENT metadata block. */
7081  return DRFLAC_TRUE;
7082 }
7083 #endif
7084 
7085 drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
7086 {
7087  drflac_bool32 relaxed;
7088  drflac_uint8 id[4];
7089 
7090  if (pInit == NULL || onRead == NULL || onSeek == NULL) {
7091  return DRFLAC_FALSE;
7092  }
7093 
7094  DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
7095  pInit->onRead = onRead;
7096  pInit->onSeek = onSeek;
7097  pInit->onMeta = onMeta;
7098  pInit->container = container;
7099  pInit->pUserData = pUserData;
7100  pInit->pUserDataMD = pUserDataMD;
7101 
7102  pInit->bs.onRead = onRead;
7103  pInit->bs.onSeek = onSeek;
7104  pInit->bs.pUserData = pUserData;
7105  drflac__reset_cache(&pInit->bs);
7106 
7107 
7108  /* If the container is explicitly defined then we can try opening in relaxed mode. */
7109  relaxed = container != drflac_container_unknown;
7110 
7111  /* Skip over any ID3 tags. */
7112  for (;;) {
7113  if (onRead(pUserData, id, 4) != 4) {
7114  return DRFLAC_FALSE; /* Ran out of data. */
7115  }
7116  pInit->runningFilePos += 4;
7117 
7118  if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') {
7119  drflac_uint8 header[6];
7120  drflac_uint8 flags;
7121  drflac_uint32 headerSize;
7122 
7123  if (onRead(pUserData, header, 6) != 6) {
7124  return DRFLAC_FALSE; /* Ran out of data. */
7125  }
7126  pInit->runningFilePos += 6;
7127 
7128  flags = header[1];
7129 
7130  DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
7131  headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
7132  if (flags & 0x10) {
7133  headerSize += 10;
7134  }
7135 
7136  if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) {
7137  return DRFLAC_FALSE; /* Failed to seek past the tag. */
7138  }
7139  pInit->runningFilePos += headerSize;
7140  } else {
7141  break;
7142  }
7143  }
7144 
7145  if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') {
7146  return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7147  }
7148 #ifndef DR_FLAC_NO_OGG
7149  if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') {
7150  return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7151  }
7152 #endif
7153 
7154  /* If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable. */
7155  if (relaxed) {
7156  if (container == drflac_container_native) {
7157  return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7158  }
7159 #ifndef DR_FLAC_NO_OGG
7160  if (container == drflac_container_ogg) {
7161  return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
7162  }
7163 #endif
7164  }
7165 
7166  /* Unsupported container. */
7167  return DRFLAC_FALSE;
7168 }
7169 
7170 void drflac__init_from_info(drflac* pFlac, const drflac_init_info* pInit)
7171 {
7172  DRFLAC_ASSERT(pFlac != NULL);
7173  DRFLAC_ASSERT(pInit != NULL);
7174 
7175  DRFLAC_ZERO_MEMORY(pFlac, sizeof(*pFlac));
7176  pFlac->bs = pInit->bs;
7177  pFlac->onMeta = pInit->onMeta;
7178  pFlac->pUserDataMD = pInit->pUserDataMD;
7180  pFlac->sampleRate = pInit->sampleRate;
7181  pFlac->channels = (drflac_uint8)pInit->channels;
7182  pFlac->bitsPerSample = (drflac_uint8)pInit->bitsPerSample;
7183  pFlac->totalPCMFrameCount = pInit->totalPCMFrameCount;
7184  pFlac->container = pInit->container;
7185 }
7186 
7187 
7188 drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
7189 {
7191  drflac_uint32 allocationSize;
7192  drflac_uint32 wholeSIMDVectorCountPerChannel;
7193  drflac_uint32 decodedSamplesAllocationSize;
7194 #ifndef DR_FLAC_NO_OGG
7195  drflac_oggbs oggbs;
7196 #endif
7197  drflac_uint64 firstFramePos;
7198  drflac_uint64 seektablePos;
7199  drflac_uint32 seektableSize;
7200  drflac_allocation_callbacks allocationCallbacks;
7201  drflac* pFlac;
7202 
7203  /* CPU support first. */
7205 
7206  if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
7207  return NULL;
7208  }
7209 
7210  if (pAllocationCallbacks != NULL) {
7211  allocationCallbacks = *pAllocationCallbacks;
7212  if (allocationCallbacks.onFree == NULL || (allocationCallbacks.onMalloc == NULL && allocationCallbacks.onRealloc == NULL)) {
7213  return NULL; /* Invalid allocation callbacks. */
7214  }
7215  } else {
7216  allocationCallbacks.pUserData = NULL;
7217  allocationCallbacks.onMalloc = drflac__malloc_default;
7218  allocationCallbacks.onRealloc = drflac__realloc_default;
7219  allocationCallbacks.onFree = drflac__free_default;
7220  }
7221 
7222 
7223  /*
7224  The size of the allocation for the drflac object needs to be large enough to fit the following:
7225  1) The main members of the drflac structure
7226  2) A block of memory large enough to store the decoded samples of the largest frame in the stream
7227  3) If the container is Ogg, a drflac_oggbs object
7228 
7229  The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
7230  the different SIMD instruction sets.
7231  */
7232  allocationSize = sizeof(drflac);
7233 
7234  /*
7235  The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
7236  we are supporting.
7237  */
7238  if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
7239  wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
7240  } else {
7241  wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
7242  }
7243 
7244  decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;
7245 
7246  allocationSize += decodedSamplesAllocationSize;
7247  allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE; /* Allocate extra bytes to ensure we have enough for alignment. */
7248 
7249 #ifndef DR_FLAC_NO_OGG
7250  /* There's additional data required for Ogg streams. */
7251  if (init.container == drflac_container_ogg) {
7252  allocationSize += sizeof(drflac_oggbs);
7253  }
7254 
7255  DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
7256  if (init.container == drflac_container_ogg) {
7257  oggbs.onRead = onRead;
7258  oggbs.onSeek = onSeek;
7259  oggbs.pUserData = pUserData;
7260  oggbs.currentBytePos = init.oggFirstBytePos;
7261  oggbs.firstBytePos = init.oggFirstBytePos;
7262  oggbs.serialNumber = init.oggSerial;
7263  oggbs.bosPageHeader = init.oggBosHeader;
7264  oggbs.bytesRemainingInPage = 0;
7265  }
7266 #endif
7267 
7268  /*
7269  This part is a bit awkward. We need to load the seektable so that it can be referenced in-memory, but I want the drflac object to
7270  consist of only a single heap allocation. To this, the size of the seek table needs to be known, which we determine when reading
7271  and decoding the metadata.
7272  */
7273  firstFramePos = 42; /* <-- We know we are at byte 42 at this point. */
7274  seektablePos = 0;
7275  seektableSize = 0;
7276  if (init.hasMetadataBlocks) {
7277  drflac_read_proc onReadOverride = onRead;
7278  drflac_seek_proc onSeekOverride = onSeek;
7279  void* pUserDataOverride = pUserData;
7280 
7281 #ifndef DR_FLAC_NO_OGG
7282  if (init.container == drflac_container_ogg) {
7283  onReadOverride = drflac__on_read_ogg;
7284  onSeekOverride = drflac__on_seek_ogg;
7285  pUserDataOverride = (void*)&oggbs;
7286  }
7287 #endif
7288 
7289  if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize, &allocationCallbacks)) {
7290  return NULL;
7291  }
7292 
7293  allocationSize += seektableSize;
7294  }
7295 
7296 
7297  pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
7298  if (pFlac == NULL) {
7299  return NULL;
7300  }
7301 
7302  drflac__init_from_info(pFlac, &init);
7303  pFlac->allocationCallbacks = allocationCallbacks;
7305 
7306 #ifndef DR_FLAC_NO_OGG
7307  if (init.container == drflac_container_ogg) {
7308  drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
7309  *pInternalOggbs = oggbs;
7310 
7311  /* The Ogg bistream needs to be layered on top of the original bitstream. */
7312  pFlac->bs.onRead = drflac__on_read_ogg;
7313  pFlac->bs.onSeek = drflac__on_seek_ogg;
7314  pFlac->bs.pUserData = (void*)pInternalOggbs;
7315  pFlac->_oggbs = (void*)pInternalOggbs;
7316  }
7317 #endif
7318 
7319  pFlac->firstFLACFramePosInBytes = firstFramePos;
7320 
7321  /* NOTE: Seektables are not currently compatible with Ogg encapsulation (Ogg has its own accelerated seeking system). I may change this later, so I'm leaving this here for now. */
7322 #ifndef DR_FLAC_NO_OGG
7323  if (init.container == drflac_container_ogg)
7324  {
7325  pFlac->pSeekpoints = NULL;
7326  pFlac->seekpointCount = 0;
7327  }
7328  else
7329 #endif
7330  {
7331  /* If we have a seektable we need to load it now, making sure we move back to where we were previously. */
7332  if (seektablePos != 0) {
7333  pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints);
7334  pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
7335 
7336  DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
7337  DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
7338 
7339  /* Seek to the seektable, then just read directly into our seektable buffer. */
7340  if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
7341  if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) {
7342  /* Endian swap. */
7343  drflac_uint32 iSeekpoint;
7344  for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
7345  pFlac->pSeekpoints[iSeekpoint].firstPCMFrame = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
7346  pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
7347  pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
7348  }
7349  } else {
7350  /* Failed to read the seektable. Pretend we don't have one. */
7351  pFlac->pSeekpoints = NULL;
7352  pFlac->seekpointCount = 0;
7353  }
7354 
7355  /* We need to seek back to where we were. If this fails it's a critical error. */
7356  if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
7357  drflac__free_from_callbacks(pFlac, &allocationCallbacks);
7358  return NULL;
7359  }
7360  } else {
7361  /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
7362  pFlac->pSeekpoints = NULL;
7363  pFlac->seekpointCount = 0;
7364  }
7365  }
7366  }
7367 
7368 
7369  /*
7370  If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
7371  the first frame.
7372  */
7373  if (!init.hasStreamInfoBlock) {
7374  pFlac->currentFLACFrame.header = init.firstFrameHeader;
7375  do
7376  {
7377  drflac_result result = drflac__decode_flac_frame(pFlac);
7378  if (result == DRFLAC_SUCCESS) {
7379  break;
7380  } else {
7381  if (result == DRFLAC_CRC_MISMATCH) {
7383  drflac__free_from_callbacks(pFlac, &allocationCallbacks);
7384  return NULL;
7385  }
7386  continue;
7387  } else {
7388  drflac__free_from_callbacks(pFlac, &allocationCallbacks);
7389  return NULL;
7390  }
7391  }
7392  } while (1);
7393  }
7394 
7395  return pFlac;
7396 }
7397 
7398 
7399 
7400 #ifndef DR_FLAC_NO_STDIO
7401 #include <stdio.h>
7402 
7403 static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
7404 {
7405  return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
7406 }
7407 
7408 static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
7409 {
7410  DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
7411 
7412  return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
7413 }
7414 
7415 static FILE* drflac__fopen(const char* filename)
7416 {
7417  FILE* pFile;
7418 #if defined(_MSC_VER) && _MSC_VER >= 1400
7419  if (fopen_s(&pFile, filename, "rb") != 0) {
7420  return NULL;
7421  }
7422 #else
7423  pFile = fopen(filename, "rb");
7424  if (pFile == NULL) {
7425  return NULL;
7426  }
7427 #endif
7428 
7429  return pFile;
7430 }
7431 
7432 
7433 drflac* drflac_open_file(const char* filename, const drflac_allocation_callbacks* pAllocationCallbacks)
7434 {
7435  drflac* pFlac;
7436  FILE* pFile;
7437 
7438  pFile = drflac__fopen(filename);
7439  if (pFile == NULL) {
7440  return NULL;
7441  }
7442 
7443  pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
7444  if (pFlac == NULL) {
7445  fclose(pFile);
7446  return NULL;
7447  }
7448 
7449  return pFlac;
7450 }
7451 
7452 drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7453 {
7454  drflac* pFlac;
7455  FILE* pFile;
7456 
7457  pFile = drflac__fopen(filename);
7458  if (pFile == NULL) {
7459  return NULL;
7460  }
7461 
7462  pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
7463  if (pFlac == NULL) {
7464  fclose(pFile);
7465  return pFlac;
7466  }
7467 
7468  return pFlac;
7469 }
7470 #endif /* DR_FLAC_NO_STDIO */
7471 
7472 static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
7473 {
7474  drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
7475  size_t bytesRemaining;
7476 
7477  DRFLAC_ASSERT(memoryStream != NULL);
7478  DRFLAC_ASSERT(memoryStream->dataSize >= memoryStream->currentReadPos);
7479 
7480  bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos;
7481  if (bytesToRead > bytesRemaining) {
7482  bytesToRead = bytesRemaining;
7483  }
7484 
7485  if (bytesToRead > 0) {
7486  DRFLAC_COPY_MEMORY(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
7487  memoryStream->currentReadPos += bytesToRead;
7488  }
7489 
7490  return bytesToRead;
7491 }
7492 
7493 static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
7494 {
7495  drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
7496 
7497  DRFLAC_ASSERT(memoryStream != NULL);
7498  DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
7499 
7500  if (offset > (drflac_int64)memoryStream->dataSize) {
7501  return DRFLAC_FALSE;
7502  }
7503 
7504  if (origin == drflac_seek_origin_current) {
7505  if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
7506  memoryStream->currentReadPos += offset;
7507  } else {
7508  return DRFLAC_FALSE; /* Trying to seek too far forward. */
7509  }
7510  } else {
7511  if ((drflac_uint32)offset <= memoryStream->dataSize) {
7512  memoryStream->currentReadPos = offset;
7513  } else {
7514  return DRFLAC_FALSE; /* Trying to seek too far forward. */
7515  }
7516  }
7517 
7518  return DRFLAC_TRUE;
7519 }
7520 
7521 drflac* drflac_open_memory(const void* data, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks)
7522 {
7523  drflac__memory_stream memoryStream;
7524  drflac* pFlac;
7525 
7526  memoryStream.data = (const unsigned char*)data;
7527  memoryStream.dataSize = dataSize;
7528  memoryStream.currentReadPos = 0;
7529  pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, &memoryStream, pAllocationCallbacks);
7530  if (pFlac == NULL) {
7531  return NULL;
7532  }
7533 
7534  pFlac->memoryStream = memoryStream;
7535 
7536  /* This is an awful hack... */
7537 #ifndef DR_FLAC_NO_OGG
7538  if (pFlac->container == drflac_container_ogg)
7539  {
7540  drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
7541  oggbs->pUserData = &pFlac->memoryStream;
7542  }
7543  else
7544 #endif
7545  {
7546  pFlac->bs.pUserData = &pFlac->memoryStream;
7547  }
7548 
7549  return pFlac;
7550 }
7551 
7552 drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7553 {
7554  drflac__memory_stream memoryStream;
7555  drflac* pFlac;
7556 
7557  memoryStream.data = (const unsigned char*)data;
7558  memoryStream.dataSize = dataSize;
7559  memoryStream.currentReadPos = 0;
7560  pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
7561  if (pFlac == NULL) {
7562  return NULL;
7563  }
7564 
7565  pFlac->memoryStream = memoryStream;
7566 
7567  /* This is an awful hack... */
7568 #ifndef DR_FLAC_NO_OGG
7569  if (pFlac->container == drflac_container_ogg)
7570  {
7571  drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
7572  oggbs->pUserData = &pFlac->memoryStream;
7573  }
7574  else
7575 #endif
7576  {
7577  pFlac->bs.pUserData = &pFlac->memoryStream;
7578  }
7579 
7580  return pFlac;
7581 }
7582 
7583 
7584 
7585 drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7586 {
7587  return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
7588 }
7589 drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7590 {
7591  return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
7592 }
7593 
7594 drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7595 {
7596  return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
7597 }
7598 drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
7599 {
7600  return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
7601 }
7602 
7603 void drflac_close(drflac* pFlac)
7604 {
7605  if (pFlac == NULL) {
7606  return;
7607  }
7608 
7609 #ifndef DR_FLAC_NO_STDIO
7610  /*
7611  If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file()
7612  was used by looking at the callbacks.
7613  */
7614  if (pFlac->bs.onRead == drflac__on_read_stdio) {
7615  fclose((FILE*)pFlac->bs.pUserData);
7616  }
7617 
7618 #ifndef DR_FLAC_NO_OGG
7619  /* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */
7620  if (pFlac->container == drflac_container_ogg) {
7621  drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
7623 
7624  if (oggbs->onRead == drflac__on_read_stdio) {
7625  fclose((FILE*)oggbs->pUserData);
7626  }
7627  }
7628 #endif
7629 #endif
7630 
7632 }
7633 
7634 
7635 #if 0
7636 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7637 {
7638  drflac_uint64 i;
7639  for (i = 0; i < frameCount; ++i) {
7640  drflac_int32 left = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7641  drflac_int32 side = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7642  drflac_int32 right = left - side;
7643 
7644  pOutputSamples[i*2+0] = left;
7645  pOutputSamples[i*2+1] = right;
7646  }
7647 }
7648 #endif
7649 
7650 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7651 {
7652  drflac_uint64 i;
7653  drflac_uint64 frameCount4 = frameCount >> 2;
7654 
7655  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7656  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7657  for (i = 0; i < frameCount4; ++i) {
7658  drflac_int32 left0 = pInputSamples0[i*4+0] << shift0;
7659  drflac_int32 left1 = pInputSamples0[i*4+1] << shift0;
7660  drflac_int32 left2 = pInputSamples0[i*4+2] << shift0;
7661  drflac_int32 left3 = pInputSamples0[i*4+3] << shift0;
7662 
7663  drflac_int32 side0 = pInputSamples1[i*4+0] << shift1;
7664  drflac_int32 side1 = pInputSamples1[i*4+1] << shift1;
7665  drflac_int32 side2 = pInputSamples1[i*4+2] << shift1;
7666  drflac_int32 side3 = pInputSamples1[i*4+3] << shift1;
7667 
7668  drflac_int32 right0 = left0 - side0;
7669  drflac_int32 right1 = left1 - side1;
7670  drflac_int32 right2 = left2 - side2;
7671  drflac_int32 right3 = left3 - side3;
7672 
7673  pOutputSamples[i*8+0] = left0;
7674  pOutputSamples[i*8+1] = right0;
7675  pOutputSamples[i*8+2] = left1;
7676  pOutputSamples[i*8+3] = right1;
7677  pOutputSamples[i*8+4] = left2;
7678  pOutputSamples[i*8+5] = right2;
7679  pOutputSamples[i*8+6] = left3;
7680  pOutputSamples[i*8+7] = right3;
7681  }
7682 
7683  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7684  int left = pInputSamples0[i] << shift0;
7685  int side = pInputSamples1[i] << shift1;
7686  int right = left - side;
7687 
7688  pOutputSamples[i*2+0] = left;
7689  pOutputSamples[i*2+1] = right;
7690  }
7691 }
7692 
7693 #if defined(DRFLAC_SUPPORT_SSE2)
7694 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7695 {
7696  drflac_uint64 frameCount4;
7697  drflac_int32 shift0;
7698  drflac_int32 shift1;
7699  drflac_uint64 i;
7700 
7701  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
7702 
7703  frameCount4 = frameCount >> 2;
7704 
7705  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7706  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7707 
7708  for (i = 0; i < frameCount4; ++i) {
7709  __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
7710  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
7711  __m128i right = _mm_sub_epi32(left, side);
7712 
7713  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
7714  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
7715  }
7716 
7717  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7718  drflac_int32 left = pInputSamples0[i] << shift0;
7719  drflac_int32 side = pInputSamples1[i] << shift1;
7720  drflac_int32 right = left - side;
7721 
7722  pOutputSamples[i*2+0] = left;
7723  pOutputSamples[i*2+1] = right;
7724  }
7725 }
7726 #endif
7727 
7728 #if defined(DRFLAC_SUPPORT_NEON)
7729 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7730 {
7731  drflac_uint64 frameCount4;
7732  drflac_int32 shift0;
7733  drflac_int32 shift1;
7734  drflac_uint64 i;
7735  int32x4_t shift0_4;
7736  int32x4_t shift1_4;
7737 
7738  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
7739 
7740  frameCount4 = frameCount >> 2;
7741 
7742  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7743  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7744 
7745  shift0_4 = vdupq_n_s32(shift0);
7746  shift1_4 = vdupq_n_s32(shift1);
7747 
7748  for (i = 0; i < frameCount4; ++i) {
7749  int32x4_t left;
7750  int32x4_t side;
7751  int32x4_t right;
7752 
7753  left = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
7754  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
7755  right = vsubq_s32(left, side);
7756 
7757  drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
7758  }
7759 
7760  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7761  drflac_int32 left = pInputSamples0[i] << shift0;
7762  drflac_int32 side = pInputSamples1[i] << shift1;
7763  drflac_int32 right = left - side;
7764 
7765  pOutputSamples[i*2+0] = left;
7766  pOutputSamples[i*2+1] = right;
7767  }
7768 }
7769 #endif
7770 
7771 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7772 {
7773 #if defined(DRFLAC_SUPPORT_SSE2)
7774  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
7775  drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7776  } else
7777 #elif defined(DRFLAC_SUPPORT_NEON)
7778  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
7779  drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7780  } else
7781 #endif
7782  {
7783  /* Scalar fallback. */
7784 #if 0
7785  drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7786 #else
7787  drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7788 #endif
7789  }
7790 }
7791 
7792 
7793 #if 0
7794 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7795 {
7796  drflac_uint64 i;
7797  for (i = 0; i < frameCount; ++i) {
7798  drflac_int32 side = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7799  drflac_int32 right = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7800  drflac_int32 left = right + side;
7801 
7802  pOutputSamples[i*2+0] = left;
7803  pOutputSamples[i*2+1] = right;
7804  }
7805 }
7806 #endif
7807 
7808 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7809 {
7810  drflac_uint64 i;
7811  drflac_uint64 frameCount4 = frameCount >> 2;
7812 
7813  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7814  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7815  for (i = 0; i < frameCount4; ++i) {
7816  drflac_int32 side0 = pInputSamples0[i*4+0] << shift0;
7817  drflac_int32 side1 = pInputSamples0[i*4+1] << shift0;
7818  drflac_int32 side2 = pInputSamples0[i*4+2] << shift0;
7819  drflac_int32 side3 = pInputSamples0[i*4+3] << shift0;
7820 
7821  drflac_int32 right0 = pInputSamples1[i*4+0] << shift1;
7822  drflac_int32 right1 = pInputSamples1[i*4+1] << shift1;
7823  drflac_int32 right2 = pInputSamples1[i*4+2] << shift1;
7824  drflac_int32 right3 = pInputSamples1[i*4+3] << shift1;
7825 
7826  drflac_int32 left0 = right0 + side0;
7827  drflac_int32 left1 = right1 + side1;
7828  drflac_int32 left2 = right2 + side2;
7829  drflac_int32 left3 = right3 + side3;
7830 
7831  pOutputSamples[i*8+0] = left0;
7832  pOutputSamples[i*8+1] = right0;
7833  pOutputSamples[i*8+2] = left1;
7834  pOutputSamples[i*8+3] = right1;
7835  pOutputSamples[i*8+4] = left2;
7836  pOutputSamples[i*8+5] = right2;
7837  pOutputSamples[i*8+6] = left3;
7838  pOutputSamples[i*8+7] = right3;
7839  }
7840 
7841  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7842  drflac_int32 side = pInputSamples0[i] << shift0;
7843  drflac_int32 right = pInputSamples1[i] << shift1;
7844  drflac_int32 left = right + side;
7845 
7846  pOutputSamples[i*2+0] = left;
7847  pOutputSamples[i*2+1] = right;
7848  }
7849 }
7850 
7851 #if defined(DRFLAC_SUPPORT_SSE2)
7852 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7853 {
7854  drflac_uint64 frameCount4;
7855  drflac_int32 shift0;
7856  drflac_int32 shift1;
7857  drflac_uint64 i;
7858 
7859  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
7860 
7861  frameCount4 = frameCount >> 2;
7862 
7863  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7864  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7865 
7866  for (i = 0; i < frameCount4; ++i) {
7867  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
7868  __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
7869  __m128i left = _mm_add_epi32(right, side);
7870 
7871  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
7872  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
7873  }
7874 
7875  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7876  drflac_int32 side = pInputSamples0[i] << shift0;
7877  drflac_int32 right = pInputSamples1[i] << shift1;
7878  drflac_int32 left = right + side;
7879 
7880  pOutputSamples[i*2+0] = left;
7881  pOutputSamples[i*2+1] = right;
7882  }
7883 }
7884 #endif
7885 
7886 #if defined(DRFLAC_SUPPORT_NEON)
7887 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7888 {
7889  drflac_uint64 frameCount4;
7890  drflac_int32 shift0;
7891  drflac_int32 shift1;
7892  drflac_uint64 i;
7893  int32x4_t shift0_4;
7894  int32x4_t shift1_4;
7895 
7896  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
7897 
7898  frameCount4 = frameCount >> 2;
7899 
7900  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
7901  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
7902 
7903  shift0_4 = vdupq_n_s32(shift0);
7904  shift1_4 = vdupq_n_s32(shift1);
7905 
7906  for (i = 0; i < frameCount4; ++i) {
7907  int32x4_t side;
7908  int32x4_t right;
7909  int32x4_t left;
7910 
7911  side = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
7912  right = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
7913  left = vaddq_s32(right, side);
7914 
7915  drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
7916  }
7917 
7918  for (i = (frameCount4 << 2); i < frameCount; ++i) {
7919  drflac_int32 side = pInputSamples0[i] << shift0;
7920  drflac_int32 right = pInputSamples1[i] << shift1;
7921  drflac_int32 left = right + side;
7922 
7923  pOutputSamples[i*2+0] = left;
7924  pOutputSamples[i*2+1] = right;
7925  }
7926 }
7927 #endif
7928 
7929 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7930 {
7931 #if defined(DRFLAC_SUPPORT_SSE2)
7932  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
7933  drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7934  } else
7935 #elif defined(DRFLAC_SUPPORT_NEON)
7936  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
7937  drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7938  } else
7939 #endif
7940  {
7941  /* Scalar fallback. */
7942 #if 0
7943  drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7944 #else
7945  drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
7946 #endif
7947  }
7948 }
7949 
7950 
7951 #if 0
7952 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7953 {
7954  for (drflac_uint64 i = 0; i < frameCount; ++i) {
7955  int mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7956  int side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7957 
7958  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
7959 
7960  pOutputSamples[i*2+0] = ((mid + side) >> 1) << unusedBitsPerSample;
7961  pOutputSamples[i*2+1] = ((mid - side) >> 1) << unusedBitsPerSample;
7962  }
7963 }
7964 #endif
7965 
7966 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
7967 {
7968  drflac_uint64 i;
7969  drflac_uint64 frameCount4 = frameCount >> 2;
7970 
7971  drflac_int32 shift = unusedBitsPerSample;
7972  if (shift > 0) {
7973  shift -= 1;
7974  for (i = 0; i < frameCount4; ++i) {
7975  drflac_int32 temp0L;
7976  drflac_int32 temp1L;
7977  drflac_int32 temp2L;
7978  drflac_int32 temp3L;
7979  drflac_int32 temp0R;
7980  drflac_int32 temp1R;
7981  drflac_int32 temp2R;
7982  drflac_int32 temp3R;
7983 
7984  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7985  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7986  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7987  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
7988 
7989  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7990  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7991  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7992  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
7993 
7994  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
7995  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
7996  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
7997  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
7998 
7999  temp0L = ((mid0 + side0) << shift);
8000  temp1L = ((mid1 + side1) << shift);
8001  temp2L = ((mid2 + side2) << shift);
8002  temp3L = ((mid3 + side3) << shift);
8003 
8004  temp0R = ((mid0 - side0) << shift);
8005  temp1R = ((mid1 - side1) << shift);
8006  temp2R = ((mid2 - side2) << shift);
8007  temp3R = ((mid3 - side3) << shift);
8008 
8009  pOutputSamples[i*8+0] = temp0L;
8010  pOutputSamples[i*8+1] = temp0R;
8011  pOutputSamples[i*8+2] = temp1L;
8012  pOutputSamples[i*8+3] = temp1R;
8013  pOutputSamples[i*8+4] = temp2L;
8014  pOutputSamples[i*8+5] = temp2R;
8015  pOutputSamples[i*8+6] = temp3L;
8016  pOutputSamples[i*8+7] = temp3R;
8017  }
8018  } else {
8019  for (i = 0; i < frameCount4; ++i) {
8020  drflac_int32 temp0L;
8021  drflac_int32 temp1L;
8022  drflac_int32 temp2L;
8023  drflac_int32 temp3L;
8024  drflac_int32 temp0R;
8025  drflac_int32 temp1R;
8026  drflac_int32 temp2R;
8027  drflac_int32 temp3R;
8028 
8029  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8030  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8031  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8032  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8033 
8034  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8035  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8036  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8037  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8038 
8039  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
8040  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
8041  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
8042  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
8043 
8044  temp0L = ((mid0 + side0) >> 1);
8045  temp1L = ((mid1 + side1) >> 1);
8046  temp2L = ((mid2 + side2) >> 1);
8047  temp3L = ((mid3 + side3) >> 1);
8048 
8049  temp0R = ((mid0 - side0) >> 1);
8050  temp1R = ((mid1 - side1) >> 1);
8051  temp2R = ((mid2 - side2) >> 1);
8052  temp3R = ((mid3 - side3) >> 1);
8053 
8054  pOutputSamples[i*8+0] = temp0L;
8055  pOutputSamples[i*8+1] = temp0R;
8056  pOutputSamples[i*8+2] = temp1L;
8057  pOutputSamples[i*8+3] = temp1R;
8058  pOutputSamples[i*8+4] = temp2L;
8059  pOutputSamples[i*8+5] = temp2R;
8060  pOutputSamples[i*8+6] = temp3L;
8061  pOutputSamples[i*8+7] = temp3R;
8062  }
8063  }
8064 
8065  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8066  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8067  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8068 
8069  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8070 
8071  pOutputSamples[i*2+0] = ((mid + side) >> 1) << unusedBitsPerSample;
8072  pOutputSamples[i*2+1] = ((mid - side) >> 1) << unusedBitsPerSample;
8073  }
8074 }
8075 
8076 #if defined(DRFLAC_SUPPORT_SSE2)
8077 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8078 {
8079  drflac_uint64 i;
8080  drflac_uint64 frameCount4;
8081  int shift;
8082 
8083  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8084 
8085  frameCount4 = frameCount >> 2;
8086 
8087  shift = unusedBitsPerSample;
8088  if (shift == 0) {
8089  for (i = 0; i < frameCount4; ++i) {
8090  __m128i mid;
8091  __m128i side;
8092  __m128i left;
8093  __m128i right;
8094 
8095  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8096  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8097 
8098  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
8099 
8100  left = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
8101  right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
8102 
8103  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
8104  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
8105  }
8106 
8107  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8108  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8109  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8110 
8111  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8112 
8113  pOutputSamples[i*2+0] = ((mid + side) >> 1);
8114  pOutputSamples[i*2+1] = ((mid - side) >> 1);
8115  }
8116  } else {
8117  shift -= 1;
8118  for (i = 0; i < frameCount4; ++i) {
8119  __m128i mid;
8120  __m128i side;
8121  __m128i left;
8122  __m128i right;
8123 
8124  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8125  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8126 
8127  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
8128 
8129  left = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
8130  right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
8131 
8132  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
8133  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
8134  }
8135 
8136  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8137  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8138  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8139 
8140  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8141 
8142  pOutputSamples[i*2+0] = ((mid + side) << shift);
8143  pOutputSamples[i*2+1] = ((mid - side) << shift);
8144  }
8145  }
8146 }
8147 #endif
8148 
8149 #if defined(DRFLAC_SUPPORT_NEON)
8150 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8151 {
8152  drflac_uint64 i;
8153  drflac_uint64 frameCount4;
8154  int shift;
8155  int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
8156  int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
8157  int32x4_t one4;
8158 
8159  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8160 
8161  frameCount4 = frameCount >> 2;
8162 
8163  wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8164  wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8165  one4 = vdupq_n_s32(1);
8166 
8167  shift = unusedBitsPerSample;
8168  if (shift == 0) {
8169  for (i = 0; i < frameCount4; ++i) {
8170  int32x4_t mid;
8171  int32x4_t side;
8172  int32x4_t left;
8173  int32x4_t right;
8174 
8175  mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbpsShift0_4);
8176  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbpsShift1_4);
8177 
8178  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, one4));
8179 
8180  left = vshrq_n_s32(vaddq_s32(mid, side), 1);
8181  right = vshrq_n_s32(vsubq_s32(mid, side), 1);
8182 
8183  drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
8184  }
8185 
8186  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8187  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8188  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8189 
8190  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8191 
8192  pOutputSamples[i*2+0] = ((mid + side) >> 1);
8193  pOutputSamples[i*2+1] = ((mid - side) >> 1);
8194  }
8195  } else {
8196  int32x4_t shift4;
8197 
8198  shift -= 1;
8199  shift4 = vdupq_n_s32(shift);
8200 
8201  for (i = 0; i < frameCount4; ++i) {
8202  int32x4_t mid;
8203  int32x4_t side;
8204  int32x4_t left;
8205  int32x4_t right;
8206 
8207  mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbpsShift0_4);
8208  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbpsShift1_4);
8209 
8210  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, one4));
8211 
8212  left = vshlq_s32(vaddq_s32(mid, side), shift4);
8213  right = vshlq_s32(vsubq_s32(mid, side), shift4);
8214 
8215  drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
8216  }
8217 
8218  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8219  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8220  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8221 
8222  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8223 
8224  pOutputSamples[i*2+0] = ((mid + side) << shift);
8225  pOutputSamples[i*2+1] = ((mid - side) << shift);
8226  }
8227  }
8228 }
8229 #endif
8230 
8231 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8232 {
8233 #if defined(DRFLAC_SUPPORT_SSE2)
8234  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
8235  drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8236  } else
8237 #elif defined(DRFLAC_SUPPORT_NEON)
8238  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
8239  drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8240  } else
8241 #endif
8242  {
8243  /* Scalar fallback. */
8244 #if 0
8245  drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8246 #else
8247  drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8248 #endif
8249  }
8250 }
8251 
8252 
8253 #if 0
8254 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8255 {
8256  for (drflac_uint64 i = 0; i < frameCount; ++i) {
8257  pOutputSamples[i*2+0] = (pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
8258  pOutputSamples[i*2+1] = (pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
8259  }
8260 }
8261 #endif
8262 
8263 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8264 {
8265  drflac_uint64 i;
8266  drflac_uint64 frameCount4 = frameCount >> 2;
8267 
8268  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8269  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8270 
8271  for (i = 0; i < frameCount4; ++i) {
8272  drflac_int32 tempL0 = pInputSamples0[i*4+0] << shift0;
8273  drflac_int32 tempL1 = pInputSamples0[i*4+1] << shift0;
8274  drflac_int32 tempL2 = pInputSamples0[i*4+2] << shift0;
8275  drflac_int32 tempL3 = pInputSamples0[i*4+3] << shift0;
8276 
8277  drflac_int32 tempR0 = pInputSamples1[i*4+0] << shift1;
8278  drflac_int32 tempR1 = pInputSamples1[i*4+1] << shift1;
8279  drflac_int32 tempR2 = pInputSamples1[i*4+2] << shift1;
8280  drflac_int32 tempR3 = pInputSamples1[i*4+3] << shift1;
8281 
8282  pOutputSamples[i*8+0] = tempL0;
8283  pOutputSamples[i*8+1] = tempR0;
8284  pOutputSamples[i*8+2] = tempL1;
8285  pOutputSamples[i*8+3] = tempR1;
8286  pOutputSamples[i*8+4] = tempL2;
8287  pOutputSamples[i*8+5] = tempR2;
8288  pOutputSamples[i*8+6] = tempL3;
8289  pOutputSamples[i*8+7] = tempR3;
8290  }
8291 
8292  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8293  pOutputSamples[i*2+0] = (pInputSamples0[i] << shift0);
8294  pOutputSamples[i*2+1] = (pInputSamples1[i] << shift1);
8295  }
8296 }
8297 
8298 #if defined(DRFLAC_SUPPORT_SSE2)
8299 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8300 {
8301  drflac_uint64 i;
8302  drflac_uint64 frameCount4 = frameCount >> 2;
8303 
8304  int shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8305  int shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8306 
8307  for (i = 0; i < frameCount4; ++i) {
8308  __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
8309  __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
8310 
8311  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
8312  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
8313  }
8314 
8315  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8316  pOutputSamples[i*2+0] = (pInputSamples0[i] << shift0);
8317  pOutputSamples[i*2+1] = (pInputSamples1[i] << shift1);
8318  }
8319 }
8320 #endif
8321 
8322 #if defined(DRFLAC_SUPPORT_NEON)
8323 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8324 {
8325  drflac_uint64 i;
8326  drflac_uint64 frameCount4 = frameCount >> 2;
8327 
8328  int shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8329  int shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8330 
8331  int32x4_t shift4_0 = vdupq_n_s32(shift0);
8332  int32x4_t shift4_1 = vdupq_n_s32(shift1);
8333 
8334  for (i = 0; i < frameCount4; ++i) {
8335  int32x4_t left;
8336  int32x4_t right;
8337 
8338  left = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift4_0);
8339  right = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift4_1);
8340 
8341  drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
8342  }
8343 
8344  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8345  pOutputSamples[i*2+0] = (pInputSamples0[i] << shift0);
8346  pOutputSamples[i*2+1] = (pInputSamples1[i] << shift1);
8347  }
8348 }
8349 #endif
8350 
8351 static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
8352 {
8353 #if defined(DRFLAC_SUPPORT_SSE2)
8354  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
8355  drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8356  } else
8357 #elif defined(DRFLAC_SUPPORT_NEON)
8358  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
8359  drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8360  } else
8361 #endif
8362  {
8363  /* Scalar fallback. */
8364 #if 0
8365  drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8366 #else
8367  drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8368 #endif
8369  }
8370 }
8371 
8372 
8374 {
8375  drflac_uint64 framesRead;
8376  drflac_int32 unusedBitsPerSample;
8377 
8378  if (pFlac == NULL || framesToRead == 0) {
8379  return 0;
8380  }
8381 
8382  if (pBufferOut == NULL) {
8383  return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
8384  }
8385 
8386  unusedBitsPerSample = 32 - pFlac->bitsPerSample;
8387 
8388  framesRead = 0;
8389  while (framesToRead > 0) {
8390  /* If we've run out of samples in this frame, go to the next. */
8391  if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
8393  break; /* Couldn't read the next frame, so just break from the loop and return. */
8394  }
8395  } else {
8398  drflac_uint64 frameCountThisIteration = framesToRead;
8399 
8400  if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
8401  frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
8402  }
8403 
8404  if (channelCount == 2) {
8405  const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
8406  const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
8407 
8408  switch (pFlac->currentFLACFrame.header.channelAssignment)
8409  {
8411  {
8412  drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
8413  } break;
8414 
8416  {
8417  drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
8418  } break;
8419 
8421  {
8422  drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
8423  } break;
8424 
8426  default:
8427  {
8428  drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
8429  } break;
8430  }
8431  } else {
8432  /* Generic interleaving. */
8433  drflac_uint64 i;
8434  for (i = 0; i < frameCountThisIteration; ++i) {
8435  unsigned int j;
8436  for (j = 0; j < channelCount; ++j) {
8437  pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
8438  }
8439  }
8440  }
8441 
8442  framesRead += frameCountThisIteration;
8443  pBufferOut += frameCountThisIteration * channelCount;
8444  framesToRead -= frameCountThisIteration;
8445  pFlac->currentPCMFrame += frameCountThisIteration;
8446  pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
8447  }
8448  }
8449 
8450  return framesRead;
8451 }
8452 
8453 
8454 #if 0
8455 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8456 {
8457  drflac_uint64 i;
8458  for (i = 0; i < frameCount; ++i) {
8459  drflac_int32 left = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8460  drflac_int32 side = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8461  drflac_int32 right = left - side;
8462 
8463  left >>= 16;
8464  right >>= 16;
8465 
8466  pOutputSamples[i*2+0] = (drflac_int16)left;
8467  pOutputSamples[i*2+1] = (drflac_int16)right;
8468  }
8469 }
8470 #endif
8471 
8472 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8473 {
8474  drflac_uint64 i;
8475  drflac_uint64 frameCount4 = frameCount >> 2;
8476 
8477  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8478  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8479  for (i = 0; i < frameCount4; ++i) {
8480  drflac_int32 left0 = pInputSamples0[i*4+0] << shift0;
8481  drflac_int32 left1 = pInputSamples0[i*4+1] << shift0;
8482  drflac_int32 left2 = pInputSamples0[i*4+2] << shift0;
8483  drflac_int32 left3 = pInputSamples0[i*4+3] << shift0;
8484 
8485  drflac_int32 side0 = pInputSamples1[i*4+0] << shift1;
8486  drflac_int32 side1 = pInputSamples1[i*4+1] << shift1;
8487  drflac_int32 side2 = pInputSamples1[i*4+2] << shift1;
8488  drflac_int32 side3 = pInputSamples1[i*4+3] << shift1;
8489 
8490  drflac_int32 right0 = left0 - side0;
8491  drflac_int32 right1 = left1 - side1;
8492  drflac_int32 right2 = left2 - side2;
8493  drflac_int32 right3 = left3 - side3;
8494 
8495  left0 >>= 16;
8496  left1 >>= 16;
8497  left2 >>= 16;
8498  left3 >>= 16;
8499 
8500  right0 >>= 16;
8501  right1 >>= 16;
8502  right2 >>= 16;
8503  right3 >>= 16;
8504 
8505  pOutputSamples[i*8+0] = (drflac_int16)left0;
8506  pOutputSamples[i*8+1] = (drflac_int16)right0;
8507  pOutputSamples[i*8+2] = (drflac_int16)left1;
8508  pOutputSamples[i*8+3] = (drflac_int16)right1;
8509  pOutputSamples[i*8+4] = (drflac_int16)left2;
8510  pOutputSamples[i*8+5] = (drflac_int16)right2;
8511  pOutputSamples[i*8+6] = (drflac_int16)left3;
8512  pOutputSamples[i*8+7] = (drflac_int16)right3;
8513  }
8514 
8515  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8516  drflac_int32 left = pInputSamples0[i] << shift0;
8517  drflac_int32 side = pInputSamples1[i] << shift1;
8518  drflac_int32 right = left - side;
8519 
8520  left >>= 16;
8521  right >>= 16;
8522 
8523  pOutputSamples[i*2+0] = (drflac_int16)left;
8524  pOutputSamples[i*2+1] = (drflac_int16)right;
8525  }
8526 }
8527 
8528 #if defined(DRFLAC_SUPPORT_SSE2)
8529 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8530 {
8531  drflac_uint64 frameCount4;
8532  drflac_int32 shift0;
8533  drflac_int32 shift1;
8534  drflac_uint64 i;
8535 
8536  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8537 
8538  frameCount4 = frameCount >> 2;
8539 
8540  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8541  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8542 
8543  for (i = 0; i < frameCount4; ++i) {
8544  __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
8545  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
8546  __m128i right = _mm_sub_epi32(left, side);
8547 
8548  left = _mm_srai_epi32(left, 16);
8549  right = _mm_srai_epi32(right, 16);
8550 
8551  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
8552  }
8553 
8554  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8555  drflac_int32 left = pInputSamples0[i] << shift0;
8556  drflac_int32 side = pInputSamples1[i] << shift1;
8557  drflac_int32 right = left - side;
8558 
8559  left >>= 16;
8560  right >>= 16;
8561 
8562  pOutputSamples[i*2+0] = (drflac_int16)left;
8563  pOutputSamples[i*2+1] = (drflac_int16)right;
8564  }
8565 }
8566 #endif
8567 
8568 #if defined(DRFLAC_SUPPORT_NEON)
8569 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8570 {
8571  drflac_uint64 frameCount4;
8572  drflac_int32 shift0;
8573  drflac_int32 shift1;
8574  drflac_uint64 i;
8575  int32x4_t shift0_4;
8576  int32x4_t shift1_4;
8577 
8578  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8579 
8580  frameCount4 = frameCount >> 2;
8581 
8582  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8583  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8584 
8585  shift0_4 = vdupq_n_s32(shift0);
8586  shift1_4 = vdupq_n_s32(shift1);
8587 
8588  for (i = 0; i < frameCount4; ++i) {
8589  int32x4_t left;
8590  int32x4_t side;
8591  int32x4_t right;
8592 
8593  left = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
8594  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
8595  right = vsubq_s32(left, side);
8596 
8597  left = vshrq_n_s32(left, 16);
8598  right = vshrq_n_s32(right, 16);
8599 
8600  drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
8601  }
8602 
8603  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8604  drflac_int32 left = pInputSamples0[i] << shift0;
8605  drflac_int32 side = pInputSamples1[i] << shift1;
8606  drflac_int32 right = left - side;
8607 
8608  left >>= 16;
8609  right >>= 16;
8610 
8611  pOutputSamples[i*2+0] = (drflac_int16)left;
8612  pOutputSamples[i*2+1] = (drflac_int16)right;
8613  }
8614 }
8615 #endif
8616 
8617 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8618 {
8619 #if defined(DRFLAC_SUPPORT_SSE2)
8620  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
8621  drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8622  } else
8623 #elif defined(DRFLAC_SUPPORT_NEON)
8624  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
8625  drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8626  } else
8627 #endif
8628  {
8629  /* Scalar fallback. */
8630 #if 0
8631  drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8632 #else
8633  drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8634 #endif
8635  }
8636 }
8637 
8638 
8639 #if 0
8640 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8641 {
8642  drflac_uint64 i;
8643  for (i = 0; i < frameCount; ++i) {
8644  drflac_int32 side = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8645  drflac_int32 right = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8646  drflac_int32 left = right + side;
8647 
8648  left >>= 16;
8649  right >>= 16;
8650 
8651  pOutputSamples[i*2+0] = (drflac_int16)left;
8652  pOutputSamples[i*2+1] = (drflac_int16)right;
8653  }
8654 }
8655 #endif
8656 
8657 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8658 {
8659  drflac_uint64 i;
8660  drflac_uint64 frameCount4 = frameCount >> 2;
8661 
8662  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8663  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8664  for (i = 0; i < frameCount4; ++i) {
8665  drflac_int32 side0 = pInputSamples0[i*4+0] << shift0;
8666  drflac_int32 side1 = pInputSamples0[i*4+1] << shift0;
8667  drflac_int32 side2 = pInputSamples0[i*4+2] << shift0;
8668  drflac_int32 side3 = pInputSamples0[i*4+3] << shift0;
8669 
8670  drflac_int32 right0 = pInputSamples1[i*4+0] << shift1;
8671  drflac_int32 right1 = pInputSamples1[i*4+1] << shift1;
8672  drflac_int32 right2 = pInputSamples1[i*4+2] << shift1;
8673  drflac_int32 right3 = pInputSamples1[i*4+3] << shift1;
8674 
8675  drflac_int32 left0 = right0 + side0;
8676  drflac_int32 left1 = right1 + side1;
8677  drflac_int32 left2 = right2 + side2;
8678  drflac_int32 left3 = right3 + side3;
8679 
8680  left0 >>= 16;
8681  left1 >>= 16;
8682  left2 >>= 16;
8683  left3 >>= 16;
8684 
8685  right0 >>= 16;
8686  right1 >>= 16;
8687  right2 >>= 16;
8688  right3 >>= 16;
8689 
8690  pOutputSamples[i*8+0] = (drflac_int16)left0;
8691  pOutputSamples[i*8+1] = (drflac_int16)right0;
8692  pOutputSamples[i*8+2] = (drflac_int16)left1;
8693  pOutputSamples[i*8+3] = (drflac_int16)right1;
8694  pOutputSamples[i*8+4] = (drflac_int16)left2;
8695  pOutputSamples[i*8+5] = (drflac_int16)right2;
8696  pOutputSamples[i*8+6] = (drflac_int16)left3;
8697  pOutputSamples[i*8+7] = (drflac_int16)right3;
8698  }
8699 
8700  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8701  drflac_int32 side = pInputSamples0[i] << shift0;
8702  drflac_int32 right = pInputSamples1[i] << shift1;
8703  drflac_int32 left = right + side;
8704 
8705  left >>= 16;
8706  right >>= 16;
8707 
8708  pOutputSamples[i*2+0] = (drflac_int16)left;
8709  pOutputSamples[i*2+1] = (drflac_int16)right;
8710  }
8711 }
8712 
8713 #if defined(DRFLAC_SUPPORT_SSE2)
8714 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8715 {
8716  drflac_uint64 frameCount4;
8717  drflac_int32 shift0;
8718  drflac_int32 shift1;
8719  drflac_uint64 i;
8720 
8721  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8722 
8723  frameCount4 = frameCount >> 2;
8724 
8725  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8726  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8727 
8728  for (i = 0; i < frameCount4; ++i) {
8729  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
8730  __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
8731  __m128i left = _mm_add_epi32(right, side);
8732 
8733  left = _mm_srai_epi32(left, 16);
8734  right = _mm_srai_epi32(right, 16);
8735 
8736  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
8737  }
8738 
8739  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8740  drflac_int32 side = pInputSamples0[i] << shift0;
8741  drflac_int32 right = pInputSamples1[i] << shift1;
8742  drflac_int32 left = right + side;
8743 
8744  left >>= 16;
8745  right >>= 16;
8746 
8747  pOutputSamples[i*2+0] = (drflac_int16)left;
8748  pOutputSamples[i*2+1] = (drflac_int16)right;
8749  }
8750 }
8751 #endif
8752 
8753 #if defined(DRFLAC_SUPPORT_NEON)
8754 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8755 {
8756  drflac_uint64 frameCount4;
8757  drflac_int32 shift0;
8758  drflac_int32 shift1;
8759  drflac_uint64 i;
8760  int32x4_t shift0_4;
8761  int32x4_t shift1_4;
8762 
8763  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8764 
8765  frameCount4 = frameCount >> 2;
8766 
8767  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8768  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8769 
8770  shift0_4 = vdupq_n_s32(shift0);
8771  shift1_4 = vdupq_n_s32(shift1);
8772 
8773  for (i = 0; i < frameCount4; ++i) {
8774  int32x4_t side;
8775  int32x4_t right;
8776  int32x4_t left;
8777 
8778  side = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
8779  right = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
8780  left = vaddq_s32(right, side);
8781 
8782  left = vshrq_n_s32(left, 16);
8783  right = vshrq_n_s32(right, 16);
8784 
8785  drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
8786  }
8787 
8788  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8789  drflac_int32 side = pInputSamples0[i] << shift0;
8790  drflac_int32 right = pInputSamples1[i] << shift1;
8791  drflac_int32 left = right + side;
8792 
8793  left >>= 16;
8794  right >>= 16;
8795 
8796  pOutputSamples[i*2+0] = (drflac_int16)left;
8797  pOutputSamples[i*2+1] = (drflac_int16)right;
8798  }
8799 }
8800 #endif
8801 
8802 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8803 {
8804 #if defined(DRFLAC_SUPPORT_SSE2)
8805  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
8806  drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8807  } else
8808 #elif defined(DRFLAC_SUPPORT_NEON)
8809  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
8810  drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8811  } else
8812 #endif
8813  {
8814  /* Scalar fallback. */
8815 #if 0
8816  drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8817 #else
8818  drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
8819 #endif
8820  }
8821 }
8822 
8823 
8824 #if 0
8825 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8826 {
8827  for (drflac_uint64 i = 0; i < frameCount; ++i) {
8828  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8829  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8830 
8831  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8832 
8833  pOutputSamples[i*2+0] = (drflac_int16)((((mid + side) >> 1) << unusedBitsPerSample) >> 16);
8834  pOutputSamples[i*2+1] = (drflac_int16)((((mid - side) >> 1) << unusedBitsPerSample) >> 16);
8835  }
8836 }
8837 #endif
8838 
8839 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8840 {
8841  drflac_uint64 i;
8842  drflac_uint64 frameCount4 = frameCount >> 2;
8843 
8844  int shift = unusedBitsPerSample;
8845  if (shift > 0) {
8846  shift -= 1;
8847  for (i = 0; i < frameCount4; ++i) {
8848  drflac_int32 temp0L;
8849  drflac_int32 temp1L;
8850  drflac_int32 temp2L;
8851  drflac_int32 temp3L;
8852  drflac_int32 temp0R;
8853  drflac_int32 temp1R;
8854  drflac_int32 temp2R;
8855  drflac_int32 temp3R;
8856 
8857  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8858  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8859  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8860  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8861 
8862  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8863  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8864  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8865  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8866 
8867  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
8868  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
8869  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
8870  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
8871 
8872  temp0L = ((mid0 + side0) << shift);
8873  temp1L = ((mid1 + side1) << shift);
8874  temp2L = ((mid2 + side2) << shift);
8875  temp3L = ((mid3 + side3) << shift);
8876 
8877  temp0R = ((mid0 - side0) << shift);
8878  temp1R = ((mid1 - side1) << shift);
8879  temp2R = ((mid2 - side2) << shift);
8880  temp3R = ((mid3 - side3) << shift);
8881 
8882  temp0L >>= 16;
8883  temp1L >>= 16;
8884  temp2L >>= 16;
8885  temp3L >>= 16;
8886 
8887  temp0R >>= 16;
8888  temp1R >>= 16;
8889  temp2R >>= 16;
8890  temp3R >>= 16;
8891 
8892  pOutputSamples[i*8+0] = (drflac_int16)temp0L;
8893  pOutputSamples[i*8+1] = (drflac_int16)temp0R;
8894  pOutputSamples[i*8+2] = (drflac_int16)temp1L;
8895  pOutputSamples[i*8+3] = (drflac_int16)temp1R;
8896  pOutputSamples[i*8+4] = (drflac_int16)temp2L;
8897  pOutputSamples[i*8+5] = (drflac_int16)temp2R;
8898  pOutputSamples[i*8+6] = (drflac_int16)temp3L;
8899  pOutputSamples[i*8+7] = (drflac_int16)temp3R;
8900  }
8901  } else {
8902  for (i = 0; i < frameCount4; ++i) {
8903  drflac_int32 temp0L;
8904  drflac_int32 temp1L;
8905  drflac_int32 temp2L;
8906  drflac_int32 temp3L;
8907  drflac_int32 temp0R;
8908  drflac_int32 temp1R;
8909  drflac_int32 temp2R;
8910  drflac_int32 temp3R;
8911 
8912  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8913  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8914  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8915  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8916 
8917  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8918  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8919  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8920  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8921 
8922  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
8923  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
8924  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
8925  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
8926 
8927  temp0L = ((mid0 + side0) >> 1);
8928  temp1L = ((mid1 + side1) >> 1);
8929  temp2L = ((mid2 + side2) >> 1);
8930  temp3L = ((mid3 + side3) >> 1);
8931 
8932  temp0R = ((mid0 - side0) >> 1);
8933  temp1R = ((mid1 - side1) >> 1);
8934  temp2R = ((mid2 - side2) >> 1);
8935  temp3R = ((mid3 - side3) >> 1);
8936 
8937  temp0L >>= 16;
8938  temp1L >>= 16;
8939  temp2L >>= 16;
8940  temp3L >>= 16;
8941 
8942  temp0R >>= 16;
8943  temp1R >>= 16;
8944  temp2R >>= 16;
8945  temp3R >>= 16;
8946 
8947  pOutputSamples[i*8+0] = (drflac_int16)temp0L;
8948  pOutputSamples[i*8+1] = (drflac_int16)temp0R;
8949  pOutputSamples[i*8+2] = (drflac_int16)temp1L;
8950  pOutputSamples[i*8+3] = (drflac_int16)temp1R;
8951  pOutputSamples[i*8+4] = (drflac_int16)temp2L;
8952  pOutputSamples[i*8+5] = (drflac_int16)temp2R;
8953  pOutputSamples[i*8+6] = (drflac_int16)temp3L;
8954  pOutputSamples[i*8+7] = (drflac_int16)temp3R;
8955  }
8956  }
8957 
8958  for (i = (frameCount4 << 2); i < frameCount; ++i) {
8959  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
8960  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
8961 
8962  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
8963 
8964  pOutputSamples[i*2+0] = (drflac_int16)((((mid + side) >> 1) << unusedBitsPerSample) >> 16);
8965  pOutputSamples[i*2+1] = (drflac_int16)((((mid - side) >> 1) << unusedBitsPerSample) >> 16);
8966  }
8967 }
8968 
8969 #if defined(DRFLAC_SUPPORT_SSE2)
8970 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
8971 {
8972  drflac_uint64 i;
8973  drflac_uint64 frameCount4;
8974  drflac_int32 shift;
8975 
8976  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
8977 
8978  frameCount4 = frameCount >> 2;
8979 
8980  shift = unusedBitsPerSample;
8981  if (shift == 0) {
8982  for (i = 0; i < frameCount4; ++i) {
8983  __m128i mid;
8984  __m128i side;
8985  __m128i left;
8986  __m128i right;
8987 
8988  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
8989  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
8990 
8991  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
8992 
8993  left = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
8994  right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
8995 
8996  left = _mm_srai_epi32(left, 16);
8997  right = _mm_srai_epi32(right, 16);
8998 
8999  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
9000  }
9001 
9002  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9003  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9004  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9005 
9006  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9007 
9008  pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) >> 1) >> 16);
9009  pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) >> 1) >> 16);
9010  }
9011  } else {
9012  shift -= 1;
9013  for (i = 0; i < frameCount4; ++i) {
9014  __m128i mid;
9015  __m128i side;
9016  __m128i left;
9017  __m128i right;
9018 
9019  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9020  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9021 
9022  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9023 
9024  left = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
9025  right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
9026 
9027  left = _mm_srai_epi32(left, 16);
9028  right = _mm_srai_epi32(right, 16);
9029 
9030  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
9031  }
9032 
9033  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9034  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9035  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9036 
9037  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9038 
9039  pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
9040  pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
9041  }
9042  }
9043 }
9044 #endif
9045 
9046 #if defined(DRFLAC_SUPPORT_NEON)
9047 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9048 {
9049  drflac_uint64 i;
9050  drflac_uint64 frameCount4;
9051  int shift;
9052  int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
9053  int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
9054 
9055  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9056 
9057  frameCount4 = frameCount >> 2;
9058 
9059  wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9060  wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9061 
9062  shift = unusedBitsPerSample;
9063  if (shift == 0) {
9064  for (i = 0; i < frameCount4; ++i) {
9065  int32x4_t mid;
9066  int32x4_t side;
9067  int32x4_t left;
9068  int32x4_t right;
9069 
9070  mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbpsShift0_4);
9071  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbpsShift1_4);
9072 
9073  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, vdupq_n_s32(1)));
9074 
9075  left = vshrq_n_s32(vaddq_s32(mid, side), 1);
9076  right = vshrq_n_s32(vsubq_s32(mid, side), 1);
9077 
9078  left = vshrq_n_s32(left, 16);
9079  right = vshrq_n_s32(right, 16);
9080 
9081  drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
9082  }
9083 
9084  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9085  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9086  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9087 
9088  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9089 
9090  pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) >> 1) >> 16);
9091  pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) >> 1) >> 16);
9092  }
9093  } else {
9094  int32x4_t shift4;
9095 
9096  shift -= 1;
9097  shift4 = vdupq_n_s32(shift);
9098 
9099  for (i = 0; i < frameCount4; ++i) {
9100  int32x4_t mid;
9101  int32x4_t side;
9102  int32x4_t left;
9103  int32x4_t right;
9104 
9105  mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbpsShift0_4);
9106  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbpsShift1_4);
9107 
9108  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, vdupq_n_s32(1)));
9109 
9110  left = vshlq_s32(vaddq_s32(mid, side), shift4);
9111  right = vshlq_s32(vsubq_s32(mid, side), shift4);
9112 
9113  left = vshrq_n_s32(left, 16);
9114  right = vshrq_n_s32(right, 16);
9115 
9116  drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
9117  }
9118 
9119  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9120  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9121  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9122 
9123  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9124 
9125  pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
9126  pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
9127  }
9128  }
9129 }
9130 #endif
9131 
9132 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9133 {
9134 #if defined(DRFLAC_SUPPORT_SSE2)
9135  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9136  drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9137  } else
9138 #elif defined(DRFLAC_SUPPORT_NEON)
9139  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9140  drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9141  } else
9142 #endif
9143  {
9144  /* Scalar fallback. */
9145 #if 0
9146  drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9147 #else
9148  drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9149 #endif
9150  }
9151 }
9152 
9153 
9154 #if 0
9155 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9156 {
9157  for (drflac_uint64 i = 0; i < frameCount; ++i) {
9158  pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
9159  pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
9160  }
9161 }
9162 #endif
9163 
9164 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9165 {
9166  drflac_uint64 i;
9167  drflac_uint64 frameCount4 = frameCount >> 2;
9168 
9169  int shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9170  int shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9171 
9172  for (i = 0; i < frameCount4; ++i) {
9173  drflac_int32 tempL0 = pInputSamples0[i*4+0] << shift0;
9174  drflac_int32 tempL1 = pInputSamples0[i*4+1] << shift0;
9175  drflac_int32 tempL2 = pInputSamples0[i*4+2] << shift0;
9176  drflac_int32 tempL3 = pInputSamples0[i*4+3] << shift0;
9177 
9178  drflac_int32 tempR0 = pInputSamples1[i*4+0] << shift1;
9179  drflac_int32 tempR1 = pInputSamples1[i*4+1] << shift1;
9180  drflac_int32 tempR2 = pInputSamples1[i*4+2] << shift1;
9181  drflac_int32 tempR3 = pInputSamples1[i*4+3] << shift1;
9182 
9183  tempL0 >>= 16;
9184  tempL1 >>= 16;
9185  tempL2 >>= 16;
9186  tempL3 >>= 16;
9187 
9188  tempR0 >>= 16;
9189  tempR1 >>= 16;
9190  tempR2 >>= 16;
9191  tempR3 >>= 16;
9192 
9193  pOutputSamples[i*8+0] = (drflac_int16)tempL0;
9194  pOutputSamples[i*8+1] = (drflac_int16)tempR0;
9195  pOutputSamples[i*8+2] = (drflac_int16)tempL1;
9196  pOutputSamples[i*8+3] = (drflac_int16)tempR1;
9197  pOutputSamples[i*8+4] = (drflac_int16)tempL2;
9198  pOutputSamples[i*8+5] = (drflac_int16)tempR2;
9199  pOutputSamples[i*8+6] = (drflac_int16)tempL3;
9200  pOutputSamples[i*8+7] = (drflac_int16)tempR3;
9201  }
9202 
9203  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9204  pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0[i] << shift0) >> 16);
9205  pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1[i] << shift1) >> 16);
9206  }
9207 }
9208 
9209 #if defined(DRFLAC_SUPPORT_SSE2)
9210 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9211 {
9212  drflac_uint64 i;
9213  drflac_uint64 frameCount4 = frameCount >> 2;
9214 
9215  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9216  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9217 
9218  for (i = 0; i < frameCount4; ++i) {
9219  __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9220  __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9221 
9222  left = _mm_srai_epi32(left, 16);
9223  right = _mm_srai_epi32(right, 16);
9224 
9225  /* At this point we have results. We can now pack and interleave these into a single __m128i object and then store the in the output buffer. */
9226  _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
9227  }
9228 
9229  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9230  pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0[i] << shift0) >> 16);
9231  pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1[i] << shift1) >> 16);
9232  }
9233 }
9234 #endif
9235 
9236 #if defined(DRFLAC_SUPPORT_NEON)
9237 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9238 {
9239  drflac_uint64 i;
9240  drflac_uint64 frameCount4 = frameCount >> 2;
9241 
9242  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9243  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9244 
9245  int32x4_t shift0_4 = vdupq_n_s32(shift0);
9246  int32x4_t shift1_4 = vdupq_n_s32(shift1);
9247 
9248  for (i = 0; i < frameCount4; ++i) {
9249  int32x4_t left;
9250  int32x4_t right;
9251 
9252  left = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
9253  right = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
9254 
9255  left = vshrq_n_s32(left, 16);
9256  right = vshrq_n_s32(right, 16);
9257 
9258  drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
9259  }
9260 
9261  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9262  pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0[i] << shift0) >> 16);
9263  pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1[i] << shift1) >> 16);
9264  }
9265 }
9266 #endif
9267 
9268 static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9269 {
9270 #if defined(DRFLAC_SUPPORT_SSE2)
9271  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9272  drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9273  } else
9274 #elif defined(DRFLAC_SUPPORT_NEON)
9275  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9276  drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9277  } else
9278 #endif
9279  {
9280  /* Scalar fallback. */
9281 #if 0
9282  drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9283 #else
9284  drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9285 #endif
9286  }
9287 }
9288 
9290 {
9291  drflac_uint64 framesRead;
9292  drflac_int32 unusedBitsPerSample;
9293 
9294  if (pFlac == NULL || framesToRead == 0) {
9295  return 0;
9296  }
9297 
9298  if (pBufferOut == NULL) {
9299  return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
9300  }
9301 
9302  unusedBitsPerSample = 32 - pFlac->bitsPerSample;
9303 
9304  framesRead = 0;
9305  while (framesToRead > 0) {
9306  /* If we've run out of samples in this frame, go to the next. */
9307  if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
9309  break; /* Couldn't read the next frame, so just break from the loop and return. */
9310  }
9311  } else {
9314  drflac_uint64 frameCountThisIteration = framesToRead;
9315 
9316  if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
9317  frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
9318  }
9319 
9320  if (channelCount == 2) {
9321  const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
9322  const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
9323 
9324  switch (pFlac->currentFLACFrame.header.channelAssignment)
9325  {
9327  {
9328  drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9329  } break;
9330 
9332  {
9333  drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9334  } break;
9335 
9337  {
9338  drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9339  } break;
9340 
9342  default:
9343  {
9344  drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9345  } break;
9346  }
9347  } else {
9348  /* Generic interleaving. */
9349  drflac_uint64 i;
9350  for (i = 0; i < frameCountThisIteration; ++i) {
9351  unsigned int j;
9352  for (j = 0; j < channelCount; ++j) {
9353  drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
9354  pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
9355  }
9356  }
9357  }
9358 
9359  framesRead += frameCountThisIteration;
9360  pBufferOut += frameCountThisIteration * channelCount;
9361  framesToRead -= frameCountThisIteration;
9362  pFlac->currentPCMFrame += frameCountThisIteration;
9363  pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
9364  }
9365  }
9366 
9367  return framesRead;
9368 }
9369 
9370 
9371 #if 0
9372 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9373 {
9374  drflac_uint64 i;
9375  for (i = 0; i < frameCount; ++i) {
9376  drflac_int32 left = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9377  drflac_int32 side = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9378  drflac_int32 right = left - side;
9379 
9380  pOutputSamples[i*2+0] = (float)(left / 2147483648.0);
9381  pOutputSamples[i*2+1] = (float)(right / 2147483648.0);
9382  }
9383 }
9384 #endif
9385 
9386 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9387 {
9388  drflac_uint64 i;
9389  drflac_uint64 frameCount4 = frameCount >> 2;
9390 
9391  float factor = 1 / 2147483648.0;
9392 
9393  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9394  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9395  for (i = 0; i < frameCount4; ++i) {
9396  drflac_int32 left0 = pInputSamples0[i*4+0] << shift0;
9397  drflac_int32 left1 = pInputSamples0[i*4+1] << shift0;
9398  drflac_int32 left2 = pInputSamples0[i*4+2] << shift0;
9399  drflac_int32 left3 = pInputSamples0[i*4+3] << shift0;
9400 
9401  drflac_int32 side0 = pInputSamples1[i*4+0] << shift1;
9402  drflac_int32 side1 = pInputSamples1[i*4+1] << shift1;
9403  drflac_int32 side2 = pInputSamples1[i*4+2] << shift1;
9404  drflac_int32 side3 = pInputSamples1[i*4+3] << shift1;
9405 
9406  drflac_int32 right0 = left0 - side0;
9407  drflac_int32 right1 = left1 - side1;
9408  drflac_int32 right2 = left2 - side2;
9409  drflac_int32 right3 = left3 - side3;
9410 
9411  pOutputSamples[i*8+0] = left0 * factor;
9412  pOutputSamples[i*8+1] = right0 * factor;
9413  pOutputSamples[i*8+2] = left1 * factor;
9414  pOutputSamples[i*8+3] = right1 * factor;
9415  pOutputSamples[i*8+4] = left2 * factor;
9416  pOutputSamples[i*8+5] = right2 * factor;
9417  pOutputSamples[i*8+6] = left3 * factor;
9418  pOutputSamples[i*8+7] = right3 * factor;
9419  }
9420 
9421  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9422  drflac_int32 left = pInputSamples0[i] << shift0;
9423  drflac_int32 side = pInputSamples1[i] << shift1;
9424  drflac_int32 right = left - side;
9425 
9426  pOutputSamples[i*2+0] = (float)(left * factor);
9427  pOutputSamples[i*2+1] = (float)(right * factor);
9428  }
9429 }
9430 
9431 #if defined(DRFLAC_SUPPORT_SSE2)
9432 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9433 {
9434  drflac_uint64 frameCount4;
9435  drflac_int32 shift0;
9436  drflac_int32 shift1;
9437  drflac_uint64 i;
9438  __m128 factor;
9439 
9440  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9441 
9442  frameCount4 = frameCount >> 2;
9443 
9444  factor = _mm_set1_ps(1.0f / 8388608.0f);
9445  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
9446  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
9447 
9448  for (i = 0; i < frameCount4; ++i) {
9449  __m128i left = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9450  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9451  __m128i right = _mm_sub_epi32(left, side);
9452  __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor);
9453  __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
9454 
9455  _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
9456  _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
9457  }
9458 
9459  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9460  drflac_int32 left = pInputSamples0[i] << shift0;
9461  drflac_int32 side = pInputSamples1[i] << shift1;
9462  drflac_int32 right = left - side;
9463 
9464  pOutputSamples[i*2+0] = (float)(left / 8388608.0f);
9465  pOutputSamples[i*2+1] = (float)(right / 8388608.0f);
9466  }
9467 }
9468 #endif
9469 
9470 #if defined(DRFLAC_SUPPORT_NEON)
9471 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9472 {
9473  drflac_uint64 frameCount4;
9474  drflac_int32 shift0;
9475  drflac_int32 shift1;
9476  drflac_uint64 i;
9477  float32x4_t factor4;
9478  int32x4_t shift0_4;
9479  int32x4_t shift1_4;
9480 
9481  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9482 
9483  frameCount4 = frameCount >> 2;
9484 
9485  factor4 = vdupq_n_f32(1.0f / 8388608.0f);
9486 
9487  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
9488  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
9489 
9490  shift0_4 = vdupq_n_s32(shift0);
9491  shift1_4 = vdupq_n_s32(shift1);
9492 
9493  for (i = 0; i < frameCount4; ++i) {
9494  int32x4_t left;
9495  int32x4_t side;
9496  int32x4_t right;
9497  float32x4_t leftf;
9498  float32x4_t rightf;
9499 
9500  left = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
9501  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
9502  right = vsubq_s32(left, side);
9503  leftf = vmulq_f32(vcvtq_f32_s32(left), factor4);
9504  rightf = vmulq_f32(vcvtq_f32_s32(right), factor4);
9505 
9506  drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
9507  }
9508 
9509  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9510  drflac_int32 left = pInputSamples0[i] << shift0;
9511  drflac_int32 side = pInputSamples1[i] << shift1;
9512  drflac_int32 right = left - side;
9513 
9514  pOutputSamples[i*2+0] = (float)(left / 8388608.0f);
9515  pOutputSamples[i*2+1] = (float)(right / 8388608.0f);
9516  }
9517 }
9518 #endif
9519 
9520 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9521 {
9522 #if defined(DRFLAC_SUPPORT_SSE2)
9523  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9524  drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9525  } else
9526 #elif defined(DRFLAC_SUPPORT_NEON)
9527  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9528  drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9529  } else
9530 #endif
9531  {
9532  /* Scalar fallback. */
9533 #if 0
9534  drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9535 #else
9536  drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9537 #endif
9538  }
9539 }
9540 
9541 
9542 #if 0
9543 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9544 {
9545  drflac_uint64 i;
9546  for (i = 0; i < frameCount; ++i) {
9547  drflac_int32 side = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9548  drflac_int32 right = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9549  drflac_int32 left = right + side;
9550 
9551  pOutputSamples[i*2+0] = (float)(left / 2147483648.0);
9552  pOutputSamples[i*2+1] = (float)(right / 2147483648.0);
9553  }
9554 }
9555 #endif
9556 
9557 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9558 {
9559  drflac_uint64 i;
9560  drflac_uint64 frameCount4 = frameCount >> 2;
9561 
9562  float factor = 1 / 2147483648.0;
9563 
9564  drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9565  drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9566  for (i = 0; i < frameCount4; ++i) {
9567  drflac_int32 side0 = pInputSamples0[i*4+0] << shift0;
9568  drflac_int32 side1 = pInputSamples0[i*4+1] << shift0;
9569  drflac_int32 side2 = pInputSamples0[i*4+2] << shift0;
9570  drflac_int32 side3 = pInputSamples0[i*4+3] << shift0;
9571 
9572  drflac_int32 right0 = pInputSamples1[i*4+0] << shift1;
9573  drflac_int32 right1 = pInputSamples1[i*4+1] << shift1;
9574  drflac_int32 right2 = pInputSamples1[i*4+2] << shift1;
9575  drflac_int32 right3 = pInputSamples1[i*4+3] << shift1;
9576 
9577  drflac_int32 left0 = right0 + side0;
9578  drflac_int32 left1 = right1 + side1;
9579  drflac_int32 left2 = right2 + side2;
9580  drflac_int32 left3 = right3 + side3;
9581 
9582  pOutputSamples[i*8+0] = left0 * factor;
9583  pOutputSamples[i*8+1] = right0 * factor;
9584  pOutputSamples[i*8+2] = left1 * factor;
9585  pOutputSamples[i*8+3] = right1 * factor;
9586  pOutputSamples[i*8+4] = left2 * factor;
9587  pOutputSamples[i*8+5] = right2 * factor;
9588  pOutputSamples[i*8+6] = left3 * factor;
9589  pOutputSamples[i*8+7] = right3 * factor;
9590  }
9591 
9592  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9593  drflac_int32 side = pInputSamples0[i] << shift0;
9594  drflac_int32 right = pInputSamples1[i] << shift1;
9595  drflac_int32 left = right + side;
9596 
9597  pOutputSamples[i*2+0] = (float)(left * factor);
9598  pOutputSamples[i*2+1] = (float)(right * factor);
9599  }
9600 }
9601 
9602 #if defined(DRFLAC_SUPPORT_SSE2)
9603 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9604 {
9605  drflac_uint64 frameCount4;
9606  drflac_int32 shift0;
9607  drflac_int32 shift1;
9608  drflac_uint64 i;
9609  __m128 factor;
9610 
9611  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9612 
9613  frameCount4 = frameCount >> 2;
9614 
9615  factor = _mm_set1_ps(1.0f / 8388608.0f);
9616  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
9617  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
9618 
9619  for (i = 0; i < frameCount4; ++i) {
9620  __m128i side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9621  __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9622  __m128i left = _mm_add_epi32(right, side);
9623  __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor);
9624  __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
9625 
9626  _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
9627  _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
9628  }
9629 
9630  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9631  drflac_int32 side = pInputSamples0[i] << shift0;
9632  drflac_int32 right = pInputSamples1[i] << shift1;
9633  drflac_int32 left = right + side;
9634 
9635  pOutputSamples[i*2+0] = (float)(left / 8388608.0f);
9636  pOutputSamples[i*2+1] = (float)(right / 8388608.0f);
9637  }
9638 }
9639 #endif
9640 
9641 #if defined(DRFLAC_SUPPORT_NEON)
9642 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9643 {
9644  drflac_uint64 frameCount4;
9645  drflac_int32 shift0;
9646  drflac_int32 shift1;
9647  drflac_uint64 i;
9648  float32x4_t factor4;
9649  int32x4_t shift0_4;
9650  int32x4_t shift1_4;
9651 
9652  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9653 
9654  frameCount4 = frameCount >> 2;
9655 
9656  factor4 = vdupq_n_f32(1.0f / 8388608.0f);
9657 
9658  shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
9659  shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
9660 
9661  shift0_4 = vdupq_n_s32(shift0);
9662  shift1_4 = vdupq_n_s32(shift1);
9663 
9664  for (i = 0; i < frameCount4; ++i) {
9665  int32x4_t side;
9666  int32x4_t right;
9667  int32x4_t left;
9668  float32x4_t leftf;
9669  float32x4_t rightf;
9670 
9671  side = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
9672  right = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
9673  left = vaddq_s32(right, side);
9674  leftf = vmulq_f32(vcvtq_f32_s32(left), factor4);
9675  rightf = vmulq_f32(vcvtq_f32_s32(right), factor4);
9676 
9677  drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
9678  }
9679 
9680  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9681  drflac_int32 side = pInputSamples0[i] << shift0;
9682  drflac_int32 right = pInputSamples1[i] << shift1;
9683  drflac_int32 left = right + side;
9684 
9685  pOutputSamples[i*2+0] = (float)(left / 8388608.0f);
9686  pOutputSamples[i*2+1] = (float)(right / 8388608.0f);
9687  }
9688 }
9689 #endif
9690 
9691 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9692 {
9693 #if defined(DRFLAC_SUPPORT_SSE2)
9694  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9695  drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9696  } else
9697 #elif defined(DRFLAC_SUPPORT_NEON)
9698  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9699  drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9700  } else
9701 #endif
9702  {
9703  /* Scalar fallback. */
9704 #if 0
9705  drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9706 #else
9707  drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9708 #endif
9709  }
9710 }
9711 
9712 
9713 #if 0
9714 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9715 {
9716  for (drflac_uint64 i = 0; i < frameCount; ++i) {
9717  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9718  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9719 
9720  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9721 
9722  pOutputSamples[i*2+0] = (float)((((mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
9723  pOutputSamples[i*2+1] = (float)((((mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
9724  }
9725 }
9726 #endif
9727 
9728 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9729 {
9730  drflac_uint64 i;
9731  drflac_uint64 frameCount4 = frameCount >> 2;
9732 
9733  float factor = 1 / 2147483648.0;
9734 
9735  int shift = unusedBitsPerSample;
9736  if (shift > 0) {
9737  shift -= 1;
9738  for (i = 0; i < frameCount4; ++i) {
9739  drflac_int32 temp0L;
9740  drflac_int32 temp1L;
9741  drflac_int32 temp2L;
9742  drflac_int32 temp3L;
9743  drflac_int32 temp0R;
9744  drflac_int32 temp1R;
9745  drflac_int32 temp2R;
9746  drflac_int32 temp3R;
9747 
9748  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9749  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9750  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9751  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9752 
9753  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9754  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9755  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9756  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9757 
9758  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
9759  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
9760  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
9761  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
9762 
9763  temp0L = ((mid0 + side0) << shift);
9764  temp1L = ((mid1 + side1) << shift);
9765  temp2L = ((mid2 + side2) << shift);
9766  temp3L = ((mid3 + side3) << shift);
9767 
9768  temp0R = ((mid0 - side0) << shift);
9769  temp1R = ((mid1 - side1) << shift);
9770  temp2R = ((mid2 - side2) << shift);
9771  temp3R = ((mid3 - side3) << shift);
9772 
9773  pOutputSamples[i*8+0] = (float)(temp0L * factor);
9774  pOutputSamples[i*8+1] = (float)(temp0R * factor);
9775  pOutputSamples[i*8+2] = (float)(temp1L * factor);
9776  pOutputSamples[i*8+3] = (float)(temp1R * factor);
9777  pOutputSamples[i*8+4] = (float)(temp2L * factor);
9778  pOutputSamples[i*8+5] = (float)(temp2R * factor);
9779  pOutputSamples[i*8+6] = (float)(temp3L * factor);
9780  pOutputSamples[i*8+7] = (float)(temp3R * factor);
9781  }
9782  } else {
9783  for (i = 0; i < frameCount4; ++i) {
9784  drflac_int32 temp0L;
9785  drflac_int32 temp1L;
9786  drflac_int32 temp2L;
9787  drflac_int32 temp3L;
9788  drflac_int32 temp0R;
9789  drflac_int32 temp1R;
9790  drflac_int32 temp2R;
9791  drflac_int32 temp3R;
9792 
9793  drflac_int32 mid0 = pInputSamples0[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9794  drflac_int32 mid1 = pInputSamples0[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9795  drflac_int32 mid2 = pInputSamples0[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9796  drflac_int32 mid3 = pInputSamples0[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9797 
9798  drflac_int32 side0 = pInputSamples1[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9799  drflac_int32 side1 = pInputSamples1[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9800  drflac_int32 side2 = pInputSamples1[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9801  drflac_int32 side3 = pInputSamples1[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9802 
9803  mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01);
9804  mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01);
9805  mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01);
9806  mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01);
9807 
9808  temp0L = ((mid0 + side0) >> 1);
9809  temp1L = ((mid1 + side1) >> 1);
9810  temp2L = ((mid2 + side2) >> 1);
9811  temp3L = ((mid3 + side3) >> 1);
9812 
9813  temp0R = ((mid0 - side0) >> 1);
9814  temp1R = ((mid1 - side1) >> 1);
9815  temp2R = ((mid2 - side2) >> 1);
9816  temp3R = ((mid3 - side3) >> 1);
9817 
9818  pOutputSamples[i*8+0] = (float)(temp0L * factor);
9819  pOutputSamples[i*8+1] = (float)(temp0R * factor);
9820  pOutputSamples[i*8+2] = (float)(temp1L * factor);
9821  pOutputSamples[i*8+3] = (float)(temp1R * factor);
9822  pOutputSamples[i*8+4] = (float)(temp2L * factor);
9823  pOutputSamples[i*8+5] = (float)(temp2R * factor);
9824  pOutputSamples[i*8+6] = (float)(temp3L * factor);
9825  pOutputSamples[i*8+7] = (float)(temp3R * factor);
9826  }
9827  }
9828 
9829  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9830  int mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9831  int side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9832 
9833  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9834 
9835  pOutputSamples[i*2+0] = (float)((((mid + side) >> 1) << unusedBitsPerSample) * factor);
9836  pOutputSamples[i*2+1] = (float)((((mid - side) >> 1) << unusedBitsPerSample) * factor);
9837  }
9838 }
9839 
9840 #if defined(DRFLAC_SUPPORT_SSE2)
9841 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9842 {
9843  drflac_uint64 i;
9844  drflac_uint64 frameCount4;
9845  float factor;
9846  drflac_int32 shift;
9847  __m128 factor128;
9848 
9849  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9850 
9851  frameCount4 = frameCount >> 2;
9852 
9853  factor = 1.0f / 8388608.0f;
9854  factor128 = _mm_set1_ps(1.0f / 8388608.0f);
9855 
9856  shift = unusedBitsPerSample - 8;
9857  if (shift == 0) {
9858  for (i = 0; i < frameCount4; ++i) {
9859  __m128i mid;
9860  __m128i side;
9861  __m128i tempL;
9862  __m128i tempR;
9863  __m128 leftf;
9864  __m128 rightf;
9865 
9866  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9867  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9868 
9869  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9870 
9871  tempL = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
9872  tempR = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
9873 
9874  leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
9875  rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
9876 
9877  _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
9878  _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
9879  }
9880 
9881  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9882  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9883  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9884 
9885  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9886 
9887  pOutputSamples[i*2+0] = (float)(((mid + side) >> 1) * factor);
9888  pOutputSamples[i*2+1] = (float)(((mid - side) >> 1) * factor);
9889  }
9890  } else {
9891  shift -= 1;
9892  for (i = 0; i < frameCount4; ++i) {
9893  __m128i mid;
9894  __m128i side;
9895  __m128i tempL;
9896  __m128i tempR;
9897  __m128 leftf;
9898  __m128 rightf;
9899 
9900  mid = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9901  side = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9902 
9903  mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9904 
9905  tempL = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
9906  tempR = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
9907 
9908  leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
9909  rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
9910 
9911  _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
9912  _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
9913  }
9914 
9915  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9916  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9917  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9918 
9919  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9920 
9921  pOutputSamples[i*2+0] = (float)(((mid + side) << shift) * factor);
9922  pOutputSamples[i*2+1] = (float)(((mid - side) << shift) * factor);
9923  }
9924  }
9925 }
9926 #endif
9927 
9928 #if defined(DRFLAC_SUPPORT_NEON)
9929 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
9930 {
9931  drflac_uint64 i;
9932  drflac_uint64 frameCount4;
9933  float factor;
9934  drflac_int32 shift;
9935  float32x4_t factor4;
9936  int32x4_t shift4;
9937  int32x4_t wbps0_4; /* Wasted Bits Per Sample */
9938  int32x4_t wbps1_4; /* Wasted Bits Per Sample */
9939 
9940  DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9941 
9942  frameCount4 = frameCount >> 2;
9943 
9944  factor = 1.0f / 8388608.0f;
9945  factor4 = vdupq_n_f32(factor);
9946 
9947  wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9948  wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9949 
9950  shift = unusedBitsPerSample - 8;
9951  if (shift == 0) {
9952  for (i = 0; i < frameCount4; ++i) {
9953  int32x4_t lefti;
9954  int32x4_t righti;
9955  float32x4_t leftf;
9956  float32x4_t rightf;
9957 
9958  int32x4_t mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbps0_4);
9959  int32x4_t side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbps1_4);
9960 
9961  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, vdupq_n_s32(1)));
9962 
9963  lefti = vshrq_n_s32(vaddq_s32(mid, side), 1);
9964  righti = vshrq_n_s32(vsubq_s32(mid, side), 1);
9965 
9966  leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
9967  rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
9968 
9969  drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
9970  }
9971 
9972  for (i = (frameCount4 << 2); i < frameCount; ++i) {
9973  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9974  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9975 
9976  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
9977 
9978  pOutputSamples[i*2+0] = (float)(((mid + side) >> 1) * factor);
9979  pOutputSamples[i*2+1] = (float)(((mid - side) >> 1) * factor);
9980  }
9981  } else {
9982  shift -= 1;
9983  shift4 = vdupq_n_s32(shift);
9984  for (i = 0; i < frameCount4; ++i) {
9985  int32x4_t mid;
9986  int32x4_t side;
9987  int32x4_t lefti;
9988  int32x4_t righti;
9989  float32x4_t leftf;
9990  float32x4_t rightf;
9991 
9992  mid = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), wbps0_4);
9993  side = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), wbps1_4);
9994 
9995  mid = vorrq_s32(vshlq_n_s32(mid, 1), vandq_s32(side, vdupq_n_s32(1)));
9996 
9997  lefti = vshlq_s32(vaddq_s32(mid, side), shift4);
9998  righti = vshlq_s32(vsubq_s32(mid, side), shift4);
9999 
10000  leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
10001  rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
10002 
10003  drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
10004  }
10005 
10006  for (i = (frameCount4 << 2); i < frameCount; ++i) {
10007  drflac_int32 mid = pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10008  drflac_int32 side = pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10009 
10010  mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
10011 
10012  pOutputSamples[i*2+0] = (float)(((mid + side) << shift) * factor);
10013  pOutputSamples[i*2+1] = (float)(((mid - side) << shift) * factor);
10014  }
10015  }
10016 }
10017 #endif
10018 
10019 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10020 {
10021 #if defined(DRFLAC_SUPPORT_SSE2)
10022  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10023  drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10024  } else
10025 #elif defined(DRFLAC_SUPPORT_NEON)
10026  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10027  drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10028  } else
10029 #endif
10030  {
10031  /* Scalar fallback. */
10032 #if 0
10033  drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10034 #else
10035  drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10036 #endif
10037  }
10038 }
10039 
10040 #if 0
10041 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10042 {
10043  for (drflac_uint64 i = 0; i < frameCount; ++i) {
10044  pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
10045  pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
10046  }
10047 }
10048 #endif
10049 
10050 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10051 {
10052  drflac_uint64 i;
10053  drflac_uint64 frameCount4 = frameCount >> 2;
10054 
10055  float factor = 1 / 2147483648.0;
10056 
10057  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10058  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10059 
10060  for (i = 0; i < frameCount4; ++i) {
10061  drflac_int32 tempL0 = pInputSamples0[i*4+0] << shift0;
10062  drflac_int32 tempL1 = pInputSamples0[i*4+1] << shift0;
10063  drflac_int32 tempL2 = pInputSamples0[i*4+2] << shift0;
10064  drflac_int32 tempL3 = pInputSamples0[i*4+3] << shift0;
10065 
10066  drflac_int32 tempR0 = pInputSamples1[i*4+0] << shift1;
10067  drflac_int32 tempR1 = pInputSamples1[i*4+1] << shift1;
10068  drflac_int32 tempR2 = pInputSamples1[i*4+2] << shift1;
10069  drflac_int32 tempR3 = pInputSamples1[i*4+3] << shift1;
10070 
10071  pOutputSamples[i*8+0] = (float)(tempL0 * factor);
10072  pOutputSamples[i*8+1] = (float)(tempR0 * factor);
10073  pOutputSamples[i*8+2] = (float)(tempL1 * factor);
10074  pOutputSamples[i*8+3] = (float)(tempR1 * factor);
10075  pOutputSamples[i*8+4] = (float)(tempL2 * factor);
10076  pOutputSamples[i*8+5] = (float)(tempR2 * factor);
10077  pOutputSamples[i*8+6] = (float)(tempL3 * factor);
10078  pOutputSamples[i*8+7] = (float)(tempR3 * factor);
10079  }
10080 
10081  for (i = (frameCount4 << 2); i < frameCount; ++i) {
10082  pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << shift0) * factor);
10083  pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << shift1) * factor);
10084  }
10085 }
10086 
10087 #if defined(DRFLAC_SUPPORT_SSE2)
10088 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10089 {
10090  drflac_uint64 i;
10091  drflac_uint64 frameCount4 = frameCount >> 2;
10092 
10093  float factor = 1.0f / 8388608.0f;
10094  __m128 factor128 = _mm_set1_ps(1.0f / 8388608.0f);
10095 
10096  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10097  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10098 
10099  for (i = 0; i < frameCount4; ++i) {
10100  __m128i lefti;
10101  __m128i righti;
10102  __m128 leftf;
10103  __m128 rightf;
10104 
10105  lefti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10106  righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10107 
10108  leftf = _mm_mul_ps(_mm_cvtepi32_ps(lefti), factor128);
10109  rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);
10110 
10111  _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
10112  _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
10113  }
10114 
10115  for (i = (frameCount4 << 2); i < frameCount; ++i) {
10116  pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << shift0) * factor);
10117  pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << shift1) * factor);
10118  }
10119 }
10120 #endif
10121 
10122 #if defined(DRFLAC_SUPPORT_NEON)
10123 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10124 {
10125  drflac_uint64 i;
10126  drflac_uint64 frameCount4 = frameCount >> 2;
10127 
10128  float factor = 1.0f / 8388608.0f;
10129  float32x4_t factor4 = vdupq_n_f32(factor);
10130 
10131  drflac_int32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10132  drflac_int32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10133 
10134  int32x4_t shift0_4 = vdupq_n_s32(shift0);
10135  int32x4_t shift1_4 = vdupq_n_s32(shift1);
10136 
10137  for (i = 0; i < frameCount4; ++i) {
10138  int32x4_t lefti;
10139  int32x4_t righti;
10140  float32x4_t leftf;
10141  float32x4_t rightf;
10142 
10143  lefti = vshlq_s32(vld1q_s32(pInputSamples0 + i*4), shift0_4);
10144  righti = vshlq_s32(vld1q_s32(pInputSamples1 + i*4), shift1_4);
10145 
10146  leftf = vmulq_f32(vcvtq_f32_s32(lefti), factor4);
10147  rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
10148 
10149  drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
10150  }
10151 
10152  for (i = (frameCount4 << 2); i < frameCount; ++i) {
10153  pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << shift0) * factor);
10154  pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << shift1) * factor);
10155  }
10156 }
10157 #endif
10158 
10159 static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10160 {
10161 #if defined(DRFLAC_SUPPORT_SSE2)
10162  if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10163  drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10164  } else
10165 #elif defined(DRFLAC_SUPPORT_NEON)
10166  if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10167  drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10168  } else
10169 #endif
10170  {
10171  /* Scalar fallback. */
10172 #if 0
10173  drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10174 #else
10175  drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10176 #endif
10177  }
10178 }
10179 
10180 drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
10181 {
10182  drflac_uint64 framesRead;
10183  drflac_int32 unusedBitsPerSample;
10184 
10185  if (pFlac == NULL || framesToRead == 0) {
10186  return 0;
10187  }
10188 
10189  if (pBufferOut == NULL) {
10190  return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
10191  }
10192 
10193  unusedBitsPerSample = 32 - pFlac->bitsPerSample;
10194 
10195  framesRead = 0;
10196  while (framesToRead > 0) {
10197  /* If we've run out of samples in this frame, go to the next. */
10198  if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
10200  break; /* Couldn't read the next frame, so just break from the loop and return. */
10201  }
10202  } else {
10205  drflac_uint64 frameCountThisIteration = framesToRead;
10206 
10207  if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
10208  frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
10209  }
10210 
10211  if (channelCount == 2) {
10212  const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
10213  const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
10214 
10215  switch (pFlac->currentFLACFrame.header.channelAssignment)
10216  {
10218  {
10219  drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10220  } break;
10221 
10223  {
10224  drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10225  } break;
10226 
10228  {
10229  drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10230  } break;
10231 
10233  default:
10234  {
10235  drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10236  } break;
10237  }
10238  } else {
10239  /* Generic interleaving. */
10240  drflac_uint64 i;
10241  for (i = 0; i < frameCountThisIteration; ++i) {
10242  unsigned int j;
10243  for (j = 0; j < channelCount; ++j) {
10244  pBufferOut[(i*channelCount)+j] = (float)((drflac_uint64)((pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample)) / 2147483648.0);
10245  }
10246  }
10247  }
10248 
10249  framesRead += frameCountThisIteration;
10250  pBufferOut += frameCountThisIteration * channelCount;
10251  framesToRead -= frameCountThisIteration;
10252  pFlac->currentPCMFrame += frameCountThisIteration;
10253  pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
10254  }
10255  }
10256 
10257  return framesRead;
10258 }
10259 
10260 
10262 {
10263  if (pFlac == NULL) {
10264  return DRFLAC_FALSE;
10265  }
10266 
10267  /* Don't do anything if we're already on the seek point. */
10268  if (pFlac->currentPCMFrame == pcmFrameIndex) {
10269  return DRFLAC_TRUE;
10270  }
10271 
10272  /*
10273  If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present
10274  when the decoder was opened.
10275  */
10276  if (pFlac->firstFLACFramePosInBytes == 0) {
10277  return DRFLAC_FALSE;
10278  }
10279 
10280  if (pcmFrameIndex == 0) {
10281  pFlac->currentPCMFrame = 0;
10282  return drflac__seek_to_first_frame(pFlac);
10283  } else {
10284  drflac_bool32 wasSuccessful = DRFLAC_FALSE;
10285 
10286  /* Clamp the sample to the end. */
10287  if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
10288  pcmFrameIndex = pFlac->totalPCMFrameCount;
10289  }
10290 
10291  /* If the target sample and the current sample are in the same frame we just move the position forward. */
10292  if (pcmFrameIndex > pFlac->currentPCMFrame) {
10293  /* Forward. */
10294  drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
10295  if (pFlac->currentFLACFrame.pcmFramesRemaining > offset) {
10296  pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
10297  pFlac->currentPCMFrame = pcmFrameIndex;
10298  return DRFLAC_TRUE;
10299  }
10300  } else {
10301  /* Backward. */
10302  drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentPCMFrame - pcmFrameIndex);
10303  drflac_uint32 currentFLACFramePCMFrameCount = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
10304  drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
10305  if (currentFLACFramePCMFramesConsumed > offsetAbs) {
10306  pFlac->currentFLACFrame.pcmFramesRemaining += offsetAbs;
10307  pFlac->currentPCMFrame = pcmFrameIndex;
10308  return DRFLAC_TRUE;
10309  }
10310  }
10311 
10312  /*
10313  Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
10314  we'll instead use Ogg's natural seeking facility.
10315  */
10316 #ifndef DR_FLAC_NO_OGG
10317  if (pFlac->container == drflac_container_ogg)
10318  {
10319  wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
10320  }
10321  else
10322 #endif
10323  {
10324  /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */
10325  if (!pFlac->_noSeekTableSeek) {
10326  wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
10327  }
10328 
10329 #if !defined(DR_FLAC_NO_CRC)
10330  /* Fall back to binary search if seek table seeking fails. This requires the length of the stream to be known. */
10331  if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
10332  wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
10333  }
10334 #endif
10335 
10336  /* Fall back to brute force if all else fails. */
10337  if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
10338  wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
10339  }
10340  }
10341 
10342  pFlac->currentPCMFrame = pcmFrameIndex;
10343  return wasSuccessful;
10344  }
10345 }
10346 
10347 
10348 
10349 /* High Level APIs */
10350 
10351 #if defined(SIZE_MAX)
10352  #define DRFLAC_SIZE_MAX SIZE_MAX
10353 #else
10354  #if defined(DRFLAC_64BIT)
10355  #define DRFLAC_SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
10356  #else
10357  #define DRFLAC_SIZE_MAX 0xFFFFFFFF
10358  #endif
10359 #endif
10360 
10361 
10362 /* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */
10363 #define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \
10364 static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut)\
10365 { \
10366  type* pSampleData = NULL; \
10367  drflac_uint64 totalPCMFrameCount; \
10368  \
10369  DRFLAC_ASSERT(pFlac != NULL); \
10370  \
10371  totalPCMFrameCount = pFlac->totalPCMFrameCount; \
10372  \
10373  if (totalPCMFrameCount == 0) { \
10374  type buffer[4096]; \
10375  drflac_uint64 pcmFramesRead; \
10376  size_t sampleDataBufferSize = sizeof(buffer); \
10377  \
10378  pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
10379  if (pSampleData == NULL) { \
10380  goto on_error; \
10381  } \
10382  \
10383  while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
10384  if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
10385  type* pNewSampleData; \
10386  size_t newSampleDataBufferSize; \
10387  \
10388  newSampleDataBufferSize = sampleDataBufferSize * 2; \
10389  pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
10390  if (pNewSampleData == NULL) { \
10391  drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
10392  goto on_error; \
10393  } \
10394  \
10395  sampleDataBufferSize = newSampleDataBufferSize; \
10396  pSampleData = pNewSampleData; \
10397  } \
10398  \
10399  DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
10400  totalPCMFrameCount += pcmFramesRead; \
10401  } \
10402  \
10403  /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
10404  protect those ears from random noise! */ \
10405  DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
10406  } else { \
10407  drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
10408  if (dataSize > DRFLAC_SIZE_MAX) { \
10409  goto on_error; /* The decoded data is too big. */ \
10410  } \
10411  \
10412  pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); /* <-- Safe cast as per the check above. */ \
10413  if (pSampleData == NULL) { \
10414  goto on_error; \
10415  } \
10416  \
10417  totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \
10418  } \
10419  \
10420  if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
10421  if (channelsOut) *channelsOut = pFlac->channels; \
10422  if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \
10423  \
10424  drflac_close(pFlac); \
10425  return pSampleData; \
10426  \
10427 on_error: \
10428  drflac_close(pFlac); \
10429  return NULL; \
10430 }
10431 
10435 
10436 drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
10437 {
10438  drflac* pFlac;
10439 
10440  if (channelsOut) {
10441  *channelsOut = 0;
10442  }
10443  if (sampleRateOut) {
10444  *sampleRateOut = 0;
10445  }
10446  if (totalPCMFrameCountOut) {
10447  *totalPCMFrameCountOut = 0;
10448  }
10449 
10450  pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
10451  if (pFlac == NULL) {
10452  return NULL;
10453  }
10454 
10455  return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
10456 }
10457 
10458 drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
10459 {
10460  drflac* pFlac;
10461 
10462  if (channelsOut) {
10463  *channelsOut = 0;
10464  }
10465  if (sampleRateOut) {
10466  *sampleRateOut = 0;
10467  }
10468  if (totalPCMFrameCountOut) {
10469  *totalPCMFrameCountOut = 0;
10470  }
10471 
10472  pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
10473  if (pFlac == NULL) {
10474  return NULL;
10475  }
10476 
10477  return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
10478 }
10479 
10480 float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
10481 {
10482  drflac* pFlac;
10483 
10484  if (channelsOut) {
10485  *channelsOut = 0;
10486  }
10487  if (sampleRateOut) {
10488  *sampleRateOut = 0;
10489  }
10490  if (totalPCMFrameCountOut) {
10491  *totalPCMFrameCountOut = 0;
10492  }
10493 
10494  pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
10495  if (pFlac == NULL) {
10496  return NULL;
10497  }
10498 
10499  return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
10500 }
10501 
10502 #ifndef DR_FLAC_NO_STDIO
10503 drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10504 {
10505  drflac* pFlac;
10506 
10507  if (sampleRate) {
10508  *sampleRate = 0;
10509  }
10510  if (channels) {
10511  *channels = 0;
10512  }
10513  if (totalPCMFrameCount) {
10514  *totalPCMFrameCount = 0;
10515  }
10516 
10517  pFlac = drflac_open_file(filename, pAllocationCallbacks);
10518  if (pFlac == NULL) {
10519  return NULL;
10520  }
10521 
10522  return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
10523 }
10524 
10525 drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10526 {
10527  drflac* pFlac;
10528 
10529  if (sampleRate) {
10530  *sampleRate = 0;
10531  }
10532  if (channels) {
10533  *channels = 0;
10534  }
10535  if (totalPCMFrameCount) {
10536  *totalPCMFrameCount = 0;
10537  }
10538 
10539  pFlac = drflac_open_file(filename, pAllocationCallbacks);
10540  if (pFlac == NULL) {
10541  return NULL;
10542  }
10543 
10544  return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
10545 }
10546 
10547 float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10548 {
10549  drflac* pFlac;
10550 
10551  if (sampleRate) {
10552  *sampleRate = 0;
10553  }
10554  if (channels) {
10555  *channels = 0;
10556  }
10557  if (totalPCMFrameCount) {
10558  *totalPCMFrameCount = 0;
10559  }
10560 
10561  pFlac = drflac_open_file(filename, pAllocationCallbacks);
10562  if (pFlac == NULL) {
10563  return NULL;
10564  }
10565 
10566  return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
10567 }
10568 #endif
10569 
10570 drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10571 {
10572  drflac* pFlac;
10573 
10574  if (sampleRate) {
10575  *sampleRate = 0;
10576  }
10577  if (channels) {
10578  *channels = 0;
10579  }
10580  if (totalPCMFrameCount) {
10581  *totalPCMFrameCount = 0;
10582  }
10583 
10584  pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
10585  if (pFlac == NULL) {
10586  return NULL;
10587  }
10588 
10589  return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
10590 }
10591 
10592 drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10593 {
10594  drflac* pFlac;
10595 
10596  if (sampleRate) {
10597  *sampleRate = 0;
10598  }
10599  if (channels) {
10600  *channels = 0;
10601  }
10602  if (totalPCMFrameCount) {
10603  *totalPCMFrameCount = 0;
10604  }
10605 
10606  pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
10607  if (pFlac == NULL) {
10608  return NULL;
10609  }
10610 
10611  return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
10612 }
10613 
10614 float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
10615 {
10616  drflac* pFlac;
10617 
10618  if (sampleRate) {
10619  *sampleRate = 0;
10620  }
10621  if (channels) {
10622  *channels = 0;
10623  }
10624  if (totalPCMFrameCount) {
10625  *totalPCMFrameCount = 0;
10626  }
10627 
10628  pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
10629  if (pFlac == NULL) {
10630  return NULL;
10631  }
10632 
10633  return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
10634 }
10635 
10636 
10637 void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
10638 {
10639  if (pAllocationCallbacks != NULL) {
10640  drflac__free_from_callbacks(p, pAllocationCallbacks);
10641  } else {
10643  }
10644 }
10645 
10646 
10647 
10648 
10649 void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments)
10650 {
10651  if (pIter == NULL) {
10652  return;
10653  }
10654 
10655  pIter->countRemaining = commentCount;
10656  pIter->pRunningData = (const char*)pComments;
10657 }
10658 
10659 const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
10660 {
10661  drflac_int32 length;
10662  const char* pComment;
10663 
10664  /* Safety. */
10665  if (pCommentLengthOut) {
10666  *pCommentLengthOut = 0;
10667  }
10668 
10669  if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
10670  return NULL;
10671  }
10672 
10673  length = drflac__le2host_32(*(const drflac_uint32*)pIter->pRunningData);
10674  pIter->pRunningData += 4;
10675 
10676  pComment = pIter->pRunningData;
10677  pIter->pRunningData += length;
10678  pIter->countRemaining -= 1;
10679 
10680  if (pCommentLengthOut) {
10681  *pCommentLengthOut = length;
10682  }
10683 
10684  return pComment;
10685 }
10686 
10687 
10688 
10689 
10690 void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData)
10691 {
10692  if (pIter == NULL) {
10693  return;
10694  }
10695 
10696  pIter->countRemaining = trackCount;
10697  pIter->pRunningData = (const char*)pTrackData;
10698 }
10699 
10701 {
10702  drflac_cuesheet_track cuesheetTrack;
10703  const char* pRunningData;
10704  drflac_uint64 offsetHi;
10705  drflac_uint64 offsetLo;
10706 
10707  if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
10708  return DRFLAC_FALSE;
10709  }
10710 
10711  pRunningData = pIter->pRunningData;
10712 
10713  offsetHi = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
10714  offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
10715  cuesheetTrack.offset = offsetLo | (offsetHi << 32);
10716  cuesheetTrack.trackNumber = pRunningData[0]; pRunningData += 1;
10717  DRFLAC_COPY_MEMORY(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12;
10718  cuesheetTrack.isAudio = (pRunningData[0] & 0x80) != 0;
10719  cuesheetTrack.preEmphasis = (pRunningData[0] & 0x40) != 0; pRunningData += 14;
10720  cuesheetTrack.indexCount = pRunningData[0]; pRunningData += 1;
10721  cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index);
10722 
10723  pIter->pRunningData = pRunningData;
10724  pIter->countRemaining -= 1;
10725 
10726  if (pCuesheetTrack) {
10727  *pCuesheetTrack = cuesheetTrack;
10728  }
10729 
10730  return DRFLAC_TRUE;
10731 }
10732 
10733 #if defined(__GNUC__)
10734  #pragma GCC diagnostic pop
10735 #endif
10736 #endif /* DR_FLAC_IMPLEMENTATION */
10737 
10738 
10739 /*
10740 REVISION HISTORY
10741 ================
10742 v0.12.6 - 2020-03-07
10743  - Fix compilation error with Visual Studio .NET 2003.
10744 
10745 v0.12.5 - 2020-01-30
10746  - Silence some static analysis warnings.
10747 
10748 v0.12.4 - 2020-01-29
10749  - Silence some static analysis warnings.
10750 
10751 v0.12.3 - 2019-12-02
10752  - Fix some warnings when compiling with GCC and the -Og flag.
10753  - Fix a crash in out-of-memory situations.
10754  - Fix potential integer overflow bug.
10755  - Fix some static analysis warnings.
10756  - Fix a possible crash when using custom memory allocators without a custom realloc() implementation.
10757  - Fix a bug with binary search seeking where the bits per sample is not a multiple of 8.
10758 
10759 v0.12.2 - 2019-10-07
10760  - Internal code clean up.
10761 
10762 v0.12.1 - 2019-09-29
10763  - Fix some Clang Static Analyzer warnings.
10764  - Fix an unused variable warning.
10765 
10766 v0.12.0 - 2019-09-23
10767  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
10768  routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
10769  - drflac_open()
10770  - drflac_open_relaxed()
10771  - drflac_open_with_metadata()
10772  - drflac_open_with_metadata_relaxed()
10773  - drflac_open_file()
10774  - drflac_open_file_with_metadata()
10775  - drflac_open_memory()
10776  - drflac_open_memory_with_metadata()
10777  - drflac_open_and_read_pcm_frames_s32()
10778  - drflac_open_and_read_pcm_frames_s16()
10779  - drflac_open_and_read_pcm_frames_f32()
10780  - drflac_open_file_and_read_pcm_frames_s32()
10781  - drflac_open_file_and_read_pcm_frames_s16()
10782  - drflac_open_file_and_read_pcm_frames_f32()
10783  - drflac_open_memory_and_read_pcm_frames_s32()
10784  - drflac_open_memory_and_read_pcm_frames_s16()
10785  - drflac_open_memory_and_read_pcm_frames_f32()
10786  Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
10787  DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
10788  - Remove deprecated APIs:
10789  - drflac_read_s32()
10790  - drflac_read_s16()
10791  - drflac_read_f32()
10792  - drflac_seek_to_sample()
10793  - drflac_open_and_decode_s32()
10794  - drflac_open_and_decode_s16()
10795  - drflac_open_and_decode_f32()
10796  - drflac_open_and_decode_file_s32()
10797  - drflac_open_and_decode_file_s16()
10798  - drflac_open_and_decode_file_f32()
10799  - drflac_open_and_decode_memory_s32()
10800  - drflac_open_and_decode_memory_s16()
10801  - drflac_open_and_decode_memory_f32()
10802  - Remove drflac.totalSampleCount which is now replaced with drflac.totalPCMFrameCount. You can emulate drflac.totalSampleCount
10803  by doing pFlac->totalPCMFrameCount*pFlac->channels.
10804  - Rename drflac.currentFrame to drflac.currentFLACFrame to remove ambiguity with PCM frames.
10805  - Fix errors when seeking to the end of a stream.
10806  - Optimizations to seeking.
10807  - SSE improvements and optimizations.
10808  - ARM NEON optimizations.
10809  - Optimizations to drflac_read_pcm_frames_s16().
10810  - Optimizations to drflac_read_pcm_frames_s32().
10811 
10812 v0.11.10 - 2019-06-26
10813  - Fix a compiler error.
10814 
10815 v0.11.9 - 2019-06-16
10816  - Silence some ThreadSanitizer warnings.
10817 
10818 v0.11.8 - 2019-05-21
10819  - Fix warnings.
10820 
10821 v0.11.7 - 2019-05-06
10822  - C89 fixes.
10823 
10824 v0.11.6 - 2019-05-05
10825  - Add support for C89.
10826  - Fix a compiler warning when CRC is disabled.
10827  - Change license to choice of public domain or MIT-0.
10828 
10829 v0.11.5 - 2019-04-19
10830  - Fix a compiler error with GCC.
10831 
10832 v0.11.4 - 2019-04-17
10833  - Fix some warnings with GCC when compiling with -std=c99.
10834 
10835 v0.11.3 - 2019-04-07
10836  - Silence warnings with GCC.
10837 
10838 v0.11.2 - 2019-03-10
10839  - Fix a warning.
10840 
10841 v0.11.1 - 2019-02-17
10842  - Fix a potential bug with seeking.
10843 
10844 v0.11.0 - 2018-12-16
10845  - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with
10846  drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take
10847  and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by
10848  dividing it by the channel count, and then do the same with the return value.
10849  - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as
10850  the changes to drflac_read_*() apply.
10851  - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as
10852  the changes to drflac_read_*() apply.
10853  - Optimizations.
10854 
10855 v0.10.0 - 2018-09-11
10856  - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
10857  need to do it yourself via the callback API.
10858  - Fix the clang build.
10859  - Fix undefined behavior.
10860  - Fix errors with CUESHEET metdata blocks.
10861  - Add an API for iterating over each cuesheet track in the CUESHEET metadata block. This works the same way as the
10862  Vorbis comment API.
10863  - Other miscellaneous bug fixes, mostly relating to invalid FLAC streams.
10864  - Minor optimizations.
10865 
10866 v0.9.11 - 2018-08-29
10867  - Fix a bug with sample reconstruction.
10868 
10869 v0.9.10 - 2018-08-07
10870  - Improve 64-bit detection.
10871 
10872 v0.9.9 - 2018-08-05
10873  - Fix C++ build on older versions of GCC.
10874 
10875 v0.9.8 - 2018-07-24
10876  - Fix compilation errors.
10877 
10878 v0.9.7 - 2018-07-05
10879  - Fix a warning.
10880 
10881 v0.9.6 - 2018-06-29
10882  - Fix some typos.
10883 
10884 v0.9.5 - 2018-06-23
10885  - Fix some warnings.
10886 
10887 v0.9.4 - 2018-06-14
10888  - Optimizations to seeking.
10889  - Clean up.
10890 
10891 v0.9.3 - 2018-05-22
10892  - Bug fix.
10893 
10894 v0.9.2 - 2018-05-12
10895  - Fix a compilation error due to a missing break statement.
10896 
10897 v0.9.1 - 2018-04-29
10898  - Fix compilation error with Clang.
10899 
10900 v0.9 - 2018-04-24
10901  - Fix Clang build.
10902  - Start using major.minor.revision versioning.
10903 
10904 v0.8g - 2018-04-19
10905  - Fix build on non-x86/x64 architectures.
10906 
10907 v0.8f - 2018-02-02
10908  - Stop pretending to support changing rate/channels mid stream.
10909 
10910 v0.8e - 2018-02-01
10911  - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
10912  - Fix a crash the the Rice partition order is invalid.
10913 
10914 v0.8d - 2017-09-22
10915  - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
10916 
10917 v0.8c - 2017-09-07
10918  - Fix warning on non-x86/x64 architectures.
10919 
10920 v0.8b - 2017-08-19
10921  - Fix build on non-x86/x64 architectures.
10922 
10923 v0.8a - 2017-08-13
10924  - A small optimization for the Clang build.
10925 
10926 v0.8 - 2017-08-12
10927  - API CHANGE: Rename dr_* types to drflac_*.
10928  - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
10929  - Add support for custom implementations of malloc(), realloc(), etc.
10930  - Add CRC checking to Ogg encapsulated streams.
10931  - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
10932  - Bug fixes.
10933 
10934 v0.7 - 2017-07-23
10935  - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().
10936 
10937 v0.6 - 2017-07-22
10938  - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
10939  never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.
10940 
10941 v0.5 - 2017-07-16
10942  - Fix typos.
10943  - Change drflac_bool* types to unsigned.
10944  - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.
10945 
10946 v0.4f - 2017-03-10
10947  - Fix a couple of bugs with the bitstreaming code.
10948 
10949 v0.4e - 2017-02-17
10950  - Fix some warnings.
10951 
10952 v0.4d - 2016-12-26
10953  - Add support for 32-bit floating-point PCM decoding.
10954  - Use drflac_int* and drflac_uint* sized types to improve compiler support.
10955  - Minor improvements to documentation.
10956 
10957 v0.4c - 2016-12-26
10958  - Add support for signed 16-bit integer PCM decoding.
10959 
10960 v0.4b - 2016-10-23
10961  - A minor change to drflac_bool8 and drflac_bool32 types.
10962 
10963 v0.4a - 2016-10-11
10964  - Rename drBool32 to drflac_bool32 for styling consistency.
10965 
10966 v0.4 - 2016-09-29
10967  - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type.
10968  - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32().
10969  - API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to
10970  keep it consistent with drflac_audio.
10971 
10972 v0.3f - 2016-09-21
10973  - Fix a warning with GCC.
10974 
10975 v0.3e - 2016-09-18
10976  - Fixed a bug where GCC 4.3+ was not getting properly identified.
10977  - Fixed a few typos.
10978  - Changed date formats to ISO 8601 (YYYY-MM-DD).
10979 
10980 v0.3d - 2016-06-11
10981  - Minor clean up.
10982 
10983 v0.3c - 2016-05-28
10984  - Fixed compilation error.
10985 
10986 v0.3b - 2016-05-16
10987  - Fixed Linux/GCC build.
10988  - Updated documentation.
10989 
10990 v0.3a - 2016-05-15
10991  - Minor fixes to documentation.
10992 
10993 v0.3 - 2016-05-11
10994  - Optimizations. Now at about parity with the reference implementation on 32-bit builds.
10995  - Lots of clean up.
10996 
10997 v0.2b - 2016-05-10
10998  - Bug fixes.
10999 
11000 v0.2a - 2016-05-10
11001  - Made drflac_open_and_decode() more robust.
11002  - Removed an unused debugging variable
11003 
11004 v0.2 - 2016-05-09
11005  - Added support for Ogg encapsulation.
11006  - API CHANGE. Have the onSeek callback take a third argument which specifies whether or not the seek
11007  should be relative to the start or the current position. Also changes the seeking rules such that
11008  seeking offsets will never be negative.
11009  - Have drflac_open_and_decode() fail gracefully if the stream has an unknown total sample count.
11010 
11011 v0.1b - 2016-05-07
11012  - Properly close the file handle in drflac_open_file() and family when the decoder fails to initialize.
11013  - Removed a stale comment.
11014 
11015 v0.1a - 2016-05-05
11016  - Minor formatting changes.
11017  - Fixed a warning on the GCC build.
11018 
11019 v0.1 - 2016-05-03
11020  - Initial versioned release.
11021 */
11022 
11023 /*
11024 This software is available as a choice of the following licenses. Choose
11025 whichever you prefer.
11026 
11027 ===============================================================================
11028 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
11029 ===============================================================================
11030 This is free and unencumbered software released into the public domain.
11031 
11032 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
11033 software, either in source code form or as a compiled binary, for any purpose,
11034 commercial or non-commercial, and by any means.
11035 
11036 In jurisdictions that recognize copyright laws, the author or authors of this
11037 software dedicate any and all copyright interest in the software to the public
11038 domain. We make this dedication for the benefit of the public at large and to
11039 the detriment of our heirs and successors. We intend this dedication to be an
11040 overt act of relinquishment in perpetuity of all present and future rights to
11041 this software under copyright law.
11042 
11043 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11044 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11045 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11046 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
11047 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
11048 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11049 
11050 For more information, please refer to <http://unlicense.org/>
11051 
11052 ===============================================================================
11053 ALTERNATIVE 2 - MIT No Attribution
11054 ===============================================================================
11055 Copyright 2020 David Reid
11056 
11057 Permission is hereby granted, free of charge, to any person obtaining a copy of
11058 this software and associated documentation files (the "Software"), to deal in
11059 the Software without restriction, including without limitation the rights to
11060 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11061 of the Software, and to permit persons to whom the Software is furnished to do
11062 so.
11063 
11064 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11065 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11066 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11067 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11068 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11069 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
11070 SOFTWARE.
11071 */
DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51418
drflac__realloc_default
static void * drflac__realloc_default(void *p, size_t sz, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54866
DRFLAC_ZERO_MEMORY
#define DRFLAC_ZERO_MEMORY(p, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51350
DRFLAC_INLINE
#define DRFLAC_INLINE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51139
drflac__decode_samples_with_residual__rice__scalar_zeroorder
static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar_zeroorder(drflac_bs *bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pSamplesOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52892
drflac__memory_stream
Definition: porcupine/demo/c/dr_libs/dr_flac.h:573
drflac_read_pcm_frames_s32__decode_left_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56797
drflac__seek_bits
static drflac_bool32 drflac__seek_bits(drflac_bs *bs, size_t bitsToSeek)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52100
drflac__seek_to_byte
static drflac_bool32 drflac__seek_to_byte(drflac_bs *bs, drflac_uint64 offsetFromStart)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52338
DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54514
drflac__seek_forward_by_pcm_frames
static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac *pFlac, drflac_uint64 pcmFramesToSeek)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54418
drflac__read_uint32
static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs *bs, unsigned int bitCount, drflac_uint32 *pResultOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51952
drflac_free
void drflac_free(void *p, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59227
drflac__be2host__cache_line
#define drflac__be2host__cache_line
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51834
drflac_oggbs::firstBytePos
drflac_uint64 firstBytePos
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55446
drflac_bs::onRead
drflac_read_proc onRead
Definition: porcupine/demo/c/dr_libs/dr_flac.h:584
drflac_subframe::subframeType
drflac_uint8 subframeType
Definition: porcupine/demo/c/dr_libs/dr_flac.h:628
drflac_read_pcm_frames_s16__decode_left_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57580
drflac__free_from_callbacks
static void drflac__free_from_callbacks(void *p, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54911
drflac_metadata::rawDataSize
drflac_uint32 rawDataSize
Definition: porcupine/demo/c/dr_libs/dr_flac.h:425
DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE
#define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51420
drflac_uint64
uint64_t drflac_uint64
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:250
drflac_seek_origin
drflac_seek_origin
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:335
drflac_bs::unalignedByteCount
size_t unalignedByteCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:598
drflac_cuesheet_track::trackNumber
drflac_uint8 trackNumber
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1296
drflac_uint64
unsigned long long drflac_uint64
Definition: porcupine/demo/c/dr_libs/dr_flac.h:259
drflac_open_with_metadata_private
static drflac * drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void *pUserData, void *pUserDataMD, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55935
drflac_allocation_callbacks::onMalloc
void *(* onMalloc)(size_t sz, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_flac.h:567
drflac__free_default
static void drflac__free_default(void *p, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54871
drflac_int8
int8_t drflac_int8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:243
drflac_cuesheet_track
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1293
drflac_read_proc
size_t(* drflac_read_proc)(void *pUserData, void *pBufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:448
drflac__seek_to_first_frame
static drflac_bool32 drflac__seek_to_first_frame(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54404
DRFLAC_FREE
#define DRFLAC_FREE(p)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51344
drflac__decode_samples__fixed
static drflac_bool32 drflac__decode_samples__fixed(drflac_bs *bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53922
drflac_bool32
drflac_uint32 drflac_bool32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:253
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
DRFLAC_SUBFRAME_CONSTANT
#define DRFLAC_SUBFRAME_CONSTANT
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51412
DRFLAC_ASSERT
#define DRFLAC_ASSERT(expression)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51335
drflac
Definition: porcupine/demo/c/dr_libs/dr_flac.h:688
drflac_metadata::application
struct drflac_metadata::@0::@2 application
drflac_metadata::padding
struct drflac_metadata::@0::@1 padding
drflac::channels
drflac_uint8 channels
Definition: porcupine/demo/c/dr_libs/dr_flac.h:707
drflac_seekpoint::firstPCMFrame
drflac_uint64 firstPCMFrame
Definition: porcupine/demo/c/dr_libs/dr_flac.h:390
drflac_container_unknown
@ drflac_container_unknown
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:332
DRFLAC_COPY_MEMORY
#define DRFLAC_COPY_MEMORY(dst, src, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51347
drflac_seek_origin_start
@ drflac_seek_origin_start
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:337
drflac_oggbs::pageData
drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55452
drflac__seek_to_pcm_frame__binary_search
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac *pFlac, drflac_uint64 pcmFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54644
drflac_open_memory_with_metadata
drflac * drflac_open_memory_with_metadata(const void *data, size_t dataSize, drflac_meta_proc onMeta, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56722
drflac_init_info::bs
drflac_bs bs
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54804
drflac_init_info::firstFrameHeader
drflac_frame_header firstFrameHeader
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54805
drflac__crc8_table
static drflac_uint8 drflac__crc8_table[]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51614
drflac_init_info::onSeek
drflac_seek_proc onSeek
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54791
drflac_cuesheet_track_iterator::countRemaining
drflac_uint32 countRemaining
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1279
drflac_ogg__read_page_header
static drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void *pUserData, drflac_ogg_page_header *pHeader, drflac_uint32 *pBytesRead, drflac_uint32 *pCRC32)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55407
drflac__clz_software
static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52183
drflac__decode_flac_frame
static drflac_result drflac__decode_flac_frame(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54292
drflac__get_channel_count_from_channel_assignment
static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54286
DRFLAC_FALSE
#define DRFLAC_FALSE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:255
drflac_vorbis_comment_iterator
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1257
drflac_streaminfo::channels
drflac_uint8 channels
Definition: porcupine/demo/c/dr_libs/dr_flac.h:403
drflac_ogg__seek_to_pcm_frame
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac *pFlac, drflac_uint64 pcmFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55655
drflac_uint8
unsigned char drflac_uint8
Definition: porcupine/demo/c/dr_libs/dr_flac.h:242
drflac__read_and_decode_block_header
static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void *pUserData, drflac_uint8 *isLastBlock, drflac_uint8 *blockType, drflac_uint32 *blockSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54819
drflac_oggbs::bytesRemainingInPage
drflac_uint32 bytesRemainingInPage
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55450
drflac_vorbis_comment_iterator::countRemaining
drflac_uint32 countRemaining
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1259
drflac_crc32_byte
static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55321
drflac_metadata::cuesheet
struct drflac_metadata::@0::@5 cuesheet
drflac_read_pcm_frames_s16
drflac_uint64 drflac_read_pcm_frames_s16(drflac *pFlac, drflac_uint64 framesToRead, drflac_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58123
drflac__seek_to_approximate_flac_frame_to_byte
static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac *pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64 *pLastSuccessfulSeekOffset)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54515
drflac_ogg_fail_on_crc_mismatch
@ drflac_ogg_fail_on_crc_mismatch
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55251
drflac_frame
Definition: porcupine/demo/c/dr_libs/dr_flac.h:673
drflac_cuesheet_track::pIndexPoints
const drflac_cuesheet_track_index * pIndexPoints
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1301
drflac_frame_header::channelAssignment
drflac_uint8 channelAssignment
Definition: porcupine/demo/c/dr_libs/dr_flac.h:664
drflac__seek_to_pcm_frame__brute_force
static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac *pFlac, drflac_uint64 pcmFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54441
DRFLAC_METADATA_BLOCK_TYPE_CUESHEET
#define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:301
drflac_bs::cacheL2
drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)]
Definition: porcupine/demo/c/dr_libs/dr_flac.h:613
drflac_ogg__get_page_header_size
static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header *pHeader)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55358
drflac_init_info
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54788
drflac_ogg_page_header::granulePosition
drflac_uint64 granulePosition
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54780
drflac__get_pcm_frame_range_of_current_flac_frame
static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac *pFlac, drflac_uint64 *pFirstPCMFrame, drflac_uint64 *pLastPCMFrame)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54384
drflac_int8
signed char drflac_int8
Definition: porcupine/demo/c/dr_libs/dr_flac.h:241
drflac__seek_rice_parts
static DRFLAC_INLINE drflac_bool32 drflac__seek_rice_parts(drflac_bs *bs, drflac_uint8 riceParam)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52828
drflac__init_private
static drflac_bool32 drflac__init_private(drflac_init_info *pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void *pUserData, void *pUserDataMD)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55854
drflac_crc16_byte
static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51711
drflac_has_sse41
static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51252
drflac_streaminfo::minBlockSizeInPCMFrames
drflac_uint16 minBlockSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:398
drflac_read_pcm_frames_s16__decode_independent_stereo__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58017
drflac_ogg__read_page_header_after_capture_pattern
static drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void *pUserData, drflac_ogg_page_header *pHeader, drflac_uint32 *pBytesRead, drflac_uint32 *pCRC32)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55371
drflac__memory_stream::data
const drflac_uint8 * data
Definition: porcupine/demo/c/dr_libs/dr_flac.h:575
drflac__memory_stream::dataSize
size_t dataSize
Definition: porcupine/demo/c/dr_libs/dr_flac.h:576
drflac_metadata::data
union drflac_metadata::@0 data
DRFLAC_CACHE_L1_SELECTION_SHIFT
#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51840
drflac_ogg__is_capture_pattern
static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4])
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55354
DRFLAC_CACHE_L1_SELECTION_MASK
#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51839
drflac__on_seek_ogg
static drflac_bool32 drflac__on_seek_ogg(void *pUserData, int offset, drflac_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55619
drflac_subframe::lpcOrder
drflac_uint8 lpcOrder
Definition: porcupine/demo/c/dr_libs/dr_flac.h:634
drflac__calculate_prediction_32
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52418
drflac_oggbs
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55440
drflac_init_info::hasStreamInfoBlock
drflac_bool32 hasStreamInfoBlock
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54802
drflac__clz
static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52304
drflac_bs::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/dr_flac.h:590
drflac_ogg_page_header::segmentTable
drflac_uint8 segmentTable[255]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54785
drflac_uint8
uint8_t drflac_uint8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:244
drflac::memoryStream
drflac__memory_stream memoryStream
Definition: porcupine/demo/c/dr_libs/dr_flac.h:741
drflac_next_cuesheet_track
drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator *pIter, drflac_cuesheet_track *pCuesheetTrack)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59271
drflac_read_pcm_frames_s32__decode_mid_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57052
drflac__decode_samples_with_residual__unencoded
static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs *bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pSamplesOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53744
drflac_read_pcm_frames_s32__decode_right_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57021
drflac_read_pcm_frames_f32__decode_left_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58203
DRFLAC_ERROR
#define DRFLAC_ERROR
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51358
DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51417
drflac_frame_header::flacFrameNumber
drflac_uint32 flacFrameNumber
Definition: porcupine/demo/c/dr_libs/dr_flac.h:652
drflac_int16
int16_t drflac_int16
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:245
drflac_init_info::onMeta
drflac_meta_proc onMeta
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54792
drflac_metadata::streaminfo
drflac_streaminfo streaminfo
Definition: porcupine/demo/c/dr_libs/dr_flac.h:429
drflac_bs::onSeek
drflac_seek_proc onSeek
Definition: porcupine/demo/c/dr_libs/dr_flac.h:587
drflac_int64
signed long long drflac_int64
Definition: porcupine/demo/c/dr_libs/dr_flac.h:258
drflac_open_file_with_metadata
drflac * drflac_open_file_with_metadata(const char *filename, drflac_meta_proc onMeta, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56629
drflac_streaminfo::maxFrameSizeInPCMFrames
drflac_uint32 maxFrameSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:401
drflac_subframe::wastedBitsPerSample
drflac_uint8 wastedBitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_flac.h:631
DRFLAC_OGG_MAX_PAGE_SIZE
#define DRFLAC_OGG_MAX_PAGE_SIZE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55246
drflac_metadata::seektable
struct drflac_metadata::@0::@3 seektable
drflac__flush_crc16
static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51862
drflac::currentFLACFrame
drflac_frame currentFLACFrame
Definition: porcupine/demo/c/dr_libs/dr_flac.h:730
drflac_cuesheet_track::isAudio
drflac_bool8 isAudio
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1298
drflac_bs::crc16Cache
drflac_cache_t crc16Cache
Definition: porcupine/demo/c/dr_libs/dr_flac.h:621
drflac_read_pcm_frames_f32__decode_mid_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58480
drflac__has_neon
static DRFLAC_INLINE drflac_bool32 drflac__has_neon(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51471
drflac::seekpointCount
drflac_uint32 seekpointCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:726
drflac__read_uint16
static drflac_bool32 drflac__read_uint16(drflac_bs *bs, unsigned int bitCount, drflac_uint16 *pResult)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52046
drflac::container
drflac_container container
Definition: porcupine/demo/c/dr_libs/dr_flac.h:723
drflac__init_cpu_caps
static DRFLAC_NO_THREAD_SANITIZE void drflac__init_cpu_caps(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51487
DRFLAC_MAX_SIMD_VECTOR_SIZE
#define DRFLAC_MAX_SIMD_VECTOR_SIZE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51355
drflac_ogg_page_header::segmentCount
drflac_uint8 segmentCount
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54784
drflac__read_int8
static drflac_bool32 drflac__read_int8(drflac_bs *bs, unsigned int bitCount, drflac_int8 *pResult)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52087
drflac__malloc_from_callbacks
static void * drflac__malloc_from_callbacks(size_t sz, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54876
drflac_init_info::pUserData
void * pUserData
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54794
drflac_ogg_page_header::sequenceNumber
drflac_uint32 sequenceNumber
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54782
drflac_init_info::totalPCMFrameCount
drflac_uint64 totalPCMFrameCount
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54799
DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE
#define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:299
drflac_oggbs::currentBytePos
drflac_uint64 currentBytePos
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55445
drflac_ogg_page_header::checksum
drflac_uint32 checksum
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54783
drflac::_noBinarySearchSeek
drflac_bool32 _noBinarySearchSeek
Definition: porcupine/demo/c/dr_libs/dr_flac.h:755
drflac_read_pcm_frames_s16__decode_mid_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57989
drflac_ogg_recover_on_crc_mismatch
@ drflac_ogg_recover_on_crc_mismatch
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55250
drflac_subframe
Definition: porcupine/demo/c/dr_libs/dr_flac.h:625
drflac_cache_t
drflac_uint32 drflac_cache_t
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:292
drflac_read_pcm_frames_f32__decode_independent_stereo
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58831
drflac_read_pcm_frames_f32__decode_independent_stereo__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58740
drflac_read_pcm_frames_s32__decode_left_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56893
drflac_cuesheet_track_index::offset
drflac_uint64 offset
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1287
drflac_frame_header
Definition: porcupine/demo/c/dr_libs/dr_flac.h:640
drflac_init_info::sampleRate
drflac_uint32 sampleRate
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54796
drflac__swap_endian_uint64
static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51554
drflac_init_info::container
drflac_container container
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54793
drflac_init_vorbis_comment_iterator
void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator *pIter, drflac_uint32 commentCount, const void *pComments)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59235
drflac__read_next_flac_frame_header
static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs *bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header *header)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53981
drflac__reset_cache
static void drflac__reset_cache(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51940
drflac_read_pcm_frames_f32__decode_mid_side
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58712
drflac_cache_t
drflac_uint32 drflac_cache_t
Definition: porcupine/demo/c/dr_libs/dr_flac.h:337
drflac_has_sse2
static DRFLAC_INLINE drflac_bool32 drflac_has_sse2(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51228
DRFLAC_SUBFRAME_LPC
#define DRFLAC_SUBFRAME_LPC
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51415
drflac_container_native
@ drflac_container_native
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:330
drflac_int16
signed short drflac_int16
Definition: porcupine/demo/c/dr_libs/dr_flac.h:243
drflac_ogg_page_header::headerType
drflac_uint8 headerType
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54779
drflac_frame_header::pcmFrameNumber
drflac_uint64 pcmFrameNumber
Definition: porcupine/demo/c/dr_libs/dr_flac.h:646
drflac_uint32
uint32_t drflac_uint32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:248
drflac_open_relaxed
drflac * drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56751
drflac_read_pcm_frames_s16__decode_right_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57614
drflac_bool8
drflac_uint8 drflac_bool8
Definition: porcupine/demo/c/dr_libs/dr_flac.h:269
drflac__seek_to_pcm_frame__seek_table
static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac *pFlac, drflac_uint64 pcmFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54660
drflac_seek_origin_current
@ drflac_seek_origin_current
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:338
drflac_crc8_byte
static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51666
drflac_seek_origin
drflac_seek_origin
Definition: porcupine/demo/c/dr_libs/dr_flac.h:380
drflac_container
drflac_container
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:328
drflac_allocation_callbacks::onRealloc
void *(* onRealloc)(void *p, size_t sz, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_flac.h:568
drflac_cuesheet_track_iterator
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1277
drflac__decode_samples__verbatim
static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs *bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53910
drflac_init_info::bitsPerSample
drflac_uint8 bitsPerSample
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54798
drflac__decode_samples_with_residual__rice
static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs *bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pSamplesOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53714
drflac_frame_header::bitsPerSample
drflac_uint8 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_flac.h:667
drflac_read_pcm_frames_s32__decode_right_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56925
drflac::firstFLACFramePosInBytes
drflac_uint64 firstFLACFramePosInBytes
Definition: porcupine/demo/c/dr_libs/dr_flac.h:737
drflac_open_and_read_pcm_frames_f32
float * drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void *pUserData, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59099
drflac_bs
Definition: porcupine/demo/c/dr_libs/dr_flac.h:581
drflac_read_pcm_frames_f32__decode_right_side
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58449
drflac__crc16_table
static drflac_uint16 drflac__crc16_table[]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51632
drflac_read_pcm_frames_s16__decode_mid_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57758
drflac_ogg__get_page_body_size
static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header *pHeader)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55362
drflac_allocation_callbacks::onFree
void(* onFree)(void *p, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_flac.h:569
drflac_oggbs::currentPageHeader
drflac_ogg_page_header currentPageHeader
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55449
drflac::pDecodedSamples
drflac_int32 * pDecodedSamples
Definition: porcupine/demo/c/dr_libs/dr_flac.h:745
drflac::_noBruteForceSeek
drflac_bool32 _noBruteForceSeek
Definition: porcupine/demo/c/dr_libs/dr_flac.h:756
drflac__memory_stream::currentReadPos
size_t currentReadPos
Definition: porcupine/demo/c/dr_libs/dr_flac.h:577
drflac::pUserDataMD
void * pUserDataMD
Definition: porcupine/demo/c/dr_libs/dr_flac.h:694
drflac_read_pcm_frames_s32__decode_independent_stereo
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57367
drflac_seekpoint
Definition: porcupine/demo/c/dr_libs/dr_flac.h:388
drflac__read_and_decode_metadata
static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void *pUserData, void *pUserDataMD, drflac_uint64 *pFirstFramePos, drflac_uint64 *pSeektablePos, drflac_uint32 *pSeektableSize, drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54920
drflac_cuesheet_track::indexCount
drflac_uint8 indexCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1300
drflac_oggbs::pageDataSize
drflac_uint32 pageDataSize
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55451
drflac_frame::header
drflac_frame_header header
Definition: porcupine/demo/c/dr_libs/dr_flac.h:676
drflac_oggbs::serialNumber
drflac_uint32 serialNumber
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55447
drflac_open
drflac * drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56747
DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE
#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51421
drflac::_noSeekTableSeek
drflac_bool32 _noSeekTableSeek
Definition: porcupine/demo/c/dr_libs/dr_flac.h:754
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
drflac::currentPCMFrame
drflac_uint64 currentPCMFrame
Definition: porcupine/demo/c/dr_libs/dr_flac.h:734
DRFLAC_SUBFRAME_RESERVED
#define DRFLAC_SUBFRAME_RESERVED
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51416
drflac__read_and_decode_next_flac_frame
static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54365
DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51843
drflac__le2host_32
static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51598
DRFLAC_DEFINE_FULL_READ_AND_CLOSE
#define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58993
drflac_metadata::vorbis_comment
struct drflac_metadata::@0::@4 vorbis_comment
drflac_init_info::onRead
drflac_read_proc onRead
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54790
drflac_init_info::oggSerial
drflac_uint32 oggSerial
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54807
drflac_oggbs::pUserData
void * pUserData
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55444
DRFLAC_CACHE_L1_SIZE_BITS
#define DRFLAC_CACHE_L1_SIZE_BITS(bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51837
drflac_ogg_page_header::structureVersion
drflac_uint8 structureVersion
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54778
drflac_ogg_crc_mismatch_recovery
drflac_ogg_crc_mismatch_recovery
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55248
drflac__swap_endian_uint16
static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51506
python.setup.description
description
Definition: porcupine/binding/python/setup.py:73
DRFLAC_METADATA_BLOCK_TYPE_PADDING
#define DRFLAC_METADATA_BLOCK_TYPE_PADDING
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:297
drflac_next_vorbis_comment
const char * drflac_next_vorbis_comment(drflac_vorbis_comment_iterator *pIter, drflac_uint32 *pCommentLengthOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59243
drflac::maxBlockSizeInPCMFrames
drflac_uint16 maxBlockSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:713
DRFLAC_SUBFRAME_VERBATIM
#define DRFLAC_SUBFRAME_VERBATIM
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51413
drflac__seek_to_pcm_frame__binary_search_internal
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac *pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54569
DRFLAC_CRC_MISMATCH
#define DRFLAC_CRC_MISMATCH
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51411
drflac_close
void drflac_close(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56763
drflac_bool32
drflac_uint32 drflac_bool32
Definition: porcupine/demo/c/dr_libs/dr_flac.h:270
DRFLAC_METADATA_BLOCK_TYPE_PICTURE
#define DRFLAC_METADATA_BLOCK_TYPE_PICTURE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:302
drflac_allocation_callbacks
Definition: porcupine/demo/c/dr_libs/dr_flac.h:564
drflac_init_info::pUserDataMD
void * pUserDataMD
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54795
DRFLAC_METADATA_BLOCK_TYPE_INVALID
#define DRFLAC_METADATA_BLOCK_TYPE_INVALID
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:303
L
#define L
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/stb_vorbis.c:5102
DRFLAC_TRUE
#define DRFLAC_TRUE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:254
drflac__seek_subframe
static drflac_bool32 drflac__seek_subframe(drflac_bs *bs, drflac_frame *frame, int subframeIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54214
drflac__decode_flac_frame_and_seek_forward_by_pcm_frames
static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac *pFlac, drflac_uint64 offset)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54558
DRFLAC_MALLOC
#define DRFLAC_MALLOC(sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51338
drflac__is_little_endian
static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51495
drflac_bs::crc16
drflac_uint16 crc16
Definition: porcupine/demo/c/dr_libs/dr_flac.h:620
drflac__realloc_from_callbacks
static void * drflac__realloc_from_callbacks(void *p, size_t szNew, size_t szOld, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54889
drflac_metadata::picture
struct drflac_metadata::@0::@6 picture
drflac_frame::pcmFramesRemaining
drflac_uint32 pcmFramesRemaining
Definition: porcupine/demo/c/dr_libs/dr_flac.h:682
drflac_crc8
static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51670
DRFLAC_CACHE_L1_SIZE_BYTES
#define DRFLAC_CACHE_L1_SIZE_BYTES(bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51836
drflac__read_and_seek_residual
static drflac_bool32 drflac__read_and_seek_residual(drflac_bs *bs, drflac_uint32 blockSize, drflac_uint32 order)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53834
drflac_int64
int64_t drflac_int64
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:249
DRFLAC_NO_THREAD_SANITIZE
#define DRFLAC_NO_THREAD_SANITIZE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51447
drflac_align
#define drflac_align(x, a)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51423
drflac__on_read_stdio
static size_t drflac__on_read_stdio(void *pUserData, void *bufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56592
drflac__decode_samples__lpc
static drflac_bool32 drflac__decode_samples__lpc(drflac_bs *bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53944
drflac__read_uint8
static drflac_bool32 drflac__read_uint8(drflac_bs *bs, unsigned int bitCount, drflac_uint8 *pResult)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52074
drflac_read_pcm_frames_s16__decode_left_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57467
drflac__malloc_default
static void * drflac__malloc_default(size_t sz, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54861
drflac_int32
int32_t drflac_int32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:247
drflac__be2host_32
static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51584
drflac::bs
drflac_bs bs
Definition: porcupine/demo/c/dr_libs/dr_flac.h:759
drflac_oggbs__goto_next_page
static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs *oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55491
drflac__decode_samples__constant
static drflac_bool32 drflac__decode_samples__constant(drflac_bs *bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53898
drflac_vorbis_comment_iterator::pRunningData
const char * pRunningData
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1260
DRFLAC_CACHE_L1_BITS_REMAINING
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51838
drflac_oggbs__read_physical
static size_t drflac_oggbs__read_physical(drflac_oggbs *oggbs, void *bufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55454
drflac_open_memory_and_read_pcm_frames_s16
drflac_int16 * drflac_open_memory_and_read_pcm_frames_s16(const void *data, size_t dataSize, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59191
DRFLAC_REALLOC
#define DRFLAC_REALLOC(p, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51341
drflac__calculate_prediction_64
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52459
drflac__reload_cache
static drflac_bool32 drflac__reload_cache(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51910
drflac::bitsPerSample
drflac_uint8 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_flac.h:710
DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO
#define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:296
drflac__decode_samples_with_residual__rice__scalar
static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_bs *bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pSamplesOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52919
drflac__read_and_seek_residual__rice
static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs *bs, drflac_uint32 count, drflac_uint8 riceParam)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53733
drflac_seek_proc
drflac_bool32(* drflac_seek_proc)(void *pUserData, int offset, drflac_seek_origin origin)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:465
drflac__init_from_info
static void drflac__init_from_info(drflac *pFlac, const drflac_init_info *pInit)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55920
drflac_cuesheet_track_index
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1285
drflac_oggbs::onRead
drflac_read_proc onRead
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55442
drflac__decode_samples_with_residual
static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs *bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32 *coefficients, drflac_int32 *pDecodedSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:53766
drflac_frame_header::blockSizeInPCMFrames
drflac_uint16 blockSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:658
drflac_init_info::hasMetadataBlocks
drflac_bool32 hasMetadataBlocks
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54803
drflac_open_and_read_pcm_frames_s16
drflac_int16 * drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void *pUserData, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59081
drflac_read_pcm_frames_f32
drflac_uint64 drflac_read_pcm_frames_f32(drflac *pFlac, drflac_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58850
drflac_subframe::pSamplesS32
drflac_int32 * pSamplesS32
Definition: porcupine/demo/c/dr_libs/dr_flac.h:637
drflac_bs::cache
drflac_cache_t cache
Definition: porcupine/demo/c/dr_libs/dr_flac.h:614
DRFLAC_SUBFRAME_FIXED
#define DRFLAC_SUBFRAME_FIXED
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51414
drflac_read_pcm_frames_s32__decode_independent_stereo__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57291
drflac__on_read_memory
static size_t drflac__on_read_memory(void *pUserData, void *bufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56658
drflac__crc32_table
static drflac_uint32 drflac__crc32_table[]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55254
drflac_bool8
drflac_uint8 drflac_bool8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:252
DRFLAC_METADATA_BLOCK_TYPE_APPLICATION
#define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:298
drflac_ogg_page_header::capturePattern
drflac_uint8 capturePattern[4]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54777
drflac_open_file
drflac * drflac_open_file(const char *filename, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56601
drflac_read_pcm_frames_f32__decode_left_side
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58310
DRFLAC_CACHE_L2_LINE_COUNT
#define DRFLAC_CACHE_L2_LINE_COUNT(bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51845
drflac_init_info::oggBosHeader
drflac_ogg_page_header oggBosHeader
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54809
DRFLAC_CACHE_L2_SIZE_BYTES
#define DRFLAC_CACHE_L2_SIZE_BYTES(bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51844
drflac_streaminfo::totalPCMFrameCount
drflac_uint64 totalPCMFrameCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:405
drflac_oggbs__seek_physical
static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs *oggbs, drflac_uint64 offset, drflac_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55460
drflac_init_info::runningFilePos
drflac_uint64 runningFilePos
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54801
DRFLAC_OGG_CAPTURE_PATTERN_CRC32
#define DRFLAC_OGG_CAPTURE_PATTERN_CRC32
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55247
drflac_ogg_page_header::serialNumber
drflac_uint32 serialNumber
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54781
drflac_cuesheet_track::preEmphasis
drflac_bool8 preEmphasis
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1299
DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT
#define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51419
drflac__read_int32
static drflac_bool32 drflac__read_int32(drflac_bs *bs, unsigned int bitCount, drflac_int32 *pResult)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51996
drflac_read_pcm_frames_s16__decode_right_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57727
drflac__unsynchsafe_32
static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51605
drflac_open_and_read_pcm_frames_s32
drflac_int32 * drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void *pUserData, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59063
drflac_metadata::type
drflac_uint32 type
Definition: porcupine/demo/c/dr_libs/dr_flac.h:415
drflac__read_utf8_coded_number
static drflac_result drflac__read_utf8_coded_number(drflac_bs *bs, drflac_uint64 *pNumberOut, drflac_uint8 *pCRCOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52367
drflac_read_pcm_frames_s32__decode_mid_side
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int32 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57263
drflac_uint16
uint16_t drflac_uint16
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:246
drflac__reload_l1_cache_from_l2
static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51874
drflac_open_with_metadata_relaxed
drflac * drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56759
drflac__seek_past_next_set_bit
static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs *bs, unsigned int *pOffsetOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52321
DRFLAC_CACHE_L1_SELECT_AND_SHIFT
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51842
DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51422
drflac_crc16_cache
static DRFLAC_INLINE drflac_uint16 drflac_crc16_cache(drflac_uint16 crc, drflac_cache_t data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51715
drflac__be2host_64
static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51591
drflac_frame_header::sampleRate
drflac_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_flac.h:655
drflac_read_pcm_frames_f32__decode_right_side__scalar
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, float *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58342
drflac_uint32
unsigned int drflac_uint32
Definition: porcupine/demo/c/dr_libs/dr_flac.h:246
drflac_bs::unalignedCache
drflac_cache_t unalignedCache
Definition: porcupine/demo/c/dr_libs/dr_flac.h:601
drflac_streaminfo::md5
drflac_uint8 md5[16]
Definition: porcupine/demo/c/dr_libs/dr_flac.h:406
drflac__on_seek_memory
static drflac_bool32 drflac__on_seek_memory(void *pUserData, int offset, drflac_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56674
drflac__update_crc16
static DRFLAC_INLINE void drflac__update_crc16(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51853
init
void init(const M_string &remappings)
drflac__decode_subframe
static drflac_bool32 drflac__decode_subframe(drflac_bs *bs, drflac_frame *frame, int subframeIndex, drflac_int32 *pDecodedSamplesOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54171
drflac__read_streaminfo
static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void *pUserData, drflac_streaminfo *pStreamInfo)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54829
drflac__reset_crc16
static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51848
drflac_init_info::channels
drflac_uint8 channels
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54797
drflac_streaminfo::sampleRate
drflac_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_flac.h:402
drflac_oggbs::onSeek
drflac_seek_proc onSeek
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55443
DR_FLAC_BUFFER_SIZE
#define DR_FLAC_BUFFER_SIZE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:277
drflac::_oggbs
void * _oggbs
Definition: porcupine/demo/c/dr_libs/dr_flac.h:751
drflac::sampleRate
drflac_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_flac.h:701
drflac_streaminfo
Definition: porcupine/demo/c/dr_libs/dr_flac.h:396
drflac_open_memory
drflac * drflac_open_memory(const void *data, size_t dataSize, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56697
drflac_init_info::maxBlockSizeInPCMFrames
drflac_uint16 maxBlockSizeInPCMFrames
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54800
drflac_uint16
unsigned short drflac_uint16
Definition: porcupine/demo/c/dr_libs/dr_flac.h:244
drflac_cuesheet_track::ISRC
char ISRC[12]
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1297
drflac_frame::subframes
drflac_subframe subframes[8]
Definition: porcupine/demo/c/dr_libs/dr_flac.h:685
drflac_init_cuesheet_track_iterator
void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator *pIter, drflac_uint32 trackCount, const void *pTrackData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59263
drflac_streaminfo::bitsPerSample
drflac_uint8 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_flac.h:404
drflac__be2host_16
static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51577
drflac_crc32_buffer
static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8 *pData, drflac_uint32 dataSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55346
drflac_open_file_and_read_pcm_frames_s32
drflac_int32 * drflac_open_file_and_read_pcm_frames_s32(const char *filename, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59118
drflac_cuesheet_track::offset
drflac_uint64 offset
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1295
drflac_read_pcm_frames_s16__decode_independent_stereo
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac *pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32 *pInputSamples0, const drflac_int32 *pInputSamples1, drflac_int16 *pOutputSamples)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58104
drflac__decode_block_header
static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8 *isLastBlock, drflac_uint8 *blockType, drflac_uint32 *blockSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54812
drflac::totalPCMFrameCount
drflac_uint64 totalPCMFrameCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:719
header
const std::string header
drflac__swap_endian_uint32
static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51523
drflac__gIsNEONSupported
static drflac_bool32 drflac__gIsNEONSupported
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51470
assert.h
drflac_open_file_and_read_pcm_frames_f32
float * drflac_open_file_and_read_pcm_frames_f32(const char *filename, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59154
drflac_bs::crc16CacheIgnoredBytes
drflac_uint32 crc16CacheIgnoredBytes
Definition: porcupine/demo/c/dr_libs/dr_flac.h:622
drflac_seekpoint::flacFrameOffset
drflac_uint64 flacFrameOffset
Definition: porcupine/demo/c/dr_libs/dr_flac.h:391
drflac::onMeta
drflac_meta_proc onMeta
Definition: porcupine/demo/c/dr_libs/dr_flac.h:691
drflac__seek_to_next_flac_frame
static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54413
DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT
#define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:300
drflac_open_memory_and_read_pcm_frames_s32
drflac_int32 * drflac_open_memory_and_read_pcm_frames_s32(const void *data, size_t dataSize, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59173
drflac__init_private__ogg
static drflac_bool32 drflac__init_private__ogg(drflac_init_info *pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void *pUserData, void *pUserDataMD, drflac_bool32 relaxed)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55746
drflac__read_subframe_header
static drflac_bool32 drflac__read_subframe_header(drflac_bs *bs, drflac_subframe *pSubframe)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54128
drflac_streaminfo::minFrameSizeInPCMFrames
drflac_uint32 minFrameSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:400
drflac_streaminfo::maxBlockSizeInPCMFrames
drflac_uint16 maxBlockSizeInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_flac.h:399
drflac_bs::nextL2Line
drflac_uint32 nextL2Line
Definition: porcupine/demo/c/dr_libs/dr_flac.h:604
drflac_oggbs::bosPageHeader
drflac_ogg_page_header bosPageHeader
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55448
drflac_ogg_page_header
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54775
drflac_open_with_metadata
drflac * drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void *pUserData, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56755
drflac__find_and_seek_to_next_sync_code
static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs *bs)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52145
DRFLAC_SUCCESS
#define DRFLAC_SUCCESS
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51357
drflac__on_seek_stdio
static drflac_bool32 drflac__on_seek_stdio(void *pUserData, int offset, drflac_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:56596
drflac::pSeekpoints
drflac_seekpoint * pSeekpoints
Definition: porcupine/demo/c/dr_libs/dr_flac.h:748
drflac::pExtraData
drflac_uint8 pExtraData[1]
Definition: porcupine/demo/c/dr_libs/dr_flac.h:762
drflac_int32
signed int drflac_int32
Definition: porcupine/demo/c/dr_libs/dr_flac.h:245
drflac__read_rice_parts_x1
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs *bs, drflac_uint8 riceParam, drflac_uint32 *pZeroCounterOut, drflac_uint32 *pRiceParamPartOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:52752
drflac_metadata::pRawData
const void * pRawData
Definition: porcupine/demo/c/dr_libs/dr_flac.h:422
drflac__init_private__native
static drflac_bool32 drflac__init_private__native(drflac_init_info *pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void *pUserData, void *pUserDataMD, drflac_bool32 relaxed)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55194
drflac_open_memory_and_read_pcm_frames_f32
float * drflac_open_memory_and_read_pcm_frames_f32(const void *data, size_t dataSize, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59209
drflac_open_file_and_read_pcm_frames_s16
drflac_int16 * drflac_open_file_and_read_pcm_frames_s16(const char *filename, unsigned int *channels, unsigned int *sampleRate, drflac_uint64 *totalPCMFrameCount, const drflac_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:59136
drflac_seekpoint::pcmFrameCount
drflac_uint16 pcmFrameCount
Definition: porcupine/demo/c/dr_libs/dr_flac.h:392
drflac_read_pcm_frames_s32
drflac_uint64 drflac_read_pcm_frames_s32(drflac *pFlac, drflac_uint64 framesToRead, drflac_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:57386
drflac_crc16_bytes
static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51729
drflac_result
drflac_int32 drflac_result
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51356
drflac_cuesheet_track_iterator::pRunningData
const char * pRunningData
Definition: porcupine/demo/c/dr_libs/dr_flac.h:1280
drflac_container
drflac_container
Definition: porcupine/demo/c/dr_libs/dr_flac.h:373
drflac_meta_proc
void(* drflac_meta_proc)(void *pUserData, drflac_metadata *pMetadata)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:475
drflac_init_info::oggFirstBytePos
drflac_uint64 oggFirstBytePos
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54808
drflac_metadata
Definition: porcupine/demo/c/dr_libs/dr_flac.h:409
drflac_seek_to_pcm_frame
drflac_bool32 drflac_seek_to_pcm_frame(drflac *pFlac, drflac_uint64 pcmFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:58917
drflac__seek_flac_frame
static drflac_result drflac__seek_flac_frame(drflac *pFlac)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:54335
drflac_bs::consumedBits
drflac_uint32 consumedBits
Definition: porcupine/demo/c/dr_libs/dr_flac.h:607
drflac_container_ogg
@ drflac_container_ogg
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/dr_flac.h:331
drflac__on_read_ogg
static size_t drflac__on_read_ogg(void *pUserData, void *bufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:55591
drflac_allocation_callbacks::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/dr_flac.h:566
drflac::allocationCallbacks
drflac_allocation_callbacks allocationCallbacks
Definition: porcupine/demo/c/dr_libs/dr_flac.h:697


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:50