Coverage Report

Created: 2026-09-14 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dr_libs/dr_mp3.h
Line
Count
Source
1
/*
2
MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
3
dr_mp3 - v0.7.4 - TBD
4
5
David Reid - mackron@gmail.com
6
7
GitHub: https://github.com/mackron/dr_libs
8
9
Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3.
10
*/
11
12
/*
13
Introduction
14
=============
15
dr_mp3 is a single file library. To use it, do something like the following in one .c file.
16
17
    ```c
18
    #define DR_MP3_IMPLEMENTATION
19
    #include "dr_mp3.h"
20
    ```
21
22
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:
23
24
    ```c
25
    drmp3 mp3;
26
    if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) {
27
        // Failed to open file
28
    }
29
30
    ...
31
32
    drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames);
33
    ```
34
35
The drmp3 object is transparent so you can get access to the channel count and sample rate like so:
36
37
    ```
38
    drmp3_uint32 channels = mp3.channels;
39
    drmp3_uint32 sampleRate = mp3.sampleRate;
40
    ```
41
42
The example above initializes a decoder from a file, but you can also initialize it from a block of memory and read and seek callbacks with
43
`drmp3_init_memory()` and `drmp3_init()` respectively.
44
45
You do not need to do any annoying memory management when reading PCM frames - this is all managed internally. You can request any number of PCM frames in each
46
call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount.
47
48
You can also decode an entire file in one go with `drmp3_open_and_read_pcm_frames_f32()`, `drmp3_open_memory_and_read_pcm_frames_f32()` and
49
`drmp3_open_file_and_read_pcm_frames_f32()`.
50
51
52
Build Options
53
=============
54
#define these options before including this file.
55
56
#define DR_MP3_NO_STDIO
57
  Disable drmp3_init_file(), etc.
58
59
#define DR_MP3_NO_SIMD
60
  Disable SIMD optimizations.
61
*/
62
63
#ifndef dr_mp3_h
64
#define dr_mp3_h
65
66
#ifdef __cplusplus
67
extern "C" {
68
#endif
69
70
0
#define DRMP3_STRINGIFY(x)      #x
71
0
#define DRMP3_XSTRINGIFY(x)     DRMP3_STRINGIFY(x)
72
73
0
#define DRMP3_VERSION_MAJOR     0
74
0
#define DRMP3_VERSION_MINOR     7
75
0
#define DRMP3_VERSION_REVISION  4
76
0
#define DRMP3_VERSION_STRING    DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
77
78
#include <stddef.h> /* For size_t. */
79
80
/* Sized Types */
81
typedef   signed char           drmp3_int8;
82
typedef unsigned char           drmp3_uint8;
83
typedef   signed short          drmp3_int16;
84
typedef unsigned short          drmp3_uint16;
85
typedef   signed int            drmp3_int32;
86
typedef unsigned int            drmp3_uint32;
87
#if defined(_MSC_VER) && !defined(__clang__)
88
    typedef   signed __int64    drmp3_int64;
89
    typedef unsigned __int64    drmp3_uint64;
90
#else
91
    #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
92
        #pragma GCC diagnostic push
93
        #pragma GCC diagnostic ignored "-Wlong-long"
94
        #if defined(__clang__)
95
            #pragma GCC diagnostic ignored "-Wc++11-long-long"
96
        #endif
97
    #endif
98
    typedef   signed long long  drmp3_int64;
99
    typedef unsigned long long  drmp3_uint64;
100
    #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
101
        #pragma GCC diagnostic pop
102
    #endif
103
#endif
104
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(__powerpc64__)
105
    typedef drmp3_uint64        drmp3_uintptr;
106
#else
107
    typedef drmp3_uint32        drmp3_uintptr;
108
#endif
109
typedef drmp3_uint8             drmp3_bool8;
110
typedef drmp3_uint32            drmp3_bool32;
111
19.3k
#define DRMP3_TRUE              1
112
8.71k
#define DRMP3_FALSE             0
113
114
/* Weird shifting syntax is for VC6 compatibility. */
115
2.53M
#define DRMP3_UINT64_MAX        (((drmp3_uint64)0xFFFFFFFF << 32) | (drmp3_uint64)0xFFFFFFFF)
116
/* End Sized Types */
117
118
/* Decorations */
119
#if !defined(DRMP3_API)
120
    #if defined(DRMP3_DLL)
121
        #if defined(_WIN32)
122
            #define DRMP3_DLL_IMPORT  __declspec(dllimport)
123
            #define DRMP3_DLL_EXPORT  __declspec(dllexport)
124
            #define DRMP3_DLL_PRIVATE static
125
        #else
126
            #if defined(__GNUC__) && __GNUC__ >= 4
127
                #define DRMP3_DLL_IMPORT  __attribute__((visibility("default")))
128
                #define DRMP3_DLL_EXPORT  __attribute__((visibility("default")))
129
                #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden")))
130
            #else
131
                #define DRMP3_DLL_IMPORT
132
                #define DRMP3_DLL_EXPORT
133
                #define DRMP3_DLL_PRIVATE static
134
            #endif
135
        #endif
136
137
        #if defined(DR_MP3_IMPLEMENTATION)
138
            #define DRMP3_API  DRMP3_DLL_EXPORT
139
        #else
140
            #define DRMP3_API  DRMP3_DLL_IMPORT
141
        #endif
142
        #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE
143
    #else
144
        #define DRMP3_API extern
145
        #define DRMP3_PRIVATE static
146
    #endif
147
#endif
148
/* End Decorations */
149
150
/* Result Codes */
151
typedef drmp3_int32 drmp3_result;
152
0
#define DRMP3_SUCCESS                        0
153
0
#define DRMP3_ERROR                         -1   /* A generic error. */
154
0
#define DRMP3_INVALID_ARGS                  -2
155
0
#define DRMP3_INVALID_OPERATION             -3
156
0
#define DRMP3_OUT_OF_MEMORY                 -4
157
0
#define DRMP3_OUT_OF_RANGE                  -5
158
0
#define DRMP3_ACCESS_DENIED                 -6
159
0
#define DRMP3_DOES_NOT_EXIST                -7
160
0
#define DRMP3_ALREADY_EXISTS                -8
161
0
#define DRMP3_TOO_MANY_OPEN_FILES           -9
162
0
#define DRMP3_INVALID_FILE                  -10
163
0
#define DRMP3_TOO_BIG                       -11
164
0
#define DRMP3_PATH_TOO_LONG                 -12
165
#define DRMP3_NAME_TOO_LONG                 -13
166
0
#define DRMP3_NOT_DIRECTORY                 -14
167
0
#define DRMP3_IS_DIRECTORY                  -15
168
0
#define DRMP3_DIRECTORY_NOT_EMPTY           -16
169
#define DRMP3_END_OF_FILE                   -17
170
0
#define DRMP3_NO_SPACE                      -18
171
0
#define DRMP3_BUSY                          -19
172
0
#define DRMP3_IO_ERROR                      -20
173
0
#define DRMP3_INTERRUPT                     -21
174
0
#define DRMP3_UNAVAILABLE                   -22
175
0
#define DRMP3_ALREADY_IN_USE                -23
176
0
#define DRMP3_BAD_ADDRESS                   -24
177
0
#define DRMP3_BAD_SEEK                      -25
178
0
#define DRMP3_BAD_PIPE                      -26
179
0
#define DRMP3_DEADLOCK                      -27
180
0
#define DRMP3_TOO_MANY_LINKS                -28
181
0
#define DRMP3_NOT_IMPLEMENTED               -29
182
0
#define DRMP3_NO_MESSAGE                    -30
183
0
#define DRMP3_BAD_MESSAGE                   -31
184
0
#define DRMP3_NO_DATA_AVAILABLE             -32
185
0
#define DRMP3_INVALID_DATA                  -33
186
0
#define DRMP3_TIMEOUT                       -34
187
0
#define DRMP3_NO_NETWORK                    -35
188
0
#define DRMP3_NOT_UNIQUE                    -36
189
0
#define DRMP3_NOT_SOCKET                    -37
190
0
#define DRMP3_NO_ADDRESS                    -38
191
0
#define DRMP3_BAD_PROTOCOL                  -39
192
0
#define DRMP3_PROTOCOL_UNAVAILABLE          -40
193
0
#define DRMP3_PROTOCOL_NOT_SUPPORTED        -41
194
0
#define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42
195
0
#define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED  -43
196
0
#define DRMP3_SOCKET_NOT_SUPPORTED          -44
197
0
#define DRMP3_CONNECTION_RESET              -45
198
0
#define DRMP3_ALREADY_CONNECTED             -46
199
0
#define DRMP3_NOT_CONNECTED                 -47
200
0
#define DRMP3_CONNECTION_REFUSED            -48
201
0
#define DRMP3_NO_HOST                       -49
202
0
#define DRMP3_IN_PROGRESS                   -50
203
0
#define DRMP3_CANCELLED                     -51
204
#define DRMP3_MEMORY_ALREADY_MAPPED         -52
205
#define DRMP3_AT_END                        -53
206
/* End Result Codes */
207
208
#define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME  1152
209
#define DRMP3_MAX_SAMPLES_PER_FRAME         (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
210
211
/* Inline */
212
#ifdef _MSC_VER
213
    #define DRMP3_INLINE __forceinline
214
#elif defined(__GNUC__)
215
    /*
216
    I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
217
    the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
218
    case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
219
    command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
220
    I am using "__inline__" only when we're compiling in strict ANSI mode.
221
    */
222
    #if defined(__STRICT_ANSI__)
223
        #define DRMP3_GNUC_INLINE_HINT __inline__
224
    #else
225
        #define DRMP3_GNUC_INLINE_HINT inline
226
    #endif
227
228
    #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
229
        #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline))
230
    #else
231
        #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT
232
    #endif
233
#elif defined(__WATCOMC__)
234
    #define DRMP3_INLINE __inline
235
#else
236
    #define DRMP3_INLINE
237
#endif
238
/* End Inline */
239
240
241
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
242
DRMP3_API const char* drmp3_version_string(void);
243
244
245
/* Allocation Callbacks */
246
typedef struct
247
{
248
    void* pUserData;
249
    void* (* onMalloc)(size_t sz, void* pUserData);
250
    void* (* onRealloc)(void* p, size_t sz, void* pUserData);
251
    void  (* onFree)(void* p, void* pUserData);
252
} drmp3_allocation_callbacks;
253
/* End Allocation Callbacks */
254
255
256
/*
257
Low Level Push API
258
==================
259
*/
260
322k
#define DRMP3_MAX_BITRESERVOIR_BYTES      511
261
1.13G
#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE  2304    /* more than ISO spec's */
262
#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES  DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */
263
264
typedef struct
265
{
266
    int frame_bytes, channels, sample_rate, layer, bitrate_kbps;
267
} drmp3dec_frame_info;
268
269
typedef struct
270
{
271
    const drmp3_uint8 *buf;
272
    int pos, limit;
273
} drmp3_bs;
274
275
typedef struct
276
{
277
    const drmp3_uint8 *sfbtab;
278
    drmp3_uint16 part_23_length, big_values, scalefac_compress;
279
    drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
280
    drmp3_uint8 table_select[3], region_count[3], subblock_gain[3];
281
    drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi;
282
} drmp3_L3_gr_info;
283
284
typedef struct
285
{
286
    drmp3_bs bs;
287
    drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES];
288
    drmp3_L3_gr_info gr_info[4];
289
    float grbuf[2][576], scf[40], syn[18 + 15][2*32];
290
    drmp3_uint8 ist_pos[2][39];
291
} drmp3dec_scratch;
292
293
typedef struct
294
{
295
    float mdct_overlap[2][9*32], qmf_state[15*2*32];
296
    int reserv, free_format_bytes;
297
    drmp3_uint8 header[4], reserv_buf[511];
298
    drmp3dec_scratch scratch;
299
} drmp3dec;
300
301
/* Initializes a low level decoder. */
302
DRMP3_API void drmp3dec_init(drmp3dec *dec);
303
304
/* Reads a frame from a low level decoder. */
305
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
306
307
/* Helper for converting between f32 and s16. */
308
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
309
310
311
312
/*
313
Main API (Pull API)
314
===================
315
*/
316
typedef enum
317
{
318
    DRMP3_SEEK_SET,
319
    DRMP3_SEEK_CUR,
320
    DRMP3_SEEK_END
321
} drmp3_seek_origin;
322
323
typedef struct
324
{
325
    drmp3_uint64 seekPosInBytes;        /* Points to the first byte of an MP3 frame. */
326
    drmp3_uint64 pcmFrameIndex;         /* The index of the PCM frame this seek point targets. */
327
    drmp3_uint16 mp3FramesToDiscard;    /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */
328
    drmp3_uint16 pcmFramesToDiscard;    /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */
329
} drmp3_seek_point;
330
331
typedef enum
332
{
333
    DRMP3_METADATA_TYPE_ID3V1,
334
    DRMP3_METADATA_TYPE_ID3V2,
335
    DRMP3_METADATA_TYPE_APE,
336
    DRMP3_METADATA_TYPE_XING,
337
    DRMP3_METADATA_TYPE_VBRI
338
} drmp3_metadata_type;
339
340
typedef struct
341
{
342
    drmp3_metadata_type type;
343
    const void* pRawData;               /* A pointer to the raw data. */
344
    size_t rawDataSize;
345
} drmp3_metadata;
346
347
348
/*
349
Callback for when data is read. Return value is the number of bytes actually read.
350
351
pUserData   [in]  The user data that was passed to drmp3_init(), and family.
352
pBufferOut  [out] The output buffer.
353
bytesToRead [in]  The number of bytes to read.
354
355
Returns the number of bytes actually read.
356
357
A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
358
either the entire bytesToRead is filled or you have reached the end of the stream.
359
*/
360
typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
361
362
/*
363
Callback for when data needs to be seeked.
364
365
pUserData [in] The user data that was passed to drmp3_init(), and family.
366
offset    [in] The number of bytes to move, relative to the origin. Can be negative.
367
origin    [in] The origin of the seek.
368
369
Returns whether or not the seek was successful.
370
*/
371
typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
372
373
/*
374
Callback for retrieving the current cursor position.
375
376
pUserData [in]  The user data that was passed to drmp3_init(), and family.
377
pCursor   [out] The cursor position in bytes from the start of the stream.
378
379
Returns whether or not the cursor position was successfully retrieved.
380
*/
381
typedef drmp3_bool32 (* drmp3_tell_proc)(void* pUserData, drmp3_int64* pCursor);
382
383
384
/*
385
Callback for when metadata is read.
386
387
Only the raw data is provided. The client is responsible for parsing the contents of the data themsevles.
388
*/
389
typedef void (* drmp3_meta_proc)(void* pUserData, const drmp3_metadata* pMetadata);
390
391
392
typedef struct
393
{
394
    drmp3_uint32 channels;
395
    drmp3_uint32 sampleRate;
396
} drmp3_config;
397
398
typedef struct
399
{
400
    drmp3dec decoder;
401
    drmp3_uint32 channels;
402
    drmp3_uint32 sampleRate;
403
    drmp3_read_proc onRead;
404
    drmp3_seek_proc onSeek;
405
    drmp3_meta_proc onMeta;
406
    void* pUserData;
407
    void* pUserDataMeta;
408
    drmp3_allocation_callbacks allocationCallbacks;
409
    drmp3_uint32 mp3FrameChannels;      /* The number of channels in the currently loaded MP3 frame. Internal use only. */
410
    drmp3_uint32 mp3FrameSampleRate;    /* The sample rate of the currently loaded MP3 frame. Internal use only. */
411
    drmp3_uint32 pcmFramesConsumedInMP3Frame;
412
    drmp3_uint32 pcmFramesRemainingInMP3Frame;
413
    drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME];  /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */
414
    drmp3_uint64 currentPCMFrame;       /* The current PCM frame, globally. */
415
    drmp3_uint64 streamCursor;          /* The current byte the decoder is sitting on in the raw stream. */
416
    drmp3_uint64 streamLength;          /* The length of the stream in bytes. dr_mp3 will not read beyond this. If a ID3v1 or APE tag is present, this will be set to the first byte of the tag. */
417
    drmp3_uint64 streamStartOffset;     /* The offset of the start of the MP3 data. This is used for skipping ID3v2 and VBR tags. */
418
    drmp3_seek_point* pSeekPoints;      /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */
419
    drmp3_uint32 seekPointCount;        /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */
420
    drmp3_uint32 delayInPCMFrames;
421
    drmp3_uint32 paddingInPCMFrames;
422
    drmp3_uint64 totalPCMFrameCount;    /* Set to DRMP3_UINT64_MAX if the length is unknown. Includes delay and padding. */
423
    drmp3_bool32 isVBR;
424
    drmp3_bool32 isCBR;
425
    size_t dataSize;
426
    size_t dataCapacity;
427
    size_t dataConsumed;
428
    drmp3_uint8* pData;
429
    drmp3_bool32 atEnd;
430
    struct
431
    {
432
        const drmp3_uint8* pData;
433
        size_t dataSize;
434
        size_t currentReadPos;
435
    } memory;   /* Only used for decoders that were opened against a block of memory. */
436
} drmp3;
437
438
/*
439
Initializes an MP3 decoder.
440
441
onRead    [in]           The function to call when data needs to be read from the client.
442
onSeek    [in]           The function to call when the read position of the client data needs to move.
443
onTell    [in]           The function to call when the read position of the client data needs to be retrieved.
444
pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
445
446
Returns true if successful; false otherwise.
447
448
Close the loader with drmp3_uninit().
449
450
See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit()
451
*/
452
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
453
454
/*
455
Initializes an MP3 decoder from a block of memory.
456
457
This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
458
the lifetime of the drmp3 object.
459
460
The buffer should contain the contents of the entire MP3 file.
461
*/
462
DRMP3_API drmp3_bool32 drmp3_init_memory_with_metadata(drmp3* pMP3, const void* pData, size_t dataSize, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks);
463
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
464
465
#ifndef DR_MP3_NO_STDIO
466
/*
467
Initializes an MP3 decoder from a file.
468
469
This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3
470
objects because the operating system may restrict the number of file handles an application can have open at
471
any given time.
472
*/
473
DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata(drmp3* pMP3, const char* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks);
474
DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata_w(drmp3* pMP3, const wchar_t* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks);
475
476
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
477
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
478
#endif
479
480
/*
481
Uninitializes an MP3 decoder.
482
*/
483
DRMP3_API void drmp3_uninit(drmp3* pMP3);
484
485
/*
486
Reads PCM frames as interleaved 32-bit IEEE floating point PCM.
487
488
Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
489
*/
490
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
491
492
/*
493
Reads PCM frames as interleaved signed 16-bit integer PCM.
494
495
Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
496
*/
497
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
498
499
/*
500
Seeks to a specific frame.
501
502
Note that this is _not_ an MP3 frame, but rather a PCM frame.
503
*/
504
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
505
506
/*
507
Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
508
radio. Runs in linear time. Returns 0 on error.
509
*/
510
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
511
512
/*
513
Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet
514
radio. Runs in linear time. Returns 0 on error.
515
*/
516
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
517
518
/*
519
Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
520
radio. Runs in linear time. Returns 0 on error.
521
522
This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient.
523
*/
524
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
525
526
/*
527
Calculates the seekpoints based on PCM frames. This is slow.
528
529
pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count.
530
On output it contains the actual count. The reason for this design is that the client may request too many
531
seekpoints, in which case dr_mp3 will return a corrected count.
532
533
Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates.
534
*/
535
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
536
537
/*
538
Binds a seek table to the decoder.
539
540
This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this
541
remains valid while it is bound to the decoder.
542
543
Use drmp3_calculate_seek_points() to calculate the seek points.
544
*/
545
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
546
547
548
/*
549
Opens an decodes an entire MP3 stream as a single operation.
550
551
On output pConfig will receive the channel count and sample rate of the stream.
552
553
Free the returned pointer with drmp3_free().
554
*/
555
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
556
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
557
558
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
559
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
560
561
#ifndef DR_MP3_NO_STDIO
562
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
563
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
564
#endif
565
566
/*
567
Allocates a block of memory on the heap.
568
*/
569
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
570
571
/*
572
Frees any memory that was allocated by a public drmp3 API.
573
*/
574
DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
575
576
#ifdef __cplusplus
577
}
578
#endif
579
#endif  /* dr_mp3_h */
580
581
582
/************************************************************************************************************************************************************
583
 ************************************************************************************************************************************************************
584
585
 IMPLEMENTATION
586
587
 ************************************************************************************************************************************************************
588
 ************************************************************************************************************************************************************/
589
#if defined(DR_MP3_IMPLEMENTATION)
590
#ifndef dr_mp3_c
591
#define dr_mp3_c
592
593
#include <stdlib.h>
594
#include <string.h>
595
#include <limits.h> /* For INT_MAX */
596
597
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision)
598
0
{
599
0
    if (pMajor) {
600
0
        *pMajor = DRMP3_VERSION_MAJOR;
601
0
    }
602
603
0
    if (pMinor) {
604
0
        *pMinor = DRMP3_VERSION_MINOR;
605
0
    }
606
607
0
    if (pRevision) {
608
0
        *pRevision = DRMP3_VERSION_REVISION;
609
0
    }
610
0
}
611
612
DRMP3_API const char* drmp3_version_string(void)
613
0
{
614
0
    return DRMP3_VERSION_STRING;
615
0
}
616
617
/* Disable SIMD when compiling with TCC for now. */
618
#if defined(__TINYC__)
619
#define DR_MP3_NO_SIMD
620
#endif
621
622
2.75M
#define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset)))
623
624
#ifndef DRMP3_MAX_FRAME_SYNC_MATCHES
625
2.19M
#define DRMP3_MAX_FRAME_SYNC_MATCHES      10
626
#endif
627
628
686k
#define DRMP3_SHORT_BLOCK_TYPE            2
629
175k
#define DRMP3_STOP_BLOCK_TYPE             3
630
195k
#define DRMP3_MODE_MONO                   3
631
185k
#define DRMP3_MODE_JOINT_STEREO           1
632
647M
#define DRMP3_HDR_SIZE                    4
633
1.32M
#define DRMP3_HDR_IS_MONO(h)              (((h[3]) & 0xC0) == 0xC0)
634
411k
#define DRMP3_HDR_IS_MS_STEREO(h)         (((h[3]) & 0xE0) == 0x60)
635
25.9M
#define DRMP3_HDR_IS_FREE_FORMAT(h)       (((h[2]) & 0xF0) == 0)
636
530k
#define DRMP3_HDR_IS_CRC(h)               (!((h[1]) & 1))
637
20.4M
#define DRMP3_HDR_TEST_PADDING(h)         ((h[2]) & 0x2)
638
22.0M
#define DRMP3_HDR_TEST_MPEG1(h)           ((h[1]) & 0x8)
639
4.12M
#define DRMP3_HDR_TEST_NOT_MPEG25(h)      ((h[1]) & 0x10)
640
981k
#define DRMP3_HDR_TEST_I_STEREO(h)        ((h[3]) & 0x10)
641
10.6M
#define DRMP3_HDR_TEST_MS_STEREO(h)       ((h[3]) & 0x20)
642
191k
#define DRMP3_HDR_GET_STEREO_MODE(h)      (((h[3]) >> 6) & 3)
643
182k
#define DRMP3_HDR_GET_STEREO_MODE_EXT(h)  (((h[3]) >> 4) & 3)
644
75.3M
#define DRMP3_HDR_GET_LAYER(h)            (((h[1]) >> 1) & 3)
645
73.9M
#define DRMP3_HDR_GET_BITRATE(h)          ((h[2]) >> 4)
646
40.3M
#define DRMP3_HDR_GET_SAMPLE_RATE(h)      (((h[2]) >> 2) & 3)
647
734k
#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h)   (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
648
3.74M
#define DRMP3_HDR_IS_FRAME_576(h)         ((h[1] & 14) == 2)
649
13.2M
#define DRMP3_HDR_IS_LAYER_1(h)           ((h[1] & 6) == 6)
650
651
1.18M
#define DRMP3_BITS_DEQUANTIZER_OUT        -1
652
790k
#define DRMP3_MAX_SCF                     (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210)
653
790k
#define DRMP3_MAX_SCFI                    ((DRMP3_MAX_SCF + 3) & ~3)
654
655
24.4M
#define DRMP3_MIN(a, b)           ((a) > (b) ? (b) : (a))
656
588k
#define DRMP3_MAX(a, b)           ((a) < (b) ? (b) : (a))
657
658
#if !defined(DR_MP3_NO_SIMD)
659
660
#if !defined(DR_MP3_ONLY_SIMD) && ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)))
661
#define DR_MP3_ONLY_SIMD
662
#endif
663
#if !defined(DR_MP3_ONLY_SIMD) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC))
664
#define DR_MP3_ONLY_SIMD
665
#endif
666
667
#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)))
668
#if defined(_MSC_VER)
669
#include <intrin.h>
670
#endif
671
#include <emmintrin.h>
672
#define DRMP3_HAVE_SSE 1
673
#define DRMP3_HAVE_SIMD 1
674
220M
#define DRMP3_VSTORE _mm_storeu_ps
675
1.82G
#define DRMP3_VLD _mm_loadu_ps
676
1.51G
#define DRMP3_VSET _mm_set1_ps
677
2.55G
#define DRMP3_VADD _mm_add_ps
678
984M
#define DRMP3_VSUB _mm_sub_ps
679
3.17G
#define DRMP3_VMUL _mm_mul_ps
680
#define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
681
#define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
682
421M
#define DRMP3_VMUL_S(x, s)  _mm_mul_ps(x, _mm_set1_ps(s))
683
36.8M
#define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
684
typedef __m128 drmp3_f4;
685
#if (defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)) && !defined(__clang__)
686
#define drmp3_cpuid __cpuid
687
#else
688
static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType)
689
0
{
690
0
#if defined(__PIC__)
691
0
    __asm__ __volatile__(
692
0
#if defined(__x86_64__)
693
0
        "push %%rbx\n"
694
0
        "cpuid\n"
695
0
        "xchgl %%ebx, %1\n"
696
0
        "pop  %%rbx\n"
697
0
#else
698
0
        "xchgl %%ebx, %1\n"
699
0
        "cpuid\n"
700
0
        "xchgl %%ebx, %1\n"
701
0
#endif
702
0
        : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
703
0
        : "a" (InfoType));
704
0
#else
705
0
    __asm__ __volatile__(
706
0
        "cpuid"
707
0
        : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
708
0
        : "a" (InfoType));
709
0
#endif
710
0
}
711
#endif
712
static int drmp3_have_simd(void)
713
20.4M
{
714
20.4M
#ifdef DR_MP3_ONLY_SIMD
715
20.4M
    return 1;
716
#else
717
    static int g_have_simd;
718
    int CPUInfo[4];
719
#ifdef MINIMP3_TEST
720
    static int g_counter;
721
    if (g_counter++ > 100)
722
        return 0;
723
#endif
724
    if (g_have_simd)
725
        goto end;
726
    drmp3_cpuid(CPUInfo, 0);
727
    if (CPUInfo[0] > 0)
728
    {
729
        drmp3_cpuid(CPUInfo, 1);
730
        g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
731
        return g_have_simd - 1;
732
    }
733
734
end:
735
    return g_have_simd - 1;
736
#endif
737
20.4M
}
738
#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
739
#include <arm_neon.h>
740
#define DRMP3_HAVE_SSE 0
741
#define DRMP3_HAVE_SIMD 1
742
#define DRMP3_VSTORE vst1q_f32
743
#define DRMP3_VLD vld1q_f32
744
#define DRMP3_VSET vmovq_n_f32
745
#define DRMP3_VADD vaddq_f32
746
#define DRMP3_VSUB vsubq_f32
747
#define DRMP3_VMUL vmulq_f32
748
#define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
749
#define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
750
#define DRMP3_VMUL_S(x, s)  vmulq_f32(x, vmovq_n_f32(s))
751
#define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
752
typedef float32x4_t drmp3_f4;
753
static int drmp3_have_simd(void)
754
{   /* TODO: detect neon for !DR_MP3_ONLY_SIMD */
755
    return 1;
756
}
757
#else
758
#define DRMP3_HAVE_SSE 0
759
#define DRMP3_HAVE_SIMD 0
760
#ifdef DR_MP3_ONLY_SIMD
761
#error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
762
#endif
763
#endif
764
765
#else
766
767
#define DRMP3_HAVE_SIMD 0
768
769
#endif
770
771
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) && !defined(__ARM_ARCH_6M__)
772
#define DRMP3_HAVE_ARMV6 1
773
static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a)
774
{
775
    drmp3_int32 x = 0;
776
    __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
777
    return x;
778
}
779
#else
780
#define DRMP3_HAVE_ARMV6 0
781
#endif
782
783
784
/* Standard library stuff. */
785
#ifndef DRMP3_ASSERT
786
#include <assert.h>
787
2.58M
#define DRMP3_ASSERT(expression) assert(expression)
788
#endif
789
#ifndef DRMP3_COPY_MEMORY
790
16.7M
#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
791
#endif
792
#ifndef DRMP3_MOVE_MEMORY
793
298k
#define DRMP3_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz))
794
#endif
795
#ifndef DRMP3_ZERO_MEMORY
796
2.20M
#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
797
#endif
798
3.06k
#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p)))
799
#ifndef DRMP3_MALLOC
800
0
#define DRMP3_MALLOC(sz) malloc((sz))
801
#endif
802
#ifndef DRMP3_REALLOC
803
0
#define DRMP3_REALLOC(p, sz) realloc((p), (sz))
804
#endif
805
#ifndef DRMP3_FREE
806
0
#define DRMP3_FREE(p) free((p))
807
#endif
808
809
810
811
typedef struct
812
{
813
    float scf[3*64];
814
    drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64];
