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