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


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