815
} drmp3_L12_scale_info;
816
817
typedef struct
818
{
819
    drmp3_uint8 tab_offset, code_tab_width, band_count;
820
} drmp3_L12_subband_alloc;
821
822
static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes)
823
851k
{
824
851k
    bs->buf   = data;
825
851k
    bs->pos   = 0;
826
851k
    bs->limit = bytes*8;
827
851k
}
828
829
static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n)
830
21.4M
{
831
21.4M
    drmp3_uint32 next, cache = 0, s = bs->pos & 7;
832
21.4M
    int shl = n + s;
833
21.4M
    const drmp3_uint8 *p = bs->buf + (bs->pos >> 3);
834
21.4M
    if ((bs->pos += n) > bs->limit)
835
5.87M
        return 0;
836
15.5M
    next = *p++ & (255 >> s);
837
20.7M
    while ((shl -= 8) > 0)
838
5.22M
    {
839
5.22M
        cache |= next << shl;
840
5.22M
        next = *p++;
841
5.22M
    }
842
15.5M
    return cache | (next >> -shl);
843
21.4M
}
844
845
static int drmp3_hdr_valid(const drmp3_uint8 *h)
846
645M
{
847
645M
    return h[0] == 0xff &&
848
90.2M
        ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
849
70.7M
        (DRMP3_HDR_GET_LAYER(h) != 0) &&
850
69.8M
        (DRMP3_HDR_GET_BITRATE(h) != 15) &&
851
35.4M
        (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3);
852
645M
}
853
854
static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2)
855
579M
{
856
579M
    return drmp3_hdr_valid(h2) &&
857
32.1M
        ((h1[1] ^ h2[1]) & 0xFE) == 0 &&
858
15.3M
        ((h1[2] ^ h2[2]) & 0x0C) == 0 &&
859
12.9M
        !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2));
860
579M
}
861
862
static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h)
863
4.12M
{
864
4.12M
    static const drmp3_uint8 halfrate[2][3][15] = {
865
4.12M
        { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
866
4.12M
        { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
867
4.12M
    };
868
4.12M
    return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
869
4.12M
}
870
871
static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
872
4.12M
{
873
4.12M
    static const unsigned g_hz[3] = { 44100, 48000, 32000 };
874
4.12M
    return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
875
4.12M
}
876
877
static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
878
4.57M
{
879
4.57M
    return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
880
4.57M
}
881
882
static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
883
3.59M
{
884
3.59M
    int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
885
3.59M
    if (DRMP3_HDR_IS_LAYER_1(h))
886
835k
    {
887
835k
        frame_bytes &= ~3; /* slot align */
888
835k
    }
889
3.59M
    return frame_bytes ? frame_bytes : free_format_size;
890
3.59M
}
891
892
static int drmp3_hdr_padding(const drmp3_uint8 *h)
893
20.4M
{
894
20.4M
    return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
895
20.4M
}
896
897
#ifndef DR_MP3_ONLY_MP3
898
static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
899
191k
{
900
191k
    const drmp3_L12_subband_alloc *alloc;
901
191k
    int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);
902
191k
    int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
903
904
191k
    if (DRMP3_HDR_IS_LAYER_1(hdr))
905
4.13k
    {
906
4.13k
        static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } };
907
4.13k
        alloc = g_alloc_L1;
908
4.13k
        nbands = 32;
909
187k
    } else if (!DRMP3_HDR_TEST_MPEG1(hdr))
910
184k
    {
911
184k
        static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } };
912
184k
        alloc = g_alloc_L2M2;
913
184k
        nbands = 30;
914
184k
    } else
915
3.33k
    {
916
3.33k
        static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
917
3.33k
        int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr);
918
3.33k
        unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO);
919
3.33k
        if (!kbps) /* free-format */
920
2.62k
        {
921
2.62k
            kbps = 192;
922
2.62k
        }
923
924
3.33k
        alloc = g_alloc_L2M1;
925
3.33k
        nbands = 27;
926
3.33k
        if (kbps < 56)
927
457
        {
928
457
            static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } };
929
457
            alloc = g_alloc_L2M1_lowrate;
930
457
            nbands = sample_rate_idx == 2 ? 12 : 8;
931
2.87k
        } else if (kbps >= 96 && sample_rate_idx != 1)
932
606
        {
933
606
            nbands = 30;
934
606
        }
935
3.33k
    }
936
937
191k
    sci->total_bands = (drmp3_uint8)nbands;
938
191k
    sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands);
939
940
191k
    return alloc;
941
191k
}
942
943
static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf)
944
191k
{
945
191k
    static const float g_deq_L12[18*3] = {
946
3.45M
#define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
947
191k
        DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9)
948
191k
    };
949
191k
    int i, m;
950
11.6M
    for (i = 0; i < bands; i++)
951
11.4M
    {
952
11.4M
        float s = 0;
953
11.4M
        int ba = *pba++;
954
11.4M
        int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0;
955
45.9M
        for (m = 4; m; m >>= 1)
956
34.4M
        {
957
34.4M
            if (mask & m)
958
262k
            {
959
262k
                int b = drmp3_bs_get_bits(bs, 6);
960
262k
                s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3);
961
262k
            }
962
34.4M
            *scf++ = s;
963
34.4M
        }
964
11.4M
    }
965
191k
}
966
967
static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci)
968
191k
{
969
191k
    static const drmp3_uint8 g_bitalloc_code_tab[] = {
970
191k
        0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16,
971
191k
        0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16,
972
191k
        0,17,18, 3,19,4,5,16,
973
191k
        0,17,18,16,
974
191k
        0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15,
975
191k
        0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14,
976
191k
        0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16
977
191k
    };
978
191k
    const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci);
979
980
191k
    int i, k = 0, ba_bits = 0;
981
191k
    const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab;
982
983
5.93M
    for (i = 0; i < sci->total_bands; i++)
984
5.74M
    {
985
5.74M
        drmp3_uint8 ba;
986
5.74M
        if (i == k)
987
569k
        {
988
569k
            k += subband_alloc->band_count;
989
569k
            ba_bits = subband_alloc->code_tab_width;
990
569k
            ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset;
991
569k
            subband_alloc++;
992
569k
        }
993
5.74M
        ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
994
5.74M
        sci->bitalloc[2*i] = ba;
995
5.74M
        if (i < sci->stereo_bands)
996
838k
        {
997
838k
            ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
998
838k
        }
999
5.74M
        sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0;
1000
5.74M
    }
1001
1002
11.6M
    for (i = 0; i < 2*sci->total_bands; i++)
1003
11.4M
    {
1004
11.4M
        sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6);
1005
11.4M
    }
1006
1007
191k
    drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf);
1008
1009
5.09M
    for (i = sci->stereo_bands; i < sci->total_bands; i++)
1010
4.90M
    {
1011
4.90M
        sci->bitalloc[2*i + 1] = 0;
1012
4.90M
    }
1013
191k
}
1014
1015
static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size)
1016
555k
{
1017
555k
    int i, j, k, choff = 576;
1018
2.77M
    for (j = 0; j < 4; j++)
1019
2.22M
    {
1020
2.22M
        float *dst = grbuf + group_size*j;
1021
135M
        for (i = 0; i < 2*sci->total_bands; i++)
1022
133M
        {
1023
133M
            int ba = sci->bitalloc[i];
1024
133M
            if (ba != 0)
1025
664k
            {
1026
664k
                if (ba < 17)
1027
306k
                {
1028
306k
                    int half = (1 << (ba - 1)) - 1;
1029
909k
                    for (k = 0; k < group_size; k++)
1030
602k
                    {
1031
602k
                        dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half);
1032
602k
                    }
1033
306k
                } else
1034
358k
                {
1035
358k
                    unsigned mod = (2 << (ba - 17)) + 1;    /* 3, 5, 9 */
1036
358k
                    unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3));  /* 5, 7, 10 */
1037
1.43M
                    for (k = 0; k < group_size; k++, code /= mod)
1038
1.07M
                    {
1039
1.07M
                        dst[k] = (float)((int)(code % mod - mod/2));
1040
1.07M
                    }
1041
358k
                }
1042
664k
            }
1043
133M
            dst += choff;
1044
133M
            choff = 18 - choff;
1045
133M
        }
1046
2.22M
    }
1047
555k
    return group_size*4;
1048
555k
}
1049
1050
static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst)
1051
550k
{
1052
550k
    int i, k;
1053
550k
    DRMP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
1054
17.0M
    for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6)
1055
16.4M
    {
1056
214M
        for (k = 0; k < 12; k++)
1057
197M
        {
1058
197M
            dst[k + 0]   *= scf[0];
1059
197M
            dst[k + 576] *= scf[3];
1060
197M
        }
1061
16.4M
    }
1062
550k
}
1063
#endif
1064
1065
static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
1066
339k
{
1067
339k
    static const drmp3_uint8 g_scf_long[8][23] = {
1068
339k
        { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1069
339k
        { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
1070
339k
        { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1071
339k
        { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 },
1072
339k
        { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1073
339k
        { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 },
1074
339k
        { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
1075
339k
        { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
1076
339k
    };
1077
339k
    static const drmp3_uint8 g_scf_short[8][40] = {
1078
339k
        { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1079
339k
        { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1080
339k
        { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1081
339k
        { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1082
339k
        { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1083
339k
        { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1084
339k
        { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1085
339k
        { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1086
339k
    };
1087
339k
    static const drmp3_uint8 g_scf_mixed[8][40] = {
1088
339k
        { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1089
339k
        { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1090
339k
        { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1091
339k
        { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1092
339k
        { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1093
339k
        { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1094
339k
        { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1095
339k
        { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1096
339k
    };
1097
1098
339k
    unsigned tables, scfsi = 0;
1099
339k
    int main_data_begin, part_23_sum = 0;
1100
339k
    int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
1101
339k
    int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
1102
1103
339k
    if (DRMP3_HDR_TEST_MPEG1(hdr))
1104
38.3k
    {
1105
38.3k
        gr_count *= 2;
1106
38.3k
        main_data_begin = drmp3_bs_get_bits(bs, 9);
1107
38.3k
        scfsi = drmp3_bs_get_bits(bs, 7 + gr_count);
1108
38.3k
    } else
1109
300k
    {
1110
300k
        main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count;
1111
300k
    }
1112
1113
339k
    do
1114
452k
    {
1115
452k
        if (DRMP3_HDR_IS_MONO(hdr))
1116
301k
        {
1117
301k
            scfsi <<= 4;
1118
301k
        }
1119
452k
        gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12);
1120
452k
        part_23_sum += gr->part_23_length;
1121
452k
        gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs,  9);
1122
452k
        if (gr->big_values > 288)
1123
1.26k
        {
1124
1.26k
            return -1;
1125
1.26k
        }
1126
451k
        gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8);
1127
451k
        gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
1128
451k
        gr->sfbtab = g_scf_long[sr_idx];
1129
451k
        gr->n_long_sfb  = 22;
1130
451k
        gr->n_short_sfb = 0;
1131
451k
        if (drmp3_bs_get_bits(bs, 1))
1132
294k
        {
1133
294k
            gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2);
1134
294k
            if (!gr->block_type)
1135
3.49k
            {
1136
3.49k
                return -1;
1137
3.49k
            }
1138
291k
            gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1139
291k
            gr->region_count[0] = 7;
1140
291k
            gr->region_count[1] = 255;
1141
291k
            if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE)
1142
224k
            {
1143
224k
                scfsi &= 0x0F0F;
1144
224k
                if (!gr->mixed_block_flag)
1145
25.1k
                {
1146
25.1k
                    gr->region_count[0] = 8;
1147
25.1k
                    gr->sfbtab = g_scf_short[sr_idx];
1148
25.1k
                    gr->n_long_sfb = 0;
1149
25.1k
                    gr->n_short_sfb = 39;
1150
25.1k
                } else
1151
199k
                {
1152
199k
                    gr->sfbtab = g_scf_mixed[sr_idx];
1153
199k
                    gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6;
1154
199k
                    gr->n_short_sfb = 30;
1155
199k
                }
1156
224k
            }
1157
291k
            tables = drmp3_bs_get_bits(bs, 10);
1158
291k
            tables <<= 5;
1159
291k
            gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1160
291k
            gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1161
291k
            gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1162
291k
        } else
1163
156k
        {
1164
156k
            gr->block_type = 0;
1165
156k
            gr->mixed_block_flag = 0;
1166
156k
            tables = drmp3_bs_get_bits(bs, 15);
1167
156k
            gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4);
1168
156k
            gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1169
156k
            gr->region_count[2] = 255;
1170
156k
        }
1171
447k
        gr->table_select[0] = (drmp3_uint8)(tables >> 10);
1172
447k
        gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31);
1173
447k
        gr->table_select[2] = (drmp3_uint8)((tables) & 31);
1174
447k
        gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
1175
447k
        gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1176
447k
        gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1177
447k
        gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15);
1178
447k
        scfsi <<= 4;
1179
447k
        gr++;
1180
447k
    } while(--gr_count);
1181
1182
334k
    if (part_23_sum + bs->pos > bs->limit + main_data_begin*8)
1183
11.5k
    {
1184
11.5k
        return -1;
1185
11.5k
    }
1186
1187
322k
    return main_data_begin;
1188
334k
}
1189
1190
static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi)
1191
395k
{
1192
395k
    int i, k;
1193
1.92M
    for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2)
1194
1.53M
    {
1195
1.53M
        int cnt = scf_count[i];
1196
1.53M
        if (scfsi & 8)
1197
14.7k
        {
1198
14.7k
            DRMP3_COPY_MEMORY(scf, ist_pos, cnt);
1199
14.7k
        } else
1200
1.52M
        {
1201
1.52M
            int bits = scf_size[i];
1202
1.52M
            if (!bits)
1203
532k
            {
1204
532k
                DRMP3_ZERO_MEMORY(scf, cnt);
1205
532k
                DRMP3_ZERO_MEMORY(ist_pos, cnt);
1206
532k
            } else
1207
987k
            {
1208
987k
                int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1;
1209
8.48M
                for (k = 0; k < cnt; k++)
1210
7.49M
                {
1211
7.49M
                    int s = drmp3_bs_get_bits(bitbuf, bits);
1212
7.49M
                    ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s);
1213
7.49M
                    scf[k] = (drmp3_uint8)s;
1214
7.49M
                }
1215
987k
            }
1216
1.52M
        }
1217
1.53M
        ist_pos += cnt;
1218
1.53M
        scf += cnt;
1219
1.53M
    }
1220
395k
    scf[0] = scf[1] = scf[2] = 0;
1221
395k
}
1222
1223
static float drmp3_L3_ldexp_q2(float y, int exp_q2)
1224
20.4M
{
1225
20.4M
    static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
1226
20.4M
    int e;
1227
20.4M
    do
1228
21.0M
    {
1229
21.0M
        e = DRMP3_MIN(30*4, exp_q2);
1230
21.0M
        y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
1231
21.0M
    } while ((exp_q2 -= e) > 0);
1232
20.4M
    return y;
1233
20.4M
}
1234
1235
/*
1236
I've had reports of GCC 14 throwing an incorrect -Wstringop-overflow warning here. This is an attempt
1237
to silence this warning.
1238
*/
1239
#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__)
1240
    #pragma GCC diagnostic push
1241
    #pragma GCC diagnostic ignored "-Wstringop-overflow"
1242
#endif
1243
static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch)
1244
395k
{
1245
395k
    static const drmp3_uint8 g_scf_partitions[3][28] = {
1246
395k
        { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 },
1247
395k
        { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 },
1248
395k
        { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 }
1249
395k
    };
1250
395k
    const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
1251
395k
    drmp3_uint8 scf_size[4], iscf[40];
1252
395k
    int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi;
1253
395k
    float gain;
1254
1255
395k
    if (DRMP3_HDR_TEST_MPEG1(hdr))
1256
71.3k
    {
1257
71.3k
        static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 };
1258
71.3k
        int part = g_scfc_decode[gr->scalefac_compress];
1259
71.3k
        scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2);
1260
71.3k
        scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3);
1261
71.3k
    } else
1262
323k
    {
1263
323k
        static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
1264
323k
        int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch;
1265
323k
        sfc = gr->scalefac_compress >> ist;
1266
785k
        for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4)
1267
461k
        {
1268
2.30M
            for (modprod = 1, i = 3; i >= 0; i--)
1269
1.84M
            {
1270
1.84M
                scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]);
1271
1.84M
                modprod *= g_mod[k + i];
1272
1.84M
            }
1273
461k
        }
1274
323k
        scf_partition += k;
1275
323k
        scfsi = -16;
1276
323k
    }
1277
395k
    drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi);
1278
1279
395k
    if (gr->n_short_sfb)
1280
219k
    {
1281
219k
        int sh = 3 - scf_shift;
1282
2.49M
        for (i = 0; i < gr->n_short_sfb; i += 3)
1283
2.27M
        {
1284
2.27M
            iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
1285
2.27M
            iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
1286
2.27M
            iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
1287
2.27M
        }
1288
219k
    } else if (gr->preflag)
1289
28.6k
    {
1290
28.6k
        static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
1291
315k
        for (i = 0; i < 10; i++)
1292
286k
        {
1293
286k
            iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]);
1294
286k
        }
1295
28.6k
    }
1296
1297
395k
    gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
1298
395k
    gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4),  DRMP3_MAX_SCFI - gain_exp);
1299
12.2M
    for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
1300
11.8M
    {
1301
11.8M
        scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
1302
11.8M
    }
1303
395k
}
1304
#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__)
1305
    #pragma GCC diagnostic pop
1306
#endif
1307
1308
static const float g_drmp3_pow43[129 + 16] = {
1309
    0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
1310
    0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
1311
};
1312
1313
static float drmp3_L3_pow_43(int x)
1314
2.87M
{
1315
2.87M
    float frac;
1316
2.87M
    int sign, mult = 256;
1317
1318
2.87M
    if (x < 129)
1319
2.86M
    {
1320
2.86M
        return g_drmp3_pow43[16 + x];
1321
2.86M
    }
1322
1323
13.5k
    if (x < 1024)
1324
3.60k
    {
1325
3.60k
        mult = 16;
1326
3.60k
        x <<= 3;
1327
3.60k
    }
1328
1329
13.5k
    sign = 2*x & 64;
1330
13.5k
    frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
1331
13.5k
    return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
1332
2.87M
}
1333
1334
static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
1335
395k
{
1336
395k
    static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1337
395k
        785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
1338
395k
        -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
1339
395k
        -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
1340
395k
        -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
1341
395k
        -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
1342
395k
        -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
1343
395k
        -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
1344
395k
        -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
1345
395k
        -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
1346
395k
        -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
1347
395k
        -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
1348
395k
        -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
1349
395k
        -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
1350
395k
        -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
1351
395k
        -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
1352
395k
    static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
1353
395k
    static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
1354
395k
    static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
1355
395k
    static const drmp3_uint8 g_linbits[] =  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
1356
1357
21.4M
#define DRMP3_PEEK_BITS(n)    (bs_cache >> (32 - (n)))
1358
42.8M
#define DRMP3_FLUSH_BITS(n)   { bs_cache <<= (n); bs_sh += (n); }
1359
22.2M
#define DRMP3_CHECK_BITS      while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
1360
474k
#define DRMP3_BSPOS           ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
1361
1362
395k
    float one = 0.0f;
1363
395k
    int ireg = 0, big_val_cnt = gr_info->big_values;
1364
395k
    const drmp3_uint8 *sfb = gr_info->sfbtab;
1365
395k
    const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
1366
395k
    drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
1367
395k
    int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8;
1368
395k
    bs_next_ptr += 4;
1369
1370
849k
    while (big_val_cnt > 0)
1371
453k
    {
1372
453k
        int tab_num = gr_info->table_select[ireg];
1373
453k
        int sfb_cnt = gr_info->region_count[ireg++];
1374
453k
        const drmp3_int16 *codebook = tabs + tabindex[tab_num];
1375
453k
        int linbits = g_linbits[tab_num];
1376
453k
        if (linbits)
1377
252k
        {
1378
252k
            do
1379
885k
            {
1380
885k
                np = *sfb++ / 2;
1381
885k
                pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1382
885k
                one = *scf++;
1383
885k
                do
1384
3.69M
                {
1385
3.69M
                    int j, w = 5;
1386
3.69M
                    int leaf = codebook[DRMP3_PEEK_BITS(w)];
1387
8.50M
                    while (leaf < 0)
1388
4.81M
                    {
1389
4.81M
                        DRMP3_FLUSH_BITS(w);
1390
4.81M
                        w = leaf & 7;
1391
4.81M
                        leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1392
4.81M
                    }
1393
3.69M
                    DRMP3_FLUSH_BITS(leaf >> 8);
1394
1395
11.0M
                    for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1396
7.38M
                    {
1397
7.38M
                        int lsb = leaf & 0x0F;
1398
7.38M
                        if (lsb == 15)
1399
2.87M
                        {
1400
2.87M
                            lsb += DRMP3_PEEK_BITS(linbits);
1401
2.87M
                            DRMP3_FLUSH_BITS(linbits);
1402
2.87M
                            DRMP3_CHECK_BITS;
1403
2.87M
                            *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1);
1404
2.87M
                        } else
1405
4.50M
                        {
1406
4.50M
                            *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1407
4.50M
                        }
1408
7.38M
                        DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1409
7.38M
                    }
1410
3.69M
                    DRMP3_CHECK_BITS;
1411
3.69M
                } while (--pairs_to_decode);
1412
885k
            } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1413
252k
        } else
1414
201k
        {
1415
201k
            do
1416
1.25M
            {
1417
1.25M
                np = *sfb++ / 2;
1418
1.25M
                pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1419
1.25M
                one = *scf++;
1420
1.25M
                do
1421
6.97M
                {
1422
6.97M
                    int j, w = 5;
1423
6.97M
                    int leaf = codebook[DRMP3_PEEK_BITS(w)];
1424
9.56M
                    while (leaf < 0)
1425
2.59M
                    {
1426
2.59M
                        DRMP3_FLUSH_BITS(w);
1427
2.59M
                        w = leaf & 7;
1428
2.59M
                        leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1429
2.59M
                    }
1430
6.97M
                    DRMP3_FLUSH_BITS(leaf >> 8);
1431
1432
20.9M
                    for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1433
13.9M
                    {
1434
13.9M
                        int lsb = leaf & 0x0F;
1435
13.9M
                        *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1436
13.9M
                        DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1437
13.9M
                    }
1438
6.97M
                    DRMP3_CHECK_BITS;
1439
6.97M
                } while (--pairs_to_decode);
1440
1.25M
            } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1441
201k
        }
1442
453k
    }
