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


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