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.26 - 2021-01-31
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 26
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 drmp3dec_frame_info info;
2644
2645 for (;;) {
2646 memset(&info, 0, sizeof(info));
2647
2648 /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */
2649 if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
2650 size_t bytesRead;
2651
2652 /* First we need to move the data down. */
2653 if (pMP3->pData != NULL) {
2654 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2655 }
2656
2657 pMP3->dataConsumed = 0;
2658
2659 if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
2660 drmp3_uint8* pNewData;
2661 size_t newDataCap;
2662
2663 newDataCap = DRMP3_DATA_CHUNK_SIZE;
2664
2665 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2666 if (pNewData == NULL) {
2667 return 0; /* Out of memory. */
2668 }
2669
2670 pMP3->pData = pNewData;
2671 pMP3->dataCapacity = newDataCap;
2672 }
2673
2674 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2675 if (bytesRead == 0) {
2676 if (pMP3->dataSize == 0) {
2677 pMP3->atEnd = DRMP3_TRUE;
2678 return 0; /* No data. */
2679 }
2680 }
2681
2682 pMP3->dataSize += bytesRead;
2683 }
2684
2685 if (pMP3->dataSize > INT_MAX) {
2686 pMP3->atEnd = DRMP3_TRUE;
2687 return 0; /* File too big. */
2688 }
2689
2690 DRMP3_ASSERT(pMP3->pData != NULL);
2691 DRMP3_ASSERT(pMP3->dataCapacity > 0);
2692
2693 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. */
2694
2695 /* Consume the data. */
2696 if (info.frame_bytes > 0) {
2697 pMP3->dataConsumed += (size_t)info.frame_bytes;
2698 pMP3->dataSize -= (size_t)info.frame_bytes;
2699 }
2700
2701 /* 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. */
2702 if (pcmFramesRead > 0) {
2703 pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2704 pMP3->pcmFramesConsumedInMP3Frame = 0;
2705 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2706 pMP3->mp3FrameChannels = info.channels;
2707 pMP3->mp3FrameSampleRate = info.hz;
2708 break;
2709 } else if (info.frame_bytes == 0) {
2710 /* Need more data. minimp3 recommends doing data submission in 16K chunks. */
2711 size_t bytesRead;
2712
2713 /* First we need to move the data down. */
2714 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2715 pMP3->dataConsumed = 0;
2716
2717 if (pMP3->dataCapacity == pMP3->dataSize) {
2718 /* No room. Expand. */
2719 drmp3_uint8* pNewData;
2720 size_t newDataCap;
2721
2722 newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
2723
2724 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2725 if (pNewData == NULL) {
2726 return 0; /* Out of memory. */
2727 }
2728
2729 pMP3->pData = pNewData;
2730 pMP3->dataCapacity = newDataCap;
2731 }
2732
2733 /* Fill in a chunk. */
2734 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2735 if (bytesRead == 0) {
2736 pMP3->atEnd = DRMP3_TRUE;
2737 return 0; /* Error reading more data. */
2738 }
2739
2740 pMP3->dataSize += bytesRead;
2741 }
2742 };
2743
2744 pMP3->frameInfo = info;
2745 return pcmFramesRead;
2746 }
2747
drmp3_decode_next_frame_ex__memory(drmp3 * pMP3,drmp3d_sample_t * pPCMFrames)2748 static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2749 {
2750 drmp3_uint32 pcmFramesRead = 0;
2751 drmp3dec_frame_info info;
2752
2753 DRMP3_ASSERT(pMP3 != NULL);
2754 DRMP3_ASSERT(pMP3->memory.pData != NULL);
2755
2756 if (pMP3->atEnd) {
2757 return 0;
2758 }
2759
2760 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
2761 if (pcmFramesRead > 0) {
2762 pMP3->pcmFramesConsumedInMP3Frame = 0;
2763 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2764 pMP3->mp3FrameChannels = info.channels;
2765 pMP3->mp3FrameSampleRate = info.hz;
2766 }
2767
2768 /* Consume the data. */
2769 pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2770
2771 return pcmFramesRead;
2772 }
2773
drmp3_decode_next_frame_ex(drmp3 * pMP3,drmp3d_sample_t * pPCMFrames)2774 static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2775 {
2776 if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
2777 return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
2778 } else {
2779 return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
2780 }
2781 }
2782
drmp3_decode_next_frame(drmp3 * pMP3)2783 static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
2784 {
2785 DRMP3_ASSERT(pMP3 != NULL);
2786 return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
2787 }
2788
2789 #if 0
2790 static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
2791 {
2792 drmp3_uint32 pcmFrameCount;
2793
2794 DRMP3_ASSERT(pMP3 != NULL);
2795
2796 pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
2797 if (pcmFrameCount == 0) {
2798 return 0;
2799 }
2800
2801 /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */
2802 pMP3->currentPCMFrame += pcmFrameCount;
2803 pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount;
2804 pMP3->pcmFramesRemainingInMP3Frame = 0;
2805
2806 return pcmFrameCount;
2807 }
2808 #endif
2809
drmp3_init_internal(drmp3 * pMP3,drmp3_read_proc onRead,drmp3_seek_proc onSeek,void * pUserData,const drmp3_allocation_callbacks * pAllocationCallbacks)2810 static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2811 {
2812 DRMP3_ASSERT(pMP3 != NULL);
2813 DRMP3_ASSERT(onRead != NULL);
2814
2815 /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
2816 drmp3dec_init(&pMP3->decoder);
2817
2818 pMP3->onRead = onRead;
2819 pMP3->onSeek = onSeek;
2820 pMP3->pUserData = pUserData;
2821 pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
2822
2823 if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
2824 return DRMP3_FALSE; /* Invalid allocation callbacks. */
2825 }
2826
2827 /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */
2828 if (!drmp3_decode_next_frame(pMP3)) {
2829 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
2830 return DRMP3_FALSE; /* Not a valid MP3 stream. */
2831 }
2832
2833 pMP3->channels = pMP3->mp3FrameChannels;
2834 pMP3->sampleRate = pMP3->mp3FrameSampleRate;
2835
2836 return DRMP3_TRUE;
2837 }
2838
drmp3_init(drmp3 * pMP3,drmp3_read_proc onRead,drmp3_seek_proc onSeek,void * pUserData,const drmp3_allocation_callbacks * pAllocationCallbacks)2839 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2840 {
2841 if (pMP3 == NULL || onRead == NULL) {
2842 return DRMP3_FALSE;
2843 }
2844
2845 DRMP3_ZERO_OBJECT(pMP3);
2846 return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks);
2847 }
2848
2849
drmp3__on_read_memory(void * pUserData,void * pBufferOut,size_t bytesToRead)2850 static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
2851 {
2852 drmp3* pMP3 = (drmp3*)pUserData;
2853 size_t bytesRemaining;
2854
2855 DRMP3_ASSERT(pMP3 != NULL);
2856 DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
2857
2858 bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
2859 if (bytesToRead > bytesRemaining) {
2860 bytesToRead = bytesRemaining;
2861 }
2862
2863 if (bytesToRead > 0) {
2864 DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
2865 pMP3->memory.currentReadPos += bytesToRead;
2866 }
2867
2868 return bytesToRead;
2869 }
2870
drmp3__on_seek_memory(void * pUserData,int byteOffset,drmp3_seek_origin origin)2871 static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
2872 {
2873 drmp3* pMP3 = (drmp3*)pUserData;
2874
2875 DRMP3_ASSERT(pMP3 != NULL);
2876
2877 if (origin == drmp3_seek_origin_current) {
2878 if (byteOffset > 0) {
2879 if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
2880 byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */
2881 }
2882 } else {
2883 if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
2884 byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */
2885 }
2886 }
2887
2888 /* This will never underflow thanks to the clamps above. */
2889 pMP3->memory.currentReadPos += byteOffset;
2890 } else {
2891 if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) {
2892 pMP3->memory.currentReadPos = byteOffset;
2893 } else {
2894 pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */
2895 }
2896 }
2897
2898 return DRMP3_TRUE;
2899 }
2900
drmp3_init_memory(drmp3 * pMP3,const void * pData,size_t dataSize,const drmp3_allocation_callbacks * pAllocationCallbacks)2901 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
2902 {
2903 if (pMP3 == NULL) {
2904 return DRMP3_FALSE;
2905 }
2906
2907 DRMP3_ZERO_OBJECT(pMP3);
2908
2909 if (pData == NULL || dataSize == 0) {
2910 return DRMP3_FALSE;
2911 }
2912
2913 pMP3->memory.pData = (const drmp3_uint8*)pData;
2914 pMP3->memory.dataSize = dataSize;
2915 pMP3->memory.currentReadPos = 0;
2916
2917 return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks);
2918 }
2919
2920
2921 #ifndef DR_MP3_NO_STDIO
2922 #include <stdio.h>
2923 #include <wchar.h> /* For wcslen(), wcsrtombs() */
2924
2925 /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
2926 #include <errno.h>
drmp3_result_from_errno(int e)2927 static drmp3_result drmp3_result_from_errno(int e)
2928 {
2929 switch (e)
2930 {
2931 case 0: return DRMP3_SUCCESS;
2932 #ifdef EPERM
2933 case EPERM: return DRMP3_INVALID_OPERATION;
2934 #endif
2935 #ifdef ENOENT
2936 case ENOENT: return DRMP3_DOES_NOT_EXIST;
2937 #endif
2938 #ifdef ESRCH
2939 case ESRCH: return DRMP3_DOES_NOT_EXIST;
2940 #endif
2941 #ifdef EINTR
2942 case EINTR: return DRMP3_INTERRUPT;
2943 #endif
2944 #ifdef EIO
2945 case EIO: return DRMP3_IO_ERROR;
2946 #endif
2947 #ifdef ENXIO
2948 case ENXIO: return DRMP3_DOES_NOT_EXIST;
2949 #endif
2950 #ifdef E2BIG
2951 case E2BIG: return DRMP3_INVALID_ARGS;
2952 #endif
2953 #ifdef ENOEXEC
2954 case ENOEXEC: return DRMP3_INVALID_FILE;
2955 #endif
2956 #ifdef EBADF
2957 case EBADF: return DRMP3_INVALID_FILE;
2958 #endif
2959 #ifdef ECHILD
2960 case ECHILD: return DRMP3_ERROR;
2961 #endif
2962 #ifdef EAGAIN
2963 case EAGAIN: return DRMP3_UNAVAILABLE;
2964 #endif
2965 #ifdef ENOMEM
2966 case ENOMEM: return DRMP3_OUT_OF_MEMORY;
2967 #endif
2968 #ifdef EACCES
2969 case EACCES: return DRMP3_ACCESS_DENIED;
2970 #endif
2971 #ifdef EFAULT
2972 case EFAULT: return DRMP3_BAD_ADDRESS;
2973 #endif
2974 #ifdef ENOTBLK
2975 case ENOTBLK: return DRMP3_ERROR;
2976 #endif
2977 #ifdef EBUSY
2978 case EBUSY: return DRMP3_BUSY;
2979 #endif
2980 #ifdef EEXIST
2981 case EEXIST: return DRMP3_ALREADY_EXISTS;
2982 #endif
2983 #ifdef EXDEV
2984 case EXDEV: return DRMP3_ERROR;
2985 #endif
2986 #ifdef ENODEV
2987 case ENODEV: return DRMP3_DOES_NOT_EXIST;
2988 #endif
2989 #ifdef ENOTDIR
2990 case ENOTDIR: return DRMP3_NOT_DIRECTORY;
2991 #endif
2992 #ifdef EISDIR
2993 case EISDIR: return DRMP3_IS_DIRECTORY;
2994 #endif
2995 #ifdef EINVAL
2996 case EINVAL: return DRMP3_INVALID_ARGS;
2997 #endif
2998 #ifdef ENFILE
2999 case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3000 #endif
3001 #ifdef EMFILE
3002 case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3003 #endif
3004 #ifdef ENOTTY
3005 case ENOTTY: return DRMP3_INVALID_OPERATION;
3006 #endif
3007 #ifdef ETXTBSY
3008 case ETXTBSY: return DRMP3_BUSY;
3009 #endif
3010 #ifdef EFBIG
3011 case EFBIG: return DRMP3_TOO_BIG;
3012 #endif
3013 #ifdef ENOSPC
3014 case ENOSPC: return DRMP3_NO_SPACE;
3015 #endif
3016 #ifdef ESPIPE
3017 case ESPIPE: return DRMP3_BAD_SEEK;
3018 #endif
3019 #ifdef EROFS
3020 case EROFS: return DRMP3_ACCESS_DENIED;
3021 #endif
3022 #ifdef EMLINK
3023 case EMLINK: return DRMP3_TOO_MANY_LINKS;
3024 #endif
3025 #ifdef EPIPE
3026 case EPIPE: return DRMP3_BAD_PIPE;
3027 #endif
3028 #ifdef EDOM
3029 case EDOM: return DRMP3_OUT_OF_RANGE;
3030 #endif
3031 #ifdef ERANGE
3032 case ERANGE: return DRMP3_OUT_OF_RANGE;
3033 #endif
3034 #ifdef EDEADLK
3035 case EDEADLK: return DRMP3_DEADLOCK;
3036 #endif
3037 #ifdef ENAMETOOLONG
3038 case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
3039 #endif
3040 #ifdef ENOLCK
3041 case ENOLCK: return DRMP3_ERROR;
3042 #endif
3043 #ifdef ENOSYS
3044 case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
3045 #endif
3046 #ifdef ENOTEMPTY
3047 case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
3048 #endif
3049 #ifdef ELOOP
3050 case ELOOP: return DRMP3_TOO_MANY_LINKS;
3051 #endif
3052 #ifdef ENOMSG
3053 case ENOMSG: return DRMP3_NO_MESSAGE;
3054 #endif
3055 #ifdef EIDRM
3056 case EIDRM: return DRMP3_ERROR;
3057 #endif
3058 #ifdef ECHRNG
3059 case ECHRNG: return DRMP3_ERROR;
3060 #endif
3061 #ifdef EL2NSYNC
3062 case EL2NSYNC: return DRMP3_ERROR;
3063 #endif
3064 #ifdef EL3HLT
3065 case EL3HLT: return DRMP3_ERROR;
3066 #endif
3067 #ifdef EL3RST
3068 case EL3RST: return DRMP3_ERROR;
3069 #endif
3070 #ifdef ELNRNG
3071 case ELNRNG: return DRMP3_OUT_OF_RANGE;
3072 #endif
3073 #ifdef EUNATCH
3074 case EUNATCH: return DRMP3_ERROR;
3075 #endif
3076 #ifdef ENOCSI
3077 case ENOCSI: return DRMP3_ERROR;
3078 #endif
3079 #ifdef EL2HLT
3080 case EL2HLT: return DRMP3_ERROR;
3081 #endif
3082 #ifdef EBADE
3083 case EBADE: return DRMP3_ERROR;
3084 #endif
3085 #ifdef EBADR
3086 case EBADR: return DRMP3_ERROR;
3087 #endif
3088 #ifdef EXFULL
3089 case EXFULL: return DRMP3_ERROR;
3090 #endif
3091 #ifdef ENOANO
3092 case ENOANO: return DRMP3_ERROR;
3093 #endif
3094 #ifdef EBADRQC
3095 case EBADRQC: return DRMP3_ERROR;
3096 #endif
3097 #ifdef EBADSLT
3098 case EBADSLT: return DRMP3_ERROR;
3099 #endif
3100 #ifdef EBFONT
3101 case EBFONT: return DRMP3_INVALID_FILE;
3102 #endif
3103 #ifdef ENOSTR
3104 case ENOSTR: return DRMP3_ERROR;
3105 #endif
3106 #ifdef ENODATA
3107 case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
3108 #endif
3109 #ifdef ETIME
3110 case ETIME: return DRMP3_TIMEOUT;
3111 #endif
3112 #ifdef ENOSR
3113 case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
3114 #endif
3115 #ifdef ENONET
3116 case ENONET: return DRMP3_NO_NETWORK;
3117 #endif
3118 #ifdef ENOPKG
3119 case ENOPKG: return DRMP3_ERROR;
3120 #endif
3121 #ifdef EREMOTE
3122 case EREMOTE: return DRMP3_ERROR;
3123 #endif
3124 #ifdef ENOLINK
3125 case ENOLINK: return DRMP3_ERROR;
3126 #endif
3127 #ifdef EADV
3128 case EADV: return DRMP3_ERROR;
3129 #endif
3130 #ifdef ESRMNT
3131 case ESRMNT: return DRMP3_ERROR;
3132 #endif
3133 #ifdef ECOMM
3134 case ECOMM: return DRMP3_ERROR;
3135 #endif
3136 #ifdef EPROTO
3137 case EPROTO: return DRMP3_ERROR;
3138 #endif
3139 #ifdef EMULTIHOP
3140 case EMULTIHOP: return DRMP3_ERROR;
3141 #endif
3142 #ifdef EDOTDOT
3143 case EDOTDOT: return DRMP3_ERROR;
3144 #endif
3145 #ifdef EBADMSG
3146 case EBADMSG: return DRMP3_BAD_MESSAGE;
3147 #endif
3148 #ifdef EOVERFLOW
3149 case EOVERFLOW: return DRMP3_TOO_BIG;
3150 #endif
3151 #ifdef ENOTUNIQ
3152 case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
3153 #endif
3154 #ifdef EBADFD
3155 case EBADFD: return DRMP3_ERROR;
3156 #endif
3157 #ifdef EREMCHG
3158 case EREMCHG: return DRMP3_ERROR;
3159 #endif
3160 #ifdef ELIBACC
3161 case ELIBACC: return DRMP3_ACCESS_DENIED;
3162 #endif
3163 #ifdef ELIBBAD
3164 case ELIBBAD: return DRMP3_INVALID_FILE;
3165 #endif
3166 #ifdef ELIBSCN
3167 case ELIBSCN: return DRMP3_INVALID_FILE;
3168 #endif
3169 #ifdef ELIBMAX
3170 case ELIBMAX: return DRMP3_ERROR;
3171 #endif
3172 #ifdef ELIBEXEC
3173 case ELIBEXEC: return DRMP3_ERROR;
3174 #endif
3175 #ifdef EILSEQ
3176 case EILSEQ: return DRMP3_INVALID_DATA;
3177 #endif
3178 #ifdef ERESTART
3179 case ERESTART: return DRMP3_ERROR;
3180 #endif
3181 #ifdef ESTRPIPE
3182 case ESTRPIPE: return DRMP3_ERROR;
3183 #endif
3184 #ifdef EUSERS
3185 case EUSERS: return DRMP3_ERROR;
3186 #endif
3187 #ifdef ENOTSOCK
3188 case ENOTSOCK: return DRMP3_NOT_SOCKET;
3189 #endif
3190 #ifdef EDESTADDRREQ
3191 case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
3192 #endif
3193 #ifdef EMSGSIZE
3194 case EMSGSIZE: return DRMP3_TOO_BIG;
3195 #endif
3196 #ifdef EPROTOTYPE
3197 case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
3198 #endif
3199 #ifdef ENOPROTOOPT
3200 case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
3201 #endif
3202 #ifdef EPROTONOSUPPORT
3203 case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
3204 #endif
3205 #ifdef ESOCKTNOSUPPORT
3206 case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
3207 #endif
3208 #ifdef EOPNOTSUPP
3209 case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
3210 #endif
3211 #ifdef EPFNOSUPPORT
3212 case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
3213 #endif
3214 #ifdef EAFNOSUPPORT
3215 case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
3216 #endif
3217 #ifdef EADDRINUSE
3218 case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
3219 #endif
3220 #ifdef EADDRNOTAVAIL
3221 case EADDRNOTAVAIL: return DRMP3_ERROR;
3222 #endif
3223 #ifdef ENETDOWN
3224 case ENETDOWN: return DRMP3_NO_NETWORK;
3225 #endif
3226 #ifdef ENETUNREACH
3227 case ENETUNREACH: return DRMP3_NO_NETWORK;
3228 #endif
3229 #ifdef ENETRESET
3230 case ENETRESET: return DRMP3_NO_NETWORK;
3231 #endif
3232 #ifdef ECONNABORTED
3233 case ECONNABORTED: return DRMP3_NO_NETWORK;
3234 #endif
3235 #ifdef ECONNRESET
3236 case ECONNRESET: return DRMP3_CONNECTION_RESET;
3237 #endif
3238 #ifdef ENOBUFS
3239 case ENOBUFS: return DRMP3_NO_SPACE;
3240 #endif
3241 #ifdef EISCONN
3242 case EISCONN: return DRMP3_ALREADY_CONNECTED;
3243 #endif
3244 #ifdef ENOTCONN
3245 case ENOTCONN: return DRMP3_NOT_CONNECTED;
3246 #endif
3247 #ifdef ESHUTDOWN
3248 case ESHUTDOWN: return DRMP3_ERROR;
3249 #endif
3250 #ifdef ETOOMANYREFS
3251 case ETOOMANYREFS: return DRMP3_ERROR;
3252 #endif
3253 #ifdef ETIMEDOUT
3254 case ETIMEDOUT: return DRMP3_TIMEOUT;
3255 #endif
3256 #ifdef ECONNREFUSED
3257 case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
3258 #endif
3259 #ifdef EHOSTDOWN
3260 case EHOSTDOWN: return DRMP3_NO_HOST;
3261 #endif
3262 #ifdef EHOSTUNREACH
3263 case EHOSTUNREACH: return DRMP3_NO_HOST;
3264 #endif
3265 #ifdef EALREADY
3266 case EALREADY: return DRMP3_IN_PROGRESS;
3267 #endif
3268 #ifdef EINPROGRESS
3269 case EINPROGRESS: return DRMP3_IN_PROGRESS;
3270 #endif
3271 #ifdef ESTALE
3272 case ESTALE: return DRMP3_INVALID_FILE;
3273 #endif
3274 #ifdef EUCLEAN
3275 case EUCLEAN: return DRMP3_ERROR;
3276 #endif
3277 #ifdef ENOTNAM
3278 case ENOTNAM: return DRMP3_ERROR;
3279 #endif
3280 #ifdef ENAVAIL
3281 case ENAVAIL: return DRMP3_ERROR;
3282 #endif
3283 #ifdef EISNAM
3284 case EISNAM: return DRMP3_ERROR;
3285 #endif
3286 #ifdef EREMOTEIO
3287 case EREMOTEIO: return DRMP3_IO_ERROR;
3288 #endif
3289 #ifdef EDQUOT
3290 case EDQUOT: return DRMP3_NO_SPACE;
3291 #endif
3292 #ifdef ENOMEDIUM
3293 case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
3294 #endif
3295 #ifdef EMEDIUMTYPE
3296 case EMEDIUMTYPE: return DRMP3_ERROR;
3297 #endif
3298 #ifdef ECANCELED
3299 case ECANCELED: return DRMP3_CANCELLED;
3300 #endif
3301 #ifdef ENOKEY
3302 case ENOKEY: return DRMP3_ERROR;
3303 #endif
3304 #ifdef EKEYEXPIRED
3305 case EKEYEXPIRED: return DRMP3_ERROR;
3306 #endif
3307 #ifdef EKEYREVOKED
3308 case EKEYREVOKED: return DRMP3_ERROR;
3309 #endif
3310 #ifdef EKEYREJECTED
3311 case EKEYREJECTED: return DRMP3_ERROR;
3312 #endif
3313 #ifdef EOWNERDEAD
3314 case EOWNERDEAD: return DRMP3_ERROR;
3315 #endif
3316 #ifdef ENOTRECOVERABLE
3317 case ENOTRECOVERABLE: return DRMP3_ERROR;
3318 #endif
3319 #ifdef ERFKILL
3320 case ERFKILL: return DRMP3_ERROR;
3321 #endif
3322 #ifdef EHWPOISON
3323 case EHWPOISON: return DRMP3_ERROR;
3324 #endif
3325 default: return DRMP3_ERROR;
3326 }
3327 }
3328
drmp3_fopen(FILE ** ppFile,const char * pFilePath,const char * pOpenMode)3329 static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
3330 {
3331 #if _MSC_VER && _MSC_VER >= 1400
3332 errno_t err;
3333 #endif
3334
3335 if (ppFile != NULL) {
3336 *ppFile = NULL; /* Safety. */
3337 }
3338
3339 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3340 return DRMP3_INVALID_ARGS;
3341 }
3342
3343 #if _MSC_VER && _MSC_VER >= 1400
3344 err = fopen_s(ppFile, pFilePath, pOpenMode);
3345 if (err != 0) {
3346 return drmp3_result_from_errno(err);
3347 }
3348 #else
3349 #if defined(_WIN32) || defined(__APPLE__)
3350 *ppFile = fopen(pFilePath, pOpenMode);
3351 #else
3352 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
3353 *ppFile = fopen64(pFilePath, pOpenMode);
3354 #else
3355 *ppFile = fopen(pFilePath, pOpenMode);
3356 #endif
3357 #endif
3358 if (*ppFile == NULL) {
3359 drmp3_result result = drmp3_result_from_errno(errno);
3360 if (result == DRMP3_SUCCESS) {
3361 result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
3362 }
3363
3364 return result;
3365 }
3366 #endif
3367
3368 return DRMP3_SUCCESS;
3369 }
3370
3371 /*
3372 _wfopen() isn't always available in all compilation environments.
3373
3374 * Windows only.
3375 * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
3376 * MinGW-64 (both 32- and 64-bit) seems to support it.
3377 * MinGW wraps it in !defined(__STRICT_ANSI__).
3378 * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
3379
3380 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
3381 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
3382 */
3383 #if defined(_WIN32)
3384 #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
3385 #define DRMP3_HAS_WFOPEN
3386 #endif
3387 #endif
3388
drmp3_wfopen(FILE ** ppFile,const wchar_t * pFilePath,const wchar_t * pOpenMode,const drmp3_allocation_callbacks * pAllocationCallbacks)3389 static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
3390 {
3391 if (ppFile != NULL) {
3392 *ppFile = NULL; /* Safety. */
3393 }
3394
3395 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3396 return DRMP3_INVALID_ARGS;
3397 }
3398
3399 #if defined(DRMP3_HAS_WFOPEN)
3400 {
3401 /* Use _wfopen() on Windows. */
3402 #if defined(_MSC_VER) && _MSC_VER >= 1400
3403 errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
3404 if (err != 0) {
3405 return drmp3_result_from_errno(err);
3406 }
3407 #else
3408 *ppFile = _wfopen(pFilePath, pOpenMode);
3409 if (*ppFile == NULL) {
3410 return drmp3_result_from_errno(errno);
3411 }
3412 #endif
3413 (void)pAllocationCallbacks;
3414 }
3415 #else
3416 /*
3417 Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
3418 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
3419 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.
3420 */
3421 {
3422 mbstate_t mbs;
3423 size_t lenMB;
3424 const wchar_t* pFilePathTemp = pFilePath;
3425 char* pFilePathMB = NULL;
3426 char pOpenModeMB[32] = {0};
3427
3428 /* Get the length first. */
3429 DRMP3_ZERO_OBJECT(&mbs);
3430 lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
3431 if (lenMB == (size_t)-1) {
3432 return drmp3_result_from_errno(errno);
3433 }
3434
3435 pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
3436 if (pFilePathMB == NULL) {
3437 return DRMP3_OUT_OF_MEMORY;
3438 }
3439
3440 pFilePathTemp = pFilePath;
3441 DRMP3_ZERO_OBJECT(&mbs);
3442 wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
3443
3444 /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
3445 {
3446 size_t i = 0;
3447 for (;;) {
3448 if (pOpenMode[i] == 0) {
3449 pOpenModeMB[i] = '\0';
3450 break;
3451 }
3452
3453 pOpenModeMB[i] = (char)pOpenMode[i];
3454 i += 1;
3455 }
3456 }
3457
3458 *ppFile = fopen(pFilePathMB, pOpenModeMB);
3459
3460 drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
3461 }
3462
3463 if (*ppFile == NULL) {
3464 return DRMP3_ERROR;
3465 }
3466 #endif
3467
3468 return DRMP3_SUCCESS;
3469 }
3470
3471
3472
drmp3__on_read_stdio(void * pUserData,void * pBufferOut,size_t bytesToRead)3473 static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
3474 {
3475 return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
3476 }
3477
drmp3__on_seek_stdio(void * pUserData,int offset,drmp3_seek_origin origin)3478 static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
3479 {
3480 return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
3481 }
3482
drmp3_init_file(drmp3 * pMP3,const char * pFilePath,const drmp3_allocation_callbacks * pAllocationCallbacks)3483 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3484 {
3485 drmp3_bool32 result;
3486 FILE* pFile;
3487
3488 if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
3489 return DRMP3_FALSE;
3490 }
3491
3492 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3493 if (result != DRMP3_TRUE) {
3494 fclose(pFile);
3495 return result;
3496 }
3497
3498 return DRMP3_TRUE;
3499 }
3500
drmp3_init_file_w(drmp3 * pMP3,const wchar_t * pFilePath,const drmp3_allocation_callbacks * pAllocationCallbacks)3501 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3502 {
3503 drmp3_bool32 result;
3504 FILE* pFile;
3505
3506 if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
3507 return DRMP3_FALSE;
3508 }
3509
3510 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3511 if (result != DRMP3_TRUE) {
3512 fclose(pFile);
3513 return result;
3514 }
3515
3516 return DRMP3_TRUE;
3517 }
3518 #endif
3519
drmp3_uninit(drmp3 * pMP3)3520 DRMP3_API void drmp3_uninit(drmp3* pMP3)
3521 {
3522 if (pMP3 == NULL) {
3523 return;
3524 }
3525
3526 #ifndef DR_MP3_NO_STDIO
3527 if (pMP3->onRead == drmp3__on_read_stdio) {
3528 FILE* pFile = (FILE*)pMP3->pUserData;
3529 if (pFile != NULL) {
3530 fclose(pFile);
3531 pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
3532 }
3533 }
3534 #endif
3535
3536 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
3537 }
3538
3539 #if defined(DR_MP3_FLOAT_OUTPUT)
drmp3_f32_to_s16(drmp3_int16 * dst,const float * src,drmp3_uint64 sampleCount)3540 static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
3541 {
3542 drmp3_uint64 i;
3543 drmp3_uint64 i4;
3544 drmp3_uint64 sampleCount4;
3545
3546 /* Unrolled. */
3547 i = 0;
3548 sampleCount4 = sampleCount >> 2;
3549 for (i4 = 0; i4 < sampleCount4; i4 += 1) {
3550 float x0 = src[i+0];
3551 float x1 = src[i+1];
3552 float x2 = src[i+2];
3553 float x3 = src[i+3];
3554
3555 x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0));
3556 x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1));
3557 x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2));
3558 x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3));
3559
3560 x0 = x0 * 32767.0f;
3561 x1 = x1 * 32767.0f;
3562 x2 = x2 * 32767.0f;
3563 x3 = x3 * 32767.0f;
3564
3565 dst[i+0] = (drmp3_int16)x0;
3566 dst[i+1] = (drmp3_int16)x1;
3567 dst[i+2] = (drmp3_int16)x2;
3568 dst[i+3] = (drmp3_int16)x3;
3569
3570 i += 4;
3571 }
3572
3573 /* Leftover. */
3574 for (; i < sampleCount; i += 1) {
3575 float x = src[i];
3576 x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */
3577 x = x * 32767.0f; /* -1..1 to -32767..32767 */
3578
3579 dst[i] = (drmp3_int16)x;
3580 }
3581 }
3582 #endif
3583
3584 #if !defined(DR_MP3_FLOAT_OUTPUT)
drmp3_s16_to_f32(float * dst,const drmp3_int16 * src,drmp3_uint64 sampleCount)3585 static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
3586 {
3587 drmp3_uint64 i;
3588 for (i = 0; i < sampleCount; i += 1) {
3589 float x = (float)src[i];
3590 x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */
3591 dst[i] = x;
3592 }
3593 }
3594 #endif
3595
3596
drmp3_read_pcm_frames_raw(drmp3 * pMP3,drmp3_uint64 framesToRead,void * pBufferOut)3597 static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
3598 {
3599 drmp3_uint64 totalFramesRead = 0;
3600
3601 DRMP3_ASSERT(pMP3 != NULL);
3602 DRMP3_ASSERT(pMP3->onRead != NULL);
3603
3604 while (framesToRead > 0) {
3605 drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
3606 if (pBufferOut != NULL) {
3607 #if defined(DR_MP3_FLOAT_OUTPUT)
3608 /* f32 */
3609 float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
3610 float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3611 DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
3612 #else
3613 /* s16 */
3614 drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels);
3615 drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3616 DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
3617 #endif
3618 }
3619
3620 pMP3->currentPCMFrame += framesToConsume;
3621 pMP3->pcmFramesConsumedInMP3Frame += framesToConsume;
3622 pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
3623 totalFramesRead += framesToConsume;
3624 framesToRead -= framesToConsume;
3625
3626 if (framesToRead == 0) {
3627 break;
3628 }
3629
3630 DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
3631
3632 /*
3633 At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed
3634 at this point which means we'll also need to update our sample rate conversion pipeline.
3635 */
3636 if (drmp3_decode_next_frame(pMP3) == 0) {
3637 break;
3638 }
3639 }
3640
3641 return totalFramesRead;
3642 }
3643
3644
drmp3_read_pcm_frames_f32(drmp3 * pMP3,drmp3_uint64 framesToRead,float * pBufferOut)3645 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
3646 {
3647 if (pMP3 == NULL || pMP3->onRead == NULL) {
3648 return 0;
3649 }
3650
3651 #if defined(DR_MP3_FLOAT_OUTPUT)
3652 /* Fast path. No conversion required. */
3653 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3654 #else
3655 /* Slow path. Convert from s16 to f32. */
3656 {
3657 drmp3_int16 pTempS16[8192];
3658 drmp3_uint64 totalPCMFramesRead = 0;
3659
3660 while (totalPCMFramesRead < framesToRead) {
3661 drmp3_uint64 framesJustRead;
3662 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3663 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
3664 if (framesToReadNow > framesRemaining) {
3665 framesToReadNow = framesRemaining;
3666 }
3667
3668 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
3669 if (framesJustRead == 0) {
3670 break;
3671 }
3672
3673 drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
3674 totalPCMFramesRead += framesJustRead;
3675 }
3676
3677 return totalPCMFramesRead;
3678 }
3679 #endif
3680 }
3681
drmp3_read_pcm_frames_s16(drmp3 * pMP3,drmp3_uint64 framesToRead,drmp3_int16 * pBufferOut)3682 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
3683 {
3684 if (pMP3 == NULL || pMP3->onRead == NULL) {
3685 return 0;
3686 }
3687
3688 #if !defined(DR_MP3_FLOAT_OUTPUT)
3689 /* Fast path. No conversion required. */
3690 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3691 #else
3692 /* Slow path. Convert from f32 to s16. */
3693 {
3694 float pTempF32[4096];
3695 drmp3_uint64 totalPCMFramesRead = 0;
3696
3697 while (totalPCMFramesRead < framesToRead) {
3698 drmp3_uint64 framesJustRead;
3699 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3700 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
3701 if (framesToReadNow > framesRemaining) {
3702 framesToReadNow = framesRemaining;
3703 }
3704
3705 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
3706 if (framesJustRead == 0) {
3707 break;
3708 }
3709
3710 drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
3711 totalPCMFramesRead += framesJustRead;
3712 }
3713
3714 return totalPCMFramesRead;
3715 }
3716 #endif
3717 }
3718
drmp3_reset(drmp3 * pMP3)3719 static void drmp3_reset(drmp3* pMP3)
3720 {
3721 DRMP3_ASSERT(pMP3 != NULL);
3722
3723 pMP3->pcmFramesConsumedInMP3Frame = 0;
3724 pMP3->pcmFramesRemainingInMP3Frame = 0;
3725 pMP3->currentPCMFrame = 0;
3726 pMP3->dataSize = 0;
3727 pMP3->atEnd = DRMP3_FALSE;
3728 drmp3dec_init(&pMP3->decoder);
3729 }
3730
drmp3_seek_to_start_of_stream(drmp3 * pMP3)3731 static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
3732 {
3733 DRMP3_ASSERT(pMP3 != NULL);
3734 DRMP3_ASSERT(pMP3->onSeek != NULL);
3735
3736 /* Seek to the start of the stream to begin with. */
3737 if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
3738 return DRMP3_FALSE;
3739 }
3740
3741 /* Clear any cached data. */
3742 drmp3_reset(pMP3);
3743 return DRMP3_TRUE;
3744 }
3745
3746
drmp3_seek_forward_by_pcm_frames__brute_force(drmp3 * pMP3,drmp3_uint64 frameOffset)3747 static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
3748 {
3749 drmp3_uint64 framesRead;
3750
3751 /*
3752 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
3753 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
3754 kind of manual processing.
3755 */
3756 #if defined(DR_MP3_FLOAT_OUTPUT)
3757 framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
3758 #else
3759 framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
3760 #endif
3761 if (framesRead != frameOffset) {
3762 return DRMP3_FALSE;
3763 }
3764
3765 return DRMP3_TRUE;
3766 }
3767
drmp3_seek_to_pcm_frame__brute_force(drmp3 * pMP3,drmp3_uint64 frameIndex)3768 static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
3769 {
3770 DRMP3_ASSERT(pMP3 != NULL);
3771
3772 if (frameIndex == pMP3->currentPCMFrame) {
3773 return DRMP3_TRUE;
3774 }
3775
3776 /*
3777 If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of
3778 the stream and read from the beginning.
3779 */
3780 if (frameIndex < pMP3->currentPCMFrame) {
3781 /* Moving backward. Move to the start of the stream and then move forward. */
3782 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3783 return DRMP3_FALSE;
3784 }
3785 }
3786
3787 DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
3788 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
3789 }
3790
drmp3_find_closest_seek_point(drmp3 * pMP3,drmp3_uint64 frameIndex,drmp3_uint32 * pSeekPointIndex)3791 static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
3792 {
3793 drmp3_uint32 iSeekPoint;
3794
3795 DRMP3_ASSERT(pSeekPointIndex != NULL);
3796
3797 *pSeekPointIndex = 0;
3798
3799 if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
3800 return DRMP3_FALSE;
3801 }
3802
3803 /* 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. */
3804 for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
3805 if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
3806 break; /* Found it. */
3807 }
3808
3809 *pSeekPointIndex = iSeekPoint;
3810 }
3811
3812 return DRMP3_TRUE;
3813 }
3814
drmp3_seek_to_pcm_frame__seek_table(drmp3 * pMP3,drmp3_uint64 frameIndex)3815 static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
3816 {
3817 drmp3_seek_point seekPoint;
3818 drmp3_uint32 priorSeekPointIndex;
3819 drmp3_uint16 iMP3Frame;
3820 drmp3_uint64 leftoverFrames;
3821
3822 DRMP3_ASSERT(pMP3 != NULL);
3823 DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
3824 DRMP3_ASSERT(pMP3->seekPointCount > 0);
3825
3826 /* 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. */
3827 if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
3828 seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
3829 } else {
3830 seekPoint.seekPosInBytes = 0;
3831 seekPoint.pcmFrameIndex = 0;
3832 seekPoint.mp3FramesToDiscard = 0;
3833 seekPoint.pcmFramesToDiscard = 0;
3834 }
3835
3836 /* First thing to do is seek to the first byte of the relevant MP3 frame. */
3837 if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
3838 return DRMP3_FALSE; /* Failed to seek. */
3839 }
3840
3841 /* Clear any cached data. */
3842 drmp3_reset(pMP3);
3843
3844 /* Whole MP3 frames need to be discarded first. */
3845 for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
3846 drmp3_uint32 pcmFramesRead;
3847 drmp3d_sample_t* pPCMFrames;
3848
3849 /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */
3850 pPCMFrames = NULL;
3851 if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
3852 pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
3853 }
3854
3855 /* We first need to decode the next frame. */
3856 pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
3857 if (pcmFramesRead == 0) {
3858 return DRMP3_FALSE;
3859 }
3860 }
3861
3862 /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */
3863 pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
3864
3865 /*
3866 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
3867 read-and-discard at least 2 whole MP3 frames.
3868 */
3869 leftoverFrames = frameIndex - pMP3->currentPCMFrame;
3870 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
3871 }
3872
drmp3_seek_to_pcm_frame(drmp3 * pMP3,drmp3_uint64 frameIndex)3873 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
3874 {
3875 if (pMP3 == NULL || pMP3->onSeek == NULL) {
3876 return DRMP3_FALSE;
3877 }
3878
3879 if (frameIndex == 0) {
3880 return drmp3_seek_to_start_of_stream(pMP3);
3881 }
3882
3883 /* Use the seek table if we have one. */
3884 if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
3885 return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
3886 } else {
3887 return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
3888 }
3889 }
3890
drmp3_get_mp3_and_pcm_frame_count(drmp3 * pMP3,drmp3_uint64 * pMP3FrameCount,drmp3_uint64 * pPCMFrameCount)3891 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
3892 {
3893 drmp3_uint64 currentPCMFrame;
3894 drmp3_uint64 totalPCMFrameCount;
3895 drmp3_uint64 totalMP3FrameCount;
3896
3897 if (pMP3 == NULL) {
3898 return DRMP3_FALSE;
3899 }
3900
3901 /*
3902 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
3903 on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function.
3904 */
3905
3906 /* The stream must support seeking for this to work. */
3907 if (pMP3->onSeek == NULL) {
3908 return DRMP3_FALSE;
3909 }
3910
3911 /* 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. */
3912 currentPCMFrame = pMP3->currentPCMFrame;
3913
3914 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3915 return DRMP3_FALSE;
3916 }
3917
3918 totalPCMFrameCount = 0;
3919 totalMP3FrameCount = 0;
3920
3921 for (;;) {
3922 drmp3_uint32 pcmFramesInCurrentMP3Frame;
3923
3924 pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
3925 if (pcmFramesInCurrentMP3Frame == 0) {
3926 break;
3927 }
3928
3929 totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
3930 totalMP3FrameCount += 1;
3931 }
3932
3933 /* Finally, we need to seek back to where we were. */
3934 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3935 return DRMP3_FALSE;
3936 }
3937
3938 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
3939 return DRMP3_FALSE;
3940 }
3941
3942 if (pMP3FrameCount != NULL) {
3943 *pMP3FrameCount = totalMP3FrameCount;
3944 }
3945 if (pPCMFrameCount != NULL) {
3946 *pPCMFrameCount = totalPCMFrameCount;
3947 }
3948
3949 return DRMP3_TRUE;
3950 }
3951
drmp3_get_pcm_frame_count(drmp3 * pMP3)3952 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
3953 {
3954 drmp3_uint64 totalPCMFrameCount;
3955 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
3956 return 0;
3957 }
3958
3959 return totalPCMFrameCount;
3960 }
3961
drmp3_get_mp3_frame_count(drmp3 * pMP3)3962 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
3963 {
3964 drmp3_uint64 totalMP3FrameCount;
3965 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
3966 return 0;
3967 }
3968
3969 return totalMP3FrameCount;
3970 }
3971
drmp3__accumulate_running_pcm_frame_count(drmp3 * pMP3,drmp3_uint32 pcmFrameCountIn,drmp3_uint64 * pRunningPCMFrameCount,float * pRunningPCMFrameCountFractionalPart)3972 static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
3973 {
3974 float srcRatio;
3975 float pcmFrameCountOutF;
3976 drmp3_uint32 pcmFrameCountOut;
3977
3978 srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
3979 DRMP3_ASSERT(srcRatio > 0);
3980
3981 pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
3982 pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF;
3983 *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
3984 *pRunningPCMFrameCount += pcmFrameCountOut;
3985 }
3986
3987 typedef struct
3988 {
3989 drmp3_uint64 bytePos;
3990 drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */
3991 } drmp3__seeking_mp3_frame_info;
3992
drmp3_calculate_seek_points(drmp3 * pMP3,drmp3_uint32 * pSeekPointCount,drmp3_seek_point * pSeekPoints)3993 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
3994 {
3995 drmp3_uint32 seekPointCount;
3996 drmp3_uint64 currentPCMFrame;
3997 drmp3_uint64 totalMP3FrameCount;
3998 drmp3_uint64 totalPCMFrameCount;
3999
4000 if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
4001 return DRMP3_FALSE; /* Invalid args. */
4002 }
4003
4004 seekPointCount = *pSeekPointCount;
4005 if (seekPointCount == 0) {
4006 return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */
4007 }
4008
4009 /* 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. */
4010 currentPCMFrame = pMP3->currentPCMFrame;
4011
4012 /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */
4013 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
4014 return DRMP3_FALSE;
4015 }
4016
4017 /* 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. */
4018 if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
4019 seekPointCount = 1;
4020 pSeekPoints[0].seekPosInBytes = 0;
4021 pSeekPoints[0].pcmFrameIndex = 0;
4022 pSeekPoints[0].mp3FramesToDiscard = 0;
4023 pSeekPoints[0].pcmFramesToDiscard = 0;
4024 } else {
4025 drmp3_uint64 pcmFramesBetweenSeekPoints;
4026 drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
4027 drmp3_uint64 runningPCMFrameCount = 0;
4028 float runningPCMFrameCountFractionalPart = 0;
4029 drmp3_uint64 nextTargetPCMFrame;
4030 drmp3_uint32 iMP3Frame;
4031 drmp3_uint32 iSeekPoint;
4032
4033 if (seekPointCount > totalMP3FrameCount-1) {
4034 seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
4035 }
4036
4037 pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
4038
4039 /*
4040 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
4041 MP3 frame.
4042 */
4043 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4044 return DRMP3_FALSE;
4045 }
4046
4047 /*
4048 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
4049 array. The value in the first item in this array is the byte position that will be reported in the next seek point.
4050 */
4051
4052 /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */
4053 for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
4054 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4055
4056 /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
4057 DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
4058 mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
4059 mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
4060
4061 /* We need to get information about this frame so we can know how many samples it contained. */
4062 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4063 if (pcmFramesInCurrentMP3FrameIn == 0) {
4064 return DRMP3_FALSE; /* This should never happen. */
4065 }
4066
4067 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4068 }
4069
4070 /*
4071 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
4072 calculate them.
4073 */
4074 nextTargetPCMFrame = 0;
4075 for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
4076 nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
4077
4078 for (;;) {
4079 if (nextTargetPCMFrame < runningPCMFrameCount) {
4080 /* The next seek point is in the current MP3 frame. */
4081 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4082 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4083 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4084 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4085 break;
4086 } else {
4087 size_t i;
4088 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4089
4090 /*
4091 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
4092 MP3 frame info.
4093 */
4094 for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
4095 mp3FrameInfo[i] = mp3FrameInfo[i+1];
4096 }
4097
4098 /* Cache previous MP3 frame info. */
4099 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
4100 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
4101
4102 /*
4103 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
4104 should only ever do it for the last seek point.
4105 */
4106 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4107 if (pcmFramesInCurrentMP3FrameIn == 0) {
4108 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4109 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4110 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4111 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4112 break;
4113 }
4114
4115 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4116 }
4117 }
4118 }
4119
4120 /* Finally, we need to seek back to where we were. */
4121 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4122 return DRMP3_FALSE;
4123 }
4124 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
4125 return DRMP3_FALSE;
4126 }
4127 }
4128
4129 *pSeekPointCount = seekPointCount;
4130 return DRMP3_TRUE;
4131 }
4132
drmp3_bind_seek_table(drmp3 * pMP3,drmp3_uint32 seekPointCount,drmp3_seek_point * pSeekPoints)4133 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
4134 {
4135 if (pMP3 == NULL) {
4136 return DRMP3_FALSE;
4137 }
4138
4139 if (seekPointCount == 0 || pSeekPoints == NULL) {
4140 /* Unbinding. */
4141 pMP3->seekPointCount = 0;
4142 pMP3->pSeekPoints = NULL;
4143 } else {
4144 /* Binding. */
4145 pMP3->seekPointCount = seekPointCount;
4146 pMP3->pSeekPoints = pSeekPoints;
4147 }
4148
4149 return DRMP3_TRUE;
4150 }
4151
4152
drmp3__full_read_and_close_f32(drmp3 * pMP3,drmp3_config * pConfig,drmp3_uint64 * pTotalFrameCount)4153 static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4154 {
4155 drmp3_uint64 totalFramesRead = 0;
4156 drmp3_uint64 framesCapacity = 0;
4157 float* pFrames = NULL;
4158 float temp[4096];
4159
4160 DRMP3_ASSERT(pMP3 != NULL);
4161
4162 for (;;) {
4163 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4164 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
4165 if (framesJustRead == 0) {
4166 break;
4167 }
4168
4169 /* Reallocate the output buffer if there's not enough room. */
4170 if (framesCapacity < totalFramesRead + framesJustRead) {
4171 drmp3_uint64 oldFramesBufferSize;
4172 drmp3_uint64 newFramesBufferSize;
4173 drmp3_uint64 newFramesCap;
4174 float* pNewFrames;
4175
4176 newFramesCap = framesCapacity * 2;
4177 if (newFramesCap < totalFramesRead + framesJustRead) {
4178 newFramesCap = totalFramesRead + framesJustRead;
4179 }
4180
4181 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
4182 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float);
4183 if (newFramesBufferSize > DRMP3_SIZE_MAX) {
4184 break;
4185 }
4186
4187 pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4188 if (pNewFrames == NULL) {
4189 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4190 break;
4191 }
4192
4193 pFrames = pNewFrames;
4194 framesCapacity = newFramesCap;
4195 }
4196
4197 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
4198 totalFramesRead += framesJustRead;
4199
4200 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4201 if (framesJustRead != framesToReadRightNow) {
4202 break;
4203 }
4204 }
4205
4206 if (pConfig != NULL) {
4207 pConfig->channels = pMP3->channels;
4208 pConfig->sampleRate = pMP3->sampleRate;
4209 }
4210
4211 drmp3_uninit(pMP3);
4212
4213 if (pTotalFrameCount) {
4214 *pTotalFrameCount = totalFramesRead;
4215 }
4216
4217 return pFrames;
4218 }
4219
drmp3__full_read_and_close_s16(drmp3 * pMP3,drmp3_config * pConfig,drmp3_uint64 * pTotalFrameCount)4220 static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4221 {
4222 drmp3_uint64 totalFramesRead = 0;
4223 drmp3_uint64 framesCapacity = 0;
4224 drmp3_int16* pFrames = NULL;
4225 drmp3_int16 temp[4096];
4226
4227 DRMP3_ASSERT(pMP3 != NULL);
4228
4229 for (;;) {
4230 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4231 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
4232 if (framesJustRead == 0) {
4233 break;
4234 }
4235
4236 /* Reallocate the output buffer if there's not enough room. */
4237 if (framesCapacity < totalFramesRead + framesJustRead) {
4238 drmp3_uint64 newFramesBufferSize;
4239 drmp3_uint64 oldFramesBufferSize;
4240 drmp3_uint64 newFramesCap;
4241 drmp3_int16* pNewFrames;
4242
4243 newFramesCap = framesCapacity * 2;
4244 if (newFramesCap < totalFramesRead + framesJustRead) {
4245 newFramesCap = totalFramesRead + framesJustRead;
4246 }
4247
4248 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
4249 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
4250 if (newFramesBufferSize > DRMP3_SIZE_MAX) {
4251 break;
4252 }
4253
4254 pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4255 if (pNewFrames == NULL) {
4256 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4257 break;
4258 }
4259
4260 pFrames = pNewFrames;
4261 framesCapacity = newFramesCap;
4262 }
4263
4264 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
4265 totalFramesRead += framesJustRead;
4266
4267 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4268 if (framesJustRead != framesToReadRightNow) {
4269 break;
4270 }
4271 }
4272
4273 if (pConfig != NULL) {
4274 pConfig->channels = pMP3->channels;
4275 pConfig->sampleRate = pMP3->sampleRate;
4276 }
4277
4278 drmp3_uninit(pMP3);
4279
4280 if (pTotalFrameCount) {
4281 *pTotalFrameCount = totalFramesRead;
4282 }
4283
4284 return pFrames;
4285 }
4286
4287
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)4288 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)
4289 {
4290 drmp3 mp3;
4291 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4292 return NULL;
4293 }
4294
4295 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4296 }
4297
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)4298 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)
4299 {
4300 drmp3 mp3;
4301 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4302 return NULL;
4303 }
4304
4305 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4306 }
4307
4308
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)4309 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)
4310 {
4311 drmp3 mp3;
4312 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4313 return NULL;
4314 }
4315
4316 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4317 }
4318
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)4319 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)
4320 {
4321 drmp3 mp3;
4322 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4323 return NULL;
4324 }
4325
4326 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4327 }
4328
4329
4330 #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)4331 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)
4332 {
4333 drmp3 mp3;
4334 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4335 return NULL;
4336 }
4337
4338 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4339 }
4340
drmp3_open_file_and_read_pcm_frames_s16(const char * filePath,drmp3_config * pConfig,drmp3_uint64 * pTotalFrameCount,const drmp3_allocation_callbacks * pAllocationCallbacks)4341 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)
4342 {
4343 drmp3 mp3;
4344 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4345 return NULL;
4346 }
4347
4348 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4349 }
4350 #endif
4351
drmp3_malloc(size_t sz,const drmp3_allocation_callbacks * pAllocationCallbacks)4352 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
4353 {
4354 if (pAllocationCallbacks != NULL) {
4355 return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks);
4356 } else {
4357 return drmp3__malloc_default(sz, NULL);
4358 }
4359 }
4360
drmp3_free(void * p,const drmp3_allocation_callbacks * pAllocationCallbacks)4361 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
4362 {
4363 if (pAllocationCallbacks != NULL) {
4364 drmp3__free_from_callbacks(p, pAllocationCallbacks);
4365 } else {
4366 drmp3__free_default(p, NULL);
4367 }
4368 }
4369
4370 #endif /* dr_mp3_c */
4371 #endif /*DR_MP3_IMPLEMENTATION*/
4372
4373 /*
4374 DIFFERENCES BETWEEN minimp3 AND dr_mp3
4375 ======================================
4376 - First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the
4377 code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes.
4378 - dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data
4379 to the decoder, the decoder _pulls_ data from your callbacks.
4380 - In addition to callbacks, a decoder can be initialized from a block of memory and a file.
4381 - The dr_mp3 pull API reads PCM frames rather than whole MP3 frames.
4382 - dr_mp3 adds convenience APIs for opening and decoding entire files in one go.
4383 - dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects
4384 as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when
4385 using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this.
4386 */
4387
4388 /*
4389 RELEASE NOTES - v0.5.0
4390 =======================
4391 Version 0.5.0 has breaking API changes.
4392
4393 Improved Client-Defined Memory Allocation
4394 -----------------------------------------
4395 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
4396 existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom
4397 allocation callbacks are specified.
4398
4399 To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this:
4400
4401 void* my_malloc(size_t sz, void* pUserData)
4402 {
4403 return malloc(sz);
4404 }
4405 void* my_realloc(void* p, size_t sz, void* pUserData)
4406 {
4407 return realloc(p, sz);
4408 }
4409 void my_free(void* p, void* pUserData)
4410 {
4411 free(p);
4412 }
4413
4414 ...
4415
4416 drmp3_allocation_callbacks allocationCallbacks;
4417 allocationCallbacks.pUserData = &myData;
4418 allocationCallbacks.onMalloc = my_malloc;
4419 allocationCallbacks.onRealloc = my_realloc;
4420 allocationCallbacks.onFree = my_free;
4421 drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks);
4422
4423 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
4424
4425 Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC,
4426 DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions.
4427
4428 Every API that opens a drmp3 object now takes this extra parameter. These include the following:
4429
4430 drmp3_init()
4431 drmp3_init_file()
4432 drmp3_init_memory()
4433 drmp3_open_and_read_pcm_frames_f32()
4434 drmp3_open_and_read_pcm_frames_s16()
4435 drmp3_open_memory_and_read_pcm_frames_f32()
4436 drmp3_open_memory_and_read_pcm_frames_s16()
4437 drmp3_open_file_and_read_pcm_frames_f32()
4438 drmp3_open_file_and_read_pcm_frames_s16()
4439
4440 Renamed APIs
4441 ------------
4442 The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame
4443 counts rather than sample counts.
4444
4445 drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
4446 drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
4447 drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
4448 drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
4449 drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
4450 drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
4451 */
4452
4453 /*
4454 REVISION HISTORY
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