1443
1444
395k
    for (np = 1 - big_val_cnt;; dst += 4)
1445
474k
    {
1446
474k
        const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
1447
474k
        int leaf = codebook_count1[DRMP3_PEEK_BITS(4)];
1448
474k
        if (!(leaf & 8))
1449
281k
        {
1450
281k
            leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))];
1451
281k
        }
1452
474k
        DRMP3_FLUSH_BITS(leaf & 7);
1453
474k
        if (DRMP3_BSPOS > layer3gr_limit)
1454
393k
        {
1455
393k
            break;
1456
393k
        }
1457
161k
#define DRMP3_RELOAD_SCALEFACTOR  if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
1458
320k
#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) }
1459
161k
        DRMP3_RELOAD_SCALEFACTOR;
1460
161k
        DRMP3_DEQ_COUNT1(0);
1461
161k
        DRMP3_DEQ_COUNT1(1);
1462
161k
        DRMP3_RELOAD_SCALEFACTOR;
1463
79.8k
        DRMP3_DEQ_COUNT1(2);
1464
79.8k
        DRMP3_DEQ_COUNT1(3);
1465
79.8k
        DRMP3_CHECK_BITS;
1466
79.8k
    }
1467
1468
395k
    bs->pos = layer3gr_limit;
1469
395k
}
1470
1471
static void drmp3_L3_midside_stereo(float *left, int n)
1472
268k
{
1473
268k
    int i = 0;
1474
268k
    float *right = left + 576;
1475
268k
#if DRMP3_HAVE_SIMD
1476
268k
    if (drmp3_have_simd())
1477
268k
    {
1478
1.62M
        for (; i < n - 3; i += 4)
1479
1.36M
        {
1480
1.36M
            drmp3_f4 vl = DRMP3_VLD(left + i);
1481
1.36M
            drmp3_f4 vr = DRMP3_VLD(right + i);
1482
1.36M
            DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr));
1483
1.36M
            DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr));
1484
1.36M
        }
1485
268k
#ifdef __GNUC__
1486
        /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
1487
         * For more info see: https://github.com/lieff/minimp3/issues/88
1488
         */
1489
268k
        if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
1490
5.24k
            return;
1491
268k
#endif
1492
268k
    }
1493
263k
#endif
1494
585k
    for (; i < n; i++)
1495
322k
    {
1496
322k
        float a = left[i];
1497
322k
        float b = right[i];
1498
322k
        left[i] = a + b;
1499
322k
        right[i] = a - b;
1500
322k
    }
1501
263k
}
1502
1503
static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr)
1504
10.0M
{
1505
10.0M
    int i;
1506
185M
    for (i = 0; i < n; i++)
1507
175M
    {
1508
175M
        left[i + 576] = left[i]*kr;
1509
175M
        left[i] = left[i]*kl;
1510
175M
    }
1511
10.0M
}
1512
1513
static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3])
1514
317k
{
1515
317k
    int i, k;
1516
1517
317k
    max_band[0] = max_band[1] = max_band[2] = -1;
1518
1519
10.3M
    for (i = 0; i < nbands; i++)
1520
10.0M
    {
1521
91.5M
        for (k = 0; k < sfb[i]; k += 2)
1522
81.8M
        {
1523
81.8M
            if (right[k] != 0 || right[k + 1] != 0)
1524
340k
            {
1525
340k
                max_band[i % 3] = i;
1526
340k
                break;
1527
340k
            }
1528
81.8M
        }
1529
10.0M
        right += sfb[i];
1530
10.0M
    }
1531
317k
}
1532
1533
static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh)
1534
317k
{
1535
317k
    static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 };
1536
317k
    unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64;
1537
1538
10.9M
    for (i = 0; sfb[i]; i++)
1539
10.6M
    {
1540
10.6M
        unsigned ipos = ist_pos[i];
1541
10.6M
        if ((int)i > max_band[i % 3] && ipos < max_pos)
1542
10.0M
        {
1543
10.0M
            float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1;
1544
10.0M
            if (DRMP3_HDR_TEST_MPEG1(hdr))
1545
1.86M
            {
1546
1.86M
                kl = g_pan[2*ipos];
1547
1.86M
                kr = g_pan[2*ipos + 1];
1548
1.86M
            } else
1549
8.23M
            {
1550
8.23M
                kl = 1;
1551
8.23M
                kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
1552
8.23M
                if (ipos & 1)
1553
22.3k
                {
1554
22.3k
                    kl = kr;
1555
22.3k
                    kr = 1;
1556
22.3k
                }
1557
8.23M
            }
1558
10.0M
            drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s);
1559
10.0M
        } else if (DRMP3_HDR_TEST_MS_STEREO(hdr))
1560
263k
        {
1561
263k
            drmp3_L3_midside_stereo(left, sfb[i]);
1562
263k
        }
1563
10.6M
        left += sfb[i];
1564
10.6M
    }
1565
317k
}
1566
1567
static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
1568
317k
{
1569
317k
    int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb;
1570
317k
    int i, max_blocks = gr->n_short_sfb ? 3 : 1;
1571
1572
317k
    drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band);
1573
317k
    if (gr->n_long_sfb)
1574
294k
    {
1575
294k
        max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]);
1576
294k
    }
1577
1.06M
    for (i = 0; i < max_blocks; i++)
1578
746k
    {
1579
746k
        int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0;
1580
746k
        int itop = n_sfb - max_blocks + i;
1581
746k
        int prev = itop - max_blocks;
1582
746k
        ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]);
1583
746k
    }
1584
317k
    drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
1585
317k
}
1586
1587
static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb)
1588
219k
{
1589
219k
    int i, len;
1590
219k
    float *src = grbuf, *dst = scratch;
1591
1592
2.68M
    for (;0 != (len = *sfb); sfb += 3, src += 2*len)
1593
2.46M
    {
1594
41.5M
        for (i = 0; i < len; i++, src++)
1595
39.0M
        {
1596
39.0M
            *dst++ = src[0*len];
1597
39.0M
            *dst++ = src[1*len];
1598
39.0M
            *dst++ = src[2*len];
1599
39.0M
        }
1600
2.46M
    }
1601
219k
    DRMP3_COPY_MEMORY(grbuf, scratch, (dst - scratch)*sizeof(float));
1602
219k
}
1603
1604
static void drmp3_L3_antialias(float *grbuf, int nbands)
1605
395k
{
1606
395k
    static const float g_aa[2][8] = {
1607
395k
        {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f},
1608
395k
        {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f}
1609
395k
    };
1610
1611
6.41M
    for (; nbands > 0; nbands--, grbuf += 18)
1612
6.01M
    {
1613
6.01M
        int i = 0;
1614
6.01M
#if DRMP3_HAVE_SIMD
1615
18.0M
        if (drmp3_have_simd()) for (; i < 8; i += 4)
1616
12.0M
        {
1617
12.0M
            drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i);
1618
12.0M
            drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i);
1619
12.0M
            drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i);
1620
12.0M
            drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i);
1621
12.0M
            vd = DRMP3_VREV(vd);
1622
12.0M
            DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1)));
1623
12.0M
            vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0));
1624
12.0M
            DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd));
1625
12.0M
        }
1626
6.01M
#endif
1627
#ifndef DR_MP3_ONLY_SIMD
1628
        for(; i < 8; i++)
1629
        {
1630
            float u = grbuf[18 + i];
1631
            float d = grbuf[17 - i];
1632
            grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i];
1633
            grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i];
1634
        }
1635
#endif
1636
6.01M
    }
1637
395k
}
1638
1639
static void drmp3_L3_dct3_9(float *y)
1640
12.7M
{
1641
12.7M
    float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4;
1642
1643
12.7M
    s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8];
1644
12.7M
    t0 = s0 + s6*0.5f;
1645
12.7M
    s0 -= s6;
1646
12.7M
    t4 = (s4 + s2)*0.93969262f;
1647
12.7M
    t2 = (s8 + s2)*0.76604444f;
1648
12.7M
    s6 = (s4 - s8)*0.17364818f;
1649
12.7M
    s4 += s8 - s2;
1650
1651
12.7M
    s2 = s0 - s4*0.5f;
1652
12.7M
    y[4] = s4 + s0;
1653
12.7M
    s8 = t0 - t2 + s6;
1654
12.7M
    s0 = t0 - t4 + t2;
1655
12.7M
    s4 = t0 + t4 - s6;
1656
1657
12.7M
    s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7];
1658
1659
12.7M
    s3 *= 0.86602540f;
1660
12.7M
    t0 = (s5 + s1)*0.98480775f;
1661
12.7M
    t4 = (s5 - s7)*0.34202014f;
1662
12.7M
    t2 = (s1 + s7)*0.64278761f;
1663
12.7M
    s1 = (s1 - s5 - s7)*0.86602540f;
1664
1665
12.7M
    s5 = t0 - s3 - t2;
1666
12.7M
    s7 = t4 - s3 - t0;
1667
12.7M
    s3 = t4 + s3 - t2;
1668
1669
12.7M
    y[0] = s4 - s7;
1670
12.7M
    y[1] = s2 + s1;
1671
12.7M
    y[2] = s0 - s3;
1672
12.7M
    y[3] = s8 + s5;
1673
12.7M
    y[5] = s8 - s5;
1674
12.7M
    y[6] = s0 + s3;
1675
12.7M
    y[7] = s2 - s1;
1676
12.7M
    y[8] = s4 + s7;
1677
12.7M
}
1678
1679
static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands)
1680
420k
{
1681
420k
    int i, j;
1682
420k
    static const float g_twid9[18] = {
1683
420k
        0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f
1684
420k
    };
1685
1686
6.81M
    for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9)
1687
6.39M
    {
1688
6.39M
        float co[9], si[9];
1689
6.39M
        co[0] = -grbuf[0];
1690
6.39M
        si[0] = grbuf[17];
1691
31.9M
        for (i = 0; i < 4; i++)
1692
25.5M
        {
1693
25.5M
            si[8 - 2*i] =   grbuf[4*i + 1] - grbuf[4*i + 2];
1694
25.5M
            co[1 + 2*i] =   grbuf[4*i + 1] + grbuf[4*i + 2];
1695
25.5M
            si[7 - 2*i] =   grbuf[4*i + 4] - grbuf[4*i + 3];
1696
25.5M
            co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]);
1697
25.5M
        }
1698
6.39M
        drmp3_L3_dct3_9(co);
1699
6.39M
        drmp3_L3_dct3_9(si);
1700
1701
6.39M
        si[1] = -si[1];
1702
6.39M
        si[3] = -si[3];
1703
6.39M
        si[5] = -si[5];
1704
6.39M
        si[7] = -si[7];
1705
1706
6.39M
        i = 0;
1707
1708
6.39M
#if DRMP3_HAVE_SIMD
1709
19.1M
        if (drmp3_have_simd()) for (; i < 8; i += 4)
1710
12.7M
        {
1711
12.7M
            drmp3_f4 vovl = DRMP3_VLD(overlap + i);
1712
12.7M
            drmp3_f4 vc = DRMP3_VLD(co + i);
1713
12.7M
            drmp3_f4 vs = DRMP3_VLD(si + i);
1714
12.7M
            drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i);
1715
12.7M
            drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i);
1716
12.7M
            drmp3_f4 vw0 = DRMP3_VLD(window + i);
1717
12.7M
            drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i);
1718
12.7M
            drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0));
1719
12.7M
            DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1)));
1720
12.7M
            DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1)));
1721
12.7M
            vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0));
1722
12.7M
            DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum));
1723
12.7M
        }
1724
6.39M
#endif
1725
12.7M
        for (; i < 9; i++)
1726
6.39M
        {
1727
6.39M
            float ovl  = overlap[i];
1728
6.39M
            float sum  = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i];
1729
6.39M
            overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i];
1730
6.39M
            grbuf[i]      = ovl*window[0 + i] - sum*window[9 + i];
1731
6.39M
            grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i];
1732
6.39M
        }
1733
6.39M
    }
1734
420k
}
1735
1736
static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst)
1737
37.5M
{
1738
37.5M
    float m1 = x1*0.86602540f;
1739
37.5M
    float a1 = x0 - x2*0.5f;
1740
37.5M
    dst[1] = x0 + x2;
1741
37.5M
    dst[0] = a1 + m1;
1742
37.5M
    dst[2] = a1 - m1;
1743
37.5M
}
1744
1745
static void drmp3_L3_imdct12(float *x, float *dst, float *overlap)
1746
18.7M
{
1747
18.7M
    static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f };
1748
18.7M
    float co[3], si[3];
1749
18.7M
    int i;
1750
1751
18.7M
    drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co);
1752
18.7M
    drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si);
1753
18.7M
    si[1] = -si[1];
1754
1755
75.0M
    for (i = 0; i < 3; i++)
1756
56.2M
    {
1757
56.2M
        float ovl  = overlap[i];
1758
56.2M
        float sum  = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i];
1759
56.2M
        overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i];
1760
56.2M
        dst[i]     = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i];
1761
56.2M
        dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i];
1762
56.2M
    }
1763
18.7M
}
1764
1765
static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands)
1766
219k
{
1767
6.47M
    for (;nbands > 0; nbands--, overlap += 9, grbuf += 18)
1768
6.25M
    {
1769
6.25M
        float tmp[18];
1770
6.25M
        DRMP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp));
1771
6.25M
        DRMP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float));
1772
6.25M
        drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
1773
6.25M
        drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
1774
6.25M
        drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
1775
6.25M
    }
1776
219k
}
1777
1778
static void drmp3_L3_change_sign(float *grbuf)
1779
395k
{
1780
395k
    int b, i;
1781
6.71M
    for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36)
1782
63.2M
        for (i = 1; i < 18; i += 2)
1783
56.8M
            grbuf[i] = -grbuf[i];
1784
395k
}
1785
1786
static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands)
1787
395k
{
1788
395k
    static const float g_mdct_window[2][18] = {
1789
395k
        { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f },
1790
395k
        { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f }
1791
395k
    };
1792
395k
    if (n_long_bands)
1793
244k
    {
1794
244k
        drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands);
1795
244k
        grbuf += 18*n_long_bands;
1796
244k
        overlap += 9*n_long_bands;
1797
244k
    }
1798
395k
    if (block_type == DRMP3_SHORT_BLOCK_TYPE)
1799
219k
        drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands);
1800
175k
    else
1801
175k
        drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands);
1802
395k
}
1803
1804
static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s)
1805
320k
{
1806
320k
    int pos = (s->bs.pos + 7)/8u;
1807
320k
    int remains = s->bs.limit/8u - pos;
1808
320k
    if (remains > DRMP3_MAX_BITRESERVOIR_BYTES)
1809
939
    {
1810
939
        pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES;
1811
939
        remains = DRMP3_MAX_BITRESERVOIR_BYTES;
1812
939
    }
1813
320k
    if (remains > 0)
1814
298k
    {
1815
298k
        DRMP3_MOVE_MEMORY(h->reserv_buf, s->maindata + pos, remains);
1816
298k
    }
1817
320k
    h->reserv = remains;
1818
320k
}
1819
1820
static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
1821
320k
{
1822
320k
    int frame_bytes = (bs->limit - bs->pos)/8;
1823
320k
    int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
1824
320k
    DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
1825
320k
    DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
1826
320k
    drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
1827
320k
    return h->reserv >= main_data_begin;
1828
320k
}
1829
1830
static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
1831
333k
{
1832
333k
    int ch;
1833
1834
728k
    for (ch = 0; ch < nch; ch++)
1835
395k
    {
1836
395k
        int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
1837
395k
        drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
1838
395k
        drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
1839
395k
    }
1840
1841
333k
    if (DRMP3_HDR_TEST_I_STEREO(h->header))
1842
317k
    {
1843
317k
        drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
1844
317k
    } else if (DRMP3_HDR_IS_MS_STEREO(h->header))
1845
5.24k
    {
1846
5.24k
        drmp3_L3_midside_stereo(s->grbuf[0], 576);
1847
5.24k
    }
1848
1849
728k
    for (ch = 0; ch < nch; ch++, gr_info++)
1850
395k
    {
1851
395k
        int aa_bands = 31;
1852
395k
        int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2);
1853
1854
395k
        if (gr_info->n_short_sfb)
1855
219k
        {
1856
219k
            aa_bands = n_long_bands - 1;
1857
219k
            drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb);
1858
219k
        }
1859
1860
395k
        drmp3_L3_antialias(s->grbuf[ch], aa_bands);
1861
395k
        drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
1862
395k
        drmp3_L3_change_sign(s->grbuf[ch]);
1863
395k
    }
1864
333k
}
1865
1866
static void drmp3d_DCT_II(float *grbuf, int n)
1867
1.49M
{
1868
1.49M
    static const float g_sec[24] = {
1869
1.49M
        10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f
1870
1.49M
    };
1871
1.49M
    int i, k = 0;
1872
1.49M
#if DRMP3_HAVE_SIMD
1873
6.75M
    if (drmp3_have_simd()) for (; k < n; k += 4)
1874
5.26M
    {
1875
5.26M
        drmp3_f4 t[4][8], *x;
1876
5.26M
        float *y = grbuf + k;
1877
1878
47.3M
        for (x = t[0], i = 0; i < 8; i++, x++)
1879
42.1M
        {
1880
42.1M
            drmp3_f4 x0 = DRMP3_VLD(&y[i*18]);
1881
42.1M
            drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]);
1882
42.1M
            drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]);
1883
42.1M
            drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]);
1884
42.1M
            drmp3_f4 t0 = DRMP3_VADD(x0, x3);
1885
42.1M
            drmp3_f4 t1 = DRMP3_VADD(x1, x2);
1886
42.1M
            drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]);
1887
42.1M
            drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]);
1888
42.1M
            x[0] = DRMP3_VADD(t0, t1);
1889
42.1M
            x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]);
1890
42.1M
            x[16] = DRMP3_VADD(t3, t2);
1891
42.1M
            x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]);
1892
42.1M
        }
1893
26.3M
        for (x = t[0], i = 0; i < 4; i++, x += 8)
1894
21.0M
        {
1895
21.0M
            drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1896
21.0M
            xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7);
1897
21.0M
            x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6);
1898
21.0M
            x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5);
1899
21.0M
            x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4);
1900
21.0M
            x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3);
1901
21.0M
            x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2);
1902
21.0M
            x[0] = DRMP3_VADD(x0, x1);
1903
21.0M
            x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f);
1904
21.0M
            x5 = DRMP3_VADD(x5, x6);
1905
21.0M
            x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f);
1906
21.0M
            x7 = DRMP3_VADD(x7, xt);
1907
21.0M
            x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f);
1908
21.0M
            x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */
1909
21.0M
            x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f));
1910
21.0M
            x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
1911
21.0M
            x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6);
1912
21.0M
            x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f);
1913
21.0M
            x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f);
1914
21.0M
            x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f);
1915
21.0M
            x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f);
1916
21.0M
            x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f);
1917
21.0M
            x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f);
1918
21.0M
        }
1919
1920
5.26M
        if (k > n - 3)
1921
395k
        {
1922
395k
#if DRMP3_HAVE_SSE
1923
12.6M
#define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v)
1924
#else
1925
#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[(i)*18],  vget_low_f32(v))
1926
#endif
1927
3.16M
            for (i = 0; i < 7; i++, y += 4*18)
1928
2.76M
            {
1929
2.76M
                drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1930
2.76M
                DRMP3_VSAVE2(0, t[0][i]);
1931
2.76M
                DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s));
1932
2.76M
                DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1933
2.76M
                DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s));
1934
2.76M
            }
1935
395k
            DRMP3_VSAVE2(0, t[0][7]);
1936
395k
            DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7]));
1937
395k
            DRMP3_VSAVE2(2, t[1][7]);
1938
395k
            DRMP3_VSAVE2(3, t[3][7]);
1939
395k
        } else
1940
4.86M
        {
1941
155M
#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[(i)*18], v)
1942
38.9M
            for (i = 0; i < 7; i++, y += 4*18)
1943
34.0M
            {
1944
34.0M
                drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1945
34.0M
                DRMP3_VSAVE4(0, t[0][i]);
1946
34.0M
                DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s));
1947
34.0M
                DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1948
34.0M
                DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s));
1949
34.0M
            }
1950
4.86M
            DRMP3_VSAVE4(0, t[0][7]);
1951
4.86M
            DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7]));
1952
4.86M
            DRMP3_VSAVE4(2, t[1][7]);
1953
4.86M
            DRMP3_VSAVE4(3, t[3][7]);
1954
4.86M
        }
1955
5.26M
    } else
1956
0
#endif
1957
0
#ifdef DR_MP3_ONLY_SIMD
1958
0
    {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
1959
#else
1960
    for (; k < n; k++)
1961
    {
1962
        float t[4][8], *x, *y = grbuf + k;
1963
1964
        for (x = t[0], i = 0; i < 8; i++, x++)
1965
        {
1966
            float x0 = y[i*18];
1967
            float x1 = y[(15 - i)*18];
1968
            float x2 = y[(16 + i)*18];
1969
            float x3 = y[(31 - i)*18];
1970
            float t0 = x0 + x3;
1971
            float t1 = x1 + x2;
1972
            float t2 = (x1 - x2)*g_sec[3*i + 0];
1973
            float t3 = (x0 - x3)*g_sec[3*i + 1];
1974
            x[0] = t0 + t1;
1975
            x[8] = (t0 - t1)*g_sec[3*i + 2];
1976
            x[16] = t3 + t2;
1977
            x[24] = (t3 - t2)*g_sec[3*i + 2];
1978
        }
1979
        for (x = t[0], i = 0; i < 4; i++, x += 8)
1980
        {
1981
            float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1982
            xt = x0 - x7; x0 += x7;
1983
            x7 = x1 - x6; x1 += x6;
1984
            x6 = x2 - x5; x2 += x5;
1985
            x5 = x3 - x4; x3 += x4;
1986
            x4 = x0 - x3; x0 += x3;
1987
            x3 = x1 - x2; x1 += x2;
1988
            x[0] = x0 + x1;
1989
            x[4] = (x0 - x1)*0.70710677f;
1990
            x5 =  x5 + x6;
1991
            x6 = (x6 + x7)*0.70710677f;
1992
            x7 =  x7 + xt;
1993
            x3 = (x3 + x4)*0.70710677f;
1994
            x5 -= x7*0.198912367f;  /* rotate by PI/8 */
1995
            x7 += x5*0.382683432f;
1996
            x5 -= x7*0.198912367f;
1997
            x0 = xt - x6; xt += x6;
1998
            x[1] = (xt + x7)*0.50979561f;
1999
            x[2] = (x4 + x3)*0.54119611f;
2000
            x[3] = (x0 - x5)*0.60134488f;
2001
            x[5] = (x0 + x5)*0.89997619f;
2002
            x[6] = (x4 - x3)*1.30656302f;
2003
            x[7] = (xt - x7)*2.56291556f;
2004
2005
        }
2006
        for (i = 0; i < 7; i++, y += 4*18)
2007
        {
2008
            y[0*18] = t[0][i];
2009
            y[1*18] = t[2][i] + t[3][i] + t[3][i + 1];
2010
            y[2*18] = t[1][i] + t[1][i + 1];
2011
            y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1];
2012
        }
2013
        y[0*18] = t[0][7];
2014
        y[1*18] = t[2][7] + t[3][7];
2015
        y[2*18] = t[1][7];
2016
        y[3*18] = t[3][7];
2017
    }
