DOSBox-X
|
00001 /* 00002 MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. 00003 dr_mp3 - v0.6.11 - 2020-05-26 00004 00005 David Reid - mackron@gmail.com 00006 00007 GitHub: https://github.com/mackron/dr_libs 00008 00009 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. 00010 */ 00011 00012 /* 00013 RELEASE NOTES - VERSION 0.6 00014 =========================== 00015 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 00016 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 00017 yourself. 00018 00019 00020 Changes to Initialization 00021 ------------------------- 00022 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 00023 removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed. 00024 00025 `drmp3_init()` 00026 `drmp3_init_memory()` 00027 `drmp3_init_file()` 00028 00029 00030 Miscellaneous Changes 00031 --------------------- 00032 Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API. 00033 */ 00034 00035 /* 00036 Introducation 00037 ============= 00038 dr_mp3 is a single file library. To use it, do something like the following in one .c file. 00039 00040 ```c 00041 #define DR_MP3_IMPLEMENTATION 00042 #include "dr_mp3.h" 00043 ``` 00044 00045 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: 00046 00047 ```c 00048 drmp3 mp3; 00049 if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) { 00050 // Failed to open file 00051 } 00052 00053 ... 00054 00055 drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames); 00056 ``` 00057 00058 The drmp3 object is transparent so you can get access to the channel count and sample rate like so: 00059 00060 ``` 00061 drmp3_uint32 channels = mp3.channels; 00062 drmp3_uint32 sampleRate = mp3.sampleRate; 00063 ``` 00064 00065 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 00066 `drmp3_init_memory()` and `drmp3_init()` respectively. 00067 00068 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 00069 call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount. 00070 00071 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 00072 `drmp3_open_file_and_read_pcm_frames_f32()`. 00073 00074 00075 Build Options 00076 ============= 00077 #define these options before including this file. 00078 00079 #define DR_MP3_NO_STDIO 00080 Disable drmp3_init_file(), etc. 00081 00082 #define DR_MP3_NO_SIMD 00083 Disable SIMD optimizations. 00084 */ 00085 00086 #ifndef dr_mp3_h 00087 #define dr_mp3_h 00088 00089 #ifdef __cplusplus 00090 extern "C" { 00091 #endif 00092 00093 #define DRMP3_STRINGIFY(x) #x 00094 #define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x) 00095 00096 #define DRMP3_VERSION_MAJOR 0 00097 #define DRMP3_VERSION_MINOR 6 00098 #define DRMP3_VERSION_REVISION 11 00099 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) 00100 00101 #include <stddef.h> /* For size_t. */ 00102 00103 /* Sized types. Prefer built-in types. Fall back to stdint. */ 00104 #ifdef _MSC_VER 00105 #if defined(__clang__) 00106 #pragma GCC diagnostic push 00107 #pragma GCC diagnostic ignored "-Wlanguage-extension-token" 00108 #pragma GCC diagnostic ignored "-Wlong-long" 00109 #pragma GCC diagnostic ignored "-Wc++11-long-long" 00110 #endif 00111 typedef signed __int8 drmp3_int8; 00112 typedef unsigned __int8 drmp3_uint8; 00113 typedef signed __int16 drmp3_int16; 00114 typedef unsigned __int16 drmp3_uint16; 00115 typedef signed __int32 drmp3_int32; 00116 typedef unsigned __int32 drmp3_uint32; 00117 typedef signed __int64 drmp3_int64; 00118 typedef unsigned __int64 drmp3_uint64; 00119 #if defined(__clang__) 00120 #pragma GCC diagnostic pop 00121 #endif 00122 #else 00123 #include <stdint.h> 00124 typedef int8_t drmp3_int8; 00125 typedef uint8_t drmp3_uint8; 00126 typedef int16_t drmp3_int16; 00127 typedef uint16_t drmp3_uint16; 00128 typedef int32_t drmp3_int32; 00129 typedef uint32_t drmp3_uint32; 00130 typedef int64_t drmp3_int64; 00131 typedef uint64_t drmp3_uint64; 00132 #endif 00133 typedef drmp3_uint8 drmp3_bool8; 00134 typedef drmp3_uint32 drmp3_bool32; 00135 #define DRMP3_TRUE 1 00136 #define DRMP3_FALSE 0 00137 00138 #if !defined(DRMP3_API) 00139 #if defined(DRMP3_DLL) 00140 #if defined(_WIN32) 00141 #define DRMP3_DLL_IMPORT __declspec(dllimport) 00142 #define DRMP3_DLL_EXPORT __declspec(dllexport) 00143 #define DRMP3_DLL_PRIVATE static 00144 #else 00145 #if defined(__GNUC__) && __GNUC__ >= 4 00146 #define DRMP3_DLL_IMPORT __attribute__((visibility("default"))) 00147 #define DRMP3_DLL_EXPORT __attribute__((visibility("default"))) 00148 #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden"))) 00149 #else 00150 #define DRMP3_DLL_IMPORT 00151 #define DRMP3_DLL_EXPORT 00152 #define DRMP3_DLL_PRIVATE static 00153 #endif 00154 #endif 00155 00156 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) 00157 #define DRMP3_API DRMP3_DLL_EXPORT 00158 #else 00159 #define DRMP3_API DRMP3_DLL_IMPORT 00160 #endif 00161 #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE 00162 #else 00163 #define DRMP3_API extern 00164 #define DRMP3_PRIVATE static 00165 #endif 00166 #endif 00167 00168 typedef drmp3_int32 drmp3_result; 00169 #define DRMP3_SUCCESS 0 00170 #define DRMP3_ERROR -1 /* A generic error. */ 00171 #define DRMP3_INVALID_ARGS -2 00172 #define DRMP3_INVALID_OPERATION -3 00173 #define DRMP3_OUT_OF_MEMORY -4 00174 #define DRMP3_OUT_OF_RANGE -5 00175 #define DRMP3_ACCESS_DENIED -6 00176 #define DRMP3_DOES_NOT_EXIST -7 00177 #define DRMP3_ALREADY_EXISTS -8 00178 #define DRMP3_TOO_MANY_OPEN_FILES -9 00179 #define DRMP3_INVALID_FILE -10 00180 #define DRMP3_TOO_BIG -11 00181 #define DRMP3_PATH_TOO_LONG -12 00182 #define DRMP3_NAME_TOO_LONG -13 00183 #define DRMP3_NOT_DIRECTORY -14 00184 #define DRMP3_IS_DIRECTORY -15 00185 #define DRMP3_DIRECTORY_NOT_EMPTY -16 00186 #define DRMP3_END_OF_FILE -17 00187 #define DRMP3_NO_SPACE -18 00188 #define DRMP3_BUSY -19 00189 #define DRMP3_IO_ERROR -20 00190 #define DRMP3_INTERRUPT -21 00191 #define DRMP3_UNAVAILABLE -22 00192 #define DRMP3_ALREADY_IN_USE -23 00193 #define DRMP3_BAD_ADDRESS -24 00194 #define DRMP3_BAD_SEEK -25 00195 #define DRMP3_BAD_PIPE -26 00196 #define DRMP3_DEADLOCK -27 00197 #define DRMP3_TOO_MANY_LINKS -28 00198 #define DRMP3_NOT_IMPLEMENTED -29 00199 #define DRMP3_NO_MESSAGE -30 00200 #define DRMP3_BAD_MESSAGE -31 00201 #define DRMP3_NO_DATA_AVAILABLE -32 00202 #define DRMP3_INVALID_DATA -33 00203 #define DRMP3_TIMEOUT -34 00204 #define DRMP3_NO_NETWORK -35 00205 #define DRMP3_NOT_UNIQUE -36 00206 #define DRMP3_NOT_SOCKET -37 00207 #define DRMP3_NO_ADDRESS -38 00208 #define DRMP3_BAD_PROTOCOL -39 00209 #define DRMP3_PROTOCOL_UNAVAILABLE -40 00210 #define DRMP3_PROTOCOL_NOT_SUPPORTED -41 00211 #define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42 00212 #define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43 00213 #define DRMP3_SOCKET_NOT_SUPPORTED -44 00214 #define DRMP3_CONNECTION_RESET -45 00215 #define DRMP3_ALREADY_CONNECTED -46 00216 #define DRMP3_NOT_CONNECTED -47 00217 #define DRMP3_CONNECTION_REFUSED -48 00218 #define DRMP3_NO_HOST -49 00219 #define DRMP3_IN_PROGRESS -50 00220 #define DRMP3_CANCELLED -51 00221 #define DRMP3_MEMORY_ALREADY_MAPPED -52 00222 #define DRMP3_AT_END -53 00223 00224 00225 #define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 00226 #define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) 00227 00228 #ifdef _MSC_VER 00229 #define DRMP3_INLINE __forceinline 00230 #elif defined(__GNUC__) 00231 /* 00232 I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when 00233 the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some 00234 case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the 00235 command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue 00236 I am using "__inline__" only when we're compiling in strict ANSI mode. 00237 */ 00238 #if defined(__STRICT_ANSI__) 00239 #define DRMP3_INLINE __inline__ __attribute__((always_inline)) 00240 #else 00241 #define DRMP3_INLINE inline __attribute__((always_inline)) 00242 #endif 00243 #else 00244 #define DRMP3_INLINE 00245 #endif 00246 00247 00248 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision); 00249 DRMP3_API const char* drmp3_version_string(); 00250 00251 00252 /* 00253 Low Level Push API 00254 ================== 00255 */ 00256 typedef struct 00257 { 00258 int frame_bytes, channels, hz, layer, bitrate_kbps; 00259 } drmp3dec_frame_info; 00260 00261 typedef struct 00262 { 00263 float mdct_overlap[2][9*32], qmf_state[15*2*32]; 00264 int reserv, free_format_bytes; 00265 drmp3_uint8 header[4], reserv_buf[511]; 00266 } drmp3dec; 00267 00268 /* Initializes a low level decoder. */ 00269 DRMP3_API void drmp3dec_init(drmp3dec *dec); 00270 00271 /* Reads a frame from a low level decoder. */ 00272 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info); 00273 00274 /* Helper for converting between f32 and s16. */ 00275 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples); 00276 00277 00278 00279 /* 00280 Main API (Pull API) 00281 =================== 00282 */ 00283 #ifndef DRMP3_DEFAULT_CHANNELS 00284 #define DRMP3_DEFAULT_CHANNELS 2 00285 #endif 00286 #ifndef DRMP3_DEFAULT_SAMPLE_RATE 00287 #define DRMP3_DEFAULT_SAMPLE_RATE 44100 00288 #endif 00289 00290 00291 typedef enum 00292 { 00293 drmp3_seek_origin_start, 00294 drmp3_seek_origin_current 00295 } drmp3_seek_origin; 00296 00297 typedef struct 00298 { 00299 drmp3_uint64 seekPosInBytes; /* Points to the first byte of an MP3 frame. */ 00300 drmp3_uint64 pcmFrameIndex; /* The index of the PCM frame this seek point targets. */ 00301 drmp3_uint16 mp3FramesToDiscard; /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */ 00302 drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */ 00303 } drmp3_seek_point; 00304 00305 /* 00306 Callback for when data is read. Return value is the number of bytes actually read. 00307 00308 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. 00309 pBufferOut [out] The output buffer. 00310 bytesToRead [in] The number of bytes to read. 00311 00312 Returns the number of bytes actually read. 00313 00314 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until 00315 either the entire bytesToRead is filled or you have reached the end of the stream. 00316 */ 00317 typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); 00318 00319 /* 00320 Callback for when data needs to be seeked. 00321 00322 pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. 00323 offset [in] The number of bytes to move, relative to the origin. Will never be negative. 00324 origin [in] The origin of the seek - the current position or the start of the stream. 00325 00326 Returns whether or not the seek was successful. 00327 00328 Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which 00329 will be either drmp3_seek_origin_start or drmp3_seek_origin_current. 00330 */ 00331 typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin); 00332 00333 typedef struct 00334 { 00335 void* pUserData; 00336 void* (* onMalloc)(size_t sz, void* pUserData); 00337 void* (* onRealloc)(void* p, size_t sz, void* pUserData); 00338 void (* onFree)(void* p, void* pUserData); 00339 } drmp3_allocation_callbacks; 00340 00341 typedef struct 00342 { 00343 drmp3_uint32 channels; 00344 drmp3_uint32 sampleRate; 00345 } drmp3_config; 00346 00347 typedef struct 00348 { 00349 drmp3dec decoder; 00350 drmp3dec_frame_info frameInfo; 00351 drmp3_uint32 channels; 00352 drmp3_uint32 sampleRate; 00353 drmp3_read_proc onRead; 00354 drmp3_seek_proc onSeek; 00355 void* pUserData; 00356 drmp3_allocation_callbacks allocationCallbacks; 00357 drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */ 00358 drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */ 00359 drmp3_uint32 pcmFramesConsumedInMP3Frame; 00360 drmp3_uint32 pcmFramesRemainingInMP3Frame; 00361 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. */ 00362 drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */ 00363 drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */ 00364 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. */ 00365 drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */ 00366 size_t dataSize; 00367 size_t dataCapacity; 00368 size_t dataConsumed; 00369 drmp3_uint8* pData; 00370 drmp3_bool32 atEnd : 1; 00371 struct 00372 { 00373 const drmp3_uint8* pData; 00374 size_t dataSize; 00375 size_t currentReadPos; 00376 } memory; /* Only used for decoders that were opened against a block of memory. */ 00377 } drmp3; 00378 00379 /* 00380 Initializes an MP3 decoder. 00381 00382 onRead [in] The function to call when data needs to be read from the client. 00383 onSeek [in] The function to call when the read position of the client data needs to move. 00384 pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. 00385 00386 Returns true if successful; false otherwise. 00387 00388 Close the loader with drmp3_uninit(). 00389 00390 See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit() 00391 */ 00392 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks); 00393 00394 /* 00395 Initializes an MP3 decoder from a block of memory. 00396 00397 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for 00398 the lifetime of the drmp3 object. 00399 00400 The buffer should contain the contents of the entire MP3 file. 00401 */ 00402 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks); 00403 00404 #ifndef DR_MP3_NO_STDIO 00405 /* 00406 Initializes an MP3 decoder from a file. 00407 00408 This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3 00409 objects because the operating system may restrict the number of file handles an application can have open at 00410 any given time. 00411 */ 00412 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); 00413 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); 00414 #endif 00415 00416 /* 00417 Uninitializes an MP3 decoder. 00418 */ 00419 DRMP3_API void drmp3_uninit(drmp3* pMP3); 00420 00421 /* 00422 Reads PCM frames as interleaved 32-bit IEEE floating point PCM. 00423 00424 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. 00425 */ 00426 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut); 00427 00428 /* 00429 Reads PCM frames as interleaved signed 16-bit integer PCM. 00430 00431 Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. 00432 */ 00433 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut); 00434 00435 /* 00436 Seeks to a specific frame. 00437 00438 Note that this is _not_ an MP3 frame, but rather a PCM frame. 00439 */ 00440 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex); 00441 00442 /* 00443 Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet 00444 radio. Runs in linear time. Returns 0 on error. 00445 */ 00446 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3); 00447 00448 /* 00449 Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet 00450 radio. Runs in linear time. Returns 0 on error. 00451 */ 00452 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3); 00453 00454 /* 00455 Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet 00456 radio. Runs in linear time. Returns 0 on error. 00457 00458 This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient. 00459 */ 00460 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount); 00461 00462 /* 00463 Calculates the seekpoints based on PCM frames. This is slow. 00464 00465 pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count. 00466 On output it contains the actual count. The reason for this design is that the client may request too many 00467 seekpoints, in which case dr_mp3 will return a corrected count. 00468 00469 Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates. 00470 */ 00471 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints); 00472 00473 /* 00474 Binds a seek table to the decoder. 00475 00476 This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this 00477 remains valid while it is bound to the decoder. 00478 00479 Use drmp3_calculate_seek_points() to calculate the seek points. 00480 */ 00481 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints); 00482 00483 00484 /* 00485 Opens an decodes an entire MP3 stream as a single operation. 00486 00487 On output pConfig will receive the channel count and sample rate of the stream. 00488 00489 Free the returned pointer with drmp3_free(). 00490 */ 00491 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); 00492 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); 00493 00494 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); 00495 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); 00496 00497 #ifndef DR_MP3_NO_STDIO 00498 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); 00499 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); 00500 #endif 00501 00502 /* 00503 Allocates a block of memory on the heap. 00504 */ 00505 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks); 00506 00507 /* 00508 Frees any memory that was allocated by a public drmp3 API. 00509 */ 00510 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks); 00511 00512 #ifdef __cplusplus 00513 } 00514 #endif 00515 #endif /* dr_mp3_h */ 00516 00517 00518 /************************************************************************************************************************************************************ 00519 ************************************************************************************************************************************************************ 00520 00521 IMPLEMENTATION 00522 00523 ************************************************************************************************************************************************************ 00524 ************************************************************************************************************************************************************/ 00525 #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) 00526 #include <stdlib.h> 00527 #include <string.h> 00528 #include <limits.h> /* For INT_MAX */ 00529 00530 DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision) 00531 { 00532 if (pMajor) { 00533 *pMajor = DRMP3_VERSION_MAJOR; 00534 } 00535 00536 if (pMinor) { 00537 *pMinor = DRMP3_VERSION_MINOR; 00538 } 00539 00540 if (pRevision) { 00541 *pRevision = DRMP3_VERSION_REVISION; 00542 } 00543 } 00544 00545 DRMP3_API const char* drmp3_version_string() 00546 { 00547 return DRMP3_VERSION_STRING; 00548 } 00549 00550 /* Disable SIMD when compiling with TCC for now. */ 00551 #if defined(__TINYC__) 00552 #define DR_MP3_NO_SIMD 00553 #endif 00554 00555 #define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset))) 00556 00557 #define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ 00558 #ifndef DRMP3_MAX_FRAME_SYNC_MATCHES 00559 #define DRMP3_MAX_FRAME_SYNC_MATCHES 10 00560 #endif 00561 00562 #define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ 00563 00564 #define DRMP3_MAX_BITRESERVOIR_BYTES 511 00565 #define DRMP3_SHORT_BLOCK_TYPE 2 00566 #define DRMP3_STOP_BLOCK_TYPE 3 00567 #define DRMP3_MODE_MONO 3 00568 #define DRMP3_MODE_JOINT_STEREO 1 00569 #define DRMP3_HDR_SIZE 4 00570 #define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0) 00571 #define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60) 00572 #define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0) 00573 #define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1)) 00574 #define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2) 00575 #define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8) 00576 #define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10) 00577 #define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10) 00578 #define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20) 00579 #define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3) 00580 #define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3) 00581 #define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) 00582 #define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4) 00583 #define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) 00584 #define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3) 00585 #define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2) 00586 #define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) 00587 00588 #define DRMP3_BITS_DEQUANTIZER_OUT -1 00589 #define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210) 00590 #define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3) 00591 00592 #define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a)) 00593 #define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a)) 00594 00595 #if !defined(DR_MP3_NO_SIMD) 00596 00597 #if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)) 00598 /* x64 always have SSE2, arm64 always have neon, no need for generic code */ 00599 #define DR_MP3_ONLY_SIMD 00600 #endif 00601 00602 #if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) 00603 #if defined(_MSC_VER) 00604 #include <intrin.h> 00605 #endif 00606 #include <emmintrin.h> 00607 #define DRMP3_HAVE_SSE 1 00608 #define DRMP3_HAVE_SIMD 1 00609 #define DRMP3_VSTORE _mm_storeu_ps 00610 #define DRMP3_VLD _mm_loadu_ps 00611 #define DRMP3_VSET _mm_set1_ps 00612 #define DRMP3_VADD _mm_add_ps 00613 #define DRMP3_VSUB _mm_sub_ps 00614 #define DRMP3_VMUL _mm_mul_ps 00615 #define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y)) 00616 #define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y)) 00617 #define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) 00618 #define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) 00619 typedef __m128 drmp3_f4; 00620 #if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD) 00621 #define drmp3_cpuid __cpuid 00622 #else 00623 static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType) 00624 { 00625 #if defined(__PIC__) 00626 __asm__ __volatile__( 00627 #if defined(__x86_64__) 00628 "push %%rbx\n" 00629 "cpuid\n" 00630 "xchgl %%ebx, %1\n" 00631 "pop %%rbx\n" 00632 #else 00633 "xchgl %%ebx, %1\n" 00634 "cpuid\n" 00635 "xchgl %%ebx, %1\n" 00636 #endif 00637 : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) 00638 : "a" (InfoType)); 00639 #else 00640 __asm__ __volatile__( 00641 "cpuid" 00642 : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) 00643 : "a" (InfoType)); 00644 #endif 00645 } 00646 #endif 00647 static int drmp3_have_simd(void) 00648 { 00649 #ifdef DR_MP3_ONLY_SIMD 00650 return 1; 00651 #else 00652 static int g_have_simd; 00653 int CPUInfo[4]; 00654 #ifdef MINIMP3_TEST 00655 static int g_counter; 00656 if (g_counter++ > 100) 00657 return 0; 00658 #endif 00659 if (g_have_simd) 00660 goto end; 00661 drmp3_cpuid(CPUInfo, 0); 00662 if (CPUInfo[0] > 0) 00663 { 00664 drmp3_cpuid(CPUInfo, 1); 00665 g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ 00666 return g_have_simd - 1; 00667 } 00668 00669 end: 00670 return g_have_simd - 1; 00671 #endif 00672 } 00673 #elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)/*VS2019*/ 00674 #include <arm_neon.h> 00675 #define DRMP3_HAVE_SSE 0 00676 #define DRMP3_HAVE_SIMD 1 00677 #define DRMP3_VSTORE vst1q_f32 00678 #define DRMP3_VLD vld1q_f32 00679 #define DRMP3_VSET vmovq_n_f32 00680 #define DRMP3_VADD vaddq_f32 00681 #define DRMP3_VSUB vsubq_f32 00682 #define DRMP3_VMUL vmulq_f32 00683 #define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y) 00684 #define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y) 00685 #define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s)) 00686 #define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x))) 00687 typedef float32x4_t drmp3_f4; 00688 static int drmp3_have_simd(void) 00689 { /* TODO: detect neon for !DR_MP3_ONLY_SIMD */ 00690 return 1; 00691 } 00692 #else 00693 #define DRMP3_HAVE_SSE 0 00694 #define DRMP3_HAVE_SIMD 0 00695 #ifdef DR_MP3_ONLY_SIMD 00696 #error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled 00697 #endif 00698 #endif 00699 00700 #else 00701 00702 #define DRMP3_HAVE_SIMD 0 00703 00704 #endif 00705 00706 #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) 00707 #define DRMP3_HAVE_ARMV6 1 00708 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(int32_t a) 00709 { 00710 drmp3_int32 x = 0; 00711 __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); 00712 return x; 00713 } 00714 #endif 00715 00716 00717 typedef struct 00718 { 00719 const drmp3_uint8 *buf; 00720 int pos, limit; 00721 } drmp3_bs; 00722 00723 typedef struct 00724 { 00725 float scf[3*64]; 00726 drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64]; 00727 } drmp3_L12_scale_info; 00728 00729 typedef struct 00730 { 00731 drmp3_uint8 tab_offset, code_tab_width, band_count; 00732 } drmp3_L12_subband_alloc; 00733 00734 typedef struct 00735 { 00736 const drmp3_uint8 *sfbtab; 00737 drmp3_uint16 part_23_length, big_values, scalefac_compress; 00738 drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; 00739 drmp3_uint8 table_select[3], region_count[3], subblock_gain[3]; 00740 drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi; 00741 } drmp3_L3_gr_info; 00742 00743 typedef struct 00744 { 00745 drmp3_bs bs; 00746 drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES]; 00747 drmp3_L3_gr_info gr_info[4]; 00748 float grbuf[2][576], scf[40], syn[18 + 15][2*32]; 00749 drmp3_uint8 ist_pos[2][39]; 00750 } drmp3dec_scratch; 00751 00752 static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes) 00753 { 00754 bs->buf = data; 00755 bs->pos = 0; 00756 bs->limit = bytes*8; 00757 } 00758 00759 static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n) 00760 { 00761 drmp3_uint32 next, cache = 0, s = bs->pos & 7; 00762 int shl = n + s; 00763 const drmp3_uint8 *p = bs->buf + (bs->pos >> 3); 00764 if ((bs->pos += n) > bs->limit) 00765 return 0; 00766 next = *p++ & (255 >> s); 00767 while ((shl -= 8) > 0) 00768 { 00769 cache |= next << shl; 00770 next = *p++; 00771 } 00772 return cache | (next >> -shl); 00773 } 00774 00775 static int drmp3_hdr_valid(const drmp3_uint8 *h) 00776 { 00777 return h[0] == 0xff && 00778 ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) && 00779 (DRMP3_HDR_GET_LAYER(h) != 0) && 00780 (DRMP3_HDR_GET_BITRATE(h) != 15) && 00781 (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3); 00782 } 00783 00784 static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2) 00785 { 00786 return drmp3_hdr_valid(h2) && 00787 ((h1[1] ^ h2[1]) & 0xFE) == 0 && 00788 ((h1[2] ^ h2[2]) & 0x0C) == 0 && 00789 !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2)); 00790 } 00791 00792 static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h) 00793 { 00794 static const drmp3_uint8 halfrate[2][3][15] = { 00795 { { 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 } }, 00796 { { 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 } }, 00797 }; 00798 return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)]; 00799 } 00800 00801 static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h) 00802 { 00803 static const unsigned g_hz[3] = { 44100, 48000, 32000 }; 00804 return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h); 00805 } 00806 00807 static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h) 00808 { 00809 return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h)); 00810 } 00811 00812 static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size) 00813 { 00814 int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h); 00815 if (DRMP3_HDR_IS_LAYER_1(h)) 00816 { 00817 frame_bytes &= ~3; /* slot align */ 00818 } 00819 return frame_bytes ? frame_bytes : free_format_size; 00820 } 00821 00822 static int drmp3_hdr_padding(const drmp3_uint8 *h) 00823 { 00824 return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0; 00825 } 00826 00827 #ifndef DR_MP3_ONLY_MP3 00828 static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci) 00829 { 00830 const drmp3_L12_subband_alloc *alloc; 00831 int mode = DRMP3_HDR_GET_STEREO_MODE(hdr); 00832 int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32; 00833 00834 if (DRMP3_HDR_IS_LAYER_1(hdr)) 00835 { 00836 static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } }; 00837 alloc = g_alloc_L1; 00838 nbands = 32; 00839 } else if (!DRMP3_HDR_TEST_MPEG1(hdr)) 00840 { 00841 static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } }; 00842 alloc = g_alloc_L2M2; 00843 nbands = 30; 00844 } else 00845 { 00846 static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } }; 00847 int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr); 00848 unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO); 00849 if (!kbps) /* free-format */ 00850 { 00851 kbps = 192; 00852 } 00853 00854 alloc = g_alloc_L2M1; 00855 nbands = 27; 00856 if (kbps < 56) 00857 { 00858 static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } }; 00859 alloc = g_alloc_L2M1_lowrate; 00860 nbands = sample_rate_idx == 2 ? 12 : 8; 00861 } else if (kbps >= 96 && sample_rate_idx != 1) 00862 { 00863 nbands = 30; 00864 } 00865 } 00866 00867 sci->total_bands = (drmp3_uint8)nbands; 00868 sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands); 00869 00870 return alloc; 00871 } 00872 00873 static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf) 00874 { 00875 static const float g_deq_L12[18*3] = { 00876 #define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x 00877 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) 00878 }; 00879 int i, m; 00880 for (i = 0; i < bands; i++) 00881 { 00882 float s = 0; 00883 int ba = *pba++; 00884 int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0; 00885 for (m = 4; m; m >>= 1) 00886 { 00887 if (mask & m) 00888 { 00889 int b = drmp3_bs_get_bits(bs, 6); 00890 s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3); 00891 } 00892 *scf++ = s; 00893 } 00894 } 00895 } 00896 00897 static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci) 00898 { 00899 static const drmp3_uint8 g_bitalloc_code_tab[] = { 00900 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16, 00901 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16, 00902 0,17,18, 3,19,4,5,16, 00903 0,17,18,16, 00904 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15, 00905 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14, 00906 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16 00907 }; 00908 const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci); 00909 00910 int i, k = 0, ba_bits = 0; 00911 const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab; 00912 00913 for (i = 0; i < sci->total_bands; i++) 00914 { 00915 drmp3_uint8 ba; 00916 if (i == k) 00917 { 00918 k += subband_alloc->band_count; 00919 ba_bits = subband_alloc->code_tab_width; 00920 ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset; 00921 subband_alloc++; 00922 } 00923 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; 00924 sci->bitalloc[2*i] = ba; 00925 if (i < sci->stereo_bands) 00926 { 00927 ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; 00928 } 00929 sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0; 00930 } 00931 00932 for (i = 0; i < 2*sci->total_bands; i++) 00933 { 00934 sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6); 00935 } 00936 00937 drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf); 00938 00939 for (i = sci->stereo_bands; i < sci->total_bands; i++) 00940 { 00941 sci->bitalloc[2*i + 1] = 0; 00942 } 00943 } 00944 00945 static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size) 00946 { 00947 int i, j, k, choff = 576; 00948 for (j = 0; j < 4; j++) 00949 { 00950 float *dst = grbuf + group_size*j; 00951 for (i = 0; i < 2*sci->total_bands; i++) 00952 { 00953 int ba = sci->bitalloc[i]; 00954 if (ba != 0) 00955 { 00956 if (ba < 17) 00957 { 00958 int half = (1 << (ba - 1)) - 1; 00959 for (k = 0; k < group_size; k++) 00960 { 00961 dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half); 00962 } 00963 } else 00964 { 00965 unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */ 00966 unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */ 00967 for (k = 0; k < group_size; k++, code /= mod) 00968 { 00969 dst[k] = (float)((int)(code % mod - mod/2)); 00970 } 00971 } 00972 } 00973 dst += choff; 00974 choff = 18 - choff; 00975 } 00976 } 00977 return group_size*4; 00978 } 00979 00980 static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst) 00981 { 00982 int i, k; 00983 memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); 00984 for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) 00985 { 00986 for (k = 0; k < 12; k++) 00987 { 00988 dst[k + 0] *= scf[0]; 00989 dst[k + 576] *= scf[3]; 00990 } 00991 } 00992 } 00993 #endif 00994 00995 static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) 00996 { 00997 static const drmp3_uint8 g_scf_long[8][23] = { 00998 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, 00999 { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, 01000 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, 01001 { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 }, 01002 { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, 01003 { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 }, 01004 { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, 01005 { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } 01006 }; 01007 static const drmp3_uint8 g_scf_short[8][40] = { 01008 { 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 }, 01009 { 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 }, 01010 { 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 }, 01011 { 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 }, 01012 { 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 }, 01013 { 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 }, 01014 { 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 }, 01015 { 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 } 01016 }; 01017 static const drmp3_uint8 g_scf_mixed[8][40] = { 01018 { 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 }, 01019 { 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 }, 01020 { 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 }, 01021 { 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 }, 01022 { 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 }, 01023 { 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 }, 01024 { 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 }, 01025 { 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 } 01026 }; 01027 01028 unsigned tables, scfsi = 0; 01029 int main_data_begin, part_23_sum = 0; 01030 int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; 01031 int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0); 01032 01033 if (DRMP3_HDR_TEST_MPEG1(hdr)) 01034 { 01035 gr_count *= 2; 01036 main_data_begin = drmp3_bs_get_bits(bs, 9); 01037 scfsi = drmp3_bs_get_bits(bs, 7 + gr_count); 01038 } else 01039 { 01040 main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count; 01041 } 01042 01043 do 01044 { 01045 if (DRMP3_HDR_IS_MONO(hdr)) 01046 { 01047 scfsi <<= 4; 01048 } 01049 gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12); 01050 part_23_sum += gr->part_23_length; 01051 gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9); 01052 if (gr->big_values > 288) 01053 { 01054 return -1; 01055 } 01056 gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8); 01057 gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9); 01058 gr->sfbtab = g_scf_long[sr_idx]; 01059 gr->n_long_sfb = 22; 01060 gr->n_short_sfb = 0; 01061 if (drmp3_bs_get_bits(bs, 1)) 01062 { 01063 gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2); 01064 if (!gr->block_type) 01065 { 01066 return -1; 01067 } 01068 gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); 01069 gr->region_count[0] = 7; 01070 gr->region_count[1] = 255; 01071 if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE) 01072 { 01073 scfsi &= 0x0F0F; 01074 if (!gr->mixed_block_flag) 01075 { 01076 gr->region_count[0] = 8; 01077 gr->sfbtab = g_scf_short[sr_idx]; 01078 gr->n_long_sfb = 0; 01079 gr->n_short_sfb = 39; 01080 } else 01081 { 01082 gr->sfbtab = g_scf_mixed[sr_idx]; 01083 gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6; 01084 gr->n_short_sfb = 30; 01085 } 01086 } 01087 tables = drmp3_bs_get_bits(bs, 10); 01088 tables <<= 5; 01089 gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); 01090 gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); 01091 gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); 01092 } else 01093 { 01094 gr->block_type = 0; 01095 gr->mixed_block_flag = 0; 01096 tables = drmp3_bs_get_bits(bs, 15); 01097 gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4); 01098 gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); 01099 gr->region_count[2] = 255; 01100 } 01101 gr->table_select[0] = (drmp3_uint8)(tables >> 10); 01102 gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31); 01103 gr->table_select[2] = (drmp3_uint8)((tables) & 31); 01104 gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500)); 01105 gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); 01106 gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); 01107 gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15); 01108 scfsi <<= 4; 01109 gr++; 01110 } while(--gr_count); 01111 01112 if (part_23_sum + bs->pos > bs->limit + main_data_begin*8) 01113 { 01114 return -1; 01115 } 01116 01117 return main_data_begin; 01118 } 01119 01120 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) 01121 { 01122 int i, k; 01123 for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2) 01124 { 01125 int cnt = scf_count[i]; 01126 if (scfsi & 8) 01127 { 01128 memcpy(scf, ist_pos, cnt); 01129 } else 01130 { 01131 int bits = scf_size[i]; 01132 if (!bits) 01133 { 01134 memset(scf, 0, cnt); 01135 memset(ist_pos, 0, cnt); 01136 } else 01137 { 01138 int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; 01139 for (k = 0; k < cnt; k++) 01140 { 01141 int s = drmp3_bs_get_bits(bitbuf, bits); 01142 ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s); 01143 scf[k] = (drmp3_uint8)s; 01144 } 01145 } 01146 } 01147 ist_pos += cnt; 01148 scf += cnt; 01149 } 01150 scf[0] = scf[1] = scf[2] = 0; 01151 } 01152 01153 static float drmp3_L3_ldexp_q2(float y, int exp_q2) 01154 { 01155 static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f }; 01156 int e; 01157 do 01158 { 01159 e = DRMP3_MIN(30*4, exp_q2); 01160 y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2)); 01161 } while ((exp_q2 -= e) > 0); 01162 return y; 01163 } 01164 01165 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) 01166 { 01167 static const drmp3_uint8 g_scf_partitions[3][28] = { 01168 { 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 }, 01169 { 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 }, 01170 { 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 } 01171 }; 01172 const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb]; 01173 drmp3_uint8 scf_size[4], iscf[40]; 01174 int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi; 01175 float gain; 01176 01177 if (DRMP3_HDR_TEST_MPEG1(hdr)) 01178 { 01179 static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 }; 01180 int part = g_scfc_decode[gr->scalefac_compress]; 01181 scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2); 01182 scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3); 01183 } else 01184 { 01185 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 }; 01186 int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch; 01187 sfc = gr->scalefac_compress >> ist; 01188 for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4) 01189 { 01190 for (modprod = 1, i = 3; i >= 0; i--) 01191 { 01192 scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]); 01193 modprod *= g_mod[k + i]; 01194 } 01195 } 01196 scf_partition += k; 01197 scfsi = -16; 01198 } 01199 drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi); 01200 01201 if (gr->n_short_sfb) 01202 { 01203 int sh = 3 - scf_shift; 01204 for (i = 0; i < gr->n_short_sfb; i += 3) 01205 { 01206 iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh)); 01207 iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh)); 01208 iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh)); 01209 } 01210 } else if (gr->preflag) 01211 { 01212 static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 }; 01213 for (i = 0; i < 10; i++) 01214 { 01215 iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]); 01216 } 01217 } 01218 01219 gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0); 01220 gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp); 01221 for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++) 01222 { 01223 scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); 01224 } 01225 } 01226 01227 static const float g_drmp3_pow43[129 + 16] = { 01228 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, 01229 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 01230 }; 01231 01232 static float drmp3_L3_pow_43(int x) 01233 { 01234 float frac; 01235 int sign, mult = 256; 01236 01237 if (x < 129) 01238 { 01239 return g_drmp3_pow43[16 + x]; 01240 } 01241 01242 if (x < 1024) 01243 { 01244 mult = 16; 01245 x <<= 3; 01246 } 01247 01248 sign = 2*x & 64; 01249 frac = (float)((x & 63) - sign) / ((x & ~63) + sign); 01250 return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult; 01251 } 01252 01253 static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit) 01254 { 01255 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, 01256 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, 01257 -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, 01258 -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, 01259 -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, 01260 -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, 01261 -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, 01262 -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, 01263 -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, 01264 -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, 01265 -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, 01266 -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, 01267 -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, 01268 -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, 01269 -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, 01270 -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 }; 01271 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}; 01272 static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; 01273 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 }; 01274 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 }; 01275 01276 #define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n)) 01277 #define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } 01278 #define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } 01279 #define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) 01280 01281 float one = 0.0f; 01282 int ireg = 0, big_val_cnt = gr_info->big_values; 01283 const drmp3_uint8 *sfb = gr_info->sfbtab; 01284 const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8; 01285 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); 01286 int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8; 01287 bs_next_ptr += 4; 01288 01289 while (big_val_cnt > 0) 01290 { 01291 int tab_num = gr_info->table_select[ireg]; 01292 int sfb_cnt = gr_info->region_count[ireg++]; 01293 const drmp3_int16 *codebook = tabs + tabindex[tab_num]; 01294 int linbits = g_linbits[tab_num]; 01295 if (linbits) 01296 { 01297 do 01298 { 01299 np = *sfb++ / 2; 01300 pairs_to_decode = DRMP3_MIN(big_val_cnt, np); 01301 one = *scf++; 01302 do 01303 { 01304 int j, w = 5; 01305 int leaf = codebook[DRMP3_PEEK_BITS(w)]; 01306 while (leaf < 0) 01307 { 01308 DRMP3_FLUSH_BITS(w); 01309 w = leaf & 7; 01310 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)]; 01311 } 01312 DRMP3_FLUSH_BITS(leaf >> 8); 01313 01314 for (j = 0; j < 2; j++, dst++, leaf >>= 4) 01315 { 01316 int lsb = leaf & 0x0F; 01317 if (lsb == 15) 01318 { 01319 lsb += DRMP3_PEEK_BITS(linbits); 01320 DRMP3_FLUSH_BITS(linbits); 01321 DRMP3_CHECK_BITS; 01322 *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1); 01323 } else 01324 { 01325 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; 01326 } 01327 DRMP3_FLUSH_BITS(lsb ? 1 : 0); 01328 } 01329 DRMP3_CHECK_BITS; 01330 } while (--pairs_to_decode); 01331 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); 01332 } else 01333 { 01334 do 01335 { 01336 np = *sfb++ / 2; 01337 pairs_to_decode = DRMP3_MIN(big_val_cnt, np); 01338 one = *scf++; 01339 do 01340 { 01341 int j, w = 5; 01342 int leaf = codebook[DRMP3_PEEK_BITS(w)]; 01343 while (leaf < 0) 01344 { 01345 DRMP3_FLUSH_BITS(w); 01346 w = leaf & 7; 01347 leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)]; 01348 } 01349 DRMP3_FLUSH_BITS(leaf >> 8); 01350 01351 for (j = 0; j < 2; j++, dst++, leaf >>= 4) 01352 { 01353 int lsb = leaf & 0x0F; 01354 *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; 01355 DRMP3_FLUSH_BITS(lsb ? 1 : 0); 01356 } 01357 DRMP3_CHECK_BITS; 01358 } while (--pairs_to_decode); 01359 } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); 01360 } 01361 } 01362 01363 for (np = 1 - big_val_cnt;; dst += 4) 01364 { 01365 const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32; 01366 int leaf = codebook_count1[DRMP3_PEEK_BITS(4)]; 01367 if (!(leaf & 8)) 01368 { 01369 leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))]; 01370 } 01371 DRMP3_FLUSH_BITS(leaf & 7); 01372 if (DRMP3_BSPOS > layer3gr_limit) 01373 { 01374 break; 01375 } 01376 #define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; } 01377 #define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) } 01378 DRMP3_RELOAD_SCALEFACTOR; 01379 DRMP3_DEQ_COUNT1(0); 01380 DRMP3_DEQ_COUNT1(1); 01381 DRMP3_RELOAD_SCALEFACTOR; 01382 DRMP3_DEQ_COUNT1(2); 01383 DRMP3_DEQ_COUNT1(3); 01384 DRMP3_CHECK_BITS; 01385 } 01386 01387 bs->pos = layer3gr_limit; 01388 } 01389 01390 static void drmp3_L3_midside_stereo(float *left, int n) 01391 { 01392 int i = 0; 01393 float *right = left + 576; 01394 #if DRMP3_HAVE_SIMD 01395 if (drmp3_have_simd()) for (; i < n - 3; i += 4) 01396 { 01397 drmp3_f4 vl = DRMP3_VLD(left + i); 01398 drmp3_f4 vr = DRMP3_VLD(right + i); 01399 DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr)); 01400 DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr)); 01401 } 01402 #endif 01403 for (; i < n; i++) 01404 { 01405 float a = left[i]; 01406 float b = right[i]; 01407 left[i] = a + b; 01408 right[i] = a - b; 01409 } 01410 } 01411 01412 static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr) 01413 { 01414 int i; 01415 for (i = 0; i < n; i++) 01416 { 01417 left[i + 576] = left[i]*kr; 01418 left[i] = left[i]*kl; 01419 } 01420 } 01421 01422 static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3]) 01423 { 01424 int i, k; 01425 01426 max_band[0] = max_band[1] = max_band[2] = -1; 01427 01428 for (i = 0; i < nbands; i++) 01429 { 01430 for (k = 0; k < sfb[i]; k += 2) 01431 { 01432 if (right[k] != 0 || right[k + 1] != 0) 01433 { 01434 max_band[i % 3] = i; 01435 break; 01436 } 01437 } 01438 right += sfb[i]; 01439 } 01440 } 01441 01442 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) 01443 { 01444 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 }; 01445 unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64; 01446 01447 for (i = 0; sfb[i]; i++) 01448 { 01449 unsigned ipos = ist_pos[i]; 01450 if ((int)i > max_band[i % 3] && ipos < max_pos) 01451 { 01452 float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1; 01453 if (DRMP3_HDR_TEST_MPEG1(hdr)) 01454 { 01455 kl = g_pan[2*ipos]; 01456 kr = g_pan[2*ipos + 1]; 01457 } else 01458 { 01459 kl = 1; 01460 kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh); 01461 if (ipos & 1) 01462 { 01463 kl = kr; 01464 kr = 1; 01465 } 01466 } 01467 drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s); 01468 } else if (DRMP3_HDR_TEST_MS_STEREO(hdr)) 01469 { 01470 drmp3_L3_midside_stereo(left, sfb[i]); 01471 } 01472 left += sfb[i]; 01473 } 01474 } 01475 01476 static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) 01477 { 01478 int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb; 01479 int i, max_blocks = gr->n_short_sfb ? 3 : 1; 01480 01481 drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band); 01482 if (gr->n_long_sfb) 01483 { 01484 max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]); 01485 } 01486 for (i = 0; i < max_blocks; i++) 01487 { 01488 int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0; 01489 int itop = n_sfb - max_blocks + i; 01490 int prev = itop - max_blocks; 01491 ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]); 01492 } 01493 drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1); 01494 } 01495 01496 static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb) 01497 { 01498 int i, len; 01499 float *src = grbuf, *dst = scratch; 01500 01501 for (;0 != (len = *sfb); sfb += 3, src += 2*len) 01502 { 01503 for (i = 0; i < len; i++, src++) 01504 { 01505 *dst++ = src[0*len]; 01506 *dst++ = src[1*len]; 01507 *dst++ = src[2*len]; 01508 } 01509 } 01510 memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); 01511 } 01512 01513 static void drmp3_L3_antialias(float *grbuf, int nbands) 01514 { 01515 static const float g_aa[2][8] = { 01516 {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f}, 01517 {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f} 01518 }; 01519 01520 for (; nbands > 0; nbands--, grbuf += 18) 01521 { 01522 int i = 0; 01523 #if DRMP3_HAVE_SIMD 01524 if (drmp3_have_simd()) for (; i < 8; i += 4) 01525 { 01526 drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i); 01527 drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i); 01528 drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i); 01529 drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i); 01530 vd = DRMP3_VREV(vd); 01531 DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1))); 01532 vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0)); 01533 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd)); 01534 } 01535 #endif 01536 #ifndef DR_MP3_ONLY_SIMD 01537 for(; i < 8; i++) 01538 { 01539 float u = grbuf[18 + i]; 01540 float d = grbuf[17 - i]; 01541 grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i]; 01542 grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i]; 01543 } 01544 #endif 01545 } 01546 } 01547 01548 static void drmp3_L3_dct3_9(float *y) 01549 { 01550 float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4; 01551 01552 s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8]; 01553 t0 = s0 + s6*0.5f; 01554 s0 -= s6; 01555 t4 = (s4 + s2)*0.93969262f; 01556 t2 = (s8 + s2)*0.76604444f; 01557 s6 = (s4 - s8)*0.17364818f; 01558 s4 += s8 - s2; 01559 01560 s2 = s0 - s4*0.5f; 01561 y[4] = s4 + s0; 01562 s8 = t0 - t2 + s6; 01563 s0 = t0 - t4 + t2; 01564 s4 = t0 + t4 - s6; 01565 01566 s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7]; 01567 01568 s3 *= 0.86602540f; 01569 t0 = (s5 + s1)*0.98480775f; 01570 t4 = (s5 - s7)*0.34202014f; 01571 t2 = (s1 + s7)*0.64278761f; 01572 s1 = (s1 - s5 - s7)*0.86602540f; 01573 01574 s5 = t0 - s3 - t2; 01575 s7 = t4 - s3 - t0; 01576 s3 = t4 + s3 - t2; 01577 01578 y[0] = s4 - s7; 01579 y[1] = s2 + s1; 01580 y[2] = s0 - s3; 01581 y[3] = s8 + s5; 01582 y[5] = s8 - s5; 01583 y[6] = s0 + s3; 01584 y[7] = s2 - s1; 01585 y[8] = s4 + s7; 01586 } 01587 01588 static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands) 01589 { 01590 int i, j; 01591 static const float g_twid9[18] = { 01592 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 01593 }; 01594 01595 for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9) 01596 { 01597 float co[9], si[9]; 01598 co[0] = -grbuf[0]; 01599 si[0] = grbuf[17]; 01600 for (i = 0; i < 4; i++) 01601 { 01602 si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2]; 01603 co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2]; 01604 si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3]; 01605 co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]); 01606 } 01607 drmp3_L3_dct3_9(co); 01608 drmp3_L3_dct3_9(si); 01609 01610 si[1] = -si[1]; 01611 si[3] = -si[3]; 01612 si[5] = -si[5]; 01613 si[7] = -si[7]; 01614 01615 i = 0; 01616 01617 #if DRMP3_HAVE_SIMD 01618 if (drmp3_have_simd()) for (; i < 8; i += 4) 01619 { 01620 drmp3_f4 vovl = DRMP3_VLD(overlap + i); 01621 drmp3_f4 vc = DRMP3_VLD(co + i); 01622 drmp3_f4 vs = DRMP3_VLD(si + i); 01623 drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i); 01624 drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i); 01625 drmp3_f4 vw0 = DRMP3_VLD(window + i); 01626 drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i); 01627 drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0)); 01628 DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1))); 01629 DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1))); 01630 vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0)); 01631 DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum)); 01632 } 01633 #endif 01634 for (; i < 9; i++) 01635 { 01636 float ovl = overlap[i]; 01637 float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i]; 01638 overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i]; 01639 grbuf[i] = ovl*window[0 + i] - sum*window[9 + i]; 01640 grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i]; 01641 } 01642 } 01643 } 01644 01645 static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst) 01646 { 01647 float m1 = x1*0.86602540f; 01648 float a1 = x0 - x2*0.5f; 01649 dst[1] = x0 + x2; 01650 dst[0] = a1 + m1; 01651 dst[2] = a1 - m1; 01652 } 01653 01654 static void drmp3_L3_imdct12(float *x, float *dst, float *overlap) 01655 { 01656 static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f }; 01657 float co[3], si[3]; 01658 int i; 01659 01660 drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co); 01661 drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si); 01662 si[1] = -si[1]; 01663 01664 for (i = 0; i < 3; i++) 01665 { 01666 float ovl = overlap[i]; 01667 float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i]; 01668 overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i]; 01669 dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i]; 01670 dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i]; 01671 } 01672 } 01673 01674 static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands) 01675 { 01676 for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) 01677 { 01678 float tmp[18]; 01679 memcpy(tmp, grbuf, sizeof(tmp)); 01680 memcpy(grbuf, overlap, 6*sizeof(float)); 01681 drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6); 01682 drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); 01683 drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6); 01684 } 01685 } 01686 01687 static void drmp3_L3_change_sign(float *grbuf) 01688 { 01689 int b, i; 01690 for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36) 01691 for (i = 1; i < 18; i += 2) 01692 grbuf[i] = -grbuf[i]; 01693 } 01694 01695 static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands) 01696 { 01697 static const float g_mdct_window[2][18] = { 01698 { 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 }, 01699 { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f } 01700 }; 01701 if (n_long_bands) 01702 { 01703 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands); 01704 grbuf += 18*n_long_bands; 01705 overlap += 9*n_long_bands; 01706 } 01707 if (block_type == DRMP3_SHORT_BLOCK_TYPE) 01708 drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands); 01709 else 01710 drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands); 01711 } 01712 01713 static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s) 01714 { 01715 int pos = (s->bs.pos + 7)/8u; 01716 int remains = s->bs.limit/8u - pos; 01717 if (remains > DRMP3_MAX_BITRESERVOIR_BYTES) 01718 { 01719 pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES; 01720 remains = DRMP3_MAX_BITRESERVOIR_BYTES; 01721 } 01722 if (remains > 0) 01723 { 01724 memmove(h->reserv_buf, s->maindata + pos, remains); 01725 } 01726 h->reserv = remains; 01727 } 01728 01729 static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin) 01730 { 01731 int frame_bytes = (bs->limit - bs->pos)/8; 01732 int bytes_have = DRMP3_MIN(h->reserv, main_data_begin); 01733 memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin)); 01734 memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); 01735 drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); 01736 return h->reserv >= main_data_begin; 01737 } 01738 01739 static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch) 01740 { 01741 int ch; 01742 01743 for (ch = 0; ch < nch; ch++) 01744 { 01745 int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length; 01746 drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch); 01747 drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit); 01748 } 01749 01750 if (DRMP3_HDR_TEST_I_STEREO(h->header)) 01751 { 01752 drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header); 01753 } else if (DRMP3_HDR_IS_MS_STEREO(h->header)) 01754 { 01755 drmp3_L3_midside_stereo(s->grbuf[0], 576); 01756 } 01757 01758 for (ch = 0; ch < nch; ch++, gr_info++) 01759 { 01760 int aa_bands = 31; 01761 int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2); 01762 01763 if (gr_info->n_short_sfb) 01764 { 01765 aa_bands = n_long_bands - 1; 01766 drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb); 01767 } 01768 01769 drmp3_L3_antialias(s->grbuf[ch], aa_bands); 01770 drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands); 01771 drmp3_L3_change_sign(s->grbuf[ch]); 01772 } 01773 } 01774 01775 static void drmp3d_DCT_II(float *grbuf, int n) 01776 { 01777 static const float g_sec[24] = { 01778 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 01779 }; 01780 int i, k = 0; 01781 #if DRMP3_HAVE_SIMD 01782 if (drmp3_have_simd()) for (; k < n; k += 4) 01783 { 01784 drmp3_f4 t[4][8], *x; 01785 float *y = grbuf + k; 01786 01787 for (x = t[0], i = 0; i < 8; i++, x++) 01788 { 01789 drmp3_f4 x0 = DRMP3_VLD(&y[i*18]); 01790 drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]); 01791 drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]); 01792 drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]); 01793 drmp3_f4 t0 = DRMP3_VADD(x0, x3); 01794 drmp3_f4 t1 = DRMP3_VADD(x1, x2); 01795 drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]); 01796 drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]); 01797 x[0] = DRMP3_VADD(t0, t1); 01798 x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]); 01799 x[16] = DRMP3_VADD(t3, t2); 01800 x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]); 01801 } 01802 for (x = t[0], i = 0; i < 4; i++, x += 8) 01803 { 01804 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; 01805 xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7); 01806 x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6); 01807 x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5); 01808 x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4); 01809 x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3); 01810 x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2); 01811 x[0] = DRMP3_VADD(x0, x1); 01812 x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f); 01813 x5 = DRMP3_VADD(x5, x6); 01814 x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f); 01815 x7 = DRMP3_VADD(x7, xt); 01816 x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f); 01817 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */ 01818 x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f)); 01819 x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); 01820 x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6); 01821 x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f); 01822 x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f); 01823 x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f); 01824 x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f); 01825 x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f); 01826 x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f); 01827 } 01828 01829 if (k > n - 3) 01830 { 01831 #if DRMP3_HAVE_SSE 01832 #define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) 01833 #else 01834 #define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) 01835 #endif 01836 for (i = 0; i < 7; i++, y += 4*18) 01837 { 01838 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); 01839 DRMP3_VSAVE2(0, t[0][i]); 01840 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s)); 01841 DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1])); 01842 DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s)); 01843 } 01844 DRMP3_VSAVE2(0, t[0][7]); 01845 DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7])); 01846 DRMP3_VSAVE2(2, t[1][7]); 01847 DRMP3_VSAVE2(3, t[3][7]); 01848 } else 01849 { 01850 #define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v) 01851 for (i = 0; i < 7; i++, y += 4*18) 01852 { 01853 drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); 01854 DRMP3_VSAVE4(0, t[0][i]); 01855 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s)); 01856 DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1])); 01857 DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s)); 01858 } 01859 DRMP3_VSAVE4(0, t[0][7]); 01860 DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7])); 01861 DRMP3_VSAVE4(2, t[1][7]); 01862 DRMP3_VSAVE4(3, t[3][7]); 01863 } 01864 } else 01865 #endif 01866 #ifdef DR_MP3_ONLY_SIMD 01867 {} 01868 #else 01869 for (; k < n; k++) 01870 { 01871 float t[4][8], *x, *y = grbuf + k; 01872 01873 for (x = t[0], i = 0; i < 8; i++, x++) 01874 { 01875 float x0 = y[i*18]; 01876 float x1 = y[(15 - i)*18]; 01877 float x2 = y[(16 + i)*18]; 01878 float x3 = y[(31 - i)*18]; 01879 float t0 = x0 + x3; 01880 float t1 = x1 + x2; 01881 float t2 = (x1 - x2)*g_sec[3*i + 0]; 01882 float t3 = (x0 - x3)*g_sec[3*i + 1]; 01883 x[0] = t0 + t1; 01884 x[8] = (t0 - t1)*g_sec[3*i + 2]; 01885 x[16] = t3 + t2; 01886 x[24] = (t3 - t2)*g_sec[3*i + 2]; 01887 } 01888 for (x = t[0], i = 0; i < 4; i++, x += 8) 01889 { 01890 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; 01891 xt = x0 - x7; x0 += x7; 01892 x7 = x1 - x6; x1 += x6; 01893 x6 = x2 - x5; x2 += x5; 01894 x5 = x3 - x4; x3 += x4; 01895 x4 = x0 - x3; x0 += x3; 01896 x3 = x1 - x2; x1 += x2; 01897 x[0] = x0 + x1; 01898 x[4] = (x0 - x1)*0.70710677f; 01899 x5 = x5 + x6; 01900 x6 = (x6 + x7)*0.70710677f; 01901 x7 = x7 + xt; 01902 x3 = (x3 + x4)*0.70710677f; 01903 x5 -= x7*0.198912367f; /* rotate by PI/8 */ 01904 x7 += x5*0.382683432f; 01905 x5 -= x7*0.198912367f; 01906 x0 = xt - x6; xt += x6; 01907 x[1] = (xt + x7)*0.50979561f; 01908 x[2] = (x4 + x3)*0.54119611f; 01909 x[3] = (x0 - x5)*0.60134488f; 01910 x[5] = (x0 + x5)*0.89997619f; 01911 x[6] = (x4 - x3)*1.30656302f; 01912 x[7] = (xt - x7)*2.56291556f; 01913 01914 } 01915 for (i = 0; i < 7; i++, y += 4*18) 01916 { 01917 y[0*18] = t[0][i]; 01918 y[1*18] = t[2][i] + t[3][i] + t[3][i + 1]; 01919 y[2*18] = t[1][i] + t[1][i + 1]; 01920 y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1]; 01921 } 01922 y[0*18] = t[0][7]; 01923 y[1*18] = t[2][7] + t[3][7]; 01924 y[2*18] = t[1][7]; 01925 y[3*18] = t[3][7]; 01926 } 01927 #endif 01928 } 01929 01930 #ifndef DR_MP3_FLOAT_OUTPUT 01931 typedef drmp3_int16 drmp3d_sample_t; 01932 01933 static drmp3_int16 drmp3d_scale_pcm(float sample) 01934 { 01935 drmp3_int16 s; 01936 #if DRMP3_HAVE_ARMV6 01937 drmp3_int32 s32 = (drmp3_int32)(sample + .5f); 01938 s32 -= (s32 < 0); 01939 s = (drmp3_int16)drmp3_clip_int16_arm(s32); 01940 #else 01941 if (sample >= 32766.5) return (drmp3_int16) 32767; 01942 if (sample <= -32767.5) return (drmp3_int16)-32768; 01943 s = (drmp3_int16)(sample + .5f); 01944 s -= (s < 0); /* away from zero, to be compliant */ 01945 #endif 01946 return s; 01947 } 01948 #else 01949 typedef float drmp3d_sample_t; 01950 01951 static float drmp3d_scale_pcm(float sample) 01952 { 01953 return sample*(1.f/32768.f); 01954 } 01955 #endif 01956 01957 static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z) 01958 { 01959 float a; 01960 a = (z[14*64] - z[ 0]) * 29; 01961 a += (z[ 1*64] + z[13*64]) * 213; 01962 a += (z[12*64] - z[ 2*64]) * 459; 01963 a += (z[ 3*64] + z[11*64]) * 2037; 01964 a += (z[10*64] - z[ 4*64]) * 5153; 01965 a += (z[ 5*64] + z[ 9*64]) * 6574; 01966 a += (z[ 8*64] - z[ 6*64]) * 37489; 01967 a += z[ 7*64] * 75038; 01968 pcm[0] = drmp3d_scale_pcm(a); 01969 01970 z += 2; 01971 a = z[14*64] * 104; 01972 a += z[12*64] * 1567; 01973 a += z[10*64] * 9727; 01974 a += z[ 8*64] * 64019; 01975 a += z[ 6*64] * -9975; 01976 a += z[ 4*64] * -45; 01977 a += z[ 2*64] * 146; 01978 a += z[ 0*64] * -5; 01979 pcm[16*nch] = drmp3d_scale_pcm(a); 01980 } 01981 01982 static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins) 01983 { 01984 int i; 01985 float *xr = xl + 576*(nch - 1); 01986 drmp3d_sample_t *dstr = dstl + (nch - 1); 01987 01988 static const float g_win[] = { 01989 -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992, 01990 -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856, 01991 -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630, 01992 -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313, 01993 -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908, 01994 -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415, 01995 -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835, 01996 -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169, 01997 -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420, 01998 -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590, 01999 -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679, 02000 -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692, 02001 -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629, 02002 -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494, 02003 -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290 02004 }; 02005 float *zlin = lins + 15*64; 02006 const float *w = g_win; 02007 02008 zlin[4*15] = xl[18*16]; 02009 zlin[4*15 + 1] = xr[18*16]; 02010 zlin[4*15 + 2] = xl[0]; 02011 zlin[4*15 + 3] = xr[0]; 02012 02013 zlin[4*31] = xl[1 + 18*16]; 02014 zlin[4*31 + 1] = xr[1 + 18*16]; 02015 zlin[4*31 + 2] = xl[1]; 02016 zlin[4*31 + 3] = xr[1]; 02017 02018 drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1); 02019 drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1); 02020 drmp3d_synth_pair(dstl, nch, lins + 4*15); 02021 drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64); 02022 02023 #if DRMP3_HAVE_SIMD 02024 if (drmp3_have_simd()) for (i = 14; i >= 0; i--) 02025 { 02026 #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)]); 02027 #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)); } 02028 #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))); } 02029 #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))); } 02030 drmp3_f4 a, b; 02031 zlin[4*i] = xl[18*(31 - i)]; 02032 zlin[4*i + 1] = xr[18*(31 - i)]; 02033 zlin[4*i + 2] = xl[1 + 18*(31 - i)]; 02034 zlin[4*i + 3] = xr[1 + 18*(31 - i)]; 02035 zlin[4*i + 64] = xl[1 + 18*(1 + i)]; 02036 zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)]; 02037 zlin[4*i - 64 + 2] = xl[18*(1 + i)]; 02038 zlin[4*i - 64 + 3] = xr[18*(1 + i)]; 02039 02040 DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7) 02041 02042 { 02043 #ifndef DR_MP3_FLOAT_OUTPUT 02044 #if DRMP3_HAVE_SSE 02045 static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; 02046 static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; 02047 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), 02048 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); 02049 dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1); 02050 dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5); 02051 dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0); 02052 dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4); 02053 dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3); 02054 dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7); 02055 dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2); 02056 dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6); 02057 #else 02058 int16x4_t pcma, pcmb; 02059 a = DRMP3_VADD(a, DRMP3_VSET(0.5f)); 02060 b = DRMP3_VADD(b, DRMP3_VSET(0.5f)); 02061 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0))))); 02062 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0))))); 02063 vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1); 02064 vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1); 02065 vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0); 02066 vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0); 02067 vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3); 02068 vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3); 02069 vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2); 02070 vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); 02071 #endif 02072 #else 02073 static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; 02074 a = DRMP3_VMUL(a, g_scale); 02075 b = DRMP3_VMUL(b, g_scale); 02076 #if DRMP3_HAVE_SSE 02077 _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))); 02078 _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1))); 02079 _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0))); 02080 _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0))); 02081 _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3))); 02082 _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3))); 02083 _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); 02084 _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2))); 02085 #else 02086 vst1q_lane_f32(dstr + (15 - i)*nch, a, 1); 02087 vst1q_lane_f32(dstr + (17 + i)*nch, b, 1); 02088 vst1q_lane_f32(dstl + (15 - i)*nch, a, 0); 02089 vst1q_lane_f32(dstl + (17 + i)*nch, b, 0); 02090 vst1q_lane_f32(dstr + (47 - i)*nch, a, 3); 02091 vst1q_lane_f32(dstr + (49 + i)*nch, b, 3); 02092 vst1q_lane_f32(dstl + (47 - i)*nch, a, 2); 02093 vst1q_lane_f32(dstl + (49 + i)*nch, b, 2); 02094 #endif 02095 #endif /* DR_MP3_FLOAT_OUTPUT */ 02096 } 02097 } else 02098 #endif 02099 #ifdef DR_MP3_ONLY_SIMD 02100 {} 02101 #else 02102 for (i = 14; i >= 0; i--) 02103 { 02104 #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]; 02105 #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; } 02106 #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; } 02107 #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; } 02108 float a[4], b[4]; 02109 02110 zlin[4*i] = xl[18*(31 - i)]; 02111 zlin[4*i + 1] = xr[18*(31 - i)]; 02112 zlin[4*i + 2] = xl[1 + 18*(31 - i)]; 02113 zlin[4*i + 3] = xr[1 + 18*(31 - i)]; 02114 zlin[4*(i + 16)] = xl[1 + 18*(1 + i)]; 02115 zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)]; 02116 zlin[4*(i - 16) + 2] = xl[18*(1 + i)]; 02117 zlin[4*(i - 16) + 3] = xr[18*(1 + i)]; 02118 02119 DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7) 02120 02121 dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]); 02122 dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]); 02123 dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]); 02124 dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]); 02125 dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]); 02126 dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]); 02127 dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]); 02128 dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]); 02129 } 02130 #endif 02131 } 02132 02133 static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins) 02134 { 02135 int i; 02136 for (i = 0; i < nch; i++) 02137 { 02138 drmp3d_DCT_II(grbuf + 576*i, nbands); 02139 } 02140 02141 memcpy(lins, qmf_state, sizeof(float)*15*64); 02142 02143 for (i = 0; i < nbands; i += 2) 02144 { 02145 drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64); 02146 } 02147 #ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL 02148 if (nch == 1) 02149 { 02150 for (i = 0; i < 15*64; i += 2) 02151 { 02152 qmf_state[i] = lins[nbands*64 + i]; 02153 } 02154 } else 02155 #endif 02156 { 02157 memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); 02158 } 02159 } 02160 02161 static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes) 02162 { 02163 int i, nmatch; 02164 for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++) 02165 { 02166 i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i); 02167 if (i + DRMP3_HDR_SIZE > mp3_bytes) 02168 return nmatch > 0; 02169 if (!drmp3_hdr_compare(hdr, hdr + i)) 02170 return 0; 02171 } 02172 return 1; 02173 } 02174 02175 static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes) 02176 { 02177 int i, k; 02178 for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++) 02179 { 02180 if (drmp3_hdr_valid(mp3)) 02181 { 02182 int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes); 02183 int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3); 02184 02185 for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++) 02186 { 02187 if (drmp3_hdr_compare(mp3, mp3 + k)) 02188 { 02189 int fb = k - drmp3_hdr_padding(mp3); 02190 int nextfb = fb + drmp3_hdr_padding(mp3 + k); 02191 if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb)) 02192 continue; 02193 frame_and_padding = k; 02194 frame_bytes = fb; 02195 *free_format_bytes = fb; 02196 } 02197 } 02198 02199 if ((frame_bytes && i + frame_and_padding <= mp3_bytes && 02200 drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) || 02201 (!i && frame_and_padding == mp3_bytes)) 02202 { 02203 *ptr_frame_bytes = frame_and_padding; 02204 return i; 02205 } 02206 *free_format_bytes = 0; 02207 } 02208 } 02209 *ptr_frame_bytes = 0; 02210 return mp3_bytes; 02211 } 02212 02213 DRMP3_API void drmp3dec_init(drmp3dec *dec) 02214 { 02215 dec->header[0] = 0; 02216 } 02217 02218 DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info) 02219 { 02220 int i = 0, igr, frame_size = 0, success = 1; 02221 const drmp3_uint8 *hdr; 02222 drmp3_bs bs_frame[1]; 02223 drmp3dec_scratch scratch; 02224 02225 if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3)) 02226 { 02227 frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3); 02228 if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size))) 02229 { 02230 frame_size = 0; 02231 } 02232 } 02233 if (!frame_size) 02234 { 02235 memset(dec, 0, sizeof(drmp3dec)); 02236 i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); 02237 if (!frame_size || i + frame_size > mp3_bytes) 02238 { 02239 info->frame_bytes = i; 02240 return 0; 02241 } 02242 } 02243 02244 hdr = mp3 + i; 02245 memcpy(dec->header, hdr, DRMP3_HDR_SIZE); 02246 info->frame_bytes = i + frame_size; 02247 info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; 02248 info->hz = drmp3_hdr_sample_rate_hz(hdr); 02249 info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr); 02250 info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr); 02251 02252 drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE); 02253 if (DRMP3_HDR_IS_CRC(hdr)) 02254 { 02255 drmp3_bs_get_bits(bs_frame, 16); 02256 } 02257 02258 if (info->layer == 3) 02259 { 02260 int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); 02261 if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) 02262 { 02263 drmp3dec_init(dec); 02264 return 0; 02265 } 02266 success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); 02267 if (success && pcm != NULL) 02268 { 02269 for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels)) 02270 { 02271 memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); 02272 drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); 02273 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); 02274 } 02275 } 02276 drmp3_L3_save_reservoir(dec, &scratch); 02277 } else 02278 { 02279 #ifdef DR_MP3_ONLY_MP3 02280 return 0; 02281 #else 02282 drmp3_L12_scale_info sci[1]; 02283 02284 if (pcm == NULL) { 02285 return drmp3_hdr_frame_samples(hdr); 02286 } 02287 02288 drmp3_L12_read_scale_info(hdr, bs_frame, sci); 02289 02290 memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); 02291 for (i = 0, igr = 0; igr < 3; igr++) 02292 { 02293 if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) 02294 { 02295 i = 0; 02296 drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); 02297 drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); 02298 memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); 02299 pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels); 02300 } 02301 if (bs_frame->pos > bs_frame->limit) 02302 { 02303 drmp3dec_init(dec); 02304 return 0; 02305 } 02306 } 02307 #endif 02308 } 02309 02310 return success*drmp3_hdr_frame_samples(dec->header); 02311 } 02312 02313 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples) 02314 { 02315 size_t i = 0; 02316 #if DRMP3_HAVE_SIMD 02317 size_t aligned_count = num_samples & ~7; 02318 for(; i < aligned_count; i+=8) 02319 { 02320 drmp3_f4 scale = DRMP3_VSET(32768.0f); 02321 drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale); 02322 drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale); 02323 #if DRMP3_HAVE_SSE 02324 drmp3_f4 s16max = DRMP3_VSET( 32767.0f); 02325 drmp3_f4 s16min = DRMP3_VSET(-32768.0f); 02326 __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)), 02327 _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min))); 02328 out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0); 02329 out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1); 02330 out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2); 02331 out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3); 02332 out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4); 02333 out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5); 02334 out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6); 02335 out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7); 02336 #else 02337 int16x4_t pcma, pcmb; 02338 a = DRMP3_VADD(a, DRMP3_VSET(0.5f)); 02339 b = DRMP3_VADD(b, DRMP3_VSET(0.5f)); 02340 pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0))))); 02341 pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0))))); 02342 vst1_lane_s16(out+i , pcma, 0); 02343 vst1_lane_s16(out+i+1, pcma, 1); 02344 vst1_lane_s16(out+i+2, pcma, 2); 02345 vst1_lane_s16(out+i+3, pcma, 3); 02346 vst1_lane_s16(out+i+4, pcmb, 0); 02347 vst1_lane_s16(out+i+5, pcmb, 1); 02348 vst1_lane_s16(out+i+6, pcmb, 2); 02349 vst1_lane_s16(out+i+7, pcmb, 3); 02350 #endif 02351 } 02352 #endif 02353 for(; i < num_samples; i++) 02354 { 02355 float sample = in[i] * 32768.0f; 02356 if (sample >= 32766.5) 02357 out[i] = (drmp3_int16) 32767; 02358 else if (sample <= -32767.5) 02359 out[i] = (drmp3_int16)-32768; 02360 else 02361 { 02362 short s = (drmp3_int16)(sample + .5f); 02363 s -= (s < 0); /* away from zero, to be compliant */ 02364 out[i] = s; 02365 } 02366 } 02367 } 02368 02369 02370 02371 /************************************************************************************************************************************************************ 02372 02373 Main Public API 02374 02375 ************************************************************************************************************************************************************/ 02376 #include <math.h> /* For sin() and exp(). */ 02377 02378 #if defined(SIZE_MAX) 02379 #define DRMP3_SIZE_MAX SIZE_MAX 02380 #else 02381 #if defined(_WIN64) || defined(_LP64) || defined(__LP64__) 02382 #define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF) 02383 #else 02384 #define DRMP3_SIZE_MAX 0xFFFFFFFF 02385 #endif 02386 #endif 02387 02388 /* Options. */ 02389 #ifndef DRMP3_SEEK_LEADING_MP3_FRAMES 02390 #define DRMP3_SEEK_LEADING_MP3_FRAMES 2 02391 #endif 02392 02393 #define DRMP3_MIN_DATA_CHUNK_SIZE 16384 02394 02395 /* 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. */ 02396 #ifndef DRMP3_DATA_CHUNK_SIZE 02397 #define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4 02398 #endif 02399 02400 02401 /* Standard library stuff. */ 02402 #ifndef DRMP3_ASSERT 02403 #include <assert.h> 02404 #define DRMP3_ASSERT(expression) assert(expression) 02405 #endif 02406 #ifndef DRMP3_COPY_MEMORY 02407 #define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) 02408 #endif 02409 #ifndef DRMP3_ZERO_MEMORY 02410 #define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) 02411 #endif 02412 #define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p))) 02413 #ifndef DRMP3_MALLOC 02414 #define DRMP3_MALLOC(sz) malloc((sz)) 02415 #endif 02416 #ifndef DRMP3_REALLOC 02417 #define DRMP3_REALLOC(p, sz) realloc((p), (sz)) 02418 #endif 02419 #ifndef DRMP3_FREE 02420 #define DRMP3_FREE(p) free((p)) 02421 #endif 02422 02423 #define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0])) 02424 #define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi))) 02425 02426 #ifndef DRMP3_PI_D 02427 #define DRMP3_PI_D 3.14159265358979323846264 02428 #endif 02429 02430 #define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2 02431 02432 static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a) 02433 { 02434 return x*(1-a) + y*a; 02435 } 02436 static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a) 02437 { 02438 float r0 = (y - x); 02439 float r1 = r0*a; 02440 return x + r1; 02441 /*return x + (y - x)*a;*/ 02442 } 02443 02444 02445 /* 02446 Greatest common factor using Euclid's algorithm iteratively. 02447 */ 02448 static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b) 02449 { 02450 for (;;) { 02451 if (b == 0) { 02452 break; 02453 } else { 02454 drmp3_uint32 t = a; 02455 a = b; 02456 b = t % a; 02457 } 02458 } 02459 02460 return a; 02461 } 02462 02463 02464 static DRMP3_INLINE double drmp3_sin(double x) 02465 { 02466 /* TODO: Implement custom sin(x). */ 02467 return sin(x); 02468 } 02469 02470 static DRMP3_INLINE double drmp3_exp(double x) 02471 { 02472 /* TODO: Implement custom exp(x). */ 02473 return exp(x); 02474 } 02475 02476 static DRMP3_INLINE double drmp3_cos(double x) 02477 { 02478 return drmp3_sin((DRMP3_PI_D*0.5) - x); 02479 } 02480 02481 02482 static void* drmp3__malloc_default(size_t sz, void* pUserData) 02483 { 02484 (void)pUserData; 02485 return DRMP3_MALLOC(sz); 02486 } 02487 02488 static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData) 02489 { 02490 (void)pUserData; 02491 return DRMP3_REALLOC(p, sz); 02492 } 02493 02494 static void drmp3__free_default(void* p, void* pUserData) 02495 { 02496 (void)pUserData; 02497 DRMP3_FREE(p); 02498 } 02499 02500 02501 static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) 02502 { 02503 if (pAllocationCallbacks == NULL) { 02504 return NULL; 02505 } 02506 02507 if (pAllocationCallbacks->onMalloc != NULL) { 02508 return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData); 02509 } 02510 02511 /* Try using realloc(). */ 02512 if (pAllocationCallbacks->onRealloc != NULL) { 02513 return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData); 02514 } 02515 02516 return NULL; 02517 } 02518 02519 static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks) 02520 { 02521 if (pAllocationCallbacks == NULL) { 02522 return NULL; 02523 } 02524 02525 if (pAllocationCallbacks->onRealloc != NULL) { 02526 return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData); 02527 } 02528 02529 /* Try emulating realloc() in terms of malloc()/free(). */ 02530 if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) { 02531 void* p2; 02532 02533 p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData); 02534 if (p2 == NULL) { 02535 return NULL; 02536 } 02537 02538 if (p != NULL) { 02539 DRMP3_COPY_MEMORY(p2, p, szOld); 02540 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData); 02541 } 02542 02543 return p2; 02544 } 02545 02546 return NULL; 02547 } 02548 02549 static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks) 02550 { 02551 if (p == NULL || pAllocationCallbacks == NULL) { 02552 return; 02553 } 02554 02555 if (pAllocationCallbacks->onFree != NULL) { 02556 pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData); 02557 } 02558 } 02559 02560 02561 static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks) 02562 { 02563 if (pAllocationCallbacks != NULL) { 02564 /* Copy. */ 02565 return *pAllocationCallbacks; 02566 } else { 02567 /* Defaults. */ 02568 drmp3_allocation_callbacks allocationCallbacks; 02569 allocationCallbacks.pUserData = NULL; 02570 allocationCallbacks.onMalloc = drmp3__malloc_default; 02571 allocationCallbacks.onRealloc = drmp3__realloc_default; 02572 allocationCallbacks.onFree = drmp3__free_default; 02573 return allocationCallbacks; 02574 } 02575 } 02576 02577 02578 02579 static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead) 02580 { 02581 size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead); 02582 pMP3->streamCursor += bytesRead; 02583 return bytesRead; 02584 } 02585 02586 static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin) 02587 { 02588 DRMP3_ASSERT(offset >= 0); 02589 02590 if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) { 02591 return DRMP3_FALSE; 02592 } 02593 02594 if (origin == drmp3_seek_origin_start) { 02595 pMP3->streamCursor = (drmp3_uint64)offset; 02596 } else { 02597 pMP3->streamCursor += offset; 02598 } 02599 02600 return DRMP3_TRUE; 02601 } 02602 02603 static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin) 02604 { 02605 if (offset <= 0x7FFFFFFF) { 02606 return drmp3__on_seek(pMP3, (int)offset, origin); 02607 } 02608 02609 02610 /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */ 02611 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) { 02612 return DRMP3_FALSE; 02613 } 02614 02615 offset -= 0x7FFFFFFF; 02616 while (offset > 0) { 02617 if (offset <= 0x7FFFFFFF) { 02618 if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) { 02619 return DRMP3_FALSE; 02620 } 02621 offset = 0; 02622 } else { 02623 if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) { 02624 return DRMP3_FALSE; 02625 } 02626 offset -= 0x7FFFFFFF; 02627 } 02628 } 02629 02630 return DRMP3_TRUE; 02631 } 02632 02633 02634 static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) 02635 { 02636 drmp3_uint32 pcmFramesRead = 0; 02637 02638 DRMP3_ASSERT(pMP3 != NULL); 02639 DRMP3_ASSERT(pMP3->onRead != NULL); 02640 02641 if (pMP3->atEnd) { 02642 return 0; 02643 } 02644 02645 for (;;) { 02646 drmp3dec_frame_info info; 02647 02648 /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */ 02649 if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) { 02650 size_t bytesRead; 02651 02652 /* First we need to move the data down. */ 02653 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); 02654 pMP3->dataConsumed = 0; 02655 02656 if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) { 02657 drmp3_uint8* pNewData; 02658 size_t newDataCap; 02659 02660 newDataCap = DRMP3_DATA_CHUNK_SIZE; 02661 02662 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks); 02663 if (pNewData == NULL) { 02664 return 0; /* Out of memory. */ 02665 } 02666 02667 pMP3->pData = pNewData; 02668 pMP3->dataCapacity = newDataCap; 02669 } 02670 02671 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); 02672 if (bytesRead == 0) { 02673 if (pMP3->dataSize == 0) { 02674 pMP3->atEnd = DRMP3_TRUE; 02675 return 0; /* No data. */ 02676 } 02677 } 02678 02679 pMP3->dataSize += bytesRead; 02680 } 02681 02682 if (pMP3->dataSize > INT_MAX) { 02683 pMP3->atEnd = DRMP3_TRUE; 02684 return 0; /* File too big. */ 02685 } 02686 02687 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. */ 02688 02689 /* Consume the data. */ 02690 if (info.frame_bytes > 0) { 02691 pMP3->dataConsumed += (size_t)info.frame_bytes; 02692 pMP3->dataSize -= (size_t)info.frame_bytes; 02693 } 02694 02695 /* 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. */ 02696 if (pcmFramesRead > 0) { 02697 pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header); 02698 pMP3->pcmFramesConsumedInMP3Frame = 0; 02699 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; 02700 pMP3->mp3FrameChannels = info.channels; 02701 pMP3->mp3FrameSampleRate = info.hz; 02702 break; 02703 } else if (info.frame_bytes == 0) { 02704 /* Need more data. minimp3 recommends doing data submission in 16K chunks. */ 02705 size_t bytesRead; 02706 02707 /* First we need to move the data down. */ 02708 memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); 02709 pMP3->dataConsumed = 0; 02710 02711 if (pMP3->dataCapacity == pMP3->dataSize) { 02712 /* No room. Expand. */ 02713 drmp3_uint8* pNewData; 02714 size_t newDataCap; 02715 02716 newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE; 02717 02718 pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks); 02719 if (pNewData == NULL) { 02720 return 0; /* Out of memory. */ 02721 } 02722 02723 pMP3->pData = pNewData; 02724 pMP3->dataCapacity = newDataCap; 02725 } 02726 02727 /* Fill in a chunk. */ 02728 bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); 02729 if (bytesRead == 0) { 02730 pMP3->atEnd = DRMP3_TRUE; 02731 return 0; /* Error reading more data. */ 02732 } 02733 02734 pMP3->dataSize += bytesRead; 02735 } 02736 }; 02737 02738 return pcmFramesRead; 02739 } 02740 02741 static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) 02742 { 02743 drmp3_uint32 pcmFramesRead = 0; 02744 drmp3dec_frame_info info; 02745 02746 DRMP3_ASSERT(pMP3 != NULL); 02747 DRMP3_ASSERT(pMP3->memory.pData != NULL); 02748 02749 if (pMP3->atEnd) { 02750 return 0; 02751 } 02752 02753 pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info); 02754 if (pcmFramesRead > 0) { 02755 pMP3->pcmFramesConsumedInMP3Frame = 0; 02756 pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; 02757 pMP3->mp3FrameChannels = info.channels; 02758 pMP3->mp3FrameSampleRate = info.hz; 02759 } 02760 02761 /* Consume the data. */ 02762 pMP3->memory.currentReadPos += (size_t)info.frame_bytes; 02763 02764 return pcmFramesRead; 02765 } 02766 02767 static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) 02768 { 02769 if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) { 02770 return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames); 02771 } else { 02772 return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames); 02773 } 02774 } 02775 02776 static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3) 02777 { 02778 DRMP3_ASSERT(pMP3 != NULL); 02779 return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames); 02780 } 02781 02782 #if 0 02783 static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3) 02784 { 02785 drmp3_uint32 pcmFrameCount; 02786 02787 DRMP3_ASSERT(pMP3 != NULL); 02788 02789 pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL); 02790 if (pcmFrameCount == 0) { 02791 return 0; 02792 } 02793 02794 /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */ 02795 pMP3->currentPCMFrame += pcmFrameCount; 02796 pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount; 02797 pMP3->pcmFramesRemainingInMP3Frame = 0; 02798 02799 return pcmFrameCount; 02800 } 02801 #endif 02802 02803 static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) 02804 { 02805 DRMP3_ASSERT(pMP3 != NULL); 02806 DRMP3_ASSERT(onRead != NULL); 02807 02808 /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */ 02809 drmp3dec_init(&pMP3->decoder); 02810 02811 pMP3->onRead = onRead; 02812 pMP3->onSeek = onSeek; 02813 pMP3->pUserData = pUserData; 02814 pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks); 02815 02816 if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) { 02817 return DRMP3_FALSE; /* Invalid allocation callbacks. */ 02818 } 02819 02820 /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */ 02821 if (!drmp3_decode_next_frame(pMP3)) { 02822 drmp3_uninit(pMP3); 02823 return DRMP3_FALSE; /* Not a valid MP3 stream. */ 02824 } 02825 02826 pMP3->channels = pMP3->mp3FrameChannels; 02827 pMP3->sampleRate = pMP3->mp3FrameSampleRate; 02828 02829 return DRMP3_TRUE; 02830 } 02831 02832 DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) 02833 { 02834 if (pMP3 == NULL || onRead == NULL) { 02835 return DRMP3_FALSE; 02836 } 02837 02838 DRMP3_ZERO_OBJECT(pMP3); 02839 return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks); 02840 } 02841 02842 02843 static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead) 02844 { 02845 drmp3* pMP3 = (drmp3*)pUserData; 02846 size_t bytesRemaining; 02847 02848 DRMP3_ASSERT(pMP3 != NULL); 02849 DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos); 02850 02851 bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos; 02852 if (bytesToRead > bytesRemaining) { 02853 bytesToRead = bytesRemaining; 02854 } 02855 02856 if (bytesToRead > 0) { 02857 DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead); 02858 pMP3->memory.currentReadPos += bytesToRead; 02859 } 02860 02861 return bytesToRead; 02862 } 02863 02864 static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin) 02865 { 02866 drmp3* pMP3 = (drmp3*)pUserData; 02867 02868 DRMP3_ASSERT(pMP3 != NULL); 02869 02870 if (origin == drmp3_seek_origin_current) { 02871 if (byteOffset > 0) { 02872 if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) { 02873 byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */ 02874 } 02875 } else { 02876 if (pMP3->memory.currentReadPos < (size_t)-byteOffset) { 02877 byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */ 02878 } 02879 } 02880 02881 /* This will never underflow thanks to the clamps above. */ 02882 pMP3->memory.currentReadPos += byteOffset; 02883 } else { 02884 if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) { 02885 pMP3->memory.currentReadPos = byteOffset; 02886 } else { 02887 pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */ 02888 } 02889 } 02890 02891 return DRMP3_TRUE; 02892 } 02893 02894 DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks) 02895 { 02896 if (pMP3 == NULL) { 02897 return DRMP3_FALSE; 02898 } 02899 02900 DRMP3_ZERO_OBJECT(pMP3); 02901 02902 if (pData == NULL || dataSize == 0) { 02903 return DRMP3_FALSE; 02904 } 02905 02906 pMP3->memory.pData = (const drmp3_uint8*)pData; 02907 pMP3->memory.dataSize = dataSize; 02908 pMP3->memory.currentReadPos = 0; 02909 02910 return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks); 02911 } 02912 02913 02914 #ifndef DR_MP3_NO_STDIO 02915 #include <stdio.h> 02916 #include <wchar.h> /* For wcslen(), wcsrtombs() */ 02917 02918 /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */ 02919 #include <errno.h> 02920 static drmp3_result drmp3_result_from_errno(int e) 02921 { 02922 switch (e) 02923 { 02924 case 0: return DRMP3_SUCCESS; 02925 #ifdef EPERM 02926 case EPERM: return DRMP3_INVALID_OPERATION; 02927 #endif 02928 #ifdef ENOENT 02929 case ENOENT: return DRMP3_DOES_NOT_EXIST; 02930 #endif 02931 #ifdef ESRCH 02932 case ESRCH: return DRMP3_DOES_NOT_EXIST; 02933 #endif 02934 #ifdef EINTR 02935 case EINTR: return DRMP3_INTERRUPT; 02936 #endif 02937 #ifdef EIO 02938 case EIO: return DRMP3_IO_ERROR; 02939 #endif 02940 #ifdef ENXIO 02941 case ENXIO: return DRMP3_DOES_NOT_EXIST; 02942 #endif 02943 #ifdef E2BIG 02944 case E2BIG: return DRMP3_INVALID_ARGS; 02945 #endif 02946 #ifdef ENOEXEC 02947 case ENOEXEC: return DRMP3_INVALID_FILE; 02948 #endif 02949 #ifdef EBADF 02950 case EBADF: return DRMP3_INVALID_FILE; 02951 #endif 02952 #ifdef ECHILD 02953 case ECHILD: return DRMP3_ERROR; 02954 #endif 02955 #ifdef EAGAIN 02956 case EAGAIN: return DRMP3_UNAVAILABLE; 02957 #endif 02958 #ifdef ENOMEM 02959 case ENOMEM: return DRMP3_OUT_OF_MEMORY; 02960 #endif 02961 #ifdef EACCES 02962 case EACCES: return DRMP3_ACCESS_DENIED; 02963 #endif 02964 #ifdef EFAULT 02965 case EFAULT: return DRMP3_BAD_ADDRESS; 02966 #endif 02967 #ifdef ENOTBLK 02968 case ENOTBLK: return DRMP3_ERROR; 02969 #endif 02970 #ifdef EBUSY 02971 case EBUSY: return DRMP3_BUSY; 02972 #endif 02973 #ifdef EEXIST 02974 case EEXIST: return DRMP3_ALREADY_EXISTS; 02975 #endif 02976 #ifdef EXDEV 02977 case EXDEV: return DRMP3_ERROR; 02978 #endif 02979 #ifdef ENODEV 02980 case ENODEV: return DRMP3_DOES_NOT_EXIST; 02981 #endif 02982 #ifdef ENOTDIR 02983 case ENOTDIR: return DRMP3_NOT_DIRECTORY; 02984 #endif 02985 #ifdef EISDIR 02986 case EISDIR: return DRMP3_IS_DIRECTORY; 02987 #endif 02988 #ifdef EINVAL 02989 case EINVAL: return DRMP3_INVALID_ARGS; 02990 #endif 02991 #ifdef ENFILE 02992 case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES; 02993 #endif 02994 #ifdef EMFILE 02995 case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES; 02996 #endif 02997 #ifdef ENOTTY 02998 case ENOTTY: return DRMP3_INVALID_OPERATION; 02999 #endif 03000 #ifdef ETXTBSY 03001 case ETXTBSY: return DRMP3_BUSY; 03002 #endif 03003 #ifdef EFBIG 03004 case EFBIG: return DRMP3_TOO_BIG; 03005 #endif 03006 #ifdef ENOSPC 03007 case ENOSPC: return DRMP3_NO_SPACE; 03008 #endif 03009 #ifdef ESPIPE 03010 case ESPIPE: return DRMP3_BAD_SEEK; 03011 #endif 03012 #ifdef EROFS 03013 case EROFS: return DRMP3_ACCESS_DENIED; 03014 #endif 03015 #ifdef EMLINK 03016 case EMLINK: return DRMP3_TOO_MANY_LINKS; 03017 #endif 03018 #ifdef EPIPE 03019 case EPIPE: return DRMP3_BAD_PIPE; 03020 #endif 03021 #ifdef EDOM 03022 case EDOM: return DRMP3_OUT_OF_RANGE; 03023 #endif 03024 #ifdef ERANGE 03025 case ERANGE: return DRMP3_OUT_OF_RANGE; 03026 #endif 03027 #ifdef EDEADLK 03028 case EDEADLK: return DRMP3_DEADLOCK; 03029 #endif 03030 #ifdef ENAMETOOLONG 03031 case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG; 03032 #endif 03033 #ifdef ENOLCK 03034 case ENOLCK: return DRMP3_ERROR; 03035 #endif 03036 #ifdef ENOSYS 03037 case ENOSYS: return DRMP3_NOT_IMPLEMENTED; 03038 #endif 03039 #ifdef ENOTEMPTY 03040 case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY; 03041 #endif 03042 #ifdef ELOOP 03043 case ELOOP: return DRMP3_TOO_MANY_LINKS; 03044 #endif 03045 #ifdef ENOMSG 03046 case ENOMSG: return DRMP3_NO_MESSAGE; 03047 #endif 03048 #ifdef EIDRM 03049 case EIDRM: return DRMP3_ERROR; 03050 #endif 03051 #ifdef ECHRNG 03052 case ECHRNG: return DRMP3_ERROR; 03053 #endif 03054 #ifdef EL2NSYNC 03055 case EL2NSYNC: return DRMP3_ERROR; 03056 #endif 03057 #ifdef EL3HLT 03058 case EL3HLT: return DRMP3_ERROR; 03059 #endif 03060 #ifdef EL3RST 03061 case EL3RST: return DRMP3_ERROR; 03062 #endif 03063 #ifdef ELNRNG 03064 case ELNRNG: return DRMP3_OUT_OF_RANGE; 03065 #endif 03066 #ifdef EUNATCH 03067 case EUNATCH: return DRMP3_ERROR; 03068 #endif 03069 #ifdef ENOCSI 03070 case ENOCSI: return DRMP3_ERROR; 03071 #endif 03072 #ifdef EL2HLT 03073 case EL2HLT: return DRMP3_ERROR; 03074 #endif 03075 #ifdef EBADE 03076 case EBADE: return DRMP3_ERROR; 03077 #endif 03078 #ifdef EBADR 03079 case EBADR: return DRMP3_ERROR; 03080 #endif 03081 #ifdef EXFULL 03082 case EXFULL: return DRMP3_ERROR; 03083 #endif 03084 #ifdef ENOANO 03085 case ENOANO: return DRMP3_ERROR; 03086 #endif 03087 #ifdef EBADRQC 03088 case EBADRQC: return DRMP3_ERROR; 03089 #endif 03090 #ifdef EBADSLT 03091 case EBADSLT: return DRMP3_ERROR; 03092 #endif 03093 #ifdef EBFONT 03094 case EBFONT: return DRMP3_INVALID_FILE; 03095 #endif 03096 #ifdef ENOSTR 03097 case ENOSTR: return DRMP3_ERROR; 03098 #endif 03099 #ifdef ENODATA 03100 case ENODATA: return DRMP3_NO_DATA_AVAILABLE; 03101 #endif 03102 #ifdef ETIME 03103 case ETIME: return DRMP3_TIMEOUT; 03104 #endif 03105 #ifdef ENOSR 03106 case ENOSR: return DRMP3_NO_DATA_AVAILABLE; 03107 #endif 03108 #ifdef ENONET 03109 case ENONET: return DRMP3_NO_NETWORK; 03110 #endif 03111 #ifdef ENOPKG 03112 case ENOPKG: return DRMP3_ERROR; 03113 #endif 03114 #ifdef EREMOTE 03115 case EREMOTE: return DRMP3_ERROR; 03116 #endif 03117 #ifdef ENOLINK 03118 case ENOLINK: return DRMP3_ERROR; 03119 #endif 03120 #ifdef EADV 03121 case EADV: return DRMP3_ERROR; 03122 #endif 03123 #ifdef ESRMNT 03124 case ESRMNT: return DRMP3_ERROR; 03125 #endif 03126 #ifdef ECOMM 03127 case ECOMM: return DRMP3_ERROR; 03128 #endif 03129 #ifdef EPROTO 03130 case EPROTO: return DRMP3_ERROR; 03131 #endif 03132 #ifdef EMULTIHOP 03133 case EMULTIHOP: return DRMP3_ERROR; 03134 #endif 03135 #ifdef EDOTDOT 03136 case EDOTDOT: return DRMP3_ERROR; 03137 #endif 03138 #ifdef EBADMSG 03139 case EBADMSG: return DRMP3_BAD_MESSAGE; 03140 #endif 03141 #ifdef EOVERFLOW 03142 case EOVERFLOW: return DRMP3_TOO_BIG; 03143 #endif 03144 #ifdef ENOTUNIQ 03145 case ENOTUNIQ: return DRMP3_NOT_UNIQUE; 03146 #endif 03147 #ifdef EBADFD 03148 case EBADFD: return DRMP3_ERROR; 03149 #endif 03150 #ifdef EREMCHG 03151 case EREMCHG: return DRMP3_ERROR; 03152 #endif 03153 #ifdef ELIBACC 03154 case ELIBACC: return DRMP3_ACCESS_DENIED; 03155 #endif 03156 #ifdef ELIBBAD 03157 case ELIBBAD: return DRMP3_INVALID_FILE; 03158 #endif 03159 #ifdef ELIBSCN 03160 case ELIBSCN: return DRMP3_INVALID_FILE; 03161 #endif 03162 #ifdef ELIBMAX 03163 case ELIBMAX: return DRMP3_ERROR; 03164 #endif 03165 #ifdef ELIBEXEC 03166 case ELIBEXEC: return DRMP3_ERROR; 03167 #endif 03168 #ifdef EILSEQ 03169 case EILSEQ: return DRMP3_INVALID_DATA; 03170 #endif 03171 #ifdef ERESTART 03172 case ERESTART: return DRMP3_ERROR; 03173 #endif 03174 #ifdef ESTRPIPE 03175 case ESTRPIPE: return DRMP3_ERROR; 03176 #endif 03177 #ifdef EUSERS 03178 case EUSERS: return DRMP3_ERROR; 03179 #endif 03180 #ifdef ENOTSOCK 03181 case ENOTSOCK: return DRMP3_NOT_SOCKET; 03182 #endif 03183 #ifdef EDESTADDRREQ 03184 case EDESTADDRREQ: return DRMP3_NO_ADDRESS; 03185 #endif 03186 #ifdef EMSGSIZE 03187 case EMSGSIZE: return DRMP3_TOO_BIG; 03188 #endif 03189 #ifdef EPROTOTYPE 03190 case EPROTOTYPE: return DRMP3_BAD_PROTOCOL; 03191 #endif 03192 #ifdef ENOPROTOOPT 03193 case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE; 03194 #endif 03195 #ifdef EPROTONOSUPPORT 03196 case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED; 03197 #endif 03198 #ifdef ESOCKTNOSUPPORT 03199 case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED; 03200 #endif 03201 #ifdef EOPNOTSUPP 03202 case EOPNOTSUPP: return DRMP3_INVALID_OPERATION; 03203 #endif 03204 #ifdef EPFNOSUPPORT 03205 case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED; 03206 #endif 03207 #ifdef EAFNOSUPPORT 03208 case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED; 03209 #endif 03210 #ifdef EADDRINUSE 03211 case EADDRINUSE: return DRMP3_ALREADY_IN_USE; 03212 #endif 03213 #ifdef EADDRNOTAVAIL 03214 case EADDRNOTAVAIL: return DRMP3_ERROR; 03215 #endif 03216 #ifdef ENETDOWN 03217 case ENETDOWN: return DRMP3_NO_NETWORK; 03218 #endif 03219 #ifdef ENETUNREACH 03220 case ENETUNREACH: return DRMP3_NO_NETWORK; 03221 #endif 03222 #ifdef ENETRESET 03223 case ENETRESET: return DRMP3_NO_NETWORK; 03224 #endif 03225 #ifdef ECONNABORTED 03226 case ECONNABORTED: return DRMP3_NO_NETWORK; 03227 #endif 03228 #ifdef ECONNRESET 03229 case ECONNRESET: return DRMP3_CONNECTION_RESET; 03230 #endif 03231 #ifdef ENOBUFS 03232 case ENOBUFS: return DRMP3_NO_SPACE; 03233 #endif 03234 #ifdef EISCONN 03235 case EISCONN: return DRMP3_ALREADY_CONNECTED; 03236 #endif 03237 #ifdef ENOTCONN 03238 case ENOTCONN: return DRMP3_NOT_CONNECTED; 03239 #endif 03240 #ifdef ESHUTDOWN 03241 case ESHUTDOWN: return DRMP3_ERROR; 03242 #endif 03243 #ifdef ETOOMANYREFS 03244 case ETOOMANYREFS: return DRMP3_ERROR; 03245 #endif 03246 #ifdef ETIMEDOUT 03247 case ETIMEDOUT: return DRMP3_TIMEOUT; 03248 #endif 03249 #ifdef ECONNREFUSED 03250 case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED; 03251 #endif 03252 #ifdef EHOSTDOWN 03253 case EHOSTDOWN: return DRMP3_NO_HOST; 03254 #endif 03255 #ifdef EHOSTUNREACH 03256 case EHOSTUNREACH: return DRMP3_NO_HOST; 03257 #endif 03258 #ifdef EALREADY 03259 case EALREADY: return DRMP3_IN_PROGRESS; 03260 #endif 03261 #ifdef EINPROGRESS 03262 case EINPROGRESS: return DRMP3_IN_PROGRESS; 03263 #endif 03264 #ifdef ESTALE 03265 case ESTALE: return DRMP3_INVALID_FILE; 03266 #endif 03267 #ifdef EUCLEAN 03268 case EUCLEAN: return DRMP3_ERROR; 03269 #endif 03270 #ifdef ENOTNAM 03271 case ENOTNAM: return DRMP3_ERROR; 03272 #endif 03273 #ifdef ENAVAIL 03274 case ENAVAIL: return DRMP3_ERROR; 03275 #endif 03276 #ifdef EISNAM 03277 case EISNAM: return DRMP3_ERROR; 03278 #endif 03279 #ifdef EREMOTEIO 03280 case EREMOTEIO: return DRMP3_IO_ERROR; 03281 #endif 03282 #ifdef EDQUOT 03283 case EDQUOT: return DRMP3_NO_SPACE; 03284 #endif 03285 #ifdef ENOMEDIUM 03286 case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST; 03287 #endif 03288 #ifdef EMEDIUMTYPE 03289 case EMEDIUMTYPE: return DRMP3_ERROR; 03290 #endif 03291 #ifdef ECANCELED 03292 case ECANCELED: return DRMP3_CANCELLED; 03293 #endif 03294 #ifdef ENOKEY 03295 case ENOKEY: return DRMP3_ERROR; 03296 #endif 03297 #ifdef EKEYEXPIRED 03298 case EKEYEXPIRED: return DRMP3_ERROR; 03299 #endif 03300 #ifdef EKEYREVOKED 03301 case EKEYREVOKED: return DRMP3_ERROR; 03302 #endif 03303 #ifdef EKEYREJECTED 03304 case EKEYREJECTED: return DRMP3_ERROR; 03305 #endif 03306 #ifdef EOWNERDEAD 03307 case EOWNERDEAD: return DRMP3_ERROR; 03308 #endif 03309 #ifdef ENOTRECOVERABLE 03310 case ENOTRECOVERABLE: return DRMP3_ERROR; 03311 #endif 03312 #ifdef ERFKILL 03313 case ERFKILL: return DRMP3_ERROR; 03314 #endif 03315 #ifdef EHWPOISON 03316 case EHWPOISON: return DRMP3_ERROR; 03317 #endif 03318 default: return DRMP3_ERROR; 03319 } 03320 } 03321 03322 static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) 03323 { 03324 #if _MSC_VER && _MSC_VER >= 1400 03325 errno_t err; 03326 #endif 03327 03328 if (ppFile != NULL) { 03329 *ppFile = NULL; /* Safety. */ 03330 } 03331 03332 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) { 03333 return DRMP3_INVALID_ARGS; 03334 } 03335 03336 #if _MSC_VER && _MSC_VER >= 1400 03337 err = fopen_s(ppFile, pFilePath, pOpenMode); 03338 if (err != 0) { 03339 return drmp3_result_from_errno(err); 03340 } 03341 #else 03342 #if defined(_WIN32) || defined(__APPLE__) 03343 *ppFile = fopen(pFilePath, pOpenMode); 03344 #else 03345 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE) 03346 *ppFile = fopen64(pFilePath, pOpenMode); 03347 #else 03348 *ppFile = fopen(pFilePath, pOpenMode); 03349 #endif 03350 #endif 03351 if (*ppFile == NULL) { 03352 drmp3_result result = drmp3_result_from_errno(errno); 03353 if (result == DRMP3_SUCCESS) { 03354 result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */ 03355 } 03356 03357 return result; 03358 } 03359 #endif 03360 03361 return DRMP3_SUCCESS; 03362 } 03363 03364 /* 03365 _wfopen() isn't always available in all compilation environments. 03366 03367 * Windows only. 03368 * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back). 03369 * MinGW-64 (both 32- and 64-bit) seems to support it. 03370 * MinGW wraps it in !defined(__STRICT_ANSI__). 03371 03372 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs() 03373 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support. 03374 */ 03375 #if defined(_WIN32) 03376 #if defined(_MSC_VER) || defined(__MINGW64__) || !defined(__STRICT_ANSI__) 03377 #define DRMP3_HAS_WFOPEN 03378 #endif 03379 #endif 03380 03381 static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks) 03382 { 03383 if (ppFile != NULL) { 03384 *ppFile = NULL; /* Safety. */ 03385 } 03386 03387 if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) { 03388 return DRMP3_INVALID_ARGS; 03389 } 03390 03391 #if defined(DRMP3_HAS_WFOPEN) 03392 { 03393 /* Use _wfopen() on Windows. */ 03394 #if defined(_MSC_VER) && _MSC_VER >= 1400 03395 errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode); 03396 if (err != 0) { 03397 return drmp3_result_from_errno(err); 03398 } 03399 #else 03400 *ppFile = _wfopen(pFilePath, pOpenMode); 03401 if (*ppFile == NULL) { 03402 return drmp3_result_from_errno(errno); 03403 } 03404 #endif 03405 (void)pAllocationCallbacks; 03406 } 03407 #else 03408 /* 03409 Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can 03410 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 03411 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. 03412 */ 03413 { 03414 mbstate_t mbs; 03415 size_t lenMB; 03416 const wchar_t* pFilePathTemp = pFilePath; 03417 char* pFilePathMB = NULL; 03418 char pOpenModeMB[32] = {0}; 03419 03420 /* Get the length first. */ 03421 DRMP3_ZERO_OBJECT(&mbs); 03422 lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs); 03423 if (lenMB == (size_t)-1) { 03424 return drmp3_result_from_errno(errno); 03425 } 03426 03427 pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks); 03428 if (pFilePathMB == NULL) { 03429 return DRMP3_OUT_OF_MEMORY; 03430 } 03431 03432 pFilePathTemp = pFilePath; 03433 DRMP3_ZERO_OBJECT(&mbs); 03434 wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs); 03435 03436 /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */ 03437 { 03438 size_t i = 0; 03439 for (;;) { 03440 if (pOpenMode[i] == 0) { 03441 pOpenModeMB[i] = '\0'; 03442 break; 03443 } 03444 03445 pOpenModeMB[i] = (char)pOpenMode[i]; 03446 i += 1; 03447 } 03448 } 03449 03450 *ppFile = fopen(pFilePathMB, pOpenModeMB); 03451 03452 drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks); 03453 } 03454 03455 if (*ppFile == NULL) { 03456 return DRMP3_ERROR; 03457 } 03458 #endif 03459 03460 return DRMP3_SUCCESS; 03461 } 03462 03463 03464 03465 static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) 03466 { 03467 return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData); 03468 } 03469 03470 static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin) 03471 { 03472 return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; 03473 } 03474 03475 DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) 03476 { 03477 FILE* pFile; 03478 if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) { 03479 return DRMP3_FALSE; 03480 } 03481 03482 return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); 03483 } 03484 03485 DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) 03486 { 03487 FILE* pFile; 03488 if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) { 03489 return DRMP3_FALSE; 03490 } 03491 03492 return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); 03493 } 03494 #endif 03495 03496 DRMP3_API void drmp3_uninit(drmp3* pMP3) 03497 { 03498 if (pMP3 == NULL) { 03499 return; 03500 } 03501 03502 #ifndef DR_MP3_NO_STDIO 03503 if (pMP3->onRead == drmp3__on_read_stdio) { 03504 fclose((FILE*)pMP3->pUserData); 03505 } 03506 #endif 03507 03508 drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); 03509 } 03510 03511 #if defined(DR_MP3_FLOAT_OUTPUT) 03512 static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount) 03513 { 03514 drmp3_uint64 i; 03515 drmp3_uint64 i4; 03516 drmp3_uint64 sampleCount4; 03517 03518 /* Unrolled. */ 03519 i = 0; 03520 sampleCount4 = sampleCount >> 2; 03521 for (i4 = 0; i4 < sampleCount4; i4 += 1) { 03522 float x0 = src[i+0]; 03523 float x1 = src[i+1]; 03524 float x2 = src[i+2]; 03525 float x3 = src[i+3]; 03526 03527 x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0)); 03528 x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1)); 03529 x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2)); 03530 x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3)); 03531 03532 x0 = x0 * 32767.0f; 03533 x1 = x1 * 32767.0f; 03534 x2 = x2 * 32767.0f; 03535 x3 = x3 * 32767.0f; 03536 03537 dst[i+0] = (drmp3_int16)x0; 03538 dst[i+1] = (drmp3_int16)x1; 03539 dst[i+2] = (drmp3_int16)x2; 03540 dst[i+3] = (drmp3_int16)x3; 03541 03542 i += 4; 03543 } 03544 03545 /* Leftover. */ 03546 for (; i < sampleCount; i += 1) { 03547 float x = src[i]; 03548 x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */ 03549 x = x * 32767.0f; /* -1..1 to -32767..32767 */ 03550 03551 dst[i] = (drmp3_int16)x; 03552 } 03553 } 03554 #endif 03555 03556 #if !defined(DR_MP3_FLOAT_OUTPUT) 03557 static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount) 03558 { 03559 drmp3_uint64 i; 03560 for (i = 0; i < sampleCount; i += 1) { 03561 float x = (float)src[i]; 03562 x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */ 03563 dst[i] = x; 03564 } 03565 } 03566 #endif 03567 03568 03569 static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut) 03570 { 03571 drmp3_uint64 totalFramesRead = 0; 03572 03573 DRMP3_ASSERT(pMP3 != NULL); 03574 DRMP3_ASSERT(pMP3->onRead != NULL); 03575 03576 while (framesToRead > 0) { 03577 drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead); 03578 if (pBufferOut != NULL) { 03579 #if defined(DR_MP3_FLOAT_OUTPUT) 03580 /* f32 */ 03581 float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels); 03582 float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); 03583 DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels); 03584 #else 03585 /* s16 */ 03586 drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels); 03587 drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); 03588 DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels); 03589 #endif 03590 } 03591 03592 pMP3->currentPCMFrame += framesToConsume; 03593 pMP3->pcmFramesConsumedInMP3Frame += framesToConsume; 03594 pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume; 03595 totalFramesRead += framesToConsume; 03596 framesToRead -= framesToConsume; 03597 03598 if (framesToRead == 0) { 03599 break; 03600 } 03601 03602 DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0); 03603 03604 /* 03605 At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed 03606 at this point which means we'll also need to update our sample rate conversion pipeline. 03607 */ 03608 if (drmp3_decode_next_frame(pMP3) == 0) { 03609 break; 03610 } 03611 } 03612 03613 return totalFramesRead; 03614 } 03615 03616 03617 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut) 03618 { 03619 if (pMP3 == NULL || pMP3->onRead == NULL) { 03620 return 0; 03621 } 03622 03623 #if defined(DR_MP3_FLOAT_OUTPUT) 03624 /* Fast path. No conversion required. */ 03625 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut); 03626 #else 03627 /* Slow path. Convert from s16 to f32. */ 03628 { 03629 drmp3_int16 pTempS16[8192]; 03630 drmp3_uint64 totalPCMFramesRead = 0; 03631 03632 while (totalPCMFramesRead < framesToRead) { 03633 drmp3_uint64 framesJustRead; 03634 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead; 03635 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels; 03636 if (framesToReadNow > framesRemaining) { 03637 framesToReadNow = framesRemaining; 03638 } 03639 03640 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16); 03641 if (framesJustRead == 0) { 03642 break; 03643 } 03644 03645 drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels); 03646 totalPCMFramesRead += framesJustRead; 03647 } 03648 03649 return totalPCMFramesRead; 03650 } 03651 #endif 03652 } 03653 03654 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut) 03655 { 03656 if (pMP3 == NULL || pMP3->onRead == NULL) { 03657 return 0; 03658 } 03659 03660 #if !defined(DR_MP3_FLOAT_OUTPUT) 03661 /* Fast path. No conversion required. */ 03662 return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut); 03663 #else 03664 /* Slow path. Convert from f32 to s16. */ 03665 { 03666 float pTempF32[4096]; 03667 drmp3_uint64 totalPCMFramesRead = 0; 03668 03669 while (totalPCMFramesRead < framesToRead) { 03670 drmp3_uint64 framesJustRead; 03671 drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead; 03672 drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels; 03673 if (framesToReadNow > framesRemaining) { 03674 framesToReadNow = framesRemaining; 03675 } 03676 03677 framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32); 03678 if (framesJustRead == 0) { 03679 break; 03680 } 03681 03682 drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels); 03683 totalPCMFramesRead += framesJustRead; 03684 } 03685 03686 return totalPCMFramesRead; 03687 } 03688 #endif 03689 } 03690 03691 static void drmp3_reset(drmp3* pMP3) 03692 { 03693 DRMP3_ASSERT(pMP3 != NULL); 03694 03695 pMP3->pcmFramesConsumedInMP3Frame = 0; 03696 pMP3->pcmFramesRemainingInMP3Frame = 0; 03697 pMP3->currentPCMFrame = 0; 03698 pMP3->dataSize = 0; 03699 pMP3->atEnd = DRMP3_FALSE; 03700 drmp3dec_init(&pMP3->decoder); 03701 } 03702 03703 static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3) 03704 { 03705 DRMP3_ASSERT(pMP3 != NULL); 03706 DRMP3_ASSERT(pMP3->onSeek != NULL); 03707 03708 /* Seek to the start of the stream to begin with. */ 03709 if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) { 03710 return DRMP3_FALSE; 03711 } 03712 03713 /* Clear any cached data. */ 03714 drmp3_reset(pMP3); 03715 return DRMP3_TRUE; 03716 } 03717 03718 03719 static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset) 03720 { 03721 drmp3_uint64 framesRead; 03722 03723 /* 03724 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 03725 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 03726 kind of manual processing. 03727 */ 03728 #if defined(DR_MP3_FLOAT_OUTPUT) 03729 framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL); 03730 #else 03731 framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL); 03732 #endif 03733 if (framesRead != frameOffset) { 03734 return DRMP3_FALSE; 03735 } 03736 03737 return DRMP3_TRUE; 03738 } 03739 03740 static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex) 03741 { 03742 DRMP3_ASSERT(pMP3 != NULL); 03743 03744 if (frameIndex == pMP3->currentPCMFrame) { 03745 return DRMP3_TRUE; 03746 } 03747 03748 /* 03749 If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of 03750 the stream and read from the beginning. 03751 */ 03752 if (frameIndex < pMP3->currentPCMFrame) { 03753 /* Moving backward. Move to the start of the stream and then move forward. */ 03754 if (!drmp3_seek_to_start_of_stream(pMP3)) { 03755 return DRMP3_FALSE; 03756 } 03757 } 03758 03759 DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame); 03760 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame)); 03761 } 03762 03763 static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex) 03764 { 03765 drmp3_uint32 iSeekPoint; 03766 03767 DRMP3_ASSERT(pSeekPointIndex != NULL); 03768 03769 *pSeekPointIndex = 0; 03770 03771 if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) { 03772 return DRMP3_FALSE; 03773 } 03774 03775 /* 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. */ 03776 for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) { 03777 if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) { 03778 break; /* Found it. */ 03779 } 03780 03781 *pSeekPointIndex = iSeekPoint; 03782 } 03783 03784 return DRMP3_TRUE; 03785 } 03786 03787 static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex) 03788 { 03789 drmp3_seek_point seekPoint; 03790 drmp3_uint32 priorSeekPointIndex; 03791 drmp3_uint16 iMP3Frame; 03792 drmp3_uint64 leftoverFrames; 03793 03794 DRMP3_ASSERT(pMP3 != NULL); 03795 DRMP3_ASSERT(pMP3->pSeekPoints != NULL); 03796 DRMP3_ASSERT(pMP3->seekPointCount > 0); 03797 03798 /* 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. */ 03799 if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) { 03800 seekPoint = pMP3->pSeekPoints[priorSeekPointIndex]; 03801 } else { 03802 seekPoint.seekPosInBytes = 0; 03803 seekPoint.pcmFrameIndex = 0; 03804 seekPoint.mp3FramesToDiscard = 0; 03805 seekPoint.pcmFramesToDiscard = 0; 03806 } 03807 03808 /* First thing to do is seek to the first byte of the relevant MP3 frame. */ 03809 if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) { 03810 return DRMP3_FALSE; /* Failed to seek. */ 03811 } 03812 03813 /* Clear any cached data. */ 03814 drmp3_reset(pMP3); 03815 03816 /* Whole MP3 frames need to be discarded first. */ 03817 for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) { 03818 drmp3_uint32 pcmFramesRead; 03819 drmp3d_sample_t* pPCMFrames; 03820 03821 /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */ 03822 pPCMFrames = NULL; 03823 if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) { 03824 pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames; 03825 } 03826 03827 /* We first need to decode the next frame. */ 03828 pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames); 03829 if (pcmFramesRead == 0) { 03830 return DRMP3_FALSE; 03831 } 03832 } 03833 03834 /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */ 03835 pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard; 03836 03837 /* 03838 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 03839 read-and-discard at least 2 whole MP3 frames. 03840 */ 03841 leftoverFrames = frameIndex - pMP3->currentPCMFrame; 03842 return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames); 03843 } 03844 03845 DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex) 03846 { 03847 if (pMP3 == NULL || pMP3->onSeek == NULL) { 03848 return DRMP3_FALSE; 03849 } 03850 03851 if (frameIndex == 0) { 03852 return drmp3_seek_to_start_of_stream(pMP3); 03853 } 03854 03855 /* Use the seek table if we have one. */ 03856 if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) { 03857 return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex); 03858 } else { 03859 return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex); 03860 } 03861 } 03862 03863 DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount) 03864 { 03865 drmp3_uint64 currentPCMFrame; 03866 drmp3_uint64 totalPCMFrameCount; 03867 drmp3_uint64 totalMP3FrameCount; 03868 03869 if (pMP3 == NULL) { 03870 return DRMP3_FALSE; 03871 } 03872 03873 /* 03874 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 03875 on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function. 03876 */ 03877 03878 /* The stream must support seeking for this to work. */ 03879 if (pMP3->onSeek == NULL) { 03880 return DRMP3_FALSE; 03881 } 03882 03883 /* 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. */ 03884 currentPCMFrame = pMP3->currentPCMFrame; 03885 03886 if (!drmp3_seek_to_start_of_stream(pMP3)) { 03887 return DRMP3_FALSE; 03888 } 03889 03890 totalPCMFrameCount = 0; 03891 totalMP3FrameCount = 0; 03892 03893 for (;;) { 03894 drmp3_uint32 pcmFramesInCurrentMP3Frame; 03895 03896 pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL); 03897 if (pcmFramesInCurrentMP3Frame == 0) { 03898 break; 03899 } 03900 03901 totalPCMFrameCount += pcmFramesInCurrentMP3Frame; 03902 totalMP3FrameCount += 1; 03903 } 03904 03905 /* Finally, we need to seek back to where we were. */ 03906 if (!drmp3_seek_to_start_of_stream(pMP3)) { 03907 return DRMP3_FALSE; 03908 } 03909 03910 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) { 03911 return DRMP3_FALSE; 03912 } 03913 03914 if (pMP3FrameCount != NULL) { 03915 *pMP3FrameCount = totalMP3FrameCount; 03916 } 03917 if (pPCMFrameCount != NULL) { 03918 *pPCMFrameCount = totalPCMFrameCount; 03919 } 03920 03921 return DRMP3_TRUE; 03922 } 03923 03924 DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3) 03925 { 03926 drmp3_uint64 totalPCMFrameCount; 03927 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) { 03928 return 0; 03929 } 03930 03931 return totalPCMFrameCount; 03932 } 03933 03934 DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3) 03935 { 03936 drmp3_uint64 totalMP3FrameCount; 03937 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) { 03938 return 0; 03939 } 03940 03941 return totalMP3FrameCount; 03942 } 03943 03944 static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart) 03945 { 03946 float srcRatio; 03947 float pcmFrameCountOutF; 03948 drmp3_uint32 pcmFrameCountOut; 03949 03950 srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate; 03951 DRMP3_ASSERT(srcRatio > 0); 03952 03953 pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio); 03954 pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF; 03955 *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut; 03956 *pRunningPCMFrameCount += pcmFrameCountOut; 03957 } 03958 03959 typedef struct 03960 { 03961 drmp3_uint64 bytePos; 03962 drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */ 03963 } drmp3__seeking_mp3_frame_info; 03964 03965 DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints) 03966 { 03967 drmp3_uint32 seekPointCount; 03968 drmp3_uint64 currentPCMFrame; 03969 drmp3_uint64 totalMP3FrameCount; 03970 drmp3_uint64 totalPCMFrameCount; 03971 03972 if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) { 03973 return DRMP3_FALSE; /* Invalid args. */ 03974 } 03975 03976 seekPointCount = *pSeekPointCount; 03977 if (seekPointCount == 0) { 03978 return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */ 03979 } 03980 03981 /* 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. */ 03982 currentPCMFrame = pMP3->currentPCMFrame; 03983 03984 /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */ 03985 if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) { 03986 return DRMP3_FALSE; 03987 } 03988 03989 /* 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. */ 03990 if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) { 03991 seekPointCount = 1; 03992 pSeekPoints[0].seekPosInBytes = 0; 03993 pSeekPoints[0].pcmFrameIndex = 0; 03994 pSeekPoints[0].mp3FramesToDiscard = 0; 03995 pSeekPoints[0].pcmFramesToDiscard = 0; 03996 } else { 03997 drmp3_uint64 pcmFramesBetweenSeekPoints; 03998 drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1]; 03999 drmp3_uint64 runningPCMFrameCount = 0; 04000 float runningPCMFrameCountFractionalPart = 0; 04001 drmp3_uint64 nextTargetPCMFrame; 04002 drmp3_uint32 iMP3Frame; 04003 drmp3_uint32 iSeekPoint; 04004 04005 if (seekPointCount > totalMP3FrameCount-1) { 04006 seekPointCount = (drmp3_uint32)totalMP3FrameCount-1; 04007 } 04008 04009 pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1); 04010 04011 /* 04012 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 04013 MP3 frame. 04014 */ 04015 if (!drmp3_seek_to_start_of_stream(pMP3)) { 04016 return DRMP3_FALSE; 04017 } 04018 04019 /* 04020 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 04021 array. The value in the first item in this array is the byte position that will be reported in the next seek point. 04022 */ 04023 04024 /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */ 04025 for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) { 04026 drmp3_uint32 pcmFramesInCurrentMP3FrameIn; 04027 04028 /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */ 04029 DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize); 04030 mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize; 04031 mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount; 04032 04033 /* We need to get information about this frame so we can know how many samples it contained. */ 04034 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); 04035 if (pcmFramesInCurrentMP3FrameIn == 0) { 04036 return DRMP3_FALSE; /* This should never happen. */ 04037 } 04038 04039 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart); 04040 } 04041 04042 /* 04043 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 04044 calculate them. 04045 */ 04046 nextTargetPCMFrame = 0; 04047 for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) { 04048 nextTargetPCMFrame += pcmFramesBetweenSeekPoints; 04049 04050 for (;;) { 04051 if (nextTargetPCMFrame < runningPCMFrameCount) { 04052 /* The next seek point is in the current MP3 frame. */ 04053 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos; 04054 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame; 04055 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES; 04056 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex); 04057 break; 04058 } else { 04059 size_t i; 04060 drmp3_uint32 pcmFramesInCurrentMP3FrameIn; 04061 04062 /* 04063 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 04064 MP3 frame info. 04065 */ 04066 for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) { 04067 mp3FrameInfo[i] = mp3FrameInfo[i+1]; 04068 } 04069 04070 /* Cache previous MP3 frame info. */ 04071 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize; 04072 mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount; 04073 04074 /* 04075 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 04076 should only ever do it for the last seek point. 04077 */ 04078 pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); 04079 if (pcmFramesInCurrentMP3FrameIn == 0) { 04080 pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos; 04081 pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame; 04082 pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES; 04083 pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex); 04084 break; 04085 } 04086 04087 drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart); 04088 } 04089 } 04090 } 04091 04092 /* Finally, we need to seek back to where we were. */ 04093 if (!drmp3_seek_to_start_of_stream(pMP3)) { 04094 return DRMP3_FALSE; 04095 } 04096 if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) { 04097 return DRMP3_FALSE; 04098 } 04099 } 04100 04101 *pSeekPointCount = seekPointCount; 04102 return DRMP3_TRUE; 04103 } 04104 04105 DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints) 04106 { 04107 if (pMP3 == NULL) { 04108 return DRMP3_FALSE; 04109 } 04110 04111 if (seekPointCount == 0 || pSeekPoints == NULL) { 04112 /* Unbinding. */ 04113 pMP3->seekPointCount = 0; 04114 pMP3->pSeekPoints = NULL; 04115 } else { 04116 /* Binding. */ 04117 pMP3->seekPointCount = seekPointCount; 04118 pMP3->pSeekPoints = pSeekPoints; 04119 } 04120 04121 return DRMP3_TRUE; 04122 } 04123 04124 04125 static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) 04126 { 04127 drmp3_uint64 totalFramesRead = 0; 04128 drmp3_uint64 framesCapacity = 0; 04129 float* pFrames = NULL; 04130 float temp[4096]; 04131 04132 DRMP3_ASSERT(pMP3 != NULL); 04133 04134 for (;;) { 04135 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; 04136 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp); 04137 if (framesJustRead == 0) { 04138 break; 04139 } 04140 04141 /* Reallocate the output buffer if there's not enough room. */ 04142 if (framesCapacity < totalFramesRead + framesJustRead) { 04143 drmp3_uint64 oldFramesBufferSize; 04144 drmp3_uint64 newFramesBufferSize; 04145 drmp3_uint64 newFramesCap; 04146 float* pNewFrames; 04147 04148 newFramesCap = framesCapacity * 2; 04149 if (newFramesCap < totalFramesRead + framesJustRead) { 04150 newFramesCap = totalFramesRead + framesJustRead; 04151 } 04152 04153 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float); 04154 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float); 04155 if (newFramesBufferSize > DRMP3_SIZE_MAX) { 04156 break; 04157 } 04158 04159 pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); 04160 if (pNewFrames == NULL) { 04161 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); 04162 break; 04163 } 04164 04165 pFrames = pNewFrames; 04166 framesCapacity = newFramesCap; 04167 } 04168 04169 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float))); 04170 totalFramesRead += framesJustRead; 04171 04172 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */ 04173 if (framesJustRead != framesToReadRightNow) { 04174 break; 04175 } 04176 } 04177 04178 if (pConfig != NULL) { 04179 pConfig->channels = pMP3->channels; 04180 pConfig->sampleRate = pMP3->sampleRate; 04181 } 04182 04183 drmp3_uninit(pMP3); 04184 04185 if (pTotalFrameCount) { 04186 *pTotalFrameCount = totalFramesRead; 04187 } 04188 04189 return pFrames; 04190 } 04191 04192 static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) 04193 { 04194 drmp3_uint64 totalFramesRead = 0; 04195 drmp3_uint64 framesCapacity = 0; 04196 drmp3_int16* pFrames = NULL; 04197 drmp3_int16 temp[4096]; 04198 04199 DRMP3_ASSERT(pMP3 != NULL); 04200 04201 for (;;) { 04202 drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; 04203 drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp); 04204 if (framesJustRead == 0) { 04205 break; 04206 } 04207 04208 /* Reallocate the output buffer if there's not enough room. */ 04209 if (framesCapacity < totalFramesRead + framesJustRead) { 04210 drmp3_uint64 newFramesBufferSize; 04211 drmp3_uint64 oldFramesBufferSize; 04212 drmp3_uint64 newFramesCap; 04213 drmp3_int16* pNewFrames; 04214 04215 newFramesCap = framesCapacity * 2; 04216 if (newFramesCap < totalFramesRead + framesJustRead) { 04217 newFramesCap = totalFramesRead + framesJustRead; 04218 } 04219 04220 oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16); 04221 newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16); 04222 if (newFramesBufferSize > DRMP3_SIZE_MAX) { 04223 break; 04224 } 04225 04226 pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); 04227 if (pNewFrames == NULL) { 04228 drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); 04229 break; 04230 } 04231 04232 pFrames = pNewFrames; 04233 framesCapacity = newFramesCap; 04234 } 04235 04236 DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16))); 04237 totalFramesRead += framesJustRead; 04238 04239 /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */ 04240 if (framesJustRead != framesToReadRightNow) { 04241 break; 04242 } 04243 } 04244 04245 if (pConfig != NULL) { 04246 pConfig->channels = pMP3->channels; 04247 pConfig->sampleRate = pMP3->sampleRate; 04248 } 04249 04250 drmp3_uninit(pMP3); 04251 04252 if (pTotalFrameCount) { 04253 *pTotalFrameCount = totalFramesRead; 04254 } 04255 04256 return pFrames; 04257 } 04258 04259 04260 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) 04261 { 04262 drmp3 mp3; 04263 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { 04264 return NULL; 04265 } 04266 04267 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); 04268 } 04269 04270 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) 04271 { 04272 drmp3 mp3; 04273 if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { 04274 return NULL; 04275 } 04276 04277 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); 04278 } 04279 04280 04281 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) 04282 { 04283 drmp3 mp3; 04284 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) { 04285 return NULL; 04286 } 04287 04288 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); 04289 } 04290 04291 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) 04292 { 04293 drmp3 mp3; 04294 if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) { 04295 return NULL; 04296 } 04297 04298 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); 04299 } 04300 04301 04302 #ifndef DR_MP3_NO_STDIO 04303 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) 04304 { 04305 drmp3 mp3; 04306 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) { 04307 return NULL; 04308 } 04309 04310 return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); 04311 } 04312 04313 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) 04314 { 04315 drmp3 mp3; 04316 if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) { 04317 return NULL; 04318 } 04319 04320 return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); 04321 } 04322 #endif 04323 04324 DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) 04325 { 04326 if (pAllocationCallbacks != NULL) { 04327 return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks); 04328 } else { 04329 return drmp3__malloc_default(sz, NULL); 04330 } 04331 } 04332 04333 DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks) 04334 { 04335 if (pAllocationCallbacks != NULL) { 04336 drmp3__free_from_callbacks(p, pAllocationCallbacks); 04337 } else { 04338 drmp3__free_default(p, NULL); 04339 } 04340 } 04341 04342 #endif /*DR_MP3_IMPLEMENTATION*/ 04343 04344 /* 04345 DIFFERENCES BETWEEN minimp3 AND dr_mp3 04346 ====================================== 04347 - First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the 04348 code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes. 04349 - dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data 04350 to the decoder, the decoder _pulls_ data from your callbacks. 04351 - In addition to callbacks, a decoder can be initialized from a block of memory and a file. 04352 - The dr_mp3 pull API reads PCM frames rather than whole MP3 frames. 04353 - dr_mp3 adds convenience APIs for opening and decoding entire files in one go. 04354 - dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects 04355 as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when 04356 using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this. 04357 */ 04358 04359 /* 04360 RELEASE NOTES - v0.5.0 04361 ======================= 04362 Version 0.5.0 has breaking API changes. 04363 04364 Improved Client-Defined Memory Allocation 04365 ----------------------------------------- 04366 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The 04367 existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom 04368 allocation callbacks are specified. 04369 04370 To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this: 04371 04372 void* my_malloc(size_t sz, void* pUserData) 04373 { 04374 return malloc(sz); 04375 } 04376 void* my_realloc(void* p, size_t sz, void* pUserData) 04377 { 04378 return realloc(p, sz); 04379 } 04380 void my_free(void* p, void* pUserData) 04381 { 04382 free(p); 04383 } 04384 04385 ... 04386 04387 drmp3_allocation_callbacks allocationCallbacks; 04388 allocationCallbacks.pUserData = &myData; 04389 allocationCallbacks.onMalloc = my_malloc; 04390 allocationCallbacks.onRealloc = my_realloc; 04391 allocationCallbacks.onFree = my_free; 04392 drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks); 04393 04394 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines. 04395 04396 Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC, 04397 DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions. 04398 04399 Every API that opens a drmp3 object now takes this extra parameter. These include the following: 04400 04401 drmp3_init() 04402 drmp3_init_file() 04403 drmp3_init_memory() 04404 drmp3_open_and_read_pcm_frames_f32() 04405 drmp3_open_and_read_pcm_frames_s16() 04406 drmp3_open_memory_and_read_pcm_frames_f32() 04407 drmp3_open_memory_and_read_pcm_frames_s16() 04408 drmp3_open_file_and_read_pcm_frames_f32() 04409 drmp3_open_file_and_read_pcm_frames_s16() 04410 04411 Renamed APIs 04412 ------------ 04413 The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame 04414 counts rather than sample counts. 04415 04416 drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32() 04417 drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16() 04418 drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32() 04419 drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16() 04420 drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32() 04421 drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16() 04422 */ 04423 04424 /* 04425 REVISION HISTORY 04426 ================ 04427 v0.6.11 - 2020-05-26 04428 - Fix use of uninitialized variable error. 04429 04430 v0.6.10 - 2020-05-16 04431 - Add compile-time and run-time version querying. 04432 - DRMP3_VERSION_MINOR 04433 - DRMP3_VERSION_MAJOR 04434 - DRMP3_VERSION_REVISION 04435 - DRMP3_VERSION_STRING 04436 - drmp3_version() 04437 - drmp3_version_string() 04438 04439 v0.6.9 - 2020-04-30 04440 - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs. 04441 04442 v0.6.8 - 2020-04-26 04443 - Optimizations to decoding when initializing from memory. 04444 04445 v0.6.7 - 2020-04-25 04446 - Fix a compilation error with DR_MP3_NO_STDIO 04447 - Optimization to decoding by reducing some data movement. 04448 04449 v0.6.6 - 2020-04-23 04450 - Fix a minor bug with the running PCM frame counter. 04451 04452 v0.6.5 - 2020-04-19 04453 - Fix compilation error on ARM builds. 04454 04455 v0.6.4 - 2020-04-19 04456 - Bring up to date with changes to minimp3. 04457 04458 v0.6.3 - 2020-04-13 04459 - Fix some pedantic warnings. 04460 04461 v0.6.2 - 2020-04-10 04462 - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL. 04463 04464 v0.6.1 - 2020-04-05 04465 - Fix warnings. 04466 04467 v0.6.0 - 2020-04-04 04468 - API CHANGE: Remove the pConfig parameter from the following APIs: 04469 - drmp3_init() 04470 - drmp3_init_memory() 04471 - drmp3_init_file() 04472 - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path. 04473 04474 v0.5.6 - 2020-02-12 04475 - Bring up to date with minimp3. 04476 04477 v0.5.5 - 2020-01-29 04478 - Fix a memory allocation bug in high level s16 decoding APIs. 04479 04480 v0.5.4 - 2019-12-02 04481 - Fix a possible null pointer dereference when using custom memory allocators for realloc(). 04482 04483 v0.5.3 - 2019-11-14 04484 - Fix typos in documentation. 04485 04486 v0.5.2 - 2019-11-02 04487 - Bring up to date with minimp3. 04488 04489 v0.5.1 - 2019-10-08 04490 - Fix a warning with GCC. 04491 04492 v0.5.0 - 2019-10-07 04493 - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation 04494 routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs: 04495 - drmp3_init() 04496 - drmp3_init_file() 04497 - drmp3_init_memory() 04498 - drmp3_open_and_read_pcm_frames_f32() 04499 - drmp3_open_and_read_pcm_frames_s16() 04500 - drmp3_open_memory_and_read_pcm_frames_f32() 04501 - drmp3_open_memory_and_read_pcm_frames_s16() 04502 - drmp3_open_file_and_read_pcm_frames_f32() 04503 - drmp3_open_file_and_read_pcm_frames_s16() 04504 - API CHANGE: Renamed the following APIs: 04505 - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32() 04506 - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16() 04507 - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32() 04508 - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16() 04509 - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32() 04510 - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16() 04511 04512 v0.4.7 - 2019-07-28 04513 - Fix a compiler error. 04514 04515 v0.4.6 - 2019-06-14 04516 - Fix a compiler error. 04517 04518 v0.4.5 - 2019-06-06 04519 - Bring up to date with minimp3. 04520 04521 v0.4.4 - 2019-05-06 04522 - Fixes to the VC6 build. 04523 04524 v0.4.3 - 2019-05-05 04525 - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and 04526 DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to 04527 DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE. 04528 - Add s16 reading APIs 04529 - drmp3_read_pcm_frames_s16 04530 - drmp3_open_memory_and_read_pcm_frames_s16 04531 - drmp3_open_and_read_pcm_frames_s16 04532 - drmp3_open_file_and_read_pcm_frames_s16 04533 - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section. 04534 - Add support for C89. 04535 - Change license to choice of public domain or MIT-0. 04536 04537 v0.4.2 - 2019-02-21 04538 - Fix a warning. 04539 04540 v0.4.1 - 2018-12-30 04541 - Fix a warning. 04542 04543 v0.4.0 - 2018-12-16 04544 - API CHANGE: Rename some APIs: 04545 - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32 04546 - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame 04547 - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32 04548 - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32 04549 - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32 04550 - Add drmp3_get_pcm_frame_count(). 04551 - Add drmp3_get_mp3_frame_count(). 04552 - Improve seeking performance. 04553 04554 v0.3.2 - 2018-09-11 04555 - Fix a couple of memory leaks. 04556 - Bring up to date with minimp3. 04557 04558 v0.3.1 - 2018-08-25 04559 - Fix C++ build. 04560 04561 v0.3.0 - 2018-08-25 04562 - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has 04563 been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or 04564 not the DR_MP3_FLOAT_OUTPUT option is set. 04565 04566 v0.2.11 - 2018-08-08 04567 - Fix a bug where the last part of a file is not read. 04568 04569 v0.2.10 - 2018-08-07 04570 - Improve 64-bit detection. 04571 04572 v0.2.9 - 2018-08-05 04573 - Fix C++ build on older versions of GCC. 04574 - Bring up to date with minimp3. 04575 04576 v0.2.8 - 2018-08-02 04577 - Fix compilation errors with older versions of GCC. 04578 04579 v0.2.7 - 2018-07-13 04580 - Bring up to date with minimp3. 04581 04582 v0.2.6 - 2018-07-12 04583 - Bring up to date with minimp3. 04584 04585 v0.2.5 - 2018-06-22 04586 - Bring up to date with minimp3. 04587 04588 v0.2.4 - 2018-05-12 04589 - Bring up to date with minimp3. 04590 04591 v0.2.3 - 2018-04-29 04592 - Fix TCC build. 04593 04594 v0.2.2 - 2018-04-28 04595 - Fix bug when opening a decoder from memory. 04596 04597 v0.2.1 - 2018-04-27 04598 - Efficiency improvements when the decoder reaches the end of the stream. 04599 04600 v0.2 - 2018-04-21 04601 - Bring up to date with minimp3. 04602 - Start using major.minor.revision versioning. 04603 04604 v0.1d - 2018-03-30 04605 - Bring up to date with minimp3. 04606 04607 v0.1c - 2018-03-11 04608 - Fix C++ build error. 04609 04610 v0.1b - 2018-03-07 04611 - Bring up to date with minimp3. 04612 04613 v0.1a - 2018-02-28 04614 - Fix compilation error on GCC/Clang. 04615 - Fix some warnings. 04616 04617 v0.1 - 2018-02-xx 04618 - Initial versioned release. 04619 */ 04620 04621 /* 04622 This software is available as a choice of the following licenses. Choose 04623 whichever you prefer. 04624 04625 =============================================================================== 04626 ALTERNATIVE 1 - Public Domain (www.unlicense.org) 04627 =============================================================================== 04628 This is free and unencumbered software released into the public domain. 04629 04630 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 04631 software, either in source code form or as a compiled binary, for any purpose, 04632 commercial or non-commercial, and by any means. 04633 04634 In jurisdictions that recognize copyright laws, the author or authors of this 04635 software dedicate any and all copyright interest in the software to the public 04636 domain. We make this dedication for the benefit of the public at large and to 04637 the detriment of our heirs and successors. We intend this dedication to be an 04638 overt act of relinquishment in perpetuity of all present and future rights to 04639 this software under copyright law. 04640 04641 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 04642 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 04643 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 04644 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 04645 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 04646 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 04647 04648 For more information, please refer to <http://unlicense.org/> 04649 04650 =============================================================================== 04651 ALTERNATIVE 2 - MIT No Attribution 04652 =============================================================================== 04653 Copyright 2020 David Reid 04654 04655 Permission is hereby granted, free of charge, to any person obtaining a copy of 04656 this software and associated documentation files (the "Software"), to deal in 04657 the Software without restriction, including without limitation the rights to 04658 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 04659 of the Software, and to permit persons to whom the Software is furnished to do 04660 so. 04661 04662 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 04663 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 04664 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 04665 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 04666 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 04667 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 04668 SOFTWARE. 04669 */ 04670 04671 /* 04672 https://github.com/lieff/minimp3 04673 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. 04674 This software is distributed without any warranty. 04675 See <http://creativecommons.org/publicdomain/zero/1.0/>. 04676 */