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