2018
#endif
2019
1.49M
}
2020
2021
#ifndef DR_MP3_FLOAT_OUTPUT
2022
typedef drmp3_int16 drmp3d_sample_t;
2023
2024
static drmp3_int16 drmp3d_scale_pcm(float sample)
2025
50.4M
{
2026
50.4M
    drmp3_int16 s;
2027
#if DRMP3_HAVE_ARMV6
2028
    drmp3_int32 s32 = (drmp3_int32)(sample + .5f);
2029
    s32 -= (s32 < 0);
2030
    s = (drmp3_int16)drmp3_clip_int16_arm(s32);
2031
#else
2032
50.4M
    if (sample >=  32766.5f) return (drmp3_int16) 32767;
2033
49.7M
    if (sample <= -32767.5f) return (drmp3_int16)-32768;
2034
49.1M
    s = (drmp3_int16)(sample + .5f);
2035
49.1M
    s -= (s < 0);   /* away from zero, to be compliant */
2036
49.1M
#endif
2037
49.1M
    return s;
2038
49.7M
}
2039
#else
2040
typedef float drmp3d_sample_t;
2041
2042
static float drmp3d_scale_pcm(float sample)
2043
{
2044
    return sample*(1.f/32768.f);
2045
}
2046
#endif
2047
2048
static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z)
2049
25.2M
{
2050
25.2M
    float a;
2051
25.2M
    a  = (z[14*64] - z[    0]) * 29;
2052
25.2M
    a += (z[ 1*64] + z[13*64]) * 213;
2053
25.2M
    a += (z[12*64] - z[ 2*64]) * 459;
2054
25.2M
    a += (z[ 3*64] + z[11*64]) * 2037;
2055
25.2M
    a += (z[10*64] - z[ 4*64]) * 5153;
2056
25.2M
    a += (z[ 5*64] + z[ 9*64]) * 6574;
2057
25.2M
    a += (z[ 8*64] - z[ 6*64]) * 37489;
2058
25.2M
    a +=  z[ 7*64]             * 75038;
2059
25.2M
    pcm[0] = drmp3d_scale_pcm(a);
2060
2061
25.2M
    z += 2;
2062
25.2M
    a  = z[14*64] * 104;
2063
25.2M
    a += z[12*64] * 1567;
2064
25.2M
    a += z[10*64] * 9727;
2065
25.2M
    a += z[ 8*64] * 64019;
2066
25.2M
    a += z[ 6*64] * -9975;
2067
25.2M
    a += z[ 4*64] * -45;
2068
25.2M
    a += z[ 2*64] * 146;
2069
25.2M
    a += z[ 0*64] * -5;
2070
25.2M
    pcm[16*nch] = drmp3d_scale_pcm(a);
2071
25.2M
}
2072
2073
static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
2074
6.30M
{
2075
6.30M
    int i;
2076
6.30M
    float *xr = xl + 576*(nch - 1);
2077
6.30M
    drmp3d_sample_t *dstr = dstl + (nch - 1);
2078
2079
6.30M
    static const float g_win[] = {
2080
6.30M
        -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992,
2081
6.30M
        -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856,
2082
6.30M
        -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630,
2083
6.30M
        -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313,
2084
6.30M
        -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908,
2085
6.30M
        -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415,
2086
6.30M
        -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835,
2087
6.30M
        -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169,
2088
6.30M
        -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420,
2089
6.30M
        -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590,
2090
6.30M
        -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679,
2091
6.30M
        -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692,
2092
6.30M
        -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629,
2093
6.30M
        -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494,
2094
6.30M
        -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290
2095
6.30M
    };
2096
6.30M
    float *zlin = lins + 15*64;
2097
6.30M
    const float *w = g_win;
2098
2099
6.30M
    zlin[4*15]     = xl[18*16];
2100
6.30M
    zlin[4*15 + 1] = xr[18*16];
2101
6.30M
    zlin[4*15 + 2] = xl[0];
2102
6.30M
    zlin[4*15 + 3] = xr[0];
2103
2104
6.30M
    zlin[4*31]     = xl[1 + 18*16];
2105
6.30M
    zlin[4*31 + 1] = xr[1 + 18*16];
2106
6.30M
    zlin[4*31 + 2] = xl[1];
2107
6.30M
    zlin[4*31 + 3] = xr[1];
2108
2109
6.30M
    drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
2110
6.30M
    drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
2111
6.30M
    drmp3d_synth_pair(dstl, nch, lins + 4*15);
2112
6.30M
    drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
2113
2114
6.30M
#if DRMP3_HAVE_SIMD
2115
100M
    if (drmp3_have_simd()) for (i = 14; i >= 0; i--)
2116
94.5M
    {
2117
756M
#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
2118
94.5M
#define DRMP3_V0(k) { DRMP3_VLOAD(k) b =               DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a =               DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1));  }
2119
283M
#define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); }
2120
378M
#define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); }
2121
94.5M
        drmp3_f4 a, b;
2122
94.5M
        zlin[4*i]     = xl[18*(31 - i)];
2123
94.5M
        zlin[4*i + 1] = xr[18*(31 - i)];
2124
94.5M
        zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2125
94.5M
        zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2126
94.5M
        zlin[4*i + 64] = xl[1 + 18*(1 + i)];
2127
94.5M
        zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)];
2128
94.5M
        zlin[4*i - 64 + 2] = xl[18*(1 + i)];
2129
94.5M
        zlin[4*i - 64 + 3] = xr[18*(1 + i)];
2130
2131
94.5M
        DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7)
2132
2133
94.5M
        {
2134
94.5M
#ifndef DR_MP3_FLOAT_OUTPUT
2135
94.5M
#if DRMP3_HAVE_SSE
2136
94.5M
            static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
2137
94.5M
            static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
2138
94.5M
            __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
2139
94.5M
                                           _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
2140
94.5M
            dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2141
94.5M
            dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2142
94.5M
            dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2143
94.5M
            dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2144
94.5M
            dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2145
94.5M
            dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2146
94.5M
            dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2147
94.5M
            dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2148
#else
2149
            int16x4_t pcma, pcmb;
2150
            a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2151
            b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2152
            pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2153
            pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2154
            vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1);
2155
            vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1);
2156
            vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0);
2157
            vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0);
2158
            vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3);
2159
            vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3);
2160
            vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2);
2161
            vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
2162
#endif
2163
#else
2164
        #if DRMP3_HAVE_SSE
2165
            static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
2166
        #else
2167
            const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f);
2168
        #endif
2169
            a = DRMP3_VMUL(a, g_scale);
2170
            b = DRMP3_VMUL(b, g_scale);
2171
#if DRMP3_HAVE_SSE
2172
            _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)));
2173
            _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1)));
2174
            _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)));
2175
            _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0)));
2176
            _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)));
2177
            _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3)));
2178
            _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)));
2179
            _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2)));
2180
#else
2181
            vst1q_lane_f32(dstr + (15 - i)*nch, a, 1);
2182
            vst1q_lane_f32(dstr + (17 + i)*nch, b, 1);
2183
            vst1q_lane_f32(dstl + (15 - i)*nch, a, 0);
2184
            vst1q_lane_f32(dstl + (17 + i)*nch, b, 0);
2185
            vst1q_lane_f32(dstr + (47 - i)*nch, a, 3);
2186
            vst1q_lane_f32(dstr + (49 + i)*nch, b, 3);
2187
            vst1q_lane_f32(dstl + (47 - i)*nch, a, 2);
2188
            vst1q_lane_f32(dstl + (49 + i)*nch, b, 2);
2189
#endif
2190
#endif /* DR_MP3_FLOAT_OUTPUT */
2191
94.5M
        }
2192
94.5M
    } else
2193
0
#endif
2194
0
#ifdef DR_MP3_ONLY_SIMD
2195
0
    {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
2196
#else
2197
    for (i = 14; i >= 0; i--)
2198
    {
2199
#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
2200
#define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j]  = vz[j]*w1 + vy[j]*w0, a[j]  = vz[j]*w0 - vy[j]*w1; }
2201
#define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
2202
#define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
2203
        float a[4], b[4];
2204
2205
        zlin[4*i]     = xl[18*(31 - i)];
2206
        zlin[4*i + 1] = xr[18*(31 - i)];
2207
        zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2208
        zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2209
        zlin[4*(i + 16)]   = xl[1 + 18*(1 + i)];
2210
        zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)];
2211
        zlin[4*(i - 16) + 2] = xl[18*(1 + i)];
2212
        zlin[4*(i - 16) + 3] = xr[18*(1 + i)];
2213
2214
        DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7)
2215
2216
        dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]);
2217
        dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]);
2218
        dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]);
2219
        dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]);
2220
        dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]);
2221
        dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]);
2222
        dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]);
2223
        dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]);
2224
    }
2225
#endif
2226
6.30M
}
2227
2228
static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins)
2229
883k
{
2230
883k
    int i;
2231
2.37M
    for (i = 0; i < nch; i++)
2232
1.49M
    {
2233
1.49M
        drmp3d_DCT_II(grbuf + 576*i, nbands);
2234
1.49M
    }
2235
2236
883k
    DRMP3_COPY_MEMORY(lins, qmf_state, sizeof(float)*15*64);
2237
2238
7.18M
    for (i = 0; i < nbands; i += 2)
2239
6.30M
    {
2240
6.30M
        drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
2241
6.30M
    }
2242
883k
#ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL
2243
883k
    if (nch == 1)
2244
276k
    {
2245
132M
        for (i = 0; i < 15*64; i += 2)
2246
132M
        {
2247
132M
            qmf_state[i] = lins[nbands*64 + i];
2248
132M
        }
2249
276k
    } else
2250
607k
#endif
2251
607k
    {
2252
607k
        DRMP3_COPY_MEMORY(qmf_state, lins + nbands*64, sizeof(float)*15*64);
2253
607k
    }
2254
883k
}
2255
2256
static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
2257
732k
{
2258
732k
    int i, nmatch;
2259
2.19M
    for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
2260
2.15M
    {
2261
2.15M
        i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
2262
2.15M
        if (i + DRMP3_HDR_SIZE > mp3_bytes)
2263
3.99k
            return nmatch > 0;
2264
2.14M
        if (!drmp3_hdr_compare(hdr, hdr + i))
2265
681k
            return 0;
2266
2.14M
    }
2267
47.4k
    return 1;
2268
732k
}
2269
2270
static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
2271
57.6k
{
2272
57.6k
    int i, k;
2273
65.8M
    for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
2274
65.7M
    {
2275
65.7M
        if (drmp3_hdr_valid(mp3))
2276
946k
        {
2277
946k
            int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
2278
946k
            int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
2279
2280
569M
            for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
2281
568M
            {
2282
568M
                if (drmp3_hdr_compare(mp3, mp3 + k))
2283
8.42M
                {
2284
8.42M
                    int fb = k - drmp3_hdr_padding(mp3);
2285
8.42M
                    int nextfb = fb + drmp3_hdr_padding(mp3 + k);
2286
8.42M
                    if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
2287
8.08M
                        continue;
2288
349k
                    frame_and_padding = k;
2289
349k
                    frame_bytes = fb;
2290
349k
                    *free_format_bytes = fb;
2291
349k
                }
2292
568M
            }
2293
2294
946k
            if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
2295
732k
                drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
2296
895k
                (!i && frame_and_padding == mp3_bytes))
2297
51.3k
            {
2298
51.3k
                *ptr_frame_bytes = frame_and_padding;
2299
51.3k
                return i;
2300
51.3k
            }
2301
894k
            *free_format_bytes = 0;
2302
894k
        }
2303
65.7M
    }
2304
6.33k
    *ptr_frame_bytes = 0;
2305
6.33k
    return mp3_bytes;
2306
57.6k
}
2307
2308
DRMP3_API void drmp3dec_init(drmp3dec *dec)
2309
31.6k
{
2310
31.6k
    dec->header[0] = 0;
2311
31.6k
}
2312
2313
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
2314
535k
{
2315
535k
    int i = 0, igr, frame_size = 0, success = 1;
2316
535k
    const drmp3_uint8 *hdr;
2317
535k
    drmp3_bs bs_frame[1];
2318
2319
535k
    if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
2320
499k
    {
2321
499k
        frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
2322
499k
        if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
2323
21.8k
        {
2324
21.8k
            frame_size = 0;
2325
21.8k
        }
2326
499k
    }
2327
535k
    if (!frame_size)
2328
57.6k
    {
2329
57.6k
        DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec));
2330
57.6k
        i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
2331
57.6k
        if (!frame_size || i + frame_size > mp3_bytes)
2332
6.33k
        {
2333
6.33k
            info->frame_bytes = i;
2334
6.33k
            return 0;
2335
6.33k
        }
2336
57.6k
    }
2337
2338
529k
    hdr = mp3 + i;
2339
529k
    DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE);
2340
529k
    info->frame_bytes = i + frame_size;
2341
529k
    info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
2342
529k
    info->sample_rate = drmp3_hdr_sample_rate_hz(hdr);
2343
529k
    info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
2344
529k
    info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
2345
2346
529k
    drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
2347
529k
    if (DRMP3_HDR_IS_CRC(hdr))
2348
222k
    {
2349
222k
        drmp3_bs_get_bits(bs_frame, 16);
2350
222k
    }
2351
2352
529k
    if (info->layer == 3)
2353
337k
    {
2354
337k
        int main_data_begin = drmp3_L3_read_side_info(bs_frame, dec->scratch.gr_info, hdr);
2355
337k
        if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
2356
17.0k
        {
2357
17.0k
            drmp3dec_init(dec);
2358
17.0k
            return 0;
2359
17.0k
        }
2360
320k
        success = drmp3_L3_restore_reservoir(dec, bs_frame, &dec->scratch, main_data_begin);
2361
320k
        if (success && pcm != NULL)
2362
298k
        {
2363
632k
            for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
2364
333k
            {
2365
333k
                DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float));
2366
333k
                drmp3_L3_decode(dec, &dec->scratch, dec->scratch.gr_info + igr*info->channels, info->channels);
2367
333k
                drmp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, dec->scratch.syn[0]);
2368
333k
            }
2369
298k
        }
2370
320k
        drmp3_L3_save_reservoir(dec, &dec->scratch);
2371
320k
    } else
2372
191k
    {
2373
#ifdef DR_MP3_ONLY_MP3
2374
        return 0;
2375
#else
2376
191k
        drmp3_L12_scale_info sci[1];
2377
2378
191k
        if (pcm == NULL) {
2379
0
            return drmp3_hdr_frame_samples(hdr);
2380
0
        }
2381
2382
191k
        drmp3_L12_read_scale_info(hdr, bs_frame, sci);
2383
2384
191k
        DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float));
2385
735k
        for (i = 0, igr = 0; igr < 3; igr++)
2386
555k
        {
2387
555k
            if (12 == (i += drmp3_L12_dequantize_granule(dec->scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
2388
550k
            {
2389
550k
                i = 0;
2390
550k
                drmp3_L12_apply_scf_384(sci, sci->scf + igr, dec->scratch.grbuf[0]);
2391
550k
                drmp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, dec->scratch.syn[0]);
2392
550k
                DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float));
2393
550k
                pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
2394
550k
            }
2395
555k
            if (bs_frame->pos > bs_frame->limit)
2396
11.1k
            {
2397
11.1k
                drmp3dec_init(dec);
2398
11.1k
                return 0;
2399
11.1k
            }
2400
555k
        }
2401
191k
#endif
2402
191k
    }
2403
2404
500k
    return success*drmp3_hdr_frame_samples(dec->header);
2405
529k
}
2406
2407
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
2408
0
{
2409
0
    size_t i = 0;
2410
0
#if DRMP3_HAVE_SIMD
2411
0
    size_t aligned_count = num_samples & ~7;
2412
0
    for(; i < aligned_count; i+=8)
2413
0
    {
2414
0
        drmp3_f4 scale = DRMP3_VSET(32768.0f);
2415
0
        drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i  ]), scale);
2416
0
        drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale);
2417
0
#if DRMP3_HAVE_SSE
2418
0
        drmp3_f4 s16max = DRMP3_VSET( 32767.0f);
2419
0
        drmp3_f4 s16min = DRMP3_VSET(-32768.0f);
2420
0
        __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)),
2421
0
                                        _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min)));
2422
0
        out[i  ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2423
0
        out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2424
0
        out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2425
0
        out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2426
0
        out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2427
0
        out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2428
0
        out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2429
0
        out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2430
#else
2431
        int16x4_t pcma, pcmb;
2432
        a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2433
        b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2434
        pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2435
        pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2436
        vst1_lane_s16(out+i  , pcma, 0);
2437
        vst1_lane_s16(out+i+1, pcma, 1);
2438
        vst1_lane_s16(out+i+2, pcma, 2);
2439
        vst1_lane_s16(out+i+3, pcma, 3);
2440
        vst1_lane_s16(out+i+4, pcmb, 0);
2441
        vst1_lane_s16(out+i+5, pcmb, 1);
2442
        vst1_lane_s16(out+i+6, pcmb, 2);
2443
        vst1_lane_s16(out+i+7, pcmb, 3);
2444
#endif
2445
0
    }
2446
0
#endif
2447
0
    for(; i < num_samples; i++)
2448
0
    {
2449
0
        float sample = in[i] * 32768.0f;
2450
0
        if (sample >=  32766.5f)
2451
0
            out[i] = (drmp3_int16) 32767;
2452
0
        else if (sample <= -32767.5f)
2453
0
            out[i] = (drmp3_int16)-32768;
2454
0
        else
2455
0
        {
2456
0
            short s = (drmp3_int16)(sample + .5f);
2457
0
            s -= (s < 0);   /* away from zero, to be compliant */
2458
0
            out[i] = s;
2459
0
        }
2460
0
    }
2461
0
}
2462
2463
2464
2465
/************************************************************************************************************************************************************
2466
2467
 Main Public API
2468
2469
 ************************************************************************************************************************************************************/
2470
/* SIZE_MAX */
2471
#if defined(SIZE_MAX)
2472
3.47k
    #define DRMP3_SIZE_MAX  SIZE_MAX
2473
#else
2474
    #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
2475
        #define DRMP3_SIZE_MAX  ((drmp3_uint64)0xFFFFFFFFFFFFFFFF)
2476
    #else
2477
        #define DRMP3_SIZE_MAX  0xFFFFFFFF
2478
    #endif
2479
#endif
2480
/* End SIZE_MAX */
2481
2482
/* Options. */
2483
#ifndef DRMP3_SEEK_LEADING_MP3_FRAMES
2484
0
#define DRMP3_SEEK_LEADING_MP3_FRAMES   2
2485
#endif
2486
2487
0
#define DRMP3_MIN_DATA_CHUNK_SIZE   16384
2488
2489
/* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */
2490
#ifndef DRMP3_DATA_CHUNK_SIZE
2491
0
#define DRMP3_DATA_CHUNK_SIZE  (DRMP3_MIN_DATA_CHUNK_SIZE*4)
2492
#endif
2493
2494
2495
306k
#define DRMP3_COUNTOF(x)        (sizeof(x) / sizeof(x[0]))
2496
#define DRMP3_CLAMP(x, lo, hi)  (DRMP3_MAX(lo, DRMP3_MIN(x, hi)))
2497
2498
#ifndef DRMP3_PI_D
2499
#define DRMP3_PI_D    3.14159265358979323846264
2500
#endif
2501
2502
#define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER   2
2503
2504
static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a)
2505
0
{
2506
0
    return x*(1-a) + y*a;
2507
0
}
2508
static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a)
2509
0
{
2510
0
    float r0 = (y - x);
2511
0
    float r1 = r0*a;
2512
0
    return x + r1;
2513
0
    /*return x + (y - x)*a;*/
2514
0
}
2515
2516
2517
/*
2518
Greatest common factor using Euclid's algorithm iteratively.
2519
*/
2520
static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b)
2521
0
{
2522
0
    for (;;) {
2523
0
        if (b == 0) {
2524
0
            break;
2525
0
        } else {
2526
0
            drmp3_uint32 t = a;
2527
0
            a = b;
2528
0
            b = t % a;
2529
0
        }
2530
0
    }
2531
0
2532
0
    return a;
2533
0
}
2534
2535
2536
static void* drmp3__malloc_default(size_t sz, void* pUserData)
2537
0
{
2538
0
    (void)pUserData;
2539
0
    return DRMP3_MALLOC(sz);
2540
0
}
2541
2542
static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData)
2543
0
{
2544
0
    (void)pUserData;
2545
0
    return DRMP3_REALLOC(p, sz);
2546
0
}
2547
2548
static void drmp3__free_default(void* p, void* pUserData)
2549
0
{
2550
0
    (void)pUserData;
2551
0
    DRMP3_FREE(p);
2552
0
}
2553
2554
2555
static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
2556
0
{
2557
0
    if (pAllocationCallbacks == NULL) {
2558
0
        return NULL;
2559
0
    }
2560
2561
0
    if (pAllocationCallbacks->onMalloc != NULL) {
2562
0
        return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
2563
0
    }
2564
2565
    /* Try using realloc(). */
2566
0
    if (pAllocationCallbacks->onRealloc != NULL) {
2567
0
        return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
2568
0
    }
2569
2570
0
    return NULL;
2571
0
}
2572
2573
static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
2574
0
{
2575
0
    if (pAllocationCallbacks == NULL) {
2576
0
        return NULL;
2577
0
    }
2578
2579
0
    if (pAllocationCallbacks->onRealloc != NULL) {
2580
0
        return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
2581
0
    }
2582
2583
    /* Try emulating realloc() in terms of malloc()/free(). */
2584
0
    if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
2585
0
        void* p2;
2586
2587
0
        p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
2588
0
        if (p2 == NULL) {
2589
0
            return NULL;
2590
0
        }
2591
2592
0
        if (p != NULL) {
2593
0
            DRMP3_COPY_MEMORY(p2, p, szOld);
2594
0
            pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2595
0
        }
2596
2597
0
        return p2;
2598
0
    }
2599
2600
0
    return NULL;
2601
0
}
2602
2603
static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
2604
3.00k
{
2605
3.00k
    if (p == NULL || pAllocationCallbacks == NULL) {
2606
3.00k
        return;
2607
3.00k
    }
2608
2609
0
    if (pAllocationCallbacks->onFree != NULL) {
2610
0
        pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2611
0
    }
2612
0
}
2613
2614
2615
static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
2616
3.06k
{
2617
3.06k
    if (pAllocationCallbacks != NULL) {
2618
        /* Copy. */
2619
0
        return *pAllocationCallbacks;
2620
3.06k
    } else {
2621
        /* Defaults. */
2622
3.06k
        drmp3_allocation_callbacks allocationCallbacks;
2623
3.06k
        allocationCallbacks.pUserData = NULL;
2624
3.06k
        allocationCallbacks.onMalloc  = drmp3__malloc_default;
2625
3.06k
        allocationCallbacks.onRealloc = drmp3__realloc_default;
2626
3.06k
        allocationCallbacks.onFree    = drmp3__free_default;
2627
3.06k
        return allocationCallbacks;
2628
3.06k
    }
2629
3.06k
}
2630
2631
2632
2633
static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
2634
0
{
2635
0
    size_t bytesRead;
2636
2637
0
    DRMP3_ASSERT(pMP3         != NULL);
2638
0
    DRMP3_ASSERT(pMP3->onRead != NULL);
2639
2640
    /*
2641
    Don't try reading 0 bytes from the callback. This can happen when the stream is clamped against
2642
    ID3v1 or APE tags at the end of the stream.
2643
    */
2644
0
    if (bytesToRead == 0) {
2645
0
        return 0;
2646
0
    }
2647
2648
0
    bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
2649
0
    pMP3->streamCursor += bytesRead;
2650
2651
0
    return bytesRead;
2652
0
}
2653
2654
static size_t drmp3__on_read_clamped(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
2655
0
{
2656
0
    DRMP3_ASSERT(pMP3         != NULL);
2657
0
    DRMP3_ASSERT(pMP3->onRead != NULL);
2658
2659
0
    if (pMP3->streamLength == DRMP3_UINT64_MAX) {
2660
0
        return drmp3__on_read(pMP3, pBufferOut, bytesToRead);
2661
0
    } else {
2662
0
        drmp3_uint64 bytesRemaining;
2663
2664
0
        bytesRemaining = (pMP3->streamLength - pMP3->streamCursor);
2665
0
        if (bytesToRead >         bytesRemaining) {
2666
0
            bytesToRead = (size_t)bytesRemaining;
2667
0
        }
2668
    
2669
0
        return drmp3__on_read(pMP3, pBufferOut, bytesToRead);
2670
0
    }
2671
0
}
2672
2673
static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
2674
0
{
2675
0
    DRMP3_ASSERT(offset >= 0);
2676
0
    DRMP3_ASSERT(origin == DRMP3_SEEK_SET || origin == DRMP3_SEEK_CUR);
2677
2678
0
    if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
2679
0
        return DRMP3_FALSE;
2680
0
    }
2681
2682
0
    if (origin == DRMP3_SEEK_SET) {
2683
0
        pMP3->streamCursor = (drmp3_uint64)offset;
2684
0
    } else{
2685
0
        pMP3->streamCursor += offset;
2686
0
    }
2687
2688
0
    return DRMP3_TRUE;
2689
0
}
2690
2691
static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin)
2692
0
{
2693
0
    if (offset <= 0x7FFFFFFF) {
2694
0
        return drmp3__on_seek(pMP3, (int)offset, origin);
2695
0
    }
2696
2697
    /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */
2698
0
    if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_SET)) {
2699
0
        return DRMP3_FALSE;
2700
0
    }
2701
2702
0
    offset -= 0x7FFFFFFF;
2703
0
    while (offset > 0) {
2704
0
        if (offset <= 0x7FFFFFFF) {
2705
0
            if (!drmp3__on_seek(pMP3, (int)offset, DRMP3_SEEK_CUR)) {
2706
0
                return DRMP3_FALSE;
2707
0
            }
2708
0
            offset = 0;
2709
0
        } else {
2710
0
            if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_CUR)) {
2711
0
                return DRMP3_FALSE;
2712
0
            }
2713
0
            offset -= 0x7FFFFFFF;
2714
0
        }
2715
0
    }
2716
2717
0
    return DRMP3_TRUE;
2718
0
}
2719
2720
static void drmp3__on_meta(drmp3* pMP3, drmp3_metadata_type type, const void* pRawData, size_t rawDataSize)
2721
0
{
2722
0
    if (pMP3->onMeta) {
2723
0
        drmp3_metadata metadata;
2724
2725
0
        DRMP3_ZERO_OBJECT(&metadata);
2726
0
        metadata.type        = type;
2727
0
        metadata.pRawData    = pRawData;
2728
0
        metadata.rawDataSize = rawDataSize;
2729
2730
0
        pMP3->onMeta(pMP3->pUserDataMeta, &metadata);
2731
0
    }
2732
0
}
2733
2734
2735
static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData)
2736
0
{
2737
0
    drmp3_uint32 pcmFramesRead = 0;
2738
2739
0
    DRMP3_ASSERT(pMP3 != NULL);
2740
0
    DRMP3_ASSERT(pMP3->onRead != NULL);
2741
2742
0
    if (pMP3->atEnd) {
2743
0
        return 0;
2744
0
    }
2745
2746
0
    for (;;) {
2747
0
        drmp3dec_frame_info info;
2748
2749
        /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */
2750
0
        if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
2751
0
            size_t bytesRead;
2752
2753
            /* First we need to move the data down. */
2754
0
            if (pMP3->pData != NULL) {
2755
0
                DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2756
0
            }
2757
2758
0
            pMP3->dataConsumed = 0;
2759
2760
0
            if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
2761
0
                drmp3_uint8* pNewData;
2762
0
                size_t newDataCap;
2763
2764
0
                newDataCap = DRMP3_DATA_CHUNK_SIZE;
2765
2766
0
                pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2767
0
                if (pNewData == NULL) {
2768
0
                    return 0; /* Out of memory. */
2769
0
                }
2770
2771
0
                pMP3->pData = pNewData;
2772
0
                pMP3->dataCapacity = newDataCap;
2773
0
            }
2774
2775
0
            bytesRead = drmp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2776
0
            if (bytesRead == 0) {
2777
0
                if (pMP3->dataSize == 0) {
2778
0
                    pMP3->atEnd = DRMP3_TRUE;
2779
0
                    return 0; /* No data. */
2780
0
                }
2781
0
            }
2782
2783
0
            pMP3->dataSize += bytesRead;
2784
0
        }
