Coverage Report

Created: 2026-09-14 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dr_libs/dr_flac.h
Line
Count
Source
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.13.4 - TBD
4
5
David Reid - mackron@gmail.com
6
7
GitHub: https://github.com/mackron/dr_libs
8
*/
9
10
/*
11
Introduction
12
============
13
dr_flac is a single file library. To use it, do something like the following in one .c file.
14
15
    ```c
16
    #define DR_FLAC_IMPLEMENTATION
17
    #include "dr_flac.h"
18
    ```
19
20
You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:
21
22
    ```c
23
    drflac* pFlac = drflac_open_file("MySong.flac", NULL);
24
    if (pFlac == NULL) {
25
        // Failed to open FLAC file
26
    }
27
28
    drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32));
29
    drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples);
30
    ```
31
32
The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of channels and the bits per sample,
33
should be directly accessible - just make sure you don't change their values. Samples are always output as interleaved signed 32-bit PCM. In the example above
34
a native FLAC stream was opened, however dr_flac has seamless support for Ogg encapsulated FLAC streams as well.
35
36
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 the decoder will give you as many
37
samples as it can, up to the amount requested. Later on when you need the next batch of samples, just call it again. Example:
38
39
    ```c
40
    while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) {
41
        do_something();
42
    }
43
    ```
44
45
You can seek to a specific PCM frame with `drflac_seek_to_pcm_frame()`.
46
47
If you just want to quickly decode an entire FLAC file in one go you can do something like this:
48
49
    ```c
50
    unsigned int channels;
51
    unsigned int sampleRate;
52
    drflac_uint64 totalPCMFrameCount;
53
    drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount, NULL);
54
    if (pSampleData == NULL) {
55
        // Failed to open and decode FLAC file.
56
    }
57
58
    ...
59
60
    drflac_free(pSampleData, NULL);
61
    ```
62
63
You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs respectively, but note that these
64
should be considered lossy.
65
66
67
If you need access to metadata (album art, etc.), use `drflac_open_with_metadata()`, `drflac_open_file_with_metdata()` or `drflac_open_memory_with_metadata()`.
68
The rationale for keeping these APIs separate is that they're slightly slower than the normal versions and also just a little bit harder to use. dr_flac
69
reports metadata to the application through the use of a callback, and every metadata block is reported before `drflac_open_with_metdata()` returns.
70
71
The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
72
streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
73
74
    `drflac_open_relaxed()`
75
    `drflac_open_with_metadata_relaxed()`
76
77
It is not recommended to use these APIs for file based streams because a missing header would usually indicate a corrupt or perverse file. In addition, these
78
APIs can take a long time to initialize because they may need to spend a lot of time finding the first frame.
79
80
81
82
Build Options
83
=============
84
#define these options before including this file.
85
86
#define DR_FLAC_NO_STDIO
87
  Disable `drflac_open_file()` and family.
88
89
#define DR_FLAC_NO_OGG
90
  Disables support for Ogg/FLAC streams.
91
92
#define DR_FLAC_BUFFER_SIZE <number>
93
  Defines the size of the internal buffer to store data from onRead(). This buffer is used to reduce the number of calls back to the client for more data.
94
  Larger values means more memory, but better performance. My tests show diminishing returns after about 4KB (which is the default). Consider reducing this if
95
  you have a very efficient implementation of onRead(), or increase it if it's very inefficient. Must be a multiple of 8.
96
97
#define DR_FLAC_NO_CRC
98
  Disables CRC checks. This will offer a performance boost when CRC is unnecessary. This will disable binary search seeking. When seeking, the seek table will
99
  be used if available. Otherwise the seek will be performed using brute force.
100
101
#define DR_FLAC_NO_SIMD
102
  Disables SIMD optimizations (SSE on x86/x64 architectures, NEON on ARM architectures). Use this if you are having compatibility issues with your compiler.
103
104
#define DR_FLAC_NO_WCHAR
105
  Disables all functions ending with `_w`. Use this if your compiler does not provide wchar.h. Not required if DR_FLAC_NO_STDIO is also defined.
106
107
108
109
Notes
110
=====
111
- dr_flac does not support changing the sample rate nor channel count mid stream.
112
- dr_flac is not thread-safe, but its APIs can be called from any thread so long as you do your own synchronization.
113
- When using Ogg encapsulation, a corrupted metadata block will result in `drflac_open_with_metadata()` and `drflac_open()` returning inconsistent samples due
114
  to differences in corrupted stream recorvery logic between the two APIs.
115
*/
116
117
#ifndef dr_flac_h
118
#define dr_flac_h
119
120
#ifdef __cplusplus
121
extern "C" {
122
#endif
123
124
0
#define DRFLAC_STRINGIFY(x)      #x
125
0
#define DRFLAC_XSTRINGIFY(x)     DRFLAC_STRINGIFY(x)
126
127
0
#define DRFLAC_VERSION_MAJOR     0
128
0
#define DRFLAC_VERSION_MINOR     13
129
0
#define DRFLAC_VERSION_REVISION  4
130
0
#define DRFLAC_VERSION_STRING    DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
131
132
#include <stddef.h> /* For size_t. */
133
134
/* Sized Types */
135
typedef   signed char           drflac_int8;
136
typedef unsigned char           drflac_uint8;
137
typedef   signed short          drflac_int16;
138
typedef unsigned short          drflac_uint16;
139
typedef   signed int            drflac_int32;
140
typedef unsigned int            drflac_uint32;
141
#if defined(_MSC_VER) && !defined(__clang__)
142
    typedef   signed __int64    drflac_int64;
143
    typedef unsigned __int64    drflac_uint64;
144
#else
145
    #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
146
        #pragma GCC diagnostic push
147
        #pragma GCC diagnostic ignored "-Wlong-long"
148
        #if defined(__clang__)
149
            #pragma GCC diagnostic ignored "-Wc++11-long-long"
150
        #endif
151
    #endif
152
    typedef   signed long long  drflac_int64;
153
    typedef unsigned long long  drflac_uint64;
154
    #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
155
        #pragma GCC diagnostic pop
156
    #endif
157
#endif
158
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
159
    typedef drflac_uint64       drflac_uintptr;
160
#else
161
    typedef drflac_uint32       drflac_uintptr;
162
#endif
163
typedef drflac_uint8            drflac_bool8;
164
typedef drflac_uint32           drflac_bool32;
165
0
#define DRFLAC_TRUE             1
166
0
#define DRFLAC_FALSE            0
167
/* End Sized Types */
168
169
/* Decorations */
170
#if !defined(DRFLAC_API)
171
    #if defined(DRFLAC_DLL)
172
        #if defined(_WIN32)
173
            #define DRFLAC_DLL_IMPORT  __declspec(dllimport)
174
            #define DRFLAC_DLL_EXPORT  __declspec(dllexport)
175
            #define DRFLAC_DLL_PRIVATE static
176
        #else
177
            #if defined(__GNUC__) && __GNUC__ >= 4
178
                #define DRFLAC_DLL_IMPORT  __attribute__((visibility("default")))
179
                #define DRFLAC_DLL_EXPORT  __attribute__((visibility("default")))
180
                #define DRFLAC_DLL_PRIVATE __attribute__((visibility("hidden")))
181
            #else
182
                #define DRFLAC_DLL_IMPORT
183
                #define DRFLAC_DLL_EXPORT
184
                #define DRFLAC_DLL_PRIVATE static
185
            #endif
186
        #endif
187
188
        #if defined(DR_FLAC_IMPLEMENTATION) || defined(DRFLAC_IMPLEMENTATION)
189
            #define DRFLAC_API  DRFLAC_DLL_EXPORT
190
        #else
191
            #define DRFLAC_API  DRFLAC_DLL_IMPORT
192
        #endif
193
        #define DRFLAC_PRIVATE DRFLAC_DLL_PRIVATE
194
    #else
195
        #define DRFLAC_API extern
196
        #define DRFLAC_PRIVATE static
197
    #endif
198
#endif
199
/* End Decorations */
200
201
#if defined(_MSC_VER) && _MSC_VER >= 1700   /* Visual Studio 2012 */
202
    #define DRFLAC_DEPRECATED       __declspec(deprecated)
203
#elif (defined(__GNUC__) && __GNUC__ >= 4)  /* GCC 4 */
204
    #define DRFLAC_DEPRECATED       __attribute__((deprecated))
205
#elif defined(__has_feature)                /* Clang */
206
    #if __has_feature(attribute_deprecated)
207
        #define DRFLAC_DEPRECATED   __attribute__((deprecated))
208
    #else
209
        #define DRFLAC_DEPRECATED
210
    #endif
211
#else
212
    #define DRFLAC_DEPRECATED
213
#endif
214
215
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision);
216
DRFLAC_API const char* drflac_version_string(void);
217
218
/* Allocation Callbacks */
219
typedef struct
220
{
221
    void* pUserData;
222
    void* (* onMalloc)(size_t sz, void* pUserData);
223
    void* (* onRealloc)(void* p, size_t sz, void* pUserData);
224
    void  (* onFree)(void* p, void* pUserData);
225
} drflac_allocation_callbacks;
226
/* End Allocation Callbacks */
227
228
/*
229
As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed,
230
but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8.
231
*/
232
#ifndef DR_FLAC_BUFFER_SIZE
233
#define DR_FLAC_BUFFER_SIZE   4096
234
#endif
235
236
237
/* Architecture Detection */
238
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
239
#define DRFLAC_64BIT
240
#endif
241
242
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
243
    #define DRFLAC_X64
244
#elif defined(__i386) || defined(_M_IX86)
245
    #define DRFLAC_X86
246
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
247
    #define DRFLAC_ARM
248
#endif
249
/* End Architecture Detection */
250
251
252
#ifdef DRFLAC_64BIT
253
typedef drflac_uint64 drflac_cache_t;
254
#else
255
typedef drflac_uint32 drflac_cache_t;
256
#endif
257
258
/* The various metadata block types. */
259
0
#define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO       0
260
0
#define DRFLAC_METADATA_BLOCK_TYPE_PADDING          1
261
0
#define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION      2
262
0
#define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE        3
263
0
#define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT   4
264
0
#define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET         5
265
0
#define DRFLAC_METADATA_BLOCK_TYPE_PICTURE          6
266
0
#define DRFLAC_METADATA_BLOCK_TYPE_INVALID          127
267
268
/* The various picture types specified in the PICTURE block. */
269
#define DRFLAC_PICTURE_TYPE_OTHER                   0
270
#define DRFLAC_PICTURE_TYPE_FILE_ICON               1
271
#define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON         2
272
#define DRFLAC_PICTURE_TYPE_COVER_FRONT             3
273
#define DRFLAC_PICTURE_TYPE_COVER_BACK              4
274
#define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE            5
275
#define DRFLAC_PICTURE_TYPE_MEDIA                   6
276
#define DRFLAC_PICTURE_TYPE_LEAD_ARTIST             7
277
#define DRFLAC_PICTURE_TYPE_ARTIST                  8
278
#define DRFLAC_PICTURE_TYPE_CONDUCTOR               9
279
#define DRFLAC_PICTURE_TYPE_BAND                    10
280
#define DRFLAC_PICTURE_TYPE_COMPOSER                11
281
#define DRFLAC_PICTURE_TYPE_LYRICIST                12
282
#define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION      13
283
#define DRFLAC_PICTURE_TYPE_DURING_RECORDING        14
284
#define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE      15
285
#define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE          16
286
#define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH     17
287
#define DRFLAC_PICTURE_TYPE_ILLUSTRATION            18
288
#define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE           19
289
#define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE      20
290
291
typedef enum
292
{
293
    drflac_container_native,
294
    drflac_container_ogg,
295
    drflac_container_unknown
296
} drflac_container;
297
298
typedef enum
299
{
300
    DRFLAC_SEEK_SET,
301
    DRFLAC_SEEK_CUR,
302
    DRFLAC_SEEK_END
303
} drflac_seek_origin;
304
305
/* The order of members in this structure is important because we map this directly to the raw data within the SEEKTABLE metadata block. */
306
typedef struct
307
{
308
    drflac_uint64 firstPCMFrame;
309
    drflac_uint64 flacFrameOffset;   /* The offset from the first byte of the header of the first frame. */
310
    drflac_uint16 pcmFrameCount;
311
} drflac_seekpoint;
312
313
typedef struct
314
{
315
    drflac_uint16 minBlockSizeInPCMFrames;
316
    drflac_uint16 maxBlockSizeInPCMFrames;
317
    drflac_uint32 minFrameSizeInPCMFrames;
318
    drflac_uint32 maxFrameSizeInPCMFrames;
319
    drflac_uint32 sampleRate;
320
    drflac_uint8  channels;
321
    drflac_uint8  bitsPerSample;
322
    drflac_uint64 totalPCMFrameCount;
323
    drflac_uint8  md5[16];
324
} drflac_streaminfo;
325
326
typedef struct
327
{
328
    /*
329
    The metadata type. Use this to know how to interpret the data below. Will be set to one of the
330
    DRFLAC_METADATA_BLOCK_TYPE_* tokens.
331
    */
332
    drflac_uint32 type;
333
334
    /* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
335
    drflac_uint32 rawDataSize;
336
337
    /* The offset in the stream of the raw data. */
338
    drflac_uint64 rawDataOffset;
339
340
    /*
341
    A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
342
    not modify the contents of this buffer. Use the structures below for more meaningful and structured
343
    information about the metadata. It's possible for this to be null.
344
    */
345
    const void* pRawData;
346
347
    union
348
    {
349
        drflac_streaminfo streaminfo;
350
351
        struct
352
        {
353
            int unused;
354
        } padding;
355
356
        struct
357
        {
358
            drflac_uint32 id;
359
            const void* pData;
360
            drflac_uint32 dataSize;
361
        } application;
362
363
        struct
364
        {
365
            drflac_uint32 seekpointCount;
366
            const drflac_seekpoint* pSeekpoints;
367
        } seektable;
368
369
        struct
370
        {
371
            drflac_uint32 vendorLength;
372
            const char* vendor;
373
            drflac_uint32 commentCount;
374
            const void* pComments;
375
        } vorbis_comment;
376
377
        struct
378
        {
379
            char catalog[128];
380
            drflac_uint64 leadInSampleCount;
381
            drflac_bool32 isCD;
382
            drflac_uint8 trackCount;
383
            const void* pTrackData;
384
        } cuesheet;
385
386
        struct
387
        {
388
            drflac_uint32 type;
389
            drflac_uint32 mimeLength;
390
            const char* mime;
391
            drflac_uint32 descriptionLength;
392
            const char* description;
393
            drflac_uint32 width;
394
            drflac_uint32 height;
395
            drflac_uint32 colorDepth;
396
            drflac_uint32 indexColorCount;
397
            drflac_uint32 pictureDataSize;
398
            drflac_uint64 pictureDataOffset;  /* Offset from the start of the stream. */
399
            const drflac_uint8* pPictureData;
400
        } picture;
401
    } data;
402
} drflac_metadata;
403
404
405
/*
406
Callback for when data needs to be read from the client.
407
408
409
Parameters
410
----------
411
pUserData (in)
412
    The user data that was passed to drflac_open() and family.
413
414
pBufferOut (out)
415
    The output buffer.
416
417
bytesToRead (in)
418
    The number of bytes to read.
419
420
421
Return Value
422
------------
423
The number of bytes actually read.
424
425
426
Remarks
427
-------
428
A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until either the entire bytesToRead is filled or
429
you have reached the end of the stream.
430
*/
431
typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
432
433
/*
434
Callback for when data needs to be seeked.
435
436
437
Parameters
438
----------
439
pUserData (in)
440
    The user data that was passed to drflac_open() and family.
441
442
offset (in)
443
    The number of bytes to move, relative to the origin. Will never be negative.
444
445
origin (in)
446
    The origin of the seek - the current position, the start of the stream, or the end of the stream.
447
448
449
Return Value
450
------------
451
Whether or not the seek was successful.
452
453
454
Remarks
455
-------
456
Seeking relative to the start and the current position must always be supported. If seeking from the end of the stream is not supported, return DRFLAC_FALSE.
457
458
When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
459
and handled by returning DRFLAC_FALSE.
460
*/
461
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
462
463
/*
464
Callback for when the current position in the stream needs to be retrieved.
465
466
467
Parameters
468
----------
469
pUserData (in)
470
    The user data that was passed to drflac_open() and family.
471
472
pCursor (out)
473
    A pointer to a variable to receive the current position in the stream.
474
475
476
Return Value
477
------------
478
Whether or not the operation was successful.
479
*/
480
typedef drflac_bool32 (* drflac_tell_proc)(void* pUserData, drflac_int64* pCursor);
481
482
/*
483
Callback for when a metadata block is read.
484
485
486
Parameters
487
----------
488
pUserData (in)
489
    The user data that was passed to drflac_open() and family.
490
491
pMetadata (in)
492
    A pointer to a structure containing the data of the metadata block.
493
494
495
Remarks
496
-------
497
Use pMetadata->type to determine which metadata block is being handled and how to read the data. This
498
will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
499
*/
500
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
501
502
503
/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
504
typedef struct
505
{
506
    const drflac_uint8* data;
507
    size_t dataSize;
508
    size_t currentReadPos;
509
} drflac__memory_stream;
510
511
/* Structure for internal use. Used for bit streaming. */
512
typedef struct
513
{
514
    /* The function to call when more data needs to be read. */
515
    drflac_read_proc onRead;
516
517
    /* The function to call when the current read position needs to be moved. */
518
    drflac_seek_proc onSeek;
519
520
    /* The function to call when the current read position needs to be retrieved. */
521
    drflac_tell_proc onTell;
522
523
    /* The user data to pass around to onRead and onSeek. */
524
    void* pUserData;
525
526
527
    /*
528
    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
529
    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
530
    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).
531
    */
532
    size_t unalignedByteCount;
533
534
    /* The content of the unaligned bytes. */
535
    drflac_cache_t unalignedCache;
536
537
    /* The index of the next valid cache line in the "L2" cache. */
538
    drflac_uint32 nextL2Line;
539
540
    /* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */
541
    drflac_uint32 consumedBits;
542
543
    /*
544
    The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
545
    Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
546
    */
547
    drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
548
    drflac_cache_t cache;
549
550
    /*
551
    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
552
    is reset to 0 at the beginning of each frame.
553
    */
554
    drflac_uint16 crc16;
555
    drflac_cache_t crc16Cache;              /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
556
    drflac_uint32 crc16CacheIgnoredBytes;   /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
557
} drflac_bs;
558
559
typedef struct
560
{
561
    /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
562
    drflac_uint8 subframeType;
563
564
    /* The number of wasted bits per sample as specified by the sub-frame header. */
565
    drflac_uint8 wastedBitsPerSample;
566
567
    /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
568
    drflac_uint8 lpcOrder;
569
570
    /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
571
    drflac_int32* pSamplesS32;
572
} drflac_subframe;
573
574
typedef struct
575
{
576
    /*
577
    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
578
    always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
579
    */
580
    drflac_uint64 pcmFrameNumber;
581
582
    /*
583
    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
584
    is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
585
    */
586
    drflac_uint32 flacFrameNumber;
587
588
    /* The sample rate of this frame. */
589
    drflac_uint32 sampleRate;
590
591
    /* The number of PCM frames in each sub-frame within this frame. */
592
    drflac_uint16 blockSizeInPCMFrames;
593
594
    /*
595
    The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
596
    will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
597
    */
598
    drflac_uint8 channelAssignment;
599
600
    /* The number of bits per sample within this frame. */
601
    drflac_uint8 bitsPerSample;
602
603
    /* The frame's CRC. */
604
    drflac_uint8 crc8;
605
} drflac_frame_header;
606
607
typedef struct
608
{
609
    /* The header. */
610
    drflac_frame_header header;
611
612
    /*
613
    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,
614
    this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame.
615
    */
616
    drflac_uint32 pcmFramesRemaining;
617
618
    /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */
619
    drflac_subframe subframes[8];
620
} drflac_frame;
621
622
typedef struct
623
{
624
    /* The function to call when a metadata block is read. */
625
    drflac_meta_proc onMeta;
626
627
    /* The user data posted to the metadata callback function. */
628
    void* pUserDataMD;
629
630
    /* Memory allocation callbacks. */
631
    drflac_allocation_callbacks allocationCallbacks;
632
633
634
    /* The sample rate. Will be set to something like 44100. */
635
    drflac_uint32 sampleRate;
636
637
    /*
638
    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
639
    value specified in the STREAMINFO block.
640
    */
641
    drflac_uint8 channels;
642
643
    /* The bits per sample. Will be set to something like 16, 24, etc. */
644
    drflac_uint8 bitsPerSample;
645
646
    /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */
647
    drflac_uint16 maxBlockSizeInPCMFrames;
648
649
    /*
650
    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
651
    the total PCM frame count is unknown. Likely the case with streams like internet radio.
652
    */
653
    drflac_uint64 totalPCMFrameCount;
654
655
656
    /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */
657
    drflac_container container;
658
659
    /* The number of seekpoints in the seektable. */
660
    drflac_uint32 seekpointCount;
661
662
663
    /* Information about the frame the decoder is currently sitting on. */
664
    drflac_frame currentFLACFrame;
665
666
667
    /* The index of the PCM frame the decoder is currently sitting on. This is only used for seeking. */
668
    drflac_uint64 currentPCMFrame;
669
670
    /* The position of the first FLAC frame in the stream. This is only ever used for seeking. */
671
    drflac_uint64 firstFLACFramePosInBytes;
672
673
674
    /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */
675
    drflac__memory_stream memoryStream;
676
677
678
    /* A pointer to the decoded sample data. This is an offset of pExtraData. */
679
    drflac_int32* pDecodedSamples;
680
681
    /* A pointer to the seek table. This is an offset of pExtraData, or NULL if there is no seek table. */
682
    drflac_seekpoint* pSeekpoints;
683
684
    /* Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData. */
685
    void* _oggbs;
686
687
    /* Internal use only. Used for profiling and testing different seeking modes. */
688
    drflac_bool32 _noSeekTableSeek    : 1;
689
    drflac_bool32 _noBinarySearchSeek : 1;
690
    drflac_bool32 _noBruteForceSeek   : 1;
691
692
    /* The bit streamer. The raw FLAC data is fed through this object. */
693
    drflac_bs bs;
694
695
    /* Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs. */
696
    drflac_uint8 pExtraData[1];
697
} drflac;
698
699
700
/*
701
Opens a FLAC decoder.
702
703
704
Parameters
705
----------
706
onRead (in)
707
    The function to call when data needs to be read from the client.
708
709
onSeek (in)
710
    The function to call when the read position of the client data needs to move.
711
712
onTell (in)
713
    The function to call when the read position of the client needs to be queried.
714
715
pUserData (in, optional)
716
    A pointer to application defined data that will be passed to onRead and onSeek.
717
718
pAllocationCallbacks (in, optional)
719
    A pointer to application defined callbacks for managing memory allocations.
720
721
722
Return Value
723
------------
724
Returns a pointer to an object representing the decoder.
725
726
727
Remarks
728
-------
729
Close the decoder with `drflac_close()`.
730
731
`pAllocationCallbacks` can be NULL in which case it will use `DRFLAC_MALLOC`, `DRFLAC_REALLOC` and `DRFLAC_FREE`.
732
733
This function will automatically detect whether or not you are attempting to open a native or Ogg encapsulated FLAC, both of which should work seamlessly
734
without any manual intervention. Ogg encapsulation also works with multiplexed streams which basically means it can play FLAC encoded audio tracks in videos.
735
736
This is the lowest level function for opening a FLAC stream. You can also use `drflac_open_file()` and `drflac_open_memory()` to open the stream from a file or
737
from a block of memory respectively.
738
739
The STREAMINFO block must be present for this to succeed. Use `drflac_open_relaxed()` to open a FLAC stream where the header may not be present.
740
741
Use `drflac_open_with_metadata()` if you need access to metadata.
742
743
744
Seek Also
745
---------
746
drflac_open_file()
747
drflac_open_memory()
748
drflac_open_with_metadata()
749
drflac_close()
750
*/
751
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
752
753
/*
754
Opens a FLAC stream with relaxed validation of the header block.
755
756
757
Parameters
758
----------
759
onRead (in)
760
    The function to call when data needs to be read from the client.
761
762
onSeek (in)
763
    The function to call when the read position of the client data needs to move.
764
765
onTell (in)
766
    The function to call when the read position of the client needs to be queried.
767
768
container (in)
769
    Whether or not the FLAC stream is encapsulated using standard FLAC encapsulation or Ogg encapsulation.
770
771
pUserData (in, optional)
772
    A pointer to application defined data that will be passed to onRead and onSeek.
773
774
pAllocationCallbacks (in, optional)
775
    A pointer to application defined callbacks for managing memory allocations.
776
777
778
Return Value
779
------------
780
A pointer to an object representing the decoder.
781
782
783
Remarks
784
-------
785
The same as drflac_open(), except attempts to open the stream even when a header block is not present.
786
787
Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do not set this to `drflac_container_unknown`
788
as that is for internal use only.
789
790
Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never found it will continue forever. To abort,
791
force your `onRead` callback to return 0, which dr_flac will use as an indicator that the end of the stream was found.
792
793
Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
794
*/
795
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
796
797
/*
798
Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
799
800
801
Parameters
802
----------
803
onRead (in)
804
    The function to call when data needs to be read from the client.
805
806
onSeek (in)
807
    The function to call when the read position of the client data needs to move.
808
809
onTell (in)
810
    The function to call when the read position of the client needs to be queried.
811
812
onMeta (in)
813
    The function to call for every metadata block.
814
815
pUserData (in, optional)
816
    A pointer to application defined data that will be passed to onRead, onSeek and onMeta.
817
818
pAllocationCallbacks (in, optional)
819
    A pointer to application defined callbacks for managing memory allocations.
820
821
822
Return Value
823
------------
824
A pointer to an object representing the decoder.
825
826
827
Remarks
828
-------
829
Close the decoder with `drflac_close()`.
830
831
`pAllocationCallbacks` can be NULL in which case it will use `DRFLAC_MALLOC`, `DRFLAC_REALLOC` and `DRFLAC_FREE`.
832
833
This is slower than `drflac_open()`, so avoid this one if you don't need metadata. Internally, this will allocate and free memory on the heap for every
834
metadata block except for STREAMINFO and PADDING blocks.
835
836
The caller is notified of the metadata via the `onMeta` callback. All metadata blocks will be handled before the function returns. This callback takes a
837
pointer to a `drflac_metadata` object which is a union containing the data of all relevant metadata blocks. Use the `type` member to discriminate against
838
the different metadata types.
839
840
The STREAMINFO block must be present for this to succeed. Use `drflac_open_with_metadata_relaxed()` to open a FLAC stream where the header may not be present.
841
842
Note that this will behave inconsistently with `drflac_open()` if the stream is an Ogg encapsulated stream and a metadata block is corrupted. This is due to
843
the way the Ogg stream recovers from corrupted pages. When `drflac_open_with_metadata()` is being used, the open routine will try to read the contents of the
844
metadata block, whereas `drflac_open()` will simply seek past it (for the sake of efficiency). This inconsistency can result in different samples being
845
returned depending on whether or not the stream is being opened with metadata.
846
847
848
Seek Also
849
---------
850
drflac_open_file_with_metadata()
851
drflac_open_memory_with_metadata()
852
drflac_open()
853
drflac_close()
854
*/
855
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
856
857
/*
858
The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present.
859
860
See Also
861
--------
862
drflac_open_with_metadata()
863
drflac_open_relaxed()
864
*/
865
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
866
867
/*
868
Closes the given FLAC decoder.
869
870
871
Parameters
872
----------
873
pFlac (in)
874
    The decoder to close.
875
876
877
Remarks
878
-------
879
This will destroy the decoder object.
880
881
882
See Also
883
--------
884
drflac_open()
885
drflac_open_with_metadata()
886
drflac_open_file()
887
drflac_open_file_w()
888
drflac_open_file_with_metadata()
889
drflac_open_file_with_metadata_w()
890
drflac_open_memory()
891
drflac_open_memory_with_metadata()
892
*/
893
DRFLAC_API void drflac_close(drflac* pFlac);
894
895
896
/*
897
Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM.
898
899
900
Parameters
901
----------
902
pFlac (in)
903
    The decoder.
904
905
framesToRead (in)
906
    The number of PCM frames to read.
907
908
pBufferOut (out, optional)
909
    A pointer to the buffer that will receive the decoded samples.
910
911
912
Return Value
913
------------
914
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
915
916
917
Remarks
918
-------
919
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
920
*/
921
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);
922
923
924
/*
925
Reads sample data from the given FLAC decoder, output as interleaved signed 16-bit PCM.
926
927
928
Parameters
929
----------
930
pFlac (in)
931
    The decoder.
932
933
framesToRead (in)
934
    The number of PCM frames to read.
935
936
pBufferOut (out, optional)
937
    A pointer to the buffer that will receive the decoded samples.
938
939
940
Return Value
941
------------
942
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
943
944
945
Remarks
946
-------
947
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
948
949
Note that this is lossy for streams where the bits per sample is larger than 16.
950
*/
951
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);
952
953
/*
954
Reads sample data from the given FLAC decoder, output as interleaved 32-bit floating point PCM.
955
956
957
Parameters
958
----------
959
pFlac (in)
960
    The decoder.
961
962
framesToRead (in)
963
    The number of PCM frames to read.
964
965
pBufferOut (out, optional)
966
    A pointer to the buffer that will receive the decoded samples.
967
968
969
Return Value
970
------------
971
Returns the number of PCM frames actually read. If the return value is less than `framesToRead` it has reached the end.
972
973
974
Remarks
975
-------
976
pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames seeked.
977
978
Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly represent every possible number.
979
*/
980
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
981
982
/*
983
Seeks to the PCM frame at the given index.
984
985
986
Parameters
987
----------
988
pFlac (in)
989
    The decoder.
990
991
pcmFrameIndex (in)
992
    The index of the PCM frame to seek to. See notes below.
993
994
995
Return Value
996
-------------
997
`DRFLAC_TRUE` if successful; `DRFLAC_FALSE` otherwise.
998
*/
999
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
1000
1001
1002
1003
#ifndef DR_FLAC_NO_STDIO
1004
/*
1005
Opens a FLAC decoder from the file at the given path.
1006
1007
1008
Parameters
1009
----------
1010
pFileName (in)
1011
    The path of the file to open, either absolute or relative to the current directory.
1012
1013
pAllocationCallbacks (in, optional)
1014
    A pointer to application defined callbacks for managing memory allocations.
1015
1016
1017
Return Value
1018
------------
1019
A pointer to an object representing the decoder.
1020
1021
1022
Remarks
1023
-------
1024
Close the decoder with drflac_close().
1025
1026
1027
Remarks
1028
-------
1029
This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the number of files a process can have open
1030
at any given time, so keep this mind if you have many decoders open at the same time.
1031
1032
1033
See Also
1034
--------
1035
drflac_open_file_with_metadata()
1036
drflac_open()
1037
drflac_close()
1038
*/
1039
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
1040
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
1041
1042
/*
1043
Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.)
1044
1045
1046
Parameters
1047
----------
1048
pFileName (in)
1049
    The path of the file to open, either absolute or relative to the current directory.
1050
1051
pAllocationCallbacks (in, optional)
1052
    A pointer to application defined callbacks for managing memory allocations.
1053
1054
onMeta (in)
1055
    The callback to fire for each metadata block.
1056
1057
pUserData (in)
1058
    A pointer to the user data to pass to the metadata callback.
1059
1060
pAllocationCallbacks (in)
1061
    A pointer to application defined callbacks for managing memory allocations.
1062
1063
1064
Remarks
1065
-------
1066
Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
1067
1068
1069
See Also
1070
--------
1071
drflac_open_with_metadata()
1072
drflac_open()
1073
drflac_close()
1074
*/
1075
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1076
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1077
#endif
1078
1079
/*
1080
Opens a FLAC decoder from a pre-allocated block of memory
1081
1082
1083
Parameters
1084
----------
1085
pData (in)
1086
    A pointer to the raw encoded FLAC data.
1087
1088
dataSize (in)
1089
    The size in bytes of `data`.
1090
1091
pAllocationCallbacks (in)
1092
    A pointer to application defined callbacks for managing memory allocations.
1093
1094
1095
Return Value
1096
------------
1097
A pointer to an object representing the decoder.
1098
1099
1100
Remarks
1101
-------
1102
This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for the lifetime of the decoder.
1103
1104
1105
See Also
1106
--------
1107
drflac_open()
1108
drflac_close()
1109
*/
1110
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
1111
1112
/*
1113
Opens a FLAC decoder from a pre-allocated block of memory and notifies the caller of the metadata chunks (album art, etc.)
1114
1115
1116
Parameters
1117
----------
1118
pData (in)
1119
    A pointer to the raw encoded FLAC data.
1120
1121
dataSize (in)
1122
    The size in bytes of `data`.
1123
1124
onMeta (in)
1125
    The callback to fire for each metadata block.
1126
1127
pUserData (in)
1128
    A pointer to the user data to pass to the metadata callback.
1129
1130
pAllocationCallbacks (in)
1131
    A pointer to application defined callbacks for managing memory allocations.
1132
1133
1134
Remarks
1135
-------
1136
Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
1137
1138
1139
See Also
1140
-------
1141
drflac_open_with_metadata()
1142
drflac_open()
1143
drflac_close()
1144
*/
1145
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
1146
1147
1148
1149
/* High Level APIs */
1150
1151
/*
1152
Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a
1153
pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with drflac_free().
1154
1155
You can pass in custom memory allocation callbacks via the pAllocationCallbacks parameter. This can be NULL in which
1156
case it will use DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
1157
1158
Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously
1159
read samples into a dynamically sized buffer on the heap until no samples are left.
1160
1161
Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
1162
*/
1163
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1164
1165
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1166
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1167
1168
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1169
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
1170
1171
#ifndef DR_FLAC_NO_STDIO
1172
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
1173
DRFLAC_API 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);
1174
1175
/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1176
DRFLAC_API 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);
1177
1178
/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1179
DRFLAC_API 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);
1180
#endif
1181
1182
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
1183
DRFLAC_API 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);
1184
1185
/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
1186
DRFLAC_API 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);
1187
1188
/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
1189
DRFLAC_API 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);
1190
1191
/*
1192
Frees memory that was allocated internally by dr_flac.
1193
1194
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.
1195
*/
1196
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
1197
1198
1199
/* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */
1200
typedef struct
1201
{
1202
    drflac_uint32 countRemaining;
1203
    const char* pRunningData;
1204
} drflac_vorbis_comment_iterator;
1205
1206
/*
1207
Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT
1208
metadata block.
1209
*/
1210
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
1211
1212
/*
1213
Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The
1214
returned string is NOT null terminated.
1215
*/
1216
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
1217
1218
1219
/* Structure representing an iterator for cuesheet tracks in a CUESHEET metadata block. */
1220
typedef struct
1221
{
1222
    drflac_uint32 countRemaining;
1223
    const char* pRunningData;
1224
} drflac_cuesheet_track_iterator;
1225
1226
/* The order of members here is important because we map this directly to the raw data within the CUESHEET metadata block. */
1227
typedef struct
1228
{
1229
    drflac_uint64 offset;
1230
    drflac_uint8 index;
1231
    drflac_uint8 reserved[3];
1232
} drflac_cuesheet_track_index;
1233
1234
typedef struct
1235
{
1236
    drflac_uint64 offset;
1237
    drflac_uint8 trackNumber;
1238
    char ISRC[12];
1239
    drflac_bool8 isAudio;
1240
    drflac_bool8 preEmphasis;
1241
    drflac_uint8 indexCount;
1242
    const drflac_cuesheet_track_index* pIndexPoints;
1243
} drflac_cuesheet_track;
1244
1245
/*
1246
Initializes a cuesheet track iterator. This can be used for iterating over the cuesheet tracks in a CUESHEET metadata
1247
block.
1248
*/
1249
DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData);
1250
1251
/* Goes to the next cuesheet track in the given iterator. If DRFLAC_FALSE is returned it means there are no more comments. */
1252
DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack);
1253
1254
1255
#ifdef __cplusplus
1256
}
1257
#endif
1258
#endif  /* dr_flac_h */
1259
1260
1261
/************************************************************************************************************************************************************
1262
 ************************************************************************************************************************************************************
1263
1264
 IMPLEMENTATION
1265
1266
 ************************************************************************************************************************************************************
1267
 ************************************************************************************************************************************************************/
1268
#if defined(DR_FLAC_IMPLEMENTATION) || defined(DRFLAC_IMPLEMENTATION)
1269
#ifndef dr_flac_c
1270
#define dr_flac_c
1271
1272
/* Disable some annoying warnings. */
1273
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
1274
    #pragma GCC diagnostic push
1275
    #if __GNUC__ >= 7
1276
    #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
1277
    #endif
1278
#endif
1279
1280
#ifdef __linux__
1281
    #ifndef _BSD_SOURCE
1282
        #define _BSD_SOURCE
1283
    #endif
1284
    #ifndef _DEFAULT_SOURCE
1285
        #define _DEFAULT_SOURCE
1286
    #endif
1287
    #ifndef __USE_BSD
1288
        #define __USE_BSD
1289
    #endif
1290
    #include <endian.h>
1291
#endif
1292
1293
#include <stdlib.h>
1294
#include <string.h>
1295
1296
/* Inline */
1297
#ifdef _MSC_VER
1298
    #define DRFLAC_INLINE __forceinline
1299
#elif defined(__GNUC__)
1300
    /*
1301
    I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
1302
    the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
1303
    case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
1304
    command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
1305
    I am using "__inline__" only when we're compiling in strict ANSI mode.
1306
    */
1307
    #if defined(__STRICT_ANSI__)
1308
        #define DRFLAC_GNUC_INLINE_HINT __inline__
1309
    #else
1310
        #define DRFLAC_GNUC_INLINE_HINT inline
1311
    #endif
1312
1313
    #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
1314
        #define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT __attribute__((always_inline))
1315
    #else
1316
        #define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT
1317
    #endif
1318
#elif defined(__WATCOMC__)
1319
    #define DRFLAC_INLINE __inline
1320
#else
1321
    #define DRFLAC_INLINE
1322
#endif
1323
/* End Inline */
1324
1325
/*
1326
Intrinsics Support
1327
1328
There's a bug in GCC 4.2.x which results in an incorrect compilation error when using _mm_slli_epi32() where it complains with
1329
1330
    "error: shift must be an immediate"
1331
1332
Unfortuantely dr_flac depends on this for a few things so we're just going to disable SSE on GCC 4.2 and below.
1333
*/
1334
#if !defined(DR_FLAC_NO_SIMD)
1335
    #if defined(DRFLAC_X64) || defined(DRFLAC_X86)
1336
        #if defined(_MSC_VER) && !defined(__clang__)
1337
            /* MSVC. */
1338
            #if _MSC_VER >= 1400 && !defined(DRFLAC_NO_SSE2)    /* 2005 */
1339
                #define DRFLAC_SUPPORT_SSE2
1340
            #endif
1341
            #if _MSC_VER >= 1600 && !defined(DRFLAC_NO_SSE41)   /* 2010 */
1342
                #define DRFLAC_SUPPORT_SSE41
1343
            #endif
1344
        #elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
1345
            /* Assume GNUC-style. */
1346
            #if defined(__SSE2__) && !defined(DRFLAC_NO_SSE2)
1347
                #define DRFLAC_SUPPORT_SSE2
1348
            #endif
1349
            #if defined(__SSE4_1__) && !defined(DRFLAC_NO_SSE41)
1350
                #define DRFLAC_SUPPORT_SSE41
1351
            #endif
1352
        #endif
1353
1354
        /* If at this point we still haven't determined compiler support for the intrinsics just fall back to __has_include. */
1355
        #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include)
1356
            #if !defined(DRFLAC_SUPPORT_SSE2) && !defined(DRFLAC_NO_SSE2) && __has_include(<emmintrin.h>)
1357
                #define DRFLAC_SUPPORT_SSE2
1358
            #endif
1359
            #if !defined(DRFLAC_SUPPORT_SSE41) && !defined(DRFLAC_NO_SSE41) && __has_include(<smmintrin.h>)
1360
                #define DRFLAC_SUPPORT_SSE41
1361
            #endif
1362
        #endif
1363
1364
        #if defined(DRFLAC_SUPPORT_SSE41)
1365
            #include <smmintrin.h>
1366
        #elif defined(DRFLAC_SUPPORT_SSE2)
1367
            #include <emmintrin.h>
1368
        #endif
1369
    #endif
1370
1371
    #if defined(DRFLAC_ARM)
1372
        #if !defined(DRFLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1373
            #define DRFLAC_SUPPORT_NEON
1374
            #include <arm_neon.h>
1375
        #endif
1376
    #endif
1377
#endif
1378
1379
/* Compile-time CPU feature support. */
1380
#if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
1381
    #if defined(_MSC_VER) && !defined(__clang__)
1382
        #if _MSC_VER >= 1400
1383
            #include <intrin.h>
1384
            static void drflac__cpuid(int info[4], int fid)
1385
            {
1386
                __cpuid(info, fid);
1387
            }
1388
        #else
1389
            #define DRFLAC_NO_CPUID
1390
        #endif
1391
    #else
1392
        #if defined(__GNUC__) || defined(__clang__)
1393
            static void drflac__cpuid(int info[4], int fid)
1394
0
            {
1395
                /*
1396
                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
1397
                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
1398
                supporting different assembly dialects.
1399
1400
                What's basically happening is that we're saving and restoring the ebx register manually.
1401
                */
1402
                #if defined(DRFLAC_X86) && defined(__PIC__)
1403
                    __asm__ __volatile__ (
1404
                        "xchg{l} {%%}ebx, %k1;"
1405
                        "cpuid;"
1406
                        "xchg{l} {%%}ebx, %k1;"
1407
                        : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1408
                    );
1409
                #else
1410
0
                    __asm__ __volatile__ (
1411
0
                        "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
1412
0
                    );
1413
0
                #endif
1414
0
            }
1415
        #else
1416
            #define DRFLAC_NO_CPUID
1417
        #endif
1418
    #endif
1419
#else
1420
    #define DRFLAC_NO_CPUID
1421
#endif
1422
1423
static DRFLAC_INLINE drflac_bool32 drflac_has_sse2(void)
1424
0
{
1425
0
#if defined(DRFLAC_SUPPORT_SSE2)
1426
0
    #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE2)
1427
0
        #if defined(DRFLAC_X64)
1428
0
            return DRFLAC_TRUE;    /* 64-bit targets always support SSE2. */
1429
        #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)
1430
            return DRFLAC_TRUE;    /* If the compiler is allowed to freely generate SSE2 code we can assume support. */
1431
        #else
1432
            #if defined(DRFLAC_NO_CPUID)
1433
                return DRFLAC_FALSE;
1434
            #else
1435
                int info[4];
1436
                drflac__cpuid(info, 1);
1437
                return (info[3] & (1 << 26)) != 0;
1438
            #endif
1439
        #endif
1440
    #else
1441
        return DRFLAC_FALSE;       /* SSE2 is only supported on x86 and x64 architectures. */
1442
    #endif
1443
#else
1444
    return DRFLAC_FALSE;           /* No compiler support. */
1445
#endif
1446
0
}
1447
1448
static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
1449
0
{
1450
#if defined(DRFLAC_SUPPORT_SSE41)
1451
    #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41)
1452
        #if defined(__SSE4_1__) || defined(__AVX__)
1453
            return DRFLAC_TRUE;    /* If the compiler is allowed to freely generate SSE41 code we can assume support. */
1454
        #else
1455
            #if defined(DRFLAC_NO_CPUID)
1456
                return DRFLAC_FALSE;
1457
            #else
1458
                int info[4];
1459
                drflac__cpuid(info, 1);
1460
                return (info[2] & (1 << 19)) != 0;
1461
            #endif
1462
        #endif
1463
    #else
1464
        return DRFLAC_FALSE;       /* SSE41 is only supported on x86 and x64 architectures. */
1465
    #endif
1466
#else
1467
0
    return DRFLAC_FALSE;           /* No compiler support. */
1468
0
#endif
1469
0
}
1470
1471
1472
#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) && !defined(__clang__)
1473
    #define DRFLAC_HAS_LZCNT_INTRINSIC
1474
#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
1475
    #define DRFLAC_HAS_LZCNT_INTRINSIC
1476
#elif defined(__clang__)
1477
    #if defined(__has_builtin)
1478
        #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl)
1479
            #define DRFLAC_HAS_LZCNT_INTRINSIC
1480
        #endif
1481
    #endif
1482
#endif
1483
1484
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(__clang__)
1485
    #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1486
    #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1487
    #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1488
#elif defined(__clang__)
1489
    #if defined(__has_builtin)
1490
        #if __has_builtin(__builtin_bswap16)
1491
            #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1492
        #endif
1493
        #if __has_builtin(__builtin_bswap32)
1494
            #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1495
        #endif
1496
        #if __has_builtin(__builtin_bswap64)
1497
            #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1498
        #endif
1499
    #endif
1500
#elif defined(__GNUC__)
1501
    #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
1502
        #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1503
        #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1504
    #endif
1505
    #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
1506
        #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1507
    #endif
1508
#elif defined(__WATCOMC__) && defined(__386__)
1509
    #define DRFLAC_HAS_BYTESWAP16_INTRINSIC
1510
    #define DRFLAC_HAS_BYTESWAP32_INTRINSIC
1511
    #define DRFLAC_HAS_BYTESWAP64_INTRINSIC
1512
    extern __inline drflac_uint16 _watcom_bswap16(drflac_uint16);
1513
    extern __inline drflac_uint32 _watcom_bswap32(drflac_uint32);
1514
    extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
1515
#pragma aux _watcom_bswap16 = \
1516
    "xchg al, ah" \
1517
    parm  [ax]    \
1518
    value [ax]    \
1519
    modify nomemory;
1520
#pragma aux _watcom_bswap32 = \
1521
    "bswap eax" \
1522
    parm  [eax] \
1523
    value [eax] \
1524
    modify nomemory;
1525
#pragma aux _watcom_bswap64 = \
1526
    "bswap eax"     \
1527
    "bswap edx"     \
1528
    "xchg eax,edx"  \
1529
    parm [eax edx]  \
1530
    value [eax edx] \
1531
    modify nomemory;
1532
#endif
1533
1534
1535
/* Standard library stuff. */
1536
#ifndef DRFLAC_ASSERT
1537
#include <assert.h>
1538
0
#define DRFLAC_ASSERT(expression)           assert(expression)
1539
#endif
1540
#ifndef DRFLAC_MALLOC
1541
0
#define DRFLAC_MALLOC(sz)                   malloc((sz))
1542
#endif
1543
#ifndef DRFLAC_REALLOC
1544
0
#define DRFLAC_REALLOC(p, sz)               realloc((p), (sz))
1545
#endif
1546
#ifndef DRFLAC_FREE
1547
0
#define DRFLAC_FREE(p)                      free((p))
1548
#endif
1549
#ifndef DRFLAC_COPY_MEMORY
1550
0
#define DRFLAC_COPY_MEMORY(dst, src, sz)    memcpy((dst), (src), (sz))
1551
#endif
1552
#ifndef DRFLAC_ZERO_MEMORY
1553
0
#define DRFLAC_ZERO_MEMORY(p, sz)           memset((p), 0, (sz))
1554
#endif
1555
#ifndef DRFLAC_ZERO_OBJECT
1556
0
#define DRFLAC_ZERO_OBJECT(p)               DRFLAC_ZERO_MEMORY((p), sizeof(*(p)))
1557
#endif
1558
1559
#define DRFLAC_MIN(a, b)                    (((a) < (b)) ? (a) : (b))
1560
1561
0
#define DRFLAC_MAX_SIMD_VECTOR_SIZE                     64  /* 64 for AVX-512 in the future. */
1562
1563
/* Result Codes */
1564
typedef drflac_int32 drflac_result;
1565
0
#define DRFLAC_SUCCESS                                   0
1566
0
#define DRFLAC_ERROR                                    -1   /* A generic error. */
1567
0
#define DRFLAC_INVALID_ARGS                             -2
1568
0
#define DRFLAC_INVALID_OPERATION                        -3
1569
0
#define DRFLAC_OUT_OF_MEMORY                            -4
1570
0
#define DRFLAC_OUT_OF_RANGE                             -5
1571
0
#define DRFLAC_ACCESS_DENIED                            -6
1572
0
#define DRFLAC_DOES_NOT_EXIST                           -7
1573
0
#define DRFLAC_ALREADY_EXISTS                           -8
1574
0
#define DRFLAC_TOO_MANY_OPEN_FILES                      -9
1575
0
#define DRFLAC_INVALID_FILE                             -10
1576
0
#define DRFLAC_TOO_BIG                                  -11
1577
0
#define DRFLAC_PATH_TOO_LONG                            -12
1578
#define DRFLAC_NAME_TOO_LONG                            -13
1579
0
#define DRFLAC_NOT_DIRECTORY                            -14
1580
0
#define DRFLAC_IS_DIRECTORY                             -15
1581
0
#define DRFLAC_DIRECTORY_NOT_EMPTY                      -16
1582
#define DRFLAC_END_OF_FILE                              -17
1583
0
#define DRFLAC_NO_SPACE                                 -18
1584
0
#define DRFLAC_BUSY                                     -19
1585
0
#define DRFLAC_IO_ERROR                                 -20
1586
0
#define DRFLAC_INTERRUPT                                -21
1587
0
#define DRFLAC_UNAVAILABLE                              -22
1588
0
#define DRFLAC_ALREADY_IN_USE                           -23
1589
0
#define DRFLAC_BAD_ADDRESS                              -24
1590
0
#define DRFLAC_BAD_SEEK                                 -25
1591
0
#define DRFLAC_BAD_PIPE                                 -26
1592
0
#define DRFLAC_DEADLOCK                                 -27
1593
0
#define DRFLAC_TOO_MANY_LINKS                           -28
1594
0
#define DRFLAC_NOT_IMPLEMENTED                          -29
1595
0
#define DRFLAC_NO_MESSAGE                               -30
1596
0
#define DRFLAC_BAD_MESSAGE                              -31
1597
0
#define DRFLAC_NO_DATA_AVAILABLE                        -32
1598
0
#define DRFLAC_INVALID_DATA                             -33
1599
0
#define DRFLAC_TIMEOUT                                  -34
1600
0
#define DRFLAC_NO_NETWORK                               -35
1601
0
#define DRFLAC_NOT_UNIQUE                               -36
1602
0
#define DRFLAC_NOT_SOCKET                               -37
1603
0
#define DRFLAC_NO_ADDRESS                               -38
1604
0
#define DRFLAC_BAD_PROTOCOL                             -39
1605
0
#define DRFLAC_PROTOCOL_UNAVAILABLE                     -40
1606
0
#define DRFLAC_PROTOCOL_NOT_SUPPORTED                   -41
1607
0
#define DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED            -42
1608
0
#define DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED             -43
1609
0
#define DRFLAC_SOCKET_NOT_SUPPORTED                     -44
1610
0
#define DRFLAC_CONNECTION_RESET                         -45
1611
0
#define DRFLAC_ALREADY_CONNECTED                        -46
1612
0
#define DRFLAC_NOT_CONNECTED                            -47
1613
0
#define DRFLAC_CONNECTION_REFUSED                       -48
1614
0
#define DRFLAC_NO_HOST                                  -49
1615
0
#define DRFLAC_IN_PROGRESS                              -50
1616
0
#define DRFLAC_CANCELLED                                -51
1617
#define DRFLAC_MEMORY_ALREADY_MAPPED                    -52
1618
0
#define DRFLAC_AT_END                                   -53
1619
1620
0
#define DRFLAC_CRC_MISMATCH                             -100
1621
/* End Result Codes */
1622
1623
1624
0
#define DRFLAC_SUBFRAME_CONSTANT                        0
1625
0
#define DRFLAC_SUBFRAME_VERBATIM                        1
1626
0
#define DRFLAC_SUBFRAME_FIXED                           8
1627
0
#define DRFLAC_SUBFRAME_LPC                             32
1628
0
#define DRFLAC_SUBFRAME_RESERVED                        255
1629
1630
0
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE  0
1631
0
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1
1632
1633
0
#define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT           0
1634
0
#define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE             8
1635
0
#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE            9
1636
0
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE              10
1637
1638
0
#define DRFLAC_SEEKPOINT_SIZE_IN_BYTES                  18
1639
0
#define DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES             36
1640
0
#define DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES       12
1641
1642
0
#define drflac_align(x, a)                              ((((x) + (a) - 1) / (a)) * (a))
1643
1644
1645
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision)
1646
0
{
1647
0
    if (pMajor) {
1648
0
        *pMajor = DRFLAC_VERSION_MAJOR;
1649
0
    }
1650
1651
0
    if (pMinor) {
1652
0
        *pMinor = DRFLAC_VERSION_MINOR;
1653
0
    }
1654
1655
0
    if (pRevision) {
1656
0
        *pRevision = DRFLAC_VERSION_REVISION;
1657
0
    }
1658
0
}
1659
1660
DRFLAC_API const char* drflac_version_string(void)
1661
0
{
1662
0
    return DRFLAC_VERSION_STRING;
1663
0
}
1664
1665
1666
/* CPU caps. */
1667
#if defined(__has_feature)
1668
    #if __has_feature(thread_sanitizer)
1669
        #define DRFLAC_NO_THREAD_SANITIZE __attribute__((no_sanitize("thread")))
1670
    #else
1671
        #define DRFLAC_NO_THREAD_SANITIZE
1672
    #endif
1673
#else
1674
    #define DRFLAC_NO_THREAD_SANITIZE
1675
#endif
1676
1677
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1678
static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE;
1679
#endif
1680
1681
#ifndef DRFLAC_NO_CPUID
1682
static drflac_bool32 drflac__gIsSSE2Supported  = DRFLAC_FALSE;
1683
static drflac_bool32 drflac__gIsSSE41Supported = DRFLAC_FALSE;
1684
1685
/*
1686
I've had a bug report that Clang's ThreadSanitizer presents a warning in this function. Having reviewed this, this does
1687
actually make sense. However, since CPU caps should never differ for a running process, I don't think the trade off of
1688
complicating internal API's by passing around CPU caps versus just disabling the warnings is worthwhile. I'm therefore
1689
just going to disable these warnings. This is disabled via the DRFLAC_NO_THREAD_SANITIZE attribute.
1690
*/
1691
DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps(void)
1692
0
{
1693
0
    static drflac_bool32 isCPUCapsInitialized = DRFLAC_FALSE;
1694
1695
0
    if (!isCPUCapsInitialized) {
1696
        /* LZCNT */
1697
0
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
1698
0
        int info[4] = {0};
1699
0
        drflac__cpuid(info, 0x80000001);
1700
0
        drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0;
1701
0
#endif
1702
1703
        /* SSE2 */
1704
0
        drflac__gIsSSE2Supported = drflac_has_sse2();
1705
1706
        /* SSE4.1 */
1707
0
        drflac__gIsSSE41Supported = drflac_has_sse41();
1708
1709
        /* Initialized. */
1710
0
        isCPUCapsInitialized = DRFLAC_TRUE;
1711
0
    }
1712
0
}
1713
#else
1714
static drflac_bool32 drflac__gIsNEONSupported  = DRFLAC_FALSE;
1715
1716
static DRFLAC_INLINE drflac_bool32 drflac__has_neon(void)
1717
{
1718
#if defined(DRFLAC_SUPPORT_NEON)
1719
    #if defined(DRFLAC_ARM) && !defined(DRFLAC_NO_NEON)
1720
        #if (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
1721
            return DRFLAC_TRUE;    /* If the compiler is allowed to freely generate NEON code we can assume support. */
1722
        #else
1723
            /* TODO: Runtime check. */
1724
            return DRFLAC_FALSE;
1725
        #endif
1726
    #else
1727
        return DRFLAC_FALSE;       /* NEON is only supported on ARM architectures. */
1728
    #endif
1729
#else
1730
    return DRFLAC_FALSE;           /* No compiler support. */
1731
#endif
1732
}
1733
1734
DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps(void)
1735
{
1736
    drflac__gIsNEONSupported = drflac__has_neon();
1737
1738
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
1739
    drflac__gIsLZCNTSupported = DRFLAC_TRUE;
1740
#endif
1741
}
1742
#endif
1743
1744
1745
/* Endian Management */
1746
static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian(void)
1747
0
{
1748
0
#if defined(DRFLAC_X86) || defined(DRFLAC_X64)
1749
0
    return DRFLAC_TRUE;
1750
#elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
1751
    return DRFLAC_TRUE;
1752
#else
1753
    int n = 1;
1754
    return (*(char*)&n) == 1;
1755
#endif
1756
0
}
1757
1758
static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
1759
0
{
1760
0
#ifdef DRFLAC_HAS_BYTESWAP16_INTRINSIC
1761
    #if defined(_MSC_VER) && !defined(__clang__)
1762
        return _byteswap_ushort(n);
1763
    #elif defined(__GNUC__) || defined(__clang__)
1764
        return __builtin_bswap16(n);
1765
    #elif defined(__WATCOMC__) && defined(__386__)
1766
        return _watcom_bswap16(n);
1767
    #else
1768
        #error "This compiler does not support the byte swap intrinsic."
1769
    #endif
1770
#else
1771
    return ((n & 0xFF00) >> 8) |
1772
           ((n & 0x00FF) << 8);
1773
#endif
1774
0
}
1775
1776
static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
1777
0
{
1778
0
#ifdef DRFLAC_HAS_BYTESWAP32_INTRINSIC
1779
    #if defined(_MSC_VER) && !defined(__clang__)
1780
        return _byteswap_ulong(n);
1781
    #elif defined(__GNUC__) || defined(__clang__)
1782
        #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT)   /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
1783
            /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
1784
            drflac_uint32 r;
1785
            __asm__ __volatile__ (
1786
            #if defined(DRFLAC_64BIT)
1787
                "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! */
1788
            #else
1789
                "rev %[out], %[in]" : [out]"=r"(r) : [in]"r"(n)
1790
            #endif
1791
            );
1792
            return r;
1793
        #else
1794
0
            return __builtin_bswap32(n);
1795
0
        #endif
1796
    #elif defined(__WATCOMC__) && defined(__386__)
1797
        return _watcom_bswap32(n);
1798
    #else
1799
        #error "This compiler does not support the byte swap intrinsic."
1800
    #endif
1801
#else
1802
    return ((n & 0xFF000000) >> 24) |
1803
           ((n & 0x00FF0000) >>  8) |
1804
           ((n & 0x0000FF00) <<  8) |
1805
           ((n & 0x000000FF) << 24);
1806
#endif
1807
0
}
1808
1809
static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
1810
0
{
1811
0
#ifdef DRFLAC_HAS_BYTESWAP64_INTRINSIC
1812
    #if defined(_MSC_VER) && !defined(__clang__)
1813
        return _byteswap_uint64(n);
1814
    #elif defined(__GNUC__) || defined(__clang__)
1815
        return __builtin_bswap64(n);
1816
    #elif defined(__WATCOMC__) && defined(__386__)
1817
        return _watcom_bswap64(n);
1818
    #else
1819
        #error "This compiler does not support the byte swap intrinsic."
1820
    #endif
1821
#else
1822
    /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
1823
    return ((n & ((drflac_uint64)0xFF000000 << 32)) >> 56) |
1824
           ((n & ((drflac_uint64)0x00FF0000 << 32)) >> 40) |
1825
           ((n & ((drflac_uint64)0x0000FF00 << 32)) >> 24) |
1826
           ((n & ((drflac_uint64)0x000000FF << 32)) >>  8) |
1827
           ((n & ((drflac_uint64)0xFF000000      )) <<  8) |
1828
           ((n & ((drflac_uint64)0x00FF0000      )) << 24) |
1829
           ((n & ((drflac_uint64)0x0000FF00      )) << 40) |
1830
           ((n & ((drflac_uint64)0x000000FF      )) << 56);
1831
#endif
1832
0
}
1833
1834
1835
static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n)
1836
0
{
1837
0
    if (drflac__is_little_endian()) {
1838
0
        return drflac__swap_endian_uint16(n);
1839
0
    }
1840
1841
0
    return n;
1842
0
}
1843
1844
static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n)
1845
0
{
1846
0
    if (drflac__is_little_endian()) {
1847
0
        return drflac__swap_endian_uint32(n);
1848
0
    }
1849
1850
0
    return n;
1851
0
}
1852
1853
static DRFLAC_INLINE drflac_uint32 drflac__be2host_32_ptr_unaligned(const void* pData)
1854
0
{
1855
0
    const drflac_uint8* pNum = (drflac_uint8*)pData;
1856
0
    return *(pNum) << 24 | *(pNum+1) << 16 | *(pNum+2) << 8 | *(pNum+3);
1857
0
}
1858
1859
static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n)
1860
0
{
1861
0
    if (drflac__is_little_endian()) {
1862
0
        return drflac__swap_endian_uint64(n);
1863
0
    }
1864
1865
0
    return n;
1866
0
}
1867
1868
1869
static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n)
1870
0
{
1871
0
    if (!drflac__is_little_endian()) {
1872
0
        return drflac__swap_endian_uint32(n);
1873
0
    }
1874
0
1875
0
    return n;
1876
0
}
1877
1878
static DRFLAC_INLINE drflac_uint32 drflac__le2host_32_ptr_unaligned(const void* pData)
1879
0
{
1880
0
    const drflac_uint8* pNum = (drflac_uint8*)pData;
1881
0
    return *pNum | *(pNum+1) << 8 |  *(pNum+2) << 16 | *(pNum+3) << 24;
1882
0
}
1883
1884
1885
static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n)
1886
0
{
1887
0
    drflac_uint32 result = 0;
1888
0
    result |= (n & 0x7F000000) >> 3;
1889
0
    result |= (n & 0x007F0000) >> 2;
1890
0
    result |= (n & 0x00007F00) >> 1;
1891
0
    result |= (n & 0x0000007F) >> 0;
1892
1893
0
    return result;
1894
0
}
1895
1896
1897
1898
/* The CRC code below is based on this document: http://zlib.net/crc_v3.txt */
1899
static drflac_uint8 drflac__crc8_table[] = {
1900
    0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
1901
    0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
1902
    0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
1903
    0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
1904
    0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
1905
    0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
1906
    0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
1907
    0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
1908
    0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
1909
    0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
1910
    0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
1911
    0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
1912
    0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
1913
    0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
1914
    0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
1915
    0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
1916
};
1917
1918
static drflac_uint16 drflac__crc16_table[] = {
1919
    0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
1920
    0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
1921
    0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
1922
    0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
1923
    0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
1924
    0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
1925
    0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
1926
    0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
1927
    0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
1928
    0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
1929
    0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
1930
    0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
1931
    0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
1932
    0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
1933
    0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
1934
    0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
1935
    0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
1936
    0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
1937
    0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
1938
    0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
1939
    0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
1940
    0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
1941
    0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
1942
    0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
1943
    0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
1944
    0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
1945
    0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
1946
    0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
1947
    0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
1948
    0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
1949
    0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
1950
    0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
1951
};
1952
1953
static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data)
1954
0
{
1955
0
    return drflac__crc8_table[crc ^ data];
1956
0
}
1957
1958
static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count)
1959
0
{
1960
#ifdef DR_FLAC_NO_CRC
1961
    (void)crc;
1962
    (void)data;
1963
    (void)count;
1964
    return 0;
1965
#else
1966
#if 0
1967
    /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */
1968
    drflac_uint8 p = 0x07;
1969
    for (int i = count-1; i >= 0; --i) {
1970
        drflac_uint8 bit = (data & (1 << i)) >> i;
1971
        if (crc & 0x80) {
1972
            crc = ((crc << 1) | bit) ^ p;
1973
        } else {
1974
            crc = ((crc << 1) | bit);
1975
        }
1976
    }
1977
    return crc;
1978
#else
1979
0
    drflac_uint32 wholeBytes;
1980
0
    drflac_uint32 leftoverBits;
1981
0
    drflac_uint64 leftoverDataMask;
1982
1983
0
    static drflac_uint64 leftoverDataMaskTable[8] = {
1984
0
        0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
1985
0
    };
1986
1987
0
    DRFLAC_ASSERT(count <= 32);
1988
1989
0
    wholeBytes = count >> 3;
1990
0
    leftoverBits = count - (wholeBytes*8);
1991
0
    leftoverDataMask = leftoverDataMaskTable[leftoverBits];
1992
1993
0
    switch (wholeBytes) {
1994
0
        case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
1995
0
        case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
1996
0
        case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
1997
0
        case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
1998
0
        case 0: if (leftoverBits > 0) crc = (drflac_uint8)((crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]);
1999
0
    }
2000
0
    return crc;
2001
0
#endif
2002
0
#endif
2003
0
}
2004
2005
static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data)
2006
0
{
2007
0
    return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data];
2008
0
}
2009
2010
static DRFLAC_INLINE drflac_uint16 drflac_crc16_cache(drflac_uint16 crc, drflac_cache_t data)
2011
0
{
2012
0
#ifdef DRFLAC_64BIT
2013
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
2014
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
2015
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
2016
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
2017
0
#endif
2018
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
2019
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
2020
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >>  8) & 0xFF));
2021
0
    crc = drflac_crc16_byte(crc, (drflac_uint8)((data >>  0) & 0xFF));
2022
2023
0
    return crc;
2024
0
}
2025
2026
static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount)
2027
0
{
2028
0
    switch (byteCount)
2029
0
    {
2030
0
#ifdef DRFLAC_64BIT
2031
0
    case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
2032
0
    case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
2033
0
    case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
2034
0
    case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
2035
0
#endif
2036
0
    case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
2037
0
    case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
2038
0
    case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >>  8) & 0xFF));
2039
0
    case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >>  0) & 0xFF));
2040
0
    }
2041
2042
0
    return crc;
2043
0
}
2044
2045
#if 0
2046
static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count)
2047
{
2048
#ifdef DR_FLAC_NO_CRC
2049
    (void)crc;
2050
    (void)data;
2051
    (void)count;
2052
    return 0;
2053
#else
2054
#if 0
2055
    /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */
2056
    drflac_uint16 p = 0x8005;
2057
    for (int i = count-1; i >= 0; --i) {
2058
        drflac_uint16 bit = (data & (1ULL << i)) >> i;
2059
        if (r & 0x8000) {
2060
            r = ((r << 1) | bit) ^ p;
2061
        } else {
2062
            r = ((r << 1) | bit);
2063
        }
2064
    }
2065
2066
    return crc;
2067
#else
2068
    drflac_uint32 wholeBytes;
2069
    drflac_uint32 leftoverBits;
2070
    drflac_uint64 leftoverDataMask;
2071
2072
    static drflac_uint64 leftoverDataMaskTable[8] = {
2073
        0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
2074
    };
2075
2076
    DRFLAC_ASSERT(count <= 64);
2077
2078
    wholeBytes = count >> 3;
2079
    leftoverBits = count & 7;
2080
    leftoverDataMask = leftoverDataMaskTable[leftoverBits];
2081
2082
    switch (wholeBytes) {
2083
        default:
2084
        case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
2085
        case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
2086
        case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
2087
        case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
2088
        case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
2089
    }
2090
    return crc;
2091
#endif
2092
#endif
2093
}
2094
2095
static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count)
2096
{
2097
#ifdef DR_FLAC_NO_CRC
2098
    (void)crc;
2099
    (void)data;
2100
    (void)count;
2101
    return 0;
2102
#else
2103
    drflac_uint32 wholeBytes;
2104
    drflac_uint32 leftoverBits;
2105
    drflac_uint64 leftoverDataMask;
2106
2107
    static drflac_uint64 leftoverDataMaskTable[8] = {
2108
        0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
2109
    };
2110
2111
    DRFLAC_ASSERT(count <= 64);
2112
2113
    wholeBytes = count >> 3;
2114
    leftoverBits = count & 7;
2115
    leftoverDataMask = leftoverDataMaskTable[leftoverBits];
2116
2117
    switch (wholeBytes) {
2118
        default:
2119
        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. */
2120
        case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
2121
        case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
2122
        case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
2123
        case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000      ) << leftoverBits)) >> (24 + leftoverBits)));
2124
        case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000      ) << leftoverBits)) >> (16 + leftoverBits)));
2125
        case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00      ) << leftoverBits)) >> ( 8 + leftoverBits)));
2126
        case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF      ) << leftoverBits)) >> ( 0 + leftoverBits)));
2127
        case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
2128
    }
2129
    return crc;
2130
#endif
2131
}
2132
2133
2134
static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count)
2135
{
2136
#ifdef DRFLAC_64BIT
2137
    return drflac_crc16__64bit(crc, data, count);
2138
#else
2139
    return drflac_crc16__32bit(crc, data, count);
2140
#endif
2141
}
2142
#endif
2143
2144
2145
#ifdef DRFLAC_64BIT
2146
0
#define drflac__be2host__cache_line drflac__be2host_64
2147
#else
2148
#define drflac__be2host__cache_line drflac__be2host_32
2149
#endif
2150
2151
/*
2152
BIT READING ATTEMPT #2
2153
2154
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
2155
on the most significant bit. It uses the notion of an L1 and L2 cache (borrowed from CPU architecture), where the L1 cache
2156
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
2157
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
2158
from onRead() is read into.
2159
*/
2160
0
#define DRFLAC_CACHE_L1_SIZE_BYTES(bs)                      (sizeof((bs)->cache))
2161
0
#define DRFLAC_CACHE_L1_SIZE_BITS(bs)                       (sizeof((bs)->cache)*8)
2162
0
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs)                  (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
2163
0
#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount)           (~((~(drflac_cache_t)0) >> (_bitCount)))
2164
0
#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount)      (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
2165
0
#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount)               (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
2166
0
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount)     (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >>  DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
2167
#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)))
2168
0
#define DRFLAC_CACHE_L2_SIZE_BYTES(bs)                      (sizeof((bs)->cacheL2))
2169
0
#define DRFLAC_CACHE_L2_LINE_COUNT(bs)                      (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
2170
#define DRFLAC_CACHE_L2_LINES_REMAINING(bs)                 (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
2171
2172
2173
#ifndef DR_FLAC_NO_CRC
2174
static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs)
2175
0
{
2176
0
    bs->crc16 = 0;
2177
0
    bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2178
0
}
2179
2180
static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs)
2181
0
{
2182
0
    if (bs->crc16CacheIgnoredBytes == 0) {
2183
0
        bs->crc16 = drflac_crc16_cache(bs->crc16, bs->crc16Cache);
2184
0
    } else {
2185
0
        bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes);
2186
0
        bs->crc16CacheIgnoredBytes = 0;
2187
0
    }
2188
0
}
2189
2190
static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs)
2191
0
{
2192
    /* We should never be flushing in a situation where we are not aligned on a byte boundary. */
2193
0
    DRFLAC_ASSERT((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
2194
2195
    /*
2196
    The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined
2197
    by the number of bits that have been consumed.
2198
    */
2199
0
    if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
2200
0
        drflac__update_crc16(bs);
2201
0
    } else {
2202
        /* We only accumulate the consumed bits. */
2203
0
        bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes);
2204
2205
        /*
2206
        The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated
2207
        so we can handle that later.
2208
        */
2209
0
        bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2210
0
    }
2211
2212
0
    return bs->crc16;
2213
0
}
2214
#endif
2215
2216
static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs)
2217
0
{
2218
0
    size_t bytesRead;
2219
0
    size_t alignedL1LineCount;
2220
2221
    /* Fast path. Try loading straight from L2. */
2222
0
    if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
2223
0
        bs->cache = bs->cacheL2[bs->nextL2Line++];
2224
0
        return DRFLAC_TRUE;
2225
0
    }
2226
2227
    /*
2228
    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
2229
    any left.
2230
    */
2231
0
    if (bs->unalignedByteCount > 0) {
2232
0
        return DRFLAC_FALSE;   /* If we have any unaligned bytes it means there's no more aligned bytes left in the client. */
2233
0
    }
2234
2235
0
    bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs));
2236
2237
0
    bs->nextL2Line = 0;
2238
0
    if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) {
2239
0
        bs->cache = bs->cacheL2[bs->nextL2Line++];
2240
0
        return DRFLAC_TRUE;
2241
0
    }
2242
2243
2244
    /*
2245
    If we get here it means we were unable to retrieve enough data to fill the entire L2 cache. It probably
2246
    means we've just reached the end of the file. We need to move the valid data down to the end of the buffer
2247
    and adjust the index of the next line accordingly. Also keep in mind that the L2 cache must be aligned to
2248
    the size of the L1 so we'll need to seek backwards by any misaligned bytes.
2249
    */
2250
0
    alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs);
2251
2252
    /* We need to keep track of any unaligned bytes for later use. */
2253
0
    bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs));
2254
0
    if (bs->unalignedByteCount > 0) {
2255
0
        bs->unalignedCache = bs->cacheL2[alignedL1LineCount];
2256
0
    }
2257
2258
0
    if (alignedL1LineCount > 0) {
2259
0
        size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount;
2260
0
        size_t i;
2261
0
        for (i = alignedL1LineCount; i > 0; --i) {
2262
0
            bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1];
2263
0
        }
2264
2265
0
        bs->nextL2Line = (drflac_uint32)offset;
2266
0
        bs->cache = bs->cacheL2[bs->nextL2Line++];
2267
0
        return DRFLAC_TRUE;
2268
0
    } else {
2269
        /* If we get into this branch it means we weren't able to load any L1-aligned data. */
2270
0
        bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs);
2271
0
        return DRFLAC_FALSE;
2272
0
    }
2273
0
}
2274
2275
static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
2276
0
{
2277
0
    size_t bytesRead;
2278
2279
0
#ifndef DR_FLAC_NO_CRC
2280
0
    drflac__update_crc16(bs);
2281
0
#endif
2282
2283
    /* Fast path. Try just moving the next value in the L2 cache to the L1 cache. */
2284
0
    if (drflac__reload_l1_cache_from_l2(bs)) {
2285
0
        bs->cache = drflac__be2host__cache_line(bs->cache);
2286
0
        bs->consumedBits = 0;
2287
0
#ifndef DR_FLAC_NO_CRC
2288
0
        bs->crc16Cache = bs->cache;
2289
0
#endif
2290
0
        return DRFLAC_TRUE;
2291
0
    }
2292
2293
    /* Slow path. */
2294
2295
    /*
2296
    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
2297
    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
2298
    data from the unaligned cache.
2299
    */
2300
0
    bytesRead = bs->unalignedByteCount;
2301
0
    if (bytesRead == 0) {
2302
0
        bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);   /* <-- The stream has been exhausted, so marked the bits as consumed. */
2303
0
        return DRFLAC_FALSE;
2304
0
    }
2305
2306
0
    DRFLAC_ASSERT(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
2307
0
    bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
2308
2309
0
    bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
2310
0
    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. */
2311
0
    bs->unalignedByteCount = 0;     /* <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes. */
2312
2313
0
#ifndef DR_FLAC_NO_CRC
2314
0
    bs->crc16Cache = bs->cache >> bs->consumedBits;
2315
0
    bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3;
2316
0
#endif
2317
0
    return DRFLAC_TRUE;
2318
0
}
2319
2320
static void drflac__reset_cache(drflac_bs* bs)
2321
0
{
2322
0
    bs->nextL2Line   = DRFLAC_CACHE_L2_LINE_COUNT(bs);  /* <-- This clears the L2 cache. */
2323
0
    bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);   /* <-- This clears the L1 cache. */
2324
0
    bs->cache = 0;
2325
0
    bs->unalignedByteCount = 0;                         /* <-- This clears the trailing unaligned bytes. */
2326
0
    bs->unalignedCache = 0;
2327
2328
0
#ifndef DR_FLAC_NO_CRC
2329
0
    bs->crc16Cache = 0;
2330
0
    bs->crc16CacheIgnoredBytes = 0;
2331
0
#endif
2332
0
}
2333
2334
2335
static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut)
2336
0
{
2337
0
    DRFLAC_ASSERT(bs != NULL);
2338
0
    DRFLAC_ASSERT(pResultOut != NULL);
2339
0
    DRFLAC_ASSERT(bitCount > 0);
2340
0
    DRFLAC_ASSERT(bitCount <= 32);
2341
2342
0
    if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2343
0
        if (!drflac__reload_cache(bs)) {
2344
0
            return DRFLAC_FALSE;
2345
0
        }
2346
0
    }
2347
2348
0
    if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2349
        /*
2350
        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
2351
        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
2352
        more optimal solution for this.
2353
        */
2354
0
#ifdef DRFLAC_64BIT
2355
0
        *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
2356
0
        bs->consumedBits += bitCount;
2357
0
        bs->cache <<= bitCount;
2358
#else
2359
        if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2360
            *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
2361
            bs->consumedBits += bitCount;
2362
            bs->cache <<= bitCount;
2363
        } else {
2364
            /* Cannot shift by 32-bits, so need to do it differently. */
2365
            *pResultOut = (drflac_uint32)bs->cache;
2366
            bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);
2367
            bs->cache = 0;
2368
        }
2369
#endif
2370
2371
0
        return DRFLAC_TRUE;
2372
0
    } else {
2373
        /* 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. */
2374
0
        drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2375
0
        drflac_uint32 bitCountLo = bitCount - bitCountHi;
2376
0
        drflac_uint32 resultHi;
2377
2378
0
        DRFLAC_ASSERT(bitCountHi > 0);
2379
0
        DRFLAC_ASSERT(bitCountHi < 32);
2380
0
        resultHi = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
2381
2382
0
        if (!drflac__reload_cache(bs)) {
2383
0
            return DRFLAC_FALSE;
2384
0
        }
2385
0
        if (bitCountLo > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2386
            /* This happens when we get to end of stream */
2387
0
            return DRFLAC_FALSE;
2388
0
        }
2389
2390
0
        *pResultOut = (resultHi << bitCountLo) | (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo);
2391
0
        bs->consumedBits += bitCountLo;
2392
0
        bs->cache <<= bitCountLo;
2393
0
        return DRFLAC_TRUE;
2394
0
    }
2395
0
}
2396
2397
static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult)
2398
0
{
2399
0
    drflac_uint32 result;
2400
2401
0
    DRFLAC_ASSERT(bs != NULL);
2402
0
    DRFLAC_ASSERT(pResult != NULL);
2403
0
    DRFLAC_ASSERT(bitCount > 0);
2404
0
    DRFLAC_ASSERT(bitCount <= 32);
2405
2406
0
    if (!drflac__read_uint32(bs, bitCount, &result)) {
2407
0
        return DRFLAC_FALSE;
2408
0
    }
2409
2410
    /* Do not attempt to shift by 32 as it's undefined. */
2411
0
    if (bitCount < 32) {
2412
0
        drflac_uint32 signbit;
2413
0
        signbit = ((result >> (bitCount-1)) & 0x01);
2414
0
        result |= (~signbit + 1) << bitCount;
2415
0
    }
2416
2417
0
    *pResult = (drflac_int32)result;
2418
0
    return DRFLAC_TRUE;
2419
0
}
2420
2421
#ifdef DRFLAC_64BIT
2422
static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut)
2423
0
{
2424
0
    drflac_uint32 resultHi;
2425
0
    drflac_uint32 resultLo;
2426
2427
0
    DRFLAC_ASSERT(bitCount <= 64);
2428
0
    DRFLAC_ASSERT(bitCount >  32);
2429
2430
0
    if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
2431
0
        return DRFLAC_FALSE;
2432
0
    }
2433
2434
0
    if (!drflac__read_uint32(bs, 32, &resultLo)) {
2435
0
        return DRFLAC_FALSE;
2436
0
    }
2437
2438
0
    *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo);
2439
0
    return DRFLAC_TRUE;
2440
0
}
2441
#endif
2442
2443
/* Function below is unused, but leaving it here in case I need to quickly add it again. */
2444
#if 0
2445
static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut)
2446
{
2447
    drflac_uint64 result;
2448
    drflac_uint64 signbit;
2449
2450
    DRFLAC_ASSERT(bitCount <= 64);
2451
2452
    if (!drflac__read_uint64(bs, bitCount, &result)) {
2453
        return DRFLAC_FALSE;
2454
    }
2455
2456
    signbit = ((result >> (bitCount-1)) & 0x01);
2457
    result |= (~signbit + 1) << bitCount;
2458
2459
    *pResultOut = (drflac_int64)result;
2460
    return DRFLAC_TRUE;
2461
}
2462
#endif
2463
2464
static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult)
2465
0
{
2466
0
    drflac_uint32 result;
2467
2468
0
    DRFLAC_ASSERT(bs != NULL);
2469
0
    DRFLAC_ASSERT(pResult != NULL);
2470
0
    DRFLAC_ASSERT(bitCount > 0);
2471
0
    DRFLAC_ASSERT(bitCount <= 16);
2472
2473
0
    if (!drflac__read_uint32(bs, bitCount, &result)) {
2474
0
        return DRFLAC_FALSE;
2475
0
    }
2476
2477
0
    *pResult = (drflac_uint16)result;
2478
0
    return DRFLAC_TRUE;
2479
0
}
2480
2481
#if 0
2482
static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult)
2483
{
2484
    drflac_int32 result;
2485
2486
    DRFLAC_ASSERT(bs != NULL);
2487
    DRFLAC_ASSERT(pResult != NULL);
2488
    DRFLAC_ASSERT(bitCount > 0);
2489
    DRFLAC_ASSERT(bitCount <= 16);
2490
2491
    if (!drflac__read_int32(bs, bitCount, &result)) {
2492
        return DRFLAC_FALSE;
2493
    }
2494
2495
    *pResult = (drflac_int16)result;
2496
    return DRFLAC_TRUE;
2497
}
2498
#endif
2499
2500
static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult)
2501
0
{
2502
0
    drflac_uint32 result;
2503
2504
0
    DRFLAC_ASSERT(bs != NULL);
2505
0
    DRFLAC_ASSERT(pResult != NULL);
2506
0
    DRFLAC_ASSERT(bitCount > 0);
2507
0
    DRFLAC_ASSERT(bitCount <= 8);
2508
2509
0
    if (!drflac__read_uint32(bs, bitCount, &result)) {
2510
0
        return DRFLAC_FALSE;
2511
0
    }
2512
2513
0
    *pResult = (drflac_uint8)result;
2514
0
    return DRFLAC_TRUE;
2515
0
}
2516
2517
static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult)
2518
0
{
2519
0
    drflac_int32 result;
2520
2521
0
    DRFLAC_ASSERT(bs != NULL);
2522
0
    DRFLAC_ASSERT(pResult != NULL);
2523
0
    DRFLAC_ASSERT(bitCount > 0);
2524
0
    DRFLAC_ASSERT(bitCount <= 8);
2525
2526
0
    if (!drflac__read_int32(bs, bitCount, &result)) {
2527
0
        return DRFLAC_FALSE;
2528
0
    }
2529
2530
0
    *pResult = (drflac_int8)result;
2531
0
    return DRFLAC_TRUE;
2532
0
}
2533
2534
2535
static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
2536
0
{
2537
0
    if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2538
0
        bs->consumedBits += (drflac_uint32)bitsToSeek;
2539
0
        bs->cache <<= bitsToSeek;
2540
0
        return DRFLAC_TRUE;
2541
0
    } else {
2542
        /* It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here. */
2543
0
        bitsToSeek       -= DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2544
0
        bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2545
0
        bs->cache         = 0;
2546
2547
        /* Simple case. Seek in groups of the same number as bits that fit within a cache line. */
2548
0
#ifdef DRFLAC_64BIT
2549
0
        while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2550
0
            drflac_uint64 bin;
2551
0
            if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2552
0
                return DRFLAC_FALSE;
2553
0
            }
2554
0
            bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2555
0
        }
2556
#else
2557
        while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
2558
            drflac_uint32 bin;
2559
            if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
2560
                return DRFLAC_FALSE;
2561
            }
2562
            bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs);
2563
        }
2564
#endif
2565
2566
        /* Whole leftover bytes. */
2567
0
        while (bitsToSeek >= 8) {
2568
0
            drflac_uint8 bin;
2569
0
            if (!drflac__read_uint8(bs, 8, &bin)) {
2570
0
                return DRFLAC_FALSE;
2571
0
            }
2572
0
            bitsToSeek -= 8;
2573
0
        }
2574
2575
        /* Leftover bits. */
2576
0
        if (bitsToSeek > 0) {
2577
0
            drflac_uint8 bin;
2578
0
            if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) {
2579
0
                return DRFLAC_FALSE;
2580
0
            }
2581
0
            bitsToSeek = 0; /* <-- Necessary for the assert below. */
2582
0
        }
2583
2584
0
        DRFLAC_ASSERT(bitsToSeek == 0);
2585
0
        return DRFLAC_TRUE;
2586
0
    }
2587
0
}
2588
2589
2590
/* 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. */
2591
static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
2592
0
{
2593
0
    DRFLAC_ASSERT(bs != NULL);
2594
2595
    /*
2596
    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
2597
    thing to do is align to the next byte.
2598
    */
2599
0
    if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
2600
0
        return DRFLAC_FALSE;
2601
0
    }
2602
2603
0
    for (;;) {
2604
0
        drflac_uint8 hi;
2605
2606
0
#ifndef DR_FLAC_NO_CRC
2607
0
        drflac__reset_crc16(bs);
2608
0
#endif
2609
2610
0
        if (!drflac__read_uint8(bs, 8, &hi)) {
2611
0
            return DRFLAC_FALSE;
2612
0
        }
2613
2614
0
        if (hi == 0xFF) {
2615
0
            drflac_uint8 lo;
2616
0
            if (!drflac__read_uint8(bs, 6, &lo)) {
2617
0
                return DRFLAC_FALSE;
2618
0
            }
2619
2620
0
            if (lo == 0x3E) {
2621
0
                return DRFLAC_TRUE;
2622
0
            } else {
2623
0
                if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
2624
0
                    return DRFLAC_FALSE;
2625
0
                }
2626
0
            }
2627
0
        }
2628
0
    }
2629
2630
    /* Should never get here. */
2631
    /*return DRFLAC_FALSE;*/
2632
0
}
2633
2634
2635
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
2636
#define DRFLAC_IMPLEMENT_CLZ_LZCNT
2637
#endif
2638
#if  defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(__clang__)
2639
#define DRFLAC_IMPLEMENT_CLZ_MSVC
2640
#endif
2641
#if  defined(__WATCOMC__) && defined(__386__)
2642
#define DRFLAC_IMPLEMENT_CLZ_WATCOM
2643
#endif
2644
#ifdef __MRC__
2645
#include <intrinsics.h>
2646
#define DRFLAC_IMPLEMENT_CLZ_MRC
2647
#endif
2648
2649
static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
2650
0
{
2651
0
    drflac_uint32 n;
2652
0
    static drflac_uint32 clz_table_4[] = {
2653
0
        0,
2654
0
        4,
2655
0
        3, 3,
2656
0
        2, 2, 2, 2,
2657
0
        1, 1, 1, 1, 1, 1, 1, 1
2658
0
    };
2659
2660
0
    if (x == 0) {
2661
0
        return sizeof(x)*8;
2662
0
    }
2663
2664
0
    n = clz_table_4[x >> (sizeof(x)*8 - 4)];
2665
0
    if (n == 0) {
2666
0
#ifdef DRFLAC_64BIT
2667
0
        if ((x & ((drflac_uint64)0xFFFFFFFF << 32)) == 0) { n  = 32; x <<= 32; }
2668
0
        if ((x & ((drflac_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; }
2669
0
        if ((x & ((drflac_uint64)0xFF000000 << 32)) == 0) { n += 8;  x <<= 8;  }
2670
0
        if ((x & ((drflac_uint64)0xF0000000 << 32)) == 0) { n += 4;  x <<= 4;  }
2671
#else
2672
        if ((x & 0xFFFF0000) == 0) { n  = 16; x <<= 16; }
2673
        if ((x & 0xFF000000) == 0) { n += 8;  x <<= 8;  }
2674
        if ((x & 0xF0000000) == 0) { n += 4;  x <<= 4;  }
2675
#endif
2676
0
        n += clz_table_4[x >> (sizeof(x)*8 - 4)];
2677
0
    }
2678
2679
0
    return n - 1;
2680
0
}
2681
2682
#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2683
static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported(void)
2684
0
{
2685
    /* Fast compile time check for ARM. */
2686
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
2687
    return DRFLAC_TRUE;
2688
#elif defined(__MRC__)
2689
    return DRFLAC_TRUE;
2690
#else
2691
    /* If the compiler itself does not support the intrinsic then we'll need to return false. */
2692
0
    #ifdef DRFLAC_HAS_LZCNT_INTRINSIC
2693
0
        return drflac__gIsLZCNTSupported;
2694
    #else
2695
        return DRFLAC_FALSE;
2696
    #endif
2697
0
#endif
2698
0
}
2699
2700
static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
2701
0
{
2702
    /*
2703
    It's critical for competitive decoding performance that this function be highly optimal. With MSVC we can use the __lzcnt64() and __lzcnt() intrinsics
2704
    to achieve good performance, however on GCC and Clang it's a little bit more annoying. The __builtin_clzl() and __builtin_clzll() intrinsics leave
2705
    it undefined as to the return value when `x` is 0. We need this to be well defined as returning 32 or 64, depending on whether or not it's a 32- or
2706
    64-bit build. To work around this we would need to add a conditional to check for the x = 0 case, but this creates unnecessary inefficiency. To work
2707
    around this problem I have written some inline assembly to emit the LZCNT (x86) or CLZ (ARM) instruction directly which removes the need to include
2708
    the conditional. This has worked well in the past, but for some reason Clang's MSVC compatible driver, clang-cl, does not seem to be handling this
2709
    in the same way as the normal Clang driver. It seems that `clang-cl` is just outputting the wrong results sometimes, maybe due to some register
2710
    getting clobbered?
2711
2712
    I'm not sure if this is a bug with dr_flac's inlined assembly (most likely), a bug in `clang-cl` or just a misunderstanding on my part with inline
2713
    assembly rules for `clang-cl`. If somebody can identify an error in dr_flac's inlined assembly I'm happy to get that fixed.
2714
2715
    Fortunately there is an easy workaround for this. Clang implements MSVC-specific intrinsics for compatibility. It also defines _MSC_VER for extra
2716
    compatibility. We can therefore just check for _MSC_VER and use the MSVC intrinsic which, fortunately for us, Clang supports. It would still be nice
2717
    to know how to fix the inlined assembly for correctness sake, however.
2718
    */
2719
2720
#if defined(_MSC_VER) /*&& !defined(__clang__)*/    /* <-- Intentionally wanting Clang to use the MSVC __lzcnt64/__lzcnt intrinsics due to above ^. */
2721
    #ifdef DRFLAC_64BIT
2722
        return (drflac_uint32)__lzcnt64(x);
2723
    #else
2724
        return (drflac_uint32)__lzcnt(x);
2725
    #endif
2726
#else
2727
0
    #if defined(__GNUC__) || defined(__clang__)
2728
0
        #if defined(DRFLAC_X64)
2729
0
            {
2730
                /*
2731
                A note on lzcnt.
2732
2733
                We check for the presence of the lzcnt instruction at runtime before calling this function, but we still generate this code. I have had
2734
                a report where the assembler does not recognize the lzcnt instruction. To work around this we are going to use `rep; bsr` instead which
2735
                has an identical byte encoding as lzcnt, and should hopefully improve compatibility with older assemblers.
2736
                */
2737
0
                drflac_uint64 r;
2738
0
                __asm__ __volatile__ (
2739
0
                    "rep; bsr{q %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
2740
                    /*"lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"*/
2741
0
                );
2742
2743
0
                return (drflac_uint32)r;
2744
0
            }
2745
        #elif defined(DRFLAC_X86)
2746
            {
2747
                drflac_uint32 r;
2748
                __asm__ __volatile__ (
2749
                    "rep; bsr{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
2750
                    /*"lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"*/
2751
                );
2752
2753
                return r;
2754
            }
2755
        #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !(defined(__thumb__) && !defined(__thumb2__)) && !defined(DRFLAC_64BIT)   /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
2756
            {
2757
                unsigned int r;
2758
                __asm__ __volatile__ (
2759
                #if defined(DRFLAC_64BIT)
2760
                    "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! */
2761
                #else
2762
                    "clz %[out], %[in]" : [out]"=r"(r) : [in]"r"(x)
2763
                #endif
2764
                );
2765
2766
                return r;
2767
            }
2768
        #else
2769
            if (x == 0) {
2770
                return sizeof(x)*8;
2771
            }
2772
            #ifdef DRFLAC_64BIT
2773
                return (drflac_uint32)__builtin_clzll((drflac_uint64)x);
2774
            #else
2775
                return (drflac_uint32)__builtin_clzl((drflac_uint32)x);
2776
            #endif
2777
        #endif
2778
    #else
2779
        /* Unsupported compiler. */
2780
        #error "This compiler does not support the lzcnt intrinsic."
2781
    #endif
2782
0
#endif
2783
0
}
2784
#endif
2785
2786
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2787
#include <intrin.h> /* For BitScanReverse(). */
2788
2789
static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
2790
{
2791
    drflac_uint32 n;
2792
2793
    if (x == 0) {
2794
        return sizeof(x)*8;
2795
    }
2796
2797
#ifdef DRFLAC_64BIT
2798
    _BitScanReverse64((unsigned long*)&n, x);
2799
#else
2800
    _BitScanReverse((unsigned long*)&n, x);
2801
#endif
2802
    return sizeof(x)*8 - n - 1;
2803
}
2804
#endif
2805
2806
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
2807
static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
2808
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM_LZCNT
2809
/* Use the LZCNT instruction (only available on some processors since the 2010s). */
2810
#pragma aux drflac__clz_watcom_lzcnt = \
2811
    "db 0F3h, 0Fh, 0BDh, 0C0h" /* lzcnt eax, eax */ \
2812
    parm [eax] \
2813
    value [eax] \
2814
    modify nomemory;
2815
#else
2816
/* Use the 386+-compatible implementation. */
2817
#pragma aux drflac__clz_watcom = \
2818
    "bsr eax, eax" \
2819
    "xor eax, 31" \
2820
    parm [eax] nomemory \
2821
    value [eax] \
2822
    modify exact [eax] nomemory;
2823
#endif
2824
#endif
2825
2826
static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
2827
0
{
2828
0
#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
2829
0
    if (drflac__is_lzcnt_supported()) {
2830
0
        return drflac__clz_lzcnt(x);
2831
0
    } else
2832
0
#endif
2833
0
    {
2834
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
2835
        return drflac__clz_msvc(x);
2836
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM_LZCNT)
2837
        return drflac__clz_watcom_lzcnt(x);
2838
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
2839
        return (x == 0) ? sizeof(x)*8 : drflac__clz_watcom(x);
2840
#elif defined(__MRC__)
2841
        return __cntlzw(x);
2842
#else
2843
0
        return drflac__clz_software(x);
2844
0
#endif
2845
0
    }
2846
0
}
2847
2848
2849
static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut)
2850
0
{
2851
0
    drflac_uint32 zeroCounter = 0;
2852
0
    drflac_uint32 setBitOffsetPlus1;
2853
2854
0
    while (bs->cache == 0) {
2855
0
        zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
2856
0
        if (!drflac__reload_cache(bs)) {
2857
0
            return DRFLAC_FALSE;
2858
0
        }
2859
0
    }
2860
2861
0
    if (bs->cache == 1) {
2862
        /* Not catching this would lead to undefined behaviour: a shift of a 32-bit number by 32 or more is undefined */
2863
0
        *pOffsetOut = zeroCounter + (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs) - 1;
2864
0
        if (!drflac__reload_cache(bs)) {
2865
0
            return DRFLAC_FALSE;
2866
0
        }
2867
2868
0
        return DRFLAC_TRUE;
2869
0
    }
2870
2871
0
    setBitOffsetPlus1 = drflac__clz(bs->cache);
2872
0
    setBitOffsetPlus1 += 1;
2873
2874
0
    if (setBitOffsetPlus1 > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
2875
        /* This happens when we get to end of stream */
2876
0
        return DRFLAC_FALSE;
2877
0
    }
2878
2879
0
    bs->consumedBits += setBitOffsetPlus1;
2880
0
    bs->cache <<= setBitOffsetPlus1;
2881
2882
0
    *pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1;
2883
0
    return DRFLAC_TRUE;
2884
0
}
2885
2886
2887
2888
static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart)
2889
0
{
2890
0
    DRFLAC_ASSERT(bs != NULL);
2891
0
    DRFLAC_ASSERT(offsetFromStart > 0);
2892
2893
    /*
2894
    Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which
2895
    is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit.
2896
    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.
2897
    */
2898
0
    if (offsetFromStart > 0x7FFFFFFF) {
2899
0
        drflac_uint64 bytesRemaining = offsetFromStart;
2900
0
        if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_SET)) {
2901
0
            return DRFLAC_FALSE;
2902
0
        }
2903
0
        bytesRemaining -= 0x7FFFFFFF;
2904
2905
0
        while (bytesRemaining > 0x7FFFFFFF) {
2906
0
            if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_CUR)) {
2907
0
                return DRFLAC_FALSE;
2908
0
            }
2909
0
            bytesRemaining -= 0x7FFFFFFF;
2910
0
        }
2911
2912
0
        if (bytesRemaining > 0) {
2913
0
            if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, DRFLAC_SEEK_CUR)) {
2914
0
                return DRFLAC_FALSE;
2915
0
            }
2916
0
        }
2917
0
    } else {
2918
0
        if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, DRFLAC_SEEK_SET)) {
2919
0
            return DRFLAC_FALSE;
2920
0
        }
2921
0
    }
2922
2923
    /* The cache should be reset to force a reload of fresh data from the client. */
2924
0
    drflac__reset_cache(bs);
2925
0
    return DRFLAC_TRUE;
2926
0
}
2927
2928
2929
static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64* pNumberOut, drflac_uint8* pCRCOut)
2930
0
{
2931
0
    drflac_uint8 crc;
2932
0
    drflac_uint64 result;
2933
0
    drflac_uint8 utf8[7] = {0};
2934
0
    int byteCount;
2935
0
    int i;
2936
2937
0
    DRFLAC_ASSERT(bs != NULL);
2938
0
    DRFLAC_ASSERT(pNumberOut != NULL);
2939
0
    DRFLAC_ASSERT(pCRCOut != NULL);
2940
2941
0
    crc = *pCRCOut;
2942
2943
0
    if (!drflac__read_uint8(bs, 8, utf8)) {
2944
0
        *pNumberOut = 0;
2945
0
        return DRFLAC_AT_END;
2946
0
    }
2947
0
    crc = drflac_crc8(crc, utf8[0], 8);
2948
2949
0
    if ((utf8[0] & 0x80) == 0) {
2950
0
        *pNumberOut = utf8[0];
2951
0
        *pCRCOut = crc;
2952
0
        return DRFLAC_SUCCESS;
2953
0
    }
2954
2955
    /*byteCount = 1;*/
2956
0
    if ((utf8[0] & 0xE0) == 0xC0) {
2957
0
        byteCount = 2;
2958
0
    } else if ((utf8[0] & 0xF0) == 0xE0) {
2959
0
        byteCount = 3;
2960
0
    } else if ((utf8[0] & 0xF8) == 0xF0) {
2961
0
        byteCount = 4;
2962
0
    } else if ((utf8[0] & 0xFC) == 0xF8) {
2963
0
        byteCount = 5;
2964
0
    } else if ((utf8[0] & 0xFE) == 0xFC) {
2965
0
        byteCount = 6;
2966
0
    } else if ((utf8[0] & 0xFF) == 0xFE) {
2967
0
        byteCount = 7;
2968
0
    } else {
2969
0
        *pNumberOut = 0;
2970
0
        return DRFLAC_CRC_MISMATCH;     /* Bad UTF-8 encoding. */
2971
0
    }
2972
2973
    /* Read extra bytes. */
2974
0
    DRFLAC_ASSERT(byteCount > 1);
2975
2976
0
    result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1)));
2977
0
    for (i = 1; i < byteCount; ++i) {
2978
0
        if (!drflac__read_uint8(bs, 8, utf8 + i)) {
2979
0
            *pNumberOut = 0;
2980
0
            return DRFLAC_AT_END;
2981
0
        }
2982
0
        crc = drflac_crc8(crc, utf8[i], 8);
2983
2984
0
        result = (result << 6) | (utf8[i] & 0x3F);
2985
0
    }
2986
2987
0
    *pNumberOut = result;
2988
0
    *pCRCOut = crc;
2989
0
    return DRFLAC_SUCCESS;
2990
0
}
2991
2992
2993
static DRFLAC_INLINE drflac_uint32 drflac__ilog2_u32(drflac_uint32 x)
2994
0
{
2995
0
#if 1   /* Needs optimizing. */
2996
0
    drflac_uint32 result = 0;
2997
0
    while (x > 0) {
2998
0
        result += 1;
2999
0
        x >>= 1;
3000
0
    }
3001
3002
0
    return result;
3003
0
#endif
3004
0
}
3005
3006
static DRFLAC_INLINE drflac_bool32 drflac__use_64_bit_prediction(drflac_uint32 bitsPerSample, drflac_uint32 order, drflac_uint32 precision)
3007
0
{
3008
    /* https://web.archive.org/web/20220205005724/https://github.com/ietf-wg-cellar/flac-specification/blob/37a49aa48ba4ba12e8757badfc59c0df35435fec/rfc_backmatter.md */
3009
0
    return bitsPerSample + precision + drflac__ilog2_u32(order) > 32;
3010
0
}
3011
3012
3013
/*
3014
The next two functions are responsible for calculating the prediction.
3015
3016
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
3017
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.
3018
*/
3019
#if defined(__clang__)
3020
__attribute__((no_sanitize("signed-integer-overflow")))
3021
#endif
3022
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
3023
0
{
3024
0
    drflac_int32 prediction = 0;
3025
3026
0
    DRFLAC_ASSERT(order <= 32);
3027
3028
    /* 32-bit version. */
3029
3030
    /* VC++ optimizes this to a single jmp. I've not yet verified this for other compilers. */
3031
0
    switch (order)
3032
0
    {
3033
0
    case 32: prediction += coefficients[31] * pDecodedSamples[-32];
3034
0
    case 31: prediction += coefficients[30] * pDecodedSamples[-31];
3035
0
    case 30: prediction += coefficients[29] * pDecodedSamples[-30];
3036
0
    case 29: prediction += coefficients[28] * pDecodedSamples[-29];
3037
0
    case 28: prediction += coefficients[27] * pDecodedSamples[-28];
3038
0
    case 27: prediction += coefficients[26] * pDecodedSamples[-27];
3039
0
    case 26: prediction += coefficients[25] * pDecodedSamples[-26];
3040
0
    case 25: prediction += coefficients[24] * pDecodedSamples[-25];
3041
0
    case 24: prediction += coefficients[23] * pDecodedSamples[-24];
3042
0
    case 23: prediction += coefficients[22] * pDecodedSamples[-23];
3043
0
    case 22: prediction += coefficients[21] * pDecodedSamples[-22];
3044
0
    case 21: prediction += coefficients[20] * pDecodedSamples[-21];
3045
0
    case 20: prediction += coefficients[19] * pDecodedSamples[-20];
3046
0
    case 19: prediction += coefficients[18] * pDecodedSamples[-19];
3047
0
    case 18: prediction += coefficients[17] * pDecodedSamples[-18];
3048
0
    case 17: prediction += coefficients[16] * pDecodedSamples[-17];
3049
0
    case 16: prediction += coefficients[15] * pDecodedSamples[-16];
3050
0
    case 15: prediction += coefficients[14] * pDecodedSamples[-15];
3051
0
    case 14: prediction += coefficients[13] * pDecodedSamples[-14];
3052
0
    case 13: prediction += coefficients[12] * pDecodedSamples[-13];
3053
0
    case 12: prediction += coefficients[11] * pDecodedSamples[-12];
3054
0
    case 11: prediction += coefficients[10] * pDecodedSamples[-11];
3055
0
    case 10: prediction += coefficients[ 9] * pDecodedSamples[-10];
3056
0
    case  9: prediction += coefficients[ 8] * pDecodedSamples[- 9];
3057
0
    case  8: prediction += coefficients[ 7] * pDecodedSamples[- 8];
3058
0
    case  7: prediction += coefficients[ 6] * pDecodedSamples[- 7];
3059
0
    case  6: prediction += coefficients[ 5] * pDecodedSamples[- 6];
3060
0
    case  5: prediction += coefficients[ 4] * pDecodedSamples[- 5];
3061
0
    case  4: prediction += coefficients[ 3] * pDecodedSamples[- 4];
3062
0
    case  3: prediction += coefficients[ 2] * pDecodedSamples[- 3];
3063
0
    case  2: prediction += coefficients[ 1] * pDecodedSamples[- 2];
3064
0
    case  1: prediction += coefficients[ 0] * pDecodedSamples[- 1];
3065
0
    }
3066
3067
0
    return (drflac_int32)(prediction >> shift);
3068
0
}
3069
3070
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
3071
0
{
3072
0
    drflac_int64 prediction;
3073
3074
0
    DRFLAC_ASSERT(order <= 32);
3075
3076
    /* 64-bit version. */
3077
3078
    /* This method is faster on the 32-bit build when compiling with VC++. See note below. */
3079
#ifndef DRFLAC_64BIT
3080
    if (order == 8)
3081
    {
3082
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3083
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3084
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3085
        prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3086
        prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3087
        prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3088
        prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3089
        prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
3090
    }
3091
    else if (order == 7)
3092
    {
3093
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3094
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3095
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3096
        prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3097
        prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3098
        prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3099
        prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
3100
    }
3101
    else if (order == 3)
3102
    {
3103
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3104
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3105
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3106
    }
3107
    else if (order == 6)
3108
    {
3109
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3110
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3111
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3112
        prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3113
        prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3114
        prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
3115
    }
3116
    else if (order == 5)
3117
    {
3118
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3119
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3120
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3121
        prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3122
        prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
3123
    }
3124
    else if (order == 4)
3125
    {
3126
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3127
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3128
        prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
3129
        prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
3130
    }
3131
    else if (order == 12)
3132
    {
3133
        prediction  = coefficients[0]  * (drflac_int64)pDecodedSamples[-1];
3134
        prediction += coefficients[1]  * (drflac_int64)pDecodedSamples[-2];
3135
        prediction += coefficients[2]  * (drflac_int64)pDecodedSamples[-3];
3136
        prediction += coefficients[3]  * (drflac_int64)pDecodedSamples[-4];
3137
        prediction += coefficients[4]  * (drflac_int64)pDecodedSamples[-5];
3138
        prediction += coefficients[5]  * (drflac_int64)pDecodedSamples[-6];
3139
        prediction += coefficients[6]  * (drflac_int64)pDecodedSamples[-7];
3140
        prediction += coefficients[7]  * (drflac_int64)pDecodedSamples[-8];
3141
        prediction += coefficients[8]  * (drflac_int64)pDecodedSamples[-9];
3142
        prediction += coefficients[9]  * (drflac_int64)pDecodedSamples[-10];
3143
        prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3144
        prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
3145
    }
3146
    else if (order == 2)
3147
    {
3148
        prediction  = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3149
        prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
3150
    }
3151
    else if (order == 1)
3152
    {
3153
        prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
3154
    }
3155
    else if (order == 10)
3156
    {
3157
        prediction  = coefficients[0]  * (drflac_int64)pDecodedSamples[-1];
3158
        prediction += coefficients[1]  * (drflac_int64)pDecodedSamples[-2];
3159
        prediction += coefficients[2]  * (drflac_int64)pDecodedSamples[-3];
3160
        prediction += coefficients[3]  * (drflac_int64)pDecodedSamples[-4];
3161
        prediction += coefficients[4]  * (drflac_int64)pDecodedSamples[-5];
3162
        prediction += coefficients[5]  * (drflac_int64)pDecodedSamples[-6];
3163
        prediction += coefficients[6]  * (drflac_int64)pDecodedSamples[-7];
3164
        prediction += coefficients[7]  * (drflac_int64)pDecodedSamples[-8];
3165
        prediction += coefficients[8]  * (drflac_int64)pDecodedSamples[-9];
3166
        prediction += coefficients[9]  * (drflac_int64)pDecodedSamples[-10];
3167
    }
3168
    else if (order == 9)
3169
    {
3170
        prediction  = coefficients[0]  * (drflac_int64)pDecodedSamples[-1];
3171
        prediction += coefficients[1]  * (drflac_int64)pDecodedSamples[-2];
3172
        prediction += coefficients[2]  * (drflac_int64)pDecodedSamples[-3];
3173
        prediction += coefficients[3]  * (drflac_int64)pDecodedSamples[-4];
3174
        prediction += coefficients[4]  * (drflac_int64)pDecodedSamples[-5];
3175
        prediction += coefficients[5]  * (drflac_int64)pDecodedSamples[-6];
3176
        prediction += coefficients[6]  * (drflac_int64)pDecodedSamples[-7];
3177
        prediction += coefficients[7]  * (drflac_int64)pDecodedSamples[-8];
3178
        prediction += coefficients[8]  * (drflac_int64)pDecodedSamples[-9];
3179
    }
3180
    else if (order == 11)
3181
    {
3182
        prediction  = coefficients[0]  * (drflac_int64)pDecodedSamples[-1];
3183
        prediction += coefficients[1]  * (drflac_int64)pDecodedSamples[-2];
3184
        prediction += coefficients[2]  * (drflac_int64)pDecodedSamples[-3];
3185
        prediction += coefficients[3]  * (drflac_int64)pDecodedSamples[-4];
3186
        prediction += coefficients[4]  * (drflac_int64)pDecodedSamples[-5];
3187
        prediction += coefficients[5]  * (drflac_int64)pDecodedSamples[-6];
3188
        prediction += coefficients[6]  * (drflac_int64)pDecodedSamples[-7];
3189
        prediction += coefficients[7]  * (drflac_int64)pDecodedSamples[-8];
3190
        prediction += coefficients[8]  * (drflac_int64)pDecodedSamples[-9];
3191
        prediction += coefficients[9]  * (drflac_int64)pDecodedSamples[-10];
3192
        prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3193
    }
3194
    else
3195
    {
3196
        int j;
3197
3198
        prediction = 0;
3199
        for (j = 0; j < (int)order; ++j) {
3200
            prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1];
3201
        }
3202
    }
3203
#endif
3204
3205
    /*
3206
    VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some
3207
    reason. The ugly version above is faster so we'll just switch between the two depending on the target platform.
3208
    */
3209
0
#ifdef DRFLAC_64BIT
3210
0
    prediction = 0;
3211
0
    switch (order)
3212
0
    {
3213
0
    case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
3214
0
    case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
3215
0
    case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
3216
0
    case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
3217
0
    case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
3218
0
    case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
3219
0
    case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
3220
0
    case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
3221
0
    case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
3222
0
    case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
3223
0
    case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
3224
0
    case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
3225
0
    case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
3226
0
    case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
3227
0
    case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
3228
0
    case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
3229
0
    case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
3230
0
    case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
3231
0
    case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
3232
0
    case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
3233
0
    case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
3234
0
    case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
3235
0
    case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
3236
0
    case  9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
3237
0
    case  8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
3238
0
    case  7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
3239
0
    case  6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
3240
0
    case  5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
3241
0
    case  4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
3242
0
    case  3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
3243
0
    case  2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
3244
0
    case  1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
3245
0
    }
3246
0
#endif
3247
3248
0
    return (drflac_int32)(prediction >> shift);
3249
0
}
3250
3251
3252
#if 0
3253
/*
3254
Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the
3255
sake of readability and should only be used as a reference.
3256
*/
3257
static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3258
{
3259
    drflac_uint32 i;
3260
3261
    DRFLAC_ASSERT(bs != NULL);
3262
    DRFLAC_ASSERT(pSamplesOut != NULL);
3263
3264
    for (i = 0; i < count; ++i) {
3265
        drflac_uint32 zeroCounter = 0;
3266
        for (;;) {
3267
            drflac_uint8 bit;
3268
            if (!drflac__read_uint8(bs, 1, &bit)) {
3269
                return DRFLAC_FALSE;
3270
            }
3271
3272
            if (bit == 0) {
3273
                zeroCounter += 1;
3274
            } else {
3275
                break;
3276
            }
3277
        }
3278
3279
        drflac_uint32 decodedRice;
3280
        if (riceParam > 0) {
3281
            if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
3282
                return DRFLAC_FALSE;
3283
            }
3284
        } else {
3285
            decodedRice = 0;
3286
        }
3287
3288
        decodedRice |= (zeroCounter << riceParam);
3289
        if ((decodedRice & 0x01)) {
3290
            decodedRice = ~(decodedRice >> 1);
3291
        } else {
3292
            decodedRice =  (decodedRice >> 1);
3293
        }
3294
3295
3296
        if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3297
            pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
3298
        } else {
3299
            pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
3300
        }
3301
    }
3302
3303
    return DRFLAC_TRUE;
3304
}
3305
#endif
3306
3307
#if 0
3308
static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3309
{
3310
    drflac_uint32 zeroCounter = 0;
3311
    drflac_uint32 decodedRice;
3312
3313
    for (;;) {
3314
        drflac_uint8 bit;
3315
        if (!drflac__read_uint8(bs, 1, &bit)) {
3316
            return DRFLAC_FALSE;
3317
        }
3318
3319
        if (bit == 0) {
3320
            zeroCounter += 1;
3321
        } else {
3322
            break;
3323
        }
3324
    }
3325
3326
    if (riceParam > 0) {
3327
        if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
3328
            return DRFLAC_FALSE;
3329
        }
3330
    } else {
3331
        decodedRice = 0;
3332
    }
3333
3334
    *pZeroCounterOut = zeroCounter;
3335
    *pRiceParamPartOut = decodedRice;
3336
    return DRFLAC_TRUE;
3337
}
3338
#endif
3339
3340
#if 0
3341
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3342
{
3343
    drflac_cache_t riceParamMask;
3344
    drflac_uint32 zeroCounter;
3345
    drflac_uint32 setBitOffsetPlus1;
3346
    drflac_uint32 riceParamPart;
3347
    drflac_uint32 riceLength;
3348
3349
    DRFLAC_ASSERT(riceParam > 0);   /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */
3350
3351
    riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
3352
3353
    zeroCounter = 0;
3354
    while (bs->cache == 0) {
3355
        zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
3356
        if (!drflac__reload_cache(bs)) {
3357
            return DRFLAC_FALSE;
3358
        }
3359
    }
3360
3361
    setBitOffsetPlus1 = drflac__clz(bs->cache);
3362
    zeroCounter += setBitOffsetPlus1;
3363
    setBitOffsetPlus1 += 1;
3364
3365
    riceLength = setBitOffsetPlus1 + riceParam;
3366
    if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3367
        riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
3368
3369
        bs->consumedBits += riceLength;
3370
        bs->cache <<= riceLength;
3371
    } else {
3372
        drflac_uint32 bitCountLo;
3373
        drflac_cache_t resultHi;
3374
3375
        bs->consumedBits += riceLength;
3376
        bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1);    /* <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }" */
3377
3378
        /* 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. */
3379
        bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
3380
        resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam);  /* <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0. */
3381
3382
        if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3383
#ifndef DR_FLAC_NO_CRC
3384
            drflac__update_crc16(bs);
3385
#endif
3386
            bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3387
            bs->consumedBits = 0;
3388
#ifndef DR_FLAC_NO_CRC
3389
            bs->crc16Cache = bs->cache;
3390
#endif
3391
        } else {
3392
            /* Slow path. We need to fetch more data from the client. */
3393
            if (!drflac__reload_cache(bs)) {
3394
                return DRFLAC_FALSE;
3395
            }
3396
            if (bitCountLo > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3397
                /* This happens when we get to end of stream */
3398
                return DRFLAC_FALSE;
3399
            }
3400
        }
3401
3402
        riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
3403
3404
        bs->consumedBits += bitCountLo;
3405
        bs->cache <<= bitCountLo;
3406
    }
3407
3408
    pZeroCounterOut[0] = zeroCounter;
3409
    pRiceParamPartOut[0] = riceParamPart;
3410
3411
    return DRFLAC_TRUE;
3412
}
3413
#endif
3414
3415
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
3416
0
{
3417
0
    drflac_uint32  riceParamPlus1 = riceParam + 1;
3418
    /*drflac_cache_t riceParamPlus1Mask  = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/
3419
0
    drflac_uint32  riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
3420
0
    drflac_uint32  riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
3421
3422
    /*
3423
    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
3424
    no idea how this will work in practice...
3425
    */
3426
0
    drflac_cache_t bs_cache = bs->cache;
3427
0
    drflac_uint32  bs_consumedBits = bs->consumedBits;
3428
3429
    /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
3430
0
    drflac_uint32  lzcount = drflac__clz(bs_cache);
3431
0
    if (lzcount < sizeof(bs_cache)*8) {
3432
0
        pZeroCounterOut[0] = lzcount;
3433
3434
        /*
3435
        It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
3436
        this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
3437
        outside of this function at a higher level.
3438
        */
3439
0
    extract_rice_param_part:
3440
0
        bs_cache       <<= lzcount;
3441
0
        bs_consumedBits += lzcount;
3442
3443
0
        if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
3444
            /* Getting here means the rice parameter part is wholly contained within the current cache line. */
3445
0
            pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
3446
0
            bs_cache       <<= riceParamPlus1;
3447
0
            bs_consumedBits += riceParamPlus1;
3448
0
        } else {
3449
0
            drflac_uint32 riceParamPartHi;
3450
0
            drflac_uint32 riceParamPartLo;
3451
0
            drflac_uint32 riceParamPartLoBitCount;
3452
3453
            /*
3454
            Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
3455
            line, reload the cache, and then combine it with the head of the next cache line.
3456
            */
3457
3458
            /* Grab the high part of the rice parameter part. */
3459
0
            riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
3460
3461
            /* Before reloading the cache we need to grab the size in bits of the low part. */
3462
0
            riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
3463
0
            DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
3464
3465
            /* Now reload the cache. */
3466
0
            if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3467
0
            #ifndef DR_FLAC_NO_CRC
3468
0
                drflac__update_crc16(bs);
3469
0
            #endif
3470
0
                bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3471
0
                bs_consumedBits = riceParamPartLoBitCount;
3472
0
            #ifndef DR_FLAC_NO_CRC
3473
0
                bs->crc16Cache = bs_cache;
3474
0
            #endif
3475
0
            } else {
3476
                /* Slow path. We need to fetch more data from the client. */
3477
0
                if (!drflac__reload_cache(bs)) {
3478
0
                    return DRFLAC_FALSE;
3479
0
                }
3480
0
                if (riceParamPartLoBitCount > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3481
                    /* This happens when we get to end of stream */
3482
0
                    return DRFLAC_FALSE;
3483
0
                }
3484
3485
0
                bs_cache = bs->cache;
3486
0
                bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
3487
0
            }
3488
3489
            /* We should now have enough information to construct the rice parameter part. */
3490
0
            riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount)));
3491
0
            pRiceParamPartOut[0] = riceParamPartHi | riceParamPartLo;
3492
3493
0
            bs_cache <<= riceParamPartLoBitCount;
3494
0
        }
3495
0
    } else {
3496
        /*
3497
        Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
3498
        to drflac__clz() and we need to reload the cache.
3499
        */
3500
0
        drflac_uint32 zeroCounter = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs_consumedBits);
3501
0
        for (;;) {
3502
0
            if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3503
0
            #ifndef DR_FLAC_NO_CRC
3504
0
                drflac__update_crc16(bs);
3505
0
            #endif
3506
0
                bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3507
0
                bs_consumedBits = 0;
3508
0
            #ifndef DR_FLAC_NO_CRC
3509
0
                bs->crc16Cache = bs_cache;
3510
0
            #endif
3511
0
            } else {
3512
                /* Slow path. We need to fetch more data from the client. */
3513
0
                if (!drflac__reload_cache(bs)) {
3514
0
                    return DRFLAC_FALSE;
3515
0
                }
3516
3517
0
                bs_cache = bs->cache;
3518
0
                bs_consumedBits = bs->consumedBits;
3519
0
            }
3520
3521
0
            lzcount = drflac__clz(bs_cache);
3522
0
            zeroCounter += lzcount;
3523
3524
0
            if (lzcount < sizeof(bs_cache)*8) {
3525
0
                break;
3526
0
            }
3527
0
        }
3528
3529
0
        pZeroCounterOut[0] = zeroCounter;
3530
0
        goto extract_rice_param_part;
3531
0
    }
3532
3533
    /* Make sure the cache is restored at the end of it all. */
3534
0
    bs->cache = bs_cache;
3535
0
    bs->consumedBits = bs_consumedBits;
3536
3537
0
    return DRFLAC_TRUE;
3538
0
}
3539
3540
static DRFLAC_INLINE drflac_bool32 drflac__seek_rice_parts(drflac_bs* bs, drflac_uint8 riceParam)
3541
0
{
3542
0
    drflac_uint32  riceParamPlus1 = riceParam + 1;
3543
0
    drflac_uint32  riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
3544
3545
    /*
3546
    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
3547
    no idea how this will work in practice...
3548
    */
3549
0
    drflac_cache_t bs_cache = bs->cache;
3550
0
    drflac_uint32  bs_consumedBits = bs->consumedBits;
3551
3552
    /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
3553
0
    drflac_uint32  lzcount = drflac__clz(bs_cache);
3554
0
    if (lzcount < sizeof(bs_cache)*8) {
3555
        /*
3556
        It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
3557
        this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
3558
        outside of this function at a higher level.
3559
        */
3560
0
    extract_rice_param_part:
3561
0
        bs_cache       <<= lzcount;
3562
0
        bs_consumedBits += lzcount;
3563
3564
0
        if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
3565
            /* Getting here means the rice parameter part is wholly contained within the current cache line. */
3566
0
            bs_cache       <<= riceParamPlus1;
3567
0
            bs_consumedBits += riceParamPlus1;
3568
0
        } else {
3569
            /*
3570
            Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
3571
            line, reload the cache, and then combine it with the head of the next cache line.
3572
            */
3573
3574
            /* Before reloading the cache we need to grab the size in bits of the low part. */
3575
0
            drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
3576
0
            DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
3577
3578
            /* Now reload the cache. */
3579
0
            if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3580
0
            #ifndef DR_FLAC_NO_CRC
3581
0
                drflac__update_crc16(bs);
3582
0
            #endif
3583
0
                bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3584
0
                bs_consumedBits = riceParamPartLoBitCount;
3585
0
            #ifndef DR_FLAC_NO_CRC
3586
0
                bs->crc16Cache = bs_cache;
3587
0
            #endif
3588
0
            } else {
3589
                /* Slow path. We need to fetch more data from the client. */
3590
0
                if (!drflac__reload_cache(bs)) {
3591
0
                    return DRFLAC_FALSE;
3592
0
                }
3593
3594
0
                if (riceParamPartLoBitCount > DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
3595
                    /* This happens when we get to end of stream */
3596
0
                    return DRFLAC_FALSE;
3597
0
                }
3598
3599
0
                bs_cache = bs->cache;
3600
0
                bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
3601
0
            }
3602
3603
0
            bs_cache <<= riceParamPartLoBitCount;
3604
0
        }
3605
0
    } else {
3606
        /*
3607
        Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call
3608
        to drflac__clz() and we need to reload the cache.
3609
        */
3610
0
        for (;;) {
3611
0
            if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
3612
0
            #ifndef DR_FLAC_NO_CRC
3613
0
                drflac__update_crc16(bs);
3614
0
            #endif
3615
0
                bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
3616
0
                bs_consumedBits = 0;
3617
0
            #ifndef DR_FLAC_NO_CRC
3618
0
                bs->crc16Cache = bs_cache;
3619
0
            #endif
3620
0
            } else {
3621
                /* Slow path. We need to fetch more data from the client. */
3622
0
                if (!drflac__reload_cache(bs)) {
3623
0
                    return DRFLAC_FALSE;
3624
0
                }
3625
3626
0
                bs_cache = bs->cache;
3627
0
                bs_consumedBits = bs->consumedBits;
3628
0
            }
3629
3630
0
            lzcount = drflac__clz(bs_cache);
3631
0
            if (lzcount < sizeof(bs_cache)*8) {
3632
0
                break;
3633
0
            }
3634
0
        }
3635
3636
0
        goto extract_rice_param_part;
3637
0
    }
3638
3639
    /* Make sure the cache is restored at the end of it all. */
3640
0
    bs->cache = bs_cache;
3641
0
    bs->consumedBits = bs_consumedBits;
3642
3643
0
    return DRFLAC_TRUE;
3644
0
}
3645
3646
3647
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)
3648
0
{
3649
0
    drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3650
0
    drflac_uint32 zeroCountPart0;
3651
0
    drflac_uint32 riceParamPart0;
3652
0
    drflac_uint32 riceParamMask;
3653
0
    drflac_uint32 i;
3654
3655
0
    DRFLAC_ASSERT(bs != NULL);
3656
0
    DRFLAC_ASSERT(pSamplesOut != NULL);
3657
3658
0
    (void)bitsPerSample;
3659
0
    (void)order;
3660
0
    (void)shift;
3661
0
    (void)coefficients;
3662
3663
0
    riceParamMask  = (drflac_uint32)~((~0UL) << riceParam);
3664
3665
0
    i = 0;
3666
0
    while (i < count) {
3667
        /* Rice extraction. */
3668
0
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3669
0
            return DRFLAC_FALSE;
3670
0
        }
3671
3672
        /* Rice reconstruction. */
3673
0
        riceParamPart0 &= riceParamMask;
3674
0
        riceParamPart0 |= (zeroCountPart0 << riceParam);
3675
0
        riceParamPart0  = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3676
3677
0
        pSamplesOut[i] = riceParamPart0;
3678
3679
0
        i += 1;
3680
0
    }
3681
3682
0
    return DRFLAC_TRUE;
3683
0
}
3684
3685
static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
3686
0
{
3687
0
    drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3688
0
    drflac_uint32 zeroCountPart0 = 0;
3689
0
    drflac_uint32 zeroCountPart1 = 0;
3690
0
    drflac_uint32 zeroCountPart2 = 0;
3691
0
    drflac_uint32 zeroCountPart3 = 0;
3692
0
    drflac_uint32 riceParamPart0 = 0;
3693
0
    drflac_uint32 riceParamPart1 = 0;
3694
0
    drflac_uint32 riceParamPart2 = 0;
3695
0
    drflac_uint32 riceParamPart3 = 0;
3696
0
    drflac_uint32 riceParamMask;
3697
0
    const drflac_int32* pSamplesOutEnd;
3698
0
    drflac_uint32 i;
3699
3700
0
    DRFLAC_ASSERT(bs != NULL);
3701
0
    DRFLAC_ASSERT(pSamplesOut != NULL);
3702
3703
0
    if (lpcOrder == 0) {
3704
0
        return drflac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
3705
0
    }
3706
3707
0
    riceParamMask  = (drflac_uint32)~((~0UL) << riceParam);
3708
0
    pSamplesOutEnd = pSamplesOut + (count & ~3);
3709
3710
0
    if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3711
0
        while (pSamplesOut < pSamplesOutEnd) {
3712
            /*
3713
            Rice extraction. It's faster to do this one at a time against local variables than it is to use the x4 version
3714
            against an array. Not sure why, but perhaps it's making more efficient use of registers?
3715
            */
3716
0
            if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3717
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3718
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3719
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3720
0
                return DRFLAC_FALSE;
3721
0
            }
3722
3723
0
            riceParamPart0 &= riceParamMask;
3724
0
            riceParamPart1 &= riceParamMask;
3725
0
            riceParamPart2 &= riceParamMask;
3726
0
            riceParamPart3 &= riceParamMask;
3727
3728
0
            riceParamPart0 |= (zeroCountPart0 << riceParam);
3729
0
            riceParamPart1 |= (zeroCountPart1 << riceParam);
3730
0
            riceParamPart2 |= (zeroCountPart2 << riceParam);
3731
0
            riceParamPart3 |= (zeroCountPart3 << riceParam);
3732
3733
0
            riceParamPart0  = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3734
0
            riceParamPart1  = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3735
0
            riceParamPart2  = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3736
0
            riceParamPart3  = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3737
3738
0
            pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3739
0
            pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
3740
0
            pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
3741
0
            pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
3742
3743
0
            pSamplesOut += 4;
3744
0
        }
3745
0
    } else {
3746
0
        while (pSamplesOut < pSamplesOutEnd) {
3747
0
            if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
3748
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
3749
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
3750
0
                !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
3751
0
                return DRFLAC_FALSE;
3752
0
            }
3753
3754
0
            riceParamPart0 &= riceParamMask;
3755
0
            riceParamPart1 &= riceParamMask;
3756
0
            riceParamPart2 &= riceParamMask;
3757
0
            riceParamPart3 &= riceParamMask;
3758
3759
0
            riceParamPart0 |= (zeroCountPart0 << riceParam);
3760
0
            riceParamPart1 |= (zeroCountPart1 << riceParam);
3761
0
            riceParamPart2 |= (zeroCountPart2 << riceParam);
3762
0
            riceParamPart3 |= (zeroCountPart3 << riceParam);
3763
3764
0
            riceParamPart0  = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3765
0
            riceParamPart1  = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
3766
0
            riceParamPart2  = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
3767
0
            riceParamPart3  = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
3768
3769
0
            pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3770
0
            pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
3771
0
            pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
3772
0
            pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
3773
3774
0
            pSamplesOut += 4;
3775
0
        }
3776
0
    }
3777
3778
0
    i = (count & ~3);
3779
0
    while (i < count) {
3780
        /* Rice extraction. */
3781
0
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
3782
0
            return DRFLAC_FALSE;
3783
0
        }
3784
3785
        /* Rice reconstruction. */
3786
0
        riceParamPart0 &= riceParamMask;
3787
0
        riceParamPart0 |= (zeroCountPart0 << riceParam);
3788
0
        riceParamPart0  = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
3789
        /*riceParamPart0  = (riceParamPart0 >> 1) ^ (~(riceParamPart0 & 0x01) + 1);*/
3790
3791
        /* Sample reconstruction. */
3792
0
        if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
3793
0
            pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3794
0
        } else {
3795
0
            pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
3796
0
        }
3797
3798
0
        i += 1;
3799
0
        pSamplesOut += 1;
3800
0
    }
3801
3802
0
    return DRFLAC_TRUE;
3803
0
}
3804
3805
#if defined(DRFLAC_SUPPORT_SSE2)
3806
static DRFLAC_INLINE __m128i drflac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
3807
0
{
3808
0
    __m128i r;
3809
3810
    /* Pack. */
3811
0
    r = _mm_packs_epi32(a, b);
3812
3813
    /* a3a2 a1a0 b3b2 b1b0 -> a3a2 b3b2 a1a0 b1b0 */
3814
0
    r = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 1, 2, 0));
3815
3816
    /* a3a2 b3b2 a1a0 b1b0 -> a3b3 a2b2 a1b1 a0b0 */
3817
0
    r = _mm_shufflehi_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3818
0
    r = _mm_shufflelo_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
3819
3820
0
    return r;
3821
0
}
3822
#endif
3823
3824
#if defined(DRFLAC_SUPPORT_SSE41)
3825
static DRFLAC_INLINE __m128i drflac__mm_not_si128(__m128i a)
3826
{
3827
    return _mm_xor_si128(a, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()));
3828
}
3829
3830
static DRFLAC_INLINE __m128i drflac__mm_hadd_epi32(__m128i x)
3831
{
3832
    __m128i x64 = _mm_add_epi32(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3833
    __m128i x32 = _mm_shufflelo_epi16(x64, _MM_SHUFFLE(1, 0, 3, 2));
3834
    return _mm_add_epi32(x64, x32);
3835
}
3836
3837
static DRFLAC_INLINE __m128i drflac__mm_hadd_epi64(__m128i x)
3838
{
3839
    return _mm_add_epi64(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
3840
}
3841
3842
static DRFLAC_INLINE __m128i drflac__mm_srai_epi64(__m128i x, int count)
3843
{
3844
    /*
3845
    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
3846
    is shifted with zero bits, whereas the right side is shifted with sign bits.
3847
    */
3848
    __m128i lo = _mm_srli_epi64(x, count);
3849
    __m128i hi = _mm_srai_epi32(x, count);
3850
3851
    hi = _mm_and_si128(hi, _mm_set_epi32(0xFFFFFFFF, 0, 0xFFFFFFFF, 0));    /* The high part needs to have the low part cleared. */
3852
3853
    return _mm_or_si128(lo, hi);
3854
}
3855
3856
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)
3857
{
3858
    int i;
3859
    drflac_uint32 riceParamMask;
3860
    drflac_int32* pDecodedSamples    = pSamplesOut;
3861
    drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
3862
    drflac_uint32 zeroCountParts0 = 0;
3863
    drflac_uint32 zeroCountParts1 = 0;
3864
    drflac_uint32 zeroCountParts2 = 0;
3865
    drflac_uint32 zeroCountParts3 = 0;
3866
    drflac_uint32 riceParamParts0 = 0;
3867
    drflac_uint32 riceParamParts1 = 0;
3868
    drflac_uint32 riceParamParts2 = 0;
3869
    drflac_uint32 riceParamParts3 = 0;
3870
    __m128i coefficients128_0;
3871
    __m128i coefficients128_4;
3872
    __m128i coefficients128_8;
3873
    __m128i samples128_0;
3874
    __m128i samples128_4;
3875
    __m128i samples128_8;
3876
    __m128i riceParamMask128;
3877
3878
    const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
3879
3880
    riceParamMask    = (drflac_uint32)~((~0UL) << riceParam);
3881
    riceParamMask128 = _mm_set1_epi32(riceParamMask);
3882
3883
    /* Pre-load. */
3884
    coefficients128_0 = _mm_setzero_si128();
3885
    coefficients128_4 = _mm_setzero_si128();
3886
    coefficients128_8 = _mm_setzero_si128();
3887
3888
    samples128_0 = _mm_setzero_si128();
3889
    samples128_4 = _mm_setzero_si128();
3890
    samples128_8 = _mm_setzero_si128();
3891
3892
    /*
3893
    Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
3894
    what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
3895
    in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
3896
    so I think there's opportunity for this to be simplified.
3897
    */
3898
#if 1
3899
    {
3900
        int runningOrder = order;
3901
3902
        /* 0 - 3. */
3903
        if (runningOrder >= 4) {
3904
            coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
3905
            samples128_0      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 4));
3906
            runningOrder -= 4;
3907
        } else {
3908
            switch (runningOrder) {
3909
                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;
3910
                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;
3911
                case 1: coefficients128_0 = _mm_set_epi32(0, 0,               0,               coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0,               0,               0); break;
3912
            }
3913
            runningOrder = 0;
3914
        }
3915
3916
        /* 4 - 7 */
3917
        if (runningOrder >= 4) {
3918
            coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
3919
            samples128_4      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 8));
3920
            runningOrder -= 4;
3921
        } else {
3922
            switch (runningOrder) {
3923
                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;
3924
                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;
3925
                case 1: coefficients128_4 = _mm_set_epi32(0, 0,               0,               coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0,               0,               0); break;
3926
            }
3927
            runningOrder = 0;
3928
        }
3929
3930
        /* 8 - 11 */
3931
        if (runningOrder == 4) {
3932
            coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
3933
            samples128_8      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 12));
3934
            runningOrder -= 4;
3935
        } else {
3936
            switch (runningOrder) {
3937
                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;
3938
                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;
3939
                case 1: coefficients128_8 = _mm_set_epi32(0, 0,                0,               coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0,                0,                0); break;
3940
            }
3941
            runningOrder = 0;
3942
        }
3943
3944
        /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
3945
        coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
3946
        coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
3947
        coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
3948
    }
3949
#else
3950
    /* This causes strict-aliasing warnings with GCC. */
3951
    switch (order)
3952
    {
3953
    case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
3954
    case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
3955
    case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
3956
    case 9:  ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
3957
    case 8:  ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
3958
    case 7:  ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
3959
    case 6:  ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
3960
    case 5:  ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
3961
    case 4:  ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
3962
    case 3:  ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
3963
    case 2:  ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
3964
    case 1:  ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
3965
    }
3966
#endif
3967
3968
    /* For this version we are doing one sample at a time. */
3969
    while (pDecodedSamples < pDecodedSamplesEnd) {
3970
        __m128i prediction128;
3971
        __m128i zeroCountPart128;
3972
        __m128i riceParamPart128;
3973
3974
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
3975
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
3976
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
3977
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
3978
            return DRFLAC_FALSE;
3979
        }
3980
3981
        zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
3982
        riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
3983
3984
        riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
3985
        riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
3986
        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 */
3987
        /*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... */
3988
3989
        if (order <= 4) {
3990
            for (i = 0; i < 4; i += 1) {
3991
                prediction128 = _mm_mullo_epi32(coefficients128_0, samples128_0);
3992
3993
                /* Horizontal add and shift. */
3994
                prediction128 = drflac__mm_hadd_epi32(prediction128);
3995
                prediction128 = _mm_srai_epi32(prediction128, shift);
3996
                prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
3997
3998
                samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
3999
                riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4000
            }
4001
        } else if (order <= 8) {
4002
            for (i = 0; i < 4; i += 1) {
4003
                prediction128 =                              _mm_mullo_epi32(coefficients128_4, samples128_4);
4004
                prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
4005
4006
                /* Horizontal add and shift. */
4007
                prediction128 = drflac__mm_hadd_epi32(prediction128);
4008
                prediction128 = _mm_srai_epi32(prediction128, shift);
4009
                prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4010
4011
                samples128_4 = _mm_alignr_epi8(samples128_0,  samples128_4, 4);
4012
                samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4013
                riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4014
            }
4015
        } else {
4016
            for (i = 0; i < 4; i += 1) {
4017
                prediction128 =                              _mm_mullo_epi32(coefficients128_8, samples128_8);
4018
                prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_4, samples128_4));
4019
                prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
4020
4021
                /* Horizontal add and shift. */
4022
                prediction128 = drflac__mm_hadd_epi32(prediction128);
4023
                prediction128 = _mm_srai_epi32(prediction128, shift);
4024
                prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4025
4026
                samples128_8 = _mm_alignr_epi8(samples128_4,  samples128_8, 4);
4027
                samples128_4 = _mm_alignr_epi8(samples128_0,  samples128_4, 4);
4028
                samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4029
                riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4030
            }
4031
        }
4032
4033
        /* We store samples in groups of 4. */
4034
        _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
4035
        pDecodedSamples += 4;
4036
    }
4037
4038
    /* Make sure we process the last few samples. */
4039
    i = (count & ~3);
4040
    while (i < (int)count) {
4041
        /* Rice extraction. */
4042
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
4043
            return DRFLAC_FALSE;
4044
        }
4045
4046
        /* Rice reconstruction. */
4047
        riceParamParts0 &= riceParamMask;
4048
        riceParamParts0 |= (zeroCountParts0 << riceParam);
4049
        riceParamParts0  = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
4050
4051
        /* Sample reconstruction. */
4052
        pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
4053
4054
        i += 1;
4055
        pDecodedSamples += 1;
4056
    }
4057
4058
    return DRFLAC_TRUE;
4059
}
4060
4061
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)
4062
{
4063
    int i;
4064
    drflac_uint32 riceParamMask;
4065
    drflac_int32* pDecodedSamples    = pSamplesOut;
4066
    drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4067
    drflac_uint32 zeroCountParts0 = 0;
4068
    drflac_uint32 zeroCountParts1 = 0;
4069
    drflac_uint32 zeroCountParts2 = 0;
4070
    drflac_uint32 zeroCountParts3 = 0;
4071
    drflac_uint32 riceParamParts0 = 0;
4072
    drflac_uint32 riceParamParts1 = 0;
4073
    drflac_uint32 riceParamParts2 = 0;
4074
    drflac_uint32 riceParamParts3 = 0;
4075
    __m128i coefficients128_0;
4076
    __m128i coefficients128_4;
4077
    __m128i coefficients128_8;
4078
    __m128i samples128_0;
4079
    __m128i samples128_4;
4080
    __m128i samples128_8;
4081
    __m128i prediction128;
4082
    __m128i riceParamMask128;
4083
4084
    const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4085
4086
    DRFLAC_ASSERT(order <= 12);
4087
4088
    riceParamMask    = (drflac_uint32)~((~0UL) << riceParam);
4089
    riceParamMask128 = _mm_set1_epi32(riceParamMask);
4090
4091
    prediction128 = _mm_setzero_si128();
4092
4093
    /* Pre-load. */
4094
    coefficients128_0  = _mm_setzero_si128();
4095
    coefficients128_4  = _mm_setzero_si128();
4096
    coefficients128_8  = _mm_setzero_si128();
4097
4098
    samples128_0  = _mm_setzero_si128();
4099
    samples128_4  = _mm_setzero_si128();
4100
    samples128_8  = _mm_setzero_si128();
4101
4102
#if 1
4103
    {
4104
        int runningOrder = order;
4105
4106
        /* 0 - 3. */
4107
        if (runningOrder >= 4) {
4108
            coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
4109
            samples128_0      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 4));
4110
            runningOrder -= 4;
4111
        } else {
4112
            switch (runningOrder) {
4113
                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;
4114
                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;
4115
                case 1: coefficients128_0 = _mm_set_epi32(0, 0,               0,               coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0,               0,               0); break;
4116
            }
4117
            runningOrder = 0;
4118
        }
4119
4120
        /* 4 - 7 */
4121
        if (runningOrder >= 4) {
4122
            coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
4123
            samples128_4      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 8));
4124
            runningOrder -= 4;
4125
        } else {
4126
            switch (runningOrder) {
4127
                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;
4128
                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;
4129
                case 1: coefficients128_4 = _mm_set_epi32(0, 0,               0,               coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0,               0,               0); break;
4130
            }
4131
            runningOrder = 0;
4132
        }
4133
4134
        /* 8 - 11 */
4135
        if (runningOrder == 4) {
4136
            coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
4137
            samples128_8      = _mm_loadu_si128((const __m128i*)(pSamplesOut  - 12));
4138
            runningOrder -= 4;
4139
        } else {
4140
            switch (runningOrder) {
4141
                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;
4142
                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;
4143
                case 1: coefficients128_8 = _mm_set_epi32(0, 0,                0,               coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0,                0,                0); break;
4144
            }
4145
            runningOrder = 0;
4146
        }
4147
4148
        /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4149
        coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
4150
        coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
4151
        coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
4152
    }
4153
#else
4154
    switch (order)
4155
    {
4156
    case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
4157
    case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
4158
    case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
4159
    case 9:  ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
4160
    case 8:  ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
4161
    case 7:  ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
4162
    case 6:  ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
4163
    case 5:  ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
4164
    case 4:  ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
4165
    case 3:  ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
4166
    case 2:  ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
4167
    case 1:  ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
4168
    }
4169
#endif
4170
4171
    /* For this version we are doing one sample at a time. */
4172
    while (pDecodedSamples < pDecodedSamplesEnd) {
4173
        __m128i zeroCountPart128;
4174
        __m128i riceParamPart128;
4175
4176
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
4177
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
4178
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
4179
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
4180
            return DRFLAC_FALSE;
4181
        }
4182
4183
        zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
4184
        riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
4185
4186
        riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
4187
        riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
4188
        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)));
4189
4190
        for (i = 0; i < 4; i += 1) {
4191
            prediction128 = _mm_xor_si128(prediction128, prediction128);    /* Reset to 0. */
4192
4193
            switch (order)
4194
            {
4195
            case 12:
4196
            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))));
4197
            case 10:
4198
            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))));
4199
            case  8:
4200
            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))));
4201
            case  6:
4202
            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))));
4203
            case  4:
4204
            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))));
4205
            case  2:
4206
            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))));
4207
            }
4208
4209
            /* Horizontal add and shift. */
4210
            prediction128 = drflac__mm_hadd_epi64(prediction128);
4211
            prediction128 = drflac__mm_srai_epi64(prediction128, shift);
4212
            prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
4213
4214
            /* Our value should be sitting in prediction128[0]. We need to combine this with our SSE samples. */
4215
            samples128_8 = _mm_alignr_epi8(samples128_4,  samples128_8, 4);
4216
            samples128_4 = _mm_alignr_epi8(samples128_0,  samples128_4, 4);
4217
            samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
4218
4219
            /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
4220
            riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
4221
        }
4222
4223
        /* We store samples in groups of 4. */
4224
        _mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
4225
        pDecodedSamples += 4;
4226
    }
4227
4228
    /* Make sure we process the last few samples. */
4229
    i = (count & ~3);
4230
    while (i < (int)count) {
4231
        /* Rice extraction. */
4232
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
4233
            return DRFLAC_FALSE;
4234
        }
4235
4236
        /* Rice reconstruction. */
4237
        riceParamParts0 &= riceParamMask;
4238
        riceParamParts0 |= (zeroCountParts0 << riceParam);
4239
        riceParamParts0  = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
4240
4241
        /* Sample reconstruction. */
4242
        pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
4243
4244
        i += 1;
4245
        pDecodedSamples += 1;
4246
    }
4247
4248
    return DRFLAC_TRUE;
4249
}
4250
4251
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4252
{
4253
    DRFLAC_ASSERT(bs != NULL);
4254
    DRFLAC_ASSERT(pSamplesOut != NULL);
4255
4256
    /* 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. */
4257
    if (lpcOrder > 0 && lpcOrder <= 12) {
4258
        if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4259
            return drflac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4260
        } else {
4261
            return drflac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4262
        }
4263
    } else {
4264
        return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4265
    }
4266
}
4267
#endif
4268
4269
#if defined(DRFLAC_SUPPORT_NEON)
4270
static DRFLAC_INLINE void drflac__vst2q_s32(drflac_int32* p, int32x4x2_t x)
4271
{
4272
    vst1q_s32(p+0, x.val[0]);
4273
    vst1q_s32(p+4, x.val[1]);
4274
}
4275
4276
static DRFLAC_INLINE void drflac__vst2q_u32(drflac_uint32* p, uint32x4x2_t x)
4277
{
4278
    vst1q_u32(p+0, x.val[0]);
4279
    vst1q_u32(p+4, x.val[1]);
4280
}
4281
4282
static DRFLAC_INLINE void drflac__vst2q_f32(float* p, float32x4x2_t x)
4283
{
4284
    vst1q_f32(p+0, x.val[0]);
4285
    vst1q_f32(p+4, x.val[1]);
4286
}
4287
4288
static DRFLAC_INLINE void drflac__vst2q_s16(drflac_int16* p, int16x4x2_t x)
4289
{
4290
    vst1q_s16(p, vcombine_s16(x.val[0], x.val[1]));
4291
}
4292
4293
static DRFLAC_INLINE void drflac__vst2q_u16(drflac_uint16* p, uint16x4x2_t x)
4294
{
4295
    vst1q_u16(p, vcombine_u16(x.val[0], x.val[1]));
4296
}
4297
4298
static DRFLAC_INLINE int32x4_t drflac__vdupq_n_s32x4(drflac_int32 x3, drflac_int32 x2, drflac_int32 x1, drflac_int32 x0)
4299
{
4300
    drflac_int32 x[4];
4301
    x[3] = x3;
4302
    x[2] = x2;
4303
    x[1] = x1;
4304
    x[0] = x0;
4305
    return vld1q_s32(x);
4306
}
4307
4308
static DRFLAC_INLINE int32x4_t drflac__valignrq_s32_1(int32x4_t a, int32x4_t b)
4309
{
4310
    /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
4311
4312
    /* Reference */
4313
    /*return drflac__vdupq_n_s32x4(
4314
        vgetq_lane_s32(a, 0),
4315
        vgetq_lane_s32(b, 3),
4316
        vgetq_lane_s32(b, 2),
4317
        vgetq_lane_s32(b, 1)
4318
    );*/
4319
4320
    return vextq_s32(b, a, 1);
4321
}
4322
4323
static DRFLAC_INLINE uint32x4_t drflac__valignrq_u32_1(uint32x4_t a, uint32x4_t b)
4324
{
4325
    /* Equivalent to SSE's _mm_alignr_epi8(a, b, 4) */
4326
4327
    /* Reference */
4328
    /*return drflac__vdupq_n_s32x4(
4329
        vgetq_lane_s32(a, 0),
4330
        vgetq_lane_s32(b, 3),
4331
        vgetq_lane_s32(b, 2),
4332
        vgetq_lane_s32(b, 1)
4333
    );*/
4334
4335
    return vextq_u32(b, a, 1);
4336
}
4337
4338
static DRFLAC_INLINE int32x2_t drflac__vhaddq_s32(int32x4_t x)
4339
{
4340
    /* The sum must end up in position 0. */
4341
4342
    /* Reference */
4343
    /*return vdupq_n_s32(
4344
        vgetq_lane_s32(x, 3) +
4345
        vgetq_lane_s32(x, 2) +
4346
        vgetq_lane_s32(x, 1) +
4347
        vgetq_lane_s32(x, 0)
4348
    );*/
4349
4350
    int32x2_t r = vadd_s32(vget_high_s32(x), vget_low_s32(x));
4351
    return vpadd_s32(r, r);
4352
}
4353
4354
static DRFLAC_INLINE int64x1_t drflac__vhaddq_s64(int64x2_t x)
4355
{
4356
    return vadd_s64(vget_high_s64(x), vget_low_s64(x));
4357
}
4358
4359
static DRFLAC_INLINE int32x4_t drflac__vrevq_s32(int32x4_t x)
4360
{
4361
    /* Reference */
4362
    /*return drflac__vdupq_n_s32x4(
4363
        vgetq_lane_s32(x, 0),
4364
        vgetq_lane_s32(x, 1),
4365
        vgetq_lane_s32(x, 2),
4366
        vgetq_lane_s32(x, 3)
4367
    );*/
4368
4369
    return vrev64q_s32(vcombine_s32(vget_high_s32(x), vget_low_s32(x)));
4370
}
4371
4372
static DRFLAC_INLINE int32x4_t drflac__vnotq_s32(int32x4_t x)
4373
{
4374
    return veorq_s32(x, vdupq_n_s32(0xFFFFFFFF));
4375
}
4376
4377
static DRFLAC_INLINE uint32x4_t drflac__vnotq_u32(uint32x4_t x)
4378
{
4379
    return veorq_u32(x, vdupq_n_u32(0xFFFFFFFF));
4380
}
4381
4382
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)
4383
{
4384
    int i;
4385
    drflac_uint32 riceParamMask;
4386
    drflac_int32* pDecodedSamples    = pSamplesOut;
4387
    drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4388
    drflac_uint32 zeroCountParts[4];
4389
    drflac_uint32 riceParamParts[4];
4390
    int32x4_t coefficients128_0;
4391
    int32x4_t coefficients128_4;
4392
    int32x4_t coefficients128_8;
4393
    int32x4_t samples128_0;
4394
    int32x4_t samples128_4;
4395
    int32x4_t samples128_8;
4396
    uint32x4_t riceParamMask128;
4397
    int32x4_t riceParam128;
4398
    int32x2_t shift64;
4399
    uint32x4_t one128;
4400
4401
    const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4402
4403
    riceParamMask    = (drflac_uint32)~((~0UL) << riceParam);
4404
    riceParamMask128 = vdupq_n_u32(riceParamMask);
4405
4406
    riceParam128 = vdupq_n_s32(riceParam);
4407
    shift64 = vdup_n_s32(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
4408
    one128 = vdupq_n_u32(1);
4409
4410
    /*
4411
    Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
4412
    what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
4413
    in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
4414
    so I think there's opportunity for this to be simplified.
4415
    */
4416
    {
4417
        int runningOrder = order;
4418
        drflac_int32 tempC[4] = {0, 0, 0, 0};
4419
        drflac_int32 tempS[4] = {0, 0, 0, 0};
4420
4421
        /* 0 - 3. */
4422
        if (runningOrder >= 4) {
4423
            coefficients128_0 = vld1q_s32(coefficients + 0);
4424
            samples128_0      = vld1q_s32(pSamplesOut  - 4);
4425
            runningOrder -= 4;
4426
        } else {
4427
            switch (runningOrder) {
4428
                case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
4429
                case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
4430
                case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
4431
            }
4432
4433
            coefficients128_0 = vld1q_s32(tempC);
4434
            samples128_0      = vld1q_s32(tempS);
4435
            runningOrder = 0;
4436
        }
4437
4438
        /* 4 - 7 */
4439
        if (runningOrder >= 4) {
4440
            coefficients128_4 = vld1q_s32(coefficients + 4);
4441
            samples128_4      = vld1q_s32(pSamplesOut  - 8);
4442
            runningOrder -= 4;
4443
        } else {
4444
            switch (runningOrder) {
4445
                case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
4446
                case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
4447
                case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
4448
            }
4449
4450
            coefficients128_4 = vld1q_s32(tempC);
4451
            samples128_4      = vld1q_s32(tempS);
4452
            runningOrder = 0;
4453
        }
4454
4455
        /* 8 - 11 */
4456
        if (runningOrder == 4) {
4457
            coefficients128_8 = vld1q_s32(coefficients + 8);
4458
            samples128_8      = vld1q_s32(pSamplesOut  - 12);
4459
            runningOrder -= 4;
4460
        } else {
4461
            switch (runningOrder) {
4462
                case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
4463
                case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
4464
                case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
4465
            }
4466
4467
            coefficients128_8 = vld1q_s32(tempC);
4468
            samples128_8      = vld1q_s32(tempS);
4469
            runningOrder = 0;
4470
        }
4471
4472
        /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4473
        coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
4474
        coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
4475
        coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
4476
    }
4477
4478
    /* For this version we are doing one sample at a time. */
4479
    while (pDecodedSamples < pDecodedSamplesEnd) {
4480
        int32x4_t prediction128;
4481
        int32x2_t prediction64;
4482
        uint32x4_t zeroCountPart128;
4483
        uint32x4_t riceParamPart128;
4484
4485
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
4486
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
4487
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
4488
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
4489
            return DRFLAC_FALSE;
4490
        }
4491
4492
        zeroCountPart128 = vld1q_u32(zeroCountParts);
4493
        riceParamPart128 = vld1q_u32(riceParamParts);
4494
4495
        riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
4496
        riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
4497
        riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
4498
4499
        if (order <= 4) {
4500
            for (i = 0; i < 4; i += 1) {
4501
                prediction128 = vmulq_s32(coefficients128_0, samples128_0);
4502
4503
                /* Horizontal add and shift. */
4504
                prediction64 = drflac__vhaddq_s32(prediction128);
4505
                prediction64 = vshl_s32(prediction64, shift64);
4506
                prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4507
4508
                samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4509
                riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4510
            }
4511
        } else if (order <= 8) {
4512
            for (i = 0; i < 4; i += 1) {
4513
                prediction128 =                vmulq_s32(coefficients128_4, samples128_4);
4514
                prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
4515
4516
                /* Horizontal add and shift. */
4517
                prediction64 = drflac__vhaddq_s32(prediction128);
4518
                prediction64 = vshl_s32(prediction64, shift64);
4519
                prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4520
4521
                samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4522
                samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4523
                riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4524
            }
4525
        } else {
4526
            for (i = 0; i < 4; i += 1) {
4527
                prediction128 =                vmulq_s32(coefficients128_8, samples128_8);
4528
                prediction128 = vmlaq_s32(prediction128, coefficients128_4, samples128_4);
4529
                prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
4530
4531
                /* Horizontal add and shift. */
4532
                prediction64 = drflac__vhaddq_s32(prediction128);
4533
                prediction64 = vshl_s32(prediction64, shift64);
4534
                prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
4535
4536
                samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
4537
                samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4538
                samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
4539
                riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4540
            }
4541
        }
4542
4543
        /* We store samples in groups of 4. */
4544
        vst1q_s32(pDecodedSamples, samples128_0);
4545
        pDecodedSamples += 4;
4546
    }
4547
4548
    /* Make sure we process the last few samples. */
4549
    i = (count & ~3);
4550
    while (i < (int)count) {
4551
        /* Rice extraction. */
4552
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4553
            return DRFLAC_FALSE;
4554
        }
4555
4556
        /* Rice reconstruction. */
4557
        riceParamParts[0] &= riceParamMask;
4558
        riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4559
        riceParamParts[0]  = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4560
4561
        /* Sample reconstruction. */
4562
        pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
4563
4564
        i += 1;
4565
        pDecodedSamples += 1;
4566
    }
4567
4568
    return DRFLAC_TRUE;
4569
}
4570
4571
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)
4572
{
4573
    int i;
4574
    drflac_uint32 riceParamMask;
4575
    drflac_int32* pDecodedSamples    = pSamplesOut;
4576
    drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
4577
    drflac_uint32 zeroCountParts[4];
4578
    drflac_uint32 riceParamParts[4];
4579
    int32x4_t coefficients128_0;
4580
    int32x4_t coefficients128_4;
4581
    int32x4_t coefficients128_8;
4582
    int32x4_t samples128_0;
4583
    int32x4_t samples128_4;
4584
    int32x4_t samples128_8;
4585
    uint32x4_t riceParamMask128;
4586
    int32x4_t riceParam128;
4587
    int64x1_t shift64;
4588
    uint32x4_t one128;
4589
    int64x2_t prediction128 = { 0 };
4590
    uint32x4_t zeroCountPart128;
4591
    uint32x4_t riceParamPart128;
4592
4593
    const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
4594
4595
    riceParamMask    = (drflac_uint32)~((~0UL) << riceParam);
4596
    riceParamMask128 = vdupq_n_u32(riceParamMask);
4597
4598
    riceParam128 = vdupq_n_s32(riceParam);
4599
    shift64 = vdup_n_s64(-shift); /* Negate the shift because we'll be doing a variable shift using vshlq_s32(). */
4600
    one128 = vdupq_n_u32(1);
4601
4602
    /*
4603
    Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
4604
    what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
4605
    in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
4606
    so I think there's opportunity for this to be simplified.
4607
    */
4608
    {
4609
        int runningOrder = order;
4610
        drflac_int32 tempC[4] = {0, 0, 0, 0};
4611
        drflac_int32 tempS[4] = {0, 0, 0, 0};
4612
4613
        /* 0 - 3. */
4614
        if (runningOrder >= 4) {
4615
            coefficients128_0 = vld1q_s32(coefficients + 0);
4616
            samples128_0      = vld1q_s32(pSamplesOut  - 4);
4617
            runningOrder -= 4;
4618
        } else {
4619
            switch (runningOrder) {
4620
                case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
4621
                case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
4622
                case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
4623
            }
4624
4625
            coefficients128_0 = vld1q_s32(tempC);
4626
            samples128_0      = vld1q_s32(tempS);
4627
            runningOrder = 0;
4628
        }
4629
4630
        /* 4 - 7 */
4631
        if (runningOrder >= 4) {
4632
            coefficients128_4 = vld1q_s32(coefficients + 4);
4633
            samples128_4      = vld1q_s32(pSamplesOut  - 8);
4634
            runningOrder -= 4;
4635
        } else {
4636
            switch (runningOrder) {
4637
                case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
4638
                case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
4639
                case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
4640
            }
4641
4642
            coefficients128_4 = vld1q_s32(tempC);
4643
            samples128_4      = vld1q_s32(tempS);
4644
            runningOrder = 0;
4645
        }
4646
4647
        /* 8 - 11 */
4648
        if (runningOrder == 4) {
4649
            coefficients128_8 = vld1q_s32(coefficients + 8);
4650
            samples128_8      = vld1q_s32(pSamplesOut  - 12);
4651
            runningOrder -= 4;
4652
        } else {
4653
            switch (runningOrder) {
4654
                case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
4655
                case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
4656
                case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
4657
            }
4658
4659
            coefficients128_8 = vld1q_s32(tempC);
4660
            samples128_8      = vld1q_s32(tempS);
4661
            runningOrder = 0;
4662
        }
4663
4664
        /* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
4665
        coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
4666
        coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
4667
        coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
4668
    }
4669
4670
    /* For this version we are doing one sample at a time. */
4671
    while (pDecodedSamples < pDecodedSamplesEnd) {
4672
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
4673
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
4674
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
4675
            !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
4676
            return DRFLAC_FALSE;
4677
        }
4678
4679
        zeroCountPart128 = vld1q_u32(zeroCountParts);
4680
        riceParamPart128 = vld1q_u32(riceParamParts);
4681
4682
        riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
4683
        riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
4684
        riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
4685
4686
        for (i = 0; i < 4; i += 1) {
4687
            int64x1_t prediction64;
4688
4689
            prediction128 = veorq_s64(prediction128, prediction128);    /* Reset to 0. */
4690
            switch (order)
4691
            {
4692
            case 12:
4693
            case 11: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_8), vget_low_s32(samples128_8)));
4694
            case 10:
4695
            case  9: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_8), vget_high_s32(samples128_8)));
4696
            case  8:
4697
            case  7: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_4), vget_low_s32(samples128_4)));
4698
            case  6:
4699
            case  5: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_4), vget_high_s32(samples128_4)));
4700
            case  4:
4701
            case  3: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_0), vget_low_s32(samples128_0)));
4702
            case  2:
4703
            case  1: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_0), vget_high_s32(samples128_0)));
4704
            }
4705
4706
            /* Horizontal add and shift. */
4707
            prediction64 = drflac__vhaddq_s64(prediction128);
4708
            prediction64 = vshl_s64(prediction64, shift64);
4709
            prediction64 = vadd_s64(prediction64, vdup_n_s64(vgetq_lane_u32(riceParamPart128, 0)));
4710
4711
            /* Our value should be sitting in prediction64[0]. We need to combine this with our SSE samples. */
4712
            samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
4713
            samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
4714
            samples128_0 = drflac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
4715
4716
            /* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
4717
            riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
4718
        }
4719
4720
        /* We store samples in groups of 4. */
4721
        vst1q_s32(pDecodedSamples, samples128_0);
4722
        pDecodedSamples += 4;
4723
    }
4724
4725
    /* Make sure we process the last few samples. */
4726
    i = (count & ~3);
4727
    while (i < (int)count) {
4728
        /* Rice extraction. */
4729
        if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0])) {
4730
            return DRFLAC_FALSE;
4731
        }
4732
4733
        /* Rice reconstruction. */
4734
        riceParamParts[0] &= riceParamMask;
4735
        riceParamParts[0] |= (zeroCountParts[0] << riceParam);
4736
        riceParamParts[0]  = (riceParamParts[0] >> 1) ^ t[riceParamParts[0] & 0x01];
4737
4738
        /* Sample reconstruction. */
4739
        pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
4740
4741
        i += 1;
4742
        pDecodedSamples += 1;
4743
    }
4744
4745
    return DRFLAC_TRUE;
4746
}
4747
4748
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4749
{
4750
    DRFLAC_ASSERT(bs != NULL);
4751
    DRFLAC_ASSERT(pSamplesOut != NULL);
4752
4753
    /* 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. */
4754
    if (lpcOrder > 0 && lpcOrder <= 12) {
4755
        if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4756
            return drflac__decode_samples_with_residual__rice__neon_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4757
        } else {
4758
            return drflac__decode_samples_with_residual__rice__neon_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
4759
        }
4760
    } else {
4761
        return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4762
    }
4763
}
4764
#endif
4765
4766
static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4767
0
{
4768
#if defined(DRFLAC_SUPPORT_SSE41)
4769
    if (drflac__gIsSSE41Supported) {
4770
        return drflac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4771
    } else
4772
#elif defined(DRFLAC_SUPPORT_NEON)
4773
    if (drflac__gIsNEONSupported) {
4774
        return drflac__decode_samples_with_residual__rice__neon(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4775
    } else
4776
#endif
4777
0
    {
4778
        /* Scalar fallback. */
4779
    #if 0
4780
        return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4781
    #else
4782
0
        return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
4783
0
    #endif
4784
0
    }
4785
0
}
4786
4787
/* 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. */
4788
static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam)
4789
0
{
4790
0
    drflac_uint32 i;
4791
4792
0
    DRFLAC_ASSERT(bs != NULL);
4793
4794
0
    for (i = 0; i < count; ++i) {
4795
0
        if (!drflac__seek_rice_parts(bs, riceParam)) {
4796
0
            return DRFLAC_FALSE;
4797
0
        }
4798
0
    }
4799
4800
0
    return DRFLAC_TRUE;
4801
0
}
4802
4803
#if defined(__clang__)
4804
__attribute__((no_sanitize("signed-integer-overflow")))
4805
#endif
4806
static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
4807
0
{
4808
0
    drflac_uint32 i;
4809
4810
0
    DRFLAC_ASSERT(bs != NULL);
4811
0
    DRFLAC_ASSERT(unencodedBitsPerSample <= 31);    /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
4812
0
    DRFLAC_ASSERT(pSamplesOut != NULL);
4813
4814
0
    for (i = 0; i < count; ++i) {
4815
0
        if (unencodedBitsPerSample > 0) {
4816
0
            if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
4817
0
                return DRFLAC_FALSE;
4818
0
            }
4819
0
        } else {
4820
0
            pSamplesOut[i] = 0;
4821
0
        }
4822
4823
0
        if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
4824
0
            pSamplesOut[i] += drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
4825
0
        } else {
4826
0
            pSamplesOut[i] += drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
4827
0
        }
4828
0
    }
4829
4830
0
    return DRFLAC_TRUE;
4831
0
}
4832
4833
4834
/*
4835
Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called
4836
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be ignored. The
4837
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4838
*/
4839
static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
4840
0
{
4841
0
    drflac_uint8 residualMethod;
4842
0
    drflac_uint8 partitionOrder;
4843
0
    drflac_uint32 samplesInPartition;
4844
0
    drflac_uint32 partitionsRemaining;
4845
4846
0
    DRFLAC_ASSERT(bs != NULL);
4847
0
    DRFLAC_ASSERT(blockSize != 0);
4848
0
    DRFLAC_ASSERT(pDecodedSamples != NULL);       /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */
4849
4850
0
    if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4851
0
        return DRFLAC_FALSE;
4852
0
    }
4853
4854
0
    if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4855
0
        return DRFLAC_FALSE;    /* Unknown or unsupported residual coding method. */
4856
0
    }
4857
4858
    /* Ignore the first <order> values. */
4859
0
    pDecodedSamples += lpcOrder;
4860
4861
0
    if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4862
0
        return DRFLAC_FALSE;
4863
0
    }
4864
4865
    /*
4866
    From the FLAC spec:
4867
      The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4868
    */
4869
0
    if (partitionOrder > 8) {
4870
0
        return DRFLAC_FALSE;
4871
0
    }
4872
4873
    /* Validation check. */
4874
0
    if ((blockSize / (1 << partitionOrder)) < lpcOrder) {
4875
0
        return DRFLAC_FALSE;
4876
0
    }
4877
4878
0
    samplesInPartition = (blockSize / (1 << partitionOrder)) - lpcOrder;
4879
0
    partitionsRemaining = (1 << partitionOrder);
4880
0
    for (;;) {
4881
0
        drflac_uint8 riceParam = 0;
4882
0
        if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
4883
0
            if (!drflac__read_uint8(bs, 4, &riceParam)) {
4884
0
                return DRFLAC_FALSE;
4885
0
            }
4886
0
            if (riceParam == 15) {
4887
0
                riceParam = 0xFF;
4888
0
            }
4889
0
        } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4890
0
            if (!drflac__read_uint8(bs, 5, &riceParam)) {
4891
0
                return DRFLAC_FALSE;
4892
0
            }
4893
0
            if (riceParam == 31) {
4894
0
                riceParam = 0xFF;
4895
0
            }
4896
0
        }
4897
4898
0
        if (riceParam != 0xFF) {
4899
0
            if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
4900
0
                return DRFLAC_FALSE;
4901
0
            }
4902
0
        } else {
4903
0
            drflac_uint8 unencodedBitsPerSample = 0;
4904
0
            if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
4905
0
                return DRFLAC_FALSE;
4906
0
            }
4907
4908
0
            if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
4909
0
                return DRFLAC_FALSE;
4910
0
            }
4911
0
        }
4912
4913
0
        pDecodedSamples += samplesInPartition;
4914
4915
0
        if (partitionsRemaining == 1) {
4916
0
            break;
4917
0
        }
4918
4919
0
        partitionsRemaining -= 1;
4920
4921
0
        if (partitionOrder != 0) {
4922
0
            samplesInPartition = blockSize / (1 << partitionOrder);
4923
0
        }
4924
0
    }
4925
4926
0
    return DRFLAC_TRUE;
4927
0
}
4928
4929
/*
4930
Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called
4931
when the decoder is sitting at the very start of the RESIDUAL block. The first <order> residuals will be set to 0. The
4932
<blockSize> and <order> parameters are used to determine how many residual values need to be decoded.
4933
*/
4934
static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order)
4935
0
{
4936
0
    drflac_uint8 residualMethod;
4937
0
    drflac_uint8 partitionOrder;
4938
0
    drflac_uint32 samplesInPartition;
4939
0
    drflac_uint32 partitionsRemaining;
4940
4941
0
    DRFLAC_ASSERT(bs != NULL);
4942
0
    DRFLAC_ASSERT(blockSize != 0);
4943
4944
0
    if (!drflac__read_uint8(bs, 2, &residualMethod)) {
4945
0
        return DRFLAC_FALSE;
4946
0
    }
4947
4948
0
    if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4949
0
        return DRFLAC_FALSE;    /* Unknown or unsupported residual coding method. */
4950
0
    }
4951
4952
0
    if (!drflac__read_uint8(bs, 4, &partitionOrder)) {
4953
0
        return DRFLAC_FALSE;
4954
0
    }
4955
4956
    /*
4957
    From the FLAC spec:
4958
      The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
4959
    */
4960
0
    if (partitionOrder > 8) {
4961
0
        return DRFLAC_FALSE;
4962
0
    }
4963
4964
    /* Validation check. */
4965
0
    if ((blockSize / (1 << partitionOrder)) <= order) {
4966
0
        return DRFLAC_FALSE;
4967
0
    }
4968
4969
0
    samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
4970
0
    partitionsRemaining = (1 << partitionOrder);
4971
0
    for (;;)
4972
0
    {
4973
0
        drflac_uint8 riceParam = 0;
4974
0
        if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
4975
0
            if (!drflac__read_uint8(bs, 4, &riceParam)) {
4976
0
                return DRFLAC_FALSE;
4977
0
            }
4978
0
            if (riceParam == 15) {
4979
0
                riceParam = 0xFF;
4980
0
            }
4981
0
        } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
4982
0
            if (!drflac__read_uint8(bs, 5, &riceParam)) {
4983
0
                return DRFLAC_FALSE;
4984
0
            }
4985
0
            if (riceParam == 31) {
4986
0
                riceParam = 0xFF;
4987
0
            }
4988
0
        }
4989
4990
0
        if (riceParam != 0xFF) {
4991
0
            if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) {
4992
0
                return DRFLAC_FALSE;
4993
0
            }
4994
0
        } else {
4995
0
            drflac_uint8 unencodedBitsPerSample = 0;
4996
0
            if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
4997
0
                return DRFLAC_FALSE;
4998
0
            }
4999
5000
0
            if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) {
5001
0
                return DRFLAC_FALSE;
5002
0
            }
5003
0
        }
5004
5005
5006
0
        if (partitionsRemaining == 1) {
5007
0
            break;
5008
0
        }
5009
5010
0
        partitionsRemaining -= 1;
5011
0
        samplesInPartition = blockSize / (1 << partitionOrder);
5012
0
    }
5013
5014
0
    return DRFLAC_TRUE;
5015
0
}
5016
5017
5018
static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
5019
0
{
5020
0
    drflac_uint32 i;
5021
5022
    /* Only a single sample needs to be decoded here. */
5023
0
    drflac_int32 sample;
5024
0
    if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5025
0
        return DRFLAC_FALSE;
5026
0
    }
5027
5028
    /*
5029
    We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely)
5030
    we'll want to look at a more efficient way.
5031
    */
5032
0
    for (i = 0; i < blockSize; ++i) {
5033
0
        pDecodedSamples[i] = sample;
5034
0
    }
5035
5036
0
    return DRFLAC_TRUE;
5037
0
}
5038
5039
static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
5040
0
{
5041
0
    drflac_uint32 i;
5042
5043
0
    for (i = 0; i < blockSize; ++i) {
5044
0
        drflac_int32 sample;
5045
0
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5046
0
            return DRFLAC_FALSE;
5047
0
        }
5048
5049
0
        pDecodedSamples[i] = sample;
5050
0
    }
5051
5052
0
    return DRFLAC_TRUE;
5053
0
}
5054
5055
static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
5056
0
{
5057
0
    drflac_uint32 i;
5058
5059
0
    static drflac_int32 lpcCoefficientsTable[5][4] = {
5060
0
        {0,  0, 0,  0},
5061
0
        {1,  0, 0,  0},
5062
0
        {2, -1, 0,  0},
5063
0
        {3, -3, 1,  0},
5064
0
        {4, -6, 4, -1}
5065
0
    };
5066
5067
    /* Warm up samples and coefficients. */
5068
0
    for (i = 0; i < lpcOrder; ++i) {
5069
0
        drflac_int32 sample;
5070
0
        if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
5071
0
            return DRFLAC_FALSE;
5072
0
        }
5073
5074
0
        pDecodedSamples[i] = sample;
5075
0
    }
5076
5077
0
    if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
5078
0
        return DRFLAC_FALSE;
5079
0
    }
5080
5081
0
    return DRFLAC_TRUE;
5082
0
}
5083
5084
static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
5085
0
{
5086
0
    drflac_uint8 i;
5087
0
    drflac_uint8 lpcPrecision;
5088
0
    drflac_int8 lpcShift;
5089
0
    drflac_int32 coefficients[32];
5090
5091
    /* Warm up samples. */
5092
0
    for (i = 0; i < lpcOrder; ++i) {
5093
0
        drflac_int32 sample;
5094
0
        if (!drflac__read_int32(bs, bitsPerSample, &sample)) {
5095
0
            return DRFLAC_FALSE;
5096
0
        }
5097
5098
0
        pDecodedSamples[i] = sample;
5099
0
    }
5100
5101
0
    if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
5102
0
        return DRFLAC_FALSE;
5103
0
    }
5104
0
    if (lpcPrecision == 15) {
5105
0
        return DRFLAC_FALSE;    /* Invalid. */
5106
0
    }
5107
0
    lpcPrecision += 1;
5108
5109
0
    if (!drflac__read_int8(bs, 5, &lpcShift)) {
5110
0
        return DRFLAC_FALSE;
5111
0
    }
5112
5113
    /*
5114
    From the FLAC specification:
5115
5116
        Quantized linear predictor coefficient shift needed in bits (NOTE: this number is signed two's-complement)
5117
5118
    Emphasis on the "signed two's-complement". In practice there does not seem to be any encoders nor decoders supporting negative shifts. For now dr_flac is
5119
    not going to support negative shifts as I don't have any reference files. However, when a reference file comes through I will consider adding support.
5120
    */
5121
0
    if (lpcShift < 0) {
5122
0
        return DRFLAC_FALSE;
5123
0
    }
5124
5125
0
    DRFLAC_ZERO_MEMORY(coefficients, sizeof(coefficients));
5126
0
    for (i = 0; i < lpcOrder; ++i) {
5127
0
        if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
5128
0
            return DRFLAC_FALSE;
5129
0
        }
5130
0
    }
5131
5132
0
    if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
5133
0
        return DRFLAC_FALSE;
5134
0
    }
5135
5136
0
    return DRFLAC_TRUE;
5137
0
}
5138
5139
5140
static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
5141
0
{
5142
0
    const drflac_uint32 sampleRateTable[12]  = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
5143
0
    const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};   /* -1 = reserved. */
5144
5145
0
    DRFLAC_ASSERT(bs != NULL);
5146
0
    DRFLAC_ASSERT(header != NULL);
5147
5148
    /* Keep looping until we find a valid sync code. */
5149
0
    for (;;) {
5150
0
        drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */
5151
0
        drflac_uint8 reserved = 0;
5152
0
        drflac_uint8 blockingStrategy = 0;
5153
0
        drflac_uint8 blockSize = 0;
5154
0
        drflac_uint8 sampleRate = 0;
5155
0
        drflac_uint8 channelAssignment = 0;
5156
0
        drflac_uint8 bitsPerSample = 0;
5157
0
        drflac_bool32 isVariableBlockSize;
5158
5159
0
        if (!drflac__find_and_seek_to_next_sync_code(bs)) {
5160
0
            return DRFLAC_FALSE;
5161
0
        }
5162
5163
0
        if (!drflac__read_uint8(bs, 1, &reserved)) {
5164
0
            return DRFLAC_FALSE;
5165
0
        }
5166
0
        if (reserved == 1) {
5167
0
            continue;
5168
0
        }
5169
0
        crc8 = drflac_crc8(crc8, reserved, 1);
5170
5171
0
        if (!drflac__read_uint8(bs, 1, &blockingStrategy)) {
5172
0
            return DRFLAC_FALSE;
5173
0
        }
5174
0
        crc8 = drflac_crc8(crc8, blockingStrategy, 1);
5175
5176
0
        if (!drflac__read_uint8(bs, 4, &blockSize)) {
5177
0
            return DRFLAC_FALSE;
5178
0
        }
5179
0
        if (blockSize == 0) {
5180
0
            continue;
5181
0
        }
5182
0
        crc8 = drflac_crc8(crc8, blockSize, 4);
5183
5184
0
        if (!drflac__read_uint8(bs, 4, &sampleRate)) {
5185
0
            return DRFLAC_FALSE;
5186
0
        }
5187
0
        crc8 = drflac_crc8(crc8, sampleRate, 4);
5188
5189
0
        if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
5190
0
            return DRFLAC_FALSE;
5191
0
        }
5192
0
        if (channelAssignment > 10) {
5193
0
            continue;
5194
0
        }
5195
0
        crc8 = drflac_crc8(crc8, channelAssignment, 4);
5196
5197
0
        if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
5198
0
            return DRFLAC_FALSE;
5199
0
        }
5200
0
        if (bitsPerSample == 3 || bitsPerSample == 7) {
5201
0
            continue;
5202
0
        }
5203
0
        crc8 = drflac_crc8(crc8, bitsPerSample, 3);
5204
5205
5206
0
        if (!drflac__read_uint8(bs, 1, &reserved)) {
5207
0
            return DRFLAC_FALSE;
5208
0
        }
5209
0
        if (reserved == 1) {
5210
0
            continue;
5211
0
        }
5212
0
        crc8 = drflac_crc8(crc8, reserved, 1);
5213
5214
5215
0
        isVariableBlockSize = blockingStrategy == 1;
5216
0
        if (isVariableBlockSize) {
5217
0
            drflac_uint64 pcmFrameNumber;
5218
0
            drflac_result result = drflac__read_utf8_coded_number(bs, &pcmFrameNumber, &crc8);
5219
0
            if (result != DRFLAC_SUCCESS) {
5220
0
                if (result == DRFLAC_AT_END) {
5221
0
                    return DRFLAC_FALSE;
5222
0
                } else {
5223
0
                    continue;
5224
0
                }
5225
0
            }
5226
0
            header->flacFrameNumber  = 0;
5227
0
            header->pcmFrameNumber = pcmFrameNumber;
5228
0
        } else {
5229
0
            drflac_uint64 flacFrameNumber = 0;
5230
0
            drflac_result result = drflac__read_utf8_coded_number(bs, &flacFrameNumber, &crc8);
5231
0
            if (result != DRFLAC_SUCCESS) {
5232
0
                if (result == DRFLAC_AT_END) {
5233
0
                    return DRFLAC_FALSE;
5234
0
                } else {
5235
0
                    continue;
5236
0
                }
5237
0
            }
5238
0
            header->flacFrameNumber  = (drflac_uint32)flacFrameNumber;   /* <-- Safe cast. */
5239
0
            header->pcmFrameNumber = 0;
5240
0
        }
5241
5242
5243
0
        DRFLAC_ASSERT(blockSize > 0);
5244
0
        if (blockSize == 1) {
5245
0
            header->blockSizeInPCMFrames = 192;
5246
0
        } else if (blockSize <= 5) {
5247
0
            DRFLAC_ASSERT(blockSize >= 2);
5248
0
            header->blockSizeInPCMFrames = 576 * (1 << (blockSize - 2));
5249
0
        } else if (blockSize == 6) {
5250
0
            if (!drflac__read_uint16(bs, 8, &header->blockSizeInPCMFrames)) {
5251
0
                return DRFLAC_FALSE;
5252
0
            }
5253
0
            crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 8);
5254
0
            header->blockSizeInPCMFrames += 1;
5255
0
        } else if (blockSize == 7) {
5256
0
            if (!drflac__read_uint16(bs, 16, &header->blockSizeInPCMFrames)) {
5257
0
                return DRFLAC_FALSE;
5258
0
            }
5259
0
            crc8 = drflac_crc8(crc8, header->blockSizeInPCMFrames, 16);
5260
0
            if (header->blockSizeInPCMFrames == 0xFFFF) {
5261
0
                return DRFLAC_FALSE;    /* Frame is too big. This is the size of the frame minus 1. The STREAMINFO block defines the max block size which is 16-bits. Adding one will make it 17 bits and therefore too big. */
5262
0
            }
5263
0
            header->blockSizeInPCMFrames += 1;
5264
0
        } else {
5265
0
            DRFLAC_ASSERT(blockSize >= 8);
5266
0
            header->blockSizeInPCMFrames = 256 * (1 << (blockSize - 8));
5267
0
        }
5268
5269
5270
0
        if (sampleRate <= 11) {
5271
0
            header->sampleRate = sampleRateTable[sampleRate];
5272
0
        } else if (sampleRate == 12) {
5273
0
            if (!drflac__read_uint32(bs, 8, &header->sampleRate)) {
5274
0
                return DRFLAC_FALSE;
5275
0
            }
5276
0
            crc8 = drflac_crc8(crc8, header->sampleRate, 8);
5277
0
            header->sampleRate *= 1000;
5278
0
        } else if (sampleRate == 13) {
5279
0
            if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
5280
0
                return DRFLAC_FALSE;
5281
0
            }
5282
0
            crc8 = drflac_crc8(crc8, header->sampleRate, 16);
5283
0
        } else if (sampleRate == 14) {
5284
0
            if (!drflac__read_uint32(bs, 16, &header->sampleRate)) {
5285
0
                return DRFLAC_FALSE;
5286
0
            }
5287
0
            crc8 = drflac_crc8(crc8, header->sampleRate, 16);
5288
0
            header->sampleRate *= 10;
5289
0
        } else {
5290
0
            continue;  /* Invalid. Assume an invalid block. */
5291
0
        }
5292
5293
5294
0
        header->channelAssignment = channelAssignment;
5295
5296
0
        header->bitsPerSample = bitsPerSampleTable[bitsPerSample];
5297
0
        if (header->bitsPerSample == 0) {
5298
0
            header->bitsPerSample = streaminfoBitsPerSample;
5299
0
        }
5300
5301
0
        if (header->bitsPerSample != streaminfoBitsPerSample) {
5302
            /* If this subframe has a different bitsPerSample then streaminfo or the first frame, reject it */
5303
0
            return DRFLAC_FALSE;
5304
0
        }
5305
5306
0
        if (!drflac__read_uint8(bs, 8, &header->crc8)) {
5307
0
            return DRFLAC_FALSE;
5308
0
        }
5309
5310
0
#ifndef DR_FLAC_NO_CRC
5311
0
        if (header->crc8 != crc8) {
5312
0
            continue;    /* CRC mismatch. Loop back to the top and find the next sync code. */
5313
0
        }
5314
0
#endif
5315
0
        return DRFLAC_TRUE;
5316
0
    }
5317
0
}
5318
5319
static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe)
5320
0
{
5321
0
    drflac_uint8 header;
5322
0
    int type;
5323
5324
0
    if (!drflac__read_uint8(bs, 8, &header)) {
5325
0
        return DRFLAC_FALSE;
5326
0
    }
5327
5328
    /* First bit should always be 0. */
5329
0
    if ((header & 0x80) != 0) {
5330
0
        return DRFLAC_FALSE;
5331
0
    }
5332
5333
    /*
5334
    Default to 0 for the LPC order. It's important that we always set this to 0 for non LPC
5335
    and FIXED subframes because we'll be using it in a generic validation check later.
5336
    */
5337
0
    pSubframe->lpcOrder = 0;
5338
5339
0
    type = (header & 0x7E) >> 1;
5340
0
    if (type == 0) {
5341
0
        pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
5342
0
    } else if (type == 1) {
5343
0
        pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM;
5344
0
    } else {
5345
0
        if ((type & 0x20) != 0) {
5346
0
            pSubframe->subframeType = DRFLAC_SUBFRAME_LPC;
5347
0
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x1F) + 1;
5348
0
        } else if ((type & 0x08) != 0) {
5349
0
            pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED;
5350
0
            pSubframe->lpcOrder = (drflac_uint8)(type & 0x07);
5351
0
            if (pSubframe->lpcOrder > 4) {
5352
0
                pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
5353
0
                pSubframe->lpcOrder = 0;
5354
0
            }
5355
0
        } else {
5356
0
            pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED;
5357
0
        }
5358
0
    }
5359
5360
0
    if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) {
5361
0
        return DRFLAC_FALSE;
5362
0
    }
5363
5364
    /* Wasted bits per sample. */
5365
0
    pSubframe->wastedBitsPerSample = 0;
5366
0
    if ((header & 0x01) == 1) {
5367
0
        unsigned int wastedBitsPerSample;
5368
0
        if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) {
5369
0
            return DRFLAC_FALSE;
5370
0
        }
5371
0
        pSubframe->wastedBitsPerSample = (drflac_uint8)wastedBitsPerSample + 1;
5372
0
    }
5373
5374
0
    return DRFLAC_TRUE;
5375
0
}
5376
5377
static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
5378
0
{
5379
0
    drflac_subframe* pSubframe;
5380
0
    drflac_uint32 subframeBitsPerSample;
5381
0
    drflac_bool32 decodeResult;
5382
5383
0
    DRFLAC_ASSERT(bs != NULL);
5384
0
    DRFLAC_ASSERT(frame != NULL);
5385
5386
0
    pSubframe = frame->subframes + subframeIndex;
5387
0
    if (!drflac__read_subframe_header(bs, pSubframe)) {
5388
0
        return DRFLAC_FALSE;
5389
0
    }
5390
5391
    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
5392
0
    subframeBitsPerSample = frame->header.bitsPerSample;
5393
0
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
5394
0
        subframeBitsPerSample += 1;
5395
0
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
5396
0
        subframeBitsPerSample += 1;
5397
0
    }
5398
5399
0
    if (subframeBitsPerSample > 32) {
5400
        /* libFLAC and ffmpeg reject 33-bit subframes as well */
5401
0
        return DRFLAC_FALSE;
5402
0
    }
5403
5404
    /* Need to handle wasted bits per sample. */
5405
0
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
5406
0
        return DRFLAC_FALSE;
5407
0
    }
5408
0
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
5409
5410
0
    pSubframe->pSamplesS32 = pDecodedSamplesOut;
5411
5412
    /*
5413
    pDecodedSamplesOut will be pointing to a buffer that was allocated with enough memory to store
5414
    maxBlockSizeInPCMFrames samples (as specified in the FLAC header). We need to guard against an
5415
    overflow here. At a higher level we are checking maxBlockSizeInPCMFrames from the header, but
5416
    here we need to do an additional check to ensure this frame's block size fully encompasses any
5417
    warmup samples which is determined by the LPC order. For non LPC and FIXED subframes, the LPC
5418
    order will be have been set to 0 in drflac__read_subframe_header().
5419
    */
5420
0
    if (frame->header.blockSizeInPCMFrames < pSubframe->lpcOrder) {
5421
0
        return DRFLAC_FALSE;
5422
0
    }
5423
5424
0
    switch (pSubframe->subframeType)
5425
0
    {
5426
0
        case DRFLAC_SUBFRAME_CONSTANT:
5427
0
        {
5428
0
            decodeResult = drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
5429
0
        } break;
5430
5431
0
        case DRFLAC_SUBFRAME_VERBATIM:
5432
0
        {
5433
0
            decodeResult = drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
5434
0
        } break;
5435
5436
0
        case DRFLAC_SUBFRAME_FIXED:
5437
0
        {
5438
0
            decodeResult = drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
5439
0
        } break;
5440
5441
0
        case DRFLAC_SUBFRAME_LPC:
5442
0
        {
5443
0
            decodeResult = drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
5444
0
        } break;
5445
5446
0
        default: decodeResult = DRFLAC_FALSE;
5447
0
    }
5448
5449
0
    return decodeResult;
5450
0
}
5451
5452
static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex)
5453
0
{
5454
0
    drflac_subframe* pSubframe;
5455
0
    drflac_uint32 subframeBitsPerSample;
5456
5457
0
    DRFLAC_ASSERT(bs != NULL);
5458
0
    DRFLAC_ASSERT(frame != NULL);
5459
5460
0
    pSubframe = frame->subframes + subframeIndex;
5461
0
    if (!drflac__read_subframe_header(bs, pSubframe)) {
5462
0
        return DRFLAC_FALSE;
5463
0
    }
5464
5465
    /* Side channels require an extra bit per sample. Took a while to figure that one out... */
5466
0
    subframeBitsPerSample = frame->header.bitsPerSample;
5467
0
    if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
5468
0
        subframeBitsPerSample += 1;
5469
0
    } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) {
5470
0
        subframeBitsPerSample += 1;
5471
0
    }
5472
5473
    /* Need to handle wasted bits per sample. */
5474
0
    if (pSubframe->wastedBitsPerSample >= subframeBitsPerSample) {
5475
0
        return DRFLAC_FALSE;
5476
0
    }
5477
0
    subframeBitsPerSample -= pSubframe->wastedBitsPerSample;
5478
5479
0
    pSubframe->pSamplesS32 = NULL;
5480
5481
0
    switch (pSubframe->subframeType)
5482
0
    {
5483
0
        case DRFLAC_SUBFRAME_CONSTANT:
5484
0
        {
5485
0
            if (!drflac__seek_bits(bs, subframeBitsPerSample)) {
5486
0
                return DRFLAC_FALSE;
5487
0
            }
5488
0
        } break;
5489
5490
0
        case DRFLAC_SUBFRAME_VERBATIM:
5491
0
        {
5492
0
            unsigned int bitsToSeek = frame->header.blockSizeInPCMFrames * subframeBitsPerSample;
5493
0
            if (!drflac__seek_bits(bs, bitsToSeek)) {
5494
0
                return DRFLAC_FALSE;
5495
0
            }
5496
0
        } break;
5497
5498
0
        case DRFLAC_SUBFRAME_FIXED:
5499
0
        {
5500
0
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
5501
0
            if (!drflac__seek_bits(bs, bitsToSeek)) {
5502
0
                return DRFLAC_FALSE;
5503
0
            }
5504
5505
0
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
5506
0
                return DRFLAC_FALSE;
5507
0
            }
5508
0
        } break;
5509
5510
0
        case DRFLAC_SUBFRAME_LPC:
5511
0
        {
5512
0
            drflac_uint8 lpcPrecision;
5513
5514
0
            unsigned int bitsToSeek = pSubframe->lpcOrder * subframeBitsPerSample;
5515
0
            if (!drflac__seek_bits(bs, bitsToSeek)) {
5516
0
                return DRFLAC_FALSE;
5517
0
            }
5518
5519
0
            if (!drflac__read_uint8(bs, 4, &lpcPrecision)) {
5520
0
                return DRFLAC_FALSE;
5521
0
            }
5522
0
            if (lpcPrecision == 15) {
5523
0
                return DRFLAC_FALSE;    /* Invalid. */
5524
0
            }
5525
0
            lpcPrecision += 1;
5526
5527
5528
0
            bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5;    /* +5 for shift. */
5529
0
            if (!drflac__seek_bits(bs, bitsToSeek)) {
5530
0
                return DRFLAC_FALSE;
5531
0
            }
5532
5533
0
            if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
5534
0
                return DRFLAC_FALSE;
5535
0
            }
5536
0
        } break;
5537
5538
0
        default: return DRFLAC_FALSE;
5539
0
    }
5540
5541
0
    return DRFLAC_TRUE;
5542
0
}
5543
5544
5545
static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment)
5546
0
{
5547
0
    drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
5548
5549
0
    DRFLAC_ASSERT(channelAssignment <= 10);
5550
0
    return lookup[channelAssignment];
5551
0
}
5552
5553
static drflac_result drflac__decode_flac_frame(drflac* pFlac)
5554
0
{
5555
0
    int channelCount;
5556
0
    int i;
5557
0
    drflac_uint8 paddingSizeInBits;
5558
0
    drflac_uint16 desiredCRC16;
5559
0
#ifndef DR_FLAC_NO_CRC
5560
0
    drflac_uint16 actualCRC16;
5561
0
#endif
5562
5563
    /* This function should be called while the stream is sitting on the first byte after the frame header. */
5564
0
    pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5565
0
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
5566
5567
    /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
5568
0
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
5569
0
        return DRFLAC_ERROR;
5570
0
    }
5571
5572
    /* The number of channels in the frame must match the channel count from the STREAMINFO block. */
5573
0
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
5574
0
    if (channelCount != (int)pFlac->channels) {
5575
0
        return DRFLAC_ERROR;
5576
0
    }
5577
5578
0
    for (i = 0; i < channelCount; ++i) {
5579
0
        if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
5580
0
            return DRFLAC_ERROR;
5581
0
        }
5582
0
    }
5583
5584
0
    paddingSizeInBits = (drflac_uint8)(DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7);
5585
0
    if (paddingSizeInBits > 0) {
5586
0
        drflac_uint8 padding = 0;
5587
0
        if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) {
5588
0
            return DRFLAC_AT_END;
5589
0
        }
5590
0
    }
5591
5592
0
#ifndef DR_FLAC_NO_CRC
5593
0
    actualCRC16 = drflac__flush_crc16(&pFlac->bs);
5594
0
#endif
5595
0
    if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5596
0
        return DRFLAC_AT_END;
5597
0
    }
5598
5599
0
#ifndef DR_FLAC_NO_CRC
5600
0
    if (actualCRC16 != desiredCRC16) {
5601
0
        return DRFLAC_CRC_MISMATCH;    /* CRC mismatch. */
5602
0
    }
5603
0
#endif
5604
5605
0
    pFlac->currentFLACFrame.pcmFramesRemaining = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
5606
5607
0
    return DRFLAC_SUCCESS;
5608
0
}
5609
5610
static drflac_result drflac__seek_flac_frame(drflac* pFlac)
5611
0
{
5612
0
    drflac_result result;
5613
0
    int channelCount;
5614
0
    int i;
5615
0
    drflac_uint16 desiredCRC16;
5616
0
#ifndef DR_FLAC_NO_CRC
5617
0
    drflac_uint16 actualCRC16;
5618
0
#endif
5619
5620
0
    pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5621
5622
0
    channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
5623
0
    for (i = 0; i < channelCount; ++i) {
5624
0
        if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i)) {
5625
0
            result = DRFLAC_ERROR;
5626
0
            goto error;
5627
0
        }
5628
0
    }
5629
5630
    /* Padding. */
5631
0
    if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) {
5632
0
        result = DRFLAC_ERROR;
5633
0
        goto error;
5634
0
    }
5635
5636
    /* CRC. */
5637
0
#ifndef DR_FLAC_NO_CRC
5638
0
    actualCRC16 = drflac__flush_crc16(&pFlac->bs);
5639
0
#endif
5640
0
    if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) {
5641
0
        result = DRFLAC_AT_END;
5642
0
        goto error;
5643
0
    }
5644
5645
0
#ifndef DR_FLAC_NO_CRC
5646
0
    if (actualCRC16 != desiredCRC16) {
5647
0
        result = DRFLAC_CRC_MISMATCH;   /* CRC mismatch. */
5648
0
        goto error;
5649
0
    }
5650
0
#endif
5651
5652
0
    return DRFLAC_SUCCESS;
5653
5654
0
error:
5655
0
    DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
5656
0
    return result;
5657
0
}
5658
5659
static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
5660
0
{
5661
0
    DRFLAC_ASSERT(pFlac != NULL);
5662
5663
0
    for (;;) {
5664
0
        drflac_result result;
5665
5666
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5667
0
            return DRFLAC_FALSE;
5668
0
        }
5669
5670
0
        result = drflac__decode_flac_frame(pFlac);
5671
0
        if (result != DRFLAC_SUCCESS) {
5672
0
            if (result == DRFLAC_CRC_MISMATCH) {
5673
0
                continue;   /* CRC mismatch. Skip to the next frame. */
5674
0
            } else {
5675
0
                return DRFLAC_FALSE;
5676
0
            }
5677
0
        }
5678
5679
0
        return DRFLAC_TRUE;
5680
0
    }
5681
0
}
5682
5683
static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
5684
0
{
5685
0
    drflac_uint64 firstPCMFrame;
5686
0
    drflac_uint64 lastPCMFrame;
5687
5688
0
    DRFLAC_ASSERT(pFlac != NULL);
5689
5690
0
    firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
5691
0
    if (firstPCMFrame == 0) {
5692
0
        firstPCMFrame = ((drflac_uint64)pFlac->currentFLACFrame.header.flacFrameNumber) * pFlac->maxBlockSizeInPCMFrames;
5693
0
    }
5694
5695
0
    lastPCMFrame = firstPCMFrame + pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
5696
0
    if (lastPCMFrame > 0) {
5697
0
        lastPCMFrame -= 1; /* Needs to be zero based. */
5698
0
    }
5699
5700
0
    if (pFirstPCMFrame) {
5701
0
        *pFirstPCMFrame = firstPCMFrame;
5702
0
    }
5703
0
    if (pLastPCMFrame) {
5704
0
        *pLastPCMFrame = lastPCMFrame;
5705
0
    }
5706
0
}
5707
5708
static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
5709
0
{
5710
0
    drflac_bool32 result;
5711
5712
0
    DRFLAC_ASSERT(pFlac != NULL);
5713
5714
0
    result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
5715
5716
0
    DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5717
0
    pFlac->currentPCMFrame = 0;
5718
5719
0
    return result;
5720
0
}
5721
5722
static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
5723
0
{
5724
    /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
5725
0
    DRFLAC_ASSERT(pFlac != NULL);
5726
0
    return drflac__seek_flac_frame(pFlac);
5727
0
}
5728
5729
5730
static drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek)
5731
0
{
5732
0
    drflac_uint64 pcmFramesRead = 0;
5733
0
    while (pcmFramesToSeek > 0) {
5734
0
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5735
0
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
5736
0
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
5737
0
            }
5738
0
        } else {
5739
0
            if (pFlac->currentFLACFrame.pcmFramesRemaining > pcmFramesToSeek) {
5740
0
                pcmFramesRead   += pcmFramesToSeek;
5741
0
                pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)pcmFramesToSeek;   /* <-- Safe cast. Will always be < currentFrame.pcmFramesRemaining < 65536. */
5742
0
                pcmFramesToSeek  = 0;
5743
0
            } else {
5744
0
                pcmFramesRead   += pFlac->currentFLACFrame.pcmFramesRemaining;
5745
0
                pcmFramesToSeek -= pFlac->currentFLACFrame.pcmFramesRemaining;
5746
0
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5747
0
            }
5748
0
        }
5749
0
    }
5750
5751
0
    pFlac->currentPCMFrame += pcmFramesRead;
5752
0
    return pcmFramesRead;
5753
0
}
5754
5755
5756
static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drflac_uint64 pcmFrameIndex)
5757
0
{
5758
0
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
5759
0
    drflac_uint64 runningPCMFrameCount;
5760
5761
0
    DRFLAC_ASSERT(pFlac != NULL);
5762
5763
    /* 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. */
5764
0
    if (pcmFrameIndex >= pFlac->currentPCMFrame) {
5765
        /* Seeking forward. Need to seek from the current position. */
5766
0
        runningPCMFrameCount = pFlac->currentPCMFrame;
5767
5768
        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
5769
0
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
5770
0
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5771
0
                return DRFLAC_FALSE;
5772
0
            }
5773
0
        } else {
5774
0
            isMidFrame = DRFLAC_TRUE;
5775
0
        }
5776
0
    } else {
5777
        /* Seeking backwards. Need to seek from the start of the file. */
5778
0
        runningPCMFrameCount = 0;
5779
5780
        /* Move back to the start. */
5781
0
        if (!drflac__seek_to_first_frame(pFlac)) {
5782
0
            return DRFLAC_FALSE;
5783
0
        }
5784
5785
        /* Decode the first frame in preparation for sample-exact seeking below. */
5786
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5787
0
            return DRFLAC_FALSE;
5788
0
        }
5789
0
    }
5790
5791
    /*
5792
    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
5793
    header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame.
5794
    */
5795
0
    for (;;) {
5796
0
        drflac_uint64 pcmFrameCountInThisFLACFrame;
5797
0
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
5798
0
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
5799
5800
0
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
5801
5802
0
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
5803
0
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
5804
            /*
5805
            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
5806
            it never existed and keep iterating.
5807
            */
5808
0
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
5809
5810
0
            if (!isMidFrame) {
5811
0
                drflac_result result = drflac__decode_flac_frame(pFlac);
5812
0
                if (result == DRFLAC_SUCCESS) {
5813
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
5814
0
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
5815
0
                } else {
5816
0
                    if (result == DRFLAC_CRC_MISMATCH) {
5817
0
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
5818
0
                    } else {
5819
0
                        return DRFLAC_FALSE;
5820
0
                    }
5821
0
                }
5822
0
            } else {
5823
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
5824
0
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
5825
0
            }
5826
0
        } else {
5827
            /*
5828
            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
5829
            frame never existed and leave the running sample count untouched.
5830
            */
5831
0
            if (!isMidFrame) {
5832
0
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
5833
0
                if (result == DRFLAC_SUCCESS) {
5834
0
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
5835
0
                } else {
5836
0
                    if (result == DRFLAC_CRC_MISMATCH) {
5837
0
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
5838
0
                    } else {
5839
0
                        return DRFLAC_FALSE;
5840
0
                    }
5841
0
                }
5842
0
            } else {
5843
                /*
5844
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
5845
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
5846
                */
5847
0
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
5848
0
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
5849
0
                isMidFrame = DRFLAC_FALSE;
5850
0
            }
5851
5852
            /* If we are seeking to the end of the file and we've just hit it, we're done. */
5853
0
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
5854
0
                return DRFLAC_TRUE;
5855
0
            }
5856
0
        }
5857
5858
0
    next_iteration:
5859
        /* Grab the next frame in preparation for the next iteration. */
5860
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5861
0
            return DRFLAC_FALSE;
5862
0
        }
5863
0
    }
5864
0
}
5865
5866
5867
#if !defined(DR_FLAC_NO_CRC)
5868
/*
5869
We use an average compression ratio to determine our approximate start location. FLAC files are generally about 50%-70% the size of their
5870
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
5871
location.
5872
*/
5873
0
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
5874
5875
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)
5876
0
{
5877
0
    DRFLAC_ASSERT(pFlac != NULL);
5878
0
    DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
5879
0
    DRFLAC_ASSERT(targetByte >= rangeLo);
5880
0
    DRFLAC_ASSERT(targetByte <= rangeHi);
5881
5882
0
    *pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
5883
5884
0
    for (;;) {
5885
        /* After rangeLo == rangeHi == targetByte fails, we need to break out. */
5886
0
        drflac_uint64 lastTargetByte = targetByte;
5887
5888
        /* 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. */
5889
0
        if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
5890
            /* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
5891
0
            if (targetByte == 0) {
5892
0
                drflac__seek_to_first_frame(pFlac); /* Try to recover. */
5893
0
                return DRFLAC_FALSE;
5894
0
            }
5895
5896
            /* Halve the byte location and continue. */
5897
0
            targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5898
0
            rangeHi = targetByte;
5899
0
        } else {
5900
            /* Getting here should mean that we have seeked to an appropriate byte. */
5901
5902
            /* Clear the details of the FLAC frame so we don't misreport data. */
5903
0
            DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
5904
5905
            /*
5906
            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
5907
            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
5908
            so it needs to stay this way for now.
5909
            */
5910
0
#if 1
5911
0
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
5912
                /* Halve the byte location and continue. */
5913
0
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5914
0
                rangeHi = targetByte;
5915
0
            } else {
5916
0
                break;
5917
0
            }
5918
#else
5919
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
5920
                /* Halve the byte location and continue. */
5921
                targetByte = rangeLo + ((rangeHi - rangeLo)/2);
5922
                rangeHi = targetByte;
5923
            } else {
5924
                break;
5925
            }
5926
#endif
5927
0
        }
5928
5929
        /* We already tried this byte and there are no more to try, break out. */
5930
0
        if(targetByte == lastTargetByte) {
5931
0
            return DRFLAC_FALSE;
5932
0
        }
5933
0
    }
5934
5935
    /* The current PCM frame needs to be updated based on the frame we just seeked to. */
5936
0
    drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
5937
5938
0
    DRFLAC_ASSERT(targetByte <= rangeHi);
5939
5940
0
    *pLastSuccessfulSeekOffset = targetByte;
5941
0
    return DRFLAC_TRUE;
5942
0
}
5943
5944
static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
5945
0
{
5946
    /* 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(). */
5947
#if 0
5948
    if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
5949
        /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
5950
        if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
5951
            return DRFLAC_FALSE;
5952
        }
5953
    }
5954
#endif
5955
5956
0
    return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
5957
0
}
5958
5959
5960
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
5961
0
{
5962
    /* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */
5963
5964
0
    drflac_uint64 targetByte;
5965
0
    drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
5966
0
    drflac_uint64 pcmRangeHi = 0;
5967
0
    drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
5968
0
    drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
5969
0
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
5970
5971
0
    targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
5972
0
    if (targetByte > byteRangeHi) {
5973
0
        targetByte = byteRangeHi;
5974
0
    }
5975
5976
0
    for (;;) {
5977
        /*
5978
        If only two adjacent byte offsets remain, binary search cannot narrow the range any further. Seek to the closest frame before the target and decode
5979
        forward from there.
5980
        */
5981
0
        if ((byteRangeHi - byteRangeLo) == 1) {
5982
0
            if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
5983
0
                break;
5984
0
            }
5985
5986
0
            if (pFlac->currentPCMFrame <= pcmFrameIndex && drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
5987
0
                return DRFLAC_TRUE;
5988
0
            }
5989
5990
0
            break;
5991
0
        }
5992
5993
0
        if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
5994
            /* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
5995
0
            drflac_uint64 newPCMRangeLo;
5996
0
            drflac_uint64 newPCMRangeHi;
5997
0
            drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
5998
5999
            /* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
6000
0
            if (pcmRangeLo == newPCMRangeLo) {
6001
0
                if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
6002
0
                    break;  /* Failed to seek to closest frame. */
6003
0
                }
6004
6005
0
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
6006
0
                    return DRFLAC_TRUE;
6007
0
                } else {
6008
0
                    break;  /* Failed to seek forward. */
6009
0
                }
6010
0
            }
6011
6012
0
            pcmRangeLo = newPCMRangeLo;
6013
0
            pcmRangeHi = newPCMRangeHi;
6014
6015
0
            if (pcmRangeLo <= pcmFrameIndex && pcmRangeHi >= pcmFrameIndex) {
6016
                /* The target PCM frame is in this FLAC frame. */
6017
0
                if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
6018
0
                    return DRFLAC_TRUE;
6019
0
                } else {
6020
0
                    break;  /* Failed to seek to FLAC frame. */
6021
0
                }
6022
0
            } else {
6023
0
                if (pcmRangeLo > pcmFrameIndex) {
6024
                    /* We seeked too far forward. We need to move our target byte backward and try again. */
6025
0
                    byteRangeHi = lastSuccessfulSeekOffset;
6026
0
                    if (byteRangeLo > byteRangeHi) {
6027
0
                        byteRangeLo = byteRangeHi;
6028
0
                    }
6029
6030
0
                    targetByte = byteRangeLo + ((byteRangeHi - byteRangeLo) / 2);
6031
0
                    if (targetByte < byteRangeLo) {
6032
0
                        targetByte = byteRangeLo;
6033
0
                    }
6034
0
                } else /*if (pcmRangeHi < pcmFrameIndex)*/ {
6035
                    /* We didn't seek far enough. We need to move our target byte forward and try again. */
6036
6037
                    /* If we're close enough we can just seek forward. */
6038
0
                    if ((pcmFrameIndex - pcmRangeLo) < seekForwardThreshold) {
6039
0
                        if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
6040
0
                            return DRFLAC_TRUE;
6041
0
                        } else {
6042
0
                            break;  /* Failed to seek to FLAC frame. */
6043
0
                        }
6044
0
                    } else {
6045
0
                        const double approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0);
6046
6047
0
                        byteRangeLo = lastSuccessfulSeekOffset;
6048
0
                        if (byteRangeHi < byteRangeLo) {
6049
0
                            byteRangeHi = byteRangeLo;
6050
0
                        }
6051
6052
0
                        targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0) * approxCompressionRatio);
6053
0
                        if (targetByte > byteRangeHi) {
6054
0
                            targetByte = byteRangeHi;
6055
0
                        }
6056
6057
0
                        if (closestSeekOffsetBeforeTargetPCMFrame < lastSuccessfulSeekOffset) {
6058
0
                            closestSeekOffsetBeforeTargetPCMFrame = lastSuccessfulSeekOffset;
6059
0
                        }
6060
0
                    }
6061
0
                }
6062
0
            }
6063
0
        } else {
6064
            /* Getting here is really bad. We just recover as best we can, but moving to the first frame in the stream, and then abort. */
6065
0
            break;
6066
0
        }
6067
0
    }
6068
6069
0
    drflac__seek_to_first_frame(pFlac); /* <-- Try to recover. */
6070
0
    return DRFLAC_FALSE;
6071
0
}
6072
6073
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search(drflac* pFlac, drflac_uint64 pcmFrameIndex)
6074
0
{
6075
0
    drflac_uint64 byteRangeLo;
6076
0
    drflac_uint64 byteRangeHi;
6077
0
    drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
6078
6079
    /* Our algorithm currently assumes the FLAC stream is currently sitting at the start. */
6080
0
    if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
6081
0
        return DRFLAC_FALSE;
6082
0
    }
6083
6084
    /* If we're close enough to the start, just move to the start and seek forward. */
6085
0
    if (pcmFrameIndex < seekForwardThreshold) {
6086
0
        return drflac__seek_forward_by_pcm_frames(pFlac, pcmFrameIndex) == pcmFrameIndex;
6087
0
    }
6088
6089
    /*
6090
    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
6091
    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.
6092
    */
6093
0
    byteRangeLo = pFlac->firstFLACFramePosInBytes;
6094
0
    byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
6095
6096
0
    return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
6097
0
}
6098
#endif  /* !DR_FLAC_NO_CRC */
6099
6100
static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac_uint64 pcmFrameIndex)
6101
0
{
6102
0
    drflac_uint32 iClosestSeekpoint = 0;
6103
0
    drflac_bool32 isMidFrame = DRFLAC_FALSE;
6104
0
    drflac_uint64 runningPCMFrameCount;
6105
0
    drflac_uint32 iSeekpoint;
6106
6107
6108
0
    DRFLAC_ASSERT(pFlac != NULL);
6109
6110
0
    if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
6111
0
        return DRFLAC_FALSE;
6112
0
    }
6113
6114
    /* Do not use the seektable if pcmFramIndex is not coverd by it. */
6115
0
    if (pFlac->pSeekpoints[0].firstPCMFrame > pcmFrameIndex) {
6116
0
        return DRFLAC_FALSE;
6117
0
    }
6118
6119
0
    for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
6120
0
        if (pFlac->pSeekpoints[iSeekpoint].firstPCMFrame >= pcmFrameIndex) {
6121
0
            break;
6122
0
        }
6123
6124
0
        iClosestSeekpoint = iSeekpoint;
6125
0
    }
6126
6127
    /* There's been cases where the seek table contains only zeros. We need to do some basic validation on the closest seekpoint. */
6128
0
    if (pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount == 0 || pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount > pFlac->maxBlockSizeInPCMFrames) {
6129
0
        return DRFLAC_FALSE;
6130
0
    }
6131
0
    if (pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame > pFlac->totalPCMFrameCount && pFlac->totalPCMFrameCount > 0) {
6132
0
        return DRFLAC_FALSE;
6133
0
    }
6134
6135
0
#if !defined(DR_FLAC_NO_CRC)
6136
    /* 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. */
6137
0
    if (pFlac->totalPCMFrameCount > 0) {
6138
0
        drflac_uint64 byteRangeLo;
6139
0
        drflac_uint64 byteRangeHi;
6140
6141
0
        byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
6142
0
        byteRangeLo = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset;
6143
6144
        /*
6145
        If our closest seek point is not the last one, we only need to search between it and the next one. The section below calculates an appropriate starting
6146
        value for byteRangeHi which will clamp it appropriately.
6147
6148
        Note that the next seekpoint must have an offset greater than the closest seekpoint because otherwise our binary search algorithm will break down. There
6149
        have been cases where a seektable consists of seek points where every byte offset is set to 0 which causes problems. If this happens we need to abort.
6150
        */
6151
0
        if (iClosestSeekpoint < pFlac->seekpointCount-1) {
6152
0
            drflac_uint32 iNextSeekpoint = iClosestSeekpoint + 1;
6153
6154
            /* Basic validation on the seekpoints to ensure they're usable. */
6155
0
            if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) {
6156
0
                return DRFLAC_FALSE;    /* The next seekpoint doesn't look right. The seek table cannot be trusted from here. Abort. */
6157
0
            }
6158
6159
0
            if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Make sure it's not a placeholder seekpoint. */
6160
0
                byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1; /* byteRangeHi must be zero based. */
6161
0
            }
6162
0
        }
6163
6164
0
        if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
6165
0
            if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6166
0
                drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
6167
6168
0
                if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
6169
0
                    return DRFLAC_TRUE;
6170
0
                }
6171
0
            }
6172
0
        }
6173
0
    }
6174
0
#endif  /* !DR_FLAC_NO_CRC */
6175
6176
    /* Getting here means we need to use a slower algorithm because the binary search method failed or cannot be used. */
6177
6178
    /*
6179
    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
6180
    from the seekpoint's first sample.
6181
    */
6182
0
    if (pcmFrameIndex >= pFlac->currentPCMFrame && pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame <= pFlac->currentPCMFrame) {
6183
        /* Optimized case. Just seek forward from where we are. */
6184
0
        runningPCMFrameCount = pFlac->currentPCMFrame;
6185
6186
        /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */
6187
0
        if (pFlac->currentPCMFrame == 0 && pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
6188
0
            if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6189
0
                return DRFLAC_FALSE;
6190
0
            }
6191
0
        } else {
6192
0
            isMidFrame = DRFLAC_TRUE;
6193
0
        }
6194
0
    } else {
6195
        /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */
6196
0
        runningPCMFrameCount = pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame;
6197
6198
0
        if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
6199
0
            return DRFLAC_FALSE;
6200
0
        }
6201
6202
        /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */
6203
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6204
0
            return DRFLAC_FALSE;
6205
0
        }
6206
0
    }
6207
6208
0
    for (;;) {
6209
0
        drflac_uint64 pcmFrameCountInThisFLACFrame;
6210
0
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
6211
0
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
6212
6213
0
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
6214
6215
0
        pcmFrameCountInThisFLACFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
6216
0
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFLACFrame)) {
6217
            /*
6218
            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
6219
            it never existed and keep iterating.
6220
            */
6221
0
            drflac_uint64 pcmFramesToDecode = pcmFrameIndex - runningPCMFrameCount;
6222
6223
0
            if (!isMidFrame) {
6224
0
                drflac_result result = drflac__decode_flac_frame(pFlac);
6225
0
                if (result == DRFLAC_SUCCESS) {
6226
                    /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
6227
0
                    return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
6228
0
                } else {
6229
0
                    if (result == DRFLAC_CRC_MISMATCH) {
6230
0
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
6231
0
                    } else {
6232
0
                        return DRFLAC_FALSE;
6233
0
                    }
6234
0
                }
6235
0
            } else {
6236
                /* We started seeking mid-frame which means we need to skip the frame decoding part. */
6237
0
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
6238
0
            }
6239
0
        } else {
6240
            /*
6241
            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
6242
            frame never existed and leave the running sample count untouched.
6243
            */
6244
0
            if (!isMidFrame) {
6245
0
                drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
6246
0
                if (result == DRFLAC_SUCCESS) {
6247
0
                    runningPCMFrameCount += pcmFrameCountInThisFLACFrame;
6248
0
                } else {
6249
0
                    if (result == DRFLAC_CRC_MISMATCH) {
6250
0
                        goto next_iteration;   /* CRC mismatch. Pretend this frame never existed. */
6251
0
                    } else {
6252
0
                        return DRFLAC_FALSE;
6253
0
                    }
6254
0
                }
6255
0
            } else {
6256
                /*
6257
                We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with
6258
                drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header.
6259
                */
6260
0
                runningPCMFrameCount += pFlac->currentFLACFrame.pcmFramesRemaining;
6261
0
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
6262
0
                isMidFrame = DRFLAC_FALSE;
6263
0
            }
6264
6265
            /* If we are seeking to the end of the file and we've just hit it, we're done. */
6266
0
            if (pcmFrameIndex == pFlac->totalPCMFrameCount && runningPCMFrameCount == pFlac->totalPCMFrameCount) {
6267
0
                return DRFLAC_TRUE;
6268
0
            }
6269
0
        }
6270
6271
0
    next_iteration:
6272
        /* Grab the next frame in preparation for the next iteration. */
6273
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
6274
0
            return DRFLAC_FALSE;
6275
0
        }
6276
0
    }
6277
0
}
6278
6279
6280
#ifndef DR_FLAC_NO_OGG
6281
typedef struct
6282
{
6283
    drflac_uint8 capturePattern[4];  /* Should be "OggS" */
6284
    drflac_uint8 structureVersion;   /* Always 0. */
6285
    drflac_uint8 headerType;
6286
    drflac_uint64 granulePosition;
6287
    drflac_uint32 serialNumber;
6288
    drflac_uint32 sequenceNumber;
6289
    drflac_uint32 checksum;
6290
    drflac_uint8 segmentCount;
6291
    drflac_uint8 segmentTable[255];
6292
} drflac_ogg_page_header;
6293
#endif
6294
6295
typedef struct
6296
{
6297
    drflac_read_proc onRead;
6298
    drflac_seek_proc onSeek;
6299
    drflac_tell_proc onTell;
6300
    drflac_meta_proc onMeta;
6301
    drflac_container container;
6302
    void* pUserData;
6303
    void* pUserDataMD;
6304
    drflac_uint32 sampleRate;
6305
    drflac_uint8  channels;
6306
    drflac_uint8  bitsPerSample;
6307
    drflac_uint64 totalPCMFrameCount;
6308
    drflac_uint16 maxBlockSizeInPCMFrames;
6309
    drflac_uint64 runningFilePos;
6310
    drflac_bool32 hasStreamInfoBlock;
6311
    drflac_bool32 hasMetadataBlocks;
6312
    drflac_bs bs;                           /* <-- A bit streamer is required for loading data during initialization. */
6313
    drflac_frame_header firstFrameHeader;   /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */
6314
6315
#ifndef DR_FLAC_NO_OGG
6316
    drflac_uint32 oggSerial;
6317
    drflac_uint64 oggFirstBytePos;
6318
    drflac_ogg_page_header oggBosHeader;
6319
#endif
6320
} drflac_init_info;
6321
6322
static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
6323
0
{
6324
0
    blockHeader = drflac__be2host_32(blockHeader);
6325
0
    *isLastBlock = (drflac_uint8)((blockHeader & 0x80000000UL) >> 31);
6326
0
    *blockType   = (drflac_uint8)((blockHeader & 0x7F000000UL) >> 24);
6327
0
    *blockSize   =                (blockHeader & 0x00FFFFFFUL);
6328
0
}
6329
6330
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)
6331
0
{
6332
0
    drflac_uint32 blockHeader;
6333
6334
0
    *blockSize = 0;
6335
0
    if (onRead(pUserData, &blockHeader, 4) != 4) {
6336
0
        return DRFLAC_FALSE;
6337
0
    }
6338
6339
0
    drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize);
6340
0
    return DRFLAC_TRUE;
6341
0
}
6342
6343
static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
6344
0
{
6345
0
    drflac_uint32 blockSizes;
6346
0
    drflac_uint64 frameSizes = 0;
6347
0
    drflac_uint64 importantProps;
6348
0
    drflac_uint8 md5[16];
6349
6350
    /* min/max block size. */
6351
0
    if (onRead(pUserData, &blockSizes, 4) != 4) {
6352
0
        return DRFLAC_FALSE;
6353
0
    }
6354
6355
    /* min/max frame size. */
6356
0
    if (onRead(pUserData, &frameSizes, 6) != 6) {
6357
0
        return DRFLAC_FALSE;
6358
0
    }
6359
6360
    /* Sample rate, channels, bits per sample and total sample count. */
6361
0
    if (onRead(pUserData, &importantProps, 8) != 8) {
6362
0
        return DRFLAC_FALSE;
6363
0
    }
6364
6365
    /* MD5 */
6366
0
    if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) {
6367
0
        return DRFLAC_FALSE;
6368
0
    }
6369
6370
0
    blockSizes     = drflac__be2host_32(blockSizes);
6371
0
    frameSizes     = drflac__be2host_64(frameSizes);
6372
0
    importantProps = drflac__be2host_64(importantProps);
6373
6374
0
    pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
6375
0
    pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
6376
0
    pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
6377
0
    pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes     &  (((drflac_uint64)0x00FFFFFF << 16) <<  0)) >> 16);
6378
0
    pStreamInfo->sampleRate              = (drflac_uint32)((importantProps &  (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
6379
0
    pStreamInfo->channels                = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
6380
0
    pStreamInfo->bitsPerSample           = (drflac_uint8 )((importantProps &  (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
6381
0
    pStreamInfo->totalPCMFrameCount      =                ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
6382
0
    DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
6383
6384
0
    return DRFLAC_TRUE;
6385
0
}
6386
6387
6388
static void* drflac__malloc_default(size_t sz, void* pUserData)
6389
0
{
6390
0
    (void)pUserData;
6391
0
    return DRFLAC_MALLOC(sz);
6392
0
}
6393
6394
static void* drflac__realloc_default(void* p, size_t sz, void* pUserData)
6395
0
{
6396
0
    (void)pUserData;
6397
0
    return DRFLAC_REALLOC(p, sz);
6398
0
}
6399
6400
static void drflac__free_default(void* p, void* pUserData)
6401
0
{
6402
0
    (void)pUserData;
6403
0
    DRFLAC_FREE(p);
6404
0
}
6405
6406
6407
static void* drflac__malloc_from_callbacks(size_t sz, const drflac_allocation_callbacks* pAllocationCallbacks)
6408
0
{
6409
0
    if (pAllocationCallbacks == NULL) {
6410
0
        return NULL;
6411
0
    }
6412
6413
0
    if (pAllocationCallbacks->onMalloc != NULL) {
6414
0
        return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
6415
0
    }
6416
6417
    /* Try using realloc(). */
6418
0
    if (pAllocationCallbacks->onRealloc != NULL) {
6419
0
        return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
6420
0
    }
6421
6422
0
    return NULL;
6423
0
}
6424
6425
static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drflac_allocation_callbacks* pAllocationCallbacks)
6426
0
{
6427
0
    if (pAllocationCallbacks == NULL) {
6428
0
        return NULL;
6429
0
    }
6430
6431
0
    if (pAllocationCallbacks->onRealloc != NULL) {
6432
0
        return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
6433
0
    }
6434
6435
    /* Try emulating realloc() in terms of malloc()/free(). */
6436
0
    if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
6437
0
        void* p2;
6438
6439
0
        p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
6440
0
        if (p2 == NULL) {
6441
0
            return NULL;
6442
0
        }
6443
6444
0
        if (p != NULL) {
6445
0
            DRFLAC_COPY_MEMORY(p2, p, DRFLAC_MIN(szNew, szOld));
6446
0
            pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
6447
0
        }
6448
6449
0
        return p2;
6450
0
    }
6451
6452
0
    return NULL;
6453
0
}
6454
6455
static void drflac__free_from_callbacks(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
6456
0
{
6457
0
    if (p == NULL || pAllocationCallbacks == NULL) {
6458
0
        return;
6459
0
    }
6460
6461
0
    if (pAllocationCallbacks->onFree != NULL) {
6462
0
        pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
6463
0
    }
6464
0
}
6465
6466
6467
static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeekpointCount, drflac_allocation_callbacks* pAllocationCallbacks)
6468
0
{
6469
    /*
6470
    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
6471
    we'll be sitting on byte 42.
6472
    */
6473
0
    drflac_uint64 runningFilePos   = 42;
6474
0
    drflac_uint64 seektablePos     = 0;
6475
0
    drflac_uint32 seektableSize    = 0;
6476
0
    drflac_int64  fileSize         = 0;
6477
0
    drflac_bool32 hasKnownFileSize = DRFLAC_FALSE;
6478
6479
    /* We'll be doing some memory allocations here against untrusted data. We'll do a basic validation check that they don't exceed the size of the file. */
6480
0
    if (onTell != NULL && onSeek != NULL) {
6481
0
        if (onSeek(pUserData, 0, DRFLAC_SEEK_END)) {
6482
0
            if (onTell(pUserData, &fileSize)) {
6483
0
                hasKnownFileSize = DRFLAC_TRUE;
6484
0
            }
6485
6486
0
            onSeek(pUserData, (int)runningFilePos, DRFLAC_SEEK_SET);    /* Safe cast because runningFilePos should always be 42 at this point. */
6487
0
        }
6488
0
    }
6489
6490
0
    for (;;) {
6491
0
        drflac_metadata metadata;
6492
0
        drflac_uint8 isLastBlock = 0;
6493
0
        drflac_uint8 blockType = 0;
6494
0
        drflac_uint32 blockSize;
6495
0
        if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
6496
0
            return DRFLAC_FALSE;
6497
0
        }
6498
6499
0
        if (hasKnownFileSize && (blockSize > ((drflac_uint64)fileSize - runningFilePos))) {
6500
0
            return DRFLAC_FALSE;    /* Block size exceeds the size of the file. */
6501
0
        }
6502
6503
0
        runningFilePos += 4;
6504
6505
0
        metadata.type = blockType;
6506
0
        metadata.rawDataSize = 0;
6507
0
        metadata.rawDataOffset = runningFilePos;
6508
0
        metadata.pRawData = NULL;
6509
6510
0
        switch (blockType)
6511
0
        {
6512
0
            case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION:
6513
0
            {
6514
0
                if (blockSize < 4) {
6515
0
                    return DRFLAC_FALSE;
6516
0
                }
6517
6518
0
                if (onMeta) {
6519
0
                    void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6520
0
                    if (pRawData == NULL) {
6521
0
                        return DRFLAC_FALSE;
6522
0
                    }
6523
6524
0
                    if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6525
0
                        drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6526
0
                        return DRFLAC_FALSE;
6527
0
                    }
6528
6529
0
                    metadata.pRawData = pRawData;
6530
0
                    metadata.rawDataSize = blockSize;
6531
0
                    metadata.data.application.id       = drflac__be2host_32(*(drflac_uint32*)pRawData);
6532
0
                    metadata.data.application.pData    = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32));
6533
0
                    metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32);
6534
0
                    onMeta(pUserDataMD, &metadata);
6535
6536
0
                    drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6537
0
                }
6538
0
            } break;
6539
6540
0
            case DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE:
6541
0
            {
6542
0
                seektablePos  = runningFilePos;
6543
0
                seektableSize = blockSize;
6544
6545
0
                if (onMeta) {
6546
0
                    drflac_uint32 seekpointCount;
6547
0
                    drflac_uint32 iSeekpoint;
6548
0
                    void* pRawData;
6549
0
                    size_t rawDataSize;
6550
6551
0
                    seekpointCount = blockSize/DRFLAC_SEEKPOINT_SIZE_IN_BYTES;
6552
0
                    rawDataSize = seekpointCount * sizeof(drflac_seekpoint);
6553
6554
0
                    pRawData = drflac__malloc_from_callbacks(rawDataSize, pAllocationCallbacks);
6555
0
                    if (pRawData == NULL) {
6556
0
                        return DRFLAC_FALSE;
6557
0
                    }
6558
6559
                    /* We need to read seekpoint by seekpoint and do some processing. */
6560
0
                    for (iSeekpoint = 0; iSeekpoint < seekpointCount; ++iSeekpoint) {
6561
0
                        drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
6562
6563
0
                        if (onRead(pUserData, pSeekpoint, DRFLAC_SEEKPOINT_SIZE_IN_BYTES) != DRFLAC_SEEKPOINT_SIZE_IN_BYTES) {
6564
0
                            drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6565
0
                            return DRFLAC_FALSE;
6566
0
                        }
6567
6568
                        /* Endian swap. */
6569
0
                        pSeekpoint->firstPCMFrame   = drflac__be2host_64(pSeekpoint->firstPCMFrame);
6570
0
                        pSeekpoint->flacFrameOffset = drflac__be2host_64(pSeekpoint->flacFrameOffset);
6571
0
                        pSeekpoint->pcmFrameCount   = drflac__be2host_16(pSeekpoint->pcmFrameCount);
6572
0
                    }
6573
6574
0
                    metadata.pRawData = pRawData;
6575
0
                    metadata.rawDataSize = rawDataSize;
6576
0
                    metadata.data.seektable.seekpointCount = seekpointCount;
6577
0
                    metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
6578
6579
0
                    onMeta(pUserDataMD, &metadata);
6580
6581
0
                    drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6582
0
                }
6583
0
            } break;
6584
6585
0
            case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT:
6586
0
            {
6587
0
                if (blockSize < 8) {
6588
0
                    return DRFLAC_FALSE;
6589
0
                }
6590
6591
0
                if (onMeta) {
6592
0
                    void* pRawData;
6593
0
                    const char* pRunningData;
6594
0
                    const char* pRunningDataEnd;
6595
0
                    drflac_uint32 i;
6596
6597
0
                    pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6598
0
                    if (pRawData == NULL) {
6599
0
                        return DRFLAC_FALSE;
6600
0
                    }
6601
6602
0
                    if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6603
0
                        drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6604
0
                        return DRFLAC_FALSE;
6605
0
                    }
6606
6607
0
                    metadata.pRawData = pRawData;
6608
0
                    metadata.rawDataSize = blockSize;
6609
6610
0
                    pRunningData    = (const char*)pRawData;
6611
0
                    pRunningDataEnd = (const char*)pRawData + blockSize;
6612
6613
0
                    metadata.data.vorbis_comment.vendorLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6614
6615
                    /* Need space for the rest of the block */
6616
0
                    if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6617
0
                        drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6618
0
                        return DRFLAC_FALSE;
6619
0
                    }
6620
0
                    metadata.data.vorbis_comment.vendor       = pRunningData;                                   pRunningData += metadata.data.vorbis_comment.vendorLength;
6621
0
                    metadata.data.vorbis_comment.commentCount = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6622
6623
                    /* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */
6624
0
                    if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) { /* <-- Note the order of operations to avoid overflow to a valid value */
6625
0
                        drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6626
0
                        return DRFLAC_FALSE;
6627
0
                    }
6628
0
                    metadata.data.vorbis_comment.pComments    = pRunningData;
6629
6630
                    /* Check that the comments section is valid before passing it to the callback */
6631
0
                    for (i = 0; i < metadata.data.vorbis_comment.commentCount; ++i) {
6632
0
                        drflac_uint32 commentLength;
6633
6634
0
                        if (pRunningDataEnd - pRunningData < 4) {
6635
0
                            drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6636
0
                            return DRFLAC_FALSE;
6637
0
                        }
6638
6639
0
                        commentLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6640
0
                        if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6641
0
                            drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6642
0
                            return DRFLAC_FALSE;
6643
0
                        }
6644
0
                        pRunningData += commentLength;
6645
0
                    }
6646
6647
0
                    onMeta(pUserDataMD, &metadata);
6648
6649
0
                    drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6650
0
                }
6651
0
            } break;
6652
6653
0
            case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET:
6654
0
            {
6655
0
                if (blockSize < 396) {
6656
0
                    return DRFLAC_FALSE;
6657
0
                }
6658
6659
0
                if (onMeta) {
6660
0
                    void* pRawData;
6661
0
                    const char* pRunningData;
6662
0
                    const char* pRunningDataEnd;
6663
0
                    size_t bufferSize;
6664
0
                    drflac_uint8 iTrack;
6665
0
                    drflac_uint8 iIndex;
6666
0
                    void* pTrackData;
6667
6668
                    /*
6669
                    This needs to be loaded in two passes. The first pass is used to calculate the size of the memory allocation
6670
                    we need for storing the necessary data. The second pass will fill that buffer with usable data.
6671
                    */
6672
0
                    pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6673
0
                    if (pRawData == NULL) {
6674
0
                        return DRFLAC_FALSE;
6675
0
                    }
6676
6677
0
                    if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6678
0
                        drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6679
0
                        return DRFLAC_FALSE;
6680
0
                    }
6681
6682
0
                    metadata.pRawData = pRawData;
6683
0
                    metadata.rawDataSize = blockSize;
6684
6685
0
                    pRunningData    = (const char*)pRawData;
6686
0
                    pRunningDataEnd = (const char*)pRawData + blockSize;
6687
6688
0
                    DRFLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128);                              pRunningData += 128;
6689
0
                    metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
6690
0
                    metadata.data.cuesheet.isCD              = (pRunningData[0] & 0x80) != 0;                           pRunningData += 259;
6691
0
                    metadata.data.cuesheet.trackCount        = pRunningData[0];                                         pRunningData += 1;
6692
0
                    metadata.data.cuesheet.pTrackData        = NULL;    /* Will be filled later. */
6693
6694
                    /* Pass 1: Calculate the size of the buffer for the track data. */
6695
0
                    {
6696
0
                        const char* pRunningDataSaved = pRunningData;   /* Will be restored at the end in preparation for the second pass. */
6697
6698
0
                        bufferSize = metadata.data.cuesheet.trackCount * DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES;
6699
6700
0
                        for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
6701
0
                            drflac_uint8 indexCount;
6702
0
                            drflac_uint32 indexPointSize;
6703
6704
0
                            if (pRunningDataEnd - pRunningData < DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES) {
6705
0
                                drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6706
0
                                return DRFLAC_FALSE;
6707
0
                            }
6708
6709
                            /* Skip to the index point count */
6710
0
                            pRunningData += 35;
6711
6712
0
                            indexCount = pRunningData[0];
6713
0
                            pRunningData += 1;
6714
6715
0
                            bufferSize += indexCount * sizeof(drflac_cuesheet_track_index);
6716
6717
                            /* Quick validation check. */
6718
0
                            indexPointSize = indexCount * DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
6719
0
                            if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
6720
0
                                drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6721
0
                                return DRFLAC_FALSE;
6722
0
                            }
6723
6724
0
                            pRunningData += indexPointSize;
6725
0
                        }
6726
6727
0
                        pRunningData = pRunningDataSaved;
6728
0
                    }
6729
6730
                    /* Pass 2: Allocate a buffer and fill the data. Validation was done in the step above so can be skipped. */
6731
0
                    {
6732
0
                        char* pRunningTrackData;
6733
6734
0
                        pTrackData = drflac__malloc_from_callbacks(bufferSize, pAllocationCallbacks);
6735
0
                        if (pTrackData == NULL) {
6736
0
                            drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6737
0
                            return DRFLAC_FALSE;
6738
0
                        }
6739
6740
0
                        pRunningTrackData = (char*)pTrackData;
6741
6742
0
                        for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
6743
0
                            drflac_uint8 indexCount;
6744
6745
0
                            DRFLAC_COPY_MEMORY(pRunningTrackData, pRunningData, DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES);
6746
0
                            pRunningData      += DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1; /* Skip forward, but not beyond the last byte in the CUESHEET_TRACK block which is the index count. */
6747
0
                            pRunningTrackData += DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1;
6748
6749
                            /* Grab the index count for the next part. */
6750
0
                            indexCount = pRunningData[0];
6751
0
                            pRunningData      += 1;
6752
0
                            pRunningTrackData += 1;
6753
6754
                            /* Extract each track index. */
6755
0
                            for (iIndex = 0; iIndex < indexCount; ++iIndex) {
6756
0
                                drflac_cuesheet_track_index* pTrackIndex = (drflac_cuesheet_track_index*)pRunningTrackData;
6757
6758
0
                                DRFLAC_COPY_MEMORY(pRunningTrackData, pRunningData, DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES);
6759
0
                                pRunningData      += DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
6760
0
                                pRunningTrackData += sizeof(drflac_cuesheet_track_index);
6761
6762
0
                                pTrackIndex->offset = drflac__be2host_64(pTrackIndex->offset);
6763
0
                            }
6764
0
                        }
6765
6766
0
                        metadata.data.cuesheet.pTrackData = pTrackData;
6767
0
                    }
6768
6769
                    /* The original data is no longer needed. */
6770
0
                    drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6771
0
                    pRawData = NULL;
6772
6773
0
                    onMeta(pUserDataMD, &metadata);
6774
6775
0
                    drflac__free_from_callbacks(pTrackData, pAllocationCallbacks);
6776
0
                    pTrackData = NULL;
6777
0
                }
6778
0
            } break;
6779
6780
0
            case DRFLAC_METADATA_BLOCK_TYPE_PICTURE:
6781
0
            {
6782
0
                if (blockSize < 32) {
6783
0
                    return DRFLAC_FALSE;
6784
0
                }
6785
6786
0
                if (onMeta) {
6787
0
                    drflac_bool32 result = DRFLAC_TRUE;
6788
0
                    drflac_uint32 blockSizeRemaining = blockSize;
6789
0
                    char* pMime = NULL;
6790
0
                    char* pDescription = NULL;
6791
0
                    void* pPictureData = NULL;
6792
6793
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.type, 4) != 4) {
6794
0
                        result = DRFLAC_FALSE;
6795
0
                        goto done_flac;
6796
0
                    }
6797
0
                    blockSizeRemaining -= 4;
6798
0
                    metadata.data.picture.type = drflac__be2host_32(metadata.data.picture.type);
6799
6800
6801
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.mimeLength, 4) != 4) {
6802
0
                        result = DRFLAC_FALSE;
6803
0
                        goto done_flac;
6804
0
                    }
6805
0
                    blockSizeRemaining -= 4;
6806
0
                    metadata.data.picture.mimeLength = drflac__be2host_32(metadata.data.picture.mimeLength);
6807
6808
0
                    if (blockSizeRemaining < metadata.data.picture.mimeLength) {
6809
0
                        result = DRFLAC_FALSE;
6810
0
                        goto done_flac;
6811
0
                    }
6812
6813
0
                    pMime = (char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
6814
0
                    if (pMime == NULL) {
6815
0
                        result = DRFLAC_FALSE;
6816
0
                        goto done_flac;
6817
0
                    }
6818
6819
0
                    if (onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
6820
0
                        result = DRFLAC_FALSE;
6821
0
                        goto done_flac;
6822
0
                    }
6823
0
                    blockSizeRemaining -= metadata.data.picture.mimeLength;
6824
0
                    pMime[metadata.data.picture.mimeLength] = '\0';  /* Null terminate for safety. */
6825
0
                    metadata.data.picture.mime = (const char*)pMime;
6826
6827
6828
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.descriptionLength, 4) != 4) {
6829
0
                        result = DRFLAC_FALSE;
6830
0
                        goto done_flac;
6831
0
                    }
6832
0
                    blockSizeRemaining -= 4;
6833
0
                    metadata.data.picture.descriptionLength = drflac__be2host_32(metadata.data.picture.descriptionLength);
6834
6835
0
                    if (blockSizeRemaining < metadata.data.picture.descriptionLength) {
6836
0
                        result = DRFLAC_FALSE;
6837
0
                        goto done_flac;
6838
0
                    }
6839
6840
0
                    pDescription = (char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
6841
0
                    if (pDescription == NULL) {
6842
0
                        result = DRFLAC_FALSE;
6843
0
                        goto done_flac;
6844
0
                    }
6845
6846
0
                    if (onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
6847
0
                        result = DRFLAC_FALSE;
6848
0
                        goto done_flac;
6849
0
                    }
6850
0
                    blockSizeRemaining -= metadata.data.picture.descriptionLength;
6851
0
                    pDescription[metadata.data.picture.descriptionLength] = '\0';  /* Null terminate for safety. */
6852
0
                    metadata.data.picture.description = (const char*)pDescription;
6853
6854
6855
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.width, 4) != 4) {
6856
0
                        result = DRFLAC_FALSE;
6857
0
                        goto done_flac;
6858
0
                    }
6859
0
                    blockSizeRemaining -= 4;
6860
0
                    metadata.data.picture.width = drflac__be2host_32(metadata.data.picture.width);
6861
6862
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.height, 4) != 4) {
6863
0
                        result = DRFLAC_FALSE;
6864
0
                        goto done_flac;
6865
0
                    }
6866
0
                    blockSizeRemaining -= 4;
6867
0
                    metadata.data.picture.height = drflac__be2host_32(metadata.data.picture.height);
6868
6869
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.colorDepth, 4) != 4) {
6870
0
                        result = DRFLAC_FALSE;
6871
0
                        goto done_flac;
6872
0
                    }
6873
0
                    blockSizeRemaining -= 4;
6874
0
                    metadata.data.picture.colorDepth = drflac__be2host_32(metadata.data.picture.colorDepth);
6875
6876
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.indexColorCount, 4) != 4) {
6877
0
                        result = DRFLAC_FALSE;
6878
0
                        goto done_flac;
6879
0
                    }
6880
0
                    blockSizeRemaining -= 4;
6881
0
                    metadata.data.picture.indexColorCount = drflac__be2host_32(metadata.data.picture.indexColorCount);
6882
6883
6884
                    /* Picture data. */
6885
0
                    if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.pictureDataSize, 4) != 4) {
6886
0
                        result = DRFLAC_FALSE;
6887
0
                        goto done_flac;
6888
0
                    }
6889
0
                    blockSizeRemaining -= 4;
6890
0
                    metadata.data.picture.pictureDataSize = drflac__be2host_32(metadata.data.picture.pictureDataSize);
6891
6892
0
                    if (blockSizeRemaining < metadata.data.picture.pictureDataSize) {
6893
0
                        result = DRFLAC_FALSE;
6894
0
                        goto done_flac;
6895
0
                    }
6896
6897
                    /* For the actual image data we want to store the offset to the start of the stream. */
6898
0
                    metadata.data.picture.pictureDataOffset = runningFilePos + (blockSize - blockSizeRemaining);
6899
6900
                    /*
6901
                    For the allocation of image data, we can allow memory allocation to fail, in which case we just leave
6902
                    the pointer as null. If it fails, we need to fall back to seeking past the image data.
6903
                    */
6904
0
                #ifndef DR_FLAC_NO_PICTURE_METADATA_MALLOC
6905
0
                    pPictureData = drflac__malloc_from_callbacks(metadata.data.picture.pictureDataSize, pAllocationCallbacks);
6906
0
                    if (pPictureData != NULL) {
6907
0
                        if (onRead(pUserData, pPictureData, metadata.data.picture.pictureDataSize) != metadata.data.picture.pictureDataSize) {
6908
0
                            result = DRFLAC_FALSE;
6909
0
                            goto done_flac;
6910
0
                        }
6911
0
                    } else
6912
0
                #endif
6913
0
                    {
6914
                        /* Allocation failed. We need to seek past the picture data. */
6915
0
                        if (!onSeek(pUserData, metadata.data.picture.pictureDataSize, DRFLAC_SEEK_CUR)) {
6916
0
                            result = DRFLAC_FALSE;
6917
0
                            goto done_flac;
6918
0
                        }
6919
0
                    }
6920
6921
0
                    blockSizeRemaining -= metadata.data.picture.pictureDataSize;
6922
0
                    (void)blockSizeRemaining;
6923
6924
0
                    metadata.data.picture.pPictureData = (const drflac_uint8*)pPictureData;
6925
                    
6926
6927
                    /* Only fire the callback if we actually have a way to read the image data. We must have either a valid offset, or a valid data pointer. */
6928
0
                    if (metadata.data.picture.pictureDataOffset != 0 || metadata.data.picture.pPictureData != NULL) {
6929
0
                        onMeta(pUserDataMD, &metadata);
6930
0
                    } else {
6931
                        /* Don't have a valid offset or data pointer, so just pretend we don't have a picture metadata. */
6932
0
                    }
6933
6934
0
                done_flac:
6935
0
                    drflac__free_from_callbacks(pMime,        pAllocationCallbacks);
6936
0
                    drflac__free_from_callbacks(pDescription, pAllocationCallbacks);
6937
0
                    drflac__free_from_callbacks(pPictureData, pAllocationCallbacks);
6938
6939
0
                    if (result != DRFLAC_TRUE) {
6940
0
                        return DRFLAC_FALSE;
6941
0
                    }
6942
0
                }
6943
0
            } break;
6944
6945
0
            case DRFLAC_METADATA_BLOCK_TYPE_PADDING:
6946
0
            {
6947
0
                if (onMeta) {
6948
0
                    metadata.data.padding.unused = 0;
6949
6950
                    /* 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. */
6951
0
                    if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
6952
0
                        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. */
6953
0
                    } else {
6954
0
                        onMeta(pUserDataMD, &metadata);
6955
0
                    }
6956
0
                }
6957
0
            } break;
6958
6959
0
            case DRFLAC_METADATA_BLOCK_TYPE_INVALID:
6960
0
            {
6961
                /* Invalid chunk. Just skip over this one. */
6962
0
                if (onMeta) {
6963
0
                    if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
6964
0
                        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. */
6965
0
                    }
6966
0
                }
6967
0
            } break;
6968
6969
0
            default:
6970
0
            {
6971
                /*
6972
                It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we
6973
                can at the very least report the chunk to the application and let it look at the raw data.
6974
                */
6975
0
                if (onMeta) {
6976
0
                    void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6977
0
                    if (pRawData != NULL) {
6978
0
                        if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6979
0
                            drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6980
0
                            return DRFLAC_FALSE;
6981
0
                        }
6982
0
                    } else {
6983
                        /* Allocation failed. We need to seek past the block. */
6984
0
                        if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
6985
0
                            return DRFLAC_FALSE;
6986
0
                        }
6987
0
                    }
6988
6989
0
                    metadata.pRawData = pRawData;
6990
0
                    metadata.rawDataSize = blockSize;
6991
0
                    onMeta(pUserDataMD, &metadata);
6992
6993
0
                    drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6994
0
                }
6995
0
            } break;
6996
0
        }
6997
6998
        /* 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. */
6999
0
        if (onMeta == NULL && blockSize > 0) {
7000
0
            if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
7001
0
                isLastBlock = DRFLAC_TRUE;
7002
0
            }
7003
0
        }
7004
7005
0
        runningFilePos += blockSize;
7006
0
        if (isLastBlock) {
7007
0
            break;
7008
0
        }
7009
0
    }
7010
7011
0
    *pSeektablePos   = seektablePos;
7012
0
    *pSeekpointCount = seektableSize / DRFLAC_SEEKPOINT_SIZE_IN_BYTES;
7013
0
    *pFirstFramePos  = runningFilePos;
7014
7015
0
    return DRFLAC_TRUE;
7016
0
}
7017
7018
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)
7019
0
{
7020
    /* Pre Condition: The bit stream should be sitting just past the 4-byte id header. */
7021
7022
0
    drflac_uint8 isLastBlock;
7023
0
    drflac_uint8 blockType;
7024
0
    drflac_uint32 blockSize;
7025
7026
0
    (void)onSeek;
7027
7028
0
    pInit->container = drflac_container_native;
7029
7030
    /* The first metadata block should be the STREAMINFO block. */
7031
0
    if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
7032
0
        return DRFLAC_FALSE;
7033
0
    }
7034
7035
0
    if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
7036
0
        if (!relaxed) {
7037
            /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */
7038
0
            return DRFLAC_FALSE;
7039
0
        } else {
7040
            /*
7041
            Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined
7042
            for that frame.
7043
            */
7044
0
            pInit->hasStreamInfoBlock = DRFLAC_FALSE;
7045
0
            pInit->hasMetadataBlocks  = DRFLAC_FALSE;
7046
7047
0
            if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
7048
0
                return DRFLAC_FALSE;    /* Couldn't find a frame. */
7049
0
            }
7050
7051
0
            if (pInit->firstFrameHeader.bitsPerSample == 0) {
7052
0
                return DRFLAC_FALSE;    /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */
7053
0
            }
7054
7055
0
            pInit->sampleRate              = pInit->firstFrameHeader.sampleRate;
7056
0
            pInit->channels                = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment);
7057
0
            pInit->bitsPerSample           = pInit->firstFrameHeader.bitsPerSample;
7058
0
            pInit->maxBlockSizeInPCMFrames = 65535;   /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */
7059
0
            return DRFLAC_TRUE;
7060
0
        }
7061
0
    } else {
7062
0
        drflac_streaminfo streaminfo;
7063
0
        if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
7064
0
            return DRFLAC_FALSE;
7065
0
        }
7066
7067
0
        pInit->hasStreamInfoBlock      = DRFLAC_TRUE;
7068
0
        pInit->sampleRate              = streaminfo.sampleRate;
7069
0
        pInit->channels                = streaminfo.channels;
7070
0
        pInit->bitsPerSample           = streaminfo.bitsPerSample;
7071
0
        pInit->totalPCMFrameCount      = streaminfo.totalPCMFrameCount;
7072
0
        pInit->maxBlockSizeInPCMFrames = streaminfo.maxBlockSizeInPCMFrames;    /* Don't care about the min block size - only the max (used for determining the size of the memory allocation). */
7073
0
        pInit->hasMetadataBlocks       = !isLastBlock;
7074
7075
0
        if (onMeta) {
7076
0
            drflac_metadata metadata;
7077
0
            metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
7078
0
            metadata.pRawData = NULL;
7079
0
            metadata.rawDataSize = 0;
7080
0
            metadata.data.streaminfo = streaminfo;
7081
0
            onMeta(pUserDataMD, &metadata);
7082
0
        }
7083
7084
0
        return DRFLAC_TRUE;
7085
0
    }
7086
0
}
7087
7088
#ifndef DR_FLAC_NO_OGG
7089
0
#define DRFLAC_OGG_MAX_PAGE_SIZE            65307
7090
0
#define DRFLAC_OGG_CAPTURE_PATTERN_CRC32    1605413199  /* CRC-32 of "OggS". */
7091
7092
typedef enum
7093
{
7094
    drflac_ogg_recover_on_crc_mismatch,
7095
    drflac_ogg_fail_on_crc_mismatch
7096
} drflac_ogg_crc_mismatch_recovery;
7097
7098
#ifndef DR_FLAC_NO_CRC
7099
static drflac_uint32 drflac__crc32_table[] = {
7100
    0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
7101
    0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
7102
    0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
7103
    0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
7104
    0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
7105
    0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
7106
    0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
7107
    0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
7108
    0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
7109
    0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
7110
    0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
7111
    0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
7112
    0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
7113
    0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
7114
    0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
7115
    0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
7116
    0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
7117
    0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
7118
    0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
7119
    0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
7120
    0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
7121
    0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
7122
    0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
7123
    0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
7124
    0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
7125
    0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
7126
    0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
7127
    0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
7128
    0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
7129
    0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
7130
    0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
7131
    0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
7132
    0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
7133
    0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
7134
    0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
7135
    0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
7136
    0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
7137
    0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
7138
    0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
7139
    0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
7140
    0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
7141
    0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
7142
    0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
7143
    0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
7144
    0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
7145
    0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
7146
    0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
7147
    0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
7148
    0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
7149
    0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
7150
    0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
7151
    0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
7152
    0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
7153
    0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
7154
    0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
7155
    0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
7156
    0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
7157
    0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
7158
    0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
7159
    0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
7160
    0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
7161
    0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
7162
    0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
7163
    0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
7164
};
7165
#endif
7166
7167
static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data)
7168
0
{
7169
0
#ifndef DR_FLAC_NO_CRC
7170
0
    return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data];
7171
#else
7172
    (void)data;
7173
    return crc32;
7174
#endif
7175
0
}
7176
7177
#if 0
7178
static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data)
7179
{
7180
    crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
7181
    crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
7182
    crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >>  8) & 0xFF));
7183
    crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >>  0) & 0xFF));
7184
    return crc32;
7185
}
7186
7187
static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data)
7188
{
7189
    crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
7190
    crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >>  0) & 0xFFFFFFFF));
7191
    return crc32;
7192
}
7193
#endif
7194
7195
static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize)
7196
0
{
7197
    /* This can be optimized. */
7198
0
    drflac_uint32 i;
7199
0
    for (i = 0; i < dataSize; ++i) {
7200
0
        crc32 = drflac_crc32_byte(crc32, pData[i]);
7201
0
    }
7202
0
    return crc32;
7203
0
}
7204
7205
7206
static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4])
7207
0
{
7208
0
    return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S';
7209
0
}
7210
7211
static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader)
7212
0
{
7213
0
    return 27 + pHeader->segmentCount;
7214
0
}
7215
7216
static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader)
7217
0
{
7218
0
    drflac_uint32 pageBodySize = 0;
7219
0
    int i;
7220
7221
0
    for (i = 0; i < pHeader->segmentCount; ++i) {
7222
0
        pageBodySize += pHeader->segmentTable[i];
7223
0
    }
7224
7225
0
    return pageBodySize;
7226
0
}
7227
7228
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)
7229
0
{
7230
0
    drflac_uint8 data[23];
7231
0
    drflac_uint32 i;
7232
7233
0
    DRFLAC_ASSERT(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32);
7234
7235
0
    if (onRead(pUserData, data, 23) != 23) {
7236
0
        return DRFLAC_AT_END;
7237
0
    }
7238
0
    *pBytesRead += 23;
7239
7240
    /*
7241
    It's not actually used, but set the capture pattern to 'OggS' for completeness. Not doing this will cause static analysers to complain about
7242
    us trying to access uninitialized data. We could alternatively just comment out this member of the drflac_ogg_page_header structure, but I
7243
    like to have it map to the structure of the underlying data.
7244
    */
7245
0
    pHeader->capturePattern[0] = 'O';
7246
0
    pHeader->capturePattern[1] = 'g';
7247
0
    pHeader->capturePattern[2] = 'g';
7248
0
    pHeader->capturePattern[3] = 'S';
7249
7250
0
    pHeader->structureVersion = data[0];
7251
0
    pHeader->headerType       = data[1];
7252
0
    DRFLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
7253
0
    DRFLAC_COPY_MEMORY(&pHeader->serialNumber,    &data[10], 4);
7254
0
    DRFLAC_COPY_MEMORY(&pHeader->sequenceNumber,  &data[14], 4);
7255
0
    DRFLAC_COPY_MEMORY(&pHeader->checksum,        &data[18], 4);
7256
0
    pHeader->segmentCount     = data[22];
7257
7258
    /* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */
7259
0
    data[18] = 0;
7260
0
    data[19] = 0;
7261
0
    data[20] = 0;
7262
0
    data[21] = 0;
7263
7264
0
    for (i = 0; i < 23; ++i) {
7265
0
        *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]);
7266
0
    }
7267
7268
7269
0
    if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
7270
0
        return DRFLAC_AT_END;
7271
0
    }
7272
0
    *pBytesRead += pHeader->segmentCount;
7273
7274
0
    for (i = 0; i < pHeader->segmentCount; ++i) {
7275
0
        *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]);
7276
0
    }
7277
7278
0
    return DRFLAC_SUCCESS;
7279
0
}
7280
7281
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)
7282
0
{
7283
0
    drflac_uint8 id[4];
7284
7285
0
    *pBytesRead = 0;
7286
7287
0
    if (onRead(pUserData, id, 4) != 4) {
7288
0
        return DRFLAC_AT_END;
7289
0
    }
7290
0
    *pBytesRead += 4;
7291
7292
    /* We need to read byte-by-byte until we find the OggS capture pattern. */
7293
0
    for (;;) {
7294
0
        if (drflac_ogg__is_capture_pattern(id)) {
7295
0
            drflac_result result;
7296
7297
0
            *pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
7298
7299
0
            result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
7300
0
            if (result == DRFLAC_SUCCESS) {
7301
0
                return DRFLAC_SUCCESS;
7302
0
            } else {
7303
0
                if (result == DRFLAC_CRC_MISMATCH) {
7304
0
                    continue;
7305
0
                } else {
7306
0
                    return result;
7307
0
                }
7308
0
            }
7309
0
        } else {
7310
            /* The first 4 bytes did not equal the capture pattern. Read the next byte and try again. */
7311
0
            id[0] = id[1];
7312
0
            id[1] = id[2];
7313
0
            id[2] = id[3];
7314
0
            if (onRead(pUserData, &id[3], 1) != 1) {
7315
0
                return DRFLAC_AT_END;
7316
0
            }
7317
0
            *pBytesRead += 1;
7318
0
        }
7319
0
    }
7320
0
}
7321
7322
7323
/*
7324
The main part of the Ogg encapsulation is the conversion from the physical Ogg bitstream to the native FLAC bitstream. It works
7325
in three general stages: Ogg Physical Bitstream -> Ogg/FLAC Logical Bitstream -> FLAC Native Bitstream. dr_flac is designed
7326
in such a way that the core sections assume everything is delivered in native format. Therefore, for each encapsulation type
7327
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
7328
the physical Ogg bitstream are converted and delivered in native FLAC format.
7329
*/
7330
typedef struct
7331
{
7332
    drflac_read_proc onRead;                /* The original onRead callback from drflac_open() and family. */
7333
    drflac_seek_proc onSeek;                /* The original onSeek callback from drflac_open() and family. */
7334
    drflac_tell_proc onTell;                /* The original onTell callback from drflac_open() and family. */
7335
    void* pUserData;                        /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */
7336
    drflac_uint64 currentBytePos;           /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */
7337
    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. */
7338
    drflac_uint32 serialNumber;             /* The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization. */
7339
    drflac_ogg_page_header bosPageHeader;   /* Used for seeking. */
7340
    drflac_ogg_page_header currentPageHeader;
7341
    drflac_uint32 bytesRemainingInPage;
7342
    drflac_uint32 pageDataSize;
7343
    drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE];
7344
} drflac_oggbs; /* oggbs = Ogg Bitstream */
7345
7346
static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
7347
0
{
7348
0
    size_t bytesActuallyRead = oggbs->onRead(oggbs->pUserData, bufferOut, bytesToRead);
7349
0
    oggbs->currentBytePos += bytesActuallyRead;
7350
7351
0
    return bytesActuallyRead;
7352
0
}
7353
7354
static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
7355
0
{
7356
0
    if (origin == DRFLAC_SEEK_SET) {
7357
0
        if (offset <= 0x7FFFFFFF) {
7358
0
            if (!oggbs->onSeek(oggbs->pUserData, (int)offset, DRFLAC_SEEK_SET)) {
7359
0
                return DRFLAC_FALSE;
7360
0
            }
7361
0
            oggbs->currentBytePos = offset;
7362
7363
0
            return DRFLAC_TRUE;
7364
0
        } else {
7365
0
            if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_SET)) {
7366
0
                return DRFLAC_FALSE;
7367
0
            }
7368
0
            oggbs->currentBytePos = offset;
7369
7370
0
            return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, DRFLAC_SEEK_CUR);
7371
0
        }
7372
0
    } else {
7373
0
        while (offset > 0x7FFFFFFF) {
7374
0
            if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_CUR)) {
7375
0
                return DRFLAC_FALSE;
7376
0
            }
7377
0
            oggbs->currentBytePos += 0x7FFFFFFF;
7378
0
            offset -= 0x7FFFFFFF;
7379
0
        }
7380
7381
0
        if (!oggbs->onSeek(oggbs->pUserData, (int)offset, DRFLAC_SEEK_CUR)) {    /* <-- Safe cast thanks to the loop above. */
7382
0
            return DRFLAC_FALSE;
7383
0
        }
7384
0
        oggbs->currentBytePos += offset;
7385
7386
0
        return DRFLAC_TRUE;
7387
0
    }
7388
0
}
7389
7390
static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod)
7391
0
{
7392
0
    drflac_ogg_page_header header;
7393
0
    for (;;) {
7394
0
        drflac_uint32 crc32 = 0;
7395
0
        drflac_uint32 bytesRead;
7396
0
        drflac_uint32 pageBodySize;
7397
0
#ifndef DR_FLAC_NO_CRC
7398
0
        drflac_uint32 actualCRC32;
7399
0
#endif
7400
7401
0
        if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7402
0
            return DRFLAC_FALSE;
7403
0
        }
7404
0
        oggbs->currentBytePos += bytesRead;
7405
7406
0
        pageBodySize = drflac_ogg__get_page_body_size(&header);
7407
0
        if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) {
7408
0
            continue;   /* Invalid page size. Assume it's corrupted and just move to the next page. */
7409
0
        }
7410
7411
0
        if (header.serialNumber != oggbs->serialNumber) {
7412
            /* It's not a FLAC page. Skip it. */
7413
0
            if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, DRFLAC_SEEK_CUR)) {
7414
0
                return DRFLAC_FALSE;
7415
0
            }
7416
0
            continue;
7417
0
        }
7418
7419
7420
        /* 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. */
7421
0
        if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) {
7422
0
            return DRFLAC_FALSE;
7423
0
        }
7424
0
        oggbs->pageDataSize = pageBodySize;
7425
7426
0
#ifndef DR_FLAC_NO_CRC
7427
0
        actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize);
7428
0
        if (actualCRC32 != header.checksum) {
7429
0
            if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) {
7430
0
                continue;   /* CRC mismatch. Skip this page. */
7431
0
            } else {
7432
                /*
7433
                Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we
7434
                go to the next valid page to ensure we're in a good state, but return false to let the caller know that the
7435
                seek did not fully complete.
7436
                */
7437
0
                drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch);
7438
0
                return DRFLAC_FALSE;
7439
0
            }
7440
0
        }
7441
#else
7442
        (void)recoveryMethod;   /* <-- Silence a warning. */
7443
#endif
7444
7445
0
        oggbs->currentPageHeader = header;
7446
0
        oggbs->bytesRemainingInPage = pageBodySize;
7447
0
        return DRFLAC_TRUE;
7448
0
    }
7449
0
}
7450
7451
/* Function below is unused at the moment, but I might be re-adding it later. */
7452
#if 0
7453
static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg)
7454
{
7455
    drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
7456
    drflac_uint8 iSeg = 0;
7457
    drflac_uint32 iByte = 0;
7458
    while (iByte < bytesConsumedInPage) {
7459
        drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
7460
        if (iByte + segmentSize > bytesConsumedInPage) {
7461
            break;
7462
        } else {
7463
            iSeg += 1;
7464
            iByte += segmentSize;
7465
        }
7466
    }
7467
7468
    *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte);
7469
    return iSeg;
7470
}
7471
7472
static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
7473
{
7474
    /* 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. */
7475
    for (;;) {
7476
        drflac_bool32 atEndOfPage = DRFLAC_FALSE;
7477
7478
        drflac_uint8 bytesRemainingInSeg;
7479
        drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
7480
7481
        drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
7482
        for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
7483
            drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
7484
            if (segmentSize < 255) {
7485
                if (iSeg == oggbs->currentPageHeader.segmentCount-1) {
7486
                    atEndOfPage = DRFLAC_TRUE;
7487
                }
7488
7489
                break;
7490
            }
7491
7492
            bytesToEndOfPacketOrPage += segmentSize;
7493
        }
7494
7495
        /*
7496
        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
7497
        want to load the next page and keep searching for the end of the packet.
7498
        */
7499
        drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, DRFLAC_SEEK_CUR);
7500
        oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
7501
7502
        if (atEndOfPage) {
7503
            /*
7504
            We're potentially at the next packet, but we need to check the next page first to be sure because the packet may
7505
            straddle pages.
7506
            */
7507
            if (!drflac_oggbs__goto_next_page(oggbs)) {
7508
                return DRFLAC_FALSE;
7509
            }
7510
7511
            /* If it's a fresh packet it most likely means we're at the next packet. */
7512
            if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
7513
                return DRFLAC_TRUE;
7514
            }
7515
        } else {
7516
            /* We're at the next packet. */
7517
            return DRFLAC_TRUE;
7518
        }
7519
    }
7520
}
7521
7522
static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
7523
{
7524
    /* The bitstream should be sitting on the first byte just after the header of the frame. */
7525
7526
    /* What we're actually doing here is seeking to the start of the next packet. */
7527
    return drflac_oggbs__seek_to_next_packet(oggbs);
7528
}
7529
#endif
7530
7531
static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
7532
0
{
7533
0
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
7534
0
    drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
7535
0
    size_t bytesRead = 0;
7536
7537
0
    DRFLAC_ASSERT(oggbs != NULL);
7538
0
    DRFLAC_ASSERT(pRunningBufferOut != NULL);
7539
7540
    /* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */
7541
0
    while (bytesRead < bytesToRead) {
7542
0
        size_t bytesRemainingToRead = bytesToRead - bytesRead;
7543
7544
0
        if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) {
7545
0
            DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
7546
0
            bytesRead += bytesRemainingToRead;
7547
0
            oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead;
7548
0
            break;
7549
0
        }
7550
7551
        /* If we get here it means some of the requested data is contained in the next pages. */
7552
0
        if (oggbs->bytesRemainingInPage > 0) {
7553
0
            DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
7554
0
            bytesRead += oggbs->bytesRemainingInPage;
7555
0
            pRunningBufferOut += oggbs->bytesRemainingInPage;
7556
0
            oggbs->bytesRemainingInPage = 0;
7557
0
        }
7558
7559
0
        DRFLAC_ASSERT(bytesRemainingToRead > 0);
7560
0
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7561
0
            break;  /* Failed to go to the next page. Might have simply hit the end of the stream. */
7562
0
        }
7563
0
    }
7564
7565
0
    return bytesRead;
7566
0
}
7567
7568
static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin)
7569
0
{
7570
0
    drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
7571
0
    int bytesSeeked = 0;
7572
7573
0
    DRFLAC_ASSERT(oggbs != NULL);
7574
0
    DRFLAC_ASSERT(offset >= 0);  /* <-- Never seek backwards. */
7575
7576
    /* Seeking is always forward which makes things a lot simpler. */
7577
0
    if (origin == DRFLAC_SEEK_SET) {
7578
0
        if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, DRFLAC_SEEK_SET)) {
7579
0
            return DRFLAC_FALSE;
7580
0
        }
7581
7582
0
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
7583
0
            return DRFLAC_FALSE;
7584
0
        }
7585
7586
0
        return drflac__on_seek_ogg(pUserData, offset, DRFLAC_SEEK_CUR);
7587
0
    } else if (origin == DRFLAC_SEEK_CUR) {
7588
0
        while (bytesSeeked < offset) {
7589
0
            int bytesRemainingToSeek = offset - bytesSeeked;
7590
0
            DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
7591
7592
0
            if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
7593
0
                bytesSeeked += bytesRemainingToSeek;
7594
0
                (void)bytesSeeked;  /* <-- Silence a dead store warning emitted by Clang Static Analyzer. */
7595
0
                oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
7596
0
                break;
7597
0
            }
7598
7599
            /* If we get here it means some of the requested data is contained in the next pages. */
7600
0
            if (oggbs->bytesRemainingInPage > 0) {
7601
0
                bytesSeeked += (int)oggbs->bytesRemainingInPage;
7602
0
                oggbs->bytesRemainingInPage = 0;
7603
0
            }
7604
7605
0
            DRFLAC_ASSERT(bytesRemainingToSeek > 0);
7606
0
            if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
7607
                /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
7608
0
                return DRFLAC_FALSE;
7609
0
            }
7610
0
        }
7611
0
    } else if (origin == DRFLAC_SEEK_END) {
7612
        /* Seeking to the end is not supported. */
7613
0
        return DRFLAC_FALSE;
7614
0
    }
7615
7616
0
    return DRFLAC_TRUE;
7617
0
}
7618
7619
static drflac_bool32 drflac__on_tell_ogg(void* pUserData, drflac_int64* pCursor)
7620
0
{
7621
    /*
7622
    Not implemented for Ogg containers because we don't currently track the byte position of the logical bitstream. To support this, we'll need
7623
    to track the position in drflac__on_read_ogg and drflac__on_seek_ogg.
7624
    */
7625
0
    (void)pUserData;
7626
0
    (void)pCursor;
7627
0
    return DRFLAC_FALSE;
7628
0
}
7629
7630
7631
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
7632
0
{
7633
0
    drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
7634
0
    drflac_uint64 originalBytePos;
7635
0
    drflac_uint64 runningGranulePosition;
7636
0
    drflac_uint64 runningFrameBytePos;
7637
0
    drflac_uint64 runningPCMFrameCount;
7638
7639
0
    DRFLAC_ASSERT(oggbs != NULL);
7640
7641
0
    originalBytePos = oggbs->currentBytePos;   /* For recovery. Points to the OggS identifier. */
7642
7643
    /* First seek to the first frame. */
7644
0
    if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes)) {
7645
0
        return DRFLAC_FALSE;
7646
0
    }
7647
0
    oggbs->bytesRemainingInPage = 0;
7648
7649
0
    runningGranulePosition = 0;
7650
0
    for (;;) {
7651
0
        if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7652
0
            drflac_oggbs__seek_physical(oggbs, originalBytePos, DRFLAC_SEEK_SET);
7653
0
            return DRFLAC_FALSE;   /* Never did find that sample... */
7654
0
        }
7655
7656
0
        runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
7657
0
        if (oggbs->currentPageHeader.granulePosition >= pcmFrameIndex) {
7658
0
            break; /* The sample is somewhere in the previous page. */
7659
0
        }
7660
7661
        /*
7662
        At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
7663
        disregard any pages that do not begin a fresh packet.
7664
        */
7665
0
        if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {    /* <-- Is it a fresh page? */
7666
0
            if (oggbs->currentPageHeader.segmentTable[0] >= 2) {
7667
0
                drflac_uint8 firstBytesInPage[2];
7668
0
                firstBytesInPage[0] = oggbs->pageData[0];
7669
0
                firstBytesInPage[1] = oggbs->pageData[1];
7670
7671
0
                if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) {    /* <-- Does the page begin with a frame's sync code? */
7672
0
                    runningGranulePosition = oggbs->currentPageHeader.granulePosition;
7673
0
                }
7674
7675
0
                continue;
7676
0
            }
7677
0
        }
7678
0
    }
7679
7680
    /*
7681
    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
7682
    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
7683
    a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
7684
    we find the one containing the target sample.
7685
    */
7686
0
    if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, DRFLAC_SEEK_SET)) {
7687
0
        return DRFLAC_FALSE;
7688
0
    }
7689
0
    if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
7690
0
        return DRFLAC_FALSE;
7691
0
    }
7692
7693
    /*
7694
    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
7695
    looping over these frames until we find the one containing the sample we're after.
7696
    */
7697
0
    runningPCMFrameCount = runningGranulePosition;
7698
0
    for (;;) {
7699
        /*
7700
        There are two ways to find the sample and seek past irrelevant frames:
7701
          1) Use the native FLAC decoder.
7702
          2) Use Ogg's framing system.
7703
7704
        Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to
7705
        do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code
7706
        duplication for the decoding of frame headers.
7707
7708
        Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg
7709
        bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the
7710
        standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks
7711
        the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read
7712
        using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to
7713
        avoid the use of the drflac_bs object.
7714
7715
        Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons:
7716
          1) Seeking is already partially accelerated using Ogg's paging system in the code block above.
7717
          2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon.
7718
          3) Simplicity.
7719
        */
7720
0
        drflac_uint64 firstPCMFrameInFLACFrame = 0;
7721
0
        drflac_uint64 lastPCMFrameInFLACFrame = 0;
7722
0
        drflac_uint64 pcmFrameCountInThisFrame;
7723
7724
0
        if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
7725
0
            return DRFLAC_FALSE;
7726
0
        }
7727
7728
0
        drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
7729
7730
0
        pcmFrameCountInThisFrame = (lastPCMFrameInFLACFrame - firstPCMFrameInFLACFrame) + 1;
7731
7732
        /* If we are seeking to the end of the file and we've just hit it, we're done. */
7733
0
        if (pcmFrameIndex == pFlac->totalPCMFrameCount && (runningPCMFrameCount + pcmFrameCountInThisFrame) == pFlac->totalPCMFrameCount) {
7734
0
            drflac_result result = drflac__decode_flac_frame(pFlac);
7735
0
            if (result == DRFLAC_SUCCESS) {
7736
0
                pFlac->currentPCMFrame = pcmFrameIndex;
7737
0
                pFlac->currentFLACFrame.pcmFramesRemaining = 0;
7738
0
                return DRFLAC_TRUE;
7739
0
            } else {
7740
0
                return DRFLAC_FALSE;
7741
0
            }
7742
0
        }
7743
7744
0
        if (pcmFrameIndex < (runningPCMFrameCount + pcmFrameCountInThisFrame)) {
7745
            /*
7746
            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
7747
            it never existed and keep iterating.
7748
            */
7749
0
            drflac_result result = drflac__decode_flac_frame(pFlac);
7750
0
            if (result == DRFLAC_SUCCESS) {
7751
                /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */
7752
0
                drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);    /* <-- Safe cast because the maximum number of samples in a frame is 65535. */
7753
0
                if (pcmFramesToDecode == 0) {
7754
0
                    return DRFLAC_TRUE;
7755
0
                }
7756
7757
0
                pFlac->currentPCMFrame = runningPCMFrameCount;
7758
7759
0
                return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;  /* <-- If this fails, something bad has happened (it should never fail). */
7760
0
            } else {
7761
0
                if (result == DRFLAC_CRC_MISMATCH) {
7762
0
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
7763
0
                } else {
7764
0
                    return DRFLAC_FALSE;
7765
0
                }
7766
0
            }
7767
0
        } else {
7768
            /*
7769
            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
7770
            frame never existed and leave the running sample count untouched.
7771
            */
7772
0
            drflac_result result = drflac__seek_to_next_flac_frame(pFlac);
7773
0
            if (result == DRFLAC_SUCCESS) {
7774
0
                runningPCMFrameCount += pcmFrameCountInThisFrame;
7775
0
            } else {
7776
0
                if (result == DRFLAC_CRC_MISMATCH) {
7777
0
                    continue;   /* CRC mismatch. Pretend this frame never existed. */
7778
0
                } else {
7779
0
                    return DRFLAC_FALSE;
7780
0
                }
7781
0
            }
7782
0
        }
7783
0
    }
7784
0
}
7785
7786
7787
7788
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)
7789
0
{
7790
0
    drflac_ogg_page_header header;
7791
0
    drflac_uint32 crc32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
7792
0
    drflac_uint32 bytesRead = 0;
7793
7794
    /* Pre Condition: The bit stream should be sitting just past the 4-byte OggS capture pattern. */
7795
0
    (void)relaxed;
7796
7797
0
    pInit->container = drflac_container_ogg;
7798
0
    pInit->oggFirstBytePos = 0;
7799
7800
    /*
7801
    We'll get here if the first 4 bytes of the stream were the OggS capture pattern, however it doesn't necessarily mean the
7802
    stream includes FLAC encoded audio. To check for this we need to scan the beginning-of-stream page markers and check if
7803
    any match the FLAC specification. Important to keep in mind that the stream may be multiplexed.
7804
    */
7805
0
    if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7806
0
        return DRFLAC_FALSE;
7807
0
    }
7808
0
    pInit->runningFilePos += bytesRead;
7809
7810
0
    for (;;) {
7811
0
        int pageBodySize;
7812
7813
        /* Break if we're past the beginning of stream page. */
7814
0
        if ((header.headerType & 0x02) == 0) {
7815
0
            return DRFLAC_FALSE;
7816
0
        }
7817
7818
        /* Check if it's a FLAC header. */
7819
0
        pageBodySize = drflac_ogg__get_page_body_size(&header);
7820
0
        if (pageBodySize == 51) {   /* 51 = the lacing value of the FLAC header packet. */
7821
            /* It could be a FLAC page... */
7822
0
            drflac_uint32 bytesRemainingInPage = pageBodySize;
7823
0
            drflac_uint8 packetType;
7824
7825
0
            if (onRead(pUserData, &packetType, 1) != 1) {
7826
0
                return DRFLAC_FALSE;
7827
0
            }
7828
7829
0
            bytesRemainingInPage -= 1;
7830
0
            if (packetType == 0x7F) {
7831
                /* Increasingly more likely to be a FLAC page... */
7832
0
                drflac_uint8 sig[4];
7833
0
                if (onRead(pUserData, sig, 4) != 4) {
7834
0
                    return DRFLAC_FALSE;
7835
0
                }
7836
7837
0
                bytesRemainingInPage -= 4;
7838
0
                if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') {
7839
                    /* Almost certainly a FLAC page... */
7840
0
                    drflac_uint8 mappingVersion[2];
7841
0
                    if (onRead(pUserData, mappingVersion, 2) != 2) {
7842
0
                        return DRFLAC_FALSE;
7843
0
                    }
7844
7845
0
                    if (mappingVersion[0] != 1) {
7846
0
                        return DRFLAC_FALSE;   /* Only supporting version 1.x of the Ogg mapping. */
7847
0
                    }
7848
7849
                    /*
7850
                    The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
7851
                    be handling it in a generic way based on the serial number and packet types.
7852
                    */
7853
0
                    if (!onSeek(pUserData, 2, DRFLAC_SEEK_CUR)) {
7854
0
                        return DRFLAC_FALSE;
7855
0
                    }
7856
7857
                    /* Expecting the native FLAC signature "fLaC". */
7858
0
                    if (onRead(pUserData, sig, 4) != 4) {
7859
0
                        return DRFLAC_FALSE;
7860
0
                    }
7861
7862
0
                    if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') {
7863
                        /* The remaining data in the page should be the STREAMINFO block. */
7864
0
                        drflac_streaminfo streaminfo;
7865
0
                        drflac_uint8 isLastBlock;
7866
0
                        drflac_uint8 blockType;
7867
0
                        drflac_uint32 blockSize;
7868
0
                        if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
7869
0
                            return DRFLAC_FALSE;
7870
0
                        }
7871
7872
0
                        if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) {
7873
0
                            return DRFLAC_FALSE;    /* Invalid block type. First block must be the STREAMINFO block. */
7874
0
                        }
7875
7876
0
                        if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) {
7877
                            /* Success! */
7878
0
                            pInit->hasStreamInfoBlock      = DRFLAC_TRUE;
7879
0
                            pInit->sampleRate              = streaminfo.sampleRate;
7880
0
                            pInit->channels                = streaminfo.channels;
7881
0
                            pInit->bitsPerSample           = streaminfo.bitsPerSample;
7882
0
                            pInit->totalPCMFrameCount      = streaminfo.totalPCMFrameCount;
7883
0
                            pInit->maxBlockSizeInPCMFrames = streaminfo.maxBlockSizeInPCMFrames;
7884
0
                            pInit->hasMetadataBlocks       = !isLastBlock;
7885
7886
0
                            if (onMeta) {
7887
0
                                drflac_metadata metadata;
7888
0
                                metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO;
7889
0
                                metadata.pRawData = NULL;
7890
0
                                metadata.rawDataSize = 0;
7891
0
                                metadata.data.streaminfo = streaminfo;
7892
0
                                onMeta(pUserDataMD, &metadata);
7893
0
                            }
7894
7895
0
                            pInit->runningFilePos  += pageBodySize;
7896
0
                            pInit->oggFirstBytePos  = pInit->runningFilePos - 79;   /* Subtracting 79 will place us right on top of the "OggS" identifier of the FLAC bos page. */
7897
0
                            pInit->oggSerial        = header.serialNumber;
7898
0
                            pInit->oggBosHeader     = header;
7899
0
                            break;
7900
0
                        } else {
7901
                            /* Failed to read STREAMINFO block. Aww, so close... */
7902
0
                            return DRFLAC_FALSE;
7903
0
                        }
7904
0
                    } else {
7905
                        /* Invalid file. */
7906
0
                        return DRFLAC_FALSE;
7907
0
                    }
7908
0
                } else {
7909
                    /* Not a FLAC header. Skip it. */
7910
0
                    if (!onSeek(pUserData, bytesRemainingInPage, DRFLAC_SEEK_CUR)) {
7911
0
                        return DRFLAC_FALSE;
7912
0
                    }
7913
0
                }
7914
0
            } else {
7915
                /* Not a FLAC header. Seek past the entire page and move on to the next. */
7916
0
                if (!onSeek(pUserData, bytesRemainingInPage, DRFLAC_SEEK_CUR)) {
7917
0
                    return DRFLAC_FALSE;
7918
0
                }
7919
0
            }
7920
0
        } else {
7921
0
            if (!onSeek(pUserData, pageBodySize, DRFLAC_SEEK_CUR)) {
7922
0
                return DRFLAC_FALSE;
7923
0
            }
7924
0
        }
7925
7926
0
        pInit->runningFilePos += pageBodySize;
7927
7928
7929
        /* Read the header of the next page. */
7930
0
        if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
7931
0
            return DRFLAC_FALSE;
7932
0
        }
7933
0
        pInit->runningFilePos += bytesRead;
7934
0
    }
7935
7936
    /*
7937
    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
7938
    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
7939
    Ogg bistream object.
7940
    */
7941
0
    pInit->hasMetadataBlocks = DRFLAC_TRUE;    /* <-- Always have at least VORBIS_COMMENT metadata block. */
7942
0
    return DRFLAC_TRUE;
7943
0
}
7944
#endif
7945
7946
static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
7947
0
{
7948
0
    drflac_bool32 relaxed;
7949
0
    drflac_uint8 id[4];
7950
7951
0
    if (pInit == NULL || onRead == NULL || onSeek == NULL) {    /* <-- onTell is optional. */
7952
0
        return DRFLAC_FALSE;
7953
0
    }
7954
7955
0
    DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
7956
0
    pInit->onRead       = onRead;
7957
0
    pInit->onSeek       = onSeek;
7958
0
    pInit->onTell       = onTell;
7959
0
    pInit->onMeta       = onMeta;
7960
0
    pInit->container    = container;
7961
0
    pInit->pUserData    = pUserData;
7962
0
    pInit->pUserDataMD  = pUserDataMD;
7963
7964
0
    pInit->bs.onRead    = onRead;
7965
0
    pInit->bs.onSeek    = onSeek;
7966
0
    pInit->bs.onTell    = onTell;
7967
0
    pInit->bs.pUserData = pUserData;
7968
0
    drflac__reset_cache(&pInit->bs);
7969
7970
7971
    /* If the container is explicitly defined then we can try opening in relaxed mode. */
7972
0
    relaxed = container != drflac_container_unknown;
7973
7974
    /* Skip over any ID3 tags. */
7975
0
    for (;;) {
7976
0
        if (onRead(pUserData, id, 4) != 4) {
7977
0
            return DRFLAC_FALSE;    /* Ran out of data. */
7978
0
        }
7979
0
        pInit->runningFilePos += 4;
7980
7981
0
        if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') {
7982
0
            drflac_uint8 header[6];
7983
0
            drflac_uint8 flags;
7984
0
            drflac_uint32 headerSize;
7985
7986
0
            if (onRead(pUserData, header, 6) != 6) {
7987
0
                return DRFLAC_FALSE;    /* Ran out of data. */
7988
0
            }
7989
0
            pInit->runningFilePos += 6;
7990
7991
0
            flags = header[1];
7992
7993
0
            DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
7994
0
            headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
7995
0
            if (flags & 0x10) {
7996
0
                headerSize += 10;
7997
0
            }
7998
7999
0
            if (!onSeek(pUserData, headerSize, DRFLAC_SEEK_CUR)) {
8000
0
                return DRFLAC_FALSE;    /* Failed to seek past the tag. */
8001
0
            }
8002
0
            pInit->runningFilePos += headerSize;
8003
0
        } else {
8004
0
            break;
8005
0
        }
8006
0
    }
8007
8008
0
    if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') {
8009
0
        return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
8010
0
    }
8011
0
#ifndef DR_FLAC_NO_OGG
8012
0
    if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') {
8013
0
        return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
8014
0
    }
8015
0
#endif
8016
8017
    /* If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable. */
8018
0
    if (relaxed) {
8019
0
        if (container == drflac_container_native) {
8020
0
            return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
8021
0
        }
8022
0
#ifndef DR_FLAC_NO_OGG
8023
0
        if (container == drflac_container_ogg) {
8024
0
            return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
8025
0
        }
8026
0
#endif
8027
0
    }
8028
8029
    /* Unsupported container. */
8030
0
    return DRFLAC_FALSE;
8031
0
}
8032
8033
static void drflac__init_from_info(drflac* pFlac, const drflac_init_info* pInit)
8034
0
{
8035
0
    DRFLAC_ASSERT(pFlac != NULL);
8036
0
    DRFLAC_ASSERT(pInit != NULL);
8037
8038
0
    DRFLAC_ZERO_MEMORY(pFlac, sizeof(*pFlac));
8039
0
    pFlac->bs                      = pInit->bs;
8040
0
    pFlac->onMeta                  = pInit->onMeta;
8041
0
    pFlac->pUserDataMD             = pInit->pUserDataMD;
8042
0
    pFlac->maxBlockSizeInPCMFrames = pInit->maxBlockSizeInPCMFrames;
8043
0
    pFlac->sampleRate              = pInit->sampleRate;
8044
0
    pFlac->channels                = (drflac_uint8)pInit->channels;
8045
0
    pFlac->bitsPerSample           = (drflac_uint8)pInit->bitsPerSample;
8046
0
    pFlac->totalPCMFrameCount      = pInit->totalPCMFrameCount;
8047
0
    pFlac->container               = pInit->container;
8048
0
}
8049
8050
8051
static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
8052
0
{
8053
0
    drflac_init_info init;
8054
0
    drflac_uint32 allocationSize;
8055
0
    drflac_uint32 wholeSIMDVectorCountPerChannel;
8056
0
    drflac_uint32 decodedSamplesAllocationSize;
8057
0
#ifndef DR_FLAC_NO_OGG
8058
0
    drflac_oggbs* pOggbs = NULL;
8059
0
#endif
8060
0
    drflac_uint64 firstFramePos;
8061
0
    drflac_uint64 seektablePos;
8062
0
    drflac_uint32 seekpointCount;
8063
0
    drflac_allocation_callbacks allocationCallbacks;
8064
0
    drflac* pFlac;
8065
8066
    /* CPU support first. */
8067
0
    drflac__init_cpu_caps();
8068
8069
0
    if (!drflac__init_private(&init, onRead, onSeek, onTell, onMeta, container, pUserData, pUserDataMD)) {
8070
0
        return NULL;
8071
0
    }
8072
8073
0
    if (pAllocationCallbacks != NULL) {
8074
0
        allocationCallbacks = *pAllocationCallbacks;
8075
0
        if (allocationCallbacks.onFree == NULL || (allocationCallbacks.onMalloc == NULL && allocationCallbacks.onRealloc == NULL)) {
8076
0
            return NULL;    /* Invalid allocation callbacks. */
8077
0
        }
8078
0
    } else {
8079
0
        allocationCallbacks.pUserData = NULL;
8080
0
        allocationCallbacks.onMalloc  = drflac__malloc_default;
8081
0
        allocationCallbacks.onRealloc = drflac__realloc_default;
8082
0
        allocationCallbacks.onFree    = drflac__free_default;
8083
0
    }
8084
8085
8086
    /*
8087
    The size of the allocation for the drflac object needs to be large enough to fit the following:
8088
      1) The main members of the drflac structure
8089
      2) A block of memory large enough to store the decoded samples of the largest frame in the stream
8090
      3) If the container is Ogg, a drflac_oggbs object
8091
8092
    The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration
8093
    the different SIMD instruction sets.
8094
    */
8095
0
    allocationSize = sizeof(drflac);
8096
8097
    /*
8098
    The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector
8099
    we are supporting.
8100
    */
8101
0
    if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
8102
0
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
8103
0
    } else {
8104
0
        wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
8105
0
    }
8106
8107
0
    decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels;
8108
8109
0
    allocationSize += decodedSamplesAllocationSize;
8110
0
    allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE;  /* Allocate extra bytes to ensure we have enough for alignment. */
8111
8112
0
#ifndef DR_FLAC_NO_OGG
8113
    /* There's additional data required for Ogg streams. */
8114
0
    if (init.container == drflac_container_ogg) {
8115
0
        allocationSize += sizeof(drflac_oggbs);
8116
8117
0
        pOggbs = (drflac_oggbs*)drflac__malloc_from_callbacks(sizeof(*pOggbs), &allocationCallbacks);
8118
0
        if (pOggbs == NULL) {
8119
0
            return NULL; /*DRFLAC_OUT_OF_MEMORY;*/
8120
0
        }
8121
8122
0
        DRFLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
8123
0
        pOggbs->onRead = onRead;
8124
0
        pOggbs->onSeek = onSeek;
8125
0
        pOggbs->onTell = onTell;
8126
0
        pOggbs->pUserData = pUserData;
8127
0
        pOggbs->currentBytePos = init.oggFirstBytePos;
8128
0
        pOggbs->firstBytePos = init.oggFirstBytePos;
8129
0
        pOggbs->serialNumber = init.oggSerial;
8130
0
        pOggbs->bosPageHeader = init.oggBosHeader;
8131
0
        pOggbs->bytesRemainingInPage = 0;
8132
0
    }
8133
0
#endif
8134
8135
    /*
8136
    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
8137
    consist of only a single heap allocation. To this, the size of the seek table needs to be known, which we determine when reading
8138
    and decoding the metadata.
8139
    */
8140
0
    firstFramePos  = 42;   /* <-- We know we are at byte 42 at this point. */
8141
0
    seektablePos   = 0;
8142
0
    seekpointCount = 0;
8143
0
    if (init.hasMetadataBlocks) {
8144
0
        drflac_read_proc onReadOverride = onRead;
8145
0
        drflac_seek_proc onSeekOverride = onSeek;
8146
0
        drflac_tell_proc onTellOverride = onTell;
8147
0
        void* pUserDataOverride = pUserData;
8148
8149
0
#ifndef DR_FLAC_NO_OGG
8150
0
        if (init.container == drflac_container_ogg) {
8151
0
            onReadOverride = drflac__on_read_ogg;
8152
0
            onSeekOverride = drflac__on_seek_ogg;
8153
0
            onTellOverride = drflac__on_tell_ogg;
8154
0
            pUserDataOverride = (void*)pOggbs;
8155
0
        }
8156
0
#endif
8157
8158
0
        if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onTellOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
8159
0
        #ifndef DR_FLAC_NO_OGG
8160
0
            drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
8161
0
        #endif
8162
0
            return NULL;
8163
0
        }
8164
8165
0
        if ((0xFFFFFFFF - (seekpointCount * sizeof(drflac_seekpoint))) < allocationSize) {
8166
0
        #ifndef DR_FLAC_NO_OGG
8167
0
            drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
8168
0
        #endif
8169
0
            return NULL;
8170
0
        }
8171
8172
0
        allocationSize += seekpointCount * sizeof(drflac_seekpoint);
8173
0
    }
8174
8175
0
    pFlac = (drflac*)drflac__malloc_from_callbacks((size_t)allocationSize, &allocationCallbacks);
8176
0
    if (pFlac == NULL) {
8177
0
    #ifndef DR_FLAC_NO_OGG
8178
0
        drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
8179
0
    #endif
8180
0
        return NULL;
8181
0
    }
8182
8183
0
    drflac__init_from_info(pFlac, &init);
8184
0
    pFlac->allocationCallbacks = allocationCallbacks;
8185
0
    pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE);
8186
8187
0
#ifndef DR_FLAC_NO_OGG
8188
0
    if (init.container == drflac_container_ogg) {
8189
0
        drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + (seekpointCount * sizeof(drflac_seekpoint)));
8190
0
        DRFLAC_COPY_MEMORY(pInternalOggbs, pOggbs, sizeof(*pOggbs));
8191
8192
        /* At this point the pOggbs object has been handed over to pInternalOggbs and can be freed. */
8193
0
        drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
8194
0
        pOggbs = NULL;
8195
8196
        /* The Ogg bistream needs to be layered on top of the original bitstream. */
8197
0
        pFlac->bs.onRead = drflac__on_read_ogg;
8198
0
        pFlac->bs.onSeek = drflac__on_seek_ogg;
8199
0
        pFlac->bs.onTell = drflac__on_tell_ogg;
8200
0
        pFlac->bs.pUserData = (void*)pInternalOggbs;
8201
0
        pFlac->_oggbs = (void*)pInternalOggbs;
8202
0
    }
8203
0
#endif
8204
8205
0
    pFlac->firstFLACFramePosInBytes = firstFramePos;
8206
8207
    /* 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. */
8208
0
#ifndef DR_FLAC_NO_OGG
8209
0
    if (init.container == drflac_container_ogg)
8210
0
    {
8211
0
        pFlac->pSeekpoints = NULL;
8212
0
        pFlac->seekpointCount = 0;
8213
0
    }
8214
0
    else
8215
0
#endif
8216
0
    {
8217
        /* If we have a seektable we need to load it now, making sure we move back to where we were previously. */
8218
0
        if (seektablePos != 0) {
8219
0
            pFlac->seekpointCount = seekpointCount;
8220
0
            pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
8221
8222
0
            DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
8223
0
            DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
8224
8225
            /* Seek to the seektable, then just read directly into our seektable buffer. */
8226
0
            if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, DRFLAC_SEEK_SET)) {
8227
0
                drflac_uint32 iSeekpoint;
8228
8229
0
                for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
8230
0
                    if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints + iSeekpoint, DRFLAC_SEEKPOINT_SIZE_IN_BYTES) == DRFLAC_SEEKPOINT_SIZE_IN_BYTES) {
8231
                        /* Endian swap. */
8232
0
                        pFlac->pSeekpoints[iSeekpoint].firstPCMFrame   = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
8233
0
                        pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
8234
0
                        pFlac->pSeekpoints[iSeekpoint].pcmFrameCount   = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
8235
0
                    } else {
8236
                        /* Failed to read the seektable. Pretend we don't have one. */
8237
0
                        pFlac->pSeekpoints = NULL;
8238
0
                        pFlac->seekpointCount = 0;
8239
0
                        break;
8240
0
                    }
8241
0
                }
8242
8243
                /* We need to seek back to where we were. If this fails it's a critical error. */
8244
0
                if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, DRFLAC_SEEK_SET)) {
8245
0
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
8246
0
                    return NULL;
8247
0
                }
8248
0
            } else {
8249
                /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
8250
0
                pFlac->pSeekpoints = NULL;
8251
0
                pFlac->seekpointCount = 0;
8252
0
            }
8253
0
        }
8254
0
    }
8255
8256
8257
    /*
8258
    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
8259
    the first frame.
8260
    */
8261
0
    if (!init.hasStreamInfoBlock) {
8262
0
        pFlac->currentFLACFrame.header = init.firstFrameHeader;
8263
0
        for (;;) {
8264
0
            drflac_result result = drflac__decode_flac_frame(pFlac);
8265
0
            if (result == DRFLAC_SUCCESS) {
8266
0
                break;
8267
0
            } else {
8268
0
                if (result == DRFLAC_CRC_MISMATCH) {
8269
0
                    if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
8270
0
                        drflac__free_from_callbacks(pFlac, &allocationCallbacks);
8271
0
                        return NULL;
8272
0
                    }
8273
0
                    continue;
8274
0
                } else {
8275
0
                    drflac__free_from_callbacks(pFlac, &allocationCallbacks);
8276
0
                    return NULL;
8277
0
                }
8278
0
            }
8279
0
        }
8280
0
    }
8281
8282
0
    return pFlac;
8283
0
}
8284
8285
8286
8287
#ifndef DR_FLAC_NO_STDIO
8288
#include <stdio.h>
8289
#ifndef DR_FLAC_NO_WCHAR
8290
#include <wchar.h>      /* For wcslen(), wcsrtombs() */
8291
#endif
8292
8293
/* Errno */
8294
/* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
8295
#include <errno.h>
8296
static drflac_result drflac_result_from_errno(int e)
8297
0
{
8298
0
    switch (e)
8299
0
    {
8300
0
        case 0: return DRFLAC_SUCCESS;
8301
0
    #ifdef EPERM
8302
0
        case EPERM: return DRFLAC_INVALID_OPERATION;
8303
0
    #endif
8304
0
    #ifdef ENOENT
8305
0
        case ENOENT: return DRFLAC_DOES_NOT_EXIST;
8306
0
    #endif
8307
0
    #ifdef ESRCH
8308
0
        case ESRCH: return DRFLAC_DOES_NOT_EXIST;
8309
0
    #endif
8310
0
    #ifdef EINTR
8311
0
        case EINTR: return DRFLAC_INTERRUPT;
8312
0
    #endif
8313
0
    #ifdef EIO
8314
0
        case EIO: return DRFLAC_IO_ERROR;
8315
0
    #endif
8316
0
    #ifdef ENXIO
8317
0
        case ENXIO: return DRFLAC_DOES_NOT_EXIST;
8318
0
    #endif
8319
0
    #ifdef E2BIG
8320
0
        case E2BIG: return DRFLAC_INVALID_ARGS;
8321
0
    #endif
8322
0
    #ifdef ENOEXEC
8323
0
        case ENOEXEC: return DRFLAC_INVALID_FILE;
8324
0
    #endif
8325
0
    #ifdef EBADF
8326
0
        case EBADF: return DRFLAC_INVALID_FILE;
8327
0
    #endif
8328
0
    #ifdef ECHILD
8329
0
        case ECHILD: return DRFLAC_ERROR;
8330
0
    #endif
8331
0
    #ifdef EAGAIN
8332
0
        case EAGAIN: return DRFLAC_UNAVAILABLE;
8333
0
    #endif
8334
0
    #ifdef ENOMEM
8335
0
        case ENOMEM: return DRFLAC_OUT_OF_MEMORY;
8336
0
    #endif
8337
0
    #ifdef EACCES
8338
0
        case EACCES: return DRFLAC_ACCESS_DENIED;
8339
0
    #endif
8340
0
    #ifdef EFAULT
8341
0
        case EFAULT: return DRFLAC_BAD_ADDRESS;
8342
0
    #endif
8343
0
    #ifdef ENOTBLK
8344
0
        case ENOTBLK: return DRFLAC_ERROR;
8345
0
    #endif
8346
0
    #ifdef EBUSY
8347
0
        case EBUSY: return DRFLAC_BUSY;
8348
0
    #endif
8349
0
    #ifdef EEXIST
8350
0
        case EEXIST: return DRFLAC_ALREADY_EXISTS;
8351
0
    #endif
8352
0
    #ifdef EXDEV
8353
0
        case EXDEV: return DRFLAC_ERROR;
8354
0
    #endif
8355
0
    #ifdef ENODEV
8356
0
        case ENODEV: return DRFLAC_DOES_NOT_EXIST;
8357
0
    #endif
8358
0
    #ifdef ENOTDIR
8359
0
        case ENOTDIR: return DRFLAC_NOT_DIRECTORY;
8360
0
    #endif
8361
0
    #ifdef EISDIR
8362
0
        case EISDIR: return DRFLAC_IS_DIRECTORY;
8363
0
    #endif
8364
0
    #ifdef EINVAL
8365
0
        case EINVAL: return DRFLAC_INVALID_ARGS;
8366
0
    #endif
8367
0
    #ifdef ENFILE
8368
0
        case ENFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
8369
0
    #endif
8370
0
    #ifdef EMFILE
8371
0
        case EMFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
8372
0
    #endif
8373
0
    #ifdef ENOTTY
8374
0
        case ENOTTY: return DRFLAC_INVALID_OPERATION;
8375
0
    #endif
8376
0
    #ifdef ETXTBSY
8377
0
        case ETXTBSY: return DRFLAC_BUSY;
8378
0
    #endif
8379
0
    #ifdef EFBIG
8380
0
        case EFBIG: return DRFLAC_TOO_BIG;
8381
0
    #endif
8382
0
    #ifdef ENOSPC
8383
0
        case ENOSPC: return DRFLAC_NO_SPACE;
8384
0
    #endif
8385
0
    #ifdef ESPIPE
8386
0
        case ESPIPE: return DRFLAC_BAD_SEEK;
8387
0
    #endif
8388
0
    #ifdef EROFS
8389
0
        case EROFS: return DRFLAC_ACCESS_DENIED;
8390
0
    #endif
8391
0
    #ifdef EMLINK
8392
0
        case EMLINK: return DRFLAC_TOO_MANY_LINKS;
8393
0
    #endif
8394
0
    #ifdef EPIPE
8395
0
        case EPIPE: return DRFLAC_BAD_PIPE;
8396
0
    #endif
8397
0
    #ifdef EDOM
8398
0
        case EDOM: return DRFLAC_OUT_OF_RANGE;
8399
0
    #endif
8400
0
    #ifdef ERANGE
8401
0
        case ERANGE: return DRFLAC_OUT_OF_RANGE;
8402
0
    #endif
8403
0
    #ifdef EDEADLK
8404
0
        case EDEADLK: return DRFLAC_DEADLOCK;
8405
0
    #endif
8406
0
    #ifdef ENAMETOOLONG
8407
0
        case ENAMETOOLONG: return DRFLAC_PATH_TOO_LONG;
8408
0
    #endif
8409
0
    #ifdef ENOLCK
8410
0
        case ENOLCK: return DRFLAC_ERROR;
8411
0
    #endif
8412
0
    #ifdef ENOSYS
8413
0
        case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
8414
0
    #endif
8415
    #if defined(ENOTEMPTY) && ENOTEMPTY != EEXIST   /* In AIX, ENOTEMPTY and EEXIST use the same value. */
8416
0
        case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
8417
0
    #endif
8418
0
    #ifdef ELOOP
8419
0
        case ELOOP: return DRFLAC_TOO_MANY_LINKS;
8420
0
    #endif
8421
0
    #ifdef ENOMSG
8422
0
        case ENOMSG: return DRFLAC_NO_MESSAGE;
8423
0
    #endif
8424
0
    #ifdef EIDRM
8425
0
        case EIDRM: return DRFLAC_ERROR;
8426
0
    #endif
8427
0
    #ifdef ECHRNG
8428
0
        case ECHRNG: return DRFLAC_ERROR;
8429
0
    #endif
8430
0
    #ifdef EL2NSYNC
8431
0
        case EL2NSYNC: return DRFLAC_ERROR;
8432
0
    #endif
8433
0
    #ifdef EL3HLT
8434
0
        case EL3HLT: return DRFLAC_ERROR;
8435
0
    #endif
8436
0
    #ifdef EL3RST
8437
0
        case EL3RST: return DRFLAC_ERROR;
8438
0
    #endif
8439
0
    #ifdef ELNRNG
8440
0
        case ELNRNG: return DRFLAC_OUT_OF_RANGE;
8441
0
    #endif
8442
0
    #ifdef EUNATCH
8443
0
        case EUNATCH: return DRFLAC_ERROR;
8444
0
    #endif
8445
0
    #ifdef ENOCSI
8446
0
        case ENOCSI: return DRFLAC_ERROR;
8447
0
    #endif
8448
0
    #ifdef EL2HLT
8449
0
        case EL2HLT: return DRFLAC_ERROR;
8450
0
    #endif
8451
0
    #ifdef EBADE
8452
0
        case EBADE: return DRFLAC_ERROR;
8453
0
    #endif
8454
0
    #ifdef EBADR
8455
0
        case EBADR: return DRFLAC_ERROR;
8456
0
    #endif
8457
0
    #ifdef EXFULL
8458
0
        case EXFULL: return DRFLAC_ERROR;
8459
0
    #endif
8460
0
    #ifdef ENOANO
8461
0
        case ENOANO: return DRFLAC_ERROR;
8462
0
    #endif
8463
0
    #ifdef EBADRQC
8464
0
        case EBADRQC: return DRFLAC_ERROR;
8465
0
    #endif
8466
0
    #ifdef EBADSLT
8467
0
        case EBADSLT: return DRFLAC_ERROR;
8468
0
    #endif
8469
0
    #ifdef EBFONT
8470
0
        case EBFONT: return DRFLAC_INVALID_FILE;
8471
0
    #endif
8472
0
    #ifdef ENOSTR
8473
0
        case ENOSTR: return DRFLAC_ERROR;
8474
0
    #endif
8475
0
    #ifdef ENODATA
8476
0
        case ENODATA: return DRFLAC_NO_DATA_AVAILABLE;
8477
0
    #endif
8478
0
    #ifdef ETIME
8479
0
        case ETIME: return DRFLAC_TIMEOUT;
8480
0
    #endif
8481
0
    #ifdef ENOSR
8482
0
        case ENOSR: return DRFLAC_NO_DATA_AVAILABLE;
8483
0
    #endif
8484
0
    #ifdef ENONET
8485
0
        case ENONET: return DRFLAC_NO_NETWORK;
8486
0
    #endif
8487
0
    #ifdef ENOPKG
8488
0
        case ENOPKG: return DRFLAC_ERROR;
8489
0
    #endif
8490
0
    #ifdef EREMOTE
8491
0
        case EREMOTE: return DRFLAC_ERROR;
8492
0
    #endif
8493
0
    #ifdef ENOLINK
8494
0
        case ENOLINK: return DRFLAC_ERROR;
8495
0
    #endif
8496
0
    #ifdef EADV
8497
0
        case EADV: return DRFLAC_ERROR;
8498
0
    #endif
8499
0
    #ifdef ESRMNT
8500
0
        case ESRMNT: return DRFLAC_ERROR;
8501
0
    #endif
8502
0
    #ifdef ECOMM
8503
0
        case ECOMM: return DRFLAC_ERROR;
8504
0
    #endif
8505
0
    #ifdef EPROTO
8506
0
        case EPROTO: return DRFLAC_ERROR;
8507
0
    #endif
8508
0
    #ifdef EMULTIHOP
8509
0
        case EMULTIHOP: return DRFLAC_ERROR;
8510
0
    #endif
8511
0
    #ifdef EDOTDOT
8512
0
        case EDOTDOT: return DRFLAC_ERROR;
8513
0
    #endif
8514
0
    #ifdef EBADMSG
8515
0
        case EBADMSG: return DRFLAC_BAD_MESSAGE;
8516
0
    #endif
8517
0
    #ifdef EOVERFLOW
8518
0
        case EOVERFLOW: return DRFLAC_TOO_BIG;
8519
0
    #endif
8520
0
    #ifdef ENOTUNIQ
8521
0
        case ENOTUNIQ: return DRFLAC_NOT_UNIQUE;
8522
0
    #endif
8523
0
    #ifdef EBADFD
8524
0
        case EBADFD: return DRFLAC_ERROR;
8525
0
    #endif
8526
0
    #ifdef EREMCHG
8527
0
        case EREMCHG: return DRFLAC_ERROR;
8528
0
    #endif
8529
0
    #ifdef ELIBACC
8530
0
        case ELIBACC: return DRFLAC_ACCESS_DENIED;
8531
0
    #endif
8532
0
    #ifdef ELIBBAD
8533
0
        case ELIBBAD: return DRFLAC_INVALID_FILE;
8534
0
    #endif
8535
0
    #ifdef ELIBSCN
8536
0
        case ELIBSCN: return DRFLAC_INVALID_FILE;
8537
0
    #endif
8538
0
    #ifdef ELIBMAX
8539
0
        case ELIBMAX: return DRFLAC_ERROR;
8540
0
    #endif
8541
0
    #ifdef ELIBEXEC
8542
0
        case ELIBEXEC: return DRFLAC_ERROR;
8543
0
    #endif
8544
0
    #ifdef EILSEQ
8545
0
        case EILSEQ: return DRFLAC_INVALID_DATA;
8546
0
    #endif
8547
0
    #ifdef ERESTART
8548
0
        case ERESTART: return DRFLAC_ERROR;
8549
0
    #endif
8550
0
    #ifdef ESTRPIPE
8551
0
        case ESTRPIPE: return DRFLAC_ERROR;
8552
0
    #endif
8553
0
    #ifdef EUSERS
8554
0
        case EUSERS: return DRFLAC_ERROR;
8555
0
    #endif
8556
0
    #ifdef ENOTSOCK
8557
0
        case ENOTSOCK: return DRFLAC_NOT_SOCKET;
8558
0
    #endif
8559
0
    #ifdef EDESTADDRREQ
8560
0
        case EDESTADDRREQ: return DRFLAC_NO_ADDRESS;
8561
0
    #endif
8562
0
    #ifdef EMSGSIZE
8563
0
        case EMSGSIZE: return DRFLAC_TOO_BIG;
8564
0
    #endif
8565
0
    #ifdef EPROTOTYPE
8566
0
        case EPROTOTYPE: return DRFLAC_BAD_PROTOCOL;
8567
0
    #endif
8568
0
    #ifdef ENOPROTOOPT
8569
0
        case ENOPROTOOPT: return DRFLAC_PROTOCOL_UNAVAILABLE;
8570
0
    #endif
8571
0
    #ifdef EPROTONOSUPPORT
8572
0
        case EPROTONOSUPPORT: return DRFLAC_PROTOCOL_NOT_SUPPORTED;
8573
0
    #endif
8574
0
    #ifdef ESOCKTNOSUPPORT
8575
0
        case ESOCKTNOSUPPORT: return DRFLAC_SOCKET_NOT_SUPPORTED;
8576
0
    #endif
8577
0
    #ifdef EOPNOTSUPP
8578
0
        case EOPNOTSUPP: return DRFLAC_INVALID_OPERATION;
8579
0
    #endif
8580
0
    #ifdef EPFNOSUPPORT
8581
0
        case EPFNOSUPPORT: return DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED;
8582
0
    #endif
8583
0
    #ifdef EAFNOSUPPORT
8584
0
        case EAFNOSUPPORT: return DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED;
8585
0
    #endif
8586
0
    #ifdef EADDRINUSE
8587
0
        case EADDRINUSE: return DRFLAC_ALREADY_IN_USE;
8588
0
    #endif
8589
0
    #ifdef EADDRNOTAVAIL
8590
0
        case EADDRNOTAVAIL: return DRFLAC_ERROR;
8591
0
    #endif
8592
0
    #ifdef ENETDOWN
8593
0
        case ENETDOWN: return DRFLAC_NO_NETWORK;
8594
0
    #endif
8595
0
    #ifdef ENETUNREACH
8596
0
        case ENETUNREACH: return DRFLAC_NO_NETWORK;
8597
0
    #endif
8598
0
    #ifdef ENETRESET
8599
0
        case ENETRESET: return DRFLAC_NO_NETWORK;
8600
0
    #endif
8601
0
    #ifdef ECONNABORTED
8602
0
        case ECONNABORTED: return DRFLAC_NO_NETWORK;
8603
0
    #endif
8604
0
    #ifdef ECONNRESET
8605
0
        case ECONNRESET: return DRFLAC_CONNECTION_RESET;
8606
0
    #endif
8607
0
    #ifdef ENOBUFS
8608
0
        case ENOBUFS: return DRFLAC_NO_SPACE;
8609
0
    #endif
8610
0
    #ifdef EISCONN
8611
0
        case EISCONN: return DRFLAC_ALREADY_CONNECTED;
8612
0
    #endif
8613
0
    #ifdef ENOTCONN
8614
0
        case ENOTCONN: return DRFLAC_NOT_CONNECTED;
8615
0
    #endif
8616
0
    #ifdef ESHUTDOWN
8617
0
        case ESHUTDOWN: return DRFLAC_ERROR;
8618
0
    #endif
8619
0
    #ifdef ETOOMANYREFS
8620
0
        case ETOOMANYREFS: return DRFLAC_ERROR;
8621
0
    #endif
8622
0
    #ifdef ETIMEDOUT
8623
0
        case ETIMEDOUT: return DRFLAC_TIMEOUT;
8624
0
    #endif
8625
0
    #ifdef ECONNREFUSED
8626
0
        case ECONNREFUSED: return DRFLAC_CONNECTION_REFUSED;
8627
0
    #endif
8628
0
    #ifdef EHOSTDOWN
8629
0
        case EHOSTDOWN: return DRFLAC_NO_HOST;
8630
0
    #endif
8631
0
    #ifdef EHOSTUNREACH
8632
0
        case EHOSTUNREACH: return DRFLAC_NO_HOST;
8633
0
    #endif
8634
0
    #ifdef EALREADY
8635
0
        case EALREADY: return DRFLAC_IN_PROGRESS;
8636
0
    #endif
8637
0
    #ifdef EINPROGRESS
8638
0
        case EINPROGRESS: return DRFLAC_IN_PROGRESS;
8639
0
    #endif
8640
0
    #ifdef ESTALE
8641
0
        case ESTALE: return DRFLAC_INVALID_FILE;
8642
0
    #endif
8643
0
    #ifdef EUCLEAN
8644
0
        case EUCLEAN: return DRFLAC_ERROR;
8645
0
    #endif
8646
0
    #ifdef ENOTNAM
8647
0
        case ENOTNAM: return DRFLAC_ERROR;
8648
0
    #endif
8649
0
    #ifdef ENAVAIL
8650
0
        case ENAVAIL: return DRFLAC_ERROR;
8651
0
    #endif
8652
0
    #ifdef EISNAM
8653
0
        case EISNAM: return DRFLAC_ERROR;
8654
0
    #endif
8655
0
    #ifdef EREMOTEIO
8656
0
        case EREMOTEIO: return DRFLAC_IO_ERROR;
8657
0
    #endif
8658
0
    #ifdef EDQUOT
8659
0
        case EDQUOT: return DRFLAC_NO_SPACE;
8660
0
    #endif
8661
0
    #ifdef ENOMEDIUM
8662
0
        case ENOMEDIUM: return DRFLAC_DOES_NOT_EXIST;
8663
0
    #endif
8664
0
    #ifdef EMEDIUMTYPE
8665
0
        case EMEDIUMTYPE: return DRFLAC_ERROR;
8666
0
    #endif
8667
0
    #ifdef ECANCELED
8668
0
        case ECANCELED: return DRFLAC_CANCELLED;
8669
0
    #endif
8670
0
    #ifdef ENOKEY
8671
0
        case ENOKEY: return DRFLAC_ERROR;
8672
0
    #endif
8673
0
    #ifdef EKEYEXPIRED
8674
0
        case EKEYEXPIRED: return DRFLAC_ERROR;
8675
0
    #endif
8676
0
    #ifdef EKEYREVOKED
8677
0
        case EKEYREVOKED: return DRFLAC_ERROR;
8678
0
    #endif
8679
0
    #ifdef EKEYREJECTED
8680
0
        case EKEYREJECTED: return DRFLAC_ERROR;
8681
0
    #endif
8682
0
    #ifdef EOWNERDEAD
8683
0
        case EOWNERDEAD: return DRFLAC_ERROR;
8684
0
    #endif
8685
0
    #ifdef ENOTRECOVERABLE
8686
0
        case ENOTRECOVERABLE: return DRFLAC_ERROR;
8687
0
    #endif
8688
0
    #ifdef ERFKILL
8689
0
        case ERFKILL: return DRFLAC_ERROR;
8690
0
    #endif
8691
0
    #ifdef EHWPOISON
8692
0
        case EHWPOISON: return DRFLAC_ERROR;
8693
0
    #endif
8694
0
        default: return DRFLAC_ERROR;
8695
0
    }
8696
0
}
8697
/* End Errno */
8698
8699
/* fopen */
8700
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
8701
0
{
8702
#if defined(_MSC_VER) && _MSC_VER >= 1400
8703
    errno_t err;
8704
#endif
8705
8706
0
    if (ppFile != NULL) {
8707
0
        *ppFile = NULL;  /* Safety. */
8708
0
    }
8709
8710
0
    if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
8711
0
        return DRFLAC_INVALID_ARGS;
8712
0
    }
8713
8714
#if defined(_MSC_VER) && _MSC_VER >= 1400
8715
    err = fopen_s(ppFile, pFilePath, pOpenMode);
8716
    if (err != 0) {
8717
        return drflac_result_from_errno(err);
8718
    }
8719
#else
8720
#if defined(_WIN32) || defined(__APPLE__)
8721
    *ppFile = fopen(pFilePath, pOpenMode);
8722
#else
8723
    #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
8724
        *ppFile = fopen64(pFilePath, pOpenMode);
8725
    #else
8726
0
        *ppFile = fopen(pFilePath, pOpenMode);
8727
0
    #endif
8728
0
#endif
8729
0
    if (*ppFile == NULL) {
8730
0
        drflac_result result = drflac_result_from_errno(errno);
8731
0
        if (result == DRFLAC_SUCCESS) {
8732
0
            result = DRFLAC_ERROR;   /* Just a safety check to make sure we never ever return success when pFile == NULL. */
8733
0
        }
8734
8735
0
        return result;
8736
0
    }
8737
0
#endif
8738
8739
0
    return DRFLAC_SUCCESS;
8740
0
}
8741
8742
/*
8743
_wfopen() isn't always available in all compilation environments.
8744
8745
    * Windows only.
8746
    * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
8747
    * MinGW-64 (both 32- and 64-bit) seems to support it.
8748
    * MinGW wraps it in !defined(__STRICT_ANSI__).
8749
    * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
8750
8751
This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
8752
fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
8753
*/
8754
#if defined(_WIN32)
8755
    #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
8756
        #define DRFLAC_HAS_WFOPEN
8757
    #endif
8758
#endif
8759
8760
#ifndef DR_FLAC_NO_WCHAR
8761
static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drflac_allocation_callbacks* pAllocationCallbacks)
8762
0
{
8763
0
    if (ppFile != NULL) {
8764
0
        *ppFile = NULL;  /* Safety. */
8765
0
    }
8766
8767
0
    if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
8768
0
        return DRFLAC_INVALID_ARGS;
8769
0
    }
8770
8771
#if defined(DRFLAC_HAS_WFOPEN)
8772
    {
8773
        /* Use _wfopen() on Windows. */
8774
    #if defined(_MSC_VER) && _MSC_VER >= 1400
8775
        errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
8776
        if (err != 0) {
8777
            return drflac_result_from_errno(err);
8778
        }
8779
    #else
8780
        *ppFile = _wfopen(pFilePath, pOpenMode);
8781
        if (*ppFile == NULL) {
8782
            return drflac_result_from_errno(errno);
8783
        }
8784
    #endif
8785
        (void)pAllocationCallbacks;
8786
    }
8787
#else
8788
    /*
8789
    Use fopen() on anything other than Windows. Requires a conversion. This is annoying because
8790
  fopen() is locale specific. The only real way I can think of to do this is with wcsrtombs(). Note
8791
  that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
8792
    maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler
8793
  error I'll look into improving compatibility.
8794
    */
8795
8796
  /*
8797
  Some compilers don't support wchar_t or wcsrtombs() which we're using below. In this case we just
8798
  need to abort with an error. If you encounter a compiler lacking such support, add it to this list
8799
  and submit a bug report and it'll be added to the library upstream.
8800
  */
8801
  #if defined(__DJGPP__)
8802
  {
8803
    /* Nothing to do here. This will fall through to the error check below. */
8804
  }
8805
  #else
8806
0
    {
8807
0
        mbstate_t mbs;
8808
0
        size_t lenMB;
8809
0
        const wchar_t* pFilePathTemp = pFilePath;
8810
0
        char* pFilePathMB = NULL;
8811
0
        char pOpenModeMB[32] = {0};
8812
8813
        /* Get the length first. */
8814
0
        DRFLAC_ZERO_OBJECT(&mbs);
8815
0
        lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
8816
0
        if (lenMB == (size_t)-1) {
8817
0
            return drflac_result_from_errno(errno);
8818
0
        }
8819
8820
0
        pFilePathMB = (char*)drflac__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
8821
0
        if (pFilePathMB == NULL) {
8822
0
            return DRFLAC_OUT_OF_MEMORY;
8823
0
        }
8824
8825
0
        pFilePathTemp = pFilePath;
8826
0
        DRFLAC_ZERO_OBJECT(&mbs);
8827
0
        wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
8828
8829
        /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
8830
0
        {
8831
0
            size_t i = 0;
8832
0
            for (;;) {
8833
0
                if (pOpenMode[i] == 0) {
8834
0
                    pOpenModeMB[i] = '\0';
8835
0
                    break;
8836
0
                }
8837
8838
0
                pOpenModeMB[i] = (char)pOpenMode[i];
8839
0
                i += 1;
8840
0
            }
8841
0
        }
8842
8843
0
        *ppFile = fopen(pFilePathMB, pOpenModeMB);
8844
8845
0
        drflac__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
8846
0
    }
8847
0
  #endif
8848
8849
0
    if (*ppFile == NULL) {
8850
0
        return DRFLAC_ERROR;
8851
0
    }
8852
0
#endif
8853
8854
0
    return DRFLAC_SUCCESS;
8855
0
}
8856
#endif
8857
/* End fopen */
8858
8859
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
8860
0
{
8861
0
    return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
8862
0
}
8863
8864
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
8865
0
{
8866
0
    int whence = SEEK_SET;
8867
0
    if (origin == DRFLAC_SEEK_CUR) {
8868
0
        whence = SEEK_CUR;
8869
0
    } else if (origin == DRFLAC_SEEK_END) {
8870
0
        whence = SEEK_END;
8871
0
    }
8872
8873
0
    return fseek((FILE*)pUserData, offset, whence) == 0;
8874
0
}
8875
8876
static drflac_bool32 drflac__on_tell_stdio(void* pUserData, drflac_int64* pCursor)
8877
0
{
8878
0
    FILE* pFileStdio = (FILE*)pUserData;
8879
0
    drflac_int64 result;
8880
8881
    /* These were all validated at a higher level. */
8882
0
    DRFLAC_ASSERT(pFileStdio != NULL);
8883
0
    DRFLAC_ASSERT(pCursor    != NULL);
8884
8885
#if defined(_WIN32) && !defined(NXDK)
8886
    #if defined(_MSC_VER) && _MSC_VER > 1200
8887
        result = _ftelli64(pFileStdio);
8888
    #else
8889
        result = ftell(pFileStdio);
8890
    #endif
8891
#else
8892
0
    result = ftell(pFileStdio);
8893
0
#endif
8894
8895
0
    *pCursor = result;
8896
8897
0
    return DRFLAC_TRUE;
8898
0
}
8899
8900
8901
8902
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
8903
0
{
8904
0
    drflac* pFlac;
8905
0
    FILE* pFile;
8906
8907
0
    if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
8908
0
        return NULL;
8909
0
    }
8910
8911
0
    pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
8912
0
    if (pFlac == NULL) {
8913
0
        fclose(pFile);
8914
0
        return NULL;
8915
0
    }
8916
8917
0
    return pFlac;
8918
0
}
8919
8920
#ifndef DR_FLAC_NO_WCHAR
8921
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
8922
0
{
8923
0
    drflac* pFlac;
8924
0
    FILE* pFile;
8925
8926
0
    if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
8927
0
        return NULL;
8928
0
    }
8929
8930
0
    pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
8931
0
    if (pFlac == NULL) {
8932
0
        fclose(pFile);
8933
0
        return NULL;
8934
0
    }
8935
8936
0
    return pFlac;
8937
0
}
8938
#endif
8939
8940
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8941
0
{
8942
0
    drflac* pFlac;
8943
0
    FILE* pFile;
8944
8945
0
    if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
8946
0
        return NULL;
8947
0
    }
8948
8949
0
    pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
8950
0
    if (pFlac == NULL) {
8951
0
        fclose(pFile);
8952
0
        return pFlac;
8953
0
    }
8954
8955
0
    return pFlac;
8956
0
}
8957
8958
#ifndef DR_FLAC_NO_WCHAR
8959
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
8960
0
{
8961
0
    drflac* pFlac;
8962
0
    FILE* pFile;
8963
8964
0
    if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
8965
0
        return NULL;
8966
0
    }
8967
8968
0
    pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
8969
0
    if (pFlac == NULL) {
8970
0
        fclose(pFile);
8971
0
        return pFlac;
8972
0
    }
8973
8974
0
    return pFlac;
8975
0
}
8976
#endif
8977
#endif  /* DR_FLAC_NO_STDIO */
8978
8979
static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
8980
0
{
8981
0
    drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
8982
0
    size_t bytesRemaining;
8983
8984
0
    DRFLAC_ASSERT(memoryStream != NULL);
8985
0
    DRFLAC_ASSERT(memoryStream->dataSize >= memoryStream->currentReadPos);
8986
8987
0
    bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos;
8988
0
    if (bytesToRead > bytesRemaining) {
8989
0
        bytesToRead = bytesRemaining;
8990
0
    }
8991
8992
0
    if (bytesToRead > 0) {
8993
0
        DRFLAC_COPY_MEMORY(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
8994
0
        memoryStream->currentReadPos += bytesToRead;
8995
0
    }
8996
8997
0
    return bytesToRead;
8998
0
}
8999
9000
static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
9001
0
{
9002
0
    drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
9003
0
    drflac_int64 newCursor;
9004
9005
0
    DRFLAC_ASSERT(memoryStream != NULL);
9006
9007
0
    if (origin == DRFLAC_SEEK_SET) {
9008
0
        newCursor = 0;
9009
0
    } else if (origin == DRFLAC_SEEK_CUR) {
9010
0
        newCursor = (drflac_int64)memoryStream->currentReadPos;
9011
0
    } else if (origin == DRFLAC_SEEK_END) {
9012
0
        newCursor = (drflac_int64)memoryStream->dataSize;
9013
0
    } else {
9014
0
        DRFLAC_ASSERT(!"Invalid seek origin");
9015
0
        return DRFLAC_FALSE;
9016
0
    }
9017
9018
0
    newCursor += offset;
9019
9020
0
    if (newCursor < 0) {
9021
0
        return DRFLAC_FALSE;  /* Trying to seek prior to the start of the buffer. */
9022
0
    }
9023
0
    if ((size_t)newCursor > memoryStream->dataSize) {
9024
0
        return DRFLAC_FALSE;  /* Trying to seek beyond the end of the buffer. */
9025
0
    }
9026
9027
0
    memoryStream->currentReadPos = (size_t)newCursor;
9028
9029
0
    return DRFLAC_TRUE;
9030
0
}
9031
9032
static drflac_bool32 drflac__on_tell_memory(void* pUserData, drflac_int64* pCursor)
9033
0
{
9034
0
    drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
9035
9036
0
    DRFLAC_ASSERT(memoryStream != NULL);
9037
0
    DRFLAC_ASSERT(pCursor != NULL);
9038
9039
0
    *pCursor = (drflac_int64)memoryStream->currentReadPos;
9040
0
    return DRFLAC_TRUE;
9041
0
}
9042
9043
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks)
9044
0
{
9045
0
    drflac__memory_stream memoryStream;
9046
0
    drflac* pFlac;
9047
9048
0
    memoryStream.data = (const drflac_uint8*)pData;
9049
0
    memoryStream.dataSize = dataSize;
9050
0
    memoryStream.currentReadPos = 0;
9051
0
    pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, drflac__on_tell_memory, &memoryStream, pAllocationCallbacks);
9052
0
    if (pFlac == NULL) {
9053
0
        return NULL;
9054
0
    }
9055
9056
0
    pFlac->memoryStream = memoryStream;
9057
9058
    /* This is an awful hack... */
9059
0
#ifndef DR_FLAC_NO_OGG
9060
0
    if (pFlac->container == drflac_container_ogg)
9061
0
    {
9062
0
        drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
9063
0
        oggbs->pUserData = &pFlac->memoryStream;
9064
0
    }
9065
0
    else
9066
0
#endif
9067
0
    {
9068
0
        pFlac->bs.pUserData = &pFlac->memoryStream;
9069
0
    }
9070
9071
0
    return pFlac;
9072
0
}
9073
9074
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
9075
0
{
9076
0
    drflac__memory_stream memoryStream;
9077
0
    drflac* pFlac;
9078
9079
0
    memoryStream.data = (const drflac_uint8*)pData;
9080
0
    memoryStream.dataSize = dataSize;
9081
0
    memoryStream.currentReadPos = 0;
9082
0
    pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, drflac__on_tell_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
9083
0
    if (pFlac == NULL) {
9084
0
        return NULL;
9085
0
    }
9086
9087
0
    pFlac->memoryStream = memoryStream;
9088
9089
    /* This is an awful hack... */
9090
0
#ifndef DR_FLAC_NO_OGG
9091
0
    if (pFlac->container == drflac_container_ogg)
9092
0
    {
9093
0
        drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
9094
0
        oggbs->pUserData = &pFlac->memoryStream;
9095
0
    }
9096
0
    else
9097
0
#endif
9098
0
    {
9099
0
        pFlac->bs.pUserData = &pFlac->memoryStream;
9100
0
    }
9101
9102
0
    return pFlac;
9103
0
}
9104
9105
9106
9107
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
9108
0
{
9109
0
    return drflac_open_with_metadata_private(onRead, onSeek, onTell, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
9110
0
}
9111
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
9112
0
{
9113
0
    return drflac_open_with_metadata_private(onRead, onSeek, onTell, NULL, container, pUserData, pUserData, pAllocationCallbacks);
9114
0
}
9115
9116
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
9117
0
{
9118
0
    return drflac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
9119
0
}
9120
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
9121
0
{
9122
0
    return drflac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
9123
0
}
9124
9125
DRFLAC_API void drflac_close(drflac* pFlac)
9126
0
{
9127
0
    if (pFlac == NULL) {
9128
0
        return;
9129
0
    }
9130
9131
0
#ifndef DR_FLAC_NO_STDIO
9132
    /*
9133
    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()
9134
    was used by looking at the callbacks.
9135
    */
9136
0
    if (pFlac->bs.onRead == drflac__on_read_stdio) {
9137
0
        fclose((FILE*)pFlac->bs.pUserData);
9138
0
    }
9139
9140
0
#ifndef DR_FLAC_NO_OGG
9141
    /* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */
9142
0
    if (pFlac->container == drflac_container_ogg) {
9143
0
        drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
9144
0
        DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
9145
9146
0
        if (oggbs->onRead == drflac__on_read_stdio) {
9147
0
            fclose((FILE*)oggbs->pUserData);
9148
0
        }
9149
0
    }
9150
0
#endif
9151
0
#endif
9152
9153
0
    drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
9154
0
}
9155
9156
9157
#if 0
9158
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9159
{
9160
    drflac_uint64 i;
9161
    for (i = 0; i < frameCount; ++i) {
9162
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9163
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9164
        drflac_uint32 right = left - side;
9165
9166
        pOutputSamples[i*2+0] = (drflac_int32)left;
9167
        pOutputSamples[i*2+1] = (drflac_int32)right;
9168
    }
9169
}
9170
#endif
9171
9172
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)
9173
0
{
9174
0
    drflac_uint64 i;
9175
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9176
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9177
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9178
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9179
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9180
9181
0
    for (i = 0; i < frameCount4; ++i) {
9182
0
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
9183
0
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
9184
0
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
9185
0
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
9186
9187
0
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
9188
0
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
9189
0
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
9190
0
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
9191
9192
0
        drflac_uint32 right0 = left0 - side0;
9193
0
        drflac_uint32 right1 = left1 - side1;
9194
0
        drflac_uint32 right2 = left2 - side2;
9195
0
        drflac_uint32 right3 = left3 - side3;
9196
9197
0
        pOutputSamples[i*8+0] = (drflac_int32)left0;
9198
0
        pOutputSamples[i*8+1] = (drflac_int32)right0;
9199
0
        pOutputSamples[i*8+2] = (drflac_int32)left1;
9200
0
        pOutputSamples[i*8+3] = (drflac_int32)right1;
9201
0
        pOutputSamples[i*8+4] = (drflac_int32)left2;
9202
0
        pOutputSamples[i*8+5] = (drflac_int32)right2;
9203
0
        pOutputSamples[i*8+6] = (drflac_int32)left3;
9204
0
        pOutputSamples[i*8+7] = (drflac_int32)right3;
9205
0
    }
9206
9207
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9208
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
9209
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
9210
0
        drflac_uint32 right = left - side;
9211
9212
0
        pOutputSamples[i*2+0] = (drflac_int32)left;
9213
0
        pOutputSamples[i*2+1] = (drflac_int32)right;
9214
0
    }
9215
0
}
9216
9217
#if defined(DRFLAC_SUPPORT_SSE2)
9218
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9219
0
{
9220
0
    drflac_uint64 i;
9221
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9222
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9223
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9224
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9225
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9226
9227
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9228
9229
0
    for (i = 0; i < frameCount4; ++i) {
9230
0
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9231
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9232
0
        __m128i right = _mm_sub_epi32(left, side);
9233
9234
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9235
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9236
0
    }
9237
9238
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9239
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
9240
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
9241
0
        drflac_uint32 right = left - side;
9242
9243
0
        pOutputSamples[i*2+0] = (drflac_int32)left;
9244
0
        pOutputSamples[i*2+1] = (drflac_int32)right;
9245
0
    }
9246
0
}
9247
#endif
9248
9249
#if defined(DRFLAC_SUPPORT_NEON)
9250
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9251
{
9252
    drflac_uint64 i;
9253
    drflac_uint64 frameCount4 = frameCount >> 2;
9254
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9255
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9256
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9257
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9258
    int32x4_t shift0_4;
9259
    int32x4_t shift1_4;
9260
9261
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9262
9263
    shift0_4 = vdupq_n_s32(shift0);
9264
    shift1_4 = vdupq_n_s32(shift1);
9265
9266
    for (i = 0; i < frameCount4; ++i) {
9267
        uint32x4_t left;
9268
        uint32x4_t side;
9269
        uint32x4_t right;
9270
9271
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
9272
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
9273
        right = vsubq_u32(left, side);
9274
9275
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
9276
    }
9277
9278
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9279
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
9280
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
9281
        drflac_uint32 right = left - side;
9282
9283
        pOutputSamples[i*2+0] = (drflac_int32)left;
9284
        pOutputSamples[i*2+1] = (drflac_int32)right;
9285
    }
9286
}
9287
#endif
9288
9289
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)
9290
0
{
9291
0
#if defined(DRFLAC_SUPPORT_SSE2)
9292
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9293
0
        drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9294
0
    } else
9295
#elif defined(DRFLAC_SUPPORT_NEON)
9296
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9297
        drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9298
    } else
9299
#endif
9300
0
    {
9301
        /* Scalar fallback. */
9302
#if 0
9303
        drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9304
#else
9305
0
        drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9306
0
#endif
9307
0
    }
9308
0
}
9309
9310
9311
#if 0
9312
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9313
{
9314
    drflac_uint64 i;
9315
    for (i = 0; i < frameCount; ++i) {
9316
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9317
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9318
        drflac_uint32 left  = right + side;
9319
9320
        pOutputSamples[i*2+0] = (drflac_int32)left;
9321
        pOutputSamples[i*2+1] = (drflac_int32)right;
9322
    }
9323
}
9324
#endif
9325
9326
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)
9327
0
{
9328
0
    drflac_uint64 i;
9329
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9330
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9331
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9332
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9333
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9334
9335
0
    for (i = 0; i < frameCount4; ++i) {
9336
0
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
9337
0
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
9338
0
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
9339
0
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
9340
9341
0
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
9342
0
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
9343
0
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
9344
0
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
9345
9346
0
        drflac_uint32 left0 = right0 + side0;
9347
0
        drflac_uint32 left1 = right1 + side1;
9348
0
        drflac_uint32 left2 = right2 + side2;
9349
0
        drflac_uint32 left3 = right3 + side3;
9350
9351
0
        pOutputSamples[i*8+0] = (drflac_int32)left0;
9352
0
        pOutputSamples[i*8+1] = (drflac_int32)right0;
9353
0
        pOutputSamples[i*8+2] = (drflac_int32)left1;
9354
0
        pOutputSamples[i*8+3] = (drflac_int32)right1;
9355
0
        pOutputSamples[i*8+4] = (drflac_int32)left2;
9356
0
        pOutputSamples[i*8+5] = (drflac_int32)right2;
9357
0
        pOutputSamples[i*8+6] = (drflac_int32)left3;
9358
0
        pOutputSamples[i*8+7] = (drflac_int32)right3;
9359
0
    }
9360
9361
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9362
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
9363
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
9364
0
        drflac_uint32 left  = right + side;
9365
9366
0
        pOutputSamples[i*2+0] = (drflac_int32)left;
9367
0
        pOutputSamples[i*2+1] = (drflac_int32)right;
9368
0
    }
9369
0
}
9370
9371
#if defined(DRFLAC_SUPPORT_SSE2)
9372
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9373
0
{
9374
0
    drflac_uint64 i;
9375
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9376
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9377
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9378
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9379
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9380
9381
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9382
9383
0
    for (i = 0; i < frameCount4; ++i) {
9384
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9385
0
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9386
0
        __m128i left  = _mm_add_epi32(right, side);
9387
9388
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9389
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9390
0
    }
9391
9392
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9393
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
9394
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
9395
0
        drflac_uint32 left  = right + side;
9396
9397
0
        pOutputSamples[i*2+0] = (drflac_int32)left;
9398
0
        pOutputSamples[i*2+1] = (drflac_int32)right;
9399
0
    }
9400
0
}
9401
#endif
9402
9403
#if defined(DRFLAC_SUPPORT_NEON)
9404
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9405
{
9406
    drflac_uint64 i;
9407
    drflac_uint64 frameCount4 = frameCount >> 2;
9408
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9409
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9410
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9411
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9412
    int32x4_t shift0_4;
9413
    int32x4_t shift1_4;
9414
9415
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9416
9417
    shift0_4 = vdupq_n_s32(shift0);
9418
    shift1_4 = vdupq_n_s32(shift1);
9419
9420
    for (i = 0; i < frameCount4; ++i) {
9421
        uint32x4_t side;
9422
        uint32x4_t right;
9423
        uint32x4_t left;
9424
9425
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
9426
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
9427
        left  = vaddq_u32(right, side);
9428
9429
        drflac__vst2q_u32((drflac_uint32*)pOutputSamples + i*8, vzipq_u32(left, right));
9430
    }
9431
9432
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9433
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
9434
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
9435
        drflac_uint32 left  = right + side;
9436
9437
        pOutputSamples[i*2+0] = (drflac_int32)left;
9438
        pOutputSamples[i*2+1] = (drflac_int32)right;
9439
    }
9440
}
9441
#endif
9442
9443
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)
9444
0
{
9445
0
#if defined(DRFLAC_SUPPORT_SSE2)
9446
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9447
0
        drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9448
0
    } else
9449
#elif defined(DRFLAC_SUPPORT_NEON)
9450
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9451
        drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9452
    } else
9453
#endif
9454
0
    {
9455
        /* Scalar fallback. */
9456
#if 0
9457
        drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9458
#else
9459
0
        drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9460
0
#endif
9461
0
    }
9462
0
}
9463
9464
9465
#if 0
9466
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9467
{
9468
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
9469
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9470
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9471
9472
        mid = (mid << 1) | (side & 0x01);
9473
9474
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
9475
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
9476
    }
9477
}
9478
#endif
9479
9480
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)
9481
0
{
9482
0
    drflac_uint64 i;
9483
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9484
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9485
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9486
0
    drflac_int32 shift = unusedBitsPerSample;
9487
9488
0
    if (shift > 0) {
9489
0
        shift -= 1;
9490
0
        for (i = 0; i < frameCount4; ++i) {
9491
0
            drflac_uint32 temp0L;
9492
0
            drflac_uint32 temp1L;
9493
0
            drflac_uint32 temp2L;
9494
0
            drflac_uint32 temp3L;
9495
0
            drflac_uint32 temp0R;
9496
0
            drflac_uint32 temp1R;
9497
0
            drflac_uint32 temp2R;
9498
0
            drflac_uint32 temp3R;
9499
9500
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9501
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9502
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9503
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9504
9505
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9506
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9507
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9508
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9509
9510
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
9511
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
9512
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
9513
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
9514
9515
0
            temp0L = (mid0 + side0) << shift;
9516
0
            temp1L = (mid1 + side1) << shift;
9517
0
            temp2L = (mid2 + side2) << shift;
9518
0
            temp3L = (mid3 + side3) << shift;
9519
9520
0
            temp0R = (mid0 - side0) << shift;
9521
0
            temp1R = (mid1 - side1) << shift;
9522
0
            temp2R = (mid2 - side2) << shift;
9523
0
            temp3R = (mid3 - side3) << shift;
9524
9525
0
            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
9526
0
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
9527
0
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
9528
0
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
9529
0
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
9530
0
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
9531
0
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
9532
0
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
9533
0
        }
9534
0
    } else {
9535
0
        for (i = 0; i < frameCount4; ++i) {
9536
0
            drflac_uint32 temp0L;
9537
0
            drflac_uint32 temp1L;
9538
0
            drflac_uint32 temp2L;
9539
0
            drflac_uint32 temp3L;
9540
0
            drflac_uint32 temp0R;
9541
0
            drflac_uint32 temp1R;
9542
0
            drflac_uint32 temp2R;
9543
0
            drflac_uint32 temp3R;
9544
9545
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9546
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9547
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9548
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9549
9550
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9551
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9552
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9553
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9554
9555
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
9556
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
9557
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
9558
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
9559
9560
0
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
9561
0
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
9562
0
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
9563
0
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
9564
9565
0
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
9566
0
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
9567
0
            temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
9568
0
            temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
9569
9570
0
            pOutputSamples[i*8+0] = (drflac_int32)temp0L;
9571
0
            pOutputSamples[i*8+1] = (drflac_int32)temp0R;
9572
0
            pOutputSamples[i*8+2] = (drflac_int32)temp1L;
9573
0
            pOutputSamples[i*8+3] = (drflac_int32)temp1R;
9574
0
            pOutputSamples[i*8+4] = (drflac_int32)temp2L;
9575
0
            pOutputSamples[i*8+5] = (drflac_int32)temp2R;
9576
0
            pOutputSamples[i*8+6] = (drflac_int32)temp3L;
9577
0
            pOutputSamples[i*8+7] = (drflac_int32)temp3R;
9578
0
        }
9579
0
    }
9580
9581
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9582
0
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9583
0
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9584
9585
0
        mid = (mid << 1) | (side & 0x01);
9586
9587
0
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
9588
0
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
9589
0
    }
9590
0
}
9591
9592
#if defined(DRFLAC_SUPPORT_SSE2)
9593
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9594
0
{
9595
0
    drflac_uint64 i;
9596
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9597
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9598
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9599
0
    drflac_int32 shift = unusedBitsPerSample;
9600
9601
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9602
9603
0
    if (shift == 0) {
9604
0
        for (i = 0; i < frameCount4; ++i) {
9605
0
            __m128i mid;
9606
0
            __m128i side;
9607
0
            __m128i left;
9608
0
            __m128i right;
9609
9610
0
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9611
0
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9612
9613
0
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9614
9615
0
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
9616
0
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
9617
9618
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9619
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9620
0
        }
9621
9622
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
9623
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9624
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9625
9626
0
            mid = (mid << 1) | (side & 0x01);
9627
9628
0
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
9629
0
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
9630
0
        }
9631
0
    } else {
9632
0
        shift -= 1;
9633
0
        for (i = 0; i < frameCount4; ++i) {
9634
0
            __m128i mid;
9635
0
            __m128i side;
9636
0
            __m128i left;
9637
0
            __m128i right;
9638
9639
0
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9640
0
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9641
9642
0
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
9643
9644
0
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
9645
0
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
9646
9647
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9648
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9649
0
        }
9650
9651
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
9652
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9653
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9654
9655
0
            mid = (mid << 1) | (side & 0x01);
9656
9657
0
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
9658
0
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
9659
0
        }
9660
0
    }
9661
0
}
9662
#endif
9663
9664
#if defined(DRFLAC_SUPPORT_NEON)
9665
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9666
{
9667
    drflac_uint64 i;
9668
    drflac_uint64 frameCount4 = frameCount >> 2;
9669
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9670
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9671
    drflac_int32 shift = unusedBitsPerSample;
9672
    int32x4_t  wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
9673
    int32x4_t  wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
9674
    uint32x4_t one4;
9675
9676
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
9677
9678
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9679
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9680
    one4         = vdupq_n_u32(1);
9681
9682
    if (shift == 0) {
9683
        for (i = 0; i < frameCount4; ++i) {
9684
            uint32x4_t mid;
9685
            uint32x4_t side;
9686
            int32x4_t left;
9687
            int32x4_t right;
9688
9689
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
9690
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
9691
9692
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
9693
9694
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
9695
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
9696
9697
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9698
        }
9699
9700
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
9701
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9702
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9703
9704
            mid = (mid << 1) | (side & 0x01);
9705
9706
            pOutputSamples[i*2+0] = (drflac_int32)(mid + side) >> 1;
9707
            pOutputSamples[i*2+1] = (drflac_int32)(mid - side) >> 1;
9708
        }
9709
    } else {
9710
        int32x4_t shift4;
9711
9712
        shift -= 1;
9713
        shift4 = vdupq_n_s32(shift);
9714
9715
        for (i = 0; i < frameCount4; ++i) {
9716
            uint32x4_t mid;
9717
            uint32x4_t side;
9718
            int32x4_t left;
9719
            int32x4_t right;
9720
9721
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
9722
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
9723
9724
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, one4));
9725
9726
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
9727
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
9728
9729
            drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9730
        }
9731
9732
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
9733
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9734
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9735
9736
            mid = (mid << 1) | (side & 0x01);
9737
9738
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
9739
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
9740
        }
9741
    }
9742
}
9743
#endif
9744
9745
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)
9746
0
{
9747
0
#if defined(DRFLAC_SUPPORT_SSE2)
9748
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9749
0
        drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9750
0
    } else
9751
#elif defined(DRFLAC_SUPPORT_NEON)
9752
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9753
        drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9754
    } else
9755
#endif
9756
0
    {
9757
        /* Scalar fallback. */
9758
#if 0
9759
        drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9760
#else
9761
0
        drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9762
0
#endif
9763
0
    }
9764
0
}
9765
9766
9767
#if 0
9768
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9769
{
9770
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
9771
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
9772
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
9773
    }
9774
}
9775
#endif
9776
9777
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)
9778
0
{
9779
0
    drflac_uint64 i;
9780
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9781
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9782
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9783
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9784
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9785
9786
0
    for (i = 0; i < frameCount4; ++i) {
9787
0
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
9788
0
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
9789
0
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
9790
0
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
9791
9792
0
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
9793
0
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
9794
0
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
9795
0
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
9796
9797
0
        pOutputSamples[i*8+0] = (drflac_int32)tempL0;
9798
0
        pOutputSamples[i*8+1] = (drflac_int32)tempR0;
9799
0
        pOutputSamples[i*8+2] = (drflac_int32)tempL1;
9800
0
        pOutputSamples[i*8+3] = (drflac_int32)tempR1;
9801
0
        pOutputSamples[i*8+4] = (drflac_int32)tempL2;
9802
0
        pOutputSamples[i*8+5] = (drflac_int32)tempR2;
9803
0
        pOutputSamples[i*8+6] = (drflac_int32)tempL3;
9804
0
        pOutputSamples[i*8+7] = (drflac_int32)tempR3;
9805
0
    }
9806
9807
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9808
0
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9809
0
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9810
0
    }
9811
0
}
9812
9813
#if defined(DRFLAC_SUPPORT_SSE2)
9814
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9815
0
{
9816
0
    drflac_uint64 i;
9817
0
    drflac_uint64 frameCount4 = frameCount >> 2;
9818
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9819
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9820
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9821
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9822
9823
0
    for (i = 0; i < frameCount4; ++i) {
9824
0
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
9825
0
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
9826
9827
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 0), _mm_unpacklo_epi32(left, right));
9828
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8 + 4), _mm_unpackhi_epi32(left, right));
9829
0
    }
9830
9831
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9832
0
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9833
0
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9834
0
    }
9835
0
}
9836
#endif
9837
9838
#if defined(DRFLAC_SUPPORT_NEON)
9839
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
9840
{
9841
    drflac_uint64 i;
9842
    drflac_uint64 frameCount4 = frameCount >> 2;
9843
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
9844
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
9845
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
9846
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
9847
9848
    int32x4_t shift4_0 = vdupq_n_s32(shift0);
9849
    int32x4_t shift4_1 = vdupq_n_s32(shift1);
9850
9851
    for (i = 0; i < frameCount4; ++i) {
9852
        int32x4_t left;
9853
        int32x4_t right;
9854
9855
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift4_0));
9856
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift4_1));
9857
9858
        drflac__vst2q_s32(pOutputSamples + i*8, vzipq_s32(left, right));
9859
    }
9860
9861
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
9862
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
9863
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
9864
    }
9865
}
9866
#endif
9867
9868
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)
9869
0
{
9870
0
#if defined(DRFLAC_SUPPORT_SSE2)
9871
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
9872
0
        drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9873
0
    } else
9874
#elif defined(DRFLAC_SUPPORT_NEON)
9875
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
9876
        drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9877
    } else
9878
#endif
9879
0
    {
9880
        /* Scalar fallback. */
9881
#if 0
9882
        drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9883
#else
9884
0
        drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
9885
0
#endif
9886
0
    }
9887
0
}
9888
9889
9890
static drflac_bool32 drflac__is_current_flac_frame_valid(drflac* pFlac)
9891
0
{
9892
0
    drflac_uint32 iChannel;
9893
9894
0
    if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames || pFlac->currentFLACFrame.pcmFramesRemaining > pFlac->currentFLACFrame.header.blockSizeInPCMFrames) {
9895
0
        return DRFLAC_FALSE;
9896
0
    }
9897
9898
0
    for (iChannel = 0; iChannel < pFlac->channels; iChannel += 1) {
9899
0
        if (pFlac->currentFLACFrame.subframes[iChannel].pSamplesS32 == NULL) {
9900
0
            return DRFLAC_FALSE;
9901
0
        }
9902
0
    }
9903
9904
0
    return DRFLAC_TRUE;
9905
0
}
9906
9907
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut)
9908
0
{
9909
0
    drflac_uint64 framesRead;
9910
0
    drflac_uint32 unusedBitsPerSample;
9911
9912
0
    if (pFlac == NULL || framesToRead == 0) {
9913
0
        return 0;
9914
0
    }
9915
9916
0
    if (pBufferOut == NULL) {
9917
0
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
9918
0
    }
9919
9920
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
9921
0
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
9922
9923
0
    framesRead = 0;
9924
0
    while (framesToRead > 0) {
9925
        /* If we've run out of samples in this frame, go to the next. */
9926
0
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
9927
0
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
9928
0
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
9929
0
            }
9930
0
        } else {
9931
0
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
9932
0
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
9933
0
            drflac_uint64 frameCountThisIteration = framesToRead;
9934
9935
0
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
9936
0
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
9937
0
            }
9938
9939
0
            if (channelCount == 2) {
9940
0
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
9941
0
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
9942
9943
0
                switch (pFlac->currentFLACFrame.header.channelAssignment)
9944
0
                {
9945
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
9946
0
                    {
9947
0
                        drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9948
0
                    } break;
9949
9950
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
9951
0
                    {
9952
0
                        drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9953
0
                    } break;
9954
9955
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
9956
0
                    {
9957
0
                        drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9958
0
                    } break;
9959
9960
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
9961
0
                    default:
9962
0
                    {
9963
0
                        drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
9964
0
                    } break;
9965
0
                }
9966
0
            } else {
9967
                /* Generic interleaving. */
9968
0
                drflac_uint64 i;
9969
0
                for (i = 0; i < frameCountThisIteration; ++i) {
9970
0
                    unsigned int j;
9971
0
                    for (j = 0; j < channelCount; ++j) {
9972
0
                        pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
9973
0
                    }
9974
0
                }
9975
0
            }
9976
9977
0
            framesRead                += frameCountThisIteration;
9978
0
            pBufferOut                += frameCountThisIteration * channelCount;
9979
0
            framesToRead              -= frameCountThisIteration;
9980
0
            pFlac->currentPCMFrame    += frameCountThisIteration;
9981
0
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
9982
0
        }
9983
0
    }
9984
9985
0
    return framesRead;
9986
0
}
9987
9988
9989
#if 0
9990
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
9991
{
9992
    drflac_uint64 i;
9993
    for (i = 0; i < frameCount; ++i) {
9994
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
9995
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
9996
        drflac_uint32 right = left - side;
9997
9998
        left  >>= 16;
9999
        right >>= 16;
10000
10001
        pOutputSamples[i*2+0] = (drflac_int16)left;
10002
        pOutputSamples[i*2+1] = (drflac_int16)right;
10003
    }
10004
}
10005
#endif
10006
10007
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)
10008
0
{
10009
0
    drflac_uint64 i;
10010
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10011
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10012
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10013
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10014
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10015
10016
0
    for (i = 0; i < frameCount4; ++i) {
10017
0
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
10018
0
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
10019
0
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
10020
0
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
10021
10022
0
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
10023
0
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
10024
0
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
10025
0
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
10026
10027
0
        drflac_uint32 right0 = left0 - side0;
10028
0
        drflac_uint32 right1 = left1 - side1;
10029
0
        drflac_uint32 right2 = left2 - side2;
10030
0
        drflac_uint32 right3 = left3 - side3;
10031
10032
0
        left0  >>= 16;
10033
0
        left1  >>= 16;
10034
0
        left2  >>= 16;
10035
0
        left3  >>= 16;
10036
10037
0
        right0 >>= 16;
10038
0
        right1 >>= 16;
10039
0
        right2 >>= 16;
10040
0
        right3 >>= 16;
10041
10042
0
        pOutputSamples[i*8+0] = (drflac_int16)left0;
10043
0
        pOutputSamples[i*8+1] = (drflac_int16)right0;
10044
0
        pOutputSamples[i*8+2] = (drflac_int16)left1;
10045
0
        pOutputSamples[i*8+3] = (drflac_int16)right1;
10046
0
        pOutputSamples[i*8+4] = (drflac_int16)left2;
10047
0
        pOutputSamples[i*8+5] = (drflac_int16)right2;
10048
0
        pOutputSamples[i*8+6] = (drflac_int16)left3;
10049
0
        pOutputSamples[i*8+7] = (drflac_int16)right3;
10050
0
    }
10051
10052
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10053
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
10054
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
10055
0
        drflac_uint32 right = left - side;
10056
10057
0
        left  >>= 16;
10058
0
        right >>= 16;
10059
10060
0
        pOutputSamples[i*2+0] = (drflac_int16)left;
10061
0
        pOutputSamples[i*2+1] = (drflac_int16)right;
10062
0
    }
10063
0
}
10064
10065
#if defined(DRFLAC_SUPPORT_SSE2)
10066
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10067
0
{
10068
0
    drflac_uint64 i;
10069
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10070
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10071
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10072
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10073
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10074
10075
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10076
10077
0
    for (i = 0; i < frameCount4; ++i) {
10078
0
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10079
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10080
0
        __m128i right = _mm_sub_epi32(left, side);
10081
10082
0
        left  = _mm_srai_epi32(left,  16);
10083
0
        right = _mm_srai_epi32(right, 16);
10084
10085
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10086
0
    }
10087
10088
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10089
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
10090
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
10091
0
        drflac_uint32 right = left - side;
10092
10093
0
        left  >>= 16;
10094
0
        right >>= 16;
10095
10096
0
        pOutputSamples[i*2+0] = (drflac_int16)left;
10097
0
        pOutputSamples[i*2+1] = (drflac_int16)right;
10098
0
    }
10099
0
}
10100
#endif
10101
10102
#if defined(DRFLAC_SUPPORT_NEON)
10103
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10104
{
10105
    drflac_uint64 i;
10106
    drflac_uint64 frameCount4 = frameCount >> 2;
10107
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10108
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10109
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10110
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10111
    int32x4_t shift0_4;
10112
    int32x4_t shift1_4;
10113
10114
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10115
10116
    shift0_4 = vdupq_n_s32(shift0);
10117
    shift1_4 = vdupq_n_s32(shift1);
10118
10119
    for (i = 0; i < frameCount4; ++i) {
10120
        uint32x4_t left;
10121
        uint32x4_t side;
10122
        uint32x4_t right;
10123
10124
        left  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
10125
        side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
10126
        right = vsubq_u32(left, side);
10127
10128
        left  = vshrq_n_u32(left,  16);
10129
        right = vshrq_n_u32(right, 16);
10130
10131
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
10132
    }
10133
10134
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10135
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
10136
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
10137
        drflac_uint32 right = left - side;
10138
10139
        left  >>= 16;
10140
        right >>= 16;
10141
10142
        pOutputSamples[i*2+0] = (drflac_int16)left;
10143
        pOutputSamples[i*2+1] = (drflac_int16)right;
10144
    }
10145
}
10146
#endif
10147
10148
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)
10149
0
{
10150
0
#if defined(DRFLAC_SUPPORT_SSE2)
10151
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10152
0
        drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10153
0
    } else
10154
#elif defined(DRFLAC_SUPPORT_NEON)
10155
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10156
        drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10157
    } else
10158
#endif
10159
0
    {
10160
        /* Scalar fallback. */
10161
#if 0
10162
        drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10163
#else
10164
0
        drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10165
0
#endif
10166
0
    }
10167
0
}
10168
10169
10170
#if 0
10171
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10172
{
10173
    drflac_uint64 i;
10174
    for (i = 0; i < frameCount; ++i) {
10175
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10176
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10177
        drflac_uint32 left  = right + side;
10178
10179
        left  >>= 16;
10180
        right >>= 16;
10181
10182
        pOutputSamples[i*2+0] = (drflac_int16)left;
10183
        pOutputSamples[i*2+1] = (drflac_int16)right;
10184
    }
10185
}
10186
#endif
10187
10188
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)
10189
0
{
10190
0
    drflac_uint64 i;
10191
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10192
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10193
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10194
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10195
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10196
10197
0
    for (i = 0; i < frameCount4; ++i) {
10198
0
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
10199
0
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
10200
0
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
10201
0
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
10202
10203
0
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
10204
0
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
10205
0
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
10206
0
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
10207
10208
0
        drflac_uint32 left0 = right0 + side0;
10209
0
        drflac_uint32 left1 = right1 + side1;
10210
0
        drflac_uint32 left2 = right2 + side2;
10211
0
        drflac_uint32 left3 = right3 + side3;
10212
10213
0
        left0  >>= 16;
10214
0
        left1  >>= 16;
10215
0
        left2  >>= 16;
10216
0
        left3  >>= 16;
10217
10218
0
        right0 >>= 16;
10219
0
        right1 >>= 16;
10220
0
        right2 >>= 16;
10221
0
        right3 >>= 16;
10222
10223
0
        pOutputSamples[i*8+0] = (drflac_int16)left0;
10224
0
        pOutputSamples[i*8+1] = (drflac_int16)right0;
10225
0
        pOutputSamples[i*8+2] = (drflac_int16)left1;
10226
0
        pOutputSamples[i*8+3] = (drflac_int16)right1;
10227
0
        pOutputSamples[i*8+4] = (drflac_int16)left2;
10228
0
        pOutputSamples[i*8+5] = (drflac_int16)right2;
10229
0
        pOutputSamples[i*8+6] = (drflac_int16)left3;
10230
0
        pOutputSamples[i*8+7] = (drflac_int16)right3;
10231
0
    }
10232
10233
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10234
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
10235
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
10236
0
        drflac_uint32 left  = right + side;
10237
10238
0
        left  >>= 16;
10239
0
        right >>= 16;
10240
10241
0
        pOutputSamples[i*2+0] = (drflac_int16)left;
10242
0
        pOutputSamples[i*2+1] = (drflac_int16)right;
10243
0
    }
10244
0
}
10245
10246
#if defined(DRFLAC_SUPPORT_SSE2)
10247
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10248
0
{
10249
0
    drflac_uint64 i;
10250
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10251
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10252
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10253
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10254
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10255
10256
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10257
10258
0
    for (i = 0; i < frameCount4; ++i) {
10259
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10260
0
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10261
0
        __m128i left  = _mm_add_epi32(right, side);
10262
10263
0
        left  = _mm_srai_epi32(left,  16);
10264
0
        right = _mm_srai_epi32(right, 16);
10265
10266
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10267
0
    }
10268
10269
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10270
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
10271
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
10272
0
        drflac_uint32 left  = right + side;
10273
10274
0
        left  >>= 16;
10275
0
        right >>= 16;
10276
10277
0
        pOutputSamples[i*2+0] = (drflac_int16)left;
10278
0
        pOutputSamples[i*2+1] = (drflac_int16)right;
10279
0
    }
10280
0
}
10281
#endif
10282
10283
#if defined(DRFLAC_SUPPORT_NEON)
10284
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10285
{
10286
    drflac_uint64 i;
10287
    drflac_uint64 frameCount4 = frameCount >> 2;
10288
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10289
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10290
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10291
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10292
    int32x4_t shift0_4;
10293
    int32x4_t shift1_4;
10294
10295
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10296
10297
    shift0_4 = vdupq_n_s32(shift0);
10298
    shift1_4 = vdupq_n_s32(shift1);
10299
10300
    for (i = 0; i < frameCount4; ++i) {
10301
        uint32x4_t side;
10302
        uint32x4_t right;
10303
        uint32x4_t left;
10304
10305
        side  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
10306
        right = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
10307
        left  = vaddq_u32(right, side);
10308
10309
        left  = vshrq_n_u32(left,  16);
10310
        right = vshrq_n_u32(right, 16);
10311
10312
        drflac__vst2q_u16((drflac_uint16*)pOutputSamples + i*8, vzip_u16(vmovn_u32(left), vmovn_u32(right)));
10313
    }
10314
10315
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10316
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
10317
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
10318
        drflac_uint32 left  = right + side;
10319
10320
        left  >>= 16;
10321
        right >>= 16;
10322
10323
        pOutputSamples[i*2+0] = (drflac_int16)left;
10324
        pOutputSamples[i*2+1] = (drflac_int16)right;
10325
    }
10326
}
10327
#endif
10328
10329
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)
10330
0
{
10331
0
#if defined(DRFLAC_SUPPORT_SSE2)
10332
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10333
0
        drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10334
0
    } else
10335
#elif defined(DRFLAC_SUPPORT_NEON)
10336
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10337
        drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10338
    } else
10339
#endif
10340
0
    {
10341
        /* Scalar fallback. */
10342
#if 0
10343
        drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10344
#else
10345
0
        drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10346
0
#endif
10347
0
    }
10348
0
}
10349
10350
10351
#if 0
10352
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10353
{
10354
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
10355
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10356
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10357
10358
        mid = (mid << 1) | (side & 0x01);
10359
10360
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
10361
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
10362
    }
10363
}
10364
#endif
10365
10366
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)
10367
0
{
10368
0
    drflac_uint64 i;
10369
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10370
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10371
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10372
0
    drflac_uint32 shift = unusedBitsPerSample;
10373
10374
0
    if (shift > 0) {
10375
0
        shift -= 1;
10376
0
        for (i = 0; i < frameCount4; ++i) {
10377
0
            drflac_uint32 temp0L;
10378
0
            drflac_uint32 temp1L;
10379
0
            drflac_uint32 temp2L;
10380
0
            drflac_uint32 temp3L;
10381
0
            drflac_uint32 temp0R;
10382
0
            drflac_uint32 temp1R;
10383
0
            drflac_uint32 temp2R;
10384
0
            drflac_uint32 temp3R;
10385
10386
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10387
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10388
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10389
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10390
10391
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10392
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10393
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10394
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10395
10396
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
10397
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
10398
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
10399
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
10400
10401
0
            temp0L = (mid0 + side0) << shift;
10402
0
            temp1L = (mid1 + side1) << shift;
10403
0
            temp2L = (mid2 + side2) << shift;
10404
0
            temp3L = (mid3 + side3) << shift;
10405
10406
0
            temp0R = (mid0 - side0) << shift;
10407
0
            temp1R = (mid1 - side1) << shift;
10408
0
            temp2R = (mid2 - side2) << shift;
10409
0
            temp3R = (mid3 - side3) << shift;
10410
10411
0
            temp0L >>= 16;
10412
0
            temp1L >>= 16;
10413
0
            temp2L >>= 16;
10414
0
            temp3L >>= 16;
10415
10416
0
            temp0R >>= 16;
10417
0
            temp1R >>= 16;
10418
0
            temp2R >>= 16;
10419
0
            temp3R >>= 16;
10420
10421
0
            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
10422
0
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
10423
0
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
10424
0
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
10425
0
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
10426
0
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
10427
0
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
10428
0
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
10429
0
        }
10430
0
    } else {
10431
0
        for (i = 0; i < frameCount4; ++i) {
10432
0
            drflac_uint32 temp0L;
10433
0
            drflac_uint32 temp1L;
10434
0
            drflac_uint32 temp2L;
10435
0
            drflac_uint32 temp3L;
10436
0
            drflac_uint32 temp0R;
10437
0
            drflac_uint32 temp1R;
10438
0
            drflac_uint32 temp2R;
10439
0
            drflac_uint32 temp3R;
10440
10441
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10442
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10443
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10444
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10445
10446
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10447
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10448
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10449
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10450
10451
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
10452
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
10453
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
10454
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
10455
10456
0
            temp0L = ((drflac_int32)(mid0 + side0) >> 1);
10457
0
            temp1L = ((drflac_int32)(mid1 + side1) >> 1);
10458
0
            temp2L = ((drflac_int32)(mid2 + side2) >> 1);
10459
0
            temp3L = ((drflac_int32)(mid3 + side3) >> 1);
10460
10461
0
            temp0R = ((drflac_int32)(mid0 - side0) >> 1);
10462
0
            temp1R = ((drflac_int32)(mid1 - side1) >> 1);
10463
0
            temp2R = ((drflac_int32)(mid2 - side2) >> 1);
10464
0
            temp3R = ((drflac_int32)(mid3 - side3) >> 1);
10465
10466
0
            temp0L >>= 16;
10467
0
            temp1L >>= 16;
10468
0
            temp2L >>= 16;
10469
0
            temp3L >>= 16;
10470
10471
0
            temp0R >>= 16;
10472
0
            temp1R >>= 16;
10473
0
            temp2R >>= 16;
10474
0
            temp3R >>= 16;
10475
10476
0
            pOutputSamples[i*8+0] = (drflac_int16)temp0L;
10477
0
            pOutputSamples[i*8+1] = (drflac_int16)temp0R;
10478
0
            pOutputSamples[i*8+2] = (drflac_int16)temp1L;
10479
0
            pOutputSamples[i*8+3] = (drflac_int16)temp1R;
10480
0
            pOutputSamples[i*8+4] = (drflac_int16)temp2L;
10481
0
            pOutputSamples[i*8+5] = (drflac_int16)temp2R;
10482
0
            pOutputSamples[i*8+6] = (drflac_int16)temp3L;
10483
0
            pOutputSamples[i*8+7] = (drflac_int16)temp3R;
10484
0
        }
10485
0
    }
10486
10487
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10488
0
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10489
0
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10490
10491
0
        mid = (mid << 1) | (side & 0x01);
10492
10493
0
        pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
10494
0
        pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
10495
0
    }
10496
0
}
10497
10498
#if defined(DRFLAC_SUPPORT_SSE2)
10499
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10500
0
{
10501
0
    drflac_uint64 i;
10502
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10503
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10504
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10505
0
    drflac_uint32 shift = unusedBitsPerSample;
10506
10507
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10508
10509
0
    if (shift == 0) {
10510
0
        for (i = 0; i < frameCount4; ++i) {
10511
0
            __m128i mid;
10512
0
            __m128i side;
10513
0
            __m128i left;
10514
0
            __m128i right;
10515
10516
0
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10517
0
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10518
10519
0
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
10520
10521
0
            left  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
10522
0
            right = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
10523
10524
0
            left  = _mm_srai_epi32(left,  16);
10525
0
            right = _mm_srai_epi32(right, 16);
10526
10527
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10528
0
        }
10529
10530
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
10531
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10532
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10533
10534
0
            mid = (mid << 1) | (side & 0x01);
10535
10536
0
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
10537
0
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
10538
0
        }
10539
0
    } else {
10540
0
        shift -= 1;
10541
0
        for (i = 0; i < frameCount4; ++i) {
10542
0
            __m128i mid;
10543
0
            __m128i side;
10544
0
            __m128i left;
10545
0
            __m128i right;
10546
10547
0
            mid   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10548
0
            side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10549
10550
0
            mid   = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
10551
10552
0
            left  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
10553
0
            right = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
10554
10555
0
            left  = _mm_srai_epi32(left,  16);
10556
0
            right = _mm_srai_epi32(right, 16);
10557
10558
0
            _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10559
0
        }
10560
10561
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
10562
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10563
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10564
10565
0
            mid = (mid << 1) | (side & 0x01);
10566
10567
0
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
10568
0
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
10569
0
        }
10570
0
    }
10571
0
}
10572
#endif
10573
10574
#if defined(DRFLAC_SUPPORT_NEON)
10575
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10576
{
10577
    drflac_uint64 i;
10578
    drflac_uint64 frameCount4 = frameCount >> 2;
10579
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10580
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10581
    drflac_uint32 shift = unusedBitsPerSample;
10582
    int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
10583
    int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
10584
10585
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10586
10587
    wbpsShift0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10588
    wbpsShift1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10589
10590
    if (shift == 0) {
10591
        for (i = 0; i < frameCount4; ++i) {
10592
            uint32x4_t mid;
10593
            uint32x4_t side;
10594
            int32x4_t left;
10595
            int32x4_t right;
10596
10597
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
10598
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
10599
10600
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
10601
10602
            left  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
10603
            right = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
10604
10605
            left  = vshrq_n_s32(left,  16);
10606
            right = vshrq_n_s32(right, 16);
10607
10608
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10609
        }
10610
10611
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
10612
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10613
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10614
10615
            mid = (mid << 1) | (side & 0x01);
10616
10617
            pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
10618
            pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
10619
        }
10620
    } else {
10621
        int32x4_t shift4;
10622
10623
        shift -= 1;
10624
        shift4 = vdupq_n_s32(shift);
10625
10626
        for (i = 0; i < frameCount4; ++i) {
10627
            uint32x4_t mid;
10628
            uint32x4_t side;
10629
            int32x4_t left;
10630
            int32x4_t right;
10631
10632
            mid   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbpsShift0_4);
10633
            side  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbpsShift1_4);
10634
10635
            mid   = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
10636
10637
            left  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
10638
            right = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
10639
10640
            left  = vshrq_n_s32(left,  16);
10641
            right = vshrq_n_s32(right, 16);
10642
10643
            drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10644
        }
10645
10646
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
10647
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10648
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10649
10650
            mid = (mid << 1) | (side & 0x01);
10651
10652
            pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
10653
            pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
10654
        }
10655
    }
10656
}
10657
#endif
10658
10659
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)
10660
0
{
10661
0
#if defined(DRFLAC_SUPPORT_SSE2)
10662
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10663
0
        drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10664
0
    } else
10665
#elif defined(DRFLAC_SUPPORT_NEON)
10666
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10667
        drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10668
    } else
10669
#endif
10670
0
    {
10671
        /* Scalar fallback. */
10672
#if 0
10673
        drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10674
#else
10675
0
        drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10676
0
#endif
10677
0
    }
10678
0
}
10679
10680
10681
#if 0
10682
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10683
{
10684
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
10685
        pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
10686
        pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
10687
    }
10688
}
10689
#endif
10690
10691
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)
10692
0
{
10693
0
    drflac_uint64 i;
10694
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10695
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10696
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10697
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10698
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10699
10700
0
    for (i = 0; i < frameCount4; ++i) {
10701
0
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
10702
0
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
10703
0
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
10704
0
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
10705
10706
0
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
10707
0
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
10708
0
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
10709
0
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
10710
10711
0
        tempL0 >>= 16;
10712
0
        tempL1 >>= 16;
10713
0
        tempL2 >>= 16;
10714
0
        tempL3 >>= 16;
10715
10716
0
        tempR0 >>= 16;
10717
0
        tempR1 >>= 16;
10718
0
        tempR2 >>= 16;
10719
0
        tempR3 >>= 16;
10720
10721
0
        pOutputSamples[i*8+0] = (drflac_int16)tempL0;
10722
0
        pOutputSamples[i*8+1] = (drflac_int16)tempR0;
10723
0
        pOutputSamples[i*8+2] = (drflac_int16)tempL1;
10724
0
        pOutputSamples[i*8+3] = (drflac_int16)tempR1;
10725
0
        pOutputSamples[i*8+4] = (drflac_int16)tempL2;
10726
0
        pOutputSamples[i*8+5] = (drflac_int16)tempR2;
10727
0
        pOutputSamples[i*8+6] = (drflac_int16)tempL3;
10728
0
        pOutputSamples[i*8+7] = (drflac_int16)tempR3;
10729
0
    }
10730
10731
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10732
0
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10733
0
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10734
0
    }
10735
0
}
10736
10737
#if defined(DRFLAC_SUPPORT_SSE2)
10738
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10739
0
{
10740
0
    drflac_uint64 i;
10741
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10742
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10743
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10744
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10745
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10746
10747
0
    for (i = 0; i < frameCount4; ++i) {
10748
0
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10749
0
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10750
10751
0
        left  = _mm_srai_epi32(left,  16);
10752
0
        right = _mm_srai_epi32(right, 16);
10753
10754
        /* 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. */
10755
0
        _mm_storeu_si128((__m128i*)(pOutputSamples + i*8), drflac__mm_packs_interleaved_epi32(left, right));
10756
0
    }
10757
10758
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10759
0
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10760
0
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10761
0
    }
10762
0
}
10763
#endif
10764
10765
#if defined(DRFLAC_SUPPORT_NEON)
10766
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
10767
{
10768
    drflac_uint64 i;
10769
    drflac_uint64 frameCount4 = frameCount >> 2;
10770
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10771
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10772
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10773
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10774
10775
    int32x4_t shift0_4 = vdupq_n_s32(shift0);
10776
    int32x4_t shift1_4 = vdupq_n_s32(shift1);
10777
10778
    for (i = 0; i < frameCount4; ++i) {
10779
        int32x4_t left;
10780
        int32x4_t right;
10781
10782
        left  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
10783
        right = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
10784
10785
        left  = vshrq_n_s32(left,  16);
10786
        right = vshrq_n_s32(right, 16);
10787
10788
        drflac__vst2q_s16(pOutputSamples + i*8, vzip_s16(vmovn_s32(left), vmovn_s32(right)));
10789
    }
10790
10791
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10792
        pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
10793
        pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
10794
    }
10795
}
10796
#endif
10797
10798
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)
10799
0
{
10800
0
#if defined(DRFLAC_SUPPORT_SSE2)
10801
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
10802
0
        drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10803
0
    } else
10804
#elif defined(DRFLAC_SUPPORT_NEON)
10805
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
10806
        drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10807
    } else
10808
#endif
10809
0
    {
10810
        /* Scalar fallback. */
10811
#if 0
10812
        drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10813
#else
10814
0
        drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
10815
0
#endif
10816
0
    }
10817
0
}
10818
10819
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut)
10820
0
{
10821
0
    drflac_uint64 framesRead;
10822
0
    drflac_uint32 unusedBitsPerSample;
10823
10824
0
    if (pFlac == NULL || framesToRead == 0) {
10825
0
        return 0;
10826
0
    }
10827
10828
0
    if (pBufferOut == NULL) {
10829
0
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
10830
0
    }
10831
10832
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
10833
0
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
10834
10835
0
    framesRead = 0;
10836
0
    while (framesToRead > 0) {
10837
        /* If we've run out of samples in this frame, go to the next. */
10838
0
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
10839
0
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
10840
0
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
10841
0
            }
10842
0
        } else {
10843
0
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
10844
0
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
10845
0
            drflac_uint64 frameCountThisIteration = framesToRead;
10846
10847
0
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
10848
0
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
10849
0
            }
10850
10851
0
            if (channelCount == 2) {
10852
0
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
10853
0
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
10854
10855
0
                switch (pFlac->currentFLACFrame.header.channelAssignment)
10856
0
                {
10857
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
10858
0
                    {
10859
0
                        drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10860
0
                    } break;
10861
10862
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
10863
0
                    {
10864
0
                        drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10865
0
                    } break;
10866
10867
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
10868
0
                    {
10869
0
                        drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10870
0
                    } break;
10871
10872
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
10873
0
                    default:
10874
0
                    {
10875
0
                        drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
10876
0
                    } break;
10877
0
                }
10878
0
            } else {
10879
                /* Generic interleaving. */
10880
0
                drflac_uint64 i;
10881
0
                for (i = 0; i < frameCountThisIteration; ++i) {
10882
0
                    unsigned int j;
10883
0
                    for (j = 0; j < channelCount; ++j) {
10884
0
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
10885
0
                        pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
10886
0
                    }
10887
0
                }
10888
0
            }
10889
10890
0
            framesRead                += frameCountThisIteration;
10891
0
            pBufferOut                += frameCountThisIteration * channelCount;
10892
0
            framesToRead              -= frameCountThisIteration;
10893
0
            pFlac->currentPCMFrame    += frameCountThisIteration;
10894
0
            pFlac->currentFLACFrame.pcmFramesRemaining -= (drflac_uint32)frameCountThisIteration;
10895
0
        }
10896
0
    }
10897
10898
0
    return framesRead;
10899
0
}
10900
10901
10902
#if 0
10903
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10904
{
10905
    drflac_uint64 i;
10906
    for (i = 0; i < frameCount; ++i) {
10907
        drflac_uint32 left  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
10908
        drflac_uint32 side  = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
10909
        drflac_uint32 right = left - side;
10910
10911
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
10912
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
10913
    }
10914
}
10915
#endif
10916
10917
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)
10918
0
{
10919
0
    drflac_uint64 i;
10920
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10921
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10922
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10923
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
10924
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
10925
10926
0
    float factor = 1 / 2147483648.0;
10927
10928
0
    for (i = 0; i < frameCount4; ++i) {
10929
0
        drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
10930
0
        drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
10931
0
        drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
10932
0
        drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
10933
10934
0
        drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
10935
0
        drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
10936
0
        drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
10937
0
        drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
10938
10939
0
        drflac_uint32 right0 = left0 - side0;
10940
0
        drflac_uint32 right1 = left1 - side1;
10941
0
        drflac_uint32 right2 = left2 - side2;
10942
0
        drflac_uint32 right3 = left3 - side3;
10943
10944
0
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
10945
0
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
10946
0
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
10947
0
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
10948
0
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
10949
0
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
10950
0
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
10951
0
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
10952
0
    }
10953
10954
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10955
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
10956
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
10957
0
        drflac_uint32 right = left - side;
10958
10959
0
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
10960
0
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
10961
0
    }
10962
0
}
10963
10964
#if defined(DRFLAC_SUPPORT_SSE2)
10965
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
10966
0
{
10967
0
    drflac_uint64 i;
10968
0
    drflac_uint64 frameCount4 = frameCount >> 2;
10969
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
10970
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
10971
0
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
10972
0
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
10973
0
    __m128 factor;
10974
10975
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
10976
10977
0
    factor = _mm_set1_ps(1.0f / 8388608.0f);
10978
10979
0
    for (i = 0; i < frameCount4; ++i) {
10980
0
        __m128i left  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
10981
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
10982
0
        __m128i right = _mm_sub_epi32(left, side);
10983
0
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
10984
0
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
10985
10986
0
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
10987
0
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
10988
0
    }
10989
10990
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
10991
0
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
10992
0
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
10993
0
        drflac_uint32 right = left - side;
10994
10995
0
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
10996
0
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
10997
0
    }
10998
0
}
10999
#endif
11000
11001
#if defined(DRFLAC_SUPPORT_NEON)
11002
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11003
{
11004
    drflac_uint64 i;
11005
    drflac_uint64 frameCount4 = frameCount >> 2;
11006
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11007
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11008
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11009
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11010
    float32x4_t factor4;
11011
    int32x4_t shift0_4;
11012
    int32x4_t shift1_4;
11013
11014
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11015
11016
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
11017
    shift0_4 = vdupq_n_s32(shift0);
11018
    shift1_4 = vdupq_n_s32(shift1);
11019
11020
    for (i = 0; i < frameCount4; ++i) {
11021
        uint32x4_t left;
11022
        uint32x4_t side;
11023
        uint32x4_t right;
11024
        float32x4_t leftf;
11025
        float32x4_t rightf;
11026
11027
        left   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
11028
        side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
11029
        right  = vsubq_u32(left, side);
11030
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
11031
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
11032
11033
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11034
    }
11035
11036
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11037
        drflac_uint32 left  = pInputSamples0U32[i] << shift0;
11038
        drflac_uint32 side  = pInputSamples1U32[i] << shift1;
11039
        drflac_uint32 right = left - side;
11040
11041
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
11042
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
11043
    }
11044
}
11045
#endif
11046
11047
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)
11048
0
{
11049
0
#if defined(DRFLAC_SUPPORT_SSE2)
11050
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11051
0
        drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11052
0
    } else
11053
#elif defined(DRFLAC_SUPPORT_NEON)
11054
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11055
        drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11056
    } else
11057
#endif
11058
0
    {
11059
        /* Scalar fallback. */
11060
#if 0
11061
        drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11062
#else
11063
0
        drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11064
0
#endif
11065
0
    }
11066
0
}
11067
11068
11069
#if 0
11070
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11071
{
11072
    drflac_uint64 i;
11073
    for (i = 0; i < frameCount; ++i) {
11074
        drflac_uint32 side  = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11075
        drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11076
        drflac_uint32 left  = right + side;
11077
11078
        pOutputSamples[i*2+0] = (float)((drflac_int32)left  / 2147483648.0);
11079
        pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
11080
    }
11081
}
11082
#endif
11083
11084
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)
11085
0
{
11086
0
    drflac_uint64 i;
11087
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11088
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11089
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11090
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11091
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11092
0
    float factor = 1 / 2147483648.0;
11093
11094
0
    for (i = 0; i < frameCount4; ++i) {
11095
0
        drflac_uint32 side0  = pInputSamples0U32[i*4+0] << shift0;
11096
0
        drflac_uint32 side1  = pInputSamples0U32[i*4+1] << shift0;
11097
0
        drflac_uint32 side2  = pInputSamples0U32[i*4+2] << shift0;
11098
0
        drflac_uint32 side3  = pInputSamples0U32[i*4+3] << shift0;
11099
11100
0
        drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
11101
0
        drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
11102
0
        drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
11103
0
        drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
11104
11105
0
        drflac_uint32 left0 = right0 + side0;
11106
0
        drflac_uint32 left1 = right1 + side1;
11107
0
        drflac_uint32 left2 = right2 + side2;
11108
0
        drflac_uint32 left3 = right3 + side3;
11109
11110
0
        pOutputSamples[i*8+0] = (drflac_int32)left0  * factor;
11111
0
        pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
11112
0
        pOutputSamples[i*8+2] = (drflac_int32)left1  * factor;
11113
0
        pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
11114
0
        pOutputSamples[i*8+4] = (drflac_int32)left2  * factor;
11115
0
        pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
11116
0
        pOutputSamples[i*8+6] = (drflac_int32)left3  * factor;
11117
0
        pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
11118
0
    }
11119
11120
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11121
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
11122
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
11123
0
        drflac_uint32 left  = right + side;
11124
11125
0
        pOutputSamples[i*2+0] = (drflac_int32)left  * factor;
11126
0
        pOutputSamples[i*2+1] = (drflac_int32)right * factor;
11127
0
    }
11128
0
}
11129
11130
#if defined(DRFLAC_SUPPORT_SSE2)
11131
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11132
0
{
11133
0
    drflac_uint64 i;
11134
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11135
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11136
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11137
0
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11138
0
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11139
0
    __m128 factor;
11140
11141
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11142
11143
0
    factor = _mm_set1_ps(1.0f / 8388608.0f);
11144
11145
0
    for (i = 0; i < frameCount4; ++i) {
11146
0
        __m128i side  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
11147
0
        __m128i right = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
11148
0
        __m128i left  = _mm_add_epi32(right, side);
11149
0
        __m128 leftf  = _mm_mul_ps(_mm_cvtepi32_ps(left),  factor);
11150
0
        __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor);
11151
11152
0
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11153
0
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11154
0
    }
11155
11156
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11157
0
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
11158
0
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
11159
0
        drflac_uint32 left  = right + side;
11160
11161
0
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
11162
0
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
11163
0
    }
11164
0
}
11165
#endif
11166
11167
#if defined(DRFLAC_SUPPORT_NEON)
11168
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11169
{
11170
    drflac_uint64 i;
11171
    drflac_uint64 frameCount4 = frameCount >> 2;
11172
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11173
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11174
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11175
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11176
    float32x4_t factor4;
11177
    int32x4_t shift0_4;
11178
    int32x4_t shift1_4;
11179
11180
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11181
11182
    factor4  = vdupq_n_f32(1.0f / 8388608.0f);
11183
    shift0_4 = vdupq_n_s32(shift0);
11184
    shift1_4 = vdupq_n_s32(shift1);
11185
11186
    for (i = 0; i < frameCount4; ++i) {
11187
        uint32x4_t side;
11188
        uint32x4_t right;
11189
        uint32x4_t left;
11190
        float32x4_t leftf;
11191
        float32x4_t rightf;
11192
11193
        side   = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4);
11194
        right  = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4);
11195
        left   = vaddq_u32(right, side);
11196
        leftf  = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(left)),  factor4);
11197
        rightf = vmulq_f32(vcvtq_f32_s32(vreinterpretq_s32_u32(right)), factor4);
11198
11199
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11200
    }
11201
11202
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11203
        drflac_uint32 side  = pInputSamples0U32[i] << shift0;
11204
        drflac_uint32 right = pInputSamples1U32[i] << shift1;
11205
        drflac_uint32 left  = right + side;
11206
11207
        pOutputSamples[i*2+0] = (drflac_int32)left  / 8388608.0f;
11208
        pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
11209
    }
11210
}
11211
#endif
11212
11213
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)
11214
0
{
11215
0
#if defined(DRFLAC_SUPPORT_SSE2)
11216
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11217
0
        drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11218
0
    } else
11219
#elif defined(DRFLAC_SUPPORT_NEON)
11220
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11221
        drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11222
    } else
11223
#endif
11224
0
    {
11225
        /* Scalar fallback. */
11226
#if 0
11227
        drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11228
#else
11229
0
        drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11230
0
#endif
11231
0
    }
11232
0
}
11233
11234
11235
#if 0
11236
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11237
{
11238
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
11239
        drflac_uint32 mid  = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11240
        drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11241
11242
        mid = (mid << 1) | (side & 0x01);
11243
11244
        pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
11245
        pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
11246
    }
11247
}
11248
#endif
11249
11250
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)
11251
0
{
11252
0
    drflac_uint64 i;
11253
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11254
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11255
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11256
0
    drflac_uint32 shift = unusedBitsPerSample;
11257
0
    float factor = 1 / 2147483648.0;
11258
11259
0
    if (shift > 0) {
11260
0
        shift -= 1;
11261
0
        for (i = 0; i < frameCount4; ++i) {
11262
0
            drflac_uint32 temp0L;
11263
0
            drflac_uint32 temp1L;
11264
0
            drflac_uint32 temp2L;
11265
0
            drflac_uint32 temp3L;
11266
0
            drflac_uint32 temp0R;
11267
0
            drflac_uint32 temp1R;
11268
0
            drflac_uint32 temp2R;
11269
0
            drflac_uint32 temp3R;
11270
11271
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11272
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11273
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11274
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11275
11276
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11277
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11278
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11279
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11280
11281
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
11282
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
11283
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
11284
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
11285
11286
0
            temp0L = (mid0 + side0) << shift;
11287
0
            temp1L = (mid1 + side1) << shift;
11288
0
            temp2L = (mid2 + side2) << shift;
11289
0
            temp3L = (mid3 + side3) << shift;
11290
11291
0
            temp0R = (mid0 - side0) << shift;
11292
0
            temp1R = (mid1 - side1) << shift;
11293
0
            temp2R = (mid2 - side2) << shift;
11294
0
            temp3R = (mid3 - side3) << shift;
11295
11296
0
            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
11297
0
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
11298
0
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
11299
0
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
11300
0
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
11301
0
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
11302
0
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
11303
0
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
11304
0
        }
11305
0
    } else {
11306
0
        for (i = 0; i < frameCount4; ++i) {
11307
0
            drflac_uint32 temp0L;
11308
0
            drflac_uint32 temp1L;
11309
0
            drflac_uint32 temp2L;
11310
0
            drflac_uint32 temp3L;
11311
0
            drflac_uint32 temp0R;
11312
0
            drflac_uint32 temp1R;
11313
0
            drflac_uint32 temp2R;
11314
0
            drflac_uint32 temp3R;
11315
11316
0
            drflac_uint32 mid0  = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11317
0
            drflac_uint32 mid1  = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11318
0
            drflac_uint32 mid2  = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11319
0
            drflac_uint32 mid3  = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11320
11321
0
            drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11322
0
            drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11323
0
            drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11324
0
            drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11325
11326
0
            mid0 = (mid0 << 1) | (side0 & 0x01);
11327
0
            mid1 = (mid1 << 1) | (side1 & 0x01);
11328
0
            mid2 = (mid2 << 1) | (side2 & 0x01);
11329
0
            mid3 = (mid3 << 1) | (side3 & 0x01);
11330
11331
0
            temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
11332
0
            temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
11333
0
            temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
11334
0
            temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
11335
11336
0
            temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
11337
0
            temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
11338
0
            temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
11339
0
            temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
11340
11341
0
            pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
11342
0
            pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
11343
0
            pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
11344
0
            pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
11345
0
            pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
11346
0
            pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
11347
0
            pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
11348
0
            pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
11349
0
        }
11350
0
    }
11351
11352
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11353
0
        drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11354
0
        drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11355
11356
0
        mid = (mid << 1) | (side & 0x01);
11357
11358
0
        pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
11359
0
        pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
11360
0
    }
11361
0
}
11362
11363
#if defined(DRFLAC_SUPPORT_SSE2)
11364
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11365
0
{
11366
0
    drflac_uint64 i;
11367
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11368
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11369
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11370
0
    drflac_uint32 shift = unusedBitsPerSample - 8;
11371
0
    float factor;
11372
0
    __m128 factor128;
11373
11374
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11375
11376
0
    factor = 1.0f / 8388608.0f;
11377
0
    factor128 = _mm_set1_ps(factor);
11378
11379
0
    if (shift == 0) {
11380
0
        for (i = 0; i < frameCount4; ++i) {
11381
0
            __m128i mid;
11382
0
            __m128i side;
11383
0
            __m128i tempL;
11384
0
            __m128i tempR;
11385
0
            __m128  leftf;
11386
0
            __m128  rightf;
11387
11388
0
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11389
0
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11390
11391
0
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
11392
11393
0
            tempL  = _mm_srai_epi32(_mm_add_epi32(mid, side), 1);
11394
0
            tempR  = _mm_srai_epi32(_mm_sub_epi32(mid, side), 1);
11395
11396
0
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
11397
0
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
11398
11399
0
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11400
0
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11401
0
        }
11402
11403
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
11404
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11405
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11406
11407
0
            mid = (mid << 1) | (side & 0x01);
11408
11409
0
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
11410
0
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
11411
0
        }
11412
0
    } else {
11413
0
        shift -= 1;
11414
0
        for (i = 0; i < frameCount4; ++i) {
11415
0
            __m128i mid;
11416
0
            __m128i side;
11417
0
            __m128i tempL;
11418
0
            __m128i tempR;
11419
0
            __m128 leftf;
11420
0
            __m128 rightf;
11421
11422
0
            mid    = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11423
0
            side   = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11424
11425
0
            mid    = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01)));
11426
11427
0
            tempL  = _mm_slli_epi32(_mm_add_epi32(mid, side), shift);
11428
0
            tempR  = _mm_slli_epi32(_mm_sub_epi32(mid, side), shift);
11429
11430
0
            leftf  = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128);
11431
0
            rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128);
11432
11433
0
            _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11434
0
            _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11435
0
        }
11436
11437
0
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
11438
0
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11439
0
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11440
11441
0
            mid = (mid << 1) | (side & 0x01);
11442
11443
0
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
11444
0
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
11445
0
        }
11446
0
    }
11447
0
}
11448
#endif
11449
11450
#if defined(DRFLAC_SUPPORT_NEON)
11451
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11452
{
11453
    drflac_uint64 i;
11454
    drflac_uint64 frameCount4 = frameCount >> 2;
11455
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11456
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11457
    drflac_uint32 shift = unusedBitsPerSample - 8;
11458
    float factor;
11459
    float32x4_t factor4;
11460
    int32x4_t shift4;
11461
    int32x4_t wbps0_4;  /* Wasted Bits Per Sample */
11462
    int32x4_t wbps1_4;  /* Wasted Bits Per Sample */
11463
11464
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
11465
11466
    factor  = 1.0f / 8388608.0f;
11467
    factor4 = vdupq_n_f32(factor);
11468
    wbps0_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
11469
    wbps1_4 = vdupq_n_s32(pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
11470
11471
    if (shift == 0) {
11472
        for (i = 0; i < frameCount4; ++i) {
11473
            int32x4_t lefti;
11474
            int32x4_t righti;
11475
            float32x4_t leftf;
11476
            float32x4_t rightf;
11477
11478
            uint32x4_t mid  = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
11479
            uint32x4_t side = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
11480
11481
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
11482
11483
            lefti  = vshrq_n_s32(vreinterpretq_s32_u32(vaddq_u32(mid, side)), 1);
11484
            righti = vshrq_n_s32(vreinterpretq_s32_u32(vsubq_u32(mid, side)), 1);
11485
11486
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
11487
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11488
11489
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11490
        }
11491
11492
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
11493
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11494
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11495
11496
            mid = (mid << 1) | (side & 0x01);
11497
11498
            pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
11499
            pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
11500
        }
11501
    } else {
11502
        shift -= 1;
11503
        shift4 = vdupq_n_s32(shift);
11504
        for (i = 0; i < frameCount4; ++i) {
11505
            uint32x4_t mid;
11506
            uint32x4_t side;
11507
            int32x4_t lefti;
11508
            int32x4_t righti;
11509
            float32x4_t leftf;
11510
            float32x4_t rightf;
11511
11512
            mid    = vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), wbps0_4);
11513
            side   = vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), wbps1_4);
11514
11515
            mid    = vorrq_u32(vshlq_n_u32(mid, 1), vandq_u32(side, vdupq_n_u32(1)));
11516
11517
            lefti  = vreinterpretq_s32_u32(vshlq_u32(vaddq_u32(mid, side), shift4));
11518
            righti = vreinterpretq_s32_u32(vshlq_u32(vsubq_u32(mid, side), shift4));
11519
11520
            leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
11521
            rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11522
11523
            drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11524
        }
11525
11526
        for (i = (frameCount4 << 2); i < frameCount; ++i) {
11527
            drflac_uint32 mid  = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11528
            drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11529
11530
            mid = (mid << 1) | (side & 0x01);
11531
11532
            pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
11533
            pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
11534
        }
11535
    }
11536
}
11537
#endif
11538
11539
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)
11540
0
{
11541
0
#if defined(DRFLAC_SUPPORT_SSE2)
11542
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11543
0
        drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11544
0
    } else
11545
#elif defined(DRFLAC_SUPPORT_NEON)
11546
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11547
        drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11548
    } else
11549
#endif
11550
0
    {
11551
        /* Scalar fallback. */
11552
#if 0
11553
        drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11554
#else
11555
0
        drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11556
0
#endif
11557
0
    }
11558
0
}
11559
11560
#if 0
11561
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11562
{
11563
    for (drflac_uint64 i = 0; i < frameCount; ++i) {
11564
        pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
11565
        pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
11566
    }
11567
}
11568
#endif
11569
11570
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)
11571
0
{
11572
0
    drflac_uint64 i;
11573
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11574
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11575
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11576
0
    drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
11577
0
    drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
11578
0
    float factor = 1 / 2147483648.0;
11579
11580
0
    for (i = 0; i < frameCount4; ++i) {
11581
0
        drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
11582
0
        drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
11583
0
        drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
11584
0
        drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
11585
11586
0
        drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
11587
0
        drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
11588
0
        drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
11589
0
        drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
11590
11591
0
        pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
11592
0
        pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
11593
0
        pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
11594
0
        pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
11595
0
        pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
11596
0
        pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
11597
0
        pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
11598
0
        pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
11599
0
    }
11600
11601
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11602
0
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11603
0
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11604
0
    }
11605
0
}
11606
11607
#if defined(DRFLAC_SUPPORT_SSE2)
11608
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11609
0
{
11610
0
    drflac_uint64 i;
11611
0
    drflac_uint64 frameCount4 = frameCount >> 2;
11612
0
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11613
0
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11614
0
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11615
0
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11616
11617
0
    float factor = 1.0f / 8388608.0f;
11618
0
    __m128 factor128 = _mm_set1_ps(factor);
11619
11620
0
    for (i = 0; i < frameCount4; ++i) {
11621
0
        __m128i lefti;
11622
0
        __m128i righti;
11623
0
        __m128 leftf;
11624
0
        __m128 rightf;
11625
11626
0
        lefti  = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples0 + i), shift0);
11627
0
        righti = _mm_slli_epi32(_mm_loadu_si128((const __m128i*)pInputSamples1 + i), shift1);
11628
11629
0
        leftf  = _mm_mul_ps(_mm_cvtepi32_ps(lefti),  factor128);
11630
0
        rightf = _mm_mul_ps(_mm_cvtepi32_ps(righti), factor128);
11631
11632
0
        _mm_storeu_ps(pOutputSamples + i*8 + 0, _mm_unpacklo_ps(leftf, rightf));
11633
0
        _mm_storeu_ps(pOutputSamples + i*8 + 4, _mm_unpackhi_ps(leftf, rightf));
11634
0
    }
11635
11636
0
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11637
0
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11638
0
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11639
0
    }
11640
0
}
11641
#endif
11642
11643
#if defined(DRFLAC_SUPPORT_NEON)
11644
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
11645
{
11646
    drflac_uint64 i;
11647
    drflac_uint64 frameCount4 = frameCount >> 2;
11648
    const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
11649
    const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
11650
    drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
11651
    drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
11652
11653
    float factor = 1.0f / 8388608.0f;
11654
    float32x4_t factor4 = vdupq_n_f32(factor);
11655
    int32x4_t shift0_4  = vdupq_n_s32(shift0);
11656
    int32x4_t shift1_4  = vdupq_n_s32(shift1);
11657
11658
    for (i = 0; i < frameCount4; ++i) {
11659
        int32x4_t lefti;
11660
        int32x4_t righti;
11661
        float32x4_t leftf;
11662
        float32x4_t rightf;
11663
11664
        lefti  = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples0U32 + i*4), shift0_4));
11665
        righti = vreinterpretq_s32_u32(vshlq_u32(vld1q_u32(pInputSamples1U32 + i*4), shift1_4));
11666
11667
        leftf  = vmulq_f32(vcvtq_f32_s32(lefti),  factor4);
11668
        rightf = vmulq_f32(vcvtq_f32_s32(righti), factor4);
11669
11670
        drflac__vst2q_f32(pOutputSamples + i*8, vzipq_f32(leftf, rightf));
11671
    }
11672
11673
    for (i = (frameCount4 << 2); i < frameCount; ++i) {
11674
        pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
11675
        pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
11676
    }
11677
}
11678
#endif
11679
11680
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)
11681
0
{
11682
0
#if defined(DRFLAC_SUPPORT_SSE2)
11683
0
    if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
11684
0
        drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11685
0
    } else
11686
#elif defined(DRFLAC_SUPPORT_NEON)
11687
    if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
11688
        drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11689
    } else
11690
#endif
11691
0
    {
11692
        /* Scalar fallback. */
11693
#if 0
11694
        drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11695
#else
11696
0
        drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
11697
0
#endif
11698
0
    }
11699
0
}
11700
11701
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut)
11702
0
{
11703
0
    drflac_uint64 framesRead;
11704
0
    drflac_uint32 unusedBitsPerSample;
11705
11706
0
    if (pFlac == NULL || framesToRead == 0) {
11707
0
        return 0;
11708
0
    }
11709
11710
0
    if (pBufferOut == NULL) {
11711
0
        return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead);
11712
0
    }
11713
11714
0
    DRFLAC_ASSERT(pFlac->bitsPerSample <= 32);
11715
0
    unusedBitsPerSample = 32 - pFlac->bitsPerSample;
11716
11717
0
    framesRead = 0;
11718
0
    while (framesToRead > 0) {
11719
        /* If we've run out of samples in this frame, go to the next. */
11720
0
        if (pFlac->currentFLACFrame.pcmFramesRemaining == 0) {
11721
0
            if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
11722
0
                break;  /* Couldn't read the next frame, so just break from the loop and return. */
11723
0
            }
11724
0
        } else {
11725
0
            unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
11726
0
            drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
11727
0
            drflac_uint64 frameCountThisIteration = framesToRead;
11728
11729
0
            if (frameCountThisIteration > pFlac->currentFLACFrame.pcmFramesRemaining) {
11730
0
                frameCountThisIteration = pFlac->currentFLACFrame.pcmFramesRemaining;
11731
0
            }
11732
11733
0
            if (channelCount == 2) {
11734
0
                const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
11735
0
                const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
11736
11737
0
                switch (pFlac->currentFLACFrame.header.channelAssignment)
11738
0
                {
11739
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
11740
0
                    {
11741
0
                        drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11742
0
                    } break;
11743
11744
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
11745
0
                    {
11746
0
                        drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11747
0
                    } break;
11748
11749
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE:
11750
0
                    {
11751
0
                        drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11752
0
                    } break;
11753
11754
0
                    case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
11755
0
                    default:
11756
0
                    {
11757
0
                        drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
11758
0
                    } break;
11759
0
                }
11760
0
            } else {
11761
                /* Generic interleaving. */
11762
0
                drflac_uint64 i;
11763
0
                for (i = 0; i < frameCountThisIteration; ++i) {
11764
0
                    unsigned int j;
11765
0
                    for (j = 0; j < channelCount; ++j) {
11766
0
                        drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
11767
0
                        pBufferOut[(i*channelCount)+j] = (float)(sampleS32 / 2147483648.0);
11768
0
                    }
11769
0
                }
11770
0
            }
11771
11772
0
            framesRead                += frameCountThisIteration;
11773
0
            pBufferOut                += frameCountThisIteration * channelCount;
11774
0
            framesToRead              -= frameCountThisIteration;
11775
0
            pFlac->currentPCMFrame    += frameCountThisIteration;
11776
0
            pFlac->currentFLACFrame.pcmFramesRemaining -= (unsigned int)frameCountThisIteration;
11777
0
        }
11778
0
    }
11779
11780
0
    return framesRead;
11781
0
}
11782
11783
11784
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
11785
0
{
11786
0
    if (pFlac == NULL) {
11787
0
        return DRFLAC_FALSE;
11788
0
    }
11789
11790
    /* Don't do anything if we're already on the seek point. */
11791
0
    if (pFlac->currentPCMFrame == pcmFrameIndex) {
11792
0
        return DRFLAC_TRUE;
11793
0
    }
11794
11795
    /*
11796
    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
11797
    when the decoder was opened.
11798
    */
11799
0
    if (pFlac->firstFLACFramePosInBytes == 0) {
11800
0
        return DRFLAC_FALSE;
11801
0
    }
11802
11803
0
    if (pcmFrameIndex == 0) {
11804
0
        pFlac->currentPCMFrame = 0;
11805
0
        return drflac__seek_to_first_frame(pFlac);
11806
0
    } else {
11807
0
        drflac_bool32 wasSuccessful = DRFLAC_FALSE;
11808
0
        drflac_uint64 originalPCMFrame = pFlac->currentPCMFrame;
11809
11810
        /* Clamp the sample to the end. */
11811
0
        if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
11812
0
            pcmFrameIndex = pFlac->totalPCMFrameCount;
11813
0
        }
11814
11815
        /* If the target sample and the current sample are in the same frame we just move the position forward. */
11816
0
        if (drflac__is_current_flac_frame_valid(pFlac)) {
11817
0
            if (pcmFrameIndex > pFlac->currentPCMFrame) {
11818
                /* Forward. */
11819
0
                drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex - pFlac->currentPCMFrame);
11820
0
                if (pFlac->currentFLACFrame.pcmFramesRemaining > offset) {
11821
0
                    pFlac->currentFLACFrame.pcmFramesRemaining -= offset;
11822
0
                    pFlac->currentPCMFrame = pcmFrameIndex;
11823
0
                    return DRFLAC_TRUE;
11824
0
                }
11825
0
            } else {
11826
                /* Backward. */
11827
0
                drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentPCMFrame - pcmFrameIndex);
11828
0
                drflac_uint32 currentFLACFramePCMFrameCount = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
11829
0
                drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
11830
0
                if (currentFLACFramePCMFramesConsumed > offsetAbs) {
11831
0
                    pFlac->currentFLACFrame.pcmFramesRemaining += offsetAbs;
11832
0
                    pFlac->currentPCMFrame = pcmFrameIndex;
11833
0
                    return DRFLAC_TRUE;
11834
0
                }
11835
0
            }
11836
0
        }
11837
11838
        /*
11839
        Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
11840
        we'll instead use Ogg's natural seeking facility.
11841
        */
11842
0
#ifndef DR_FLAC_NO_OGG
11843
0
        if (pFlac->container == drflac_container_ogg)
11844
0
        {
11845
0
            wasSuccessful = drflac_ogg__seek_to_pcm_frame(pFlac, pcmFrameIndex);
11846
0
        }
11847
0
        else
11848
0
#endif
11849
0
        {
11850
            /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */
11851
0
            if (/*!wasSuccessful && */!pFlac->_noSeekTableSeek) {
11852
0
                wasSuccessful = drflac__seek_to_pcm_frame__seek_table(pFlac, pcmFrameIndex);
11853
0
            }
11854
11855
0
#if !defined(DR_FLAC_NO_CRC)
11856
            /* Fall back to binary search if seek table seeking fails. This requires the length of the stream to be known. */
11857
0
            if (!wasSuccessful && !pFlac->_noBinarySearchSeek && pFlac->totalPCMFrameCount > 0) {
11858
0
                wasSuccessful = drflac__seek_to_pcm_frame__binary_search(pFlac, pcmFrameIndex);
11859
0
            }
11860
0
#endif
11861
11862
            /* Fall back to brute force if all else fails. */
11863
0
            if (!wasSuccessful && !pFlac->_noBruteForceSeek) {
11864
0
                wasSuccessful = drflac__seek_to_pcm_frame__brute_force(pFlac, pcmFrameIndex);
11865
0
            }
11866
0
        }
11867
11868
0
        if (wasSuccessful) {
11869
0
            pFlac->currentPCMFrame = pcmFrameIndex;
11870
0
        } else {
11871
            /* Seek failed. Try putting the decoder back to it's original state. */
11872
0
            if (drflac_seek_to_pcm_frame(pFlac, originalPCMFrame) == DRFLAC_FALSE) {
11873
                /* Failed to seek back to the original PCM frame. Fall back to 0. */
11874
0
                drflac_seek_to_pcm_frame(pFlac, 0);
11875
0
            }
11876
0
        }
11877
11878
0
        return wasSuccessful;
11879
0
    }
11880
0
}
11881
11882
11883
11884
/* High Level APIs */
11885
11886
/* SIZE_MAX */
11887
#if defined(SIZE_MAX)
11888
    #define DRFLAC_SIZE_MAX  SIZE_MAX
11889
#else
11890
    #if defined(DRFLAC_64BIT)
11891
        #define DRFLAC_SIZE_MAX  ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
11892
    #else
11893
        #define DRFLAC_SIZE_MAX  0xFFFFFFFF
11894
    #endif
11895
#endif
11896
/* End SIZE_MAX */
11897
11898
11899
/* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */
11900
#define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \
11901
0
static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut)\
11902
0
{                                                                                                                                                                   \
11903
0
    type* pSampleData = NULL;                                                                                                                                       \
11904
0
    drflac_uint64 totalPCMFrameCount;                                                                                                                               \
11905
0
    type buffer[4096];                                                                                                                                              \
11906
0
    drflac_uint64 pcmFramesRead;                                                                                                                                    \
11907
0
    size_t sampleDataBufferSize = sizeof(buffer);                                                                                                                   \
11908
0
                                                                                                                                                                    \
11909
0
    DRFLAC_ASSERT(pFlac != NULL);                                                                                                                                   \
11910
0
                                                                                                                                                                    \
11911
0
    totalPCMFrameCount = 0;                                                                                                                                         \
11912
0
                                                                                                                                                                    \
11913
0
    pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks);                                                          \
11914
0
    if (pSampleData == NULL) {                                                                                                                                      \
11915
0
        goto on_error;                                                                                                                                              \
11916
0
    }                                                                                                                                                               \
11917
0
                                                                                                                                                                    \
11918
0
    while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) {              \
11919
0
        if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) {                                                       \
11920
0
            type* pNewSampleData;                                                                                                                                   \
11921
0
            size_t newSampleDataBufferSize;                                                                                                                         \
11922
0
                                                                                                                                                                    \
11923
0
            newSampleDataBufferSize = sampleDataBufferSize * 2;                                                                                                     \
11924
0
            pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks);        \
11925
0
            if (pNewSampleData == NULL) {                                                                                                                           \
11926
0
                drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks);                                                                              \
11927
0
                goto on_error;                                                                                                                                      \
11928
0
            }                                                                                                                                                       \
11929
0
                                                                                                                                                                    \
11930
0
            sampleDataBufferSize = newSampleDataBufferSize;                                                                                                         \
11931
0
            pSampleData = pNewSampleData;                                                                                                                           \
11932
0
        }                                                                                                                                                           \
11933
0
                                                                                                                                                                    \
11934
0
        DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type)));                       \
11935
0
        totalPCMFrameCount += pcmFramesRead;                                                                                                                        \
11936
0
    }                                                                                                                                                               \
11937
0
                                                                                                                                                                    \
11938
0
    /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to                                           \
11939
0
       protect those ears from random noise! */                                                                                                                     \
11940
0
    DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type)));       \
11941
0
                                                                                                                                                                    \
11942
0
    if (sampleRateOut) *sampleRateOut = pFlac->sampleRate;                                                                                                          \
11943
0
    if (channelsOut) *channelsOut = pFlac->channels;                                                                                                                \
11944
0
    if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount;                                                                                         \
11945
0
                                                                                                                                                                    \
11946
0
    drflac_close(pFlac);                                                                                                                                            \
11947
0
    return pSampleData;                                                                                                                                             \
11948
0
                                                                                                                                                                    \
11949
0
on_error:                                                                                                                                                           \
11950
0
    drflac_close(pFlac);                                                                                                                                            \
11951
0
    return NULL;                                                                                                                                                    \
11952
0
}
11953
11954
0
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
11955
0
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
11956
0
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
11957
11958
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
11959
0
{
11960
0
    drflac* pFlac;
11961
11962
0
    if (channelsOut) {
11963
0
        *channelsOut = 0;
11964
0
    }
11965
0
    if (sampleRateOut) {
11966
0
        *sampleRateOut = 0;
11967
0
    }
11968
0
    if (totalPCMFrameCountOut) {
11969
0
        *totalPCMFrameCountOut = 0;
11970
0
    }
11971
11972
0
    pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
11973
0
    if (pFlac == NULL) {
11974
0
        return NULL;
11975
0
    }
11976
11977
0
    return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
11978
0
}
11979
11980
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
11981
0
{
11982
0
    drflac* pFlac;
11983
11984
0
    if (channelsOut) {
11985
0
        *channelsOut = 0;
11986
0
    }
11987
0
    if (sampleRateOut) {
11988
0
        *sampleRateOut = 0;
11989
0
    }
11990
0
    if (totalPCMFrameCountOut) {
11991
0
        *totalPCMFrameCountOut = 0;
11992
0
    }
11993
11994
0
    pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
11995
0
    if (pFlac == NULL) {
11996
0
        return NULL;
11997
0
    }
11998
11999
0
    return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
12000
0
}
12001
12002
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
12003
0
{
12004
0
    drflac* pFlac;
12005
12006
0
    if (channelsOut) {
12007
0
        *channelsOut = 0;
12008
0
    }
12009
0
    if (sampleRateOut) {
12010
0
        *sampleRateOut = 0;
12011
0
    }
12012
0
    if (totalPCMFrameCountOut) {
12013
0
        *totalPCMFrameCountOut = 0;
12014
0
    }
12015
12016
0
    pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
12017
0
    if (pFlac == NULL) {
12018
0
        return NULL;
12019
0
    }
12020
12021
0
    return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
12022
0
}
12023
12024
#ifndef DR_FLAC_NO_STDIO
12025
DRFLAC_API 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)
12026
0
{
12027
0
    drflac* pFlac;
12028
12029
0
    if (sampleRate) {
12030
0
        *sampleRate = 0;
12031
0
    }
12032
0
    if (channels) {
12033
0
        *channels = 0;
12034
0
    }
12035
0
    if (totalPCMFrameCount) {
12036
0
        *totalPCMFrameCount = 0;
12037
0
    }
12038
12039
0
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
12040
0
    if (pFlac == NULL) {
12041
0
        return NULL;
12042
0
    }
12043
12044
0
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
12045
0
}
12046
12047
DRFLAC_API 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)
12048
0
{
12049
0
    drflac* pFlac;
12050
12051
0
    if (sampleRate) {
12052
0
        *sampleRate = 0;
12053
0
    }
12054
0
    if (channels) {
12055
0
        *channels = 0;
12056
0
    }
12057
0
    if (totalPCMFrameCount) {
12058
0
        *totalPCMFrameCount = 0;
12059
0
    }
12060
12061
0
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
12062
0
    if (pFlac == NULL) {
12063
0
        return NULL;
12064
0
    }
12065
12066
0
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
12067
0
}
12068
12069
DRFLAC_API 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)
12070
0
{
12071
0
    drflac* pFlac;
12072
12073
0
    if (sampleRate) {
12074
0
        *sampleRate = 0;
12075
0
    }
12076
0
    if (channels) {
12077
0
        *channels = 0;
12078
0
    }
12079
0
    if (totalPCMFrameCount) {
12080
0
        *totalPCMFrameCount = 0;
12081
0
    }
12082
12083
0
    pFlac = drflac_open_file(filename, pAllocationCallbacks);
12084
0
    if (pFlac == NULL) {
12085
0
        return NULL;
12086
0
    }
12087
12088
0
    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
12089
0
}
12090
#endif
12091
12092
DRFLAC_API 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)
12093
0
{
12094
0
    drflac* pFlac;
12095
12096
0
    if (sampleRate) {
12097
0
        *sampleRate = 0;
12098
0
    }
12099
0
    if (channels) {
12100
0
        *channels = 0;
12101
0
    }
12102
0
    if (totalPCMFrameCount) {
12103
0
        *totalPCMFrameCount = 0;
12104
0
    }
12105
12106
0
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
12107
0
    if (pFlac == NULL) {
12108
0
        return NULL;
12109
0
    }
12110
12111
0
    return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
12112
0
}
12113
12114
DRFLAC_API 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)
12115
0
{
12116
0
    drflac* pFlac;
12117
12118
0
    if (sampleRate) {
12119
0
        *sampleRate = 0;
12120
0
    }
12121
0
    if (channels) {
12122
0
        *channels = 0;
12123
0
    }
12124
0
    if (totalPCMFrameCount) {
12125
0
        *totalPCMFrameCount = 0;
12126
0
    }
12127
12128
0
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
12129
0
    if (pFlac == NULL) {
12130
0
        return NULL;
12131
0
    }
12132
12133
0
    return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
12134
0
}
12135
12136
DRFLAC_API 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)
12137
0
{
12138
0
    drflac* pFlac;
12139
12140
0
    if (sampleRate) {
12141
0
        *sampleRate = 0;
12142
0
    }
12143
0
    if (channels) {
12144
0
        *channels = 0;
12145
0
    }
12146
0
    if (totalPCMFrameCount) {
12147
0
        *totalPCMFrameCount = 0;
12148
0
    }
12149
12150
0
    pFlac = drflac_open_memory(data, dataSize, pAllocationCallbacks);
12151
0
    if (pFlac == NULL) {
12152
0
        return NULL;
12153
0
    }
12154
12155
0
    return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
12156
0
}
12157
12158
12159
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks)
12160
0
{
12161
0
    if (pAllocationCallbacks != NULL) {
12162
0
        drflac__free_from_callbacks(p, pAllocationCallbacks);
12163
0
    } else {
12164
0
        drflac__free_default(p, NULL);
12165
0
    }
12166
0
}
12167
12168
12169
12170
12171
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments)
12172
0
{
12173
0
    if (pIter == NULL) {
12174
0
        return;
12175
0
    }
12176
12177
0
    pIter->countRemaining = commentCount;
12178
0
    pIter->pRunningData   = (const char*)pComments;
12179
0
}
12180
12181
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
12182
0
{
12183
0
    drflac_int32 length;
12184
0
    const char* pComment;
12185
12186
    /* Safety. */
12187
0
    if (pCommentLengthOut) {
12188
0
        *pCommentLengthOut = 0;
12189
0
    }
12190
12191
0
    if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
12192
0
        return NULL;
12193
0
    }
12194
12195
0
    length = drflac__le2host_32_ptr_unaligned(pIter->pRunningData);
12196
0
    pIter->pRunningData += 4;
12197
12198
0
    pComment = pIter->pRunningData;
12199
0
    pIter->pRunningData += length;
12200
0
    pIter->countRemaining -= 1;
12201
12202
0
    if (pCommentLengthOut) {
12203
0
        *pCommentLengthOut = length;
12204
0
    }
12205
12206
0
    return pComment;
12207
0
}
12208
12209
12210
12211
12212
DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData)
12213
0
{
12214
0
    if (pIter == NULL) {
12215
0
        return;
12216
0
    }
12217
12218
0
    pIter->countRemaining = trackCount;
12219
0
    pIter->pRunningData   = (const char*)pTrackData;
12220
0
}
12221
12222
DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack)
12223
0
{
12224
0
    drflac_cuesheet_track cuesheetTrack;
12225
0
    const char* pRunningData;
12226
0
    drflac_uint64 offsetHi;
12227
0
    drflac_uint64 offsetLo;
12228
12229
0
    if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
12230
0
        return DRFLAC_FALSE;
12231
0
    }
12232
12233
0
    pRunningData = pIter->pRunningData;
12234
12235
0
    offsetHi                   = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
12236
0
    offsetLo                   = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
12237
0
    cuesheetTrack.offset       = offsetLo | (offsetHi << 32);
12238
0
    cuesheetTrack.trackNumber  = pRunningData[0];                                         pRunningData += 1;
12239
0
    DRFLAC_COPY_MEMORY(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC));     pRunningData += 12;
12240
0
    cuesheetTrack.isAudio      = (pRunningData[0] & 0x80) != 0;
12241
0
    cuesheetTrack.preEmphasis  = (pRunningData[0] & 0x40) != 0;                           pRunningData += 14;
12242
0
    cuesheetTrack.indexCount   = pRunningData[0];                                         pRunningData += 1;
12243
0
    cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData;        pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index);
12244
12245
0
    pIter->pRunningData = pRunningData;
12246
0
    pIter->countRemaining -= 1;
12247
12248
0
    if (pCuesheetTrack) {
12249
0
        *pCuesheetTrack = cuesheetTrack;
12250
0
    }
12251
12252
0
    return DRFLAC_TRUE;
12253
0
}
12254
12255
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
12256
    #pragma GCC diagnostic pop
12257
#endif
12258
#endif  /* dr_flac_c */
12259
#endif  /* DR_FLAC_IMPLEMENTATION */
12260
12261
12262
/*
12263
REVISION HISTORY
12264
================
12265
v0.13.4 - TBD
12266
  - Add a bounds check when allocating memory during metadata processing.
12267
  - Fix a possible overflow error when parsing picture metadata.
12268
  - Fix an error with seek point parsing.
12269
  - Fix a possible deadlock when seeking.
12270
  - Fix an error where the decoder can be put into a bad state when seeking fails which then results in a crash when reading and seeking.
12271
12272
v0.13.3 - 2026-01-17
12273
  - Fix a compiler compatibility issue with some inlined assembly.
12274
  - Fix a compilation warning.
12275
12276
v0.13.2 - 2025-12-02
12277
  - Improve robustness of the parsing of picture metadata to improve support for memory constrained embedded devices.
12278
  - Fix a warning about an assigned by unused variable.
12279
  - Improvements to drflac_open_and_read_pcm_frames_*() and family to avoid excessively large memory allocations from malformed files.
12280
12281
v0.13.1 - 2025-09-10
12282
  - Fix an error with the NXDK build.
12283
12284
v0.13.0 - 2025-07-23
12285
  - API CHANGE: Seek origin enums have been renamed to match the naming convention used by other dr_libs libraries:
12286
    - drflac_seek_origin_start   -> DRFLAC_SEEK_SET
12287
    - drflac_seek_origin_current -> DRFLAC_SEEK_CUR
12288
    - DRFLAC_SEEK_END (new)
12289
  - API CHANGE: A new seek origin has been added to allow seeking from the end of the file. If you implement your own `onSeek` callback, you should now detect and handle `DRFLAC_SEEK_END`. If seeking to the end is not supported, return `DRFLAC_FALSE`. If you only use `*_open_file()` or `*_open_memory()`, you need not change anything.
12290
  - API CHANGE: An `onTell` callback has been added to the following functions:
12291
    - drflac_open()
12292
    - drflac_open_relaxed()
12293
    - drflac_open_with_metadata()
12294
    - drflac_open_with_metadata_relaxed()
12295
    - drflac_open_and_read_pcm_frames_s32()
12296
    - drflac_open_and_read_pcm_frames_s16()
12297
    - drflac_open_and_read_pcm_frames_f32()
12298
  - Fix compilation for AIX OS.
12299
12300
v0.12.43 - 2024-12-17
12301
  - Fix a possible buffer overflow during decoding.
12302
  - Improve detection of ARM64EC
12303
12304
v0.12.42 - 2023-11-02
12305
  - Fix build for ARMv6-M.
12306
  - Fix a compilation warning with GCC.
12307
12308
v0.12.41 - 2023-06-17
12309
  - Fix an incorrect date in revision history. No functional change.
12310
12311
v0.12.40 - 2023-05-22
12312
  - Minor code restructure. No functional change.
12313
12314
v0.12.39 - 2022-09-17
12315
  - Fix compilation with DJGPP.
12316
  - Fix compilation error with Visual Studio 2019 and the ARM build.
12317
  - Fix an error with SSE 4.1 detection.
12318
  - Add support for disabling wchar_t with DR_WAV_NO_WCHAR.
12319
  - Improve compatibility with compilers which lack support for explicit struct packing.
12320
  - Improve compatibility with low-end and embedded hardware by reducing the amount of stack
12321
    allocation when loading an Ogg encapsulated file.
12322
12323
v0.12.38 - 2022-04-10
12324
  - Fix compilation error on older versions of GCC.
12325
12326
v0.12.37 - 2022-02-12
12327
  - Improve ARM detection.
12328
12329
v0.12.36 - 2022-02-07
12330
  - Fix a compilation error with the ARM build.
12331
12332
v0.12.35 - 2022-02-06
12333
  - Fix a bug due to underestimating the amount of precision required for the prediction stage.
12334
  - Fix some bugs found from fuzz testing.
12335
12336
v0.12.34 - 2022-01-07
12337
  - Fix some misalignment bugs when reading metadata.
12338
12339
v0.12.33 - 2021-12-22
12340
  - Fix a bug with seeking when the seek table does not start at PCM frame 0.
12341
12342
v0.12.32 - 2021-12-11
12343
  - Fix a warning with Clang.
12344
12345
v0.12.31 - 2021-08-16
12346
  - Silence some warnings.
12347
12348
v0.12.30 - 2021-07-31
12349
  - Fix platform detection for ARM64.
12350
12351
v0.12.29 - 2021-04-02
12352
  - Fix a bug where the running PCM frame index is set to an invalid value when over-seeking.
12353
  - Fix a decoding error due to an incorrect validation check.
12354
12355
v0.12.28 - 2021-02-21
12356
  - Fix a warning due to referencing _MSC_VER when it is undefined.
12357
12358
v0.12.27 - 2021-01-31
12359
  - Fix a static analysis warning.
12360
12361
v0.12.26 - 2021-01-17
12362
  - Fix a compilation warning due to _BSD_SOURCE being deprecated.
12363
12364
v0.12.25 - 2020-12-26
12365
  - Update documentation.
12366
12367
v0.12.24 - 2020-11-29
12368
  - Fix ARM64/NEON detection when compiling with MSVC.
12369
12370
v0.12.23 - 2020-11-21
12371
  - Fix compilation with OpenWatcom.
12372
12373
v0.12.22 - 2020-11-01
12374
  - Fix an error with the previous release.
12375
12376
v0.12.21 - 2020-11-01
12377
  - Fix a possible deadlock when seeking.
12378
  - Improve compiler support for older versions of GCC.
12379
12380
v0.12.20 - 2020-09-08
12381
  - Fix a compilation error on older compilers.
12382
12383
v0.12.19 - 2020-08-30
12384
  - Fix a bug due to an undefined 32-bit shift.
12385
12386
v0.12.18 - 2020-08-14
12387
  - Fix a crash when compiling with clang-cl.
12388
12389
v0.12.17 - 2020-08-02
12390
  - Simplify sized types.
12391
12392
v0.12.16 - 2020-07-25
12393
  - Fix a compilation warning.
12394
12395
v0.12.15 - 2020-07-06
12396
  - Check for negative LPC shifts and return an error.
12397
12398
v0.12.14 - 2020-06-23
12399
  - Add include guard for the implementation section.
12400
12401
v0.12.13 - 2020-05-16
12402
  - Add compile-time and run-time version querying.
12403
    - DRFLAC_VERSION_MINOR
12404
    - DRFLAC_VERSION_MAJOR
12405
    - DRFLAC_VERSION_REVISION
12406
    - DRFLAC_VERSION_STRING
12407
    - drflac_version()
12408
    - drflac_version_string()
12409
12410
v0.12.12 - 2020-04-30
12411
  - Fix compilation errors with VC6.
12412
12413
v0.12.11 - 2020-04-19
12414
  - Fix some pedantic warnings.
12415
  - Fix some undefined behaviour warnings.
12416
12417
v0.12.10 - 2020-04-10
12418
  - Fix some bugs when trying to seek with an invalid seek table.
12419
12420
v0.12.9 - 2020-04-05
12421
  - Fix warnings.
12422
12423
v0.12.8 - 2020-04-04
12424
  - Add drflac_open_file_w() and drflac_open_file_with_metadata_w().
12425
  - Fix some static analysis warnings.
12426
  - Minor documentation updates.
12427
12428
v0.12.7 - 2020-03-14
12429
  - Fix compilation errors with VC6.
12430
12431
v0.12.6 - 2020-03-07
12432
  - Fix compilation error with Visual Studio .NET 2003.
12433
12434
v0.12.5 - 2020-01-30
12435
  - Silence some static analysis warnings.
12436
12437
v0.12.4 - 2020-01-29
12438
  - Silence some static analysis warnings.
12439
12440
v0.12.3 - 2019-12-02
12441
  - Fix some warnings when compiling with GCC and the -Og flag.
12442
  - Fix a crash in out-of-memory situations.
12443
  - Fix potential integer overflow bug.
12444
  - Fix some static analysis warnings.
12445
  - Fix a possible crash when using custom memory allocators without a custom realloc() implementation.
12446
  - Fix a bug with binary search seeking where the bits per sample is not a multiple of 8.
12447
12448
v0.12.2 - 2019-10-07
12449
  - Internal code clean up.
12450
12451
v0.12.1 - 2019-09-29
12452
  - Fix some Clang Static Analyzer warnings.
12453
  - Fix an unused variable warning.
12454
12455
v0.12.0 - 2019-09-23
12456
  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
12457
    routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
12458
    - drflac_open()
12459
    - drflac_open_relaxed()
12460
    - drflac_open_with_metadata()
12461
    - drflac_open_with_metadata_relaxed()
12462
    - drflac_open_file()
12463
    - drflac_open_file_with_metadata()
12464
    - drflac_open_memory()
12465
    - drflac_open_memory_with_metadata()
12466
    - drflac_open_and_read_pcm_frames_s32()
12467
    - drflac_open_and_read_pcm_frames_s16()
12468
    - drflac_open_and_read_pcm_frames_f32()
12469
    - drflac_open_file_and_read_pcm_frames_s32()
12470
    - drflac_open_file_and_read_pcm_frames_s16()
12471
    - drflac_open_file_and_read_pcm_frames_f32()
12472
    - drflac_open_memory_and_read_pcm_frames_s32()
12473
    - drflac_open_memory_and_read_pcm_frames_s16()
12474
    - drflac_open_memory_and_read_pcm_frames_f32()
12475
    Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
12476
    DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE.
12477
  - Remove deprecated APIs:
12478
    - drflac_read_s32()
12479
    - drflac_read_s16()
12480
    - drflac_read_f32()
12481
    - drflac_seek_to_sample()
12482
    - drflac_open_and_decode_s32()
12483
    - drflac_open_and_decode_s16()
12484
    - drflac_open_and_decode_f32()
12485
    - drflac_open_and_decode_file_s32()
12486
    - drflac_open_and_decode_file_s16()
12487
    - drflac_open_and_decode_file_f32()
12488
    - drflac_open_and_decode_memory_s32()
12489
    - drflac_open_and_decode_memory_s16()
12490
    - drflac_open_and_decode_memory_f32()
12491
  - Remove drflac.totalSampleCount which is now replaced with drflac.totalPCMFrameCount. You can emulate drflac.totalSampleCount
12492
    by doing pFlac->totalPCMFrameCount*pFlac->channels.
12493
  - Rename drflac.currentFrame to drflac.currentFLACFrame to remove ambiguity with PCM frames.
12494
  - Fix errors when seeking to the end of a stream.
12495
  - Optimizations to seeking.
12496
  - SSE improvements and optimizations.
12497
  - ARM NEON optimizations.
12498
  - Optimizations to drflac_read_pcm_frames_s16().
12499
  - Optimizations to drflac_read_pcm_frames_s32().
12500
12501
v0.11.10 - 2019-06-26
12502
  - Fix a compiler error.
12503
12504
v0.11.9 - 2019-06-16
12505
  - Silence some ThreadSanitizer warnings.
12506
12507
v0.11.8 - 2019-05-21
12508
  - Fix warnings.
12509
12510
v0.11.7 - 2019-05-06
12511
  - C89 fixes.
12512
12513
v0.11.6 - 2019-05-05
12514
  - Add support for C89.
12515
  - Fix a compiler warning when CRC is disabled.
12516
  - Change license to choice of public domain or MIT-0.
12517
12518
v0.11.5 - 2019-04-19
12519
  - Fix a compiler error with GCC.
12520
12521
v0.11.4 - 2019-04-17
12522
  - Fix some warnings with GCC when compiling with -std=c99.
12523
12524
v0.11.3 - 2019-04-07
12525
  - Silence warnings with GCC.
12526
12527
v0.11.2 - 2019-03-10
12528
  - Fix a warning.
12529
12530
v0.11.1 - 2019-02-17
12531
  - Fix a potential bug with seeking.
12532
12533
v0.11.0 - 2018-12-16
12534
  - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with
12535
    drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take
12536
    and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by
12537
    dividing it by the channel count, and then do the same with the return value.
12538
  - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as
12539
    the changes to drflac_read_*() apply.
12540
  - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as
12541
    the changes to drflac_read_*() apply.
12542
  - Optimizations.
12543
12544
v0.10.0 - 2018-09-11
12545
  - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
12546
    need to do it yourself via the callback API.
12547
  - Fix the clang build.
12548
  - Fix undefined behavior.
12549
  - Fix errors with CUESHEET metdata blocks.
12550
  - Add an API for iterating over each cuesheet track in the CUESHEET metadata block. This works the same way as the
12551
    Vorbis comment API.
12552
  - Other miscellaneous bug fixes, mostly relating to invalid FLAC streams.
12553
  - Minor optimizations.
12554
12555
v0.9.11 - 2018-08-29
12556
  - Fix a bug with sample reconstruction.
12557
12558
v0.9.10 - 2018-08-07
12559
  - Improve 64-bit detection.
12560
12561
v0.9.9 - 2018-08-05
12562
  - Fix C++ build on older versions of GCC.
12563
12564
v0.9.8 - 2018-07-24
12565
  - Fix compilation errors.
12566
12567
v0.9.7 - 2018-07-05
12568
  - Fix a warning.
12569
12570
v0.9.6 - 2018-06-29
12571
  - Fix some typos.
12572
12573
v0.9.5 - 2018-06-23
12574
  - Fix some warnings.
12575
12576
v0.9.4 - 2018-06-14
12577
  - Optimizations to seeking.
12578
  - Clean up.
12579
12580
v0.9.3 - 2018-05-22
12581
  - Bug fix.
12582
12583
v0.9.2 - 2018-05-12
12584
  - Fix a compilation error due to a missing break statement.
12585
12586
v0.9.1 - 2018-04-29
12587
  - Fix compilation error with Clang.
12588
12589
v0.9 - 2018-04-24
12590
  - Fix Clang build.
12591
  - Start using major.minor.revision versioning.
12592
12593
v0.8g - 2018-04-19
12594
  - Fix build on non-x86/x64 architectures.
12595
12596
v0.8f - 2018-02-02
12597
  - Stop pretending to support changing rate/channels mid stream.
12598
12599
v0.8e - 2018-02-01
12600
  - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
12601
  - Fix a crash the the Rice partition order is invalid.
12602
12603
v0.8d - 2017-09-22
12604
  - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
12605
12606
v0.8c - 2017-09-07
12607
  - Fix warning on non-x86/x64 architectures.
12608
12609
v0.8b - 2017-08-19
12610
  - Fix build on non-x86/x64 architectures.
12611
12612
v0.8a - 2017-08-13
12613
  - A small optimization for the Clang build.
12614
12615
v0.8 - 2017-08-12
12616
  - API CHANGE: Rename dr_* types to drflac_*.
12617
  - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
12618
  - Add support for custom implementations of malloc(), realloc(), etc.
12619
  - Add CRC checking to Ogg encapsulated streams.
12620
  - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
12621
  - Bug fixes.
12622
12623
v0.7 - 2017-07-23
12624
  - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().
12625
12626
v0.6 - 2017-07-22
12627
  - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
12628
    never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.
12629
12630
v0.5 - 2017-07-16
12631
  - Fix typos.
12632
  - Change drflac_bool* types to unsigned.
12633
  - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.
12634
12635
v0.4f - 2017-03-10
12636
  - Fix a couple of bugs with the bitstreaming code.
12637
12638
v0.4e - 2017-02-17
12639
  - Fix some warnings.
12640
12641
v0.4d - 2016-12-26
12642
  - Add support for 32-bit floating-point PCM decoding.
12643
  - Use drflac_int* and drflac_uint* sized types to improve compiler support.
12644
  - Minor improvements to documentation.
12645
12646
v0.4c - 2016-12-26
12647
  - Add support for signed 16-bit integer PCM decoding.
12648
12649
v0.4b - 2016-10-23
12650
  - A minor change to drflac_bool8 and drflac_bool32 types.
12651
12652
v0.4a - 2016-10-11
12653
  - Rename drBool32 to drflac_bool32 for styling consistency.
12654
12655
v0.4 - 2016-09-29
12656
  - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type.
12657
  - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32().
12658
  - API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to
12659
    keep it consistent with drflac_audio.
12660
12661
v0.3f - 2016-09-21
12662
  - Fix a warning with GCC.
12663
12664
v0.3e - 2016-09-18
12665
  - Fixed a bug where GCC 4.3+ was not getting properly identified.
12666
  - Fixed a few typos.
12667
  - Changed date formats to ISO 8601 (YYYY-MM-DD).
12668
12669
v0.3d - 2016-06-11
12670
  - Minor clean up.
12671
12672
v0.3c - 2016-05-28
12673
  - Fixed compilation error.
12674
12675
v0.3b - 2016-05-16
12676
  - Fixed Linux/GCC build.
12677
  - Updated documentation.
12678
12679
v0.3a - 2016-05-15
12680
  - Minor fixes to documentation.
12681
12682
v0.3 - 2016-05-11
12683
  - Optimizations. Now at about parity with the reference implementation on 32-bit builds.
12684
  - Lots of clean up.
12685
12686
v0.2b - 2016-05-10
12687
  - Bug fixes.
12688
12689
v0.2a - 2016-05-10
12690
  - Made drflac_open_and_decode() more robust.
12691
  - Removed an unused debugging variable
12692
12693
v0.2 - 2016-05-09
12694
  - Added support for Ogg encapsulation.
12695
  - API CHANGE. Have the onSeek callback take a third argument which specifies whether or not the seek
12696
    should be relative to the start or the current position. Also changes the seeking rules such that
12697
    seeking offsets will never be negative.
12698
  - Have drflac_open_and_decode() fail gracefully if the stream has an unknown total sample count.
12699
12700
v0.1b - 2016-05-07
12701
  - Properly close the file handle in drflac_open_file() and family when the decoder fails to initialize.
12702
  - Removed a stale comment.
12703
12704
v0.1a - 2016-05-05
12705
  - Minor formatting changes.
12706
  - Fixed a warning on the GCC build.
12707
12708
v0.1 - 2016-05-03
12709
  - Initial versioned release.
12710
*/
12711
12712
/*
12713
This software is available as a choice of the following licenses. Choose
12714
whichever you prefer.
12715
12716
===============================================================================
12717
ALTERNATIVE 1 - Public Domain (www.unlicense.org)
12718
===============================================================================
12719
This is free and unencumbered software released into the public domain.
12720
12721
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
12722
software, either in source code form or as a compiled binary, for any purpose,
12723
commercial or non-commercial, and by any means.
12724
12725
In jurisdictions that recognize copyright laws, the author or authors of this
12726
software dedicate any and all copyright interest in the software to the public
12727
domain. We make this dedication for the benefit of the public at large and to
12728
the detriment of our heirs and successors. We intend this dedication to be an
12729
overt act of relinquishment in perpetuity of all present and future rights to
12730
this software under copyright law.
12731
12732
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12733
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12734
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12735
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
12736
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
12737
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12738
12739
For more information, please refer to <http://unlicense.org/>
12740
12741
===============================================================================
12742
ALTERNATIVE 2 - MIT No Attribution
12743
===============================================================================
12744
Copyright 2023 David Reid
12745
12746
Permission is hereby granted, free of charge, to any person obtaining a copy of
12747
this software and associated documentation files (the "Software"), to deal in
12748
the Software without restriction, including without limitation the rights to
12749
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12750
of the Software, and to permit persons to whom the Software is furnished to do
12751
so.
12752
12753
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12754
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12755
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12756
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12757
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12758
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
12759
SOFTWARE.
12760
*/