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


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:54