2785
2786
0
        if (pMP3->dataSize > INT_MAX) {
2787
0
            pMP3->atEnd = DRMP3_TRUE;
2788
0
            return 0; /* File too big. */
2789
0
        }
2790
2791
0
        DRMP3_ASSERT(pMP3->pData != NULL);
2792
0
        DRMP3_ASSERT(pMP3->dataCapacity > 0);
2793
2794
        /* Do a runtime check here to try silencing a false-positive from clang-analyzer. */
2795
0
        if (pMP3->pData == NULL) {
2796
0
            return 0;
2797
0
        }
2798
2799
0
        pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);    /* <-- Safe size_t -> int conversion thanks to the check above. */
2800
2801
        /* Consume the data. */
2802
0
        pMP3->dataConsumed += (size_t)info.frame_bytes;
2803
0
        pMP3->dataSize     -= (size_t)info.frame_bytes;
2804
2805
        /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */
2806
0
        if (pcmFramesRead > 0) {
2807
0
            pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2808
0
            pMP3->pcmFramesConsumedInMP3Frame = 0;
2809
0
            pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2810
0
            pMP3->mp3FrameChannels = info.channels;
2811
0
            pMP3->mp3FrameSampleRate = info.sample_rate;
2812
2813
0
            if (pMP3FrameInfo != NULL) {
2814
0
                *pMP3FrameInfo = info;
2815
0
            }
2816
2817
0
            if (ppMP3FrameData != NULL) {
2818
0
                *ppMP3FrameData = pMP3->pData + pMP3->dataConsumed - (size_t)info.frame_bytes;
2819
0
            }
2820
2821
0
            break;
2822
0
        } else if (info.frame_bytes == 0) {
2823
            /* Need more data. minimp3 recommends doing data submission in 16K chunks. */
2824
0
            size_t bytesRead;
2825
2826
            /* First we need to move the data down. */
2827
0
            DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2828
0
            pMP3->dataConsumed = 0;
2829
2830
0
            if (pMP3->dataCapacity == pMP3->dataSize) {
2831
                /* No room. Expand. */
2832
0
                drmp3_uint8* pNewData;
2833
0
                size_t newDataCap;
2834
2835
0
                newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
2836
2837
0
                pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2838
0
                if (pNewData == NULL) {
2839
0
                    return 0; /* Out of memory. */
2840
0
                }
2841
2842
0
                pMP3->pData = pNewData;
2843
0
                pMP3->dataCapacity = newDataCap;
2844
0
            }
2845
2846
            /* Fill in a chunk. */
2847
0
            bytesRead = drmp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2848
0
            if (bytesRead == 0) {
2849
0
                pMP3->atEnd = DRMP3_TRUE;
2850
0
                return 0; /* Error reading more data. */
2851
0
            }
2852
2853
0
            pMP3->dataSize += bytesRead;
2854
0
        }
2855
0
    };
2856
2857
0
    return pcmFramesRead;
2858
0
}
2859
2860
static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData)
2861
483k
{
2862
483k
    drmp3_uint32 pcmFramesRead = 0;
2863
483k
    drmp3dec_frame_info info;
2864
2865
483k
    DRMP3_ASSERT(pMP3 != NULL);
2866
483k
    DRMP3_ASSERT(pMP3->memory.pData != NULL);
2867
2868
483k
    if (pMP3->atEnd) {
2869
0
        return 0;
2870
0
    }
2871
2872
535k
    for (;;) {
2873
535k
        pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
2874
535k
        if (pcmFramesRead > 0) {
2875
479k
            pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2876
479k
            pMP3->pcmFramesConsumedInMP3Frame  = 0;
2877
479k
            pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2878
479k
            pMP3->mp3FrameChannels             = info.channels;
2879
479k
            pMP3->mp3FrameSampleRate           = info.sample_rate;
2880
2881
479k
            if (pMP3FrameInfo != NULL) {
2882
1.73k
                *pMP3FrameInfo = info;
2883
1.73k
            }
2884
2885
479k
            if (ppMP3FrameData != NULL) {
2886
1.73k
                *ppMP3FrameData = pMP3->memory.pData + pMP3->memory.currentReadPos;
2887
1.73k
            }
2888
2889
479k
            break;
2890
479k
        } else if (info.frame_bytes > 0) {
2891
            /* No frames were read, but it looks like we skipped past one. Read the next MP3 frame. */
2892
51.6k
            pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2893
51.6k
            pMP3->streamCursor          += (size_t)info.frame_bytes;
2894
51.6k
        } else {
2895
            /* Nothing at all was read. Abort. */
2896
4.23k
            break;
2897
4.23k
        }
2898
535k
    }
2899
2900
    /* Consume the data. */
2901
483k
    pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2902
483k
    pMP3->streamCursor          += (size_t)info.frame_bytes;
2903
2904
483k
    return pcmFramesRead;
2905
483k
}
2906
2907
static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData)
2908
483k
{
2909
483k
    if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
2910
483k
        return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData);
2911
483k
    } else {
2912
0
        return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData);
2913
0
    }
2914
483k
}
2915
2916
static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
2917
480k
{
2918
480k
    DRMP3_ASSERT(pMP3 != NULL);
2919
480k
    return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames, NULL, NULL);
2920
480k
}
2921
2922
#if 0
2923
static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
2924
{
2925
    drmp3_uint32 pcmFrameCount;
2926
2927
    DRMP3_ASSERT(pMP3 != NULL);
2928
2929
    pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
2930
    if (pcmFrameCount == 0) {
2931
        return 0;
2932
    }
2933
2934
    /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */
2935
    pMP3->currentPCMFrame             += pcmFrameCount;
2936
    pMP3->pcmFramesConsumedInMP3Frame  = pcmFrameCount;
2937
    pMP3->pcmFramesRemainingInMP3Frame = 0;
2938
2939
    return pcmFrameCount;
2940
}
2941
#endif
2942
2943
static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks)
2944
3.06k
{
2945
3.06k
    drmp3dec_frame_info firstFrameInfo;
2946
3.06k
    const drmp3_uint8* pFirstFrameData;
2947
3.06k
    drmp3_uint32 firstFramePCMFrameCount;
2948
3.06k
    drmp3_uint32 detectedMP3FrameCount = 0xFFFFFFFF;
2949
2950
3.06k
    DRMP3_ASSERT(pMP3 != NULL);
2951
3.06k
    DRMP3_ASSERT(onRead != NULL);
2952
2953
    /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
2954
3.06k
    drmp3dec_init(&pMP3->decoder);
2955
2956
3.06k
    pMP3->onRead = onRead;
2957
3.06k
    pMP3->onSeek = onSeek;
2958
3.06k
    pMP3->onMeta = onMeta;
2959
3.06k
    pMP3->pUserData = pUserData;
2960
3.06k
    pMP3->pUserDataMeta = pUserDataMeta;
2961
3.06k
    pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
2962
2963
3.06k
    if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
2964
0
        return DRMP3_FALSE;    /* Invalid allocation callbacks. */
2965
0
    }
2966
2967
3.06k
    pMP3->streamCursor       = 0;
2968
3.06k
    pMP3->streamLength       = DRMP3_UINT64_MAX;
2969
3.06k
    pMP3->streamStartOffset  = 0;
2970
3.06k
    pMP3->delayInPCMFrames   = 0;
2971
3.06k
    pMP3->paddingInPCMFrames = 0;
2972
3.06k
    pMP3->totalPCMFrameCount = DRMP3_UINT64_MAX;
2973
2974
    /* We'll first check for any ID3v1 or APE tags. */
2975
3.06k
    #if 1
2976
3.06k
    if (onSeek != NULL && onTell != NULL) {
2977
3.06k
        if (onSeek(pUserData, 0, DRMP3_SEEK_END)) {
2978
3.06k
            drmp3_int64 streamLen;
2979
3.06k
            int streamEndOffset = 0;
2980
        
2981
            /* First get the length of the stream. We need this so we can ensure the stream is big enough to store the tags. */
2982
3.06k
            if (onTell(pUserData, &streamLen)) {
2983
                /* ID3v1 */
2984
3.06k
                if (streamLen > 128) {
2985
1.16k
                    char id3[3];
2986
1.16k
                    if (onSeek(pUserData, streamEndOffset - 128, DRMP3_SEEK_END)) {
2987
1.16k
                        if (onRead(pUserData, id3, 3) == 3 && id3[0] == 'T' && id3[1] == 'A' && id3[2] == 'G') {
2988
                            /* We have an ID3v1 tag. */
2989
1
                            streamEndOffset -= 128;
2990
1
                            streamLen       -= 128;
2991
2992
                            /* Fire a metadata callback for the TAG data. */
2993
1
                            if (onMeta != NULL) {
2994
0
                                drmp3_uint8 tag[128];
2995
0
                                tag[0] = 'T'; tag[1] = 'A'; tag[2] = 'G';
2996
2997
0
                                if (onRead(pUserData, tag + 3, 125) == 125) {
2998
0
                                    drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_ID3V1, tag, 128);
2999
0
                                }
3000
0
                            }
3001
1.16k
                        } else {
3002
                            /* No ID3v1 tag. */
3003
1.16k
                        }
3004
1.16k
                    } else {
3005
                        /* Failed to seek to the ID3v1 tag. */
3006
0
                    }
3007
1.90k
                } else {
3008
                    /* Stream too short. No ID3v1 tag. */
3009
1.90k
                }
3010
3011
                /* APE */
3012
3.06k
                if (streamLen > 32) {
3013
2.10k
                    char ape[32];   /* The footer. */
3014
2.10k
                    if (onSeek(pUserData, streamEndOffset - 32, DRMP3_SEEK_END)) {
3015
2.10k
                        if (onRead(pUserData, ape, 32) == 32 && ape[0] == 'A' && ape[1] == 'P' && ape[2] == 'E' && ape[3] == 'T' && ape[4] == 'A' && ape[5] == 'G' && ape[6] == 'E' && ape[7] == 'X') {
3016
                            /* We have an APE tag. */
3017
42
                            drmp3_uint32 tagSize =
3018
42
                                ((drmp3_uint32)ape[24] << 0)  |
3019
42
                                ((drmp3_uint32)ape[25] << 8)  |
3020
42
                                ((drmp3_uint32)ape[26] << 16) |
3021
42
                                ((drmp3_uint32)ape[27] << 24);
3022
3023
42
                            if (32 + tagSize < streamLen) {
3024
15
                                streamEndOffset -= 32 + tagSize;
3025
15
                                streamLen       -= 32 + tagSize;
3026
                                
3027
                                /* Fire a metadata callback for the APE data. Must include both the main content and footer. */
3028
15
                                if (onMeta != NULL) {
3029
                                    /* We first need to seek to the start of the APE tag. */
3030
0
                                    if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) {
3031
0
                                        size_t apeTagSize = (size_t)tagSize + 32;
3032
0
                                        drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks);
3033
0
                                        if (pTagData != NULL) {
3034
0
                                            if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) {
3035
0
                                                drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize);
3036
0
                                            }
3037
3038
0
                                            drmp3_free(pTagData, pAllocationCallbacks);
3039
0
                                        }
3040
0
                                    }
3041
0
                                }
3042
27
                            } else {
3043
                                /* The tag size is larger than the stream. Invalid APE tag. */
3044
27
                            }
3045
42
                        }
3046
2.10k
                    }
3047
2.10k
                } else {
3048
                    /* Stream too short. No APE tag. */
3049
955
                }
3050
3051
                /* Seek back to the start. */
3052
3.06k
                if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
3053
0
                    return DRMP3_FALSE; /* Failed to seek back to the start. */
3054
0
                }
3055
3056
3.06k
                pMP3->streamLength = (drmp3_uint64)streamLen;
3057
3058
3.06k
                if (pMP3->memory.pData != NULL) {
3059
3.06k
                    pMP3->memory.dataSize = (size_t)pMP3->streamLength;
3060
3.06k
                }
3061
3.06k
            } else {
3062
                /* Failed to get the length of the stream. ID3v1 and APE tags cannot be skipped. */
3063
0
                if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
3064
0
                    return DRMP3_FALSE; /* Failed to seek back to the start. */
3065
0
                }
3066
0
            }
3067
3.06k
        } else {
3068
            /* Failed to seek to the end. Cannot skip ID3v1 or APE tags. */
3069
0
        }
3070
3.06k
    } else {
3071
        /* No onSeek or onTell callback. Cannot skip ID3v1 or APE tags. */
3072
0
    }
3073
3.06k
    #endif
3074
3075
3076
    /* ID3v2 tags */
3077
3.06k
    #if 1
3078
3.06k
    {
3079
3.06k
        char header[10];
3080
3.06k
        if (onRead(pUserData, header, 10) == 10) {
3081
3.05k
            if (header[0] == 'I' && header[1] == 'D' && header[2] == '3') {
3082
57
                drmp3_uint32 tagSize =
3083
57
                    (((drmp3_uint32)header[6] & 0x7F) << 21) |
3084
57
                    (((drmp3_uint32)header[7] & 0x7F) << 14) |
3085
57
                    (((drmp3_uint32)header[8] & 0x7F) << 7)  |
3086
57
                    (((drmp3_uint32)header[9] & 0x7F) << 0);
3087
3088
                /* Account for the footer. */
3089
57
                if (header[5] & 0x10) {
3090
23
                    tagSize += 10;
3091
23
                }
3092
3093
                /* Read the tag content and fire a metadata callback. */
3094
57
                if (onMeta != NULL) {
3095
0
                    size_t tagSizeWithHeader = 10 + tagSize;
3096
0
                    drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(tagSizeWithHeader, pAllocationCallbacks);
3097
0
                    if (pTagData != NULL) {
3098
0
                        DRMP3_COPY_MEMORY(pTagData, header, 10);
3099
3100
0
                        if (onRead(pUserData, pTagData + 10, tagSize) == tagSize) {
3101
0
                            drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_ID3V2, pTagData, tagSizeWithHeader);
3102
0
                        }
3103
3104
0
                        drmp3_free(pTagData, pAllocationCallbacks);
3105
0
                    }
3106
57
                } else {
3107
                    /* Don't have a metadata callback, so just skip the tag. */
3108
57
                    if (onSeek != NULL) {
3109
57
                        if (!onSeek(pUserData, tagSize, DRMP3_SEEK_CUR)) {
3110
49
                            return DRMP3_FALSE; /* Failed to seek past the ID3v2 tag. */
3111
49
                        }
3112
57
                    } else {
3113
                        /* Don't have a seek callback. Read and discard. */
3114
0
                        char discard[1024];
3115
3116
0
                        while (tagSize > 0) {
3117
0
                            size_t bytesToRead = tagSize;
3118
0
                            if (bytesToRead > sizeof(discard)) {
3119
0
                                bytesToRead = sizeof(discard);
3120
0
                            }
3121
3122
0
                            if (onRead(pUserData, discard, bytesToRead) != bytesToRead) {
3123
0
                                return DRMP3_FALSE; /* Failed to read data. */
3124
0
                            }
3125
3126
0
                            tagSize -= (drmp3_uint32)bytesToRead;
3127
0
                        }
3128
0
                    }
3129
57
                }
3130
3131
8
                pMP3->streamStartOffset += 10 + tagSize;    /* +10 for the header. */
3132
8
                pMP3->streamCursor = pMP3->streamStartOffset;
3133
2.99k
            } else {
3134
                /* Not an ID3v2 tag. Seek back to the start. */
3135
2.99k
                if (onSeek != NULL) {
3136
2.99k
                    if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) {
3137
0
                        return DRMP3_FALSE; /* Failed to seek back to the start. */
3138
0
                    }
3139
2.99k
                } else {
3140
                    /* Don't have a seek callback to move backwards. We'll just fall through and let the decoding process re-sync. The ideal solution here would be to read into the cache. */
3141
3142
                    /*
3143
                    TODO: Copy the header into the cache. Will need to allocate space. See drmp3_decode_next_frame_ex__callbacks. There is not need
3144
                    to handle the memory case because that will always have a seek implementation and will never hit this code path.
3145
                    */
3146
0
                }
3147
2.99k
            }
3148
3.05k
        } else {
3149
            /* Failed to read the header. We can return false here. If we couldn't read 10 bytes there's no way we'll have a valid MP3 stream. */
3150
11
            return DRMP3_FALSE;
3151
11
        }
3152
3.06k
    }
3153
3.00k
    #endif
3154
3155
    /*
3156
    Decode the first frame to confirm that it is indeed a valid MP3 stream. Note that it's possible the first frame
3157
    is actually a Xing/LAME/VBRI header. If this is the case we need to skip over it.
3158
    */
3159
3.00k
    firstFramePCMFrameCount = drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames, &firstFrameInfo, &pFirstFrameData);
3160
3.00k
    if (firstFramePCMFrameCount > 0) {
3161
1.73k
        DRMP3_ASSERT(pFirstFrameData != NULL);
3162
3163
        /*
3164
        It might be a header. If so, we need to clear out the cached PCM frames in order to trigger a reload of fresh
3165
        data when decoding starts. We can assume all validation has already been performed to check if this is a valid
3166
        MP3 frame and that there is more than 0 bytes making up the frame.
3167
3168
        We're going to be basing this parsing code off the minimp3_ex implementation.
3169
        */
3170
1.73k
        #if 1
3171
1.73k
        DRMP3_ASSERT(firstFrameInfo.frame_bytes > 0);
3172
1.73k
        {
3173
1.73k
            drmp3_bs bs;
3174
1.73k
            drmp3_L3_gr_info grInfo[4];
3175
3176
1.73k
            drmp3_bs_init(&bs, pFirstFrameData + DRMP3_HDR_SIZE, firstFrameInfo.frame_bytes - DRMP3_HDR_SIZE);
3177
3178
1.73k
            if (DRMP3_HDR_IS_CRC(pFirstFrameData)) {
3179
282
                drmp3_bs_get_bits(&bs, 16); /* CRC. */
3180
282
            }
3181
3182
1.73k
            if (drmp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) {
3183
1.47k
                drmp3_bool32 isXing = DRMP3_FALSE;
3184
1.47k
                drmp3_bool32 isInfo = DRMP3_FALSE;
3185
1.47k
                const drmp3_uint8* pTagData;
3186
1.47k
                const drmp3_uint8* pTagDataBeg;
3187
1.47k
                const void* pDataBufferEnd = NULL;
3188
1.47k
                size_t frameBytes;
3189
3190
1.47k
                pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8);
3191
1.47k
                pTagData    = pTagDataBeg;
3192
3193
                /*
3194
                We need to determine how many bytes are actually available in pTagData. Unfortunately this is different depending on
3195
                whether or not it's being decoded from memory or callbacks.
3196
                */
3197
1.47k
                if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
3198
1.47k
                    pDataBufferEnd = pMP3->memory.pData + pMP3->memory.dataSize;
3199
1.47k
                } else {
3200
0
                    pDataBufferEnd = pMP3->pData + pMP3->dataCapacity;
3201
0
                }
3202
3203
1.47k
                frameBytes = DRMP3_MIN((size_t)firstFrameInfo.frame_bytes, (size_t)((drmp3_uint8*)pDataBufferEnd - pFirstFrameData));
3204
3205
1.47k
                if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 8) {
3206
448
                    goto done_xing_info;    /* Frame too small for a Xing/Info tag. */
3207
448
                }
3208
3209
                /* Check for both "Xing" and "Info" identifiers. */
3210
1.02k
                isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g');
3211
1.02k
                isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o');
3212
3213
1.02k
                if (isXing || isInfo) {
3214
548
                    drmp3_uint32 bytes = 0;
3215
548
                    drmp3_uint32 flags = pTagData[7];
3216
3217
548
                    pTagData += 8;  /* Skip past the ID and flags. */
3218
3219
548
                    if (flags & 0x01) { /* FRAMES flag. */
3220
396
                        if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 4) {
3221
6
                            goto done_xing_info;    /* Invalid Xing/Info tag. */
3222
6
                        }
3223
3224
390
                        detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
3225
390
                        pTagData += 4;
3226
390
                    }
3227
3228
542
                    if (flags & 0x02) { /* BYTES flag. */
3229
238
                        if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 4) {
3230
57
                            goto done_xing_info;    /* Invalid Xing/Info tag. */
3231
57
                        }
3232
3233
181
                        bytes  = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3];
3234
181
                        (void)bytes;    /* <-- Just to silence a warning about `bytes` being assigned but unused. Want to leave this here in case I want to make use of it later. */
3235
181
                        pTagData += 4;
3236
181
                    }
3237
3238
485
                    if (flags & 0x04) { /* TOC flag. */
3239
208
                        if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 100) {
3240
50
                            goto done_xing_info;    /* Invalid Xing/Info tag. */
3241
50
                        }
3242
3243
                        /* TODO: Extract and bind seek points. */
3244
158
                        pTagData += 100;
3245
158
                    }
3246
3247
435
                    if (flags & 0x08) { /* SCALE flag. */
3248
246
                        if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 4) {
3249
26
                            goto done_xing_info;    /* Invalid Xing/Info tag. */
3250
26
                        }
3251
3252
220
                        pTagData += 4;
3253
220
                    }
3254
3255
                    /* At this point we're done with the Xing/Info header. Now we can look at the LAME data. */
3256
409
                    if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 1) {
3257
7
                        goto done_xing_info;    /* Not enough data left to check for a LAME header. */
3258
7
                    }
3259
3260
402
                    if (pTagData[0]) {
3261
339
                        int delayInPCMFrames;
3262
339
                        int paddingInPCMFrames;
3263
3264
339
                        if (frameBytes < (size_t)(pTagData - pFirstFrameData) + 36) {
3265
25
                            goto done_xing_info;    /* Invalid Xing/Info tag. */
3266
25
                        }
3267
3268
314
                        pTagData += 21;
3269
3270
314
                        delayInPCMFrames   = (( (drmp3_uint32)pTagData[0]        << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
3271
314
                        paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2]     )) - (528 + 1);
3272
314
                        if (paddingInPCMFrames < 0) {
3273
91
                            paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */
3274
91
                        }
3275
                        
3276
314
                        pMP3->delayInPCMFrames   = (drmp3_uint32)delayInPCMFrames;
3277
314
                        pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames;
3278
314
                    }
3279
3280
                    /*
3281
                    My understanding is that if the "Xing" header is present we can consider this to be a VBR stream and if the "Info" header is
3282
                    present it's a CBR stream. If this is not the case let me know! I'm just tracking this for the time being in case I want to
3283
                    look at doing some CBR optimizations later on, such as faster seeking.
3284
                    */
3285
377
                    if (isXing) {
3286
3
                        pMP3->isVBR = DRMP3_TRUE;
3287
374
                    } else if (isInfo) {
3288
374
                        pMP3->isCBR = DRMP3_TRUE;
3289
374
                    }
3290
3291
                    /* Post the raw data of the tag to the metadata callback. */
3292
377
                    if (onMeta != NULL) {
3293
0
                        drmp3_metadata_type metadataType = isXing ? DRMP3_METADATA_TYPE_XING : DRMP3_METADATA_TYPE_VBRI;
3294
0
                        size_t tagDataSize;
3295
                    
3296
0
                        tagDataSize  = (size_t)firstFrameInfo.frame_bytes;
3297
0
                        tagDataSize -= (size_t)(pTagDataBeg - pFirstFrameData);
3298
3299
0
                        drmp3__on_meta(pMP3, metadataType, pTagDataBeg, tagDataSize);
3300
0
                    }
3301
3302
                    /* Since this was identified as a tag, we don't want to treat it as audio. We need to clear out the PCM cache. */
3303
377
                    pMP3->pcmFramesRemainingInMP3Frame = 0;
3304
3305
                    /* The start offset needs to be moved to the end of this frame so it's not included in any audio processing after seeking. */
3306
377
                    pMP3->streamStartOffset += (drmp3_uint32)(firstFrameInfo.frame_bytes);
3307
377
                    pMP3->streamCursor = pMP3->streamStartOffset;
3308
3309
                    /*
3310
                    The internal decoder needs to be reset to clear out any state. If we don't reset this state, it's possible for
3311
                    there to be inconsistencies in the number of samples read when reading to the end of the stream depending on
3312
                    whether or not the caller seeks to the start of the stream.
3313
                    */
3314
377
                    drmp3dec_init(&pMP3->decoder);
3315
377
                }
3316
3317
1.47k
                done_xing_info:;
3318
1.47k
            } else {
3319
                /* Failed to read the side info. */
3320
263
            }
3321
1.73k
        }
3322
1.73k
        #endif
3323
1.73k
    } else {
3324
        /* Not a valid MP3 stream. */
3325
1.26k
        drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);    /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
3326
1.26k
        return DRMP3_FALSE;
3327
1.26k
    }
3328
3329
1.73k
    if (detectedMP3FrameCount != 0xFFFFFFFF) {
3330
382
        pMP3->totalPCMFrameCount = (drmp3_uint64)detectedMP3FrameCount * firstFramePCMFrameCount;
3331
382
    }
3332
3333
1.73k
    pMP3->channels   = pMP3->mp3FrameChannels;
3334
1.73k
    pMP3->sampleRate = pMP3->mp3FrameSampleRate;
3335
3336
1.73k
    return DRMP3_TRUE;
