2 MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
3 dr_mp3 - v0.6.27 - 2021-02-21
5 David Reid - mackron@gmail.com
7 GitHub: https://github.com/mackron/dr_libs
9 Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3.
13 RELEASE NOTES - VERSION 0.6
14 ===========================
15 Version 0.6 includes breaking changes with the configuration of decoders. The ability to customize the number of output channels and the sample rate has been
16 removed. You must now use the channel count and sample rate reported by the MP3 stream itself, and all channel and sample rate conversion must be done
20 Changes to Initialization
21 -------------------------
22 Previously, `drmp3_init()`, etc. took a pointer to a `drmp3_config` object that allowed you to customize the output channels and sample rate. This has been
23 removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed.
32 Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API.
38 dr_mp3 is a single file library. To use it, do something like the following in one .c file.
41 #define DR_MP3_IMPLEMENTATION
45 You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:
49 if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) {
50 // Failed to open file
55 drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames);
58 The drmp3 object is transparent so you can get access to the channel count and sample rate like so:
61 drmp3_uint32 channels = mp3.channels;
62 drmp3_uint32 sampleRate = mp3.sampleRate;
65 The example above initializes a decoder from a file, but you can also initialize it from a block of memory and read and seek callbacks with
66 `drmp3_init_memory()` and `drmp3_init()` respectively.
68 You do not need to do any annoying memory management when reading PCM frames - this is all managed internally. You can request any number of PCM frames in each
69 call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount.
71 You can also decode an entire file in one go with `drmp3_open_and_read_pcm_frames_f32()`, `drmp3_open_memory_and_read_pcm_frames_f32()` and
72 `drmp3_open_file_and_read_pcm_frames_f32()`.
77 #define these options before including this file.
79 #define DR_MP3_NO_STDIO
80 Disable drmp3_init_file(), etc.
82 #define DR_MP3_NO_SIMD
83 Disable SIMD optimizations.
93 #define DRMP3_STRINGIFY(x) #x
94 #define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x)
96 #define DRMP3_VERSION_MAJOR 0
97 #define DRMP3_VERSION_MINOR 6
98 #define DRMP3_VERSION_REVISION 27
99 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
101 #include <stddef.h> /* For size_t. */
104 typedef signed char drmp3_int8;
105 typedef unsigned char drmp3_uint8;
106 typedef signed short drmp3_int16;
107 typedef unsigned short drmp3_uint16;
108 typedef signed int drmp3_int32;
109 typedef unsigned int drmp3_uint32;
110 #if defined(_MSC_VER)
111 typedef signed __int64 drmp3_int64;
112 typedef unsigned __int64 drmp3_uint64;
114 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
115 #pragma GCC diagnostic push
116 #pragma GCC diagnostic ignored "-Wlong-long"
117 #if defined(__clang__)
118 #pragma GCC diagnostic ignored "-Wc++11-long-long"
121 typedef signed long long drmp3_int64;
122 typedef unsigned long long drmp3_uint64;
123 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
124 #pragma GCC diagnostic pop
127 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
128 typedef drmp3_uint64 drmp3_uintptr;
130 typedef drmp3_uint32 drmp3_uintptr;
132 typedef drmp3_uint8 drmp3_bool8;
133 typedef drmp3_uint32 drmp3_bool32;
135 #define DRMP3_FALSE 0
137 #if !defined(DRMP3_API)
138 #if defined(DRMP3_DLL)
140 #define DRMP3_DLL_IMPORT __declspec(dllimport)
141 #define DRMP3_DLL_EXPORT __declspec(dllexport)
142 #define DRMP3_DLL_PRIVATE static
144 #if defined(__GNUC__) && __GNUC__ >= 4
145 #define DRMP3_DLL_IMPORT __attribute__((visibility("default")))
146 #define DRMP3_DLL_EXPORT __attribute__((visibility("default")))
147 #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden")))
149 #define DRMP3_DLL_IMPORT
150 #define DRMP3_DLL_EXPORT
151 #define DRMP3_DLL_PRIVATE static
155 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
156 #define DRMP3_API DRMP3_DLL_EXPORT
158 #define DRMP3_API DRMP3_DLL_IMPORT
160 #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE
162 #define DRMP3_API extern
163 #define DRMP3_PRIVATE static
167 typedef drmp3_int32 drmp3_result;
168 #define DRMP3_SUCCESS 0
169 #define DRMP3_ERROR -1 /* A generic error. */
170 #define DRMP3_INVALID_ARGS -2
171 #define DRMP3_INVALID_OPERATION -3
172 #define DRMP3_OUT_OF_MEMORY -4
173 #define DRMP3_OUT_OF_RANGE -5
174 #define DRMP3_ACCESS_DENIED -6
175 #define DRMP3_DOES_NOT_EXIST -7
176 #define DRMP3_ALREADY_EXISTS -8
177 #define DRMP3_TOO_MANY_OPEN_FILES -9
178 #define DRMP3_INVALID_FILE -10
179 #define DRMP3_TOO_BIG -11
180 #define DRMP3_PATH_TOO_LONG -12
181 #define DRMP3_NAME_TOO_LONG -13
182 #define DRMP3_NOT_DIRECTORY -14
183 #define DRMP3_IS_DIRECTORY -15
184 #define DRMP3_DIRECTORY_NOT_EMPTY -16
185 #define DRMP3_END_OF_FILE -17
186 #define DRMP3_NO_SPACE -18
187 #define DRMP3_BUSY -19
188 #define DRMP3_IO_ERROR -20
189 #define DRMP3_INTERRUPT -21
190 #define DRMP3_UNAVAILABLE -22
191 #define DRMP3_ALREADY_IN_USE -23
192 #define DRMP3_BAD_ADDRESS -24
193 #define DRMP3_BAD_SEEK -25
194 #define DRMP3_BAD_PIPE -26
195 #define DRMP3_DEADLOCK -27
196 #define DRMP3_TOO_MANY_LINKS -28
197 #define DRMP3_NOT_IMPLEMENTED -29
198 #define DRMP3_NO_MESSAGE -30
199 #define DRMP3_BAD_MESSAGE -31
200 #define DRMP3_NO_DATA_AVAILABLE -32
201 #define DRMP3_INVALID_DATA -33
202 #define DRMP3_TIMEOUT -34
203 #define DRMP3_NO_NETWORK -35
204 #define DRMP3_NOT_UNIQUE -36
205 #define DRMP3_NOT_SOCKET -37
206 #define DRMP3_NO_ADDRESS -38
207 #define DRMP3_BAD_PROTOCOL -39
208 #define DRMP3_PROTOCOL_UNAVAILABLE -40
209 #define DRMP3_PROTOCOL_NOT_SUPPORTED -41
210 #define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42
211 #define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43
212 #define DRMP3_SOCKET_NOT_SUPPORTED -44
213 #define DRMP3_CONNECTION_RESET -45
214 #define DRMP3_ALREADY_CONNECTED -46
215 #define DRMP3_NOT_CONNECTED -47
216 #define DRMP3_CONNECTION_REFUSED -48
217 #define DRMP3_NO_HOST -49
218 #define DRMP3_IN_PROGRESS -50
219 #define DRMP3_CANCELLED -51
220 #define DRMP3_MEMORY_ALREADY_MAPPED -52
221 #define DRMP3_AT_END -53
224 #define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
225 #define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
228 #define DRMP3_INLINE __forceinline
229 #elif defined(__GNUC__)
231 I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
232 the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
233 case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
234 command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
235 I am using "__inline__" only when we're compiling in strict ANSI mode.
237 #if defined(__STRICT_ANSI__)
238 #define DRMP3_INLINE __inline__ __attribute__((always_inline))
240 #define DRMP3_INLINE inline __attribute__((always_inline))
242 #elif defined(__WATCOMC__)
243 #define DRMP3_INLINE __inline
249 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
250 DRMP3_API const char* drmp3_version_string(void);
259 int frame_bytes, channels, hz, layer, bitrate_kbps;
260 } drmp3dec_frame_info;
264 float mdct_overlap[2][9*32], qmf_state[15*2*32];
265 int reserv, free_format_bytes;
266 drmp3_uint8 header[4], reserv_buf[511];
269 /* Initializes a low level decoder. */
270 DRMP3_API void drmp3dec_init(drmp3dec *dec);
272 /* Reads a frame from a low level decoder. */
273 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
275 /* Helper for converting between f32 and s16. */
276 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
286 drmp3_seek_origin_start,
287 drmp3_seek_origin_current
292 drmp3_uint64 seekPosInBytes; /* Points to the first byte of an MP3 frame. */
293 drmp3_uint64 pcmFrameIndex; /* The index of the PCM frame this seek point targets. */
294 drmp3_uint16 mp3FramesToDiscard; /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */
295 drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */
299 Callback for when data is read. Return value is the number of bytes actually read.
301 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
302 pBufferOut [out] The output buffer.
303 bytesToRead [in] The number of bytes to read.
305 Returns the number of bytes actually read.
307 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
308 either the entire bytesToRead is filled or you have reached the end of the stream.
310 typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
313 Callback for when data needs to be seeked.
315 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
316 offset [in] The number of bytes to move, relative to the origin. Will never be negative.
317 origin [in] The origin of the seek - the current position or the start of the stream.
319 Returns whether or not the seek was successful.
321 Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which
322 will be either drmp3_seek_origin_start or drmp3_seek_origin_current.
324 typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
329 void* (* onMalloc)(size_t sz, void* pUserData);
330 void* (* onRealloc)(void* p, size_t sz, void* pUserData);
331 void (* onFree)(void* p, void* pUserData);
332 } drmp3_allocation_callbacks;
336 drmp3_uint32 channels;
337 drmp3_uint32 sampleRate;
343 drmp3dec_frame_info frameInfo;
344 drmp3_uint32 channels;
345 drmp3_uint32 sampleRate;
346 drmp3_read_proc onRead;
347 drmp3_seek_proc onSeek;
349 drmp3_allocation_callbacks allocationCallbacks;
350 drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */
351 drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */
352 drmp3_uint32 pcmFramesConsumedInMP3Frame;
353 drmp3_uint32 pcmFramesRemainingInMP3Frame;
354 drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME]; /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */
355 drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */
356 drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */
357 drmp3_seek_point* pSeekPoints; /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */
358 drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */
363 drmp3_bool32 atEnd : 1;
366 const drmp3_uint8* pData;
368 size_t currentReadPos;
369 } memory; /* Only used for decoders that were opened against a block of memory. */
373 Initializes an MP3 decoder.
375 onRead [in] The function to call when data needs to be read from the client.
376 onSeek [in] The function to call when the read position of the client data needs to move.
377 pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
379 Returns true if successful; false otherwise.
381 Close the loader with drmp3_uninit().
383 See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit()
385 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
388 Initializes an MP3 decoder from a block of memory.
390 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
391 the lifetime of the drmp3 object.
393 The buffer should contain the contents of the entire MP3 file.
395 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
397 #ifndef DR_MP3_NO_STDIO
399 Initializes an MP3 decoder from a file.
401 This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3
402 objects because the operating system may restrict the number of file handles an application can have open at
405 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
406 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
410 Uninitializes an MP3 decoder.
412 DRMP3_API void drmp3_uninit(drmp3* pMP3);
415 Reads PCM frames as interleaved 32-bit IEEE floating point PCM.
417 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
419 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
422 Reads PCM frames as interleaved signed 16-bit integer PCM.
424 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
426 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
429 Seeks to a specific frame.
431 Note that this is _not_ an MP3 frame, but rather a PCM frame.
433 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
436 Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
437 radio. Runs in linear time. Returns 0 on error.
439 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
442 Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet
443 radio. Runs in linear time. Returns 0 on error.
445 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
448 Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
449 radio. Runs in linear time. Returns 0 on error.
451 This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient.
453 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
456 Calculates the seekpoints based on PCM frames. This is slow.
458 pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count.
459 On output it contains the actual count. The reason for this design is that the client may request too many
460 seekpoints, in which case dr_mp3 will return a corrected count.
462 Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates.
464 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
467 Binds a seek table to the decoder.
469 This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this
470 remains valid while it is bound to the decoder.
472 Use drmp3_calculate_seek_points() to calculate the seek points.
474 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
478 Opens an decodes an entire MP3 stream as a single operation.
480 On output pConfig will receive the channel count and sample rate of the stream.
482 Free the returned pointer with drmp3_free().
484 DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
485 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
487 DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
488 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
490 #ifndef DR_MP3_NO_STDIO
491 DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
492 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
496 Allocates a block of memory on the heap.
498 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
501 Frees any memory that was allocated by a public drmp3 API.
503 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
508 #endif /* dr_mp3_h */
511 /************************************************************************************************************************************************************
512 ************************************************************************************************************************************************************
516 ************************************************************************************************************************************************************
517 ************************************************************************************************************************************************************/
518 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
524 #include <limits.h> /* For INT_MAX */
526 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision)
529 *pMajor = DRMP3_VERSION_MAJOR;
533 *pMinor = DRMP3_VERSION_MINOR;
537 *pRevision = DRMP3_VERSION_REVISION;
541 DRMP3_API const char* drmp3_version_string(void)
543 return DRMP3_VERSION_STRING;
546 /* Disable SIMD when compiling with TCC for now. */
547 #if defined(__TINYC__)
548 #define DR_MP3_NO_SIMD
551 #define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset)))
553 #define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */
554 #ifndef DRMP3_MAX_FRAME_SYNC_MATCHES
555 #define DRMP3_MAX_FRAME_SYNC_MATCHES 10
558 #define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */
560 #define DRMP3_MAX_BITRESERVOIR_BYTES 511
561 #define DRMP3_SHORT_BLOCK_TYPE 2
562 #define DRMP3_STOP_BLOCK_TYPE 3
563 #define DRMP3_MODE_MONO 3
564 #define DRMP3_MODE_JOINT_STEREO 1
565 #define DRMP3_HDR_SIZE 4
566 #define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
567 #define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
568 #define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
569 #define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1))
570 #define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2)
571 #define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
572 #define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
573 #define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
574 #define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
575 #define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
576 #define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
577 #define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
578 #define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
579 #define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
580 #define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
581 #define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
582 #define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
584 #define DRMP3_BITS_DEQUANTIZER_OUT -1
585 #define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210)
586 #define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3)
588 #define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
589 #define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a))
591 #if !defined(DR_MP3_NO_SIMD)
593 #if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
594 /* x64 always have SSE2, arm64 always have neon, no need for generic code */
595 #define DR_MP3_ONLY_SIMD
598 #if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
599 #if defined(_MSC_VER)
602 #include <emmintrin.h>
603 #define DRMP3_HAVE_SSE 1
604 #define DRMP3_HAVE_SIMD 1
605 #define DRMP3_VSTORE _mm_storeu_ps
606 #define DRMP3_VLD _mm_loadu_ps
607 #define DRMP3_VSET _mm_set1_ps
608 #define DRMP3_VADD _mm_add_ps
609 #define DRMP3_VSUB _mm_sub_ps
610 #define DRMP3_VMUL _mm_mul_ps
611 #define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
612 #define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
613 #define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
614 #define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
615 typedef __m128 drmp3_f4;
616 #if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)
617 #define drmp3_cpuid __cpuid
619 static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType)
622 __asm__ __volatile__(
623 #if defined(__x86_64__)
633 : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
636 __asm__ __volatile__(
638 : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
643 static int drmp3_have_simd(void)
645 #ifdef DR_MP3_ONLY_SIMD
648 static int g_have_simd;
651 static int g_counter;
652 if (g_counter++ > 100)
657 drmp3_cpuid(CPUInfo, 0);
660 drmp3_cpuid(CPUInfo, 1);
661 g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
662 return g_have_simd - 1;
666 return g_have_simd - 1;
669 #elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
670 #include <arm_neon.h>
671 #define DRMP3_HAVE_SSE 0
672 #define DRMP3_HAVE_SIMD 1
673 #define DRMP3_VSTORE vst1q_f32
674 #define DRMP3_VLD vld1q_f32
675 #define DRMP3_VSET vmovq_n_f32
676 #define DRMP3_VADD vaddq_f32
677 #define DRMP3_VSUB vsubq_f32
678 #define DRMP3_VMUL vmulq_f32
679 #define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
680 #define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
681 #define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
682 #define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
683 typedef float32x4_t drmp3_f4;
684 static int drmp3_have_simd(void)
685 { /* TODO: detect neon for !DR_MP3_ONLY_SIMD */
689 #define DRMP3_HAVE_SSE 0
690 #define DRMP3_HAVE_SIMD 0
691 #ifdef DR_MP3_ONLY_SIMD
692 #error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
698 #define DRMP3_HAVE_SIMD 0
702 #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
703 #define DRMP3_HAVE_ARMV6 1
704 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(int32_t a)
707 __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
711 #define DRMP3_HAVE_ARMV6 0
717 const drmp3_uint8 *buf;
724 drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64];
725 } drmp3_L12_scale_info;
729 drmp3_uint8 tab_offset, code_tab_width, band_count;
730 } drmp3_L12_subband_alloc;
734 const drmp3_uint8 *sfbtab;
735 drmp3_uint16 part_23_length, big_values, scalefac_compress;
736 drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
737 drmp3_uint8 table_select[3], region_count[3], subblock_gain[3];
738 drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi;
744 drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES];
745 drmp3_L3_gr_info gr_info[4];
746 float grbuf[2][576], scf[40], syn[18 + 15][2*32];
747 drmp3_uint8 ist_pos[2][39];
750 static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes)
757 static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n)
759 drmp3_uint32 next, cache = 0, s = bs->pos & 7;
761 const drmp3_uint8 *p = bs->buf + (bs->pos >> 3);
762 if ((bs->pos += n) > bs->limit)
764 next = *p++ & (255 >> s);
765 while ((shl -= 8) > 0)
767 cache |= next << shl;
770 return cache | (next >> -shl);
773 static int drmp3_hdr_valid(const drmp3_uint8 *h)
775 return h[0] == 0xff &&
776 ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
777 (DRMP3_HDR_GET_LAYER(h) != 0) &&
778 (DRMP3_HDR_GET_BITRATE(h) != 15) &&
779 (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3);
782 static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2)
784 return drmp3_hdr_valid(h2) &&
785 ((h1[1] ^ h2[1]) & 0xFE) == 0 &&
786 ((h1[2] ^ h2[2]) & 0x0C) == 0 &&
787 !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2));
790 static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h)
792 static const drmp3_uint8 halfrate[2][3][15] = {
793 { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
794 { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
796 return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
799 static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
801 static const unsigned g_hz[3] = { 44100, 48000, 32000 };
802 return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
805 static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
807 return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
810 static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
812 int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
813 if (DRMP3_HDR_IS_LAYER_1(h))
815 frame_bytes &= ~3; /* slot align */
817 return frame_bytes ? frame_bytes : free_format_size;
820 static int drmp3_hdr_padding(const drmp3_uint8 *h)
822 return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
825 #ifndef DR_MP3_ONLY_MP3
826 static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
828 const drmp3_L12_subband_alloc *alloc;
829 int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);
830 int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
832 if (DRMP3_HDR_IS_LAYER_1(hdr))
834 static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } };
837 } else if (!DRMP3_HDR_TEST_MPEG1(hdr))
839 static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } };
840 alloc = g_alloc_L2M2;
844 static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
845 int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr);
846 unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO);
847 if (!kbps) /* free-format */
852 alloc = g_alloc_L2M1;
856 static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } };
857 alloc = g_alloc_L2M1_lowrate;
858 nbands = sample_rate_idx == 2 ? 12 : 8;
859 } else if (kbps >= 96 && sample_rate_idx != 1)
865 sci->total_bands = (drmp3_uint8)nbands;
866 sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands);
871 static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf)
873 static const float g_deq_L12[18*3] = {
874 #define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
875 DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9)
878 for (i = 0; i < bands; i++)
882 int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0;
883 for (m = 4; m; m >>= 1)
887 int b = drmp3_bs_get_bits(bs, 6);
888 s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3);
895 static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci)
897 static const drmp3_uint8 g_bitalloc_code_tab[] = {
898 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16,
899 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16,
900 0,17,18, 3,19,4,5,16,
902 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15,
903 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14,
904 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16
906 const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci);
908 int i, k = 0, ba_bits = 0;
909 const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab;
911 for (i = 0; i < sci->total_bands; i++)
916 k += subband_alloc->band_count;
917 ba_bits = subband_alloc->code_tab_width;
918 ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset;
921 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
922 sci->bitalloc[2*i] = ba;
923 if (i < sci->stereo_bands)
925 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
927 sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0;
930 for (i = 0; i < 2*sci->total_bands; i++)
932 sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6);
935 drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf);
937 for (i = sci->stereo_bands; i < sci->total_bands; i++)
939 sci->bitalloc[2*i + 1] = 0;
943 static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size)
945 int i, j, k, choff = 576;
946 for (j = 0; j < 4; j++)
948 float *dst = grbuf + group_size*j;
949 for (i = 0; i < 2*sci->total_bands; i++)
951 int ba = sci->bitalloc[i];
956 int half = (1 << (ba - 1)) - 1;
957 for (k = 0; k < group_size; k++)
959 dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half);
963 unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */
964 unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */
965 for (k = 0; k < group_size; k++, code /= mod)
967 dst[k] = (float)((int)(code % mod - mod/2));
978 static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst)
981 memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
982 for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6)
984 for (k = 0; k < 12; k++)
986 dst[k + 0] *= scf[0];
987 dst[k + 576] *= scf[3];
993 static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
995 static const drmp3_uint8 g_scf_long[8][23] = {
996 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
997 { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
998 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
999 { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 },
1000 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
1001 { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 },
1002 { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
1003 { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
1005 static const drmp3_uint8 g_scf_short[8][40] = {
1006 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1007 { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1008 { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1009 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1010 { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1011 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1012 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1013 { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1015 static const drmp3_uint8 g_scf_mixed[8][40] = {
1016 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1017 { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
1018 { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
1019 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
1020 { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
1021 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
1022 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
1023 { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
1026 unsigned tables, scfsi = 0;
1027 int main_data_begin, part_23_sum = 0;
1028 int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
1029 int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
1031 if (DRMP3_HDR_TEST_MPEG1(hdr))
1034 main_data_begin = drmp3_bs_get_bits(bs, 9);
1035 scfsi = drmp3_bs_get_bits(bs, 7 + gr_count);
1038 main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count;
1043 if (DRMP3_HDR_IS_MONO(hdr))
1047 gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12);
1048 part_23_sum += gr->part_23_length;
1049 gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9);
1050 if (gr->big_values > 288)
1054 gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8);
1055 gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
1056 gr->sfbtab = g_scf_long[sr_idx];
1057 gr->n_long_sfb = 22;
1058 gr->n_short_sfb = 0;
1059 if (drmp3_bs_get_bits(bs, 1))
1061 gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2);
1062 if (!gr->block_type)
1066 gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1067 gr->region_count[0] = 7;
1068 gr->region_count[1] = 255;
1069 if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE)
1072 if (!gr->mixed_block_flag)
1074 gr->region_count[0] = 8;
1075 gr->sfbtab = g_scf_short[sr_idx];
1077 gr->n_short_sfb = 39;
1080 gr->sfbtab = g_scf_mixed[sr_idx];
1081 gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6;
1082 gr->n_short_sfb = 30;
1085 tables = drmp3_bs_get_bits(bs, 10);
1087 gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1088 gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1089 gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1093 gr->mixed_block_flag = 0;
1094 tables = drmp3_bs_get_bits(bs, 15);
1095 gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4);
1096 gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
1097 gr->region_count[2] = 255;
1099 gr->table_select[0] = (drmp3_uint8)(tables >> 10);
1100 gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31);
1101 gr->table_select[2] = (drmp3_uint8)((tables) & 31);
1102 gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
1103 gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1104 gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
1105 gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15);
1108 } while(--gr_count);
1110 if (part_23_sum + bs->pos > bs->limit + main_data_begin*8)
1115 return main_data_begin;
1118 static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi)
1121 for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2)
1123 int cnt = scf_count[i];
1126 memcpy(scf, ist_pos, cnt);
1129 int bits = scf_size[i];
1132 memset(scf, 0, cnt);
1133 memset(ist_pos, 0, cnt);
1136 int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1;
1137 for (k = 0; k < cnt; k++)
1139 int s = drmp3_bs_get_bits(bitbuf, bits);
1140 ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s);
1141 scf[k] = (drmp3_uint8)s;
1148 scf[0] = scf[1] = scf[2] = 0;
1151 static float drmp3_L3_ldexp_q2(float y, int exp_q2)
1153 static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
1157 e = DRMP3_MIN(30*4, exp_q2);
1158 y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
1159 } while ((exp_q2 -= e) > 0);
1163 static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch)
1165 static const drmp3_uint8 g_scf_partitions[3][28] = {
1166 { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 },
1167 { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 },
1168 { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 }
1170 const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
1171 drmp3_uint8 scf_size[4], iscf[40];
1172 int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi;
1175 if (DRMP3_HDR_TEST_MPEG1(hdr))
1177 static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 };
1178 int part = g_scfc_decode[gr->scalefac_compress];
1179 scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2);
1180 scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3);
1183 static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
1184 int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch;
1185 sfc = gr->scalefac_compress >> ist;
1186 for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4)
1188 for (modprod = 1, i = 3; i >= 0; i--)
1190 scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]);
1191 modprod *= g_mod[k + i];
1197 drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi);
1199 if (gr->n_short_sfb)
1201 int sh = 3 - scf_shift;
1202 for (i = 0; i < gr->n_short_sfb; i += 3)
1204 iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
1205 iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
1206 iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
1208 } else if (gr->preflag)
1210 static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
1211 for (i = 0; i < 10; i++)
1213 iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]);
1217 gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
1218 gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp);
1219 for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
1221 scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
1225 static const float g_drmp3_pow43[129 + 16] = {
1226 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
1227 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
1230 static float drmp3_L3_pow_43(int x)
1233 int sign, mult = 256;
1237 return g_drmp3_pow43[16 + x];
1247 frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
1248 return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
1251 static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
1253 static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1254 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
1255 -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
1256 -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
1257 -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
1258 -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
1259 -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
1260 -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
1261 -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
1262 -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
1263 -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
1264 -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
1265 -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
1266 -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
1267 -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
1268 -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
1269 static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
1270 static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
1271 static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
1272 static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
1274 #define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n))
1275 #define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
1276 #define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
1277 #define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
1280 int ireg = 0, big_val_cnt = gr_info->big_values;
1281 const drmp3_uint8 *sfb = gr_info->sfbtab;
1282 const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
1283 drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
1284 int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8;
1287 while (big_val_cnt > 0)
1289 int tab_num = gr_info->table_select[ireg];
1290 int sfb_cnt = gr_info->region_count[ireg++];
1291 const drmp3_int16 *codebook = tabs + tabindex[tab_num];
1292 int linbits = g_linbits[tab_num];
1298 pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1303 int leaf = codebook[DRMP3_PEEK_BITS(w)];
1306 DRMP3_FLUSH_BITS(w);
1308 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1310 DRMP3_FLUSH_BITS(leaf >> 8);
1312 for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1314 int lsb = leaf & 0x0F;
1317 lsb += DRMP3_PEEK_BITS(linbits);
1318 DRMP3_FLUSH_BITS(linbits);
1320 *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1);
1323 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1325 DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1328 } while (--pairs_to_decode);
1329 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1335 pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
1340 int leaf = codebook[DRMP3_PEEK_BITS(w)];
1343 DRMP3_FLUSH_BITS(w);
1345 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
1347 DRMP3_FLUSH_BITS(leaf >> 8);
1349 for (j = 0; j < 2; j++, dst++, leaf >>= 4)
1351 int lsb = leaf & 0x0F;
1352 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
1353 DRMP3_FLUSH_BITS(lsb ? 1 : 0);
1356 } while (--pairs_to_decode);
1357 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
1361 for (np = 1 - big_val_cnt;; dst += 4)
1363 const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
1364 int leaf = codebook_count1[DRMP3_PEEK_BITS(4)];
1367 leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))];
1369 DRMP3_FLUSH_BITS(leaf & 7);
1370 if (DRMP3_BSPOS > layer3gr_limit)
1374 #define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
1375 #define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) }
1376 DRMP3_RELOAD_SCALEFACTOR;
1377 DRMP3_DEQ_COUNT1(0);
1378 DRMP3_DEQ_COUNT1(1);
1379 DRMP3_RELOAD_SCALEFACTOR;
1380 DRMP3_DEQ_COUNT1(2);
1381 DRMP3_DEQ_COUNT1(3);
1385 bs->pos = layer3gr_limit;
1388 static void drmp3_L3_midside_stereo(float *left, int n)
1391 float *right = left + 576;
1393 if (drmp3_have_simd()) for (; i < n - 3; i += 4)
1395 drmp3_f4 vl = DRMP3_VLD(left + i);
1396 drmp3_f4 vr = DRMP3_VLD(right + i);
1397 DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr));
1398 DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr));
1410 static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr)
1413 for (i = 0; i < n; i++)
1415 left[i + 576] = left[i]*kr;
1416 left[i] = left[i]*kl;
1420 static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3])
1424 max_band[0] = max_band[1] = max_band[2] = -1;
1426 for (i = 0; i < nbands; i++)
1428 for (k = 0; k < sfb[i]; k += 2)
1430 if (right[k] != 0 || right[k + 1] != 0)
1432 max_band[i % 3] = i;
1440 static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh)
1442 static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 };
1443 unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64;
1445 for (i = 0; sfb[i]; i++)
1447 unsigned ipos = ist_pos[i];
1448 if ((int)i > max_band[i % 3] && ipos < max_pos)
1450 float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1;
1451 if (DRMP3_HDR_TEST_MPEG1(hdr))
1454 kr = g_pan[2*ipos + 1];
1458 kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
1465 drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s);
1466 } else if (DRMP3_HDR_TEST_MS_STEREO(hdr))
1468 drmp3_L3_midside_stereo(left, sfb[i]);
1474 static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
1476 int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb;
1477 int i, max_blocks = gr->n_short_sfb ? 3 : 1;
1479 drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band);
1482 max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]);
1484 for (i = 0; i < max_blocks; i++)
1486 int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0;
1487 int itop = n_sfb - max_blocks + i;
1488 int prev = itop - max_blocks;
1489 ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]);
1491 drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
1494 static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb)
1497 float *src = grbuf, *dst = scratch;
1499 for (;0 != (len = *sfb); sfb += 3, src += 2*len)
1501 for (i = 0; i < len; i++, src++)
1503 *dst++ = src[0*len];
1504 *dst++ = src[1*len];
1505 *dst++ = src[2*len];
1508 memcpy(grbuf, scratch, (dst - scratch)*sizeof(float));
1511 static void drmp3_L3_antialias(float *grbuf, int nbands)
1513 static const float g_aa[2][8] = {
1514 {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f},
1515 {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f}
1518 for (; nbands > 0; nbands--, grbuf += 18)
1522 if (drmp3_have_simd()) for (; i < 8; i += 4)
1524 drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i);
1525 drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i);
1526 drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i);
1527 drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i);
1528 vd = DRMP3_VREV(vd);
1529 DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1)));
1530 vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0));
1531 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd));
1534 #ifndef DR_MP3_ONLY_SIMD
1537 float u = grbuf[18 + i];
1538 float d = grbuf[17 - i];
1539 grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i];
1540 grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i];
1546 static void drmp3_L3_dct3_9(float *y)
1548 float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4;
1550 s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8];
1553 t4 = (s4 + s2)*0.93969262f;
1554 t2 = (s8 + s2)*0.76604444f;
1555 s6 = (s4 - s8)*0.17364818f;
1564 s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7];
1567 t0 = (s5 + s1)*0.98480775f;
1568 t4 = (s5 - s7)*0.34202014f;
1569 t2 = (s1 + s7)*0.64278761f;
1570 s1 = (s1 - s5 - s7)*0.86602540f;
1586 static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands)
1589 static const float g_twid9[18] = {
1590 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f
1593 for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9)
1598 for (i = 0; i < 4; i++)
1600 si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2];
1601 co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2];
1602 si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3];
1603 co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]);
1605 drmp3_L3_dct3_9(co);
1606 drmp3_L3_dct3_9(si);
1616 if (drmp3_have_simd()) for (; i < 8; i += 4)
1618 drmp3_f4 vovl = DRMP3_VLD(overlap + i);
1619 drmp3_f4 vc = DRMP3_VLD(co + i);
1620 drmp3_f4 vs = DRMP3_VLD(si + i);
1621 drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i);
1622 drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i);
1623 drmp3_f4 vw0 = DRMP3_VLD(window + i);
1624 drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i);
1625 drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0));
1626 DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1)));
1627 DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1)));
1628 vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0));
1629 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum));
1634 float ovl = overlap[i];
1635 float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i];
1636 overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i];
1637 grbuf[i] = ovl*window[0 + i] - sum*window[9 + i];
1638 grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i];
1643 static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst)
1645 float m1 = x1*0.86602540f;
1646 float a1 = x0 - x2*0.5f;
1652 static void drmp3_L3_imdct12(float *x, float *dst, float *overlap)
1654 static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f };
1658 drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co);
1659 drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si);
1662 for (i = 0; i < 3; i++)
1664 float ovl = overlap[i];
1665 float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i];
1666 overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i];
1667 dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i];
1668 dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i];
1672 static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands)
1674 for (;nbands > 0; nbands--, overlap += 9, grbuf += 18)
1677 memcpy(tmp, grbuf, sizeof(tmp));
1678 memcpy(grbuf, overlap, 6*sizeof(float));
1679 drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
1680 drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
1681 drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
1685 static void drmp3_L3_change_sign(float *grbuf)
1688 for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36)
1689 for (i = 1; i < 18; i += 2)
1690 grbuf[i] = -grbuf[i];
1693 static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands)
1695 static const float g_mdct_window[2][18] = {
1696 { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f },
1697 { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f }
1701 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands);
1702 grbuf += 18*n_long_bands;
1703 overlap += 9*n_long_bands;
1705 if (block_type == DRMP3_SHORT_BLOCK_TYPE)
1706 drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands);
1708 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands);
1711 static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s)
1713 int pos = (s->bs.pos + 7)/8u;
1714 int remains = s->bs.limit/8u - pos;
1715 if (remains > DRMP3_MAX_BITRESERVOIR_BYTES)
1717 pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES;
1718 remains = DRMP3_MAX_BITRESERVOIR_BYTES;
1722 memmove(h->reserv_buf, s->maindata + pos, remains);
1724 h->reserv = remains;
1727 static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
1729 int frame_bytes = (bs->limit - bs->pos)/8;
1730 int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
1731 memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
1732 memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
1733 drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
1734 return h->reserv >= main_data_begin;
1737 static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
1741 for (ch = 0; ch < nch; ch++)
1743 int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
1744 drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
1745 drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
1748 if (DRMP3_HDR_TEST_I_STEREO(h->header))
1750 drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
1751 } else if (DRMP3_HDR_IS_MS_STEREO(h->header))
1753 drmp3_L3_midside_stereo(s->grbuf[0], 576);
1756 for (ch = 0; ch < nch; ch++, gr_info++)
1759 int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2);
1761 if (gr_info->n_short_sfb)
1763 aa_bands = n_long_bands - 1;
1764 drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb);
1767 drmp3_L3_antialias(s->grbuf[ch], aa_bands);
1768 drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
1769 drmp3_L3_change_sign(s->grbuf[ch]);
1773 static void drmp3d_DCT_II(float *grbuf, int n)
1775 static const float g_sec[24] = {
1776 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f
1780 if (drmp3_have_simd()) for (; k < n; k += 4)
1782 drmp3_f4 t[4][8], *x;
1783 float *y = grbuf + k;
1785 for (x = t[0], i = 0; i < 8; i++, x++)
1787 drmp3_f4 x0 = DRMP3_VLD(&y[i*18]);
1788 drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]);
1789 drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]);
1790 drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]);
1791 drmp3_f4 t0 = DRMP3_VADD(x0, x3);
1792 drmp3_f4 t1 = DRMP3_VADD(x1, x2);
1793 drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]);
1794 drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]);
1795 x[0] = DRMP3_VADD(t0, t1);
1796 x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]);
1797 x[16] = DRMP3_VADD(t3, t2);
1798 x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]);
1800 for (x = t[0], i = 0; i < 4; i++, x += 8)
1802 drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1803 xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7);
1804 x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6);
1805 x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5);
1806 x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4);
1807 x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3);
1808 x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2);
1809 x[0] = DRMP3_VADD(x0, x1);
1810 x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f);
1811 x5 = DRMP3_VADD(x5, x6);
1812 x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f);
1813 x7 = DRMP3_VADD(x7, xt);
1814 x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f);
1815 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */
1816 x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f));
1817 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
1818 x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6);
1819 x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f);
1820 x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f);
1821 x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f);
1822 x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f);
1823 x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f);
1824 x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f);
1830 #define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v)
1832 #define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v))
1834 for (i = 0; i < 7; i++, y += 4*18)
1836 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1837 DRMP3_VSAVE2(0, t[0][i]);
1838 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s));
1839 DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1840 DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s));
1842 DRMP3_VSAVE2(0, t[0][7]);
1843 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7]));
1844 DRMP3_VSAVE2(2, t[1][7]);
1845 DRMP3_VSAVE2(3, t[3][7]);
1848 #define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v)
1849 for (i = 0; i < 7; i++, y += 4*18)
1851 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
1852 DRMP3_VSAVE4(0, t[0][i]);
1853 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s));
1854 DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
1855 DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s));
1857 DRMP3_VSAVE4(0, t[0][7]);
1858 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7]));
1859 DRMP3_VSAVE4(2, t[1][7]);
1860 DRMP3_VSAVE4(3, t[3][7]);
1864 #ifdef DR_MP3_ONLY_SIMD
1865 {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
1869 float t[4][8], *x, *y = grbuf + k;
1871 for (x = t[0], i = 0; i < 8; i++, x++)
1874 float x1 = y[(15 - i)*18];
1875 float x2 = y[(16 + i)*18];
1876 float x3 = y[(31 - i)*18];
1879 float t2 = (x1 - x2)*g_sec[3*i + 0];
1880 float t3 = (x0 - x3)*g_sec[3*i + 1];
1882 x[8] = (t0 - t1)*g_sec[3*i + 2];
1884 x[24] = (t3 - t2)*g_sec[3*i + 2];
1886 for (x = t[0], i = 0; i < 4; i++, x += 8)
1888 float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
1889 xt = x0 - x7; x0 += x7;
1890 x7 = x1 - x6; x1 += x6;
1891 x6 = x2 - x5; x2 += x5;
1892 x5 = x3 - x4; x3 += x4;
1893 x4 = x0 - x3; x0 += x3;
1894 x3 = x1 - x2; x1 += x2;
1896 x[4] = (x0 - x1)*0.70710677f;
1898 x6 = (x6 + x7)*0.70710677f;
1900 x3 = (x3 + x4)*0.70710677f;
1901 x5 -= x7*0.198912367f; /* rotate by PI/8 */
1902 x7 += x5*0.382683432f;
1903 x5 -= x7*0.198912367f;
1904 x0 = xt - x6; xt += x6;
1905 x[1] = (xt + x7)*0.50979561f;
1906 x[2] = (x4 + x3)*0.54119611f;
1907 x[3] = (x0 - x5)*0.60134488f;
1908 x[5] = (x0 + x5)*0.89997619f;
1909 x[6] = (x4 - x3)*1.30656302f;
1910 x[7] = (xt - x7)*2.56291556f;
1913 for (i = 0; i < 7; i++, y += 4*18)
1916 y[1*18] = t[2][i] + t[3][i] + t[3][i + 1];
1917 y[2*18] = t[1][i] + t[1][i + 1];
1918 y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1];
1921 y[1*18] = t[2][7] + t[3][7];
1928 #ifndef DR_MP3_FLOAT_OUTPUT
1929 typedef drmp3_int16 drmp3d_sample_t;
1931 static drmp3_int16 drmp3d_scale_pcm(float sample)
1934 #if DRMP3_HAVE_ARMV6
1935 drmp3_int32 s32 = (drmp3_int32)(sample + .5f);
1937 s = (drmp3_int16)drmp3_clip_int16_arm(s32);
1939 if (sample >= 32766.5) return (drmp3_int16) 32767;
1940 if (sample <= -32767.5) return (drmp3_int16)-32768;
1941 s = (drmp3_int16)(sample + .5f);
1942 s -= (s < 0); /* away from zero, to be compliant */
1947 typedef float drmp3d_sample_t;
1949 static float drmp3d_scale_pcm(float sample)
1951 return sample*(1.f/32768.f);
1955 static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z)
1958 a = (z[14*64] - z[ 0]) * 29;
1959 a += (z[ 1*64] + z[13*64]) * 213;
1960 a += (z[12*64] - z[ 2*64]) * 459;
1961 a += (z[ 3*64] + z[11*64]) * 2037;
1962 a += (z[10*64] - z[ 4*64]) * 5153;
1963 a += (z[ 5*64] + z[ 9*64]) * 6574;
1964 a += (z[ 8*64] - z[ 6*64]) * 37489;
1965 a += z[ 7*64] * 75038;
1966 pcm[0] = drmp3d_scale_pcm(a);
1970 a += z[12*64] * 1567;
1971 a += z[10*64] * 9727;
1972 a += z[ 8*64] * 64019;
1973 a += z[ 6*64] * -9975;
1974 a += z[ 4*64] * -45;
1975 a += z[ 2*64] * 146;
1977 pcm[16*nch] = drmp3d_scale_pcm(a);
1980 static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
1983 float *xr = xl + 576*(nch - 1);
1984 drmp3d_sample_t *dstr = dstl + (nch - 1);
1986 static const float g_win[] = {
1987 -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992,
1988 -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856,
1989 -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630,
1990 -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313,
1991 -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908,
1992 -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415,
1993 -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835,
1994 -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169,
1995 -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420,
1996 -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590,
1997 -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679,
1998 -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692,
1999 -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629,
2000 -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494,
2001 -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290
2003 float *zlin = lins + 15*64;
2004 const float *w = g_win;
2006 zlin[4*15] = xl[18*16];
2007 zlin[4*15 + 1] = xr[18*16];
2008 zlin[4*15 + 2] = xl[0];
2009 zlin[4*15 + 3] = xr[0];
2011 zlin[4*31] = xl[1 + 18*16];
2012 zlin[4*31 + 1] = xr[1 + 18*16];
2013 zlin[4*31 + 2] = xl[1];
2014 zlin[4*31 + 3] = xr[1];
2016 drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
2017 drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
2018 drmp3d_synth_pair(dstl, nch, lins + 4*15);
2019 drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
2022 if (drmp3_have_simd()) for (i = 14; i >= 0; i--)
2024 #define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
2025 #define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); }
2026 #define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); }
2027 #define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); }
2029 zlin[4*i] = xl[18*(31 - i)];
2030 zlin[4*i + 1] = xr[18*(31 - i)];
2031 zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2032 zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2033 zlin[4*i + 64] = xl[1 + 18*(1 + i)];
2034 zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)];
2035 zlin[4*i - 64 + 2] = xl[18*(1 + i)];
2036 zlin[4*i - 64 + 3] = xr[18*(1 + i)];
2038 DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7)
2041 #ifndef DR_MP3_FLOAT_OUTPUT
2043 static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
2044 static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
2045 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
2046 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
2047 dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2048 dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2049 dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2050 dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2051 dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2052 dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2053 dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2054 dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2056 int16x4_t pcma, pcmb;
2057 a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2058 b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2059 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2060 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2061 vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1);
2062 vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1);
2063 vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0);
2064 vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0);
2065 vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3);
2066 vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3);
2067 vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2);
2068 vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
2071 static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
2072 a = DRMP3_VMUL(a, g_scale);
2073 b = DRMP3_VMUL(b, g_scale);
2075 _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)));
2076 _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1)));
2077 _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)));
2078 _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0)));
2079 _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)));
2080 _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3)));
2081 _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)));
2082 _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2)));
2084 vst1q_lane_f32(dstr + (15 - i)*nch, a, 1);
2085 vst1q_lane_f32(dstr + (17 + i)*nch, b, 1);
2086 vst1q_lane_f32(dstl + (15 - i)*nch, a, 0);
2087 vst1q_lane_f32(dstl + (17 + i)*nch, b, 0);
2088 vst1q_lane_f32(dstr + (47 - i)*nch, a, 3);
2089 vst1q_lane_f32(dstr + (49 + i)*nch, b, 3);
2090 vst1q_lane_f32(dstl + (47 - i)*nch, a, 2);
2091 vst1q_lane_f32(dstl + (49 + i)*nch, b, 2);
2093 #endif /* DR_MP3_FLOAT_OUTPUT */
2097 #ifdef DR_MP3_ONLY_SIMD
2098 {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
2100 for (i = 14; i >= 0; i--)
2102 #define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
2103 #define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
2104 #define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
2105 #define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
2108 zlin[4*i] = xl[18*(31 - i)];
2109 zlin[4*i + 1] = xr[18*(31 - i)];
2110 zlin[4*i + 2] = xl[1 + 18*(31 - i)];
2111 zlin[4*i + 3] = xr[1 + 18*(31 - i)];
2112 zlin[4*(i + 16)] = xl[1 + 18*(1 + i)];
2113 zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)];
2114 zlin[4*(i - 16) + 2] = xl[18*(1 + i)];
2115 zlin[4*(i - 16) + 3] = xr[18*(1 + i)];
2117 DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7)
2119 dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]);
2120 dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]);
2121 dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]);
2122 dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]);
2123 dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]);
2124 dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]);
2125 dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]);
2126 dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]);
2131 static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins)
2134 for (i = 0; i < nch; i++)
2136 drmp3d_DCT_II(grbuf + 576*i, nbands);
2139 memcpy(lins, qmf_state, sizeof(float)*15*64);
2141 for (i = 0; i < nbands; i += 2)
2143 drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
2145 #ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL
2148 for (i = 0; i < 15*64; i += 2)
2150 qmf_state[i] = lins[nbands*64 + i];
2155 memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64);
2159 static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
2162 for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
2164 i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
2165 if (i + DRMP3_HDR_SIZE > mp3_bytes)
2167 if (!drmp3_hdr_compare(hdr, hdr + i))
2173 static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
2176 for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
2178 if (drmp3_hdr_valid(mp3))
2180 int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
2181 int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
2183 for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
2185 if (drmp3_hdr_compare(mp3, mp3 + k))
2187 int fb = k - drmp3_hdr_padding(mp3);
2188 int nextfb = fb + drmp3_hdr_padding(mp3 + k);
2189 if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
2191 frame_and_padding = k;
2193 *free_format_bytes = fb;
2197 if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
2198 drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
2199 (!i && frame_and_padding == mp3_bytes))
2201 *ptr_frame_bytes = frame_and_padding;
2204 *free_format_bytes = 0;
2207 *ptr_frame_bytes = 0;
2211 DRMP3_API void drmp3dec_init(drmp3dec *dec)
2216 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
2218 int i = 0, igr, frame_size = 0, success = 1;
2219 const drmp3_uint8 *hdr;
2220 drmp3_bs bs_frame[1];
2221 drmp3dec_scratch scratch;
2223 if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
2225 frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
2226 if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
2233 memset(dec, 0, sizeof(drmp3dec));
2234 i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
2235 if (!frame_size || i + frame_size > mp3_bytes)
2237 info->frame_bytes = i;
2243 memcpy(dec->header, hdr, DRMP3_HDR_SIZE);
2244 info->frame_bytes = i + frame_size;
2245 info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
2246 info->hz = drmp3_hdr_sample_rate_hz(hdr);
2247 info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
2248 info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
2250 drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
2251 if (DRMP3_HDR_IS_CRC(hdr))
2253 drmp3_bs_get_bits(bs_frame, 16);
2256 if (info->layer == 3)
2258 int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr);
2259 if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
2264 success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
2265 if (success && pcm != NULL)
2267 for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
2269 memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
2270 drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
2271 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
2274 drmp3_L3_save_reservoir(dec, &scratch);
2277 #ifdef DR_MP3_ONLY_MP3
2280 drmp3_L12_scale_info sci[1];
2283 return drmp3_hdr_frame_samples(hdr);
2286 drmp3_L12_read_scale_info(hdr, bs_frame, sci);
2288 memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
2289 for (i = 0, igr = 0; igr < 3; igr++)
2291 if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
2294 drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
2295 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
2296 memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
2297 pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
2299 if (bs_frame->pos > bs_frame->limit)
2308 return success*drmp3_hdr_frame_samples(dec->header);
2311 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
2315 size_t aligned_count = num_samples & ~7;
2316 for(; i < aligned_count; i+=8)
2318 drmp3_f4 scale = DRMP3_VSET(32768.0f);
2319 drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale);
2320 drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale);
2322 drmp3_f4 s16max = DRMP3_VSET( 32767.0f);
2323 drmp3_f4 s16min = DRMP3_VSET(-32768.0f);
2324 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)),
2325 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min)));
2326 out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
2327 out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
2328 out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
2329 out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
2330 out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
2331 out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
2332 out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
2333 out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
2335 int16x4_t pcma, pcmb;
2336 a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
2337 b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
2338 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
2339 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
2340 vst1_lane_s16(out+i , pcma, 0);
2341 vst1_lane_s16(out+i+1, pcma, 1);
2342 vst1_lane_s16(out+i+2, pcma, 2);
2343 vst1_lane_s16(out+i+3, pcma, 3);
2344 vst1_lane_s16(out+i+4, pcmb, 0);
2345 vst1_lane_s16(out+i+5, pcmb, 1);
2346 vst1_lane_s16(out+i+6, pcmb, 2);
2347 vst1_lane_s16(out+i+7, pcmb, 3);
2351 for(; i < num_samples; i++)
2353 float sample = in[i] * 32768.0f;
2354 if (sample >= 32766.5)
2355 out[i] = (drmp3_int16) 32767;
2356 else if (sample <= -32767.5)
2357 out[i] = (drmp3_int16)-32768;
2360 short s = (drmp3_int16)(sample + .5f);
2361 s -= (s < 0); /* away from zero, to be compliant */
2369 /************************************************************************************************************************************************************
2373 ************************************************************************************************************************************************************/
2374 #include <math.h> /* For sin() and exp(). */
2376 #if defined(SIZE_MAX)
2377 #define DRMP3_SIZE_MAX SIZE_MAX
2379 #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
2380 #define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF)
2382 #define DRMP3_SIZE_MAX 0xFFFFFFFF
2387 #ifndef DRMP3_SEEK_LEADING_MP3_FRAMES
2388 #define DRMP3_SEEK_LEADING_MP3_FRAMES 2
2391 #define DRMP3_MIN_DATA_CHUNK_SIZE 16384
2393 /* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */
2394 #ifndef DRMP3_DATA_CHUNK_SIZE
2395 #define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4
2399 /* Standard library stuff. */
2400 #ifndef DRMP3_ASSERT
2402 #define DRMP3_ASSERT(expression) assert(expression)
2404 #ifndef DRMP3_COPY_MEMORY
2405 #define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
2407 #ifndef DRMP3_ZERO_MEMORY
2408 #define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
2410 #define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p)))
2411 #ifndef DRMP3_MALLOC
2412 #define DRMP3_MALLOC(sz) malloc((sz))
2414 #ifndef DRMP3_REALLOC
2415 #define DRMP3_REALLOC(p, sz) realloc((p), (sz))
2418 #define DRMP3_FREE(p) free((p))
2421 #define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
2422 #define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi)))
2425 #define DRMP3_PI_D 3.14159265358979323846264
2428 #define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2
2430 static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a)
2432 return x*(1-a) + y*a;
2434 static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a)
2439 /*return x + (y - x)*a;*/
2444 Greatest common factor using Euclid's algorithm iteratively.
2446 static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b)
2462 static DRMP3_INLINE double drmp3_sin(double x)
2464 /* TODO: Implement custom sin(x). */
2468 static DRMP3_INLINE double drmp3_exp(double x)
2470 /* TODO: Implement custom exp(x). */
2474 static DRMP3_INLINE double drmp3_cos(double x)
2476 return drmp3_sin((DRMP3_PI_D*0.5) - x);
2480 static void* drmp3__malloc_default(size_t sz, void* pUserData)
2483 return DRMP3_MALLOC(sz);
2486 static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData)
2489 return DRMP3_REALLOC(p, sz);
2492 static void drmp3__free_default(void* p, void* pUserData)
2499 static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
2501 if (pAllocationCallbacks == NULL) {
2505 if (pAllocationCallbacks->onMalloc != NULL) {
2506 return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
2509 /* Try using realloc(). */
2510 if (pAllocationCallbacks->onRealloc != NULL) {
2511 return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
2517 static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
2519 if (pAllocationCallbacks == NULL) {
2523 if (pAllocationCallbacks->onRealloc != NULL) {
2524 return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
2527 /* Try emulating realloc() in terms of malloc()/free(). */
2528 if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
2531 p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
2537 DRMP3_COPY_MEMORY(p2, p, szOld);
2538 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2547 static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
2549 if (p == NULL || pAllocationCallbacks == NULL) {
2553 if (pAllocationCallbacks->onFree != NULL) {
2554 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
2559 static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
2561 if (pAllocationCallbacks != NULL) {
2563 return *pAllocationCallbacks;
2566 drmp3_allocation_callbacks allocationCallbacks;
2567 allocationCallbacks.pUserData = NULL;
2568 allocationCallbacks.onMalloc = drmp3__malloc_default;
2569 allocationCallbacks.onRealloc = drmp3__realloc_default;
2570 allocationCallbacks.onFree = drmp3__free_default;
2571 return allocationCallbacks;
2577 static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
2579 size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
2580 pMP3->streamCursor += bytesRead;
2584 static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
2586 DRMP3_ASSERT(offset >= 0);
2588 if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
2592 if (origin == drmp3_seek_origin_start) {
2593 pMP3->streamCursor = (drmp3_uint64)offset;
2595 pMP3->streamCursor += offset;
2601 static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin)
2603 if (offset <= 0x7FFFFFFF) {
2604 return drmp3__on_seek(pMP3, (int)offset, origin);
2608 /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */
2609 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) {
2613 offset -= 0x7FFFFFFF;
2614 while (offset > 0) {
2615 if (offset <= 0x7FFFFFFF) {
2616 if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) {
2621 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
2624 offset -= 0x7FFFFFFF;
2632 static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2634 drmp3_uint32 pcmFramesRead = 0;
2636 DRMP3_ASSERT(pMP3 != NULL);
2637 DRMP3_ASSERT(pMP3->onRead != NULL);
2644 drmp3dec_frame_info info;
2646 /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */
2647 if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
2650 /* First we need to move the data down. */
2651 if (pMP3->pData != NULL) {
2652 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2655 pMP3->dataConsumed = 0;
2657 if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
2658 drmp3_uint8* pNewData;
2661 newDataCap = DRMP3_DATA_CHUNK_SIZE;
2663 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2664 if (pNewData == NULL) {
2665 return 0; /* Out of memory. */
2668 pMP3->pData = pNewData;
2669 pMP3->dataCapacity = newDataCap;
2672 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2673 if (bytesRead == 0) {
2674 if (pMP3->dataSize == 0) {
2675 pMP3->atEnd = DRMP3_TRUE;
2676 return 0; /* No data. */
2680 pMP3->dataSize += bytesRead;
2683 if (pMP3->dataSize > INT_MAX) {
2684 pMP3->atEnd = DRMP3_TRUE;
2685 return 0; /* File too big. */
2688 DRMP3_ASSERT(pMP3->pData != NULL);
2689 DRMP3_ASSERT(pMP3->dataCapacity > 0);
2691 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */
2693 /* Consume the data. */
2694 if (info.frame_bytes > 0) {
2695 pMP3->dataConsumed += (size_t)info.frame_bytes;
2696 pMP3->dataSize -= (size_t)info.frame_bytes;
2699 /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */
2700 if (pcmFramesRead > 0) {
2701 pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
2702 pMP3->pcmFramesConsumedInMP3Frame = 0;
2703 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2704 pMP3->mp3FrameChannels = info.channels;
2705 pMP3->mp3FrameSampleRate = info.hz;
2707 } else if (info.frame_bytes == 0) {
2708 /* Need more data. minimp3 recommends doing data submission in 16K chunks. */
2711 /* First we need to move the data down. */
2712 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
2713 pMP3->dataConsumed = 0;
2715 if (pMP3->dataCapacity == pMP3->dataSize) {
2716 /* No room. Expand. */
2717 drmp3_uint8* pNewData;
2720 newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
2722 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
2723 if (pNewData == NULL) {
2724 return 0; /* Out of memory. */
2727 pMP3->pData = pNewData;
2728 pMP3->dataCapacity = newDataCap;
2731 /* Fill in a chunk. */
2732 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
2733 if (bytesRead == 0) {
2734 pMP3->atEnd = DRMP3_TRUE;
2735 return 0; /* Error reading more data. */
2738 pMP3->dataSize += bytesRead;
2742 return pcmFramesRead;
2745 static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2747 drmp3_uint32 pcmFramesRead = 0;
2748 drmp3dec_frame_info info;
2750 DRMP3_ASSERT(pMP3 != NULL);
2751 DRMP3_ASSERT(pMP3->memory.pData != NULL);
2757 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
2758 if (pcmFramesRead > 0) {
2759 pMP3->pcmFramesConsumedInMP3Frame = 0;
2760 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
2761 pMP3->mp3FrameChannels = info.channels;
2762 pMP3->mp3FrameSampleRate = info.hz;
2765 /* Consume the data. */
2766 pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
2768 return pcmFramesRead;
2771 static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
2773 if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
2774 return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
2776 return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
2780 static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
2782 DRMP3_ASSERT(pMP3 != NULL);
2783 return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
2787 static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
2789 drmp3_uint32 pcmFrameCount;
2791 DRMP3_ASSERT(pMP3 != NULL);
2793 pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
2794 if (pcmFrameCount == 0) {
2798 /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */
2799 pMP3->currentPCMFrame += pcmFrameCount;
2800 pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount;
2801 pMP3->pcmFramesRemainingInMP3Frame = 0;
2803 return pcmFrameCount;
2807 static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2809 DRMP3_ASSERT(pMP3 != NULL);
2810 DRMP3_ASSERT(onRead != NULL);
2812 /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
2813 drmp3dec_init(&pMP3->decoder);
2815 pMP3->onRead = onRead;
2816 pMP3->onSeek = onSeek;
2817 pMP3->pUserData = pUserData;
2818 pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
2820 if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
2821 return DRMP3_FALSE; /* Invalid allocation callbacks. */
2824 /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */
2825 if (!drmp3_decode_next_frame(pMP3)) {
2826 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
2827 return DRMP3_FALSE; /* Not a valid MP3 stream. */
2830 pMP3->channels = pMP3->mp3FrameChannels;
2831 pMP3->sampleRate = pMP3->mp3FrameSampleRate;
2836 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
2838 if (pMP3 == NULL || onRead == NULL) {
2842 DRMP3_ZERO_OBJECT(pMP3);
2843 return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks);
2847 static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
2849 drmp3* pMP3 = (drmp3*)pUserData;
2850 size_t bytesRemaining;
2852 DRMP3_ASSERT(pMP3 != NULL);
2853 DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
2855 bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
2856 if (bytesToRead > bytesRemaining) {
2857 bytesToRead = bytesRemaining;
2860 if (bytesToRead > 0) {
2861 DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
2862 pMP3->memory.currentReadPos += bytesToRead;
2868 static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
2870 drmp3* pMP3 = (drmp3*)pUserData;
2872 DRMP3_ASSERT(pMP3 != NULL);
2874 if (origin == drmp3_seek_origin_current) {
2875 if (byteOffset > 0) {
2876 if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
2877 byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */
2880 if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
2881 byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */
2885 /* This will never underflow thanks to the clamps above. */
2886 pMP3->memory.currentReadPos += byteOffset;
2888 if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) {
2889 pMP3->memory.currentReadPos = byteOffset;
2891 pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */
2898 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
2904 DRMP3_ZERO_OBJECT(pMP3);
2906 if (pData == NULL || dataSize == 0) {
2910 pMP3->memory.pData = (const drmp3_uint8*)pData;
2911 pMP3->memory.dataSize = dataSize;
2912 pMP3->memory.currentReadPos = 0;
2914 return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks);
2918 #ifndef DR_MP3_NO_STDIO
2920 #include <wchar.h> /* For wcslen(), wcsrtombs() */
2922 /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
2924 static drmp3_result drmp3_result_from_errno(int e)
2928 case 0: return DRMP3_SUCCESS;
2930 case EPERM: return DRMP3_INVALID_OPERATION;
2933 case ENOENT: return DRMP3_DOES_NOT_EXIST;
2936 case ESRCH: return DRMP3_DOES_NOT_EXIST;
2939 case EINTR: return DRMP3_INTERRUPT;
2942 case EIO: return DRMP3_IO_ERROR;
2945 case ENXIO: return DRMP3_DOES_NOT_EXIST;
2948 case E2BIG: return DRMP3_INVALID_ARGS;
2951 case ENOEXEC: return DRMP3_INVALID_FILE;
2954 case EBADF: return DRMP3_INVALID_FILE;
2957 case ECHILD: return DRMP3_ERROR;
2960 case EAGAIN: return DRMP3_UNAVAILABLE;
2963 case ENOMEM: return DRMP3_OUT_OF_MEMORY;
2966 case EACCES: return DRMP3_ACCESS_DENIED;
2969 case EFAULT: return DRMP3_BAD_ADDRESS;
2972 case ENOTBLK: return DRMP3_ERROR;
2975 case EBUSY: return DRMP3_BUSY;
2978 case EEXIST: return DRMP3_ALREADY_EXISTS;
2981 case EXDEV: return DRMP3_ERROR;
2984 case ENODEV: return DRMP3_DOES_NOT_EXIST;
2987 case ENOTDIR: return DRMP3_NOT_DIRECTORY;
2990 case EISDIR: return DRMP3_IS_DIRECTORY;
2993 case EINVAL: return DRMP3_INVALID_ARGS;
2996 case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
2999 case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
3002 case ENOTTY: return DRMP3_INVALID_OPERATION;
3005 case ETXTBSY: return DRMP3_BUSY;
3008 case EFBIG: return DRMP3_TOO_BIG;
3011 case ENOSPC: return DRMP3_NO_SPACE;
3014 case ESPIPE: return DRMP3_BAD_SEEK;
3017 case EROFS: return DRMP3_ACCESS_DENIED;
3020 case EMLINK: return DRMP3_TOO_MANY_LINKS;
3023 case EPIPE: return DRMP3_BAD_PIPE;
3026 case EDOM: return DRMP3_OUT_OF_RANGE;
3029 case ERANGE: return DRMP3_OUT_OF_RANGE;
3032 case EDEADLK: return DRMP3_DEADLOCK;
3035 case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
3038 case ENOLCK: return DRMP3_ERROR;
3041 case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
3044 case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
3047 case ELOOP: return DRMP3_TOO_MANY_LINKS;
3050 case ENOMSG: return DRMP3_NO_MESSAGE;
3053 case EIDRM: return DRMP3_ERROR;
3056 case ECHRNG: return DRMP3_ERROR;
3059 case EL2NSYNC: return DRMP3_ERROR;
3062 case EL3HLT: return DRMP3_ERROR;
3065 case EL3RST: return DRMP3_ERROR;
3068 case ELNRNG: return DRMP3_OUT_OF_RANGE;
3071 case EUNATCH: return DRMP3_ERROR;
3074 case ENOCSI: return DRMP3_ERROR;
3077 case EL2HLT: return DRMP3_ERROR;
3080 case EBADE: return DRMP3_ERROR;
3083 case EBADR: return DRMP3_ERROR;
3086 case EXFULL: return DRMP3_ERROR;
3089 case ENOANO: return DRMP3_ERROR;
3092 case EBADRQC: return DRMP3_ERROR;
3095 case EBADSLT: return DRMP3_ERROR;
3098 case EBFONT: return DRMP3_INVALID_FILE;
3101 case ENOSTR: return DRMP3_ERROR;
3104 case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
3107 case ETIME: return DRMP3_TIMEOUT;
3110 case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
3113 case ENONET: return DRMP3_NO_NETWORK;
3116 case ENOPKG: return DRMP3_ERROR;
3119 case EREMOTE: return DRMP3_ERROR;
3122 case ENOLINK: return DRMP3_ERROR;
3125 case EADV: return DRMP3_ERROR;
3128 case ESRMNT: return DRMP3_ERROR;
3131 case ECOMM: return DRMP3_ERROR;
3134 case EPROTO: return DRMP3_ERROR;
3137 case EMULTIHOP: return DRMP3_ERROR;
3140 case EDOTDOT: return DRMP3_ERROR;
3143 case EBADMSG: return DRMP3_BAD_MESSAGE;
3146 case EOVERFLOW: return DRMP3_TOO_BIG;
3149 case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
3152 case EBADFD: return DRMP3_ERROR;
3155 case EREMCHG: return DRMP3_ERROR;
3158 case ELIBACC: return DRMP3_ACCESS_DENIED;
3161 case ELIBBAD: return DRMP3_INVALID_FILE;
3164 case ELIBSCN: return DRMP3_INVALID_FILE;
3167 case ELIBMAX: return DRMP3_ERROR;
3170 case ELIBEXEC: return DRMP3_ERROR;
3173 case EILSEQ: return DRMP3_INVALID_DATA;
3176 case ERESTART: return DRMP3_ERROR;
3179 case ESTRPIPE: return DRMP3_ERROR;
3182 case EUSERS: return DRMP3_ERROR;
3185 case ENOTSOCK: return DRMP3_NOT_SOCKET;
3188 case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
3191 case EMSGSIZE: return DRMP3_TOO_BIG;
3194 case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
3197 case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
3199 #ifdef EPROTONOSUPPORT
3200 case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
3202 #ifdef ESOCKTNOSUPPORT
3203 case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
3206 case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
3209 case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
3212 case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
3215 case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
3217 #ifdef EADDRNOTAVAIL
3218 case EADDRNOTAVAIL: return DRMP3_ERROR;
3221 case ENETDOWN: return DRMP3_NO_NETWORK;
3224 case ENETUNREACH: return DRMP3_NO_NETWORK;
3227 case ENETRESET: return DRMP3_NO_NETWORK;
3230 case ECONNABORTED: return DRMP3_NO_NETWORK;
3233 case ECONNRESET: return DRMP3_CONNECTION_RESET;
3236 case ENOBUFS: return DRMP3_NO_SPACE;
3239 case EISCONN: return DRMP3_ALREADY_CONNECTED;
3242 case ENOTCONN: return DRMP3_NOT_CONNECTED;
3245 case ESHUTDOWN: return DRMP3_ERROR;
3248 case ETOOMANYREFS: return DRMP3_ERROR;
3251 case ETIMEDOUT: return DRMP3_TIMEOUT;
3254 case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
3257 case EHOSTDOWN: return DRMP3_NO_HOST;
3260 case EHOSTUNREACH: return DRMP3_NO_HOST;
3263 case EALREADY: return DRMP3_IN_PROGRESS;
3266 case EINPROGRESS: return DRMP3_IN_PROGRESS;
3269 case ESTALE: return DRMP3_INVALID_FILE;
3272 case EUCLEAN: return DRMP3_ERROR;
3275 case ENOTNAM: return DRMP3_ERROR;
3278 case ENAVAIL: return DRMP3_ERROR;
3281 case EISNAM: return DRMP3_ERROR;
3284 case EREMOTEIO: return DRMP3_IO_ERROR;
3287 case EDQUOT: return DRMP3_NO_SPACE;
3290 case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
3293 case EMEDIUMTYPE: return DRMP3_ERROR;
3296 case ECANCELED: return DRMP3_CANCELLED;
3299 case ENOKEY: return DRMP3_ERROR;
3302 case EKEYEXPIRED: return DRMP3_ERROR;
3305 case EKEYREVOKED: return DRMP3_ERROR;
3308 case EKEYREJECTED: return DRMP3_ERROR;
3311 case EOWNERDEAD: return DRMP3_ERROR;
3313 #ifdef ENOTRECOVERABLE
3314 case ENOTRECOVERABLE: return DRMP3_ERROR;
3317 case ERFKILL: return DRMP3_ERROR;
3320 case EHWPOISON: return DRMP3_ERROR;
3322 default: return DRMP3_ERROR;
3326 static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
3328 #if defined(_MSC_VER) && _MSC_VER >= 1400
3332 if (ppFile != NULL) {
3333 *ppFile = NULL; /* Safety. */
3336 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3337 return DRMP3_INVALID_ARGS;
3340 #if defined(_MSC_VER) && _MSC_VER >= 1400
3341 err = fopen_s(ppFile, pFilePath, pOpenMode);
3343 return drmp3_result_from_errno(err);
3346 #if defined(_WIN32) || defined(__APPLE__)
3347 *ppFile = fopen(pFilePath, pOpenMode);
3349 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
3350 *ppFile = fopen64(pFilePath, pOpenMode);
3352 *ppFile = fopen(pFilePath, pOpenMode);
3355 if (*ppFile == NULL) {
3356 drmp3_result result = drmp3_result_from_errno(errno);
3357 if (result == DRMP3_SUCCESS) {
3358 result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
3365 return DRMP3_SUCCESS;
3369 _wfopen() isn't always available in all compilation environments.
3372 * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
3373 * MinGW-64 (both 32- and 64-bit) seems to support it.
3374 * MinGW wraps it in !defined(__STRICT_ANSI__).
3375 * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
3377 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
3378 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
3381 #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
3382 #define DRMP3_HAS_WFOPEN
3386 static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
3388 if (ppFile != NULL) {
3389 *ppFile = NULL; /* Safety. */
3392 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
3393 return DRMP3_INVALID_ARGS;
3396 #if defined(DRMP3_HAS_WFOPEN)
3398 /* Use _wfopen() on Windows. */
3399 #if defined(_MSC_VER) && _MSC_VER >= 1400
3400 errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
3402 return drmp3_result_from_errno(err);
3405 *ppFile = _wfopen(pFilePath, pOpenMode);
3406 if (*ppFile == NULL) {
3407 return drmp3_result_from_errno(errno);
3410 (void)pAllocationCallbacks;
3414 Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
3415 think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
3416 maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
3421 const wchar_t* pFilePathTemp = pFilePath;
3422 char* pFilePathMB = NULL;
3423 char pOpenModeMB[32] = {0};
3425 /* Get the length first. */
3426 DRMP3_ZERO_OBJECT(&mbs);
3427 lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
3428 if (lenMB == (size_t)-1) {
3429 return drmp3_result_from_errno(errno);
3432 pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
3433 if (pFilePathMB == NULL) {
3434 return DRMP3_OUT_OF_MEMORY;
3437 pFilePathTemp = pFilePath;
3438 DRMP3_ZERO_OBJECT(&mbs);
3439 wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
3441 /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
3445 if (pOpenMode[i] == 0) {
3446 pOpenModeMB[i] = '\0';
3450 pOpenModeMB[i] = (char)pOpenMode[i];
3455 *ppFile = fopen(pFilePathMB, pOpenModeMB);
3457 drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
3460 if (*ppFile == NULL) {
3465 return DRMP3_SUCCESS;
3470 static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
3472 return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
3475 static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
3477 return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
3480 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3482 drmp3_bool32 result;
3485 if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
3489 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3490 if (result != DRMP3_TRUE) {
3498 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
3500 drmp3_bool32 result;
3503 if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
3507 result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
3508 if (result != DRMP3_TRUE) {
3517 DRMP3_API void drmp3_uninit(drmp3* pMP3)
3523 #ifndef DR_MP3_NO_STDIO
3524 if (pMP3->onRead == drmp3__on_read_stdio) {
3525 FILE* pFile = (FILE*)pMP3->pUserData;
3526 if (pFile != NULL) {
3528 pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
3533 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
3536 #if defined(DR_MP3_FLOAT_OUTPUT)
3537 static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
3541 drmp3_uint64 sampleCount4;
3545 sampleCount4 = sampleCount >> 2;
3546 for (i4 = 0; i4 < sampleCount4; i4 += 1) {
3547 float x0 = src[i+0];
3548 float x1 = src[i+1];
3549 float x2 = src[i+2];
3550 float x3 = src[i+3];
3552 x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0));
3553 x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1));
3554 x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2));
3555 x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3));
3562 dst[i+0] = (drmp3_int16)x0;
3563 dst[i+1] = (drmp3_int16)x1;
3564 dst[i+2] = (drmp3_int16)x2;
3565 dst[i+3] = (drmp3_int16)x3;
3571 for (; i < sampleCount; i += 1) {
3573 x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */
3574 x = x * 32767.0f; /* -1..1 to -32767..32767 */
3576 dst[i] = (drmp3_int16)x;
3581 #if !defined(DR_MP3_FLOAT_OUTPUT)
3582 static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
3585 for (i = 0; i < sampleCount; i += 1) {
3586 float x = (float)src[i];
3587 x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */
3594 static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
3596 drmp3_uint64 totalFramesRead = 0;
3598 DRMP3_ASSERT(pMP3 != NULL);
3599 DRMP3_ASSERT(pMP3->onRead != NULL);
3601 while (framesToRead > 0) {
3602 drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
3603 if (pBufferOut != NULL) {
3604 #if defined(DR_MP3_FLOAT_OUTPUT)
3606 float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
3607 float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3608 DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
3611 drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels);
3612 drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
3613 DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
3617 pMP3->currentPCMFrame += framesToConsume;
3618 pMP3->pcmFramesConsumedInMP3Frame += framesToConsume;
3619 pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
3620 totalFramesRead += framesToConsume;
3621 framesToRead -= framesToConsume;
3623 if (framesToRead == 0) {
3627 DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
3630 At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed
3631 at this point which means we'll also need to update our sample rate conversion pipeline.
3633 if (drmp3_decode_next_frame(pMP3) == 0) {
3638 return totalFramesRead;
3642 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
3644 if (pMP3 == NULL || pMP3->onRead == NULL) {
3648 #if defined(DR_MP3_FLOAT_OUTPUT)
3649 /* Fast path. No conversion required. */
3650 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3652 /* Slow path. Convert from s16 to f32. */
3654 drmp3_int16 pTempS16[8192];
3655 drmp3_uint64 totalPCMFramesRead = 0;
3657 while (totalPCMFramesRead < framesToRead) {
3658 drmp3_uint64 framesJustRead;
3659 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3660 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
3661 if (framesToReadNow > framesRemaining) {
3662 framesToReadNow = framesRemaining;
3665 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
3666 if (framesJustRead == 0) {
3670 drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
3671 totalPCMFramesRead += framesJustRead;
3674 return totalPCMFramesRead;
3679 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
3681 if (pMP3 == NULL || pMP3->onRead == NULL) {
3685 #if !defined(DR_MP3_FLOAT_OUTPUT)
3686 /* Fast path. No conversion required. */
3687 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
3689 /* Slow path. Convert from f32 to s16. */
3691 float pTempF32[4096];
3692 drmp3_uint64 totalPCMFramesRead = 0;
3694 while (totalPCMFramesRead < framesToRead) {
3695 drmp3_uint64 framesJustRead;
3696 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
3697 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
3698 if (framesToReadNow > framesRemaining) {
3699 framesToReadNow = framesRemaining;
3702 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
3703 if (framesJustRead == 0) {
3707 drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
3708 totalPCMFramesRead += framesJustRead;
3711 return totalPCMFramesRead;
3716 static void drmp3_reset(drmp3* pMP3)
3718 DRMP3_ASSERT(pMP3 != NULL);
3720 pMP3->pcmFramesConsumedInMP3Frame = 0;
3721 pMP3->pcmFramesRemainingInMP3Frame = 0;
3722 pMP3->currentPCMFrame = 0;
3724 pMP3->atEnd = DRMP3_FALSE;
3725 drmp3dec_init(&pMP3->decoder);
3728 static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
3730 DRMP3_ASSERT(pMP3 != NULL);
3731 DRMP3_ASSERT(pMP3->onSeek != NULL);
3733 /* Seek to the start of the stream to begin with. */
3734 if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
3738 /* Clear any cached data. */
3744 static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
3746 drmp3_uint64 framesRead;
3749 Just using a dumb read-and-discard for now. What would be nice is to parse only the header of the MP3 frame, and then skip over leading
3750 frames without spending the time doing a full decode. I cannot see an easy way to do this in minimp3, however, so it may involve some
3751 kind of manual processing.
3753 #if defined(DR_MP3_FLOAT_OUTPUT)
3754 framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
3756 framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
3758 if (framesRead != frameOffset) {
3765 static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
3767 DRMP3_ASSERT(pMP3 != NULL);
3769 if (frameIndex == pMP3->currentPCMFrame) {
3774 If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of
3775 the stream and read from the beginning.
3777 if (frameIndex < pMP3->currentPCMFrame) {
3778 /* Moving backward. Move to the start of the stream and then move forward. */
3779 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3784 DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
3785 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
3788 static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
3790 drmp3_uint32 iSeekPoint;
3792 DRMP3_ASSERT(pSeekPointIndex != NULL);
3794 *pSeekPointIndex = 0;
3796 if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
3800 /* Linear search for simplicity to begin with while I'm getting this thing working. Once it's all working change this to a binary search. */
3801 for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
3802 if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
3803 break; /* Found it. */
3806 *pSeekPointIndex = iSeekPoint;
3812 static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
3814 drmp3_seek_point seekPoint;
3815 drmp3_uint32 priorSeekPointIndex;
3816 drmp3_uint16 iMP3Frame;
3817 drmp3_uint64 leftoverFrames;
3819 DRMP3_ASSERT(pMP3 != NULL);
3820 DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
3821 DRMP3_ASSERT(pMP3->seekPointCount > 0);
3823 /* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */
3824 if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
3825 seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
3827 seekPoint.seekPosInBytes = 0;
3828 seekPoint.pcmFrameIndex = 0;
3829 seekPoint.mp3FramesToDiscard = 0;
3830 seekPoint.pcmFramesToDiscard = 0;
3833 /* First thing to do is seek to the first byte of the relevant MP3 frame. */
3834 if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
3835 return DRMP3_FALSE; /* Failed to seek. */
3838 /* Clear any cached data. */
3841 /* Whole MP3 frames need to be discarded first. */
3842 for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
3843 drmp3_uint32 pcmFramesRead;
3844 drmp3d_sample_t* pPCMFrames;
3846 /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */
3848 if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
3849 pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
3852 /* We first need to decode the next frame. */
3853 pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
3854 if (pcmFramesRead == 0) {
3859 /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */
3860 pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
3863 Now at this point we can follow the same process as the brute force technique where we just skip over unnecessary MP3 frames and then
3864 read-and-discard at least 2 whole MP3 frames.
3866 leftoverFrames = frameIndex - pMP3->currentPCMFrame;
3867 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
3870 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
3872 if (pMP3 == NULL || pMP3->onSeek == NULL) {
3876 if (frameIndex == 0) {
3877 return drmp3_seek_to_start_of_stream(pMP3);
3880 /* Use the seek table if we have one. */
3881 if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
3882 return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
3884 return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
3888 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
3890 drmp3_uint64 currentPCMFrame;
3891 drmp3_uint64 totalPCMFrameCount;
3892 drmp3_uint64 totalMP3FrameCount;
3899 The way this works is we move back to the start of the stream, iterate over each MP3 frame and calculate the frame count based
3900 on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function.
3903 /* The stream must support seeking for this to work. */
3904 if (pMP3->onSeek == NULL) {
3908 /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */
3909 currentPCMFrame = pMP3->currentPCMFrame;
3911 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3915 totalPCMFrameCount = 0;
3916 totalMP3FrameCount = 0;
3919 drmp3_uint32 pcmFramesInCurrentMP3Frame;
3921 pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
3922 if (pcmFramesInCurrentMP3Frame == 0) {
3926 totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
3927 totalMP3FrameCount += 1;
3930 /* Finally, we need to seek back to where we were. */
3931 if (!drmp3_seek_to_start_of_stream(pMP3)) {
3935 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
3939 if (pMP3FrameCount != NULL) {
3940 *pMP3FrameCount = totalMP3FrameCount;
3942 if (pPCMFrameCount != NULL) {
3943 *pPCMFrameCount = totalPCMFrameCount;
3949 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
3951 drmp3_uint64 totalPCMFrameCount;
3952 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
3956 return totalPCMFrameCount;
3959 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
3961 drmp3_uint64 totalMP3FrameCount;
3962 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
3966 return totalMP3FrameCount;
3969 static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
3972 float pcmFrameCountOutF;
3973 drmp3_uint32 pcmFrameCountOut;
3975 srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
3976 DRMP3_ASSERT(srcRatio > 0);
3978 pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
3979 pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF;
3980 *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
3981 *pRunningPCMFrameCount += pcmFrameCountOut;
3986 drmp3_uint64 bytePos;
3987 drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */
3988 } drmp3__seeking_mp3_frame_info;
3990 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
3992 drmp3_uint32 seekPointCount;
3993 drmp3_uint64 currentPCMFrame;
3994 drmp3_uint64 totalMP3FrameCount;
3995 drmp3_uint64 totalPCMFrameCount;
3997 if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
3998 return DRMP3_FALSE; /* Invalid args. */
4001 seekPointCount = *pSeekPointCount;
4002 if (seekPointCount == 0) {
4003 return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */
4006 /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */
4007 currentPCMFrame = pMP3->currentPCMFrame;
4009 /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */
4010 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
4014 /* If there's less than DRMP3_SEEK_LEADING_MP3_FRAMES+1 frames we just report 1 seek point which will be the very start of the stream. */
4015 if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
4017 pSeekPoints[0].seekPosInBytes = 0;
4018 pSeekPoints[0].pcmFrameIndex = 0;
4019 pSeekPoints[0].mp3FramesToDiscard = 0;
4020 pSeekPoints[0].pcmFramesToDiscard = 0;
4022 drmp3_uint64 pcmFramesBetweenSeekPoints;
4023 drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
4024 drmp3_uint64 runningPCMFrameCount = 0;
4025 float runningPCMFrameCountFractionalPart = 0;
4026 drmp3_uint64 nextTargetPCMFrame;
4027 drmp3_uint32 iMP3Frame;
4028 drmp3_uint32 iSeekPoint;
4030 if (seekPointCount > totalMP3FrameCount-1) {
4031 seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
4034 pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
4037 Here is where we actually calculate the seek points. We need to start by moving the start of the stream. We then enumerate over each
4040 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4045 We need to cache the byte positions of the previous MP3 frames. As a new MP3 frame is iterated, we cycle the byte positions in this
4046 array. The value in the first item in this array is the byte position that will be reported in the next seek point.
4049 /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */
4050 for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
4051 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4053 /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
4054 DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
4055 mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
4056 mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
4058 /* We need to get information about this frame so we can know how many samples it contained. */
4059 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4060 if (pcmFramesInCurrentMP3FrameIn == 0) {
4061 return DRMP3_FALSE; /* This should never happen. */
4064 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4068 At this point we will have extracted the byte positions of the leading MP3 frames. We can now start iterating over each seek point and
4071 nextTargetPCMFrame = 0;
4072 for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
4073 nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
4076 if (nextTargetPCMFrame < runningPCMFrameCount) {
4077 /* The next seek point is in the current MP3 frame. */
4078 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4079 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4080 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4081 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4085 drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
4088 The next seek point is not in the current MP3 frame, so continue on to the next one. The first thing to do is cycle the cached
4091 for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
4092 mp3FrameInfo[i] = mp3FrameInfo[i+1];
4095 /* Cache previous MP3 frame info. */
4096 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
4097 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
4100 Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it
4101 should only ever do it for the last seek point.
4103 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
4104 if (pcmFramesInCurrentMP3FrameIn == 0) {
4105 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
4106 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
4107 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
4108 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
4112 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
4117 /* Finally, we need to seek back to where we were. */
4118 if (!drmp3_seek_to_start_of_stream(pMP3)) {
4121 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
4126 *pSeekPointCount = seekPointCount;
4130 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
4136 if (seekPointCount == 0 || pSeekPoints == NULL) {
4138 pMP3->seekPointCount = 0;
4139 pMP3->pSeekPoints = NULL;
4142 pMP3->seekPointCount = seekPointCount;
4143 pMP3->pSeekPoints = pSeekPoints;
4150 static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4152 drmp3_uint64 totalFramesRead = 0;
4153 drmp3_uint64 framesCapacity = 0;
4154 float* pFrames = NULL;
4157 DRMP3_ASSERT(pMP3 != NULL);
4160 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4161 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
4162 if (framesJustRead == 0) {
4166 /* Reallocate the output buffer if there's not enough room. */
4167 if (framesCapacity < totalFramesRead + framesJustRead) {
4168 drmp3_uint64 oldFramesBufferSize;
4169 drmp3_uint64 newFramesBufferSize;
4170 drmp3_uint64 newFramesCap;
4173 newFramesCap = framesCapacity * 2;
4174 if (newFramesCap < totalFramesRead + framesJustRead) {
4175 newFramesCap = totalFramesRead + framesJustRead;
4178 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
4179 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float);
4180 if (newFramesBufferSize > DRMP3_SIZE_MAX) {
4184 pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4185 if (pNewFrames == NULL) {
4186 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4190 pFrames = pNewFrames;
4191 framesCapacity = newFramesCap;
4194 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
4195 totalFramesRead += framesJustRead;
4197 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4198 if (framesJustRead != framesToReadRightNow) {
4203 if (pConfig != NULL) {
4204 pConfig->channels = pMP3->channels;
4205 pConfig->sampleRate = pMP3->sampleRate;
4210 if (pTotalFrameCount) {
4211 *pTotalFrameCount = totalFramesRead;
4217 static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
4219 drmp3_uint64 totalFramesRead = 0;
4220 drmp3_uint64 framesCapacity = 0;
4221 drmp3_int16* pFrames = NULL;
4222 drmp3_int16 temp[4096];
4224 DRMP3_ASSERT(pMP3 != NULL);
4227 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
4228 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
4229 if (framesJustRead == 0) {
4233 /* Reallocate the output buffer if there's not enough room. */
4234 if (framesCapacity < totalFramesRead + framesJustRead) {
4235 drmp3_uint64 newFramesBufferSize;
4236 drmp3_uint64 oldFramesBufferSize;
4237 drmp3_uint64 newFramesCap;
4238 drmp3_int16* pNewFrames;
4240 newFramesCap = framesCapacity * 2;
4241 if (newFramesCap < totalFramesRead + framesJustRead) {
4242 newFramesCap = totalFramesRead + framesJustRead;
4245 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
4246 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
4247 if (newFramesBufferSize > DRMP3_SIZE_MAX) {
4251 pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
4252 if (pNewFrames == NULL) {
4253 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
4257 pFrames = pNewFrames;
4258 framesCapacity = newFramesCap;
4261 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
4262 totalFramesRead += framesJustRead;
4264 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
4265 if (framesJustRead != framesToReadRightNow) {
4270 if (pConfig != NULL) {
4271 pConfig->channels = pMP3->channels;
4272 pConfig->sampleRate = pMP3->sampleRate;
4277 if (pTotalFrameCount) {
4278 *pTotalFrameCount = totalFramesRead;
4285 DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4288 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4292 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4295 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4298 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
4302 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4306 DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4309 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4313 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4316 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4319 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
4323 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4327 #ifndef DR_MP3_NO_STDIO
4328 DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4331 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4335 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
4338 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
4341 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
4345 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
4349 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
4351 if (pAllocationCallbacks != NULL) {
4352 return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks);
4354 return drmp3__malloc_default(sz, NULL);
4358 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
4360 if (pAllocationCallbacks != NULL) {
4361 drmp3__free_from_callbacks(p, pAllocationCallbacks);
4363 drmp3__free_default(p, NULL);
4367 #endif /* dr_mp3_c */
4368 #endif /*DR_MP3_IMPLEMENTATION*/
4371 DIFFERENCES BETWEEN minimp3 AND dr_mp3
4372 ======================================
4373 - First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the
4374 code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes.
4375 - dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data
4376 to the decoder, the decoder _pulls_ data from your callbacks.
4377 - In addition to callbacks, a decoder can be initialized from a block of memory and a file.
4378 - The dr_mp3 pull API reads PCM frames rather than whole MP3 frames.
4379 - dr_mp3 adds convenience APIs for opening and decoding entire files in one go.
4380 - dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects
4381 as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when
4382 using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this.
4386 RELEASE NOTES - v0.5.0
4387 =======================
4388 Version 0.5.0 has breaking API changes.
4390 Improved Client-Defined Memory Allocation
4391 -----------------------------------------
4392 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
4393 existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom
4394 allocation callbacks are specified.
4396 To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this:
4398 void* my_malloc(size_t sz, void* pUserData)
4402 void* my_realloc(void* p, size_t sz, void* pUserData)
4404 return realloc(p, sz);
4406 void my_free(void* p, void* pUserData)
4413 drmp3_allocation_callbacks allocationCallbacks;
4414 allocationCallbacks.pUserData = &myData;
4415 allocationCallbacks.onMalloc = my_malloc;
4416 allocationCallbacks.onRealloc = my_realloc;
4417 allocationCallbacks.onFree = my_free;
4418 drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks);
4420 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
4422 Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC,
4423 DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions.
4425 Every API that opens a drmp3 object now takes this extra parameter. These include the following:
4430 drmp3_open_and_read_pcm_frames_f32()
4431 drmp3_open_and_read_pcm_frames_s16()
4432 drmp3_open_memory_and_read_pcm_frames_f32()
4433 drmp3_open_memory_and_read_pcm_frames_s16()
4434 drmp3_open_file_and_read_pcm_frames_f32()
4435 drmp3_open_file_and_read_pcm_frames_s16()
4439 The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame
4440 counts rather than sample counts.
4442 drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
4443 drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
4444 drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
4445 drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
4446 drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
4447 drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
4453 v0.6.27 - 2021-02-21
4454 - Fix a warning due to referencing _MSC_VER when it is undefined.
4456 v0.6.26 - 2021-01-31
4457 - Bring up to date with minimp3.
4459 v0.6.25 - 2020-12-26
4460 - Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs.
4462 v0.6.24 - 2020-12-07
4463 - Fix a typo in version date for 0.6.23.
4465 v0.6.23 - 2020-12-03
4466 - Fix an error where a file can be closed twice when initialization of the decoder fails.
4468 v0.6.22 - 2020-12-02
4469 - Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails.
4471 v0.6.21 - 2020-11-28
4472 - Bring up to date with minimp3.
4474 v0.6.20 - 2020-11-21
4475 - Fix compilation with OpenWatcom.
4477 v0.6.19 - 2020-11-13
4478 - Minor code clean up.
4480 v0.6.18 - 2020-11-01
4481 - Improve compiler support for older versions of GCC.
4483 v0.6.17 - 2020-09-28
4484 - Bring up to date with minimp3.
4486 v0.6.16 - 2020-08-02
4487 - Simplify sized types.
4489 v0.6.15 - 2020-07-25
4490 - Fix a compilation warning.
4492 v0.6.14 - 2020-07-23
4493 - Fix undefined behaviour with memmove().
4495 v0.6.13 - 2020-07-06
4496 - Fix a bug when converting from s16 to f32 in drmp3_read_pcm_frames_f32().
4498 v0.6.12 - 2020-06-23
4499 - Add include guard for the implementation section.
4501 v0.6.11 - 2020-05-26
4502 - Fix use of uninitialized variable error.
4504 v0.6.10 - 2020-05-16
4505 - Add compile-time and run-time version querying.
4506 - DRMP3_VERSION_MINOR
4507 - DRMP3_VERSION_MAJOR
4508 - DRMP3_VERSION_REVISION
4509 - DRMP3_VERSION_STRING
4511 - drmp3_version_string()
4514 - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs.
4517 - Optimizations to decoding when initializing from memory.
4520 - Fix a compilation error with DR_MP3_NO_STDIO
4521 - Optimization to decoding by reducing some data movement.
4524 - Fix a minor bug with the running PCM frame counter.
4527 - Fix compilation error on ARM builds.
4530 - Bring up to date with changes to minimp3.
4533 - Fix some pedantic warnings.
4536 - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL.
4542 - API CHANGE: Remove the pConfig parameter from the following APIs:
4544 - drmp3_init_memory()
4546 - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path.
4549 - Bring up to date with minimp3.
4552 - Fix a memory allocation bug in high level s16 decoding APIs.
4555 - Fix a possible null pointer dereference when using custom memory allocators for realloc().
4558 - Fix typos in documentation.
4561 - Bring up to date with minimp3.
4564 - Fix a warning with GCC.
4567 - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
4568 routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
4571 - drmp3_init_memory()
4572 - drmp3_open_and_read_pcm_frames_f32()
4573 - drmp3_open_and_read_pcm_frames_s16()
4574 - drmp3_open_memory_and_read_pcm_frames_f32()
4575 - drmp3_open_memory_and_read_pcm_frames_s16()
4576 - drmp3_open_file_and_read_pcm_frames_f32()
4577 - drmp3_open_file_and_read_pcm_frames_s16()
4578 - API CHANGE: Renamed the following APIs:
4579 - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
4580 - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
4581 - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
4582 - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
4583 - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
4584 - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
4587 - Fix a compiler error.
4590 - Fix a compiler error.
4593 - Bring up to date with minimp3.
4596 - Fixes to the VC6 build.
4599 - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and
4600 DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to
4601 DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE.
4602 - Add s16 reading APIs
4603 - drmp3_read_pcm_frames_s16
4604 - drmp3_open_memory_and_read_pcm_frames_s16
4605 - drmp3_open_and_read_pcm_frames_s16
4606 - drmp3_open_file_and_read_pcm_frames_s16
4607 - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section.
4608 - Add support for C89.
4609 - Change license to choice of public domain or MIT-0.
4618 - API CHANGE: Rename some APIs:
4619 - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32
4620 - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame
4621 - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32
4622 - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32
4623 - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32
4624 - Add drmp3_get_pcm_frame_count().
4625 - Add drmp3_get_mp3_frame_count().
4626 - Improve seeking performance.
4629 - Fix a couple of memory leaks.
4630 - Bring up to date with minimp3.
4636 - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has
4637 been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or
4638 not the DR_MP3_FLOAT_OUTPUT option is set.
4640 v0.2.11 - 2018-08-08
4641 - Fix a bug where the last part of a file is not read.
4643 v0.2.10 - 2018-08-07
4644 - Improve 64-bit detection.
4647 - Fix C++ build on older versions of GCC.
4648 - Bring up to date with minimp3.
4651 - Fix compilation errors with older versions of GCC.
4654 - Bring up to date with minimp3.
4657 - Bring up to date with minimp3.
4660 - Bring up to date with minimp3.
4663 - Bring up to date with minimp3.
4669 - Fix bug when opening a decoder from memory.
4672 - Efficiency improvements when the decoder reaches the end of the stream.
4675 - Bring up to date with minimp3.
4676 - Start using major.minor.revision versioning.
4679 - Bring up to date with minimp3.
4682 - Fix C++ build error.
4685 - Bring up to date with minimp3.
4688 - Fix compilation error on GCC/Clang.
4689 - Fix some warnings.
4692 - Initial versioned release.
4696 This software is available as a choice of the following licenses. Choose
4697 whichever you prefer.
4699 ===============================================================================
4700 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
4701 ===============================================================================
4702 This is free and unencumbered software released into the public domain.
4704 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
4705 software, either in source code form or as a compiled binary, for any purpose,
4706 commercial or non-commercial, and by any means.
4708 In jurisdictions that recognize copyright laws, the author or authors of this
4709 software dedicate any and all copyright interest in the software to the public
4710 domain. We make this dedication for the benefit of the public at large and to
4711 the detriment of our heirs and successors. We intend this dedication to be an
4712 overt act of relinquishment in perpetuity of all present and future rights to
4713 this software under copyright law.
4715 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4716 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4717 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4718 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
4719 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4720 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4722 For more information, please refer to <http://unlicense.org/>
4724 ===============================================================================
4725 ALTERNATIVE 2 - MIT No Attribution
4726 ===============================================================================
4727 Copyright 2020 David Reid
4729 Permission is hereby granted, free of charge, to any person obtaining a copy of
4730 this software and associated documentation files (the "Software"), to deal in
4731 the Software without restriction, including without limitation the rights to
4732 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
4733 of the Software, and to permit persons to whom the Software is furnished to do
4736 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4737 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4738 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4739 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4740 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4741 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4746 https://github.com/lieff/minimp3
4747 To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
4748 This software is distributed without any warranty.
4749 See <http://creativecommons.org/publicdomain/zero/1.0/>.