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