3337
3.00k
}
3338
3339
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
3340
0
{
3341
0
    if (pMP3 == NULL || onRead == NULL) {
3342
0
        return DRMP3_FALSE;
3343
0
    }
3344
3345
0
    DRMP3_ZERO_OBJECT(pMP3);
3346
0
    return drmp3_init_internal(pMP3, onRead, onSeek, onTell, onMeta, pUserData, pUserData, pAllocationCallbacks);
3347
0
}
3348
3349
3350
static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
3351
6.33k
{
3352
6.33k
    drmp3* pMP3 = (drmp3*)pUserData;
3353
6.33k
    size_t bytesRemaining;
3354
3355
6.33k
    DRMP3_ASSERT(pMP3 != NULL);
3356
6.33k
    DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
3357
3358
6.33k
    bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
3359
6.33k
    if (bytesToRead > bytesRemaining) {
3360
11
        bytesToRead = bytesRemaining;
3361
11
    }
3362
3363
6.33k
    if (bytesToRead > 0) {
3364
6.33k
        DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
3365
6.33k
        pMP3->memory.currentReadPos += bytesToRead;
3366
6.33k
    }
3367
3368
6.33k
    return bytesToRead;
3369
6.33k
}
3370
3371
static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
3372
12.4k
{
3373
12.4k
    drmp3* pMP3 = (drmp3*)pUserData;
3374
12.4k
    drmp3_int64 newCursor;
3375
3376
12.4k
    DRMP3_ASSERT(pMP3 != NULL);
3377
3378
12.4k
    if (origin == DRMP3_SEEK_SET) {
3379
6.05k
        newCursor = 0;
3380
6.39k
    } else if (origin == DRMP3_SEEK_CUR) {
3381
57
        newCursor = (drmp3_int64)pMP3->memory.currentReadPos;
3382
6.33k
    } else if (origin == DRMP3_SEEK_END) {
3383
6.33k
        newCursor = (drmp3_int64)pMP3->memory.dataSize;
3384
6.33k
    } else {
3385
0
        DRMP3_ASSERT(!"Invalid seek origin");
3386
0
        return DRMP3_FALSE;
3387
0
    }
3388
3389
12.4k
    newCursor += byteOffset;
3390
3391
12.4k
    if (newCursor < 0) {
3392
0
        return DRMP3_FALSE;  /* Trying to seek prior to the start of the buffer. */
3393
0
    }
3394
12.4k
    if ((size_t)newCursor > pMP3->memory.dataSize) {
3395
49
        return DRMP3_FALSE;  /* Trying to seek beyond the end of the buffer. */
3396
49
    }
3397
3398
12.4k
    pMP3->memory.currentReadPos = (size_t)newCursor;
3399
3400
12.4k
    return DRMP3_TRUE;
3401
12.4k
}
3402
3403
static drmp3_bool32 drmp3__on_tell_memory(void* pUserData, drmp3_int64* pCursor)
3404
3.06k
{
3405
3.06k
    drmp3* pMP3 = (drmp3*)pUserData;
3406
3407
3.06k
    DRMP3_ASSERT(pMP3 != NULL);
3408
3.06k
    DRMP3_ASSERT(pCursor != NULL);
3409
3410
3.06k
    *pCursor = (drmp3_int64)pMP3->memory.currentReadPos;
3411
3.06k
    return DRMP3_TRUE;
3412
3.06k
}
3413
3414
DRMP3_API drmp3_bool32 drmp3_init_memory_with_metadata(drmp3* pMP3, const void* pData, size_t dataSize, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks)
3415
3.06k
{
3416
3.06k
    drmp3_bool32 result;
3417
3418
3.06k
    if (pMP3 == NULL) {
3419
0
        return DRMP3_FALSE;
3420
0
    }
3421
3422
3.06k
    DRMP3_ZERO_OBJECT(pMP3);
3423
3424
3.06k
    if (pData == NULL || dataSize == 0) {
3425
0
        return DRMP3_FALSE;
3426
0
    }
3427
3428
3.06k
    pMP3->memory.pData = (const drmp3_uint8*)pData;
3429
3.06k
    pMP3->memory.dataSize = dataSize;
3430
3.06k
    pMP3->memory.currentReadPos = 0;
3431
3432
3.06k
    result = drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, drmp3__on_tell_memory, onMeta, pMP3, pUserDataMeta, pAllocationCallbacks);
3433
3.06k
    if (result == DRMP3_FALSE) {
3434
1.32k
        return DRMP3_FALSE;
3435
1.32k
    }
3436
3437
    /* Adjust the length of the memory stream to account for ID3v1 and APE tags. */
3438
1.73k
    if (pMP3->streamLength <= (drmp3_uint64)DRMP3_SIZE_MAX) {
3439
1.73k
        pMP3->memory.dataSize = (size_t)pMP3->streamLength; /* Safe cast. */
3440
1.73k
    }
3441
3442
1.73k
    if (pMP3->streamStartOffset > (drmp3_uint64)DRMP3_SIZE_MAX) {
3443
0
        return DRMP3_FALSE; /* Tags too big. */
3444
0
    }
3445
3446
1.73k
    return DRMP3_TRUE;
3447
1.73k
}
3448
3449
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
3450
3.06k
{
3451
3.06k
    return drmp3_init_memory_with_metadata(pMP3, pData, dataSize, NULL, NULL, pAllocationCallbacks);
3452
3.06k
}
3453
3454
3455
#ifndef DR_MP3_NO_STDIO
3456
#include <stdio.h>
3457
#include <wchar.h>      /* For wcslen(), wcsrtombs() */
3458
3459
/* Errno */
3460
/* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
3461
#include <errno.h>
3462
static drmp3_result drmp3_result_from_errno(int e)
3463
0
{
3464
0
    switch (e)
3465
0
    {
3466
0
        case 0: return DRMP3_SUCCESS;
3467
0
    #ifdef EPERM
3468
0
        case EPERM: return DRMP3_INVALID_OPERATION;
3469
0
    #endif
3470
0
    #ifdef ENOENT
3471
0
        case ENOENT: return DRMP3_DOES_NOT_EXIST;
3472
0
    #endif
3473
0
    #ifdef ESRCH
3474
0
        case ESRCH: return DRMP3_DOES_NOT_EXIST;
3475
0
    #endif
3476
0
    #ifdef EINTR
3477
0
        case EINTR: return DRMP3_INTERRUPT;
3478
0
    #endif
3479
0
    #ifdef EIO
3480
0
        case EIO: return DRMP3_IO_ERROR;
3481
0
    #endif
3482
0
    #ifdef ENXIO
3483
0
        case ENXIO: return DRMP3_DOES_NOT_EXIST;
3484
0
    #endif
3485
0
    #ifdef E2BIG
3486
0
        case E2BIG: return DRMP3_INVALID_ARGS;
3487
0
    #endif
3488
0
    #ifdef ENOEXEC
3489
0
        case ENOEXEC: return DRMP3_INVALID_FILE;
3490
0
    #endif
3491
0
    #ifdef EBADF
3492
0
        case EBADF: return DRMP3_INVALID_FILE;
3493
0
    #endif
3494
0
    #ifdef ECHILD
3495
0
        case ECHILD: return DRMP3_ERROR;
3496
0
    #endif
3497
0
    #ifdef EAGAIN
3498
0
        case EAGAIN: return DRMP3_UNAVAILABLE;
3499
0
    #endif
3500
0
    #ifdef ENOMEM
3501
0
        case ENOMEM: return DRMP3_OUT_OF_MEMORY;
3502
0
    #endif
3503
0
    #ifdef EACCES
3504
0
        case EACCES: return DRMP3_ACCESS_DENIED;
3505
0
    #endif
3506
0
    #ifdef EFAULT
3507
0
        case EFAULT: return DRMP3_BAD_ADDRESS;
3508
0
    #endif
3509
0
    #ifdef ENOTBLK
3510
0
        case ENOTBLK: return DRMP3_ERROR;
3511
0
    #endif
3512
0
    #ifdef EBUSY
3513
0
        case EBUSY: return DRMP3_BUSY;
3514
0
    #endif
3515
0
    #ifdef EEXIST
3516
0
        case EEXIST: return DRMP3_ALREADY_EXISTS;
3517
0
    #endif
3518
0
    #ifdef EXDEV
3519
0
        case EXDEV: return DRMP3_ERROR;
3520
0
    #endif
3521
0
    #ifdef ENODEV
3522
0
        case ENODEV: return DRMP3_DOES_NOT_EXIST;
3523
0
    #endif
3524
0
    #ifdef ENOTDIR
3525
0
        case ENOTDIR: return DRMP3_NOT_DIRECTORY;
3526
0
    #endif
3527
0
    #ifdef EISDIR
3528
0
        case EISDIR: return DRMP3_IS_DIRECTORY;
3529
0
    #endif
3530
0
    #ifdef EINVAL
3531
0
        case EINVAL: return DRMP3_INVALID_ARGS;
3532
0
    #endif
3533
0
    #ifdef ENFILE
3534
0
        case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3535
0
    #endif
3536
0
    #ifdef EMFILE
3537
0
        case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3538
0
    #endif
3539
0
    #ifdef ENOTTY
3540
0
        case ENOTTY: return DRMP3_INVALID_OPERATION;
3541
0
    #endif
3542
0
    #ifdef ETXTBSY
3543
0
        case ETXTBSY: return DRMP3_BUSY;
3544
0
    #endif
3545
0
    #ifdef EFBIG
3546
0
        case EFBIG: return DRMP3_TOO_BIG;
3547
0
    #endif
3548
0
    #ifdef ENOSPC
3549
0
        case ENOSPC: return DRMP3_NO_SPACE;
3550
0
    #endif
3551
0
    #ifdef ESPIPE
3552
0
        case ESPIPE: return DRMP3_BAD_SEEK;
3553
0
    #endif
3554
0
    #ifdef EROFS
3555
0
        case EROFS: return DRMP3_ACCESS_DENIED;
3556
0
    #endif
3557
0
    #ifdef EMLINK
3558
0
        case EMLINK: return DRMP3_TOO_MANY_LINKS;
3559
0
    #endif
3560
0
    #ifdef EPIPE
3561
0
        case EPIPE: return DRMP3_BAD_PIPE;
3562
0
    #endif
3563
0
    #ifdef EDOM
3564
0
        case EDOM: return DRMP3_OUT_OF_RANGE;
3565
0
    #endif
3566
0
    #ifdef ERANGE
3567
0
        case ERANGE: return DRMP3_OUT_OF_RANGE;
3568
0
    #endif
3569
0
    #ifdef EDEADLK
3570
0
        case EDEADLK: return DRMP3_DEADLOCK;
3571
0
    #endif
3572
0
    #ifdef ENAMETOOLONG
3573
0
        case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
3574
0
    #endif
3575
0
    #ifdef ENOLCK
3576
0
        case ENOLCK: return DRMP3_ERROR;
3577
0
    #endif
3578
0
    #ifdef ENOSYS
3579
0
        case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
3580
0
    #endif
3581
    #if defined(ENOTEMPTY) && ENOTEMPTY != EEXIST   /* In AIX, ENOTEMPTY and EEXIST use the same value. */
3582
0
        case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
3583
0
    #endif
3584
0
    #ifdef ELOOP
3585
0
        case ELOOP: return DRMP3_TOO_MANY_LINKS;
3586
0
    #endif
3587
0
    #ifdef ENOMSG
3588
0
        case ENOMSG: return DRMP3_NO_MESSAGE;
3589
0
    #endif
3590
0
    #ifdef EIDRM
3591
0
        case EIDRM: return DRMP3_ERROR;
3592
0
    #endif
3593
0
    #ifdef ECHRNG
3594
0
        case ECHRNG: return DRMP3_ERROR;
3595
0
    #endif
3596
0
    #ifdef EL2NSYNC
3597
0
        case EL2NSYNC: return DRMP3_ERROR;
3598
0
    #endif
3599
0
    #ifdef EL3HLT
3600
0
        case EL3HLT: return DRMP3_ERROR;
3601
0
    #endif
3602
0
    #ifdef EL3RST
3603
0
        case EL3RST: return DRMP3_ERROR;
3604
0
    #endif
3605
0
    #ifdef ELNRNG
3606
0
        case ELNRNG: return DRMP3_OUT_OF_RANGE;
3607
0
    #endif
3608
0
    #ifdef EUNATCH
3609
0
        case EUNATCH: return DRMP3_ERROR;
3610
0
    #endif
3611
0
    #ifdef ENOCSI
3612
0
        case ENOCSI: return DRMP3_ERROR;
3613
0
    #endif
3614
0
    #ifdef EL2HLT
3615
0
        case EL2HLT: return DRMP3_ERROR;
3616
0
    #endif
3617
0
    #ifdef EBADE
3618
0
        case EBADE: return DRMP3_ERROR;
3619
0
    #endif
3620
0
    #ifdef EBADR
3621
0
        case EBADR: return DRMP3_ERROR;
3622
0
    #endif
3623
0
    #ifdef EXFULL
3624
0
        case EXFULL: return DRMP3_ERROR;
3625
0
    #endif
3626
0
    #ifdef ENOANO
3627
0
        case ENOANO: return DRMP3_ERROR;
3628
0
    #endif
3629
0
    #ifdef EBADRQC
3630
0
        case EBADRQC: return DRMP3_ERROR;
3631
0
    #endif
3632
0
    #ifdef EBADSLT
3633
0
        case EBADSLT: return DRMP3_ERROR;
3634
0
    #endif
3635
0
    #ifdef EBFONT
3636
0
        case EBFONT: return DRMP3_INVALID_FILE;
3637
0
    #endif
3638
0
    #ifdef ENOSTR
3639
0
        case ENOSTR: return DRMP3_ERROR;
3640
0
    #endif
3641
0
    #ifdef ENODATA
3642
0
        case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
3643
0
    #endif
3644
0
    #ifdef ETIME
3645
0
        case ETIME: return DRMP3_TIMEOUT;
3646
0
    #endif
3647
0
    #ifdef ENOSR
3648
0
        case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
3649
0
    #endif
3650
0
    #ifdef ENONET
3651
0
        case ENONET: return DRMP3_NO_NETWORK;
3652
0
    #endif
3653
0
    #ifdef ENOPKG
3654
0
        case ENOPKG: return DRMP3_ERROR;
3655
0
    #endif
3656
0
    #ifdef EREMOTE
3657
0
        case EREMOTE: return DRMP3_ERROR;
3658
0
    #endif
3659
0
    #ifdef ENOLINK
3660
0
        case ENOLINK: return DRMP3_ERROR;
3661
0
    #endif
3662
0
    #ifdef EADV
3663
0
        case EADV: return DRMP3_ERROR;
3664
0
    #endif
3665
0
    #ifdef ESRMNT
3666
0
        case ESRMNT: return DRMP3_ERROR;
3667
0
    #endif
3668
0
    #ifdef ECOMM
3669
0
        case ECOMM: return DRMP3_ERROR;
3670
0
    #endif
3671
0
    #ifdef EPROTO
3672
0
        case EPROTO: return DRMP3_ERROR;
3673
0
    #endif
3674
0
    #ifdef EMULTIHOP
3675
0
        case EMULTIHOP: return DRMP3_ERROR;
3676
0
    #endif
3677
0
    #ifdef EDOTDOT
3678
0
        case EDOTDOT: return DRMP3_ERROR;
3679
0
    #endif
3680
0
    #ifdef EBADMSG
3681
0
        case EBADMSG: return DRMP3_BAD_MESSAGE;
3682
0
    #endif
3683
0
    #ifdef EOVERFLOW
3684
0
        case EOVERFLOW: return DRMP3_TOO_BIG;
3685
0
    #endif
3686
0
    #ifdef ENOTUNIQ
3687
0
        case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
3688
0
    #endif
3689
0
    #ifdef EBADFD
3690
0
        case EBADFD: return DRMP3_ERROR;
3691
0
    #endif
3692
0
    #ifdef EREMCHG
3693
0
        case EREMCHG: return DRMP3_ERROR;
3694
0
    #endif
3695
0
    #ifdef ELIBACC
3696
0
        case ELIBACC: return DRMP3_ACCESS_DENIED;
3697
0
    #endif
3698
0
    #ifdef ELIBBAD
3699
0
        case ELIBBAD: return DRMP3_INVALID_FILE;
3700
0
    #endif
3701
0
    #ifdef ELIBSCN
3702
0
        case ELIBSCN: return DRMP3_INVALID_FILE;
3703
0
    #endif
3704
0
    #ifdef ELIBMAX
3705
0
        case ELIBMAX: return DRMP3_ERROR;
3706
0
    #endif
3707
0
    #ifdef ELIBEXEC
3708
0
        case ELIBEXEC: return DRMP3_ERROR;
3709
0
    #endif
3710
0
    #ifdef EILSEQ
3711
0
        case EILSEQ: return DRMP3_INVALID_DATA;
3712
0
    #endif
3713
0
    #ifdef ERESTART
3714
0
        case ERESTART: return DRMP3_ERROR;
3715
0
    #endif
3716
0
    #ifdef ESTRPIPE
3717
0
        case ESTRPIPE: return DRMP3_ERROR;
3718
0
    #endif
3719
0
    #ifdef EUSERS
3720
0
        case EUSERS: return DRMP3_ERROR;
3721
0
    #endif
3722
0
    #ifdef ENOTSOCK
3723
0
        case ENOTSOCK: return DRMP3_NOT_SOCKET;
3724
0
    #endif
3725
0
    #ifdef EDESTADDRREQ
3726
0
        case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
3727
0
    #endif
3728
0
    #ifdef EMSGSIZE
3729
0
        case EMSGSIZE: return DRMP3_TOO_BIG;
3730
0
    #endif
3731
0
    #ifdef EPROTOTYPE
3732
0
        case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
3733
0
    #endif
3734
0
    #ifdef ENOPROTOOPT
3735
0
        case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
3736
0
    #endif
3737
0
    #ifdef EPROTONOSUPPORT
3738
0
        case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
3739
0
    #endif
3740
0
    #ifdef ESOCKTNOSUPPORT
3741
0
        case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
3742
0
    #endif
3743
0
    #ifdef EOPNOTSUPP
3744
0
        case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
3745
0
    #endif
3746
0
    #ifdef EPFNOSUPPORT
3747
0
        case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
3748
0
    #endif
3749
0
    #ifdef EAFNOSUPPORT
3750
0
        case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
3751
0
    #endif
3752
0
    #ifdef EADDRINUSE
3753
0
        case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
3754
0
    #endif
3755
0
    #ifdef EADDRNOTAVAIL
3756
0
        case EADDRNOTAVAIL: return DRMP3_ERROR;
3757
0
    #endif
3758
0
    #ifdef ENETDOWN
3759
0
        case ENETDOWN: return DRMP3_NO_NETWORK;
3760
0
    #endif
3761
0
    #ifdef ENETUNREACH
3762
0
        case ENETUNREACH: return DRMP3_NO_NETWORK;
3763
0
    #endif
3764
0
    #ifdef ENETRESET
3765
0
        case ENETRESET: return DRMP3_NO_NETWORK;
3766
0
    #endif
3767
0
    #ifdef ECONNABORTED
3768
0
        case ECONNABORTED: return DRMP3_NO_NETWORK;
3769
0
    #endif
3770
0
    #ifdef ECONNRESET
3771
0
        case ECONNRESET: return DRMP3_CONNECTION_RESET;
3772
0
    #endif
3773
0
    #ifdef ENOBUFS
3774
0
        case ENOBUFS: return DRMP3_NO_SPACE;
3775
0
    #endif
3776
0
    #ifdef EISCONN
3777
0
        case EISCONN: return DRMP3_ALREADY_CONNECTED;
3778
0
    #endif
3779
0
    #ifdef ENOTCONN
3780
0
        case ENOTCONN: return DRMP3_NOT_CONNECTED;
3781
0
    #endif
3782
0
    #ifdef ESHUTDOWN
3783
0
        case ESHUTDOWN: return DRMP3_ERROR;
3784
0
    #endif
3785
0
    #ifdef ETOOMANYREFS
3786
0
        case ETOOMANYREFS: return DRMP3_ERROR;
3787
0
    #endif
3788
0
    #ifdef ETIMEDOUT
3789
0
        case ETIMEDOUT: return DRMP3_TIMEOUT;
3790
0
    #endif
3791
0
    #ifdef ECONNREFUSED
3792
0
        case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
3793
0
    #endif
3794
0
    #ifdef EHOSTDOWN
3795
0
        case EHOSTDOWN: return DRMP3_NO_HOST;
3796
0
    #endif
3797
0
    #ifdef EHOSTUNREACH
3798
0
        case EHOSTUNREACH: return DRMP3_NO_HOST;
3799
0
    #endif
3800
0
    #ifdef EALREADY
3801
0
        case EALREADY: return DRMP3_IN_PROGRESS;
3802
0
    #endif
3803
0
    #ifdef EINPROGRESS
3804
0
        case EINPROGRESS: return DRMP3_IN_PROGRESS;
3805
0
    #endif
3806
0
    #ifdef ESTALE
3807
0
        case ESTALE: return DRMP3_INVALID_FILE;
3808
0
    #endif
3809
0
    #ifdef EUCLEAN
3810
0
        case EUCLEAN: return DRMP3_ERROR;
3811
0
    #endif
3812
0
    #ifdef ENOTNAM
3813
0
        case ENOTNAM: return DRMP3_ERROR;
3814
0
    #endif
3815
0
    #ifdef ENAVAIL
3816
0
        case ENAVAIL: return DRMP3_ERROR;
3817
0
    #endif
3818
0
    #ifdef EISNAM
3819
0
        case EISNAM: return DRMP3_ERROR;
3820
0
    #endif
3821
0
    #ifdef EREMOTEIO
3822
0
        case EREMOTEIO: return DRMP3_IO_ERROR;
3823
0
    #endif
3824
0
    #ifdef EDQUOT
3825
0
        case EDQUOT: return DRMP3_NO_SPACE;
3826
0
    #endif
3827
0
    #ifdef ENOMEDIUM
3828
0
        case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
3829
0
    #endif
3830
0
    #ifdef EMEDIUMTYPE
3831
0
        case EMEDIUMTYPE: return DRMP3_ERROR;
3832
0
    #endif
3833
0
    #ifdef ECANCELED
3834
0
        case ECANCELED: return DRMP3_CANCELLED;
3835
0
    #endif
3836
0
    #ifdef ENOKEY
3837
0
        case ENOKEY: return DRMP3_ERROR;
3838
0
    #endif
3839
0
    #ifdef EKEYEXPIRED
3840
0
        case EKEYEXPIRED: return DRMP3_ERROR;
3841
0
    #endif
3842
0
    #ifdef EKEYREVOKED
3843
0
        case EKEYREVOKED: return DRMP3_ERROR;
3844
0
    #endif
3845
0
    #ifdef EKEYREJECTED
3846
0
        case EKEYREJECTED: return DRMP3_ERROR;
3847
0
    #endif
3848
0
    #ifdef EOWNERDEAD
3849
0
        case EOWNERDEAD: return DRMP3_ERROR;
3850
0
    #endif
3851
0
    #ifdef ENOTRECOVERABLE
3852
0
        case ENOTRECOVERABLE: return DRMP3_ERROR;
3853
0
    #endif
3854
0
    #ifdef ERFKILL
3855
0
        case ERFKILL: return DRMP3_ERROR;
3856
0
    #endif
3857
0
    #ifdef EHWPOISON
3858
0
        case EHWPOISON: return DRMP3_ERROR;
3859
0
    #endif
3860
0
        default: return DRMP3_ERROR;
3861
0
    }
3862
0
}
3863
/* End Errno */
3864
3865
/* fopen */
3866
static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
3867
0
{
3868
#if defined(_MSC_VER) && _MSC_VER >= 1400
3869
    errno_t err;
3870
#endif
3871
3872
0
    if (ppFile != NULL) {
3873
0
        *ppFile = NULL;  /* Safety. */
3874
0
    }
3875
3876
0
    if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3877
0
        return DRMP3_INVALID_ARGS;
3878
0
    }
3879
3880
#if defined(_MSC_VER) && _MSC_VER >= 1400
3881
    err = fopen_s(ppFile, pFilePath, pOpenMode);
3882
    if (err != 0) {
3883
        return drmp3_result_from_errno(err);
3884
    }
3885
#else
3886
#if defined(_WIN32) || defined(__APPLE__)
3887
    *ppFile = fopen(pFilePath, pOpenMode);
3888
#else
3889
    #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
3890
        *ppFile = fopen64(pFilePath, pOpenMode);
3891
    #else
3892
0
        *ppFile = fopen(pFilePath, pOpenMode);
3893
0
    #endif
3894
0
#endif
3895
0
    if (*ppFile == NULL) {
3896
0
        drmp3_result result = drmp3_result_from_errno(errno);
3897
0
        if (result == DRMP3_SUCCESS) {
3898
0
            result = DRMP3_ERROR;   /* Just a safety check to make sure we never ever return success when pFile == NULL. */
3899
0
        }
3900
3901
0
        return result;
3902
0
    }
3903
0
#endif
3904
3905
0
    return DRMP3_SUCCESS;
3906
0
}
3907
3908
/*
3909
_wfopen() isn't always available in all compilation environments.
3910
3911
    * Windows only.
3912
    * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
3913
    * MinGW-64 (both 32- and 64-bit) seems to support it.
3914
    * MinGW wraps it in !defined(__STRICT_ANSI__).
3915
    * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
3916
3917
This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
3918
fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
3919
*/
3920
#if defined(_WIN32)
3921
    #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
3922
        #define DRMP3_HAS_WFOPEN
3923
    #endif
3924
#endif
3925
3926
static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
3927
0
{
3928
0
    if (ppFile != NULL) {
3929
0
        *ppFile = NULL;  /* Safety. */
3930
0
    }
3931
3932
0
    if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3933
0
        return DRMP3_INVALID_ARGS;
3934
0
    }
3935
3936
#if defined(DRMP3_HAS_WFOPEN)
3937
    {
3938
        /* Use _wfopen() on Windows. */
3939
    #if defined(_MSC_VER) && _MSC_VER >= 1400
3940
        errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
3941
        if (err != 0) {
3942
            return drmp3_result_from_errno(err);
3943
        }
3944
    #else
3945
        *ppFile = _wfopen(pFilePath, pOpenMode);
3946
        if (*ppFile == NULL) {
3947
            return drmp3_result_from_errno(errno);
3948
        }
3949
    #endif
3950
        (void)pAllocationCallbacks;
3951
    }
3952
#else
3953
    /*
3954
    Use fopen() on anything other than Windows. Requires a conversion. This is annoying because
3955
  fopen() is locale specific. The only real way I can think of to do this is with wcsrtombs(). Note
3956
  that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
3957
    maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler
3958
  error I'll look into improving compatibility.
3959
    */
3960
3961
  /*
3962
  Some compilers don't support wchar_t or wcsrtombs() which we're using below. In this case we just
3963
  need to abort with an error. If you encounter a compiler lacking such support, add it to this list
3964
  and submit a bug report and it'll be added to the library upstream.
3965
  */
3966
  #if defined(__DJGPP__)
3967
  {
3968
    /* Nothing to do here. This will fall through to the error check below. */
3969
  }
3970
  #else
3971
0
    {
3972
0
        mbstate_t mbs;
3973
0
        size_t lenMB;
3974
0
        const wchar_t* pFilePathTemp = pFilePath;
3975
0
        char* pFilePathMB = NULL;
3976
0
        char pOpenModeMB[32] = {0};
3977
3978
        /* Get the length first. */
3979
0
        DRMP3_ZERO_OBJECT(&mbs);
3980
0
        lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
3981
0
        if (lenMB == (size_t)-1) {
3982
0
            return drmp3_result_from_errno(errno);
3983
0
        }
3984
3985
0
        pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
3986
0
        if (pFilePathMB == NULL) {
3987
0
            return DRMP3_OUT_OF_MEMORY;
3988
0
        }
3989
3990
0
        pFilePathTemp = pFilePath;
3991
0
        DRMP3_ZERO_OBJECT(&mbs);
3992
0
        wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
3993
3994
        /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
3995
0
        {
3996
0
            size_t i = 0;
3997
0
            for (;;) {
3998
0
                if (pOpenMode[i] == 0) {
3999
0
                    pOpenModeMB[i] = '\0';
4000
0
                    break;
4001
0
                }
4002
4003
0
                pOpenModeMB[i] = (char)pOpenMode[i];
4004
0
                i += 1;
4005
0
            }
4006
0
        }
4007
4008
0
        *ppFile = fopen(pFilePathMB, pOpenModeMB);
4009
4010
0
        drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
4011
0
    }
4012
0
  #endif
4013
4014
0
    if (*ppFile == NULL) {
4015
0
        return DRMP3_ERROR;
4016
0
    }
4017
0
#endif
4018
4019
0
    return DRMP3_SUCCESS;
4020
0
}
4021
/* End fopen */
4022
4023
4024
static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
4025
0
{
4026
0
    return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
4027
0
}
4028
4029
static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
4030
0
{
4031
0
    int whence = SEEK_SET;
4032
0
    if (origin == DRMP3_SEEK_CUR) {
4033
0
        whence = SEEK_CUR;
4034
0
    } else if (origin == DRMP3_SEEK_END) {
4035
0
        whence = SEEK_END;
4036
0
    }
4037
4038
0
    return fseek((FILE*)pUserData, offset, whence) == 0;
4039
0
}
4040
4041
static drmp3_bool32 drmp3__on_tell_stdio(void* pUserData, drmp3_int64* pCursor)
4042
0
{
4043
0
    FILE* pFileStdio = (FILE*)pUserData;
4044
0
    drmp3_int64 result;
4045
4046
    /* These were all validated at a higher level. */
4047
0
    DRMP3_ASSERT(pFileStdio != NULL);
4048
0
    DRMP3_ASSERT(pCursor    != NULL);
4049
4050
#if defined(_WIN32) && !defined(NXDK)
4051
    #if defined(_MSC_VER) && _MSC_VER > 1200
4052
        result = _ftelli64(pFileStdio);
4053
    #else
4054
        result = ftell(pFileStdio);
4055
    #endif
4056
#else
4057
0
    result = ftell(pFileStdio);
4058
0
#endif
4059
4060
0
    *pCursor = result;
4061
4062
0
    return DRMP3_TRUE;
4063
0
}
4064
4065
DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata(drmp3* pMP3, const char* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks)
4066
0
{
4067
0
    drmp3_bool32 result;
4068
0
    FILE* pFile;
4069
4070
0
    if (pMP3 == NULL) {
4071
0
        return DRMP3_FALSE;
4072
0
    }
4073
4074
0
    DRMP3_ZERO_OBJECT(pMP3);
4075
4076
0
    if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
4077
0
        return DRMP3_FALSE;
4078
0
    }
4079
4080
0
    result = drmp3_init_internal(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, drmp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks);
4081
0
    if (result != DRMP3_TRUE) {
4082
0
        fclose(pFile);
4083
0
        return result;
4084
0
    }
4085
4086
0
    return DRMP3_TRUE;
4087
0
}
4088
4089
DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata_w(drmp3* pMP3, const wchar_t* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks)
4090
0
{
4091
0
    drmp3_bool32 result;
4092
0
    FILE* pFile;
4093
4094
0
    if (pMP3 == NULL) {
4095
0
        return DRMP3_FALSE;
4096
0
    }
4097
4098
0
    DRMP3_ZERO_OBJECT(pMP3);
4099
4100
0
    if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
4101
0
        return DRMP3_FALSE;
4102
0
    }
4103
4104
0
    result = drmp3_init_internal(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, drmp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks);
4105
0
    if (result != DRMP3_TRUE) {
4106
0
        fclose(pFile);
4107
0
        return result;
4108
0
    }
4109
4110
0
    return DRMP3_TRUE;
4111
0
}
4112
4113
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
4114
0
{
4115
0
    return drmp3_init_file_with_metadata(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks);
4116
0
}
4117
4118
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
4119
0
{
4120
0
    return drmp3_init_file_with_metadata_w(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks);
4121
0
}
4122
#endif
4123
4124
DRMP3_API void drmp3_uninit(drmp3* pMP3)
4125
1.73k
{
4126
1.73k
    if (pMP3 == NULL) {
4127
0
        return;
4128
0
    }
4129
4130
1.73k
#ifndef DR_MP3_NO_STDIO
4131
1.73k
    if (pMP3->onRead == drmp3__on_read_stdio) {
4132
0
        FILE* pFile = (FILE*)pMP3->pUserData;
4133
0
        if (pFile != NULL) {
4134
0
            fclose(pFile);
4135
0
            pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
4136
0
        }
4137
0
    }
4138
1.73k
#endif
4139
4140
1.73k
    drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
4141
1.73k
}
4142
4143
#if defined(DR_MP3_FLOAT_OUTPUT)
4144
static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
4145
{
4146
    drmp3_uint64 i;
4147
    drmp3_uint64 i4;
4148
    drmp3_uint64 sampleCount4;
4149
4150
    /* Unrolled. */
4151
    i = 0;
4152
    sampleCount4 = sampleCount >> 2;
4153
    for (i4 = 0; i4 < sampleCount4; i4 += 1) {
4154
        float x0 = src[i+0];
4155
        float x1 = src[i+1];
4156
        float x2 = src[i+2];
4157
        float x3 = src[i+3];
4158
4159
        x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0));
4160
        x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1));
4161
        x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2));
4162
        x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3));
4163
4164
        x0 = x0 * 32767.0f;
4165
        x1 = x1 * 32767.0f;
4166
        x2 = x2 * 32767.0f;
4167
        x3 = x3 * 32767.0f;
4168
4169
        dst[i+0] = (drmp3_int16)x0;
4170
        dst[i+1] = (drmp3_int16)x1;
4171
        dst[i+2] = (drmp3_int16)x2;
4172
        dst[i+3] = (drmp3_int16)x3;
4173
4174
        i += 4;
4175
    }
4176
4177
    /* Leftover. */
4178
    for (; i < sampleCount; i += 1) {
4179
        float x = src[i];
4180
        x = ((x < -1) ? -1 : ((x > 1) ? 1 : x));    /* clip */
4181
        x = x * 32767.0f;                           /* -1..1 to -32767..32767 */
4182
4183
        dst[i] = (drmp3_int16)x;
4184
    }
4185
}
4186
#endif
4187
4188
#if !defined(DR_MP3_FLOAT_OUTPUT)
4189
static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
4190
304k
{
4191
304k
    drmp3_uint64 i;
4192
622M
    for (i = 0; i < sampleCount; i += 1) {
4193
622M
        float x = (float)src[i];
4194
622M
        x = x * 0.000030517578125f;         /* -32768..32767 to -1..0.999969482421875 */
4195
622M
        dst[i] = x;
4196
622M
    }
4197
304k
}
4198
#endif
4199
4200
4201
static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
4202
306k
{
4203
306k
    drmp3_uint64 totalFramesRead = 0;
4204
4205
306k
    DRMP3_ASSERT(pMP3 != NULL);
4206
306k
    DRMP3_ASSERT(pMP3->onRead != NULL);
4207
4208
784k
    while (framesToRead > 0) {
4209
784k
        drmp3_uint32 framesToConsume;
4210
4211
        /* Skip frames if necessary. */
4212
784k
        if (pMP3->currentPCMFrame < pMP3->delayInPCMFrames) {
4213
615
            drmp3_uint32 framesToSkip = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, pMP3->delayInPCMFrames - pMP3->currentPCMFrame);
4214
4215
615
            pMP3->currentPCMFrame              += framesToSkip;
4216
615
            pMP3->pcmFramesConsumedInMP3Frame  += framesToSkip;
4217
615
            pMP3->pcmFramesRemainingInMP3Frame -= framesToSkip;
4218
615
        }
4219
4220
784k
        framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
4221
4222
        /* Clamp the number of frames to read to the padding. */
4223
784k
        if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames) {
4224
278k
            if (pMP3->currentPCMFrame < (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) {
4225
278k
                drmp3_uint64 framesRemainigToPadding = (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames) - pMP3->currentPCMFrame;
4226
278k
                if (framesToConsume >               framesRemainigToPadding) {
4227
3
                    framesToConsume = (drmp3_uint32)framesRemainigToPadding;
4228
3
                }
4229
278k
            } else {
4230
                /* We're into the padding. Abort. */
4231
16
                break;
4232
16
            }
4233
278k
        }
4234
4235
783k
        if (pBufferOut != NULL) {
4236
            #if defined(DR_MP3_FLOAT_OUTPUT)
4237
            {
4238
                /* f32 */
4239
                float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(float) * totalFramesRead                   * pMP3->channels);
4240
                float* pFramesInF32  = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
4241
                DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
4242
            }
4243
            #else
4244
783k
            {
4245
                /* s16 */
4246
783k
                drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut,          sizeof(drmp3_int16) * totalFramesRead                   * pMP3->channels);
4247
783k
                drmp3_int16* pFramesInS16  = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
4248
783k
                DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
4249
783k
            }
4250
783k
            #endif
4251
783k
        }
4252
4253
783k
        pMP3->currentPCMFrame              += framesToConsume;
4254
783k
        pMP3->pcmFramesConsumedInMP3Frame  += framesToConsume;
4255
783k
        pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
4256
783k
        totalFramesRead                    += framesToConsume;
4257
783k
        framesToRead                       -= framesToConsume;
4258
4259
783k
        if (framesToRead == 0) {
4260
303k
            break;
4261
303k
        }
4262
4263
        /* If the cursor is already at the padding we need to abort. */
4264
480k
        if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames && pMP3->currentPCMFrame >= (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) {
4265
5
            break;
4266
5
        }
4267
4268
480k
        DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
4269
4270
        /* At this point we have exhausted our in-memory buffer so we need to re-fill. */
4271
480k
        if (drmp3_decode_next_frame(pMP3) == 0) {
4272
2.96k
            break;
4273
2.96k
        }
4274
480k
    }
4275
4276
306k
    return totalFramesRead;
4277
306k
}
4278
4279
4280
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
4281
98.8k
{
4282
98.8k
    if (pMP3 == NULL || pMP3->onRead == NULL) {
4283
0
        return 0;
4284
0
    }
4285
4286
#if defined(DR_MP3_FLOAT_OUTPUT)
4287
    /* Fast path. No conversion required. */
4288
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
4289
#else
4290
    /* Slow path. Convert from s16 to f32. */
4291
98.8k
    {
4292
98.8k
        drmp3_int16 pTempS16[1152*2];   /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
4293
98.8k
        drmp3_uint64 totalPCMFramesRead = 0;
4294
4295
403k
        while (totalPCMFramesRead < framesToRead) {
4296
306k
            drmp3_uint64 framesJustRead;
4297
306k
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
4298
306k
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
4299
306k
            if (framesToReadNow > framesRemaining) {
4300
97.4k
                framesToReadNow = framesRemaining;
4301
97.4k
            }
4302
4303
306k
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
4304
306k
            if (framesJustRead == 0) {
4305
1.73k
                break;
4306
1.73k
            }
4307
4308
304k
            drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
4309
304k
            totalPCMFramesRead += framesJustRead;
4310
304k
        }
4311
4312
98.8k
        return totalPCMFramesRead;
4313
98.8k
    }
4314
98.8k
#endif
4315
98.8k
}
4316
4317
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
4318
0
{
4319
0
    if (pMP3 == NULL || pMP3->onRead == NULL) {
4320
0
        return 0;
4321
0
    }
4322
4323
0
#if !defined(DR_MP3_FLOAT_OUTPUT)
4324
    /* Fast path. No conversion required. */
4325
0
    return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
4326
#else
4327
    /* Slow path. Convert from f32 to s16. */
4328
    {
4329
        float pTempF32[1152*2];   /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
4330
        drmp3_uint64 totalPCMFramesRead = 0;
4331
4332
        while (totalPCMFramesRead < framesToRead) {
4333
            drmp3_uint64 framesJustRead;
4334
            drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
4335
            drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
4336
            if (framesToReadNow > framesRemaining) {
4337
                framesToReadNow = framesRemaining;
4338
            }
4339
4340
            framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
4341
            if (framesJustRead == 0) {
4342
                break;
4343
            }
4344
4345
            drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
4346
            totalPCMFramesRead += framesJustRead;
4347
        }
4348
4349
        return totalPCMFramesRead;
4350
    }
4351
#endif
4352
0
}
4353
4354
static void drmp3_reset(drmp3* pMP3)
4355
0
{
4356
0
    DRMP3_ASSERT(pMP3 != NULL);
4357
4358
0
    pMP3->pcmFramesConsumedInMP3Frame = 0;
4359
0
    pMP3->pcmFramesRemainingInMP3Frame = 0;
4360
0
    pMP3->currentPCMFrame = 0;
4361
0
    pMP3->dataSize = 0;
4362
0
    pMP3->atEnd = DRMP3_FALSE;
4363
0
    drmp3dec_init(&pMP3->decoder);
4364
0
}
4365
4366
static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
4367
0
{
4368
0
    DRMP3_ASSERT(pMP3 != NULL);
4369
0
    DRMP3_ASSERT(pMP3->onSeek != NULL);
4370
4371
    /* Seek to the start of the stream to begin with. */
4372
0
    if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, DRMP3_SEEK_SET)) {
4373
0
        return DRMP3_FALSE;
4374
0
    }
4375
4376
    /* Clear any cached data. */
4377
0
    drmp3_reset(pMP3);
4378
0
    return DRMP3_TRUE;
4379
0
}
4380
4381
4382
static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
4383
0
{
4384
0
    drmp3_uint64 framesRead;
4385
4386
    /*
4387
    Just using a dumb read-and-discard for now. What would be nice is to parse only the header of the MP3 frame, and then skip over leading
4388
    frames without spending the time doing a full decode. I cannot see an easy way to do this in minimp3, however, so it may involve some
4389
    kind of manual processing.
4390
    */
4391
#if defined(DR_MP3_FLOAT_OUTPUT)
4392
    framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
4393
#else
4394
0
    framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
4395
0
#endif
4396
0
    if (framesRead != frameOffset) {
4397
0
        return DRMP3_FALSE;
4398
0
    }
4399
4400
0
    return DRMP3_TRUE;
4401
0
}
4402
4403
static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
4404
0
{
4405
0
    DRMP3_ASSERT(pMP3 != NULL);
4406
4407
0
    if (frameIndex == pMP3->currentPCMFrame) {
4408
0
        return DRMP3_TRUE;
4409
0
    }
4410
4411
    /*
4412
    If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of
4413
    the stream and read from the beginning.
4414
    */
4415
0
    if (frameIndex < pMP3->currentPCMFrame) {
4416
        /* Moving backward. Move to the start of the stream and then move forward. */
4417
0
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
4418
0
            return DRMP3_FALSE;
4419
0
        }
4420
0
    }
4421
4422
0
    DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
4423
0
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
4424
0
}
4425
4426
static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
4427
0
{
4428
0
    drmp3_uint32 iSeekPoint;
4429
4430
0
    DRMP3_ASSERT(pSeekPointIndex != NULL);
4431
4432
0
    *pSeekPointIndex = 0;
4433
4434
0
    if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
4435
0
        return DRMP3_FALSE;
4436
0
    }
4437
4438
    /* Linear search for simplicity to begin with while I'm getting this thing working. Once it's all working change this to a binary search. */
4439
0
    for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
4440
0
        if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
4441
0
            break;  /* Found it. */
4442
0
        }
4443
4444
0
        *pSeekPointIndex = iSeekPoint;
4445
0
    }
4446
4447
0
    return DRMP3_TRUE;
4448
0
}
4449
4450
static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
4451
0
{
4452
0
    drmp3_seek_point seekPoint;
4453
0
    drmp3_uint32 priorSeekPointIndex;
4454
0
    drmp3_uint16 iMP3Frame;
4455
0
    drmp3_uint64 leftoverFrames;
4456
4457
0
    DRMP3_ASSERT(pMP3 != NULL);
4458
0
    DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
4459
0
    DRMP3_ASSERT(pMP3->seekPointCount > 0);
4460
4461
    /* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */
4462
0
    if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
4463
0
        seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
4464
0
    } else {
4465
0
        seekPoint.seekPosInBytes     = 0;
4466
0
        seekPoint.pcmFrameIndex      = 0;
4467
0
        seekPoint.mp3FramesToDiscard = 0;
4468
0
        seekPoint.pcmFramesToDiscard = 0;
4469
0
    }
4470
4471
    /* First thing to do is seek to the first byte of the relevant MP3 frame. */
4472
0
    if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, DRMP3_SEEK_SET)) {
4473
0
        return DRMP3_FALSE; /* Failed to seek. */
4474
0
    }
4475
4476
    /* Clear any cached data. */
4477
0
    drmp3_reset(pMP3);
4478
4479
    /* Whole MP3 frames need to be discarded first. */
4480
0
    for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
4481
0
        drmp3_uint32 pcmFramesRead;
4482
0
        drmp3d_sample_t* pPCMFrames;
4483
4484
        /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */
4485
0
        pPCMFrames = NULL;
4486
0
        if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
4487
0
            pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
4488
0
        }
4489
4490
        /* We first need to decode the next frame. */
4491
0
        pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames, NULL, NULL);
4492
0
        if (pcmFramesRead == 0) {
4493
0
            return DRMP3_FALSE;
4494
0
        }
4495
0
    }
4496
4497
    /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */
4498
0
    pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
4499
4500
    /*
4501
    Now at this point we can follow the same process as the brute force technique where we just skip over unnecessary MP3 frames and then
4502
    read-and-discard at least 2 whole MP3 frames.
4503
    */
4504
0
    leftoverFrames = frameIndex - pMP3->currentPCMFrame;
4505
0
    return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
4506
0
}
4507
4508
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
4509
0
{
4510
0
    if (pMP3 == NULL || pMP3->onSeek == NULL) {
4511
0
        return DRMP3_FALSE;
4512
0
    }
4513
4514
0
    if (frameIndex == 0) {
4515
0
        return drmp3_seek_to_start_of_stream(pMP3);
4516
0
    }
4517
4518
    /* Use the seek table if we have one. */
4519
0
    if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
4520
0
        return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
4521
0
    } else {
4522
0
        return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
4523
0
    }
4524
0
}
4525
4526
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
4527
0
{
4528
0
    drmp3_uint64 currentPCMFrame;
4529
0
    drmp3_uint64 totalPCMFrameCount;
4530
0
    drmp3_uint64 totalMP3FrameCount;
4531
4532
0
    if (pMP3 == NULL) {
4533
0
        return DRMP3_FALSE;
4534
0
    }
4535
4536
    /*
4537
    The way this works is we move back to the start of the stream, iterate over each MP3 frame and calculate the frame count based
4538
    on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function.
4539
    */
4540
4541
    /* The stream must support seeking for this to work. */
4542
0
    if (pMP3->onSeek == NULL) {
4543
0
        return DRMP3_FALSE;
4544
0
    }
4545
4546
    /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */
4547
0
    currentPCMFrame = pMP3->currentPCMFrame;
4548
4549
0
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
4550
0
        return DRMP3_FALSE;
4551
0
    }
4552
4553
0
    totalPCMFrameCount = 0;
4554
0
    totalMP3FrameCount = 0;
4555
4556
0
    for (;;) {
4557
0
        drmp3_uint32 pcmFramesInCurrentMP3Frame;
4558
4559
0
        pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
4560
0
        if (pcmFramesInCurrentMP3Frame == 0) {
4561
0
            break;
4562
0
        }
4563
4564
0
        totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
4565
0
        totalMP3FrameCount += 1;
4566
0
    }
4567
4568
    /* Finally, we need to seek back to where we were. */
4569
0
    if (!drmp3_seek_to_start_of_stream(pMP3)) {
4570
0
        return DRMP3_FALSE;
4571
0
    }
4572
4573
0
    if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
4574
0
        return DRMP3_FALSE;
4575
0
    }
4576
4577
0
    if (pMP3FrameCount != NULL) {
4578
0
        *pMP3FrameCount = totalMP3FrameCount;
4579
0
    }
4580
0
    if (pPCMFrameCount != NULL) {
4581
0
        *pPCMFrameCount = totalPCMFrameCount;
4582
0
    }
4583
4584
0
    return DRMP3_TRUE;
4585
0
}
4586
4587
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
4588
0
{
4589
0
    drmp3_uint64 totalPCMFrameCount;
4590
4591
0
    if (pMP3 == NULL) {
4592
0
        return 0;
4593
0
    }
4594
4595
0
    if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX) {
4596
0
        totalPCMFrameCount = pMP3->totalPCMFrameCount;
4597
4598
0
        if (totalPCMFrameCount >= pMP3->delayInPCMFrames) {
4599
0
            totalPCMFrameCount -= pMP3->delayInPCMFrames;
4600
0
        } else {
4601
            /* The delay is greater than the frame count reported by the Xing/Info tag. Assume it's invalid and ignore. */
4602
0
        }
4603
4604
0
        if (totalPCMFrameCount >= pMP3->paddingInPCMFrames) {
4605
0
            totalPCMFrameCount -= pMP3->paddingInPCMFrames;
4606
0
        } else {
4607
            /* The padding is greater than the frame count reported by the Xing/Info tag. Assume it's invalid and ignore. */
4608
0
        }
4609
4610
0
        return totalPCMFrameCount;
4611
0
    } else {
4612
        /* Unknown frame count. Need to calculate it. */
4613
0
        if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
4614
0
            return 0;
4615
0
        }
4616
4617
0
        return totalPCMFrameCount;
4618
0
    }
4619
0
}
4620
4621
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
4622
0
{
4623
0
    drmp3_uint64 totalMP3FrameCount;
4624
0
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
4625
0
        return 0;
4626
0
    }
4627
4628
0
    return totalMP3FrameCount;
4629
0
}
4630
4631
static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
4632
0
{
4633
0
    float srcRatio;
4634
0
    float pcmFrameCountOutF;
4635
0
    drmp3_uint32 pcmFrameCountOut;
4636
4637
0
    srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
4638
0
    DRMP3_ASSERT(srcRatio > 0);
4639
4640
0
    pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
4641
0
    pcmFrameCountOut  = (drmp3_uint32)pcmFrameCountOutF;
4642
0
    *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
4643
0
    *pRunningPCMFrameCount += pcmFrameCountOut;
4644
0
}
4645
4646
typedef struct
4647
{
4648
    drmp3_uint64 bytePos;
4649
    drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */
4650
} drmp3__seeking_mp3_frame_info;
4651
4652
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
4653
0
{
4654
0
    drmp3_uint32 seekPointCount;
4655
0
    drmp3_uint64 currentPCMFrame;
4656
0
    drmp3_uint64 totalMP3FrameCount;
4657
0
    drmp3_uint64 totalPCMFrameCount;
4658
4659
0
    if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
4660
0
        return DRMP3_FALSE; /* Invalid args. */
4661
0
    }
4662
4663
0
    seekPointCount = *pSeekPointCount;
4664
0
    if (seekPointCount == 0) {
4665
0
        return DRMP3_FALSE;  /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */
4666
0
    }
4667
4668
    /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */
4669
0
    currentPCMFrame = pMP3->currentPCMFrame;
4670
4671
    /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */
4672
0
    if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
4673
0
        return DRMP3_FALSE;
4674
0
    }
4675
4676
    /* If there's less than DRMP3_SEEK_LEADING_MP3_FRAMES+1 frames we just report 1 seek point which will be the very start of the stream. */
4677
0
    if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
4678
0
        seekPointCount = 1;
4679
0
        pSeekPoints[0].seekPosInBytes     = 0;
4680
0
        pSeekPoints[0].pcmFrameIndex      = 0;
4681
0
        pSeekPoints[0].mp3FramesToDiscard = 0;
4682
0
        pSeekPoints[0].pcmFramesToDiscard = 0;
4683
0
    } else {
4684
0
        drmp3_uint64 pcmFramesBetweenSeekPoints;
4685
0
        drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
4686
0
        drmp3_uint64 runningPCMFrameCount = 0;
4687
0
        float runningPCMFrameCountFractionalPart = 0;
4688
0
        drmp3_uint64 nextTargetPCMFrame;
4689
0
        drmp3_uint32 iMP3Frame;
4690
0
        drmp3_uint32 iSeekPoint;
4691
4692
0
        if (seekPointCount > totalMP3FrameCount-1) {
4693
0
            seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
4694
0
        }
4695
4696
0
        pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
4697
4698
        /*
4699
        Here is where we actually calculate the seek points. We need to start by moving the start of the stream. We then enumerate over each
4700
        MP3 frame.
4701
        */
4702
0
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
4703
0
            return DRMP3_FALSE;
4704
0
        }
4705
4706
        /*
4707
        We need to cache the byte positions of the previous MP3 frames. As a new MP3 frame is iterated, we cycle the byte positions in this
4708
        array. The value in the first item in this array is the byte position that will be reported in the next seek point.
4709
        */
4710
4711
        /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */
4712
0
        for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
4713
0
            drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4714
4715
            /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
4716
0
            DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
4717
0
            mp3FrameInfo[iMP3Frame].bytePos       = pMP3->streamCursor - pMP3->dataSize;
4718
0
            mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
4719
4720
            /* We need to get information about this frame so we can know how many samples it contained. */
4721
0
            pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
4722
0
            if (pcmFramesInCurrentMP3FrameIn == 0) {
4723
0
                return DRMP3_FALSE; /* This should never happen. */
4724
0
            }
4725
4726
0
            drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4727
0
        }
4728
4729
        /*
4730
        At this point we will have extracted the byte positions of the leading MP3 frames. We can now start iterating over each seek point and
4731
        calculate them.
4732
        */
4733
0
        nextTargetPCMFrame = 0;
4734
0
        for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
4735
0
            nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
4736
4737
0
            for (;;) {
4738
0
                if (nextTargetPCMFrame < runningPCMFrameCount) {
4739
                    /* The next seek point is in the current MP3 frame. */
4740
0
                    pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
4741
0
                    pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
4742
0
                    pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4743
0
                    pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4744
0
                    break;
4745
0
                } else {
4746
0
                    size_t i;
4747
0
                    drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4748
4749
                    /*
4750
                    The next seek point is not in the current MP3 frame, so continue on to the next one. The first thing to do is cycle the cached
4751
                    MP3 frame info.
4752
                    */
4753
0
                    for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
4754
0
                        mp3FrameInfo[i] = mp3FrameInfo[i+1];
4755
0
                    }
4756
4757
                    /* Cache previous MP3 frame info. */
4758
0
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos       = pMP3->streamCursor - pMP3->dataSize;
4759
0
                    mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
4760
4761
                    /*
4762
                    Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it
4763
                    should only ever do it for the last seek point.
4764
                    */
4765
0
                    pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
4766
0
                    if (pcmFramesInCurrentMP3FrameIn == 0) {
4767
0
                        pSeekPoints[iSeekPoint].seekPosInBytes     = mp3FrameInfo[0].bytePos;
4768
0
                        pSeekPoints[iSeekPoint].pcmFrameIndex      = nextTargetPCMFrame;
4769
0
                        pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4770
0
                        pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4771
0
                        break;
4772
0
                    }
4773
4774
0
                    drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4775
0
                }
4776
0
            }
4777
0
        }
4778
4779
        /* Finally, we need to seek back to where we were. */
4780
0
        if (!drmp3_seek_to_start_of_stream(pMP3)) {
4781
0
            return DRMP3_FALSE;
4782
0
        }
4783
0
        if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
4784
0
            return DRMP3_FALSE;
4785
0
        }
4786
0
    }
4787
4788
0
    *pSeekPointCount = seekPointCount;
4789
0
    return DRMP3_TRUE;
4790
0
}
4791
4792
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
4793
0
{
4794
0
    if (pMP3 == NULL) {
4795
0
        return DRMP3_FALSE;
4796
0
    }
4797
4798
0
    if (seekPointCount == 0 || pSeekPoints == NULL) {
4799
        /* Unbinding. */
4800
0
        pMP3->seekPointCount = 0;
4801
0
        pMP3->pSeekPoints = NULL;
4802
0
    } else {
4803
        /* Binding. */
4804
0
        pMP3->seekPointCount = seekPointCount;
4805
0
        pMP3->pSeekPoints = pSeekPoints;
4806
0
    }
4807
4808
0
    return DRMP3_TRUE;
4809
0
}
4810
4811
4812
static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4813
0
{
4814
0
    drmp3_uint64 totalFramesRead = 0;
4815
0
    drmp3_uint64 framesCapacity = 0;
4816
0
    float* pFrames = NULL;
4817
0
    float temp[1152*2];   /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
4818
4819
0
    DRMP3_ASSERT(pMP3 != NULL);
4820
4821
0
    for (;;) {
4822
0
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4823
0
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
4824
0
        if (framesJustRead == 0) {
4825
0
            break;
4826
0
        }
4827
4828
        /* Reallocate the output buffer if there's not enough room. */
4829
0
        if (framesCapacity < totalFramesRead + framesJustRead) {
4830
0
            drmp3_uint64 oldFramesBufferSize;
4831
0
            drmp3_uint64 newFramesBufferSize;
4832
0
            drmp3_uint64 newFramesCap;
4833
0
            float* pNewFrames;
4834
4835
0
            newFramesCap = framesCapacity * 2;
4836
0
            if (newFramesCap < totalFramesRead + framesJustRead) {
4837
0
                newFramesCap = totalFramesRead + framesJustRead;
4838
0
            }
4839
4840
0
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
4841
0
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(float);
4842
0
            if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
4843
0
                break;
4844
0
            }
4845
4846
0
            pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4847
0
            if (pNewFrames == NULL) {
4848
0
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4849
0
                pFrames = NULL;
4850
0
                totalFramesRead = 0;
4851
0
                break;
4852
0
            }
4853
4854
0
            pFrames = pNewFrames;
4855
0
            framesCapacity = newFramesCap;
4856
0
        }
4857
4858
0
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
4859
0
        totalFramesRead += framesJustRead;
4860
4861
        /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4862
0
        if (framesJustRead != framesToReadRightNow) {
4863
0
            break;
4864
0
        }
4865
0
    }
4866
4867
0
    if (pConfig != NULL) {
4868
0
        pConfig->channels   = pMP3->channels;
4869
0
        pConfig->sampleRate = pMP3->sampleRate;
4870
0
    }
4871
4872
0
    drmp3_uninit(pMP3);
4873
4874
0
    if (pTotalFrameCount) {
4875
0
        *pTotalFrameCount = totalFramesRead;
4876
0
    }
4877
4878
0
    return pFrames;
4879
0
}
4880
4881
static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4882
0
{
4883
0
    drmp3_uint64 totalFramesRead = 0;
4884
0
    drmp3_uint64 framesCapacity = 0;
4885
0
    drmp3_int16* pFrames = NULL;
4886
0
    drmp3_int16 temp[1152*2];   /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */
4887
4888
0
    DRMP3_ASSERT(pMP3 != NULL);
4889
4890
0
    for (;;) {
4891
0
        drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4892
0
        drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
4893
0
        if (framesJustRead == 0) {
4894
0
            break;
4895
0
        }
4896
4897
        /* Reallocate the output buffer if there's not enough room. */
4898
0
        if (framesCapacity < totalFramesRead + framesJustRead) {
4899
0
            drmp3_uint64 newFramesBufferSize;
4900
0
            drmp3_uint64 oldFramesBufferSize;
4901
0
            drmp3_uint64 newFramesCap;
4902
0
            drmp3_int16* pNewFrames;
4903
4904
0
            newFramesCap = framesCapacity * 2;
4905
0
            if (newFramesCap < totalFramesRead + framesJustRead) {
4906
0
                newFramesCap = totalFramesRead + framesJustRead;
4907
0
            }
4908
4909
0
            oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
4910
0
            newFramesBufferSize = newFramesCap   * pMP3->channels * sizeof(drmp3_int16);
4911
0
            if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
4912
0
                break;
4913
0
            }
4914
4915
0
            pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4916
0
            if (pNewFrames == NULL) {
4917
0
                drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4918
0
                pFrames = NULL;
4919
0
                totalFramesRead = 0;
4920
0
                break;
4921
0
            }
4922
4923
0
            pFrames = pNewFrames;
4924
0
            framesCapacity = newFramesCap;
4925
0
        }
4926
4927
0
        DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
4928
0
        totalFramesRead += framesJustRead;
4929
4930
        /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4931
0
        if (framesJustRead != framesToReadRightNow) {
4932
0
            break;
4933
0
        }
4934
0
    }
4935
4936
0
    if (pConfig != NULL) {
4937
0
        pConfig->channels   = pMP3->channels;
4938
0
        pConfig->sampleRate = pMP3->sampleRate;
4939
0
    }
4940
4941
0
    drmp3_uninit(pMP3);
4942
4943
0
    if (pTotalFrameCount) {
4944
0
        *pTotalFrameCount = totalFramesRead;
4945
0
    }
4946
4947
0
    return pFrames;
4948
0
}
4949
4950
4951
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4952
0
{
4953
0
    drmp3 mp3;
4954
0
    if (!drmp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) {
4955
0
        return NULL;
4956
0
    }
4957
4958
0
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4959
0
}
4960
4961
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4962
0
{
4963
0
    drmp3 mp3;
4964
0
    if (!drmp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) {
4965
0
        return NULL;
4966
0
    }
4967
4968
0
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4969
0
}
4970
4971
4972
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4973
0
{
4974
0
    drmp3 mp3;
4975
0
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4976
0
        return NULL;
4977
0
    }
4978
4979
0
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4980
0
}
4981
4982
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4983
0
{
4984
0
    drmp3 mp3;
4985
0
    if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4986
0
        return NULL;
4987
0
    }
4988
4989
0
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4990
0
}
4991
4992
4993
#ifndef DR_MP3_NO_STDIO
4994
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4995
0
{
4996
0
    drmp3 mp3;
4997
0
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4998
0
        return NULL;
4999
0
    }
5000
5001
0
    return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
5002
0
}
5003
5004
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
5005
0
{
5006
0
    drmp3 mp3;
5007
0
    if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
5008
0
        return NULL;
5009
0
    }
5010
5011
0
    return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
5012
0
}
5013
#endif
5014
5015
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
5016
0
{
5017
0
    if (pAllocationCallbacks != NULL) {
5018
0
        return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks);
5019
0
    } else {
5020
0
        return drmp3__malloc_default(sz, NULL);
5021
0
    }
5022
0
}
5023
5024
DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
5025
0
{
5026
0
    if (pAllocationCallbacks != NULL) {
5027
0
        drmp3__free_from_callbacks(p, pAllocationCallbacks);
5028
0
    } else {
5029
        drmp3__free_default(p, NULL);
5030
0
    }
5031
0
}
5032
5033
#endif  /* dr_mp3_c */
5034
#endif  /*DR_MP3_IMPLEMENTATION*/
5035
5036
/*
5037
DIFFERENCES BETWEEN minimp3 AND dr_mp3
5038
======================================
5039
- First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the
5040
  code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes.
5041
- dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data
5042
  to the decoder, the decoder _pulls_ data from your callbacks.
5043
- In addition to callbacks, a decoder can be initialized from a block of memory and a file.
5044
- The dr_mp3 pull API reads PCM frames rather than whole MP3 frames.
5045
- dr_mp3 adds convenience APIs for opening and decoding entire files in one go.
5046
- dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects
5047
  as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when
5048
  using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this.
5049
*/
5050
5051
/*
5052
REVISION HISTORY
5053
================
5054
v0.7.4 - TBD
5055
  - Fix an overflow error with "Xing" and "Info" tag parsing.
5056
  - Add some validation checks for "Xing" and "Info" tag parsing.
5057
  - Reduce size of some stack allocations.
5058
  - Improvements to SIMD detection.
5059
5060
v0.7.3 - 2026-01-17
5061
  - Fix an error in drmp3_open_and_read_pcm_frames_s16() and family when memory allocation fails.
5062
  - Fix some compilation warnings.
5063
5064
v0.7.2 - 2025-12-02
5065
  - Reduce stack space to improve robustness on embedded systems.
5066
  - Fix a compilation error with MSVC Clang toolset relating to cpuid.
5067
  - Fix an error with APE tag parsing.
5068
5069
v0.7.1 - 2025-09-10
5070
  - Silence a warning with GCC.
5071
  - Fix an error with the NXDK build.
5072
  - Fix a decoding inconsistency when seeking. Prior to this change, reading to the end of the stream immediately after initializing will result in a different number of samples read than if the stream is seeked to the start and read to the end.
5073
5074
v0.7.0 - 2025-07-23
5075
  - The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`.
5076
  - API CHANGE: Seek origins have been renamed to match the naming convention used by dr_wav and my other libraries.
5077
    - drmp3_seek_origin_start   -> DRMP3_SEEK_SET
5078
    - drmp3_seek_origin_current -> DRMP3_SEEK_CUR
5079
    - DRMP3_SEEK_END (new)
5080
  - API CHANGE: Add DRMP3_SEEK_END as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags.
5081
  - API CHANGE: Add onTell callback to `drmp3_init()`. This is needed in order to track the location of ID3v1 and APE tags.
5082
  - API CHANGE: Add onMeta callback to `drmp3_init()`. This is used for reporting tag data back to the caller. Currently this only reports the raw tag data which means applications need to parse the data themselves.
5083
  - API CHANGE: Rename `drmp3dec_frame_info.hz` to `drmp3dec_frame_info.sample_rate`.
5084
  - Add detection of ID3v2, ID3v1, APE and Xing/VBRI tags. This should fix errors with some files where the decoder was reading tags as audio data.
5085
  - Delay and padding samples from LAME tags are now handled.
5086
  - Fix compilation for AIX OS.
5087
5088
v0.6.40 - 2024-12-17
5089
  - Improve detection of ARM64EC
5090
5091
v0.6.39 - 2024-02-27
5092
  - Fix a Wdouble-promotion warning.
5093
5094
v0.6.38 - 2023-11-02
5095
  - Fix build for ARMv6-M.
5096
5097
v0.6.37 - 2023-07-07
5098
  - Silence a static analysis warning.
5099
5100
v0.6.36 - 2023-06-17
5101
  - Fix an incorrect date in revision history. No functional change.
5102
5103
v0.6.35 - 2023-05-22
5104
  - Minor code restructure. No functional change.
5105
5106
v0.6.34 - 2022-09-17
5107
  - Fix compilation with DJGPP.
5108
  - Fix compilation when compiling with x86 with no SSE2.
5109
  - Remove an unnecessary variable from the drmp3 structure.
5110
5111
v0.6.33 - 2022-04-10
5112
  - Fix compilation error with the MSVC ARM64 build.
5113
  - Fix compilation error on older versions of GCC.
5114
  - Remove some unused functions.
5115
5116
v0.6.32 - 2021-12-11
5117
  - Fix a warning with Clang.
5118
5119
v0.6.31 - 2021-08-22
5120
  - Fix a bug when loading from memory.
5121
5122
v0.6.30 - 2021-08-16
5123
  - Silence some warnings.
5124
  - Replace memory operations with DRMP3_* macros.
5125
5126
v0.6.29 - 2021-08-08
5127
  - Bring up to date with minimp3.
5128
5129
v0.6.28 - 2021-07-31
5130
  - Fix platform detection for ARM64.
5131
  - Fix a compilation error with C89.
5132
5133
v0.6.27 - 2021-02-21
5134
  - Fix a warning due to referencing _MSC_VER when it is undefined.
5135
5136
v0.6.26 - 2021-01-31
5137
  - Bring up to date with minimp3.
5138
5139
v0.6.25 - 2020-12-26
5140
  - Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs.
5141
5142
v0.6.24 - 2020-12-07
5143
  - Fix a typo in version date for 0.6.23.
5144
5145
v0.6.23 - 2020-12-03
5146
  - Fix an error where a file can be closed twice when initialization of the decoder fails.
5147
5148
v0.6.22 - 2020-12-02
5149
  - Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails.
5150
5151
v0.6.21 - 2020-11-28
5152
  - Bring up to date with minimp3.
5153
5154
v0.6.20 - 2020-11-21
5155
  - Fix compilation with OpenWatcom.
5156
5157
v0.6.19 - 2020-11-13
5158
  - Minor code clean up.
5159
5160
v0.6.18 - 2020-11-01
5161
  - Improve compiler support for older versions of GCC.
5162
5163
v0.6.17 - 2020-09-28
5164
  - Bring up to date with minimp3.
5165
5166
v0.6.16 - 2020-08-02
5167
  - Simplify sized types.
5168
5169
v0.6.15 - 2020-07-25
5170
  - Fix a compilation warning.
5171
5172
v0.6.14 - 2020-07-23
5173
  - Fix undefined behaviour with memmove().
5174
5175
v0.6.13 - 2020-07-06
5176
  - Fix a bug when converting from s16 to f32 in drmp3_read_pcm_frames_f32().
5177
5178
v0.6.12 - 2020-06-23
5179
  - Add include guard for the implementation section.
5180
5181
v0.6.11 - 2020-05-26
5182
  - Fix use of uninitialized variable error.
5183
5184
v0.6.10 - 2020-05-16
5185
  - Add compile-time and run-time version querying.
5186
    - DRMP3_VERSION_MINOR
5187
    - DRMP3_VERSION_MAJOR
5188
    - DRMP3_VERSION_REVISION
5189
    - DRMP3_VERSION_STRING
5190
    - drmp3_version()
5191
    - drmp3_version_string()
5192
5193
v0.6.9 - 2020-04-30
5194
  - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs.
5195
5196
v0.6.8 - 2020-04-26
5197
  - Optimizations to decoding when initializing from memory.
5198
5199
v0.6.7 - 2020-04-25
5200
  - Fix a compilation error with DR_MP3_NO_STDIO
5201
  - Optimization to decoding by reducing some data movement.
5202
5203
v0.6.6 - 2020-04-23
5204
  - Fix a minor bug with the running PCM frame counter.
5205
5206
v0.6.5 - 2020-04-19
5207
  - Fix compilation error on ARM builds.
5208
5209
v0.6.4 - 2020-04-19
5210
  - Bring up to date with changes to minimp3.
5211
5212
v0.6.3 - 2020-04-13
5213
  - Fix some pedantic warnings.
5214
5215
v0.6.2 - 2020-04-10
5216
  - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL.
5217
5218
v0.6.1 - 2020-04-05
5219
  - Fix warnings.
5220
5221
v0.6.0 - 2020-04-04
5222
  - API CHANGE: Remove the pConfig parameter from the following APIs:
5223
    - drmp3_init()
5224
    - drmp3_init_memory()
5225
    - drmp3_init_file()
5226
  - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path.
5227
5228
v0.5.6 - 2020-02-12
5229
  - Bring up to date with minimp3.
5230
5231
v0.5.5 - 2020-01-29
5232
  - Fix a memory allocation bug in high level s16 decoding APIs.
5233
5234
v0.5.4 - 2019-12-02
5235
  - Fix a possible null pointer dereference when using custom memory allocators for realloc().
5236
5237
v0.5.3 - 2019-11-14
5238
  - Fix typos in documentation.
5239
5240
v0.5.2 - 2019-11-02
5241
  - Bring up to date with minimp3.
5242
5243
v0.5.1 - 2019-10-08
5244
  - Fix a warning with GCC.
5245
5246
v0.5.0 - 2019-10-07
5247
  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
5248
    routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
5249
    - drmp3_init()
5250
    - drmp3_init_file()
5251
    - drmp3_init_memory()
5252
    - drmp3_open_and_read_pcm_frames_f32()
5253
    - drmp3_open_and_read_pcm_frames_s16()
5254
    - drmp3_open_memory_and_read_pcm_frames_f32()
5255
    - drmp3_open_memory_and_read_pcm_frames_s16()
5256
    - drmp3_open_file_and_read_pcm_frames_f32()
5257
    - drmp3_open_file_and_read_pcm_frames_s16()
5258
  - API CHANGE: Renamed the following APIs:
5259
    - drmp3_open_and_read_f32()        -> drmp3_open_and_read_pcm_frames_f32()
5260
    - drmp3_open_and_read_s16()        -> drmp3_open_and_read_pcm_frames_s16()
5261
    - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
5262
    - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
5263
    - drmp3_open_file_and_read_f32()   -> drmp3_open_file_and_read_pcm_frames_f32()
5264
    - drmp3_open_file_and_read_s16()   -> drmp3_open_file_and_read_pcm_frames_s16()
5265
5266
v0.4.7 - 2019-07-28
5267
  - Fix a compiler error.
5268
5269
v0.4.6 - 2019-06-14
5270
  - Fix a compiler error.
5271
5272
v0.4.5 - 2019-06-06
5273
  - Bring up to date with minimp3.
5274
5275
v0.4.4 - 2019-05-06
5276
  - Fixes to the VC6 build.
5277
5278
v0.4.3 - 2019-05-05
5279
  - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and
5280
    DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to
5281
    DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE.
5282
  - Add s16 reading APIs
5283
    - drmp3_read_pcm_frames_s16
5284
    - drmp3_open_memory_and_read_pcm_frames_s16
5285
    - drmp3_open_and_read_pcm_frames_s16
5286
    - drmp3_open_file_and_read_pcm_frames_s16
5287
  - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section.
5288
  - Add support for C89.
5289
  - Change license to choice of public domain or MIT-0.
5290
5291
v0.4.2 - 2019-02-21
5292
  - Fix a warning.
5293
5294
v0.4.1 - 2018-12-30
5295
  - Fix a warning.
5296
5297
v0.4.0 - 2018-12-16
5298
  - API CHANGE: Rename some APIs:
5299
    - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32
5300
    - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame
5301
    - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32
5302
    - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32
5303
    - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32
5304
  - Add drmp3_get_pcm_frame_count().
5305
  - Add drmp3_get_mp3_frame_count().
5306
  - Improve seeking performance.
5307
5308
v0.3.2 - 2018-09-11
5309
  - Fix a couple of memory leaks.
5310
  - Bring up to date with minimp3.
5311
5312
v0.3.1 - 2018-08-25
5313
  - Fix C++ build.
5314
5315
v0.3.0 - 2018-08-25
5316
  - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has
5317
    been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or
5318
    not the DR_MP3_FLOAT_OUTPUT option is set.
5319
5320
v0.2.11 - 2018-08-08
5321
  - Fix a bug where the last part of a file is not read.
5322
5323
v0.2.10 - 2018-08-07
5324
  - Improve 64-bit detection.
5325
5326
v0.2.9 - 2018-08-05
5327
  - Fix C++ build on older versions of GCC.
5328
  - Bring up to date with minimp3.
5329
5330
v0.2.8 - 2018-08-02
5331
  - Fix compilation errors with older versions of GCC.
5332
5333
v0.2.7 - 2018-07-13
5334
  - Bring up to date with minimp3.
5335
5336
v0.2.6 - 2018-07-12
5337
  - Bring up to date with minimp3.
5338
5339
v0.2.5 - 2018-06-22
5340
  - Bring up to date with minimp3.
5341
5342
v0.2.4 - 2018-05-12
5343
  - Bring up to date with minimp3.
5344
5345
v0.2.3 - 2018-04-29
5346
  - Fix TCC build.
5347
5348
v0.2.2 - 2018-04-28
5349
  - Fix bug when opening a decoder from memory.
5350
5351
v0.2.1 - 2018-04-27
5352
  - Efficiency improvements when the decoder reaches the end of the stream.
5353
5354
v0.2 - 2018-04-21
5355
  - Bring up to date with minimp3.
5356
  - Start using major.minor.revision versioning.
5357
5358
v0.1d - 2018-03-30
5359
  - Bring up to date with minimp3.
5360
5361
v0.1c - 2018-03-11
5362
  - Fix C++ build error.
5363
5364
v0.1b - 2018-03-07
5365
  - Bring up to date with minimp3.
5366
5367
v0.1a - 2018-02-28
5368
  - Fix compilation error on GCC/Clang.
5369
  - Fix some warnings.
5370
5371
v0.1 - 2018-02-xx
5372
  - Initial versioned release.
5373
*/
5374
5375
/*
5376
This software is available as a choice of the following licenses. Choose
5377
whichever you prefer.
5378
5379
===============================================================================
5380
ALTERNATIVE 1 - Public Domain (www.unlicense.org)
5381
===============================================================================
5382
This is free and unencumbered software released into the public domain.
5383
5384
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5385
software, either in source code form or as a compiled binary, for any purpose,
5386
commercial or non-commercial, and by any means.
5387
5388
In jurisdictions that recognize copyright laws, the author or authors of this
5389
software dedicate any and all copyright interest in the software to the public
5390
domain. We make this dedication for the benefit of the public at large and to
5391
the detriment of our heirs and successors. We intend this dedication to be an
5392
overt act of relinquishment in perpetuity of all present and future rights to
5393
this software under copyright law.
5394
5395
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5396
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5397
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5398
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5399
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5400
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5401
5402
For more information, please refer to <http://unlicense.org/>
5403
5404
===============================================================================
5405
ALTERNATIVE 2 - MIT No Attribution
5406
===============================================================================
5407
Copyright 2023 David Reid
5408
5409
Permission is hereby granted, free of charge, to any person obtaining a copy of
5410
this software and associated documentation files (the "Software"), to deal in
5411
the Software without restriction, including without limitation the rights to
5412
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5413
of the Software, and to permit persons to whom the Software is furnished to do
5414
so.
5415
5416
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5417
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5418
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5419
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5420
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5421
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5422
SOFTWARE.
5423
*/
5424
5425
/*
5426
    https://github.com/lieff/minimp3
5427
    To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
5428
    This software is distributed without any warranty.
5429
    See <http://creativecommons.org/publicdomain/zero/1.0/>.
5430
*/