kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

dr_wav.h (201294B)


      1 /*
      2 WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
      3 dr_wav - v0.11.1 - 2019-10-07
      4 
      5 David Reid - [email protected]
      6 */
      7 
      8 /*
      9 RELEASE NOTES - v0.11.0
     10 =======================
     11 Version 0.11.0 has breaking API changes.
     12 
     13 Improved Client-Defined Memory Allocation
     14 -----------------------------------------
     15 The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
     16 existing system of DRWAV_MALLOC, DRWAV_REALLOC and DRWAV_FREE are still in place and will be used by default when no custom
     17 allocation callbacks are specified.
     18 
     19 To use the new system, you pass in a pointer to a drwav_allocation_callbacks object to drwav_init() and family, like this:
     20 
     21     void* my_malloc(size_t sz, void* pUserData)
     22     {
     23         return malloc(sz);
     24     }
     25     void* my_realloc(void* p, size_t sz, void* pUserData)
     26     {
     27         return realloc(p, sz);
     28     }
     29     void my_free(void* p, void* pUserData)
     30     {
     31         free(p);
     32     }
     33 
     34     ...
     35 
     36     drwav_allocation_callbacks allocationCallbacks;
     37     allocationCallbacks.pUserData = &myData;
     38     allocationCallbacks.onMalloc  = my_malloc;
     39     allocationCallbacks.onRealloc = my_realloc;
     40     allocationCallbacks.onFree    = my_free;
     41     drwav_init_file(&wav, "my_file.wav", &allocationCallbacks);
     42 
     43 The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
     44 
     45 Passing in null for the allocation callbacks object will cause dr_wav to use defaults which is the same as DRWAV_MALLOC,
     46 DRWAV_REALLOC and DRWAV_FREE and the equivalent of how it worked in previous versions.
     47 
     48 Every API that opens a drwav object now takes this extra parameter. These include the following:
     49 
     50     drwav_init()
     51     drwav_init_ex()
     52     drwav_init_file()
     53     drwav_init_file_ex()
     54     drwav_init_file_w()
     55     drwav_init_file_w_ex()
     56     drwav_init_memory()
     57     drwav_init_memory_ex()
     58     drwav_init_write()
     59     drwav_init_write_sequential()
     60     drwav_init_write_sequential_pcm_frames()
     61     drwav_init_file_write()
     62     drwav_init_file_write_sequential()
     63     drwav_init_file_write_sequential_pcm_frames()
     64     drwav_init_file_write_w()
     65     drwav_init_file_write_sequential_w()
     66     drwav_init_file_write_sequential_pcm_frames_w()
     67     drwav_init_memory_write()
     68     drwav_init_memory_write_sequential()
     69     drwav_init_memory_write_sequential_pcm_frames()
     70     drwav_open_and_read_pcm_frames_s16()
     71     drwav_open_and_read_pcm_frames_f32()
     72     drwav_open_and_read_pcm_frames_s32()
     73     drwav_open_file_and_read_pcm_frames_s16()
     74     drwav_open_file_and_read_pcm_frames_f32()
     75     drwav_open_file_and_read_pcm_frames_s32()
     76     drwav_open_file_and_read_pcm_frames_s16_w()
     77     drwav_open_file_and_read_pcm_frames_f32_w()
     78     drwav_open_file_and_read_pcm_frames_s32_w()
     79     drwav_open_memory_and_read_pcm_frames_s16()
     80     drwav_open_memory_and_read_pcm_frames_f32()
     81     drwav_open_memory_and_read_pcm_frames_s32()
     82 
     83 Endian Improvements
     84 -------------------
     85 Previously, the following APIs returned little-endian audio data. These now return native-endian data. This improves compatibility
     86 on big-endian architectures.
     87 
     88     drwav_read_pcm_frames()
     89     drwav_read_pcm_frames_s16()
     90     drwav_read_pcm_frames_s32()
     91     drwav_read_pcm_frames_f32()
     92     drwav_open_and_read_pcm_frames_s16()
     93     drwav_open_and_read_pcm_frames_s32()
     94     drwav_open_and_read_pcm_frames_f32()
     95     drwav_open_file_and_read_pcm_frames_s16()
     96     drwav_open_file_and_read_pcm_frames_s32()
     97     drwav_open_file_and_read_pcm_frames_f32()
     98     drwav_open_file_and_read_pcm_frames_s16_w()
     99     drwav_open_file_and_read_pcm_frames_s32_w()
    100     drwav_open_file_and_read_pcm_frames_f32_w()
    101     drwav_open_memory_and_read_pcm_frames_s16()
    102     drwav_open_memory_and_read_pcm_frames_s32()
    103     drwav_open_memory_and_read_pcm_frames_f32()
    104 
    105 APIs have been added to give you explicit control over whether or not audio data is read or written in big- or little-endian byte
    106 order:
    107 
    108     drwav_read_pcm_frames_le()
    109     drwav_read_pcm_frames_be()
    110     drwav_read_pcm_frames_s16le()
    111     drwav_read_pcm_frames_s16be()
    112     drwav_read_pcm_frames_f32le()
    113     drwav_read_pcm_frames_f32be()
    114     drwav_read_pcm_frames_s32le()
    115     drwav_read_pcm_frames_s32be()
    116     drwav_write_pcm_frames_le()
    117     drwav_write_pcm_frames_be()
    118 
    119 Removed APIs
    120 ------------
    121 The following APIs were deprecated in version 0.10.0 and have now been removed:
    122 
    123     drwav_open()
    124     drwav_open_ex()
    125     drwav_open_write()
    126     drwav_open_write_sequential()
    127     drwav_open_file()
    128     drwav_open_file_ex()
    129     drwav_open_file_write()
    130     drwav_open_file_write_sequential()
    131     drwav_open_memory()
    132     drwav_open_memory_ex()
    133     drwav_open_memory_write()
    134     drwav_open_memory_write_sequential()
    135     drwav_close()
    136 
    137 
    138 
    139 RELEASE NOTES - v0.10.0
    140 =======================
    141 Version 0.10.0 has breaking API changes. There are no significant bug fixes in this release, so if you are affected you do
    142 not need to upgrade.
    143 
    144 Removed APIs
    145 ------------
    146 The following APIs were deprecated in version 0.9.0 and have been completely removed in version 0.10.0:
    147 
    148     drwav_read()
    149     drwav_read_s16()
    150     drwav_read_f32()
    151     drwav_read_s32()
    152     drwav_seek_to_sample()
    153     drwav_write()
    154     drwav_open_and_read_s16()
    155     drwav_open_and_read_f32()
    156     drwav_open_and_read_s32()
    157     drwav_open_file_and_read_s16()
    158     drwav_open_file_and_read_f32()
    159     drwav_open_file_and_read_s32()
    160     drwav_open_memory_and_read_s16()
    161     drwav_open_memory_and_read_f32()
    162     drwav_open_memory_and_read_s32()
    163     drwav::totalSampleCount
    164 
    165 See release notes for version 0.9.0 at the bottom of this file for replacement APIs.
    166 
    167 Deprecated APIs
    168 ---------------
    169 The following APIs have been deprecated. There is a confusing and completely arbitrary difference between drwav_init*() and
    170 drwav_open*(), where drwav_init*() initializes a pre-allocated drwav object, whereas drwav_open*() will first allocated a
    171 drwav object on the heap and then initialize it. drwav_open*() has been deprecated which means you must now use a pre-
    172 allocated drwav object with drwav_init*(). If you need the previous functionality, you can just do a malloc() followed by
    173 a called to one of the drwav_init*() APIs.
    174 
    175     drwav_open()
    176     drwav_open_ex()
    177     drwav_open_write()
    178     drwav_open_write_sequential()
    179     drwav_open_file()
    180     drwav_open_file_ex()
    181     drwav_open_file_write()
    182     drwav_open_file_write_sequential()
    183     drwav_open_memory()
    184     drwav_open_memory_ex()
    185     drwav_open_memory_write()
    186     drwav_open_memory_write_sequential()
    187     drwav_close()
    188 
    189 These APIs will be removed completely in a future version. The rationale for this change is to remove confusion between the
    190 two different ways to initialize a drwav object.
    191 */
    192 
    193 /*
    194 USAGE
    195 =====
    196 This is a single-file library. To use it, do something like the following in one .c file.
    197     #define DR_WAV_IMPLEMENTATION
    198     #include "dr_wav.h"
    199 
    200 You can then #include this file in other parts of the program as you would with any other header file. Do something
    201 like the following to read audio data:
    202 
    203     drwav wav;
    204     if (!drwav_init_file(&wav, "my_song.wav")) {
    205         // Error opening WAV file.
    206     }
    207 
    208     drwav_int32* pDecodedInterleavedPCMFrames = malloc(wav.totalPCMFrameCount * wav.channels * sizeof(drwav_int32));
    209     size_t numberOfSamplesActuallyDecoded = drwav_read_pcm_frames_s32(&wav, wav.totalPCMFrameCount, pDecodedInterleavedPCMFrames);
    210 
    211     ...
    212 
    213     drwav_uninit(&wav);
    214 
    215 If you just want to quickly open and read the audio data in a single operation you can do something like this:
    216 
    217     unsigned int channels;
    218     unsigned int sampleRate;
    219     drwav_uint64 totalPCMFrameCount;
    220     float* pSampleData = drwav_open_file_and_read_pcm_frames_f32("my_song.wav", &channels, &sampleRate, &totalPCMFrameCount);
    221     if (pSampleData == NULL) {
    222         // Error opening and reading WAV file.
    223     }
    224 
    225     ...
    226 
    227     drwav_free(pSampleData);
    228 
    229 The examples above use versions of the API that convert the audio data to a consistent format (32-bit signed PCM, in
    230 this case), but you can still output the audio data in its internal format (see notes below for supported formats):
    231 
    232     size_t framesRead = drwav_read_pcm_frames(&wav, wav.totalPCMFrameCount, pDecodedInterleavedPCMFrames);
    233 
    234 You can also read the raw bytes of audio data, which could be useful if dr_wav does not have native support for
    235 a particular data format:
    236 
    237     size_t bytesRead = drwav_read_raw(&wav, bytesToRead, pRawDataBuffer);
    238 
    239 
    240 dr_wav can also be used to output WAV files. This does not currently support compressed formats. To use this, look at
    241 drwav_init_write(), drwav_init_file_write(), etc. Use drwav_write_pcm_frames() to write samples, or drwav_write_raw()
    242 to write raw data in the "data" chunk.
    243 
    244     drwav_data_format format;
    245     format.container = drwav_container_riff;     // <-- drwav_container_riff = normal WAV files, drwav_container_w64 = Sony Wave64.
    246     format.format = DR_WAVE_FORMAT_PCM;          // <-- Any of the DR_WAVE_FORMAT_* codes.
    247     format.channels = 2;
    248     format.sampleRate = 44100;
    249     format.bitsPerSample = 16;
    250     drwav_init_file_write(&wav, "data/recording.wav", &format);
    251 
    252     ...
    253 
    254     drwav_uint64 framesWritten = drwav_write_pcm_frames(pWav, frameCount, pSamples);
    255 
    256 
    257 dr_wav has seamless support the Sony Wave64 format. The decoder will automatically detect it and it should Just Work
    258 without any manual intervention.
    259 
    260 
    261 OPTIONS
    262 =======
    263 #define these options before including this file.
    264 
    265 #define DR_WAV_NO_CONVERSION_API
    266   Disables conversion APIs such as drwav_read_pcm_frames_f32() and drwav_s16_to_f32().
    267 
    268 #define DR_WAV_NO_STDIO
    269   Disables APIs that initialize a decoder from a file such as drwav_init_file(), drwav_init_file_write(), etc.
    270 
    271 
    272 
    273 QUICK NOTES
    274 ===========
    275 - Samples are always interleaved.
    276 - The default read function does not do any data conversion. Use drwav_read_pcm_frames_f32(), drwav_read_pcm_frames_s32()
    277   and drwav_read_pcm_frames_s16() to read and convert audio data to 32-bit floating point, signed 32-bit integer and
    278   signed 16-bit integer samples respectively. Tested and supported internal formats include the following:
    279   - Unsigned 8-bit PCM
    280   - Signed 12-bit PCM
    281   - Signed 16-bit PCM
    282   - Signed 24-bit PCM
    283   - Signed 32-bit PCM
    284   - IEEE 32-bit floating point
    285   - IEEE 64-bit floating point
    286   - A-law and u-law
    287   - Microsoft ADPCM
    288   - IMA ADPCM (DVI, format code 0x11)
    289 - dr_wav will try to read the WAV file as best it can, even if it's not strictly conformant to the WAV format.
    290 */
    291 
    292 #ifndef dr_wav_h
    293 #define dr_wav_h
    294 
    295 #include <stddef.h>
    296 
    297 #if defined(_MSC_VER) && _MSC_VER < 1600
    298 typedef   signed char    drwav_int8;
    299 typedef unsigned char    drwav_uint8;
    300 typedef   signed short   drwav_int16;
    301 typedef unsigned short   drwav_uint16;
    302 typedef   signed int     drwav_int32;
    303 typedef unsigned int     drwav_uint32;
    304 typedef   signed __int64 drwav_int64;
    305 typedef unsigned __int64 drwav_uint64;
    306 #else
    307 #include <stdint.h>
    308 typedef int8_t           drwav_int8;
    309 typedef uint8_t          drwav_uint8;
    310 typedef int16_t          drwav_int16;
    311 typedef uint16_t         drwav_uint16;
    312 typedef int32_t          drwav_int32;
    313 typedef uint32_t         drwav_uint32;
    314 typedef int64_t          drwav_int64;
    315 typedef uint64_t         drwav_uint64;
    316 #endif
    317 typedef drwav_uint8      drwav_bool8;
    318 typedef drwav_uint32     drwav_bool32;
    319 #define DRWAV_TRUE       1
    320 #define DRWAV_FALSE      0
    321 
    322 #ifdef __cplusplus
    323 extern "C" {
    324 #endif
    325 
    326 typedef drwav_int32 drwav_result;
    327 #define DRWAV_SUCCESS                0
    328 #define DRWAV_ERROR                 -1
    329 #define DRWAV_INVALID_ARGS          -2
    330 #define DRWAV_INVALID_OPERATION     -3
    331 #define DRWAV_INVALID_FILE          -100
    332 #define DRWAV_EOF                   -101
    333 
    334 /* Common data formats. */
    335 #define DR_WAVE_FORMAT_PCM          0x1
    336 #define DR_WAVE_FORMAT_ADPCM        0x2
    337 #define DR_WAVE_FORMAT_IEEE_FLOAT   0x3
    338 #define DR_WAVE_FORMAT_ALAW         0x6
    339 #define DR_WAVE_FORMAT_MULAW        0x7
    340 #define DR_WAVE_FORMAT_DVI_ADPCM    0x11
    341 #define DR_WAVE_FORMAT_EXTENSIBLE   0xFFFE
    342 
    343 /* Constants. */
    344 #ifndef DRWAV_MAX_SMPL_LOOPS
    345 #define DRWAV_MAX_SMPL_LOOPS        1
    346 #endif
    347 
    348 /* Flags to pass into drwav_init_ex(), etc. */
    349 #define DRWAV_SEQUENTIAL            0x00000001
    350 
    351 typedef enum
    352 {
    353     drwav_seek_origin_start,
    354     drwav_seek_origin_current
    355 } drwav_seek_origin;
    356 
    357 typedef enum
    358 {
    359     drwav_container_riff,
    360     drwav_container_w64
    361 } drwav_container;
    362 
    363 typedef struct
    364 {
    365     union
    366     {
    367         drwav_uint8 fourcc[4];
    368         drwav_uint8 guid[16];
    369     } id;
    370 
    371     /* The size in bytes of the chunk. */
    372     drwav_uint64 sizeInBytes;
    373 
    374     /*
    375     RIFF = 2 byte alignment.
    376     W64  = 8 byte alignment.
    377     */
    378     unsigned int paddingSize;
    379 } drwav_chunk_header;
    380 
    381 /*
    382 Callback for when data is read. Return value is the number of bytes actually read.
    383 
    384 pUserData   [in]  The user data that was passed to drwav_init() and family.
    385 pBufferOut  [out] The output buffer.
    386 bytesToRead [in]  The number of bytes to read.
    387 
    388 Returns the number of bytes actually read.
    389 
    390 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
    391 either the entire bytesToRead is filled or you have reached the end of the stream.
    392 */
    393 typedef size_t (* drwav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
    394 
    395 /*
    396 Callback for when data is written. Returns value is the number of bytes actually written.
    397 
    398 pUserData    [in]  The user data that was passed to drwav_init_write() and family.
    399 pData        [out] A pointer to the data to write.
    400 bytesToWrite [in]  The number of bytes to write.
    401 
    402 Returns the number of bytes actually written.
    403 
    404 If the return value differs from bytesToWrite, it indicates an error.
    405 */
    406 typedef size_t (* drwav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
    407 
    408 /*
    409 Callback for when data needs to be seeked.
    410 
    411 pUserData [in] The user data that was passed to drwav_init() and family.
    412 offset    [in] The number of bytes to move, relative to the origin. Will never be negative.
    413 origin    [in] The origin of the seek - the current position or the start of the stream.
    414 
    415 Returns whether or not the seek was successful.
    416 
    417 Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which
    418 will be either drwav_seek_origin_start or drwav_seek_origin_current.
    419 */
    420 typedef drwav_bool32 (* drwav_seek_proc)(void* pUserData, int offset, drwav_seek_origin origin);
    421 
    422 /*
    423 Callback for when drwav_init_ex() finds a chunk.
    424 
    425 pChunkUserData    [in] The user data that was passed to the pChunkUserData parameter of drwav_init_ex() and family.
    426 onRead            [in] A pointer to the function to call when reading.
    427 onSeek            [in] A pointer to the function to call when seeking.
    428 pReadSeekUserData [in] The user data that was passed to the pReadSeekUserData parameter of drwav_init_ex() and family.
    429 pChunkHeader      [in] A pointer to an object containing basic header information about the chunk. Use this to identify the chunk.
    430 
    431 Returns the number of bytes read + seeked.
    432 
    433 To read data from the chunk, call onRead(), passing in pReadSeekUserData as the first parameter. Do the same
    434 for seeking with onSeek(). The return value must be the total number of bytes you have read _plus_ seeked.
    435 
    436 You must not attempt to read beyond the boundary of the chunk.
    437 */
    438 typedef drwav_uint64 (* drwav_chunk_proc)(void* pChunkUserData, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_chunk_header* pChunkHeader);
    439 
    440 typedef struct
    441 {
    442     void* pUserData;
    443     void* (* onMalloc)(size_t sz, void* pUserData);
    444     void* (* onRealloc)(void* p, size_t sz, void* pUserData);
    445     void  (* onFree)(void* p, void* pUserData);
    446 } drwav_allocation_callbacks;
    447 
    448 /* Structure for internal use. Only used for loaders opened with drwav_init_memory(). */
    449 typedef struct
    450 {
    451     const drwav_uint8* data;
    452     size_t dataSize;
    453     size_t currentReadPos;
    454 } drwav__memory_stream;
    455 
    456 /* Structure for internal use. Only used for writers opened with drwav_init_memory_write(). */
    457 typedef struct
    458 {
    459     void** ppData;
    460     size_t* pDataSize;
    461     size_t dataSize;
    462     size_t dataCapacity;
    463     size_t currentWritePos;
    464 } drwav__memory_stream_write;
    465 
    466 typedef struct
    467 {
    468     drwav_container container;  /* RIFF, W64. */
    469     drwav_uint32 format;        /* DR_WAVE_FORMAT_* */
    470     drwav_uint32 channels;
    471     drwav_uint32 sampleRate;
    472     drwav_uint32 bitsPerSample;
    473 } drwav_data_format;
    474 
    475 typedef struct
    476 {
    477     /*
    478     The format tag exactly as specified in the wave file's "fmt" chunk. This can be used by applications
    479     that require support for data formats not natively supported by dr_wav.
    480     */
    481     drwav_uint16 formatTag;
    482 
    483     /* The number of channels making up the audio data. When this is set to 1 it is mono, 2 is stereo, etc. */
    484     drwav_uint16 channels;
    485 
    486     /* The sample rate. Usually set to something like 44100. */
    487     drwav_uint32 sampleRate;
    488 
    489     /* Average bytes per second. You probably don't need this, but it's left here for informational purposes. */
    490     drwav_uint32 avgBytesPerSec;
    491 
    492     /* Block align. This is equal to the number of channels * bytes per sample. */
    493     drwav_uint16 blockAlign;
    494 
    495     /* Bits per sample. */
    496     drwav_uint16 bitsPerSample;
    497 
    498     /* The size of the extended data. Only used internally for validation, but left here for informational purposes. */
    499     drwav_uint16 extendedSize;
    500 
    501     /*
    502     The number of valid bits per sample. When <formatTag> is equal to WAVE_FORMAT_EXTENSIBLE, <bitsPerSample>
    503     is always rounded up to the nearest multiple of 8. This variable contains information about exactly how
    504     many bits a valid per sample. Mainly used for informational purposes.
    505     */
    506     drwav_uint16 validBitsPerSample;
    507 
    508     /* The channel mask. Not used at the moment. */
    509     drwav_uint32 channelMask;
    510 
    511     /* The sub-format, exactly as specified by the wave file. */
    512     drwav_uint8 subFormat[16];
    513 } drwav_fmt;
    514 
    515 typedef struct
    516 {
    517     drwav_uint32 cuePointId;
    518     drwav_uint32 type;
    519     drwav_uint32 start;
    520     drwav_uint32 end;
    521     drwav_uint32 fraction;
    522     drwav_uint32 playCount;
    523 } drwav_smpl_loop;
    524 
    525  typedef struct
    526 {
    527     drwav_uint32 manufacturer;
    528     drwav_uint32 product;
    529     drwav_uint32 samplePeriod;
    530     drwav_uint32 midiUnityNotes;
    531     drwav_uint32 midiPitchFraction;
    532     drwav_uint32 smpteFormat;
    533     drwav_uint32 smpteOffset;
    534     drwav_uint32 numSampleLoops;
    535     drwav_uint32 samplerData;
    536     drwav_smpl_loop loops[DRWAV_MAX_SMPL_LOOPS];
    537 } drwav_smpl;
    538 
    539 typedef struct
    540 {
    541     /* A pointer to the function to call when more data is needed. */
    542     drwav_read_proc onRead;
    543 
    544     /* A pointer to the function to call when data needs to be written. Only used when the drwav object is opened in write mode. */
    545     drwav_write_proc onWrite;
    546 
    547     /* A pointer to the function to call when the wav file needs to be seeked. */
    548     drwav_seek_proc onSeek;
    549 
    550     /* The user data to pass to callbacks. */
    551     void* pUserData;
    552 
    553     /* Allocation callbacks. */
    554     drwav_allocation_callbacks allocationCallbacks;
    555 
    556 
    557     /* Whether or not the WAV file is formatted as a standard RIFF file or W64. */
    558     drwav_container container;
    559 
    560 
    561     /* Structure containing format information exactly as specified by the wav file. */
    562     drwav_fmt fmt;
    563 
    564     /* The sample rate. Will be set to something like 44100. */
    565     drwav_uint32 sampleRate;
    566 
    567     /* The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. */
    568     drwav_uint16 channels;
    569 
    570     /* The bits per sample. Will be set to something like 16, 24, etc. */
    571     drwav_uint16 bitsPerSample;
    572 
    573     /* Equal to fmt.formatTag, or the value specified by fmt.subFormat if fmt.formatTag is equal to 65534 (WAVE_FORMAT_EXTENSIBLE). */
    574     drwav_uint16 translatedFormatTag;
    575 
    576     /* The total number of PCM frames making up the audio data. */
    577     drwav_uint64 totalPCMFrameCount;
    578 
    579 
    580     /* The size in bytes of the data chunk. */
    581     drwav_uint64 dataChunkDataSize;
    582     
    583     /* The position in the stream of the first byte of the data chunk. This is used for seeking. */
    584     drwav_uint64 dataChunkDataPos;
    585 
    586     /* The number of bytes remaining in the data chunk. */
    587     drwav_uint64 bytesRemaining;
    588 
    589 
    590     /*
    591     Only used in sequential write mode. Keeps track of the desired size of the "data" chunk at the point of initialization time. Always
    592     set to 0 for non-sequential writes and when the drwav object is opened in read mode. Used for validation.
    593     */
    594     drwav_uint64 dataChunkDataSizeTargetWrite;
    595 
    596     /* Keeps track of whether or not the wav writer was initialized in sequential mode. */
    597     drwav_bool32 isSequentialWrite;
    598 
    599 
    600     /* smpl chunk. */
    601     drwav_smpl smpl;
    602 
    603 
    604     /* A hack to avoid a DRWAV_MALLOC() when opening a decoder with drwav_init_memory(). */
    605     drwav__memory_stream memoryStream;
    606     drwav__memory_stream_write memoryStreamWrite;
    607 
    608     /* Generic data for compressed formats. This data is shared across all block-compressed formats. */
    609     struct
    610     {
    611         drwav_uint64 iCurrentPCMFrame;  /* The index of the next PCM frame that will be read by drwav_read_*(). This is used with "totalPCMFrameCount" to ensure we don't read excess samples at the end of the last block. */
    612     } compressed;
    613     
    614     /* Microsoft ADPCM specific data. */
    615     struct
    616     {
    617         drwav_uint32 bytesRemainingInBlock;
    618         drwav_uint16 predictor[2];
    619         drwav_int32  delta[2];
    620         drwav_int32  cachedFrames[4];  /* Samples are stored in this cache during decoding. */
    621         drwav_uint32 cachedFrameCount;
    622         drwav_int32  prevFrames[2][2]; /* The previous 2 samples for each channel (2 channels at most). */
    623     } msadpcm;
    624 
    625     /* IMA ADPCM specific data. */
    626     struct
    627     {
    628         drwav_uint32 bytesRemainingInBlock;
    629         drwav_int32  predictor[2];
    630         drwav_int32  stepIndex[2];
    631         drwav_int32  cachedFrames[16]; /* Samples are stored in this cache during decoding. */
    632         drwav_uint32 cachedFrameCount;
    633     } ima;
    634 } drwav;
    635 
    636 
    637 /*
    638 Initializes a pre-allocated drwav object for reading.
    639 
    640 pWav                         [out]          A pointer to the drwav object being initialized.
    641 onRead                       [in]           The function to call when data needs to be read from the client.
    642 onSeek                       [in]           The function to call when the read position of the client data needs to move.
    643 onChunk                      [in, optional] The function to call when a chunk is enumerated at initialized time.
    644 pUserData, pReadSeekUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
    645 pChunkUserData               [in, optional] A pointer to application defined data that will be passed to onChunk.
    646 flags                        [in, optional] A set of flags for controlling how things are loaded.
    647 
    648 Returns true if successful; false otherwise.
    649 
    650 Close the loader with drwav_uninit().
    651 
    652 This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory()
    653 to open the stream from a file or from a block of memory respectively.
    654 
    655 Possible values for flags:
    656   DRWAV_SEQUENTIAL: Never perform a backwards seek while loading. This disables the chunk callback and will cause this function
    657                     to return as soon as the data chunk is found. Any chunks after the data chunk will be ignored.
    658 
    659 drwav_init() is equivalent to "drwav_init_ex(pWav, onRead, onSeek, NULL, pUserData, NULL, 0);".
    660 
    661 The onChunk callback is not called for the WAVE or FMT chunks. The contents of the FMT chunk can be read from pWav->fmt
    662 after the function returns.
    663 
    664 See also: drwav_init_file(), drwav_init_memory(), drwav_uninit()
    665 */
    666 drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
    667 drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
    668 
    669 /*
    670 Initializes a pre-allocated drwav object for writing.
    671 
    672 onWrite   [in]           The function to call when data needs to be written.
    673 onSeek    [in]           The function to call when the write position needs to move.
    674 pUserData [in, optional] A pointer to application defined data that will be passed to onWrite and onSeek.
    675 
    676 Returns true if successful; false otherwise.
    677 
    678 Close the writer with drwav_uninit().
    679 
    680 This is the lowest level function for initializing a WAV file. You can also use drwav_init_file_write() and drwav_init_memory_write()
    681 to open the stream from a file or from a block of memory respectively.
    682 
    683 If the total sample count is known, you can use drwav_init_write_sequential(). This avoids the need for dr_wav to perform
    684 a post-processing step for storing the total sample count and the size of the data chunk which requires a backwards seek.
    685 
    686 See also: drwav_init_file_write(), drwav_init_memory_write(), drwav_uninit()
    687 */
    688 drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
    689 drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
    690 drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
    691 
    692 /*
    693 Utility function to determine the target size of the entire data to be written (including all headers and chunks).
    694 
    695 Returns the target size in bytes.
    696 
    697 Useful if the application needs to know the size to allocate.
    698 
    699 Only writing to the RIFF chunk and one data chunk is currently supported.
    700 
    701 See also: drwav_init_write(), drwav_init_file_write(), drwav_init_memory_write()
    702 */
    703 drwav_uint64 drwav_target_write_size_bytes(drwav_data_format const *format, drwav_uint64 totalSampleCount);
    704 
    705 /*
    706 Uninitializes the given drwav object.
    707 
    708 Use this only for objects initialized with drwav_init*() functions (drwav_init(), drwav_init_ex(), drwav_init_write(), drwav_init_write_sequential()).
    709 */
    710 drwav_result drwav_uninit(drwav* pWav);
    711 
    712 
    713 /*
    714 Reads raw audio data.
    715 
    716 This is the lowest level function for reading audio data. It simply reads the given number of
    717 bytes of the raw internal sample data.
    718 
    719 Consider using drwav_read_pcm_frames_s16(), drwav_read_pcm_frames_s32() or drwav_read_pcm_frames_f32() for
    720 reading sample data in a consistent format.
    721 
    722 Returns the number of bytes actually read.
    723 */
    724 size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
    725 
    726 /*
    727 Reads up to the specified number of PCM frames from the WAV file.
    728 
    729 The output data will be in the file's internal format, converted to native-endian byte order. Use
    730 drwav_read_pcm_frames_s16/f32/s32() to read data in a specific format.
    731 
    732 If the return value is less than <framesToRead> it means the end of the file has been reached or
    733 you have requested more PCM frames than can possibly fit in the output buffer.
    734 
    735 This function will only work when sample data is of a fixed size and uncompressed. If you are
    736 using a compressed format consider using drwav_read_raw() or drwav_read_pcm_frames_s16/s32/f32().
    737 */
    738 drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
    739 drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
    740 drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
    741 
    742 /*
    743 Seeks to the given PCM frame.
    744 
    745 Returns true if successful; false otherwise.
    746 */
    747 drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex);
    748 
    749 
    750 /*
    751 Writes raw audio data.
    752 
    753 Returns the number of bytes actually written. If this differs from bytesToWrite, it indicates an error.
    754 */
    755 size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
    756 
    757 /*
    758 Writes PCM frames.
    759 
    760 Returns the number of PCM frames written.
    761 
    762 Input samples need to be in native-endian byte order. On big-endian architectures the input data will be converted to
    763 little-endian. Use drwav_write_raw() to write raw audio data without performing any conversion.
    764 */
    765 drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
    766 drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
    767 drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
    768 
    769 
    770 /* Conversion Utilities */
    771 #ifndef DR_WAV_NO_CONVERSION_API
    772 
    773 /*
    774 Reads a chunk of audio data and converts it to signed 16-bit PCM samples.
    775 
    776 Returns the number of PCM frames actually read.
    777 
    778 If the return value is less than <framesToRead> it means the end of the file has been reached.
    779 */
    780 drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
    781 drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
    782 drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
    783 
    784 /* Low-level function for converting unsigned 8-bit PCM samples to signed 16-bit PCM samples. */
    785 void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
    786 
    787 /* Low-level function for converting signed 24-bit PCM samples to signed 16-bit PCM samples. */
    788 void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
    789 
    790 /* Low-level function for converting signed 32-bit PCM samples to signed 16-bit PCM samples. */
    791 void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
    792 
    793 /* Low-level function for converting IEEE 32-bit floating point samples to signed 16-bit PCM samples. */
    794 void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
    795 
    796 /* Low-level function for converting IEEE 64-bit floating point samples to signed 16-bit PCM samples. */
    797 void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
    798 
    799 /* Low-level function for converting A-law samples to signed 16-bit PCM samples. */
    800 void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
    801 
    802 /* Low-level function for converting u-law samples to signed 16-bit PCM samples. */
    803 void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
    804 
    805 
    806 /*
    807 Reads a chunk of audio data and converts it to IEEE 32-bit floating point samples.
    808 
    809 Returns the number of PCM frames actually read.
    810 
    811 If the return value is less than <framesToRead> it means the end of the file has been reached.
    812 */
    813 drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
    814 drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
    815 drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
    816 
    817 /* Low-level function for converting unsigned 8-bit PCM samples to IEEE 32-bit floating point samples. */
    818 void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
    819 
    820 /* Low-level function for converting signed 16-bit PCM samples to IEEE 32-bit floating point samples. */
    821 void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
    822 
    823 /* Low-level function for converting signed 24-bit PCM samples to IEEE 32-bit floating point samples. */
    824 void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
    825 
    826 /* Low-level function for converting signed 32-bit PCM samples to IEEE 32-bit floating point samples. */
    827 void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
    828 
    829 /* Low-level function for converting IEEE 64-bit floating point samples to IEEE 32-bit floating point samples. */
    830 void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
    831 
    832 /* Low-level function for converting A-law samples to IEEE 32-bit floating point samples. */
    833 void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
    834 
    835 /* Low-level function for converting u-law samples to IEEE 32-bit floating point samples. */
    836 void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
    837 
    838 
    839 /*
    840 Reads a chunk of audio data and converts it to signed 32-bit PCM samples.
    841 
    842 Returns the number of PCM frames actually read.
    843 
    844 If the return value is less than <framesToRead> it means the end of the file has been reached.
    845 */
    846 drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
    847 drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
    848 drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
    849 
    850 /* Low-level function for converting unsigned 8-bit PCM samples to signed 32-bit PCM samples. */
    851 void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
    852 
    853 /* Low-level function for converting signed 16-bit PCM samples to signed 32-bit PCM samples. */
    854 void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
    855 
    856 /* Low-level function for converting signed 24-bit PCM samples to signed 32-bit PCM samples. */
    857 void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
    858 
    859 /* Low-level function for converting IEEE 32-bit floating point samples to signed 32-bit PCM samples. */
    860 void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
    861 
    862 /* Low-level function for converting IEEE 64-bit floating point samples to signed 32-bit PCM samples. */
    863 void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
    864 
    865 /* Low-level function for converting A-law samples to signed 32-bit PCM samples. */
    866 void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
    867 
    868 /* Low-level function for converting u-law samples to signed 32-bit PCM samples. */
    869 void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
    870 
    871 #endif  /* DR_WAV_NO_CONVERSION_API */
    872 
    873 
    874 /* High-Level Convenience Helpers */
    875 
    876 #ifndef DR_WAV_NO_STDIO
    877 /*
    878 Helper for initializing a wave file for reading using stdio.
    879 
    880 This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
    881 objects because the operating system may restrict the number of file handles an application can have open at
    882 any given time.
    883 */
    884 drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
    885 drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
    886 drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
    887 drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
    888 
    889 /*
    890 Helper for initializing a wave file for writing using stdio.
    891 
    892 This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
    893 objects because the operating system may restrict the number of file handles an application can have open at
    894 any given time.
    895 */
    896 drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
    897 drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    898 drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    899 drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
    900 drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    901 drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    902 #endif  /* DR_WAV_NO_STDIO */
    903 
    904 /*
    905 Helper for initializing a loader from a pre-allocated memory buffer.
    906 
    907 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
    908 the lifetime of the drwav object.
    909 
    910 The buffer should contain the contents of the entire wave file, not just the sample data.
    911 */
    912 drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
    913 drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
    914 
    915 /*
    916 Helper for initializing a writer which outputs data to a memory buffer.
    917 
    918 dr_wav will manage the memory allocations, however it is up to the caller to free the data with drwav_free().
    919 
    920 The buffer will remain allocated even after drwav_uninit() is called. Indeed, the buffer should not be
    921 considered valid until after drwav_uninit() has been called anyway.
    922 */
    923 drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
    924 drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    925 drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
    926 
    927 
    928 #ifndef DR_WAV_NO_CONVERSION_API
    929 /*
    930 Opens and reads an entire wav file in a single operation.
    931 
    932 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
    933 */
    934 drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    935 float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    936 drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    937 #ifndef DR_WAV_NO_STDIO
    938 /*
    939 Opens and decodes an entire wav file in a single operation.
    940 
    941 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
    942 */
    943 drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    944 float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    945 drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    946 drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    947 float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    948 drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    949 #endif
    950 /*
    951 Opens and decodes an entire wav file from a block of memory in a single operation.
    952 
    953 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
    954 */
    955 drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    956 float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    957 drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
    958 #endif
    959 
    960 /* Frees data that was allocated internally by dr_wav. */
    961 void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
    962 
    963 #ifdef __cplusplus
    964 }
    965 #endif
    966 #endif  /* dr_wav_h */
    967 
    968 
    969 /************************************************************************************************************************************************************
    970  ************************************************************************************************************************************************************
    971 
    972  IMPLEMENTATION
    973 
    974  ************************************************************************************************************************************************************
    975  ************************************************************************************************************************************************************/
    976 #ifdef DR_WAV_IMPLEMENTATION
    977 #include <stdlib.h>
    978 #include <string.h> /* For memcpy(), memset() */
    979 #include <limits.h> /* For INT_MAX */
    980 
    981 #ifndef DR_WAV_NO_STDIO
    982 #include <stdio.h>
    983 #include <wchar.h>
    984 #endif
    985 
    986 /* Standard library stuff. */
    987 #ifndef DRWAV_ASSERT
    988 #include <assert.h>
    989 #define DRWAV_ASSERT(expression)           assert(expression)
    990 #endif
    991 #ifndef DRWAV_MALLOC
    992 #define DRWAV_MALLOC(sz)                   malloc((sz))
    993 #endif
    994 #ifndef DRWAV_REALLOC
    995 #define DRWAV_REALLOC(p, sz)               realloc((p), (sz))
    996 #endif
    997 #ifndef DRWAV_FREE
    998 #define DRWAV_FREE(p)                      free((p))
    999 #endif
   1000 #ifndef DRWAV_COPY_MEMORY
   1001 #define DRWAV_COPY_MEMORY(dst, src, sz)    memcpy((dst), (src), (sz))
   1002 #endif
   1003 #ifndef DRWAV_ZERO_MEMORY
   1004 #define DRWAV_ZERO_MEMORY(p, sz)           memset((p), 0, (sz))
   1005 #endif
   1006 
   1007 #define drwav_countof(x)                   (sizeof(x) / sizeof(x[0]))
   1008 #define drwav_align(x, a)                  ((((x) + (a) - 1) / (a)) * (a))
   1009 #define drwav_min(a, b)                    (((a) < (b)) ? (a) : (b))
   1010 #define drwav_max(a, b)                    (((a) > (b)) ? (a) : (b))
   1011 #define drwav_clamp(x, lo, hi)             (drwav_max((lo), drwav_min((hi), (x))))
   1012 
   1013 #define DRWAV_MAX_SIMD_VECTOR_SIZE         64  /* 64 for AVX-512 in the future. */
   1014 
   1015 /* CPU architecture. */
   1016 #if defined(__x86_64__) || defined(_M_X64)
   1017     #define DRWAV_X64
   1018 #elif defined(__i386) || defined(_M_IX86)
   1019     #define DRWAV_X86
   1020 #elif defined(__arm__) || defined(_M_ARM)
   1021     #define DRWAV_ARM
   1022 #endif
   1023 
   1024 #ifdef _MSC_VER
   1025     #define DRWAV_INLINE __forceinline
   1026 #elif defined(__GNUC__)
   1027     /*
   1028     I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
   1029     the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
   1030     case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
   1031     command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
   1032     I am using "__inline__" only when we're compiling in strict ANSI mode.
   1033     */
   1034     #if defined(__STRICT_ANSI__)
   1035         #define DRWAV_INLINE __inline__ __attribute__((always_inline))
   1036     #else
   1037         #define DRWAV_INLINE inline __attribute__((always_inline))
   1038     #endif
   1039 #else
   1040     #define DRWAV_INLINE
   1041 #endif
   1042 
   1043 #if defined(SIZE_MAX)
   1044     #define DRWAV_SIZE_MAX  SIZE_MAX
   1045 #else
   1046     #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
   1047         #define DRWAV_SIZE_MAX  ((drwav_uint64)0xFFFFFFFFFFFFFFFF)
   1048     #else
   1049         #define DRWAV_SIZE_MAX  0xFFFFFFFF
   1050     #endif
   1051 #endif
   1052 
   1053 #if defined(_MSC_VER) && _MSC_VER >= 1300
   1054     #define DRWAV_HAS_BYTESWAP16_INTRINSIC
   1055     #define DRWAV_HAS_BYTESWAP32_INTRINSIC
   1056     #define DRWAV_HAS_BYTESWAP64_INTRINSIC
   1057 #elif defined(__clang__)
   1058     #if defined(__has_builtin)
   1059         #if __has_builtin(__builtin_bswap16)
   1060             #define DRWAV_HAS_BYTESWAP16_INTRINSIC
   1061         #endif
   1062         #if __has_builtin(__builtin_bswap32)
   1063             #define DRWAV_HAS_BYTESWAP32_INTRINSIC
   1064         #endif
   1065         #if __has_builtin(__builtin_bswap64)
   1066             #define DRWAV_HAS_BYTESWAP64_INTRINSIC
   1067         #endif
   1068     #endif
   1069 #elif defined(__GNUC__)
   1070     #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
   1071         #define DRWAV_HAS_BYTESWAP32_INTRINSIC
   1072         #define DRWAV_HAS_BYTESWAP64_INTRINSIC
   1073     #endif
   1074     #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
   1075         #define DRWAV_HAS_BYTESWAP16_INTRINSIC
   1076     #endif
   1077 #endif
   1078 
   1079 static const drwav_uint8 drwavGUID_W64_RIFF[16] = {0x72,0x69,0x66,0x66, 0x2E,0x91, 0xCF,0x11, 0xA5,0xD6, 0x28,0xDB,0x04,0xC1,0x00,0x00};    /* 66666972-912E-11CF-A5D6-28DB04C10000 */
   1080 static const drwav_uint8 drwavGUID_W64_WAVE[16] = {0x77,0x61,0x76,0x65, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 65766177-ACF3-11D3-8CD1-00C04F8EDB8A */
   1081 static const drwav_uint8 drwavGUID_W64_JUNK[16] = {0x6A,0x75,0x6E,0x6B, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 6B6E756A-ACF3-11D3-8CD1-00C04F8EDB8A */
   1082 static const drwav_uint8 drwavGUID_W64_FMT [16] = {0x66,0x6D,0x74,0x20, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 20746D66-ACF3-11D3-8CD1-00C04F8EDB8A */
   1083 static const drwav_uint8 drwavGUID_W64_FACT[16] = {0x66,0x61,0x63,0x74, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 74636166-ACF3-11D3-8CD1-00C04F8EDB8A */
   1084 static const drwav_uint8 drwavGUID_W64_DATA[16] = {0x64,0x61,0x74,0x61, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 61746164-ACF3-11D3-8CD1-00C04F8EDB8A */
   1085 static const drwav_uint8 drwavGUID_W64_SMPL[16] = {0x73,0x6D,0x70,0x6C, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};    /* 6C706D73-ACF3-11D3-8CD1-00C04F8EDB8A */
   1086 
   1087 static DRWAV_INLINE drwav_bool32 drwav__guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16])
   1088 {
   1089     const drwav_uint32* a32 = (const drwav_uint32*)a;
   1090     const drwav_uint32* b32 = (const drwav_uint32*)b;
   1091 
   1092     return
   1093         a32[0] == b32[0] &&
   1094         a32[1] == b32[1] &&
   1095         a32[2] == b32[2] &&
   1096         a32[3] == b32[3];
   1097 }
   1098 
   1099 static DRWAV_INLINE drwav_bool32 drwav__fourcc_equal(const unsigned char* a, const char* b)
   1100 {
   1101     return
   1102         a[0] == b[0] &&
   1103         a[1] == b[1] &&
   1104         a[2] == b[2] &&
   1105         a[3] == b[3];
   1106 }
   1107 
   1108 
   1109 
   1110 static DRWAV_INLINE int drwav__is_little_endian()
   1111 {
   1112 #if defined(DRWAV_X86) || defined(DRWAV_X64)
   1113     return DRWAV_TRUE;
   1114 #elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
   1115     return DRWAV_TRUE;
   1116 #else
   1117     int n = 1;
   1118     return (*(char*)&n) == 1;
   1119 #endif
   1120 }
   1121 
   1122 static DRWAV_INLINE unsigned short drwav__bytes_to_u16(const unsigned char* data)
   1123 {
   1124     return (data[0] << 0) | (data[1] << 8);
   1125 }
   1126 
   1127 static DRWAV_INLINE short drwav__bytes_to_s16(const unsigned char* data)
   1128 {
   1129     return (short)drwav__bytes_to_u16(data);
   1130 }
   1131 
   1132 static DRWAV_INLINE unsigned int drwav__bytes_to_u32(const unsigned char* data)
   1133 {
   1134     return (data[0] << 0) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
   1135 }
   1136 
   1137 static DRWAV_INLINE drwav_uint64 drwav__bytes_to_u64(const unsigned char* data)
   1138 {
   1139     return
   1140         ((drwav_uint64)data[0] <<  0) | ((drwav_uint64)data[1] <<  8) | ((drwav_uint64)data[2] << 16) | ((drwav_uint64)data[3] << 24) |
   1141         ((drwav_uint64)data[4] << 32) | ((drwav_uint64)data[5] << 40) | ((drwav_uint64)data[6] << 48) | ((drwav_uint64)data[7] << 56);
   1142 }
   1143 
   1144 static DRWAV_INLINE void drwav__bytes_to_guid(const unsigned char* data, drwav_uint8* guid)
   1145 {
   1146     int i;
   1147     for (i = 0; i < 16; ++i) {
   1148         guid[i] = data[i];
   1149     }
   1150 }
   1151 
   1152 
   1153 static DRWAV_INLINE drwav_uint16 drwav__bswap16(drwav_uint16 n)
   1154 {
   1155 #ifdef DRWAV_HAS_BYTESWAP16_INTRINSIC
   1156     #if defined(_MSC_VER)
   1157         return _byteswap_ushort(n);
   1158     #elif defined(__GNUC__) || defined(__clang__)
   1159         return __builtin_bswap16(n);
   1160     #else
   1161         #error "This compiler does not support the byte swap intrinsic."
   1162     #endif
   1163 #else
   1164     return ((n & 0xFF00) >> 8) |
   1165            ((n & 0x00FF) << 8);
   1166 #endif
   1167 }
   1168 
   1169 static DRWAV_INLINE drwav_uint32 drwav__bswap32(drwav_uint32 n)
   1170 {
   1171 #ifdef DRWAV_HAS_BYTESWAP32_INTRINSIC
   1172     #if defined(_MSC_VER)
   1173         return _byteswap_ulong(n);
   1174     #elif defined(__GNUC__) || defined(__clang__)
   1175         #if defined(DRWAV_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRWAV_64BIT)   /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
   1176             /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
   1177             drwav_uint32 r;
   1178             __asm__ __volatile__ (
   1179             #if defined(DRWAV_64BIT)
   1180                 "rev %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(n)   /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
   1181             #else
   1182                 "rev %[out], %[in]" : [out]"=r"(r) : [in]"r"(n)
   1183             #endif
   1184             );
   1185             return r;
   1186         #else
   1187             return __builtin_bswap32(n);
   1188         #endif
   1189     #else
   1190         #error "This compiler does not support the byte swap intrinsic."
   1191     #endif
   1192 #else
   1193     return ((n & 0xFF000000) >> 24) |
   1194            ((n & 0x00FF0000) >>  8) |
   1195            ((n & 0x0000FF00) <<  8) |
   1196            ((n & 0x000000FF) << 24);
   1197 #endif
   1198 }
   1199 
   1200 static DRWAV_INLINE drwav_uint64 drwav__bswap64(drwav_uint64 n)
   1201 {
   1202 #ifdef DRWAV_HAS_BYTESWAP64_INTRINSIC
   1203     #if defined(_MSC_VER)
   1204         return _byteswap_uint64(n);
   1205     #elif defined(__GNUC__) || defined(__clang__)
   1206         return __builtin_bswap64(n);
   1207     #else
   1208         #error "This compiler does not support the byte swap intrinsic."
   1209     #endif
   1210 #else
   1211     return ((n & (drwav_uint64)0xFF00000000000000) >> 56) |
   1212            ((n & (drwav_uint64)0x00FF000000000000) >> 40) |
   1213            ((n & (drwav_uint64)0x0000FF0000000000) >> 24) |
   1214            ((n & (drwav_uint64)0x000000FF00000000) >>  8) |
   1215            ((n & (drwav_uint64)0x00000000FF000000) <<  8) |
   1216            ((n & (drwav_uint64)0x0000000000FF0000) << 24) |
   1217            ((n & (drwav_uint64)0x000000000000FF00) << 40) |
   1218            ((n & (drwav_uint64)0x00000000000000FF) << 56);
   1219 #endif
   1220 }
   1221 
   1222 
   1223 static DRWAV_INLINE drwav_int16 drwav__bswap_s16(drwav_int16 n)
   1224 {
   1225     return (drwav_int16)drwav__bswap16((drwav_uint16)n);
   1226 }
   1227 
   1228 static DRWAV_INLINE void drwav__bswap_samples_s16(drwav_int16* pSamples, drwav_uint64 sampleCount)
   1229 {
   1230     drwav_uint64 iSample;
   1231     for (iSample = 0; iSample < sampleCount; iSample += 1) {
   1232         pSamples[iSample] = drwav__bswap_s16(pSamples[iSample]);
   1233     }
   1234 }
   1235 
   1236 
   1237 static DRWAV_INLINE void drwav__bswap_s24(drwav_uint8* p)
   1238 {
   1239     drwav_uint8 t;
   1240     t = p[0];
   1241     p[0] = p[2];
   1242     p[2] = t;
   1243 }
   1244 
   1245 static DRWAV_INLINE void drwav__bswap_samples_s24(drwav_uint8* pSamples, drwav_uint64 sampleCount)
   1246 {
   1247     drwav_uint64 iSample;
   1248     for (iSample = 0; iSample < sampleCount; iSample += 1) {
   1249         drwav_uint8* pSample = pSamples + (iSample*3);
   1250         drwav__bswap_s24(pSample);
   1251     }
   1252 }
   1253 
   1254 
   1255 static DRWAV_INLINE drwav_int32 drwav__bswap_s32(drwav_int32 n)
   1256 {
   1257     return (drwav_int32)drwav__bswap32((drwav_uint32)n);
   1258 }
   1259 
   1260 static DRWAV_INLINE void drwav__bswap_samples_s32(drwav_int32* pSamples, drwav_uint64 sampleCount)
   1261 {
   1262     drwav_uint64 iSample;
   1263     for (iSample = 0; iSample < sampleCount; iSample += 1) {
   1264         pSamples[iSample] = drwav__bswap_s32(pSamples[iSample]);
   1265     }
   1266 }
   1267 
   1268 
   1269 static DRWAV_INLINE float drwav__bswap_f32(float n)
   1270 {
   1271     union {
   1272         drwav_uint32 i;
   1273         float f;
   1274     } x;
   1275     x.f = n;
   1276     x.i = drwav__bswap32(x.i);
   1277 
   1278     return x.f;
   1279 }
   1280 
   1281 static DRWAV_INLINE void drwav__bswap_samples_f32(float* pSamples, drwav_uint64 sampleCount)
   1282 {
   1283     drwav_uint64 iSample;
   1284     for (iSample = 0; iSample < sampleCount; iSample += 1) {
   1285         pSamples[iSample] = drwav__bswap_f32(pSamples[iSample]);
   1286     }
   1287 }
   1288 
   1289 
   1290 static DRWAV_INLINE double drwav__bswap_f64(double n)
   1291 {
   1292     union {
   1293         drwav_uint64 i;
   1294         double f;
   1295     } x;
   1296     x.f = n;
   1297     x.i = drwav__bswap64(x.i);
   1298 
   1299     return x.f;
   1300 }
   1301 
   1302 static DRWAV_INLINE void drwav__bswap_samples_f64(double* pSamples, drwav_uint64 sampleCount)
   1303 {
   1304     drwav_uint64 iSample;
   1305     for (iSample = 0; iSample < sampleCount; iSample += 1) {
   1306         pSamples[iSample] = drwav__bswap_f64(pSamples[iSample]);
   1307     }
   1308 }
   1309 
   1310 
   1311 static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
   1312 {
   1313     /* Assumes integer PCM. Floating point PCM is done in drwav__bswap_samples_ieee(). */
   1314     switch (bytesPerSample)
   1315     {
   1316         case 2: /* s16, s12 (loosely packed) */
   1317         {
   1318             drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
   1319         } break;
   1320         case 3: /* s24 */
   1321         {
   1322             drwav__bswap_samples_s24((drwav_uint8*)pSamples, sampleCount);
   1323         } break;
   1324         case 4: /* s32 */
   1325         {
   1326             drwav__bswap_samples_s32((drwav_int32*)pSamples, sampleCount);
   1327         } break;
   1328         default:
   1329         {
   1330             /* Unsupported format. */
   1331             DRWAV_ASSERT(DRWAV_FALSE);
   1332         } break;
   1333     }
   1334 }
   1335 
   1336 static DRWAV_INLINE void drwav__bswap_samples_ieee(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
   1337 {
   1338     switch (bytesPerSample)
   1339     {
   1340     #if 0   /* Contributions welcome for f16 support. */
   1341         case 2: /* f16 */
   1342         {
   1343             drwav__bswap_samples_f16((drwav_float16*)pSamples, sampleCount);
   1344         } break;
   1345     #endif
   1346         case 4: /* f32 */
   1347         {
   1348             drwav__bswap_samples_f32((float*)pSamples, sampleCount);
   1349         } break;
   1350         case 8: /* f64 */
   1351         {
   1352             drwav__bswap_samples_f64((double*)pSamples, sampleCount);
   1353         } break;
   1354         default:
   1355         {
   1356             /* Unsupported format. */
   1357             DRWAV_ASSERT(DRWAV_FALSE);
   1358         } break;
   1359     }
   1360 }
   1361 
   1362 static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample, drwav_uint16 format)
   1363 {
   1364     switch (format)
   1365     {
   1366         case DR_WAVE_FORMAT_PCM:
   1367         {
   1368             drwav__bswap_samples_pcm(pSamples, sampleCount, bytesPerSample);
   1369         } break;
   1370 
   1371         case DR_WAVE_FORMAT_IEEE_FLOAT:
   1372         {
   1373             drwav__bswap_samples_ieee(pSamples, sampleCount, bytesPerSample);
   1374         } break;
   1375 
   1376         case DR_WAVE_FORMAT_ALAW:
   1377         case DR_WAVE_FORMAT_MULAW:
   1378         {
   1379             drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
   1380         } break;
   1381 
   1382         case DR_WAVE_FORMAT_ADPCM:
   1383         case DR_WAVE_FORMAT_DVI_ADPCM:
   1384         default:
   1385         {
   1386             /* Unsupported format. */
   1387             DRWAV_ASSERT(DRWAV_FALSE);
   1388         } break;
   1389     }
   1390 }
   1391 
   1392 
   1393 static void* drwav__malloc_default(size_t sz, void* pUserData)
   1394 {
   1395     (void)pUserData;
   1396     return DRWAV_MALLOC(sz);
   1397 }
   1398 
   1399 static void* drwav__realloc_default(void* p, size_t sz, void* pUserData)
   1400 {
   1401     (void)pUserData;
   1402     return DRWAV_REALLOC(p, sz);
   1403 }
   1404 
   1405 static void drwav__free_default(void* p, void* pUserData)
   1406 {
   1407     (void)pUserData;
   1408     DRWAV_FREE(p);
   1409 }
   1410 
   1411 
   1412 static void* drwav__malloc_from_callbacks(size_t sz, const drwav_allocation_callbacks* pAllocationCallbacks)
   1413 {
   1414     if (pAllocationCallbacks == NULL) {
   1415         return NULL;
   1416     }
   1417 
   1418     if (pAllocationCallbacks->onMalloc != NULL) {
   1419         return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
   1420     }
   1421 
   1422     /* Try using realloc(). */
   1423     if (pAllocationCallbacks->onRealloc != NULL) {
   1424         return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
   1425     }
   1426 
   1427     return NULL;
   1428 }
   1429 
   1430 static void* drwav__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drwav_allocation_callbacks* pAllocationCallbacks)
   1431 {
   1432     if (pAllocationCallbacks == NULL) {
   1433         return NULL;
   1434     }
   1435 
   1436     if (pAllocationCallbacks->onRealloc != NULL) {
   1437         return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
   1438     }
   1439 
   1440     /* Try emulating realloc() in terms of malloc()/free(). */
   1441     if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
   1442         void* p2;
   1443 
   1444         p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
   1445         if (p2 == NULL) {
   1446             return NULL;
   1447         }
   1448 
   1449         DRWAV_COPY_MEMORY(p2, p, szOld);
   1450         pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
   1451 
   1452         return p2;
   1453     }
   1454 
   1455     return NULL;
   1456 }
   1457 
   1458 static void drwav__free_from_callbacks(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
   1459 {
   1460     if (p == NULL || pAllocationCallbacks == NULL) {
   1461         return;
   1462     }
   1463 
   1464     if (pAllocationCallbacks->onFree != NULL) {
   1465         pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
   1466     }
   1467 }
   1468 
   1469 
   1470 drwav_allocation_callbacks drwav_copy_allocation_callbacks_or_defaults(const drwav_allocation_callbacks* pAllocationCallbacks)
   1471 {
   1472     if (pAllocationCallbacks != NULL) {
   1473         /* Copy. */
   1474         return *pAllocationCallbacks;
   1475     } else {
   1476         /* Defaults. */
   1477         drwav_allocation_callbacks allocationCallbacks;
   1478         allocationCallbacks.pUserData = NULL;
   1479         allocationCallbacks.onMalloc  = drwav__malloc_default;
   1480         allocationCallbacks.onRealloc = drwav__realloc_default;
   1481         allocationCallbacks.onFree    = drwav__free_default;
   1482         return allocationCallbacks;
   1483     }
   1484 }
   1485 
   1486 
   1487 static DRWAV_INLINE drwav_bool32 drwav__is_compressed_format_tag(drwav_uint16 formatTag)
   1488 {
   1489     return
   1490         formatTag == DR_WAVE_FORMAT_ADPCM ||
   1491         formatTag == DR_WAVE_FORMAT_DVI_ADPCM;
   1492 }
   1493 
   1494 static unsigned int drwav__chunk_padding_size_riff(drwav_uint64 chunkSize)
   1495 {
   1496     return (unsigned int)(chunkSize % 2);
   1497 }
   1498 
   1499 static unsigned int drwav__chunk_padding_size_w64(drwav_uint64 chunkSize)
   1500 {
   1501     return (unsigned int)(chunkSize % 8);
   1502 }
   1503 
   1504 drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
   1505 drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
   1506 drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
   1507 
   1508 static drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut)
   1509 {
   1510     if (container == drwav_container_riff) {
   1511         unsigned char sizeInBytes[4];
   1512 
   1513         if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) {
   1514             return DRWAV_EOF;
   1515         }
   1516 
   1517         if (onRead(pUserData, sizeInBytes, 4) != 4) {
   1518             return DRWAV_INVALID_FILE;
   1519         }
   1520 
   1521         pHeaderOut->sizeInBytes = drwav__bytes_to_u32(sizeInBytes);
   1522         pHeaderOut->paddingSize = drwav__chunk_padding_size_riff(pHeaderOut->sizeInBytes);
   1523         *pRunningBytesReadOut += 8;
   1524     } else {
   1525         unsigned char sizeInBytes[8];
   1526 
   1527         if (onRead(pUserData, pHeaderOut->id.guid, 16) != 16) {
   1528             return DRWAV_EOF;
   1529         }
   1530 
   1531         if (onRead(pUserData, sizeInBytes, 8) != 8) {
   1532             return DRWAV_INVALID_FILE;
   1533         }
   1534 
   1535         pHeaderOut->sizeInBytes = drwav__bytes_to_u64(sizeInBytes) - 24;    /* <-- Subtract 24 because w64 includes the size of the header. */
   1536         pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
   1537         *pRunningBytesReadOut += 24;
   1538     }
   1539 
   1540     return DRWAV_SUCCESS;
   1541 }
   1542 
   1543 static drwav_bool32 drwav__seek_forward(drwav_seek_proc onSeek, drwav_uint64 offset, void* pUserData)
   1544 {
   1545     drwav_uint64 bytesRemainingToSeek = offset;
   1546     while (bytesRemainingToSeek > 0) {
   1547         if (bytesRemainingToSeek > 0x7FFFFFFF) {
   1548             if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) {
   1549                 return DRWAV_FALSE;
   1550             }
   1551             bytesRemainingToSeek -= 0x7FFFFFFF;
   1552         } else {
   1553             if (!onSeek(pUserData, (int)bytesRemainingToSeek, drwav_seek_origin_current)) {
   1554                 return DRWAV_FALSE;
   1555             }
   1556             bytesRemainingToSeek = 0;
   1557         }
   1558     }
   1559 
   1560     return DRWAV_TRUE;
   1561 }
   1562 
   1563 static drwav_bool32 drwav__seek_from_start(drwav_seek_proc onSeek, drwav_uint64 offset, void* pUserData)
   1564 {
   1565     if (offset <= 0x7FFFFFFF) {
   1566         return onSeek(pUserData, (int)offset, drwav_seek_origin_start);
   1567     }
   1568 
   1569     /* Larger than 32-bit seek. */
   1570     if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_start)) {
   1571         return DRWAV_FALSE;
   1572     }
   1573     offset -= 0x7FFFFFFF;
   1574 
   1575     for (;;) {
   1576         if (offset <= 0x7FFFFFFF) {
   1577             return onSeek(pUserData, (int)offset, drwav_seek_origin_current);
   1578         }
   1579 
   1580         if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) {
   1581             return DRWAV_FALSE;
   1582         }
   1583         offset -= 0x7FFFFFFF;
   1584     }
   1585 
   1586     /* Should never get here. */
   1587     /*return DRWAV_TRUE; */
   1588 }
   1589 
   1590 
   1591 static drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_fmt* fmtOut)
   1592 {
   1593     drwav_chunk_header header;
   1594     unsigned char fmt[16];
   1595 
   1596     if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
   1597         return DRWAV_FALSE;
   1598     }
   1599 
   1600 
   1601     /* Skip non-fmt chunks. */
   1602     while ((container == drwav_container_riff && !drwav__fourcc_equal(header.id.fourcc, "fmt ")) || (container == drwav_container_w64 && !drwav__guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
   1603         if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) {
   1604             return DRWAV_FALSE;
   1605         }
   1606         *pRunningBytesReadOut += header.sizeInBytes + header.paddingSize;
   1607 
   1608         /* Try the next header. */
   1609         if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
   1610             return DRWAV_FALSE;
   1611         }
   1612     }
   1613 
   1614 
   1615     /* Validation. */
   1616     if (container == drwav_container_riff) {
   1617         if (!drwav__fourcc_equal(header.id.fourcc, "fmt ")) {
   1618             return DRWAV_FALSE;
   1619         }
   1620     } else {
   1621         if (!drwav__guid_equal(header.id.guid, drwavGUID_W64_FMT)) {
   1622             return DRWAV_FALSE;
   1623         }
   1624     }
   1625 
   1626 
   1627     if (onRead(pUserData, fmt, sizeof(fmt)) != sizeof(fmt)) {
   1628         return DRWAV_FALSE;
   1629     }
   1630     *pRunningBytesReadOut += sizeof(fmt);
   1631 
   1632     fmtOut->formatTag      = drwav__bytes_to_u16(fmt + 0);
   1633     fmtOut->channels       = drwav__bytes_to_u16(fmt + 2);
   1634     fmtOut->sampleRate     = drwav__bytes_to_u32(fmt + 4);
   1635     fmtOut->avgBytesPerSec = drwav__bytes_to_u32(fmt + 8);
   1636     fmtOut->blockAlign     = drwav__bytes_to_u16(fmt + 12);
   1637     fmtOut->bitsPerSample  = drwav__bytes_to_u16(fmt + 14);
   1638 
   1639     fmtOut->extendedSize       = 0;
   1640     fmtOut->validBitsPerSample = 0;
   1641     fmtOut->channelMask        = 0;
   1642     memset(fmtOut->subFormat, 0, sizeof(fmtOut->subFormat));
   1643 
   1644     if (header.sizeInBytes > 16) {
   1645         unsigned char fmt_cbSize[2];
   1646         int bytesReadSoFar = 0;
   1647 
   1648         if (onRead(pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) {
   1649             return DRWAV_FALSE;    /* Expecting more data. */
   1650         }
   1651         *pRunningBytesReadOut += sizeof(fmt_cbSize);
   1652 
   1653         bytesReadSoFar = 18;
   1654 
   1655         fmtOut->extendedSize = drwav__bytes_to_u16(fmt_cbSize);
   1656         if (fmtOut->extendedSize > 0) {
   1657             /* Simple validation. */
   1658             if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
   1659                 if (fmtOut->extendedSize != 22) {
   1660                     return DRWAV_FALSE;
   1661                 }
   1662             }
   1663 
   1664             if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
   1665                 unsigned char fmtext[22];
   1666                 if (onRead(pUserData, fmtext, fmtOut->extendedSize) != fmtOut->extendedSize) {
   1667                     return DRWAV_FALSE;    /* Expecting more data. */
   1668                 }
   1669 
   1670                 fmtOut->validBitsPerSample = drwav__bytes_to_u16(fmtext + 0);
   1671                 fmtOut->channelMask        = drwav__bytes_to_u32(fmtext + 2);
   1672                 drwav__bytes_to_guid(fmtext + 6, fmtOut->subFormat);
   1673             } else {
   1674                 if (!onSeek(pUserData, fmtOut->extendedSize, drwav_seek_origin_current)) {
   1675                     return DRWAV_FALSE;
   1676                 }
   1677             }
   1678             *pRunningBytesReadOut += fmtOut->extendedSize;
   1679 
   1680             bytesReadSoFar += fmtOut->extendedSize;
   1681         }
   1682 
   1683         /* Seek past any leftover bytes. For w64 the leftover will be defined based on the chunk size. */
   1684         if (!onSeek(pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current)) {
   1685             return DRWAV_FALSE;
   1686         }
   1687         *pRunningBytesReadOut += (header.sizeInBytes - bytesReadSoFar);
   1688     }
   1689 
   1690     if (header.paddingSize > 0) {
   1691         if (!onSeek(pUserData, header.paddingSize, drwav_seek_origin_current)) {
   1692             return DRWAV_FALSE;
   1693         }
   1694         *pRunningBytesReadOut += header.paddingSize;
   1695     }
   1696 
   1697     return DRWAV_TRUE;
   1698 }
   1699 
   1700 
   1701 size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor)
   1702 {
   1703     size_t bytesRead;
   1704 
   1705     DRWAV_ASSERT(onRead != NULL);
   1706     DRWAV_ASSERT(pCursor != NULL);
   1707 
   1708     bytesRead = onRead(pUserData, pBufferOut, bytesToRead);
   1709     *pCursor += bytesRead;
   1710     return bytesRead;
   1711 }
   1712 
   1713 drwav_bool32 drwav__on_seek(drwav_seek_proc onSeek, void* pUserData, int offset, drwav_seek_origin origin, drwav_uint64* pCursor)
   1714 {
   1715     DRWAV_ASSERT(onSeek != NULL);
   1716     DRWAV_ASSERT(pCursor != NULL);
   1717 
   1718     if (!onSeek(pUserData, offset, origin)) {
   1719         return DRWAV_FALSE;
   1720     }
   1721 
   1722     if (origin == drwav_seek_origin_start) {
   1723         *pCursor = offset;
   1724     } else {
   1725         *pCursor += offset;
   1726     }
   1727 
   1728     return DRWAV_TRUE;
   1729 }
   1730 
   1731 
   1732 
   1733 static drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav)
   1734 {
   1735     /*
   1736     The bytes per frame is a bit ambiguous. It can be either be based on the bits per sample, or the block align. The way I'm doing it here
   1737     is that if the bits per sample is a multiple of 8, use floor(bitsPerSample*channels/8), otherwise fall back to the block align.
   1738     */
   1739     if ((pWav->bitsPerSample & 0x7) == 0) {
   1740         /* Bits per sample is a multiple of 8. */
   1741         return (pWav->bitsPerSample * pWav->fmt.channels) >> 3;
   1742     } else {
   1743         return pWav->fmt.blockAlign;
   1744     }
   1745 }
   1746 
   1747 
   1748 drwav_bool32 drwav_preinit(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   1749 {
   1750     if (pWav == NULL || onRead == NULL || onSeek == NULL) {
   1751         return DRWAV_FALSE;
   1752     }
   1753 
   1754     DRWAV_ZERO_MEMORY(pWav, sizeof(*pWav));
   1755     pWav->onRead    = onRead;
   1756     pWav->onSeek    = onSeek;
   1757     pWav->pUserData = pReadSeekUserData;
   1758     pWav->allocationCallbacks = drwav_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
   1759 
   1760     if (pWav->allocationCallbacks.onFree == NULL || (pWav->allocationCallbacks.onMalloc == NULL && pWav->allocationCallbacks.onRealloc == NULL)) {
   1761         return DRWAV_FALSE;    /* Invalid allocation callbacks. */
   1762     }
   1763 
   1764     return DRWAV_TRUE;
   1765 }
   1766 
   1767 drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags)
   1768 {
   1769     /* This function assumes drwav_preinit() has been called beforehand. */
   1770 
   1771     drwav_uint64 cursor;    /* <-- Keeps track of the byte position so we can seek to specific locations. */
   1772     drwav_bool32 sequential;
   1773     unsigned char riff[4];
   1774     drwav_fmt fmt;
   1775     unsigned short translatedFormatTag;
   1776     drwav_uint64 sampleCountFromFactChunk;
   1777     drwav_bool32 foundDataChunk;
   1778     drwav_uint64 dataChunkSize;
   1779     drwav_uint64 chunkSize;
   1780 
   1781     cursor = 0;
   1782     sequential = (flags & DRWAV_SEQUENTIAL) != 0;
   1783 
   1784     /* The first 4 bytes should be the RIFF identifier. */
   1785     if (drwav__on_read(pWav->onRead, pWav->pUserData, riff, sizeof(riff), &cursor) != sizeof(riff)) {
   1786         return DRWAV_FALSE;
   1787     }
   1788 
   1789     /*
   1790     The first 4 bytes can be used to identify the container. For RIFF files it will start with "RIFF" and for
   1791     w64 it will start with "riff".
   1792     */
   1793     if (drwav__fourcc_equal(riff, "RIFF")) {
   1794         pWav->container = drwav_container_riff;
   1795     } else if (drwav__fourcc_equal(riff, "riff")) {
   1796         int i;
   1797         drwav_uint8 riff2[12];
   1798 
   1799         pWav->container = drwav_container_w64;
   1800 
   1801         /* Check the rest of the GUID for validity. */
   1802         if (drwav__on_read(pWav->onRead, pWav->pUserData, riff2, sizeof(riff2), &cursor) != sizeof(riff2)) {
   1803             return DRWAV_FALSE;
   1804         }
   1805 
   1806         for (i = 0; i < 12; ++i) {
   1807             if (riff2[i] != drwavGUID_W64_RIFF[i+4]) {
   1808                 return DRWAV_FALSE;
   1809             }
   1810         }
   1811     } else {
   1812         return DRWAV_FALSE;   /* Unknown or unsupported container. */
   1813     }
   1814 
   1815 
   1816     if (pWav->container == drwav_container_riff) {
   1817         unsigned char chunkSizeBytes[4];
   1818         unsigned char wave[4];
   1819 
   1820         /* RIFF/WAVE */
   1821         if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
   1822             return DRWAV_FALSE;
   1823         }
   1824 
   1825         if (drwav__bytes_to_u32(chunkSizeBytes) < 36) {
   1826             return DRWAV_FALSE;    /* Chunk size should always be at least 36 bytes. */
   1827         }
   1828 
   1829         if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
   1830             return DRWAV_FALSE;
   1831         }
   1832 
   1833         if (!drwav__fourcc_equal(wave, "WAVE")) {
   1834             return DRWAV_FALSE;    /* Expecting "WAVE". */
   1835         }
   1836     } else {
   1837         unsigned char chunkSizeBytes[8];
   1838         drwav_uint8 wave[16];
   1839 
   1840         /* W64 */
   1841         if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
   1842             return DRWAV_FALSE;
   1843         }
   1844 
   1845         if (drwav__bytes_to_u64(chunkSizeBytes) < 80) {
   1846             return DRWAV_FALSE;
   1847         }
   1848 
   1849         if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
   1850             return DRWAV_FALSE;
   1851         }
   1852 
   1853         if (!drwav__guid_equal(wave, drwavGUID_W64_WAVE)) {
   1854             return DRWAV_FALSE;
   1855         }
   1856     }
   1857 
   1858 
   1859     /* The next bytes should be the "fmt " chunk. */
   1860     if (!drwav__read_fmt(pWav->onRead, pWav->onSeek, pWav->pUserData, pWav->container, &cursor, &fmt)) {
   1861         return DRWAV_FALSE;    /* Failed to read the "fmt " chunk. */
   1862     }
   1863 
   1864     /* Basic validation. */
   1865     if (fmt.sampleRate == 0 || fmt.channels == 0 || fmt.bitsPerSample == 0 || fmt.blockAlign == 0) {
   1866         return DRWAV_FALSE; /* Invalid channel count. Probably an invalid WAV file. */
   1867     }
   1868 
   1869 
   1870     /* Translate the internal format. */
   1871     translatedFormatTag = fmt.formatTag;
   1872     if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
   1873         translatedFormatTag = drwav__bytes_to_u16(fmt.subFormat + 0);
   1874     }
   1875 
   1876 
   1877 
   1878     sampleCountFromFactChunk = 0;
   1879 
   1880     /*
   1881     We need to enumerate over each chunk for two reasons:
   1882       1) The "data" chunk may not be the next one
   1883       2) We may want to report each chunk back to the client
   1884     
   1885     In order to correctly report each chunk back to the client we will need to keep looping until the end of the file.
   1886     */
   1887     foundDataChunk = DRWAV_FALSE;
   1888     dataChunkSize = 0;
   1889 
   1890     /* The next chunk we care about is the "data" chunk. This is not necessarily the next chunk so we'll need to loop. */
   1891     for (;;)
   1892     {
   1893         drwav_chunk_header header;
   1894         drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
   1895         if (result != DRWAV_SUCCESS) {
   1896             if (!foundDataChunk) {
   1897                 return DRWAV_FALSE;
   1898             } else {
   1899                 break;  /* Probably at the end of the file. Get out of the loop. */
   1900             }
   1901         }
   1902 
   1903         /* Tell the client about this chunk. */
   1904         if (!sequential && onChunk != NULL) {
   1905             drwav_uint64 callbackBytesRead = onChunk(pChunkUserData, pWav->onRead, pWav->onSeek, pWav->pUserData, &header);
   1906 
   1907             /*
   1908             dr_wav may need to read the contents of the chunk, so we now need to seek back to the position before
   1909             we called the callback.
   1910             */
   1911             if (callbackBytesRead > 0) {
   1912                 if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
   1913                     return DRWAV_FALSE;
   1914                 }
   1915             }
   1916         }
   1917         
   1918 
   1919         if (!foundDataChunk) {
   1920             pWav->dataChunkDataPos = cursor;
   1921         }
   1922 
   1923         chunkSize = header.sizeInBytes;
   1924         if (pWav->container == drwav_container_riff) {
   1925             if (drwav__fourcc_equal(header.id.fourcc, "data")) {
   1926                 foundDataChunk = DRWAV_TRUE;
   1927                 dataChunkSize = chunkSize;
   1928             }
   1929         } else {
   1930             if (drwav__guid_equal(header.id.guid, drwavGUID_W64_DATA)) {
   1931                 foundDataChunk = DRWAV_TRUE;
   1932                 dataChunkSize = chunkSize;
   1933             }
   1934         }
   1935 
   1936         /*
   1937         If at this point we have found the data chunk and we're running in sequential mode, we need to break out of this loop. The reason for
   1938         this is that we would otherwise require a backwards seek which sequential mode forbids.
   1939         */
   1940         if (foundDataChunk && sequential) {
   1941             break;
   1942         }
   1943 
   1944         /* Optional. Get the total sample count from the FACT chunk. This is useful for compressed formats. */
   1945         if (pWav->container == drwav_container_riff) {
   1946             if (drwav__fourcc_equal(header.id.fourcc, "fact")) {
   1947                 drwav_uint32 sampleCount;
   1948                 if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCount, 4, &cursor) != 4) {
   1949                     return DRWAV_FALSE;
   1950                 }
   1951                 chunkSize -= 4;
   1952 
   1953                 if (!foundDataChunk) {
   1954                     pWav->dataChunkDataPos = cursor;
   1955                 }
   1956 
   1957                 /*
   1958                 The sample count in the "fact" chunk is either unreliable, or I'm not understanding it properly. For now I am only enabling this
   1959                 for Microsoft ADPCM formats.
   1960                 */
   1961                 if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   1962                     sampleCountFromFactChunk = sampleCount;
   1963                 } else {
   1964                     sampleCountFromFactChunk = 0;
   1965                 }
   1966             }
   1967         } else {
   1968             if (drwav__guid_equal(header.id.guid, drwavGUID_W64_FACT)) {
   1969                 if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCountFromFactChunk, 8, &cursor) != 8) {
   1970                     return DRWAV_FALSE;
   1971                 }
   1972                 chunkSize -= 8;
   1973 
   1974                 if (!foundDataChunk) {
   1975                     pWav->dataChunkDataPos = cursor;
   1976                 }
   1977             }
   1978         }
   1979 
   1980         /* "smpl" chunk. */
   1981         if (pWav->container == drwav_container_riff) {
   1982             if (drwav__fourcc_equal(header.id.fourcc, "smpl")) {
   1983                 unsigned char smplHeaderData[36];    /* 36 = size of the smpl header section, not including the loop data. */
   1984                 if (chunkSize >= sizeof(smplHeaderData)) {
   1985                     drwav_uint64 bytesJustRead = drwav__on_read(pWav->onRead, pWav->pUserData, smplHeaderData, sizeof(smplHeaderData), &cursor);
   1986                     chunkSize -= bytesJustRead;
   1987 
   1988                     if (bytesJustRead == sizeof(smplHeaderData)) {
   1989                         drwav_uint32 iLoop;
   1990 
   1991                         pWav->smpl.manufacturer      = drwav__bytes_to_u32(smplHeaderData+0);
   1992                         pWav->smpl.product           = drwav__bytes_to_u32(smplHeaderData+4);
   1993                         pWav->smpl.samplePeriod      = drwav__bytes_to_u32(smplHeaderData+8);
   1994                         pWav->smpl.midiUnityNotes    = drwav__bytes_to_u32(smplHeaderData+12);
   1995                         pWav->smpl.midiPitchFraction = drwav__bytes_to_u32(smplHeaderData+16);
   1996                         pWav->smpl.smpteFormat       = drwav__bytes_to_u32(smplHeaderData+20);
   1997                         pWav->smpl.smpteOffset       = drwav__bytes_to_u32(smplHeaderData+24);
   1998                         pWav->smpl.numSampleLoops    = drwav__bytes_to_u32(smplHeaderData+28);
   1999                         pWav->smpl.samplerData       = drwav__bytes_to_u32(smplHeaderData+32);
   2000 
   2001                         for (iLoop = 0; iLoop < pWav->smpl.numSampleLoops && iLoop < drwav_countof(pWav->smpl.loops); ++iLoop) {
   2002                             unsigned char smplLoopData[24];  /* 24 = size of a loop section in the smpl chunk. */
   2003                             bytesJustRead = drwav__on_read(pWav->onRead, pWav->pUserData, smplLoopData, sizeof(smplLoopData), &cursor);
   2004                             chunkSize -= bytesJustRead;
   2005 
   2006                             if (bytesJustRead == sizeof(smplLoopData)) {
   2007                                 pWav->smpl.loops[iLoop].cuePointId = drwav__bytes_to_u32(smplLoopData+0);
   2008                                 pWav->smpl.loops[iLoop].type       = drwav__bytes_to_u32(smplLoopData+4);
   2009                                 pWav->smpl.loops[iLoop].start      = drwav__bytes_to_u32(smplLoopData+8);
   2010                                 pWav->smpl.loops[iLoop].end        = drwav__bytes_to_u32(smplLoopData+12);
   2011                                 pWav->smpl.loops[iLoop].fraction   = drwav__bytes_to_u32(smplLoopData+16);
   2012                                 pWav->smpl.loops[iLoop].playCount  = drwav__bytes_to_u32(smplLoopData+20);
   2013                             } else {
   2014                                 break;  /* Break from the smpl loop for loop. */
   2015                             }
   2016                         }
   2017                     }
   2018                 } else {
   2019                     /* Looks like invalid data. Ignore the chunk. */
   2020                 }
   2021             }
   2022         } else {
   2023             if (drwav__guid_equal(header.id.guid, drwavGUID_W64_SMPL)) {
   2024                 /*
   2025                 This path will be hit when a W64 WAV file contains a smpl chunk. I don't have a sample file to test this path, so a contribution
   2026                 is welcome to add support for this.
   2027                 */
   2028             }
   2029         }
   2030 
   2031         /* Make sure we seek past the padding. */
   2032         chunkSize += header.paddingSize;
   2033         if (!drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData)) {
   2034             break;
   2035         }
   2036         cursor += chunkSize;
   2037 
   2038         if (!foundDataChunk) {
   2039             pWav->dataChunkDataPos = cursor;
   2040         }
   2041     }
   2042 
   2043     /* If we haven't found a data chunk, return an error. */
   2044     if (!foundDataChunk) {
   2045         return DRWAV_FALSE;
   2046     }
   2047 
   2048     /* We may have moved passed the data chunk. If so we need to move back. If running in sequential mode we can assume we are already sitting on the data chunk. */
   2049     if (!sequential) {
   2050         if (!drwav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData)) {
   2051             return DRWAV_FALSE;
   2052         }
   2053         cursor = pWav->dataChunkDataPos;
   2054     }
   2055     
   2056 
   2057     /* At this point we should be sitting on the first byte of the raw audio data. */
   2058 
   2059     pWav->fmt                 = fmt;
   2060     pWav->sampleRate          = fmt.sampleRate;
   2061     pWav->channels            = fmt.channels;
   2062     pWav->bitsPerSample       = fmt.bitsPerSample;
   2063     pWav->bytesRemaining      = dataChunkSize;
   2064     pWav->translatedFormatTag = translatedFormatTag;
   2065     pWav->dataChunkDataSize   = dataChunkSize;
   2066 
   2067     if (sampleCountFromFactChunk != 0) {
   2068         pWav->totalPCMFrameCount = sampleCountFromFactChunk;
   2069     } else {
   2070         pWav->totalPCMFrameCount = dataChunkSize / drwav_get_bytes_per_pcm_frame(pWav);
   2071 
   2072         if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   2073             drwav_uint64 totalBlockHeaderSizeInBytes;
   2074             drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
   2075 
   2076             /* Make sure any trailing partial block is accounted for. */
   2077             if ((blockCount * fmt.blockAlign) < dataChunkSize) {
   2078                 blockCount += 1;
   2079             }
   2080 
   2081             /* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
   2082             totalBlockHeaderSizeInBytes = blockCount * (6*fmt.channels);
   2083             pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
   2084         }
   2085         if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   2086             drwav_uint64 totalBlockHeaderSizeInBytes;
   2087             drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
   2088 
   2089             /* Make sure any trailing partial block is accounted for. */
   2090             if ((blockCount * fmt.blockAlign) < dataChunkSize) {
   2091                 blockCount += 1;
   2092             }
   2093 
   2094             /* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
   2095             totalBlockHeaderSizeInBytes = blockCount * (4*fmt.channels);
   2096             pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
   2097 
   2098             /* The header includes a decoded sample for each channel which acts as the initial predictor sample. */
   2099             pWav->totalPCMFrameCount += blockCount;
   2100         }
   2101     }
   2102 
   2103     /* Some formats only support a certain number of channels. */
   2104     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   2105         if (pWav->channels > 2) {
   2106             return DRWAV_FALSE;
   2107         }
   2108     }
   2109 
   2110 #ifdef DR_WAV_LIBSNDFILE_COMPAT
   2111     /*
   2112     I use libsndfile as a benchmark for testing, however in the version I'm using (from the Windows installer on the libsndfile website),
   2113     it appears the total sample count libsndfile uses for MS-ADPCM is incorrect. It would seem they are computing the total sample count
   2114     from the number of blocks, however this results in the inclusion of extra silent samples at the end of the last block. The correct
   2115     way to know the total sample count is to inspect the "fact" chunk, which should always be present for compressed formats, and should
   2116     always include the sample count. This little block of code below is only used to emulate the libsndfile logic so I can properly run my
   2117     correctness tests against libsndfile, and is disabled by default.
   2118     */
   2119     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   2120         drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
   2121         pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (6*pWav->channels))) * 2)) / fmt.channels;  /* x2 because two samples per byte. */
   2122     }
   2123     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   2124         drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
   2125         pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (4*pWav->channels))) * 2) + (blockCount * pWav->channels)) / fmt.channels;
   2126     }
   2127 #endif
   2128 
   2129     return DRWAV_TRUE;
   2130 }
   2131 
   2132 drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   2133 {
   2134     return drwav_init_ex(pWav, onRead, onSeek, NULL, pUserData, NULL, 0, pAllocationCallbacks);
   2135 }
   2136 
   2137 drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
   2138 {
   2139     if (!drwav_preinit(pWav, onRead, onSeek, pReadSeekUserData, pAllocationCallbacks)) {
   2140         return DRWAV_FALSE;
   2141     }
   2142 
   2143     return drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
   2144 }
   2145 
   2146 
   2147 static drwav_uint32 drwav__riff_chunk_size_riff(drwav_uint64 dataChunkSize)
   2148 {
   2149     drwav_uint32 dataSubchunkPaddingSize = drwav__chunk_padding_size_riff(dataChunkSize);
   2150 
   2151     if (dataChunkSize <= (0xFFFFFFFFUL - 36 - dataSubchunkPaddingSize)) {
   2152         return 36 + (drwav_uint32)(dataChunkSize + dataSubchunkPaddingSize);
   2153     } else {
   2154         return 0xFFFFFFFF;
   2155     }
   2156 }
   2157 
   2158 static drwav_uint32 drwav__data_chunk_size_riff(drwav_uint64 dataChunkSize)
   2159 {
   2160     if (dataChunkSize <= 0xFFFFFFFFUL) {
   2161         return (drwav_uint32)dataChunkSize;
   2162     } else {
   2163         return 0xFFFFFFFFUL;
   2164     }
   2165 }
   2166 
   2167 static drwav_uint64 drwav__riff_chunk_size_w64(drwav_uint64 dataChunkSize)
   2168 {
   2169     drwav_uint64 dataSubchunkPaddingSize = drwav__chunk_padding_size_w64(dataChunkSize);
   2170 
   2171     return 80 + 24 + dataChunkSize + dataSubchunkPaddingSize;   /* +24 because W64 includes the size of the GUID and size fields. */
   2172 }
   2173 
   2174 static drwav_uint64 drwav__data_chunk_size_w64(drwav_uint64 dataChunkSize)
   2175 {
   2176     return 24 + dataChunkSize;        /* +24 because W64 includes the size of the GUID and size fields. */
   2177 }
   2178 
   2179 
   2180 drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_format* pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   2181 {
   2182     if (pWav == NULL || onWrite == NULL) {
   2183         return DRWAV_FALSE;
   2184     }
   2185 
   2186     if (!isSequential && onSeek == NULL) {
   2187         return DRWAV_FALSE; /* <-- onSeek is required when in non-sequential mode. */
   2188     }
   2189 
   2190     /* Not currently supporting compressed formats. Will need to add support for the "fact" chunk before we enable this. */
   2191     if (pFormat->format == DR_WAVE_FORMAT_EXTENSIBLE) {
   2192         return DRWAV_FALSE;
   2193     }
   2194     if (pFormat->format == DR_WAVE_FORMAT_ADPCM || pFormat->format == DR_WAVE_FORMAT_DVI_ADPCM) {
   2195         return DRWAV_FALSE;
   2196     }
   2197 
   2198     DRWAV_ZERO_MEMORY(pWav, sizeof(*pWav));
   2199     pWav->onWrite   = onWrite;
   2200     pWav->onSeek    = onSeek;
   2201     pWav->pUserData = pUserData;
   2202     pWav->allocationCallbacks = drwav_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
   2203 
   2204     if (pWav->allocationCallbacks.onFree == NULL || (pWav->allocationCallbacks.onMalloc == NULL && pWav->allocationCallbacks.onRealloc == NULL)) {
   2205         return DRWAV_FALSE;    /* Invalid allocation callbacks. */
   2206     }
   2207 
   2208     pWav->fmt.formatTag = (drwav_uint16)pFormat->format;
   2209     pWav->fmt.channels = (drwav_uint16)pFormat->channels;
   2210     pWav->fmt.sampleRate = pFormat->sampleRate;
   2211     pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) / 8);
   2212     pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) / 8);
   2213     pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
   2214     pWav->fmt.extendedSize = 0;
   2215     pWav->isSequentialWrite = isSequential;
   2216 
   2217     return DRWAV_TRUE;
   2218 }
   2219 
   2220 drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
   2221 {
   2222     /* The function assumes drwav_preinit_write() was called beforehand. */
   2223 
   2224     size_t runningPos = 0;
   2225     drwav_uint64 initialDataChunkSize = 0;
   2226     drwav_uint64 chunkSizeFMT;
   2227 
   2228     /*
   2229     The initial values for the "RIFF" and "data" chunks depends on whether or not we are initializing in sequential mode or not. In
   2230     sequential mode we set this to its final values straight away since they can be calculated from the total sample count. In non-
   2231     sequential mode we initialize it all to zero and fill it out in drwav_uninit() using a backwards seek.
   2232     */
   2233     if (pWav->isSequentialWrite) {
   2234         initialDataChunkSize = (totalSampleCount * pWav->fmt.bitsPerSample) / 8;
   2235 
   2236         /*
   2237         The RIFF container has a limit on the number of samples. drwav is not allowing this. There's no practical limits for Wave64
   2238         so for the sake of simplicity I'm not doing any validation for that.
   2239         */
   2240         if (pFormat->container == drwav_container_riff) {
   2241             if (initialDataChunkSize > (0xFFFFFFFFUL - 36)) {
   2242                 return DRWAV_FALSE; /* Not enough room to store every sample. */
   2243             }
   2244         }
   2245     }
   2246 
   2247     pWav->dataChunkDataSizeTargetWrite = initialDataChunkSize;
   2248 
   2249 
   2250     /* "RIFF" chunk. */
   2251     if (pFormat->container == drwav_container_riff) {
   2252         drwav_uint32 chunkSizeRIFF = 36 + (drwav_uint32)initialDataChunkSize;   /* +36 = "RIFF"+[RIFF Chunk Size]+"WAVE" + [sizeof "fmt " chunk] */
   2253         runningPos += pWav->onWrite(pWav->pUserData, "RIFF", 4);
   2254         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 4);
   2255         runningPos += pWav->onWrite(pWav->pUserData, "WAVE", 4);
   2256     } else {
   2257         drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize;   /* +24 because W64 includes the size of the GUID and size fields. */
   2258         runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_RIFF, 16);
   2259         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 8);
   2260         runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_WAVE, 16);
   2261     }
   2262 
   2263     /* "fmt " chunk. */
   2264     if (pFormat->container == drwav_container_riff) {
   2265         chunkSizeFMT = 16;
   2266         runningPos += pWav->onWrite(pWav->pUserData, "fmt ", 4);
   2267         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 4);
   2268     } else {
   2269         chunkSizeFMT = 40;
   2270         runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_FMT, 16);
   2271         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 8);
   2272     }
   2273 
   2274     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.formatTag,      2);
   2275     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.channels,       2);
   2276     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.sampleRate,     4);
   2277     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.avgBytesPerSec, 4);
   2278     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.blockAlign,     2);
   2279     runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.bitsPerSample,  2);
   2280 
   2281     pWav->dataChunkDataPos = runningPos;
   2282 
   2283     /* "data" chunk. */
   2284     if (pFormat->container == drwav_container_riff) {
   2285         drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize;
   2286         runningPos += pWav->onWrite(pWav->pUserData, "data", 4);
   2287         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 4);
   2288     } else {
   2289         drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */
   2290         runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_DATA, 16);
   2291         runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 8);
   2292     }
   2293 
   2294 
   2295     /* Simple validation. */
   2296     if (pFormat->container == drwav_container_riff) {
   2297         if (runningPos != 20 + chunkSizeFMT + 8) {
   2298             return DRWAV_FALSE;
   2299         }
   2300     } else {
   2301         if (runningPos != 40 + chunkSizeFMT + 24) {
   2302             return DRWAV_FALSE;
   2303         }
   2304     }
   2305     
   2306 
   2307     /* Set some properties for the client's convenience. */
   2308     pWav->container = pFormat->container;
   2309     pWav->channels = (drwav_uint16)pFormat->channels;
   2310     pWav->sampleRate = pFormat->sampleRate;
   2311     pWav->bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
   2312     pWav->translatedFormatTag = (drwav_uint16)pFormat->format;
   2313 
   2314     return DRWAV_TRUE;
   2315 }
   2316 
   2317 
   2318 drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   2319 {
   2320     if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
   2321         return DRWAV_FALSE;
   2322     }
   2323 
   2324     return drwav_init_write__internal(pWav, pFormat, 0);               /* DRWAV_FALSE = Not Sequential */
   2325 }
   2326 
   2327 drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   2328 {
   2329     if (!drwav_preinit_write(pWav, pFormat, DRWAV_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
   2330         return DRWAV_FALSE;
   2331     }
   2332 
   2333     return drwav_init_write__internal(pWav, pFormat, totalSampleCount); /* DRWAV_TRUE = Sequential */
   2334 }
   2335 
   2336 drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
   2337 {
   2338     if (pFormat == NULL) {
   2339         return DRWAV_FALSE;
   2340     }
   2341 
   2342     return drwav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
   2343 }
   2344 
   2345 drwav_uint64 drwav_target_write_size_bytes(drwav_data_format const *format, drwav_uint64 totalSampleCount)
   2346 {
   2347     drwav_uint64 targetDataSizeBytes = (totalSampleCount * format->channels * format->bitsPerSample/8);
   2348     drwav_uint64 riffChunkSizeBytes;
   2349     drwav_uint64 fileSizeBytes;
   2350 
   2351     if (format->container == drwav_container_riff) {
   2352         riffChunkSizeBytes = drwav__riff_chunk_size_riff(targetDataSizeBytes);
   2353         fileSizeBytes = (8 + riffChunkSizeBytes); /* +8 because WAV doesn't include the size of the ChunkID and ChunkSize fields. */
   2354     } else {
   2355         riffChunkSizeBytes = drwav__riff_chunk_size_w64(targetDataSizeBytes);
   2356         fileSizeBytes = riffChunkSizeBytes;
   2357     }
   2358 
   2359     return fileSizeBytes;
   2360 }
   2361 
   2362 
   2363 #ifndef DR_WAV_NO_STDIO
   2364 FILE* drwav_fopen(const char* filePath, const char* openMode)
   2365 {
   2366     FILE* pFile;
   2367 #if defined(_MSC_VER) && _MSC_VER >= 1400
   2368     if (fopen_s(&pFile, filePath, openMode) != 0) {
   2369         return NULL;
   2370     }
   2371 #else
   2372     pFile = fopen(filePath, openMode);
   2373     if (pFile == NULL) {
   2374         return NULL;
   2375     }
   2376 #endif
   2377 
   2378     return pFile;
   2379 }
   2380 
   2381 FILE* drwav_wfopen(const wchar_t* pFilePath, const wchar_t* pOpenMode, const drwav_allocation_callbacks* pAllocationCallbacks)
   2382 {
   2383     FILE* pFile;
   2384 
   2385 #if defined(_WIN32)
   2386     (void)pAllocationCallbacks;
   2387     #if defined(_MSC_VER) && _MSC_VER >= 1400
   2388         if (_wfopen_s(&pFile, pFilePath, pOpenMode) != 0) {
   2389             return NULL;
   2390         }
   2391     #else
   2392         pFile = _wfopen(pFilePath, pOpenMode);
   2393         if (pFile == NULL) {
   2394             return NULL;
   2395         }
   2396     #endif
   2397 #else
   2398     /*
   2399     Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
   2400     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
   2401     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.
   2402     */
   2403     {
   2404         mbstate_t mbs;
   2405         size_t lenMB;
   2406         const wchar_t* pFilePathTemp = pFilePath;
   2407         char* pFilePathMB = NULL;
   2408         const wchar_t* pOpenModeMBTemp = pOpenMode;
   2409         char pOpenModeMB[16];
   2410         drwav_allocation_callbacks allocationCallbacks;
   2411 
   2412         allocationCallbacks = drwav_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
   2413 
   2414         /* Get the length first. */
   2415         DRWAV_ZERO_MEMORY(&mbs, sizeof(mbs));
   2416         lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
   2417         if (lenMB == (size_t)-1) {
   2418             return NULL;
   2419         }
   2420 
   2421         pFilePathMB = (char*)drwav__malloc_from_callbacks(lenMB + 1, &allocationCallbacks);
   2422         if (pFilePathMB == NULL) {
   2423             return NULL;
   2424         }
   2425 
   2426         pFilePathTemp = pFilePath;
   2427         DRWAV_ZERO_MEMORY(&mbs, sizeof(mbs));
   2428         wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
   2429 
   2430         DRWAV_ZERO_MEMORY(&mbs, sizeof(mbs));
   2431         wcsrtombs(pOpenModeMB, &pOpenModeMBTemp, sizeof(pOpenModeMB), &mbs);
   2432 
   2433         pFile = fopen(pFilePathMB, pOpenModeMB);
   2434 
   2435         drwav__free_from_callbacks(pFilePathMB, &allocationCallbacks);
   2436     }
   2437 #endif
   2438 
   2439     return pFile;
   2440 }
   2441 
   2442 
   2443 static size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
   2444 {
   2445     return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
   2446 }
   2447 
   2448 static size_t drwav__on_write_stdio(void* pUserData, const void* pData, size_t bytesToWrite)
   2449 {
   2450     return fwrite(pData, 1, bytesToWrite, (FILE*)pUserData);
   2451 }
   2452 
   2453 static drwav_bool32 drwav__on_seek_stdio(void* pUserData, int offset, drwav_seek_origin origin)
   2454 {
   2455     return fseek((FILE*)pUserData, offset, (origin == drwav_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
   2456 }
   2457 
   2458 drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
   2459 {
   2460     return drwav_init_file_ex(pWav, filename, NULL, NULL, 0, pAllocationCallbacks);
   2461 }
   2462 
   2463 
   2464 drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFile, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
   2465 {
   2466     if (!drwav_preinit(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks)) {
   2467         fclose(pFile);
   2468         return DRWAV_FALSE;
   2469     }
   2470 
   2471     return drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
   2472 }
   2473 
   2474 drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
   2475 {
   2476     FILE* pFile = drwav_fopen(filename, "rb");
   2477     if (pFile == NULL) {
   2478         return DRWAV_FALSE;
   2479     }
   2480 
   2481     /* This takes ownership of the FILE* object. */
   2482     return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks);
   2483 }
   2484 
   2485 drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
   2486 {
   2487     return drwav_init_file_ex_w(pWav, filename, NULL, NULL, 0, pAllocationCallbacks);
   2488 }
   2489 
   2490 drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
   2491 {
   2492     FILE* pFile = drwav_wfopen(filename, L"rb", pAllocationCallbacks);
   2493     if (pFile == NULL) {
   2494         return DRWAV_FALSE;
   2495     }
   2496 
   2497     /* This takes ownership of the FILE* object. */
   2498     return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks);
   2499 }
   2500 
   2501 
   2502 drwav_bool32 drwav_init_file_write__internal_FILE(drwav* pWav, FILE* pFile, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
   2503 {
   2504     if (!drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks)) {
   2505         fclose(pFile);
   2506         return DRWAV_FALSE;
   2507     }
   2508 
   2509     return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
   2510 }
   2511 
   2512 drwav_bool32 drwav_init_file_write__internal(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
   2513 {
   2514     FILE* pFile = drwav_fopen(filename, "wb");
   2515     if (pFile == NULL) {
   2516         return DRWAV_FALSE;
   2517     }
   2518 
   2519     /* This takes ownership of the FILE* object. */
   2520     return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
   2521 }
   2522 
   2523 drwav_bool32 drwav_init_file_write_w__internal(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
   2524 {
   2525     FILE* pFile = drwav_wfopen(filename, L"wb", pAllocationCallbacks);
   2526     if (pFile == NULL) {
   2527         return DRWAV_FALSE;
   2528     }
   2529 
   2530     /* This takes ownership of the FILE* object. */
   2531     return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
   2532 }
   2533 
   2534 drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
   2535 {
   2536     return drwav_init_file_write__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
   2537 }
   2538 
   2539 drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2540 {
   2541     return drwav_init_file_write__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
   2542 }
   2543 
   2544 drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2545 {
   2546     if (pFormat == NULL) {
   2547         return DRWAV_FALSE;
   2548     }
   2549 
   2550     return drwav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
   2551 }
   2552 
   2553 drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
   2554 {
   2555     return drwav_init_file_write_w__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
   2556 }
   2557 
   2558 drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2559 {
   2560     return drwav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
   2561 }
   2562 
   2563 drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2564 {
   2565     if (pFormat == NULL) {
   2566         return DRWAV_FALSE;
   2567     }
   2568 
   2569     return drwav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
   2570 }
   2571 #endif  /* DR_WAV_NO_STDIO */
   2572 
   2573 
   2574 static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
   2575 {
   2576     drwav* pWav = (drwav*)pUserData;
   2577     size_t bytesRemaining;
   2578 
   2579     DRWAV_ASSERT(pWav != NULL);
   2580     DRWAV_ASSERT(pWav->memoryStream.dataSize >= pWav->memoryStream.currentReadPos);
   2581 
   2582     bytesRemaining = pWav->memoryStream.dataSize - pWav->memoryStream.currentReadPos;
   2583     if (bytesToRead > bytesRemaining) {
   2584         bytesToRead = bytesRemaining;
   2585     }
   2586 
   2587     if (bytesToRead > 0) {
   2588         DRWAV_COPY_MEMORY(pBufferOut, pWav->memoryStream.data + pWav->memoryStream.currentReadPos, bytesToRead);
   2589         pWav->memoryStream.currentReadPos += bytesToRead;
   2590     }
   2591 
   2592     return bytesToRead;
   2593 }
   2594 
   2595 static drwav_bool32 drwav__on_seek_memory(void* pUserData, int offset, drwav_seek_origin origin)
   2596 {
   2597     drwav* pWav = (drwav*)pUserData;
   2598     DRWAV_ASSERT(pWav != NULL);
   2599 
   2600     if (origin == drwav_seek_origin_current) {
   2601         if (offset > 0) {
   2602             if (pWav->memoryStream.currentReadPos + offset > pWav->memoryStream.dataSize) {
   2603                 return DRWAV_FALSE; /* Trying to seek too far forward. */
   2604             }
   2605         } else {
   2606             if (pWav->memoryStream.currentReadPos < (size_t)-offset) {
   2607                 return DRWAV_FALSE; /* Trying to seek too far backwards. */
   2608             }
   2609         }
   2610 
   2611         /* This will never underflow thanks to the clamps above. */
   2612         pWav->memoryStream.currentReadPos += offset;
   2613     } else {
   2614         if ((drwav_uint32)offset <= pWav->memoryStream.dataSize) {
   2615             pWav->memoryStream.currentReadPos = offset;
   2616         } else {
   2617             return DRWAV_FALSE; /* Trying to seek too far forward. */
   2618         }
   2619     }
   2620     
   2621     return DRWAV_TRUE;
   2622 }
   2623 
   2624 static size_t drwav__on_write_memory(void* pUserData, const void* pDataIn, size_t bytesToWrite)
   2625 {
   2626     drwav* pWav = (drwav*)pUserData;
   2627     size_t bytesRemaining;
   2628 
   2629     DRWAV_ASSERT(pWav != NULL);
   2630     DRWAV_ASSERT(pWav->memoryStreamWrite.dataCapacity >= pWav->memoryStreamWrite.currentWritePos);
   2631 
   2632     bytesRemaining = pWav->memoryStreamWrite.dataCapacity - pWav->memoryStreamWrite.currentWritePos;
   2633     if (bytesRemaining < bytesToWrite) {
   2634         /* Need to reallocate. */
   2635         void* pNewData;
   2636         size_t newDataCapacity = (pWav->memoryStreamWrite.dataCapacity == 0) ? 256 : pWav->memoryStreamWrite.dataCapacity * 2;
   2637 
   2638         /* If doubling wasn't enough, just make it the minimum required size to write the data. */
   2639         if ((newDataCapacity - pWav->memoryStreamWrite.currentWritePos) < bytesToWrite) {
   2640             newDataCapacity = pWav->memoryStreamWrite.currentWritePos + bytesToWrite;
   2641         }
   2642 
   2643         pNewData = drwav__realloc_from_callbacks(*pWav->memoryStreamWrite.ppData, newDataCapacity, pWav->memoryStreamWrite.dataCapacity, &pWav->allocationCallbacks);
   2644         if (pNewData == NULL) {
   2645             return 0;
   2646         }
   2647 
   2648         *pWav->memoryStreamWrite.ppData = pNewData;
   2649         pWav->memoryStreamWrite.dataCapacity = newDataCapacity;
   2650     }
   2651 
   2652     DRWAV_COPY_MEMORY(((drwav_uint8*)(*pWav->memoryStreamWrite.ppData)) + pWav->memoryStreamWrite.currentWritePos, pDataIn, bytesToWrite);
   2653 
   2654     pWav->memoryStreamWrite.currentWritePos += bytesToWrite;
   2655     if (pWav->memoryStreamWrite.dataSize < pWav->memoryStreamWrite.currentWritePos) {
   2656         pWav->memoryStreamWrite.dataSize = pWav->memoryStreamWrite.currentWritePos;
   2657     }
   2658 
   2659     *pWav->memoryStreamWrite.pDataSize = pWav->memoryStreamWrite.dataSize;
   2660 
   2661     return bytesToWrite;
   2662 }
   2663 
   2664 static drwav_bool32 drwav__on_seek_memory_write(void* pUserData, int offset, drwav_seek_origin origin)
   2665 {
   2666     drwav* pWav = (drwav*)pUserData;
   2667     DRWAV_ASSERT(pWav != NULL);
   2668 
   2669     if (origin == drwav_seek_origin_current) {
   2670         if (offset > 0) {
   2671             if (pWav->memoryStreamWrite.currentWritePos + offset > pWav->memoryStreamWrite.dataSize) {
   2672                 offset = (int)(pWav->memoryStreamWrite.dataSize - pWav->memoryStreamWrite.currentWritePos);  /* Trying to seek too far forward. */
   2673             }
   2674         } else {
   2675             if (pWav->memoryStreamWrite.currentWritePos < (size_t)-offset) {
   2676                 offset = -(int)pWav->memoryStreamWrite.currentWritePos;  /* Trying to seek too far backwards. */
   2677             }
   2678         }
   2679 
   2680         /* This will never underflow thanks to the clamps above. */
   2681         pWav->memoryStreamWrite.currentWritePos += offset;
   2682     } else {
   2683         if ((drwav_uint32)offset <= pWav->memoryStreamWrite.dataSize) {
   2684             pWav->memoryStreamWrite.currentWritePos = offset;
   2685         } else {
   2686             pWav->memoryStreamWrite.currentWritePos = pWav->memoryStreamWrite.dataSize;  /* Trying to seek too far forward. */
   2687         }
   2688     }
   2689     
   2690     return DRWAV_TRUE;
   2691 }
   2692 
   2693 drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks)
   2694 {
   2695     return drwav_init_memory_ex(pWav, data, dataSize, NULL, NULL, 0, pAllocationCallbacks);
   2696 }
   2697 
   2698 drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
   2699 {
   2700     if (data == NULL || dataSize == 0) {
   2701         return DRWAV_FALSE;
   2702     }
   2703 
   2704     if (!drwav_preinit(pWav, drwav__on_read_memory, drwav__on_seek_memory, pWav, pAllocationCallbacks)) {
   2705         return DRWAV_FALSE;
   2706     }
   2707 
   2708     pWav->memoryStream.data = (const unsigned char*)data;
   2709     pWav->memoryStream.dataSize = dataSize;
   2710     pWav->memoryStream.currentReadPos = 0;
   2711 
   2712     return drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
   2713 }
   2714 
   2715 
   2716 drwav_bool32 drwav_init_memory_write__internal(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
   2717 {
   2718     if (ppData == NULL || pDataSize == NULL) {
   2719         return DRWAV_FALSE;
   2720     }
   2721 
   2722     *ppData = NULL; /* Important because we're using realloc()! */
   2723     *pDataSize = 0;
   2724 
   2725     if (!drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_memory, drwav__on_seek_memory_write, pWav, pAllocationCallbacks)) {
   2726         return DRWAV_FALSE;
   2727     }
   2728 
   2729     pWav->memoryStreamWrite.ppData = ppData;
   2730     pWav->memoryStreamWrite.pDataSize = pDataSize;
   2731     pWav->memoryStreamWrite.dataSize = 0;
   2732     pWav->memoryStreamWrite.dataCapacity = 0;
   2733     pWav->memoryStreamWrite.currentWritePos = 0;
   2734 
   2735     return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
   2736 }
   2737 
   2738 drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
   2739 {
   2740     return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
   2741 }
   2742 
   2743 drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2744 {
   2745     return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
   2746 }
   2747 
   2748 drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
   2749 {
   2750     if (pFormat == NULL) {
   2751         return DRWAV_FALSE;
   2752     }
   2753 
   2754     return drwav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
   2755 }
   2756 
   2757 
   2758 
   2759 drwav_result drwav_uninit(drwav* pWav)
   2760 {
   2761     drwav_result result = DRWAV_SUCCESS;
   2762 
   2763     if (pWav == NULL) {
   2764         return DRWAV_INVALID_ARGS;
   2765     }
   2766 
   2767     /*
   2768     If the drwav object was opened in write mode we'll need to finalize a few things:
   2769       - Make sure the "data" chunk is aligned to 16-bits for RIFF containers, or 64 bits for W64 containers.
   2770       - Set the size of the "data" chunk.
   2771     */
   2772     if (pWav->onWrite != NULL) {
   2773         drwav_uint32 paddingSize = 0;
   2774 
   2775         /* Padding. Do not adjust pWav->dataChunkDataSize - this should not include the padding. */
   2776         if (pWav->container == drwav_container_riff) {
   2777             paddingSize = drwav__chunk_padding_size_riff(pWav->dataChunkDataSize);
   2778         } else {
   2779             paddingSize = drwav__chunk_padding_size_w64(pWav->dataChunkDataSize);
   2780         }
   2781         
   2782         if (paddingSize > 0) {
   2783             drwav_uint64 paddingData = 0;
   2784             pWav->onWrite(pWav->pUserData, &paddingData, paddingSize);
   2785         }
   2786 
   2787         /*
   2788         Chunk sizes. When using sequential mode, these will have been filled in at initialization time. We only need
   2789         to do this when using non-sequential mode.
   2790         */
   2791         if (pWav->onSeek && !pWav->isSequentialWrite) {
   2792             if (pWav->container == drwav_container_riff) {
   2793                 /* The "RIFF" chunk size. */
   2794                 if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) {
   2795                     drwav_uint32 riffChunkSize = drwav__riff_chunk_size_riff(pWav->dataChunkDataSize);
   2796                     pWav->onWrite(pWav->pUserData, &riffChunkSize, 4);
   2797                 }
   2798 
   2799                 /* the "data" chunk size. */
   2800                 if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) {
   2801                     drwav_uint32 dataChunkSize = drwav__data_chunk_size_riff(pWav->dataChunkDataSize);
   2802                     pWav->onWrite(pWav->pUserData, &dataChunkSize, 4);
   2803                 }
   2804             } else {
   2805                 /* The "RIFF" chunk size. */
   2806                 if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) {
   2807                     drwav_uint64 riffChunkSize = drwav__riff_chunk_size_w64(pWav->dataChunkDataSize);
   2808                     pWav->onWrite(pWav->pUserData, &riffChunkSize, 8);
   2809                 }
   2810 
   2811                 /* The "data" chunk size. */
   2812                 if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) {
   2813                     drwav_uint64 dataChunkSize = drwav__data_chunk_size_w64(pWav->dataChunkDataSize);
   2814                     pWav->onWrite(pWav->pUserData, &dataChunkSize, 8);
   2815                 }
   2816             }
   2817         }
   2818 
   2819         /* Validation for sequential mode. */
   2820         if (pWav->isSequentialWrite) {
   2821             if (pWav->dataChunkDataSize != pWav->dataChunkDataSizeTargetWrite) {
   2822                 result = DRWAV_INVALID_FILE;
   2823             }
   2824         }
   2825     }
   2826 
   2827 #ifndef DR_WAV_NO_STDIO
   2828     /*
   2829     If we opened the file with drwav_open_file() we will want to close the file handle. We can know whether or not drwav_open_file()
   2830     was used by looking at the onRead and onSeek callbacks.
   2831     */
   2832     if (pWav->onRead == drwav__on_read_stdio || pWav->onWrite == drwav__on_write_stdio) {
   2833         fclose((FILE*)pWav->pUserData);
   2834     }
   2835 #endif
   2836 
   2837     return result;
   2838 }
   2839 
   2840 
   2841 
   2842 size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut)
   2843 {
   2844     size_t bytesRead;
   2845 
   2846     if (pWav == NULL || bytesToRead == 0 || pBufferOut == NULL) {
   2847         return 0;
   2848     }
   2849 
   2850     if (bytesToRead > pWav->bytesRemaining) {
   2851         bytesToRead = (size_t)pWav->bytesRemaining;
   2852     }
   2853 
   2854     bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead);
   2855 
   2856     pWav->bytesRemaining -= bytesRead;
   2857     return bytesRead;
   2858 }
   2859 
   2860 
   2861 
   2862 drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
   2863 {
   2864     drwav_uint32 bytesPerFrame;
   2865 
   2866     if (pWav == NULL || framesToRead == 0 || pBufferOut == NULL) {
   2867         return 0;
   2868     }
   2869 
   2870     /* Cannot use this function for compressed formats. */
   2871     if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
   2872         return 0;
   2873     }
   2874 
   2875     bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   2876     if (bytesPerFrame == 0) {
   2877         return 0;
   2878     }
   2879 
   2880     /* Don't try to read more samples than can potentially fit in the output buffer. */
   2881     if (framesToRead * bytesPerFrame > DRWAV_SIZE_MAX) {
   2882         framesToRead = DRWAV_SIZE_MAX / bytesPerFrame;
   2883     }
   2884 
   2885     return drwav_read_raw(pWav, (size_t)(framesToRead * bytesPerFrame), pBufferOut) / bytesPerFrame;
   2886 }
   2887 
   2888 drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
   2889 {
   2890     drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
   2891     drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, drwav_get_bytes_per_pcm_frame(pWav)/pWav->channels, pWav->translatedFormatTag);
   2892 
   2893     return framesRead;
   2894 }
   2895 
   2896 drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
   2897 {
   2898     if (drwav__is_little_endian()) {
   2899         return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
   2900     } else {
   2901         return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
   2902     }
   2903 }
   2904 
   2905 
   2906 
   2907 drwav_bool32 drwav_seek_to_first_pcm_frame(drwav* pWav)
   2908 {
   2909     if (pWav->onWrite != NULL) {
   2910         return DRWAV_FALSE; /* No seeking in write mode. */
   2911     }
   2912 
   2913     if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
   2914         return DRWAV_FALSE;
   2915     }
   2916 
   2917     if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
   2918         pWav->compressed.iCurrentPCMFrame = 0;
   2919     }
   2920     
   2921     pWav->bytesRemaining = pWav->dataChunkDataSize;
   2922     return DRWAV_TRUE;
   2923 }
   2924 
   2925 drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex)
   2926 {
   2927     /* Seeking should be compatible with wave files > 2GB. */
   2928 
   2929     if (pWav->onWrite != NULL) {
   2930         return DRWAV_FALSE; /* No seeking in write mode. */
   2931     }
   2932 
   2933     if (pWav == NULL || pWav->onSeek == NULL) {
   2934         return DRWAV_FALSE;
   2935     }
   2936 
   2937     /* If there are no samples, just return DRWAV_TRUE without doing anything. */
   2938     if (pWav->totalPCMFrameCount == 0) {
   2939         return DRWAV_TRUE;
   2940     }
   2941 
   2942     /* Make sure the sample is clamped. */
   2943     if (targetFrameIndex >= pWav->totalPCMFrameCount) {
   2944         targetFrameIndex  = pWav->totalPCMFrameCount - 1;
   2945     }
   2946 
   2947     /*
   2948     For compressed formats we just use a slow generic seek. If we are seeking forward we just seek forward. If we are going backwards we need
   2949     to seek back to the start.
   2950     */
   2951     if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
   2952         /* TODO: This can be optimized. */
   2953         
   2954         /*
   2955         If we're seeking forward it's simple - just keep reading samples until we hit the sample we're requesting. If we're seeking backwards,
   2956         we first need to seek back to the start and then just do the same thing as a forward seek.
   2957         */
   2958         if (targetFrameIndex < pWav->compressed.iCurrentPCMFrame) {
   2959             if (!drwav_seek_to_first_pcm_frame(pWav)) {
   2960                 return DRWAV_FALSE;
   2961             }
   2962         }
   2963 
   2964         if (targetFrameIndex > pWav->compressed.iCurrentPCMFrame) {
   2965             drwav_uint64 offsetInFrames = targetFrameIndex - pWav->compressed.iCurrentPCMFrame;
   2966 
   2967             drwav_int16 devnull[2048];
   2968             while (offsetInFrames > 0) {
   2969                 drwav_uint64 framesRead = 0;
   2970                 drwav_uint64 framesToRead = offsetInFrames;
   2971                 if (framesToRead > drwav_countof(devnull)/pWav->channels) {
   2972                     framesToRead = drwav_countof(devnull)/pWav->channels;
   2973                 }
   2974 
   2975                 if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   2976                     framesRead = drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
   2977                 } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   2978                     framesRead = drwav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
   2979                 } else {
   2980                     assert(DRWAV_FALSE);    /* If this assertion is triggered it means I've implemented a new compressed format but forgot to add a branch for it here. */
   2981                 }
   2982 
   2983                 if (framesRead != framesToRead) {
   2984                     return DRWAV_FALSE;
   2985                 }
   2986 
   2987                 offsetInFrames -= framesRead;
   2988             }
   2989         }
   2990     } else {
   2991         drwav_uint64 totalSizeInBytes;
   2992         drwav_uint64 currentBytePos;
   2993         drwav_uint64 targetBytePos;
   2994         drwav_uint64 offset;
   2995 
   2996         totalSizeInBytes = pWav->totalPCMFrameCount * drwav_get_bytes_per_pcm_frame(pWav);
   2997         DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
   2998 
   2999         currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
   3000         targetBytePos  = targetFrameIndex * drwav_get_bytes_per_pcm_frame(pWav);
   3001 
   3002         if (currentBytePos < targetBytePos) {
   3003             /* Offset forwards. */
   3004             offset = (targetBytePos - currentBytePos);
   3005         } else {
   3006             /* Offset backwards. */
   3007             if (!drwav_seek_to_first_pcm_frame(pWav)) {
   3008                 return DRWAV_FALSE;
   3009             }
   3010             offset = targetBytePos;
   3011         }
   3012 
   3013         while (offset > 0) {
   3014             int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
   3015             if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
   3016                 return DRWAV_FALSE;
   3017             }
   3018 
   3019             pWav->bytesRemaining -= offset32;
   3020             offset -= offset32;
   3021         }
   3022     }
   3023 
   3024     return DRWAV_TRUE;
   3025 }
   3026 
   3027 
   3028 size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData)
   3029 {
   3030     size_t bytesWritten;
   3031 
   3032     if (pWav == NULL || bytesToWrite == 0 || pData == NULL) {
   3033         return 0;
   3034     }
   3035 
   3036     bytesWritten = pWav->onWrite(pWav->pUserData, pData, bytesToWrite);
   3037     pWav->dataChunkDataSize += bytesWritten;
   3038 
   3039     return bytesWritten;
   3040 }
   3041 
   3042 
   3043 drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
   3044 {
   3045     drwav_uint64 bytesToWrite;
   3046     drwav_uint64 bytesWritten;
   3047     const drwav_uint8* pRunningData;
   3048 
   3049     if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
   3050         return 0;
   3051     }
   3052 
   3053     bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
   3054     if (bytesToWrite > DRWAV_SIZE_MAX) {
   3055         return 0;
   3056     }
   3057 
   3058     bytesWritten = 0;
   3059     pRunningData = (const drwav_uint8*)pData;
   3060 
   3061     while (bytesToWrite > 0) {
   3062         size_t bytesJustWritten;
   3063         drwav_uint64 bytesToWriteThisIteration = bytesToWrite;
   3064         if (bytesToWriteThisIteration > DRWAV_SIZE_MAX) {
   3065             bytesToWriteThisIteration = DRWAV_SIZE_MAX;
   3066         }
   3067 
   3068         bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
   3069         if (bytesJustWritten == 0) {
   3070             break;
   3071         }
   3072 
   3073         bytesToWrite -= bytesJustWritten;
   3074         bytesWritten += bytesJustWritten;
   3075         pRunningData += bytesJustWritten;
   3076     }
   3077 
   3078     return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
   3079 }
   3080 
   3081 drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
   3082 {
   3083     drwav_uint64 bytesToWrite;
   3084     drwav_uint64 bytesWritten;
   3085     drwav_uint32 bytesPerSample;
   3086     const drwav_uint8* pRunningData;
   3087 
   3088     if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
   3089         return 0;
   3090     }
   3091 
   3092     bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
   3093     if (bytesToWrite > DRWAV_SIZE_MAX) {
   3094         return 0;
   3095     }
   3096 
   3097     bytesWritten = 0;
   3098     pRunningData = (const drwav_uint8*)pData;
   3099 
   3100     bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels;
   3101     
   3102     while (bytesToWrite > 0) {
   3103         drwav_uint8 temp[4096];
   3104         drwav_uint32 sampleCount;
   3105         size_t bytesJustWritten;
   3106         drwav_uint64 bytesToWriteThisIteration;
   3107 
   3108         bytesToWriteThisIteration = bytesToWrite;
   3109         if (bytesToWriteThisIteration > DRWAV_SIZE_MAX) {
   3110             bytesToWriteThisIteration = DRWAV_SIZE_MAX;
   3111         }
   3112 
   3113         /*
   3114         WAV files are always little-endian. We need to byte swap on big-endian architectures. Since our input buffer is read-only we need
   3115         to use an intermediary buffer for the conversion.
   3116         */
   3117         sampleCount = sizeof(temp)/bytesPerSample;
   3118 
   3119         if (bytesToWriteThisIteration > sampleCount*bytesPerSample) {
   3120             bytesToWriteThisIteration = sampleCount*bytesPerSample;
   3121         }
   3122 
   3123         DRWAV_COPY_MEMORY(temp, pRunningData, (size_t)bytesToWriteThisIteration);
   3124         drwav__bswap_samples(temp, sampleCount, bytesPerSample, pWav->translatedFormatTag);
   3125 
   3126         bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
   3127         if (bytesJustWritten == 0) {
   3128             break;
   3129         }
   3130 
   3131         bytesToWrite -= bytesJustWritten;
   3132         bytesWritten += bytesJustWritten;
   3133         pRunningData += bytesJustWritten;
   3134     }
   3135 
   3136     return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
   3137 }
   3138 
   3139 drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
   3140 {
   3141     if (drwav__is_little_endian()) {
   3142         return drwav_write_pcm_frames_le(pWav, framesToWrite, pData);
   3143     } else {
   3144         return drwav_write_pcm_frames_be(pWav, framesToWrite, pData);
   3145     }
   3146 }
   3147 
   3148 
   3149 drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3150 {
   3151     drwav_uint64 totalFramesRead = 0;
   3152 
   3153     DRWAV_ASSERT(pWav != NULL);
   3154     DRWAV_ASSERT(framesToRead > 0);
   3155     DRWAV_ASSERT(pBufferOut != NULL);
   3156 
   3157     /* TODO: Lots of room for optimization here. */
   3158 
   3159     while (framesToRead > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
   3160         /* If there are no cached frames we need to load a new block. */
   3161         if (pWav->msadpcm.cachedFrameCount == 0 && pWav->msadpcm.bytesRemainingInBlock == 0) {
   3162             if (pWav->channels == 1) {
   3163                 /* Mono. */
   3164                 drwav_uint8 header[7];
   3165                 if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
   3166                     return totalFramesRead;
   3167                 }
   3168                 pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
   3169 
   3170                 pWav->msadpcm.predictor[0]     = header[0];
   3171                 pWav->msadpcm.delta[0]         = drwav__bytes_to_s16(header + 1);
   3172                 pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav__bytes_to_s16(header + 3);
   3173                 pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav__bytes_to_s16(header + 5);
   3174                 pWav->msadpcm.cachedFrames[2]  = pWav->msadpcm.prevFrames[0][0];
   3175                 pWav->msadpcm.cachedFrames[3]  = pWav->msadpcm.prevFrames[0][1];
   3176                 pWav->msadpcm.cachedFrameCount = 2;
   3177             } else {
   3178                 /* Stereo. */
   3179                 drwav_uint8 header[14];
   3180                 if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
   3181                     return totalFramesRead;
   3182                 }
   3183                 pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
   3184 
   3185                 pWav->msadpcm.predictor[0] = header[0];
   3186                 pWav->msadpcm.predictor[1] = header[1];
   3187                 pWav->msadpcm.delta[0] = drwav__bytes_to_s16(header + 2);
   3188                 pWav->msadpcm.delta[1] = drwav__bytes_to_s16(header + 4);
   3189                 pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav__bytes_to_s16(header + 6);
   3190                 pWav->msadpcm.prevFrames[1][1] = (drwav_int32)drwav__bytes_to_s16(header + 8);
   3191                 pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav__bytes_to_s16(header + 10);
   3192                 pWav->msadpcm.prevFrames[1][0] = (drwav_int32)drwav__bytes_to_s16(header + 12);
   3193 
   3194                 pWav->msadpcm.cachedFrames[0] = pWav->msadpcm.prevFrames[0][0];
   3195                 pWav->msadpcm.cachedFrames[1] = pWav->msadpcm.prevFrames[1][0];
   3196                 pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1];
   3197                 pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1];
   3198                 pWav->msadpcm.cachedFrameCount = 2;
   3199             }
   3200         }
   3201 
   3202         /* Output anything that's cached. */
   3203         while (framesToRead > 0 && pWav->msadpcm.cachedFrameCount > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
   3204             drwav_uint32 iSample = 0;
   3205             for (iSample = 0; iSample < pWav->channels; iSample += 1) {
   3206                 pBufferOut[iSample] = (drwav_int16)pWav->msadpcm.cachedFrames[(drwav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
   3207             }
   3208 
   3209             pBufferOut      += pWav->channels;
   3210             framesToRead    -= 1;
   3211             totalFramesRead += 1;
   3212             pWav->compressed.iCurrentPCMFrame += 1;
   3213             pWav->msadpcm.cachedFrameCount -= 1;
   3214         }
   3215 
   3216         if (framesToRead == 0) {
   3217             return totalFramesRead;
   3218         }
   3219 
   3220 
   3221         /*
   3222         If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
   3223         loop iteration which will trigger the loading of a new block.
   3224         */
   3225         if (pWav->msadpcm.cachedFrameCount == 0) {
   3226             if (pWav->msadpcm.bytesRemainingInBlock == 0) {
   3227                 continue;
   3228             } else {
   3229                 static drwav_int32 adaptationTable[] = { 
   3230                     230, 230, 230, 230, 307, 409, 512, 614, 
   3231                     768, 614, 512, 409, 307, 230, 230, 230 
   3232                 };
   3233                 static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460,  392 };
   3234                 static drwav_int32 coeff2Table[] = { 0,  -256, 0, 64,  0,  -208, -232 };
   3235 
   3236                 drwav_uint8 nibbles;
   3237                 drwav_int32 nibble0;
   3238                 drwav_int32 nibble1;
   3239 
   3240                 if (pWav->onRead(pWav->pUserData, &nibbles, 1) != 1) {
   3241                     return totalFramesRead;
   3242                 }
   3243                 pWav->msadpcm.bytesRemainingInBlock -= 1;
   3244 
   3245                 /* TODO: Optimize away these if statements. */
   3246                 nibble0 = ((nibbles & 0xF0) >> 4); if ((nibbles & 0x80)) { nibble0 |= 0xFFFFFFF0UL; }
   3247                 nibble1 = ((nibbles & 0x0F) >> 0); if ((nibbles & 0x08)) { nibble1 |= 0xFFFFFFF0UL; }
   3248 
   3249                 if (pWav->channels == 1) {
   3250                     /* Mono. */
   3251                     drwav_int32 newSample0;
   3252                     drwav_int32 newSample1;
   3253 
   3254                     newSample0  = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
   3255                     newSample0 += nibble0 * pWav->msadpcm.delta[0];
   3256                     newSample0  = drwav_clamp(newSample0, -32768, 32767);
   3257 
   3258                     pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
   3259                     if (pWav->msadpcm.delta[0] < 16) {
   3260                         pWav->msadpcm.delta[0] = 16;
   3261                     }
   3262 
   3263                     pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
   3264                     pWav->msadpcm.prevFrames[0][1] = newSample0;
   3265 
   3266 
   3267                     newSample1  = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
   3268                     newSample1 += nibble1 * pWav->msadpcm.delta[0];
   3269                     newSample1  = drwav_clamp(newSample1, -32768, 32767);
   3270 
   3271                     pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[0]) >> 8;
   3272                     if (pWav->msadpcm.delta[0] < 16) {
   3273                         pWav->msadpcm.delta[0] = 16;
   3274                     }
   3275 
   3276                     pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
   3277                     pWav->msadpcm.prevFrames[0][1] = newSample1;
   3278 
   3279 
   3280                     pWav->msadpcm.cachedFrames[2] = newSample0;
   3281                     pWav->msadpcm.cachedFrames[3] = newSample1;
   3282                     pWav->msadpcm.cachedFrameCount = 2;
   3283                 } else {
   3284                     /* Stereo. */
   3285                     drwav_int32 newSample0;
   3286                     drwav_int32 newSample1;
   3287 
   3288                     /* Left. */
   3289                     newSample0  = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
   3290                     newSample0 += nibble0 * pWav->msadpcm.delta[0];
   3291                     newSample0  = drwav_clamp(newSample0, -32768, 32767);
   3292 
   3293                     pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
   3294                     if (pWav->msadpcm.delta[0] < 16) {
   3295                         pWav->msadpcm.delta[0] = 16;
   3296                     }
   3297 
   3298                     pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
   3299                     pWav->msadpcm.prevFrames[0][1] = newSample0;
   3300 
   3301 
   3302                     /* Right. */
   3303                     newSample1  = ((pWav->msadpcm.prevFrames[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevFrames[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8;
   3304                     newSample1 += nibble1 * pWav->msadpcm.delta[1];
   3305                     newSample1  = drwav_clamp(newSample1, -32768, 32767);
   3306 
   3307                     pWav->msadpcm.delta[1] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[1]) >> 8;
   3308                     if (pWav->msadpcm.delta[1] < 16) {
   3309                         pWav->msadpcm.delta[1] = 16;
   3310                     }
   3311 
   3312                     pWav->msadpcm.prevFrames[1][0] = pWav->msadpcm.prevFrames[1][1];
   3313                     pWav->msadpcm.prevFrames[1][1] = newSample1;
   3314 
   3315                     pWav->msadpcm.cachedFrames[2] = newSample0;
   3316                     pWav->msadpcm.cachedFrames[3] = newSample1;
   3317                     pWav->msadpcm.cachedFrameCount = 1;
   3318                 }
   3319             }
   3320         }
   3321     }
   3322 
   3323     return totalFramesRead;
   3324 }
   3325 
   3326 
   3327 drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3328 {
   3329     drwav_uint64 totalFramesRead = 0;
   3330 
   3331     DRWAV_ASSERT(pWav != NULL);
   3332     DRWAV_ASSERT(framesToRead > 0);
   3333     DRWAV_ASSERT(pBufferOut != NULL);
   3334 
   3335     /* TODO: Lots of room for optimization here. */
   3336 
   3337     while (framesToRead > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
   3338         /* If there are no cached samples we need to load a new block. */
   3339         if (pWav->ima.cachedFrameCount == 0 && pWav->ima.bytesRemainingInBlock == 0) {
   3340             if (pWav->channels == 1) {
   3341                 /* Mono. */
   3342                 drwav_uint8 header[4];
   3343                 if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
   3344                     return totalFramesRead;
   3345                 }
   3346                 pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
   3347 
   3348                 pWav->ima.predictor[0] = drwav__bytes_to_s16(header + 0);
   3349                 pWav->ima.stepIndex[0] = header[2];
   3350                 pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0];
   3351                 pWav->ima.cachedFrameCount = 1;
   3352             } else {
   3353                 /* Stereo. */
   3354                 drwav_uint8 header[8];
   3355                 if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
   3356                     return totalFramesRead;
   3357                 }
   3358                 pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
   3359 
   3360                 pWav->ima.predictor[0] = drwav__bytes_to_s16(header + 0);
   3361                 pWav->ima.stepIndex[0] = header[2];
   3362                 pWav->ima.predictor[1] = drwav__bytes_to_s16(header + 4);
   3363                 pWav->ima.stepIndex[1] = header[6];
   3364 
   3365                 pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
   3366                 pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
   3367                 pWav->ima.cachedFrameCount = 1;
   3368             }
   3369         }
   3370 
   3371         /* Output anything that's cached. */
   3372         while (framesToRead > 0 && pWav->ima.cachedFrameCount > 0 && pWav->compressed.iCurrentPCMFrame < pWav->totalPCMFrameCount) {
   3373             drwav_uint32 iSample;
   3374             for (iSample = 0; iSample < pWav->channels; iSample += 1) {
   3375                 pBufferOut[iSample] = (drwav_int16)pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
   3376             }
   3377 
   3378             pBufferOut      += pWav->channels;
   3379             framesToRead    -= 1;
   3380             totalFramesRead += 1;
   3381             pWav->compressed.iCurrentPCMFrame += 1;
   3382             pWav->ima.cachedFrameCount -= 1;
   3383         }
   3384 
   3385         if (framesToRead == 0) {
   3386             return totalFramesRead;
   3387         }
   3388 
   3389         /*
   3390         If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
   3391         loop iteration which will trigger the loading of a new block.
   3392         */
   3393         if (pWav->ima.cachedFrameCount == 0) {
   3394             if (pWav->ima.bytesRemainingInBlock == 0) {
   3395                 continue;
   3396             } else {
   3397                 static drwav_int32 indexTable[16] = {
   3398                     -1, -1, -1, -1, 2, 4, 6, 8,
   3399                     -1, -1, -1, -1, 2, 4, 6, 8
   3400                 };
   3401 
   3402                 static drwav_int32 stepTable[89] = {
   3403                     7,     8,     9,     10,    11,    12,    13,    14,    16,    17, 
   3404                     19,    21,    23,    25,    28,    31,    34,    37,    41,    45, 
   3405                     50,    55,    60,    66,    73,    80,    88,    97,    107,   118, 
   3406                     130,   143,   157,   173,   190,   209,   230,   253,   279,   307,
   3407                     337,   371,   408,   449,   494,   544,   598,   658,   724,   796,
   3408                     876,   963,   1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066, 
   3409                     2272,  2499,  2749,  3024,  3327,  3660,  4026,  4428,  4871,  5358,
   3410                     5894,  6484,  7132,  7845,  8630,  9493,  10442, 11487, 12635, 13899, 
   3411                     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 
   3412                 };
   3413 
   3414                 drwav_uint32 iChannel;
   3415 
   3416                 /*
   3417                 From what I can tell with stereo streams, it looks like every 4 bytes (8 samples) is for one channel. So it goes 4 bytes for the
   3418                 left channel, 4 bytes for the right channel.
   3419                 */
   3420                 pWav->ima.cachedFrameCount = 8;
   3421                 for (iChannel = 0; iChannel < pWav->channels; ++iChannel) {
   3422                     drwav_uint32 iByte;
   3423                     drwav_uint8 nibbles[4];
   3424                     if (pWav->onRead(pWav->pUserData, &nibbles, 4) != 4) {
   3425                         return totalFramesRead;
   3426                     }
   3427                     pWav->ima.bytesRemainingInBlock -= 4;
   3428 
   3429                     for (iByte = 0; iByte < 4; ++iByte) {
   3430                         drwav_uint8 nibble0 = ((nibbles[iByte] & 0x0F) >> 0);
   3431                         drwav_uint8 nibble1 = ((nibbles[iByte] & 0xF0) >> 4);
   3432 
   3433                         drwav_int32 step      = stepTable[pWav->ima.stepIndex[iChannel]];
   3434                         drwav_int32 predictor = pWav->ima.predictor[iChannel];
   3435 
   3436                         drwav_int32      diff  = step >> 3;
   3437                         if (nibble0 & 1) diff += step >> 2;
   3438                         if (nibble0 & 2) diff += step >> 1;
   3439                         if (nibble0 & 4) diff += step;
   3440                         if (nibble0 & 8) diff  = -diff;
   3441 
   3442                         predictor = drwav_clamp(predictor + diff, -32768, 32767);
   3443                         pWav->ima.predictor[iChannel] = predictor;
   3444                         pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble0], 0, (drwav_int32)drwav_countof(stepTable)-1);
   3445                         pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+0)*pWav->channels + iChannel] = predictor;
   3446 
   3447 
   3448                         step      = stepTable[pWav->ima.stepIndex[iChannel]];
   3449                         predictor = pWav->ima.predictor[iChannel];
   3450 
   3451                                          diff  = step >> 3;
   3452                         if (nibble1 & 1) diff += step >> 2;
   3453                         if (nibble1 & 2) diff += step >> 1;
   3454                         if (nibble1 & 4) diff += step;
   3455                         if (nibble1 & 8) diff  = -diff;
   3456 
   3457                         predictor = drwav_clamp(predictor + diff, -32768, 32767);
   3458                         pWav->ima.predictor[iChannel] = predictor;
   3459                         pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble1], 0, (drwav_int32)drwav_countof(stepTable)-1);
   3460                         pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+1)*pWav->channels + iChannel] = predictor;
   3461                     }
   3462                 }
   3463             }
   3464         }
   3465     }
   3466 
   3467     return totalFramesRead;
   3468 }
   3469 
   3470 
   3471 #ifndef DR_WAV_NO_CONVERSION_API
   3472 static unsigned short g_drwavAlawTable[256] = {
   3473     0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80, 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580, 
   3474     0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0, 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0, 
   3475     0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600, 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600, 
   3476     0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00, 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00, 
   3477     0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8, 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58, 
   3478     0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8, 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58, 
   3479     0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60, 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960, 
   3480     0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0, 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0, 
   3481     0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280, 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80, 
   3482     0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940, 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40, 
   3483     0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00, 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00, 
   3484     0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500, 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500, 
   3485     0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128, 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8, 
   3486     0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028, 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8, 
   3487     0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0, 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0, 
   3488     0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250, 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350
   3489 };
   3490 
   3491 static unsigned short g_drwavMulawTable[256] = {
   3492     0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84, 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84, 
   3493     0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84, 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84, 
   3494     0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804, 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004, 
   3495     0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444, 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844, 
   3496     0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64, 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64, 
   3497     0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74, 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74, 
   3498     0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC, 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C, 
   3499     0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0, 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000, 
   3500     0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C, 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C, 
   3501     0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C, 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C, 
   3502     0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC, 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC, 
   3503     0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC, 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC, 
   3504     0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C, 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C, 
   3505     0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C, 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C, 
   3506     0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104, 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084, 
   3507     0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040, 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
   3508 };
   3509 
   3510 static DRWAV_INLINE drwav_int16 drwav__alaw_to_s16(drwav_uint8 sampleIn)
   3511 {
   3512     return (short)g_drwavAlawTable[sampleIn];
   3513 }
   3514 
   3515 static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn)
   3516 {
   3517     return (short)g_drwavMulawTable[sampleIn];
   3518 }
   3519 
   3520 
   3521 
   3522 static void drwav__pcm_to_s16(drwav_int16* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
   3523 {
   3524     unsigned int i;
   3525 
   3526     /* Special case for 8-bit sample data because it's treated as unsigned. */
   3527     if (bytesPerSample == 1) {
   3528         drwav_u8_to_s16(pOut, pIn, totalSampleCount);
   3529         return;
   3530     }
   3531 
   3532 
   3533     /* Slightly more optimal implementation for common formats. */
   3534     if (bytesPerSample == 2) {
   3535         for (i = 0; i < totalSampleCount; ++i) {
   3536            *pOut++ = ((const drwav_int16*)pIn)[i];
   3537         }
   3538         return;
   3539     }
   3540     if (bytesPerSample == 3) {
   3541         drwav_s24_to_s16(pOut, pIn, totalSampleCount);
   3542         return;
   3543     }
   3544     if (bytesPerSample == 4) {
   3545         drwav_s32_to_s16(pOut, (const drwav_int32*)pIn, totalSampleCount);
   3546         return;
   3547     }
   3548 
   3549 
   3550     /* Anything more than 64 bits per sample is not supported. */
   3551     if (bytesPerSample > 8) {
   3552         DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
   3553         return;
   3554     }
   3555 
   3556 
   3557     /* Generic, slow converter. */
   3558     for (i = 0; i < totalSampleCount; ++i) {
   3559         drwav_uint64 sample = 0;
   3560         unsigned int shift  = (8 - bytesPerSample) * 8;
   3561 
   3562         unsigned int j;
   3563         for (j = 0; j < bytesPerSample && j < 8; j += 1) {
   3564             sample |= (drwav_uint64)(pIn[j]) << shift;
   3565             shift  += 8;
   3566         }
   3567 
   3568         pIn += j;
   3569         *pOut++ = (drwav_int16)((drwav_int64)sample >> 48);
   3570     }
   3571 }
   3572 
   3573 static void drwav__ieee_to_s16(drwav_int16* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
   3574 {
   3575     if (bytesPerSample == 4) {
   3576         drwav_f32_to_s16(pOut, (const float*)pIn, totalSampleCount);
   3577         return;
   3578     } else if (bytesPerSample == 8) {
   3579         drwav_f64_to_s16(pOut, (const double*)pIn, totalSampleCount);
   3580         return;
   3581     } else {
   3582         /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
   3583         DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
   3584         return;
   3585     }
   3586 }
   3587 
   3588 drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3589 {
   3590     drwav_uint32 bytesPerFrame;
   3591     drwav_uint64 totalFramesRead;
   3592     unsigned char sampleData[4096];
   3593 
   3594     /* Fast path. */
   3595     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) {
   3596         return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
   3597     }
   3598     
   3599     bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   3600     if (bytesPerFrame == 0) {
   3601         return 0;
   3602     }
   3603 
   3604     totalFramesRead = 0;
   3605     
   3606     while (framesToRead > 0) {
   3607         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   3608         if (framesRead == 0) {
   3609             break;
   3610         }
   3611 
   3612         drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
   3613 
   3614         pBufferOut      += framesRead*pWav->channels;
   3615         framesToRead    -= framesRead;
   3616         totalFramesRead += framesRead;
   3617     }
   3618 
   3619     return totalFramesRead;
   3620 }
   3621 
   3622 drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3623 {
   3624     drwav_uint64 totalFramesRead;
   3625     unsigned char sampleData[4096];
   3626 
   3627     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   3628     if (bytesPerFrame == 0) {
   3629         return 0;
   3630     }
   3631 
   3632     totalFramesRead = 0;
   3633     
   3634     while (framesToRead > 0) {
   3635         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   3636         if (framesRead == 0) {
   3637             break;
   3638         }
   3639 
   3640         drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
   3641 
   3642         pBufferOut      += framesRead*pWav->channels;
   3643         framesToRead    -= framesRead;
   3644         totalFramesRead += framesRead;
   3645     }
   3646 
   3647     return totalFramesRead;
   3648 }
   3649 
   3650 drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3651 {
   3652     drwav_uint64 totalFramesRead;
   3653     unsigned char sampleData[4096];
   3654 
   3655     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   3656     if (bytesPerFrame == 0) {
   3657         return 0;
   3658     }
   3659 
   3660     totalFramesRead = 0;
   3661     
   3662     while (framesToRead > 0) {
   3663         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   3664         if (framesRead == 0) {
   3665             break;
   3666         }
   3667 
   3668         drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   3669 
   3670         pBufferOut      += framesRead*pWav->channels;
   3671         framesToRead    -= framesRead;
   3672         totalFramesRead += framesRead;
   3673     }
   3674 
   3675     return totalFramesRead;
   3676 }
   3677 
   3678 drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3679 {
   3680     drwav_uint64 totalFramesRead;
   3681     unsigned char sampleData[4096];
   3682 
   3683     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   3684     if (bytesPerFrame == 0) {
   3685         return 0;
   3686     }
   3687 
   3688     totalFramesRead = 0;
   3689 
   3690     while (framesToRead > 0) {
   3691         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   3692         if (framesRead == 0) {
   3693             break;
   3694         }
   3695 
   3696         drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   3697 
   3698         pBufferOut      += framesRead*pWav->channels;
   3699         framesToRead    -= framesRead;
   3700         totalFramesRead += framesRead;
   3701     }
   3702 
   3703     return totalFramesRead;
   3704 }
   3705 
   3706 drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3707 {
   3708     if (pWav == NULL || framesToRead == 0 || pBufferOut == NULL) {
   3709         return 0;
   3710     }
   3711 
   3712     /* Don't try to read more samples than can potentially fit in the output buffer. */
   3713     if (framesToRead * pWav->channels * sizeof(drwav_int16) > DRWAV_SIZE_MAX) {
   3714         framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int16) / pWav->channels;
   3715     }
   3716 
   3717     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
   3718         return drwav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
   3719     }
   3720 
   3721     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
   3722         return drwav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
   3723     }
   3724 
   3725     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
   3726         return drwav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
   3727     }
   3728 
   3729     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
   3730         return drwav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
   3731     }
   3732 
   3733     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   3734         return drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
   3735     }
   3736 
   3737     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   3738         return drwav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
   3739     }
   3740 
   3741     return 0;
   3742 }
   3743 
   3744 drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3745 {
   3746     drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
   3747     if (!drwav__is_little_endian()) {
   3748         drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
   3749     }
   3750 
   3751     return framesRead;
   3752 }
   3753 
   3754 drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
   3755 {
   3756     drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
   3757     if (drwav__is_little_endian()) {
   3758         drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
   3759     }
   3760 
   3761     return framesRead;
   3762 }
   3763 
   3764 
   3765 void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
   3766 {
   3767     int r;
   3768     size_t i;
   3769     for (i = 0; i < sampleCount; ++i) {
   3770         int x = pIn[i];
   3771         r = x << 8;
   3772         r = r - 32768;
   3773         pOut[i] = (short)r;
   3774     }
   3775 }
   3776 
   3777 void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
   3778 {
   3779     int r;
   3780     size_t i;
   3781     for (i = 0; i < sampleCount; ++i) {
   3782         int x = ((int)(((unsigned int)(((const unsigned char*)pIn)[i*3+0]) << 8) | ((unsigned int)(((const unsigned char*)pIn)[i*3+1]) << 16) | ((unsigned int)(((const unsigned char*)pIn)[i*3+2])) << 24)) >> 8;
   3783         r = x >> 8;
   3784         pOut[i] = (short)r;
   3785     }
   3786 }
   3787 
   3788 void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount)
   3789 {
   3790     int r;
   3791     size_t i;
   3792     for (i = 0; i < sampleCount; ++i) {
   3793         int x = pIn[i];
   3794         r = x >> 16;
   3795         pOut[i] = (short)r;
   3796     }
   3797 }
   3798 
   3799 void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount)
   3800 {
   3801     int r;
   3802     size_t i;
   3803     for (i = 0; i < sampleCount; ++i) {
   3804         float x = pIn[i];
   3805         float c;
   3806         c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
   3807         c = c + 1;
   3808         r = (int)(c * 32767.5f);
   3809         r = r - 32768;
   3810         pOut[i] = (short)r;
   3811     }
   3812 }
   3813 
   3814 void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount)
   3815 {
   3816     int r;
   3817     size_t i;
   3818     for (i = 0; i < sampleCount; ++i) {
   3819         double x = pIn[i];
   3820         double c;
   3821         c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
   3822         c = c + 1;
   3823         r = (int)(c * 32767.5);
   3824         r = r - 32768;
   3825         pOut[i] = (short)r;
   3826     }
   3827 }
   3828 
   3829 void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
   3830 {
   3831     size_t i;
   3832     for (i = 0; i < sampleCount; ++i) {
   3833         pOut[i] = drwav__alaw_to_s16(pIn[i]);
   3834     }
   3835 }
   3836 
   3837 void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
   3838 {
   3839     size_t i;
   3840     for (i = 0; i < sampleCount; ++i) {
   3841         pOut[i] = drwav__mulaw_to_s16(pIn[i]);
   3842     }
   3843 }
   3844 
   3845 
   3846 
   3847 static void drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t sampleCount, unsigned int bytesPerSample)
   3848 {
   3849     unsigned int i;
   3850 
   3851     /* Special case for 8-bit sample data because it's treated as unsigned. */
   3852     if (bytesPerSample == 1) {
   3853         drwav_u8_to_f32(pOut, pIn, sampleCount);
   3854         return;
   3855     }
   3856 
   3857     /* Slightly more optimal implementation for common formats. */
   3858     if (bytesPerSample == 2) {
   3859         drwav_s16_to_f32(pOut, (const drwav_int16*)pIn, sampleCount);
   3860         return;
   3861     }
   3862     if (bytesPerSample == 3) {
   3863         drwav_s24_to_f32(pOut, pIn, sampleCount);
   3864         return;
   3865     }
   3866     if (bytesPerSample == 4) {
   3867         drwav_s32_to_f32(pOut, (const drwav_int32*)pIn, sampleCount);
   3868         return;
   3869     }
   3870 
   3871 
   3872     /* Anything more than 64 bits per sample is not supported. */
   3873     if (bytesPerSample > 8) {
   3874         DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
   3875         return;
   3876     }
   3877 
   3878 
   3879     /* Generic, slow converter. */
   3880     for (i = 0; i < sampleCount; ++i) {
   3881         drwav_uint64 sample = 0;
   3882         unsigned int shift  = (8 - bytesPerSample) * 8;
   3883 
   3884         unsigned int j;
   3885         for (j = 0; j < bytesPerSample && j < 8; j += 1) {
   3886             sample |= (drwav_uint64)(pIn[j]) << shift;
   3887             shift  += 8;
   3888         }
   3889 
   3890         pIn += j;
   3891         *pOut++ = (float)((drwav_int64)sample / 9223372036854775807.0);
   3892     }
   3893 }
   3894 
   3895 static void drwav__ieee_to_f32(float* pOut, const unsigned char* pIn, size_t sampleCount, unsigned int bytesPerSample)
   3896 {
   3897     if (bytesPerSample == 4) {
   3898         unsigned int i;
   3899         for (i = 0; i < sampleCount; ++i) {
   3900             *pOut++ = ((const float*)pIn)[i];
   3901         }
   3902         return;
   3903     } else if (bytesPerSample == 8) {
   3904         drwav_f64_to_f32(pOut, (const double*)pIn, sampleCount);
   3905         return;
   3906     } else {
   3907         /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
   3908         DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
   3909         return;
   3910     }
   3911 }
   3912 
   3913 
   3914 drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   3915 {
   3916     drwav_uint64 totalFramesRead;
   3917     unsigned char sampleData[4096];
   3918 
   3919     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   3920     if (bytesPerFrame == 0) {
   3921         return 0;
   3922     }
   3923 
   3924     totalFramesRead = 0;
   3925 
   3926     while (framesToRead > 0) {
   3927         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   3928         if (framesRead == 0) {
   3929             break;
   3930         }
   3931 
   3932         drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)framesRead*pWav->channels, bytesPerFrame/pWav->channels);
   3933 
   3934         pBufferOut      += framesRead*pWav->channels;
   3935         framesToRead    -= framesRead;
   3936         totalFramesRead += framesRead;
   3937     }
   3938 
   3939     return totalFramesRead;
   3940 }
   3941 
   3942 drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   3943 {
   3944     /*
   3945     We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
   3946     want to duplicate that code.
   3947     */
   3948     drwav_uint64 totalFramesRead = 0;
   3949     drwav_int16 samples16[2048];
   3950     while (framesToRead > 0) {
   3951         drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
   3952         if (framesRead == 0) {
   3953             break;
   3954         }
   3955 
   3956         drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));   /* <-- Safe cast because we're clamping to 2048. */
   3957 
   3958         pBufferOut      += framesRead*pWav->channels;
   3959         framesToRead    -= framesRead;
   3960         totalFramesRead += framesRead;
   3961     }
   3962 
   3963     return totalFramesRead;
   3964 }
   3965 
   3966 drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   3967 {
   3968     /*
   3969     We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
   3970     want to duplicate that code.
   3971     */
   3972     drwav_uint64 totalFramesRead = 0;
   3973     drwav_int16 samples16[2048];
   3974     while (framesToRead > 0) {
   3975         drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
   3976         if (framesRead == 0) {
   3977             break;
   3978         }
   3979 
   3980         drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));   /* <-- Safe cast because we're clamping to 2048. */
   3981 
   3982         pBufferOut      += framesRead*pWav->channels;
   3983         framesToRead    -= framesRead;
   3984         totalFramesRead += framesRead;
   3985     }
   3986 
   3987     return totalFramesRead;
   3988 }
   3989 
   3990 drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   3991 {
   3992     drwav_uint64 totalFramesRead;
   3993     unsigned char sampleData[4096];
   3994     drwav_uint32 bytesPerFrame;
   3995 
   3996     /* Fast path. */
   3997     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
   3998         return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
   3999     }
   4000     
   4001     bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4002     if (bytesPerFrame == 0) {
   4003         return 0;
   4004     }
   4005 
   4006     totalFramesRead = 0;
   4007 
   4008     while (framesToRead > 0) {
   4009         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4010         if (framesRead == 0) {
   4011             break;
   4012         }
   4013 
   4014         drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
   4015 
   4016         pBufferOut      += framesRead*pWav->channels;
   4017         framesToRead    -= framesRead;
   4018         totalFramesRead += framesRead;
   4019     }
   4020 
   4021     return totalFramesRead;
   4022 }
   4023 
   4024 drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   4025 {
   4026     drwav_uint64 totalFramesRead;
   4027     unsigned char sampleData[4096];
   4028     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4029     if (bytesPerFrame == 0) {
   4030         return 0;
   4031     }
   4032 
   4033     totalFramesRead = 0;
   4034 
   4035     while (bytesPerFrame > 0) {
   4036         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4037         if (framesRead == 0) {
   4038             break;
   4039         }
   4040 
   4041         drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   4042 
   4043         pBufferOut      += framesRead*pWav->channels;
   4044         framesToRead    -= framesRead;
   4045         totalFramesRead += framesRead;
   4046     }
   4047 
   4048     return totalFramesRead;
   4049 }
   4050 
   4051 drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   4052 {
   4053     drwav_uint64 totalFramesRead;
   4054     unsigned char sampleData[4096];
   4055 
   4056     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4057     if (bytesPerFrame == 0) {
   4058         return 0;
   4059     }
   4060 
   4061     totalFramesRead = 0;
   4062 
   4063     while (framesToRead > 0) {
   4064         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4065         if (framesRead == 0) {
   4066             break;
   4067         }
   4068 
   4069         drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   4070 
   4071         pBufferOut      += framesRead*pWav->channels;
   4072         framesToRead    -= framesRead;
   4073         totalFramesRead += framesRead;
   4074     }
   4075 
   4076     return totalFramesRead;
   4077 }
   4078 
   4079 drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   4080 {
   4081     if (pWav == NULL || framesToRead == 0 || pBufferOut == NULL) {
   4082         return 0;
   4083     }
   4084 
   4085     /* Don't try to read more samples than can potentially fit in the output buffer. */
   4086     if (framesToRead * pWav->channels * sizeof(float) > DRWAV_SIZE_MAX) {
   4087         framesToRead = DRWAV_SIZE_MAX / sizeof(float) / pWav->channels;
   4088     }
   4089 
   4090     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
   4091         return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
   4092     }
   4093 
   4094     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   4095         return drwav_read_pcm_frames_f32__msadpcm(pWav, framesToRead, pBufferOut);
   4096     }
   4097 
   4098     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
   4099         return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
   4100     }
   4101 
   4102     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
   4103         return drwav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
   4104     }
   4105 
   4106     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
   4107         return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
   4108     }
   4109 
   4110     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   4111         return drwav_read_pcm_frames_f32__ima(pWav, framesToRead, pBufferOut);
   4112     }
   4113 
   4114     return 0;
   4115 }
   4116 
   4117 drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   4118 {
   4119     drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
   4120     if (!drwav__is_little_endian()) {
   4121         drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
   4122     }
   4123 
   4124     return framesRead;
   4125 }
   4126 
   4127 drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
   4128 {
   4129     drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
   4130     if (drwav__is_little_endian()) {
   4131         drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
   4132     }
   4133 
   4134     return framesRead;
   4135 }
   4136 
   4137 
   4138 void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4139 {
   4140     size_t i;
   4141 
   4142     if (pOut == NULL || pIn == NULL) {
   4143         return;
   4144     }
   4145 
   4146 #ifdef DR_WAV_LIBSNDFILE_COMPAT
   4147     /*
   4148     It appears libsndfile uses slightly different logic for the u8 -> f32 conversion to dr_wav, which in my opinion is incorrect. It appears
   4149     libsndfile performs the conversion something like "f32 = (u8 / 256) * 2 - 1", however I think it should be "f32 = (u8 / 255) * 2 - 1" (note
   4150     the divisor of 256 vs 255). I use libsndfile as a benchmark for testing, so I'm therefore leaving this block here just for my automated
   4151     correctness testing. This is disabled by default.
   4152     */
   4153     for (i = 0; i < sampleCount; ++i) {
   4154         *pOut++ = (pIn[i] / 256.0f) * 2 - 1;
   4155     }
   4156 #else
   4157     for (i = 0; i < sampleCount; ++i) {
   4158         *pOut++ = (pIn[i] / 255.0f) * 2 - 1;
   4159     }
   4160 #endif
   4161 }
   4162 
   4163 void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount)
   4164 {
   4165     size_t i;
   4166 
   4167     if (pOut == NULL || pIn == NULL) {
   4168         return;
   4169     }
   4170 
   4171     for (i = 0; i < sampleCount; ++i) {
   4172         *pOut++ = pIn[i] / 32768.0f;
   4173     }
   4174 }
   4175 
   4176 void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4177 {
   4178     size_t i;
   4179 
   4180     if (pOut == NULL || pIn == NULL) {
   4181         return;
   4182     }
   4183 
   4184     for (i = 0; i < sampleCount; ++i) {
   4185         unsigned int s0 = pIn[i*3 + 0];
   4186         unsigned int s1 = pIn[i*3 + 1];
   4187         unsigned int s2 = pIn[i*3 + 2];
   4188 
   4189         int sample32 = (int)((s0 << 8) | (s1 << 16) | (s2 << 24));
   4190         *pOut++ = (float)(sample32 / 2147483648.0);
   4191     }
   4192 }
   4193 
   4194 void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount)
   4195 {
   4196     size_t i;
   4197     if (pOut == NULL || pIn == NULL) {
   4198         return;
   4199     }
   4200 
   4201     for (i = 0; i < sampleCount; ++i) {
   4202         *pOut++ = (float)(pIn[i] / 2147483648.0);
   4203     }
   4204 }
   4205 
   4206 void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount)
   4207 {
   4208     size_t i;
   4209 
   4210     if (pOut == NULL || pIn == NULL) {
   4211         return;
   4212     }
   4213 
   4214     for (i = 0; i < sampleCount; ++i) {
   4215         *pOut++ = (float)pIn[i];
   4216     }
   4217 }
   4218 
   4219 void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4220 {
   4221     size_t i;
   4222 
   4223     if (pOut == NULL || pIn == NULL) {
   4224         return;
   4225     }
   4226 
   4227     for (i = 0; i < sampleCount; ++i) {
   4228         *pOut++ = drwav__alaw_to_s16(pIn[i]) / 32768.0f;
   4229     }
   4230 }
   4231 
   4232 void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4233 {
   4234     size_t i;
   4235 
   4236     if (pOut == NULL || pIn == NULL) {
   4237         return;
   4238     }
   4239 
   4240     for (i = 0; i < sampleCount; ++i) {
   4241         *pOut++ = drwav__mulaw_to_s16(pIn[i]) / 32768.0f;
   4242     }
   4243 }
   4244 
   4245 
   4246 
   4247 static void drwav__pcm_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
   4248 {
   4249     unsigned int i;
   4250 
   4251     /* Special case for 8-bit sample data because it's treated as unsigned. */
   4252     if (bytesPerSample == 1) {
   4253         drwav_u8_to_s32(pOut, pIn, totalSampleCount);
   4254         return;
   4255     }
   4256 
   4257     /* Slightly more optimal implementation for common formats. */
   4258     if (bytesPerSample == 2) {
   4259         drwav_s16_to_s32(pOut, (const drwav_int16*)pIn, totalSampleCount);
   4260         return;
   4261     }
   4262     if (bytesPerSample == 3) {
   4263         drwav_s24_to_s32(pOut, pIn, totalSampleCount);
   4264         return;
   4265     }
   4266     if (bytesPerSample == 4) {
   4267         for (i = 0; i < totalSampleCount; ++i) {
   4268            *pOut++ = ((const drwav_int32*)pIn)[i];
   4269         }
   4270         return;
   4271     }
   4272 
   4273 
   4274     /* Anything more than 64 bits per sample is not supported. */
   4275     if (bytesPerSample > 8) {
   4276         DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
   4277         return;
   4278     }
   4279 
   4280 
   4281     /* Generic, slow converter. */
   4282     for (i = 0; i < totalSampleCount; ++i) {
   4283         drwav_uint64 sample = 0;
   4284         unsigned int shift  = (8 - bytesPerSample) * 8;
   4285 
   4286         unsigned int j;
   4287         for (j = 0; j < bytesPerSample && j < 8; j += 1) {
   4288             sample |= (drwav_uint64)(pIn[j]) << shift;
   4289             shift  += 8;
   4290         }
   4291 
   4292         pIn += j;
   4293         *pOut++ = (drwav_int32)((drwav_int64)sample >> 32);
   4294     }
   4295 }
   4296 
   4297 static void drwav__ieee_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
   4298 {
   4299     if (bytesPerSample == 4) {
   4300         drwav_f32_to_s32(pOut, (const float*)pIn, totalSampleCount);
   4301         return;
   4302     } else if (bytesPerSample == 8) {
   4303         drwav_f64_to_s32(pOut, (const double*)pIn, totalSampleCount);
   4304         return;
   4305     } else {
   4306         /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
   4307         DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
   4308         return;
   4309     }
   4310 }
   4311 
   4312 
   4313 drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4314 {
   4315     drwav_uint64 totalFramesRead;
   4316     unsigned char sampleData[4096];
   4317     drwav_uint32 bytesPerFrame;
   4318 
   4319     /* Fast path. */
   4320     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
   4321         return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
   4322     }
   4323     
   4324     bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4325     if (bytesPerFrame == 0) {
   4326         return 0;
   4327     }
   4328 
   4329     totalFramesRead = 0;
   4330 
   4331     while (framesToRead > 0) {
   4332         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4333         if (framesRead == 0) {
   4334             break;
   4335         }
   4336 
   4337         drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
   4338 
   4339         pBufferOut      += framesRead*pWav->channels;
   4340         framesToRead    -= framesRead;
   4341         totalFramesRead += framesRead;
   4342     }
   4343 
   4344     return totalFramesRead;
   4345 }
   4346 
   4347 drwav_uint64 drwav_read_pcm_frames_s32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4348 {
   4349     /*
   4350     We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
   4351     want to duplicate that code.
   4352     */
   4353     drwav_uint64 totalFramesRead = 0;
   4354     drwav_int16 samples16[2048];
   4355     while (framesToRead > 0) {
   4356         drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
   4357         if (framesRead == 0) {
   4358             break;
   4359         }
   4360 
   4361         drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));   /* <-- Safe cast because we're clamping to 2048. */
   4362 
   4363         pBufferOut      += framesRead*pWav->channels;
   4364         framesToRead    -= framesRead;
   4365         totalFramesRead += framesRead;
   4366     }
   4367 
   4368     return totalFramesRead;
   4369 }
   4370 
   4371 drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4372 {
   4373     /*
   4374     We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
   4375     want to duplicate that code.
   4376     */
   4377     drwav_uint64 totalFramesRead = 0;
   4378     drwav_int16 samples16[2048];
   4379     while (framesToRead > 0) {
   4380         drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
   4381         if (framesRead == 0) {
   4382             break;
   4383         }
   4384 
   4385         drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));   /* <-- Safe cast because we're clamping to 2048. */
   4386 
   4387         pBufferOut      += framesRead*pWav->channels;
   4388         framesToRead    -= framesRead;
   4389         totalFramesRead += framesRead;
   4390     }
   4391 
   4392     return totalFramesRead;
   4393 }
   4394 
   4395 drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4396 {
   4397     drwav_uint64 totalFramesRead;
   4398     unsigned char sampleData[4096];
   4399 
   4400     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4401     if (bytesPerFrame == 0) {
   4402         return 0;
   4403     }
   4404 
   4405     totalFramesRead = 0;
   4406 
   4407     while (framesToRead > 0) {
   4408         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4409         if (framesRead == 0) {
   4410             break;
   4411         }
   4412 
   4413         drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
   4414 
   4415         pBufferOut      += framesRead*pWav->channels;
   4416         framesToRead    -= framesRead;
   4417         totalFramesRead += framesRead;
   4418     }
   4419 
   4420     return totalFramesRead;
   4421 }
   4422 
   4423 drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4424 {
   4425     drwav_uint64 totalFramesRead;
   4426     unsigned char sampleData[4096];
   4427 
   4428     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4429     if (bytesPerFrame == 0) {
   4430         return 0;
   4431     }
   4432 
   4433     totalFramesRead = 0;
   4434 
   4435     while (framesToRead > 0) {
   4436         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4437         if (framesRead == 0) {
   4438             break;
   4439         }
   4440 
   4441         drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   4442 
   4443         pBufferOut      += framesRead*pWav->channels;
   4444         framesToRead    -= framesRead;
   4445         totalFramesRead += framesRead;
   4446     }
   4447 
   4448     return totalFramesRead;
   4449 }
   4450 
   4451 drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4452 {
   4453     drwav_uint64 totalFramesRead;
   4454     unsigned char sampleData[4096];
   4455 
   4456     drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
   4457     if (bytesPerFrame == 0) {
   4458         return 0;
   4459     }
   4460 
   4461     totalFramesRead = 0;
   4462 
   4463     while (framesToRead > 0) {
   4464         drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
   4465         if (framesRead == 0) {
   4466             break;
   4467         }
   4468 
   4469         drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
   4470 
   4471         pBufferOut      += framesRead*pWav->channels;
   4472         framesToRead    -= framesRead;
   4473         totalFramesRead += framesRead;
   4474     }
   4475 
   4476     return totalFramesRead;
   4477 }
   4478 
   4479 drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4480 {
   4481     if (pWav == NULL || framesToRead == 0 || pBufferOut == NULL) {
   4482         return 0;
   4483     }
   4484 
   4485     /* Don't try to read more samples than can potentially fit in the output buffer. */
   4486     if (framesToRead * pWav->channels * sizeof(drwav_int32) > DRWAV_SIZE_MAX) {
   4487         framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int32) / pWav->channels;
   4488     }
   4489 
   4490 
   4491     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
   4492         return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
   4493     }
   4494 
   4495     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
   4496         return drwav_read_pcm_frames_s32__msadpcm(pWav, framesToRead, pBufferOut);
   4497     }
   4498 
   4499     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
   4500         return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
   4501     }
   4502 
   4503     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
   4504         return drwav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
   4505     }
   4506 
   4507     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
   4508         return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
   4509     }
   4510 
   4511     if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
   4512         return drwav_read_pcm_frames_s32__ima(pWav, framesToRead, pBufferOut);
   4513     }
   4514 
   4515     return 0;
   4516 }
   4517 
   4518 drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4519 {
   4520     drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
   4521     if (!drwav__is_little_endian()) {
   4522         drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
   4523     }
   4524 
   4525     return framesRead;
   4526 }
   4527 
   4528 drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
   4529 {
   4530     drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
   4531     if (drwav__is_little_endian()) {
   4532         drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
   4533     }
   4534 
   4535     return framesRead;
   4536 }
   4537 
   4538 
   4539 void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4540 {
   4541     size_t i;
   4542 
   4543     if (pOut == NULL || pIn == NULL) {
   4544         return;
   4545     }
   4546 
   4547     for (i = 0; i < sampleCount; ++i) {
   4548         *pOut++ = ((int)pIn[i] - 128) << 24;
   4549     }
   4550 }
   4551 
   4552 void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount)
   4553 {
   4554     size_t i;
   4555 
   4556     if (pOut == NULL || pIn == NULL) {
   4557         return;
   4558     }
   4559 
   4560     for (i = 0; i < sampleCount; ++i) {
   4561         *pOut++ = pIn[i] << 16;
   4562     }
   4563 }
   4564 
   4565 void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4566 {
   4567     size_t i;
   4568 
   4569     if (pOut == NULL || pIn == NULL) {
   4570         return;
   4571     }
   4572 
   4573     for (i = 0; i < sampleCount; ++i) {
   4574         unsigned int s0 = pIn[i*3 + 0];
   4575         unsigned int s1 = pIn[i*3 + 1];
   4576         unsigned int s2 = pIn[i*3 + 2];
   4577 
   4578         drwav_int32 sample32 = (drwav_int32)((s0 << 8) | (s1 << 16) | (s2 << 24));
   4579         *pOut++ = sample32;
   4580     }
   4581 }
   4582 
   4583 void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount)
   4584 {
   4585     size_t i;
   4586 
   4587     if (pOut == NULL || pIn == NULL) {
   4588         return;
   4589     }
   4590 
   4591     for (i = 0; i < sampleCount; ++i) {
   4592         *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
   4593     }
   4594 }
   4595 
   4596 void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount)
   4597 {
   4598     size_t i;
   4599 
   4600     if (pOut == NULL || pIn == NULL) {
   4601         return;
   4602     }
   4603 
   4604     for (i = 0; i < sampleCount; ++i) {
   4605         *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
   4606     }
   4607 }
   4608 
   4609 void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4610 {
   4611     size_t i;
   4612 
   4613     if (pOut == NULL || pIn == NULL) {
   4614         return;
   4615     }
   4616 
   4617     for (i = 0; i < sampleCount; ++i) {
   4618         *pOut++ = ((drwav_int32)drwav__alaw_to_s16(pIn[i])) << 16;
   4619     }
   4620 }
   4621 
   4622 void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
   4623 {
   4624     size_t i;
   4625 
   4626     if (pOut == NULL || pIn == NULL) {
   4627         return;
   4628     }
   4629 
   4630     for (i= 0; i < sampleCount; ++i) {
   4631         *pOut++ = ((drwav_int32)drwav__mulaw_to_s16(pIn[i])) << 16;
   4632     }
   4633 }
   4634 
   4635 
   4636 
   4637 drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
   4638 {
   4639     drwav_uint64 sampleDataSize;
   4640     drwav_int16* pSampleData;
   4641     drwav_uint64 framesRead;
   4642 
   4643     DRWAV_ASSERT(pWav != NULL);
   4644 
   4645     sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
   4646     if (sampleDataSize > DRWAV_SIZE_MAX) {
   4647         drwav_uninit(pWav);
   4648         return NULL;    /* File's too big. */
   4649     }
   4650 
   4651     pSampleData = (drwav_int16*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
   4652     if (pSampleData == NULL) {
   4653         drwav_uninit(pWav);
   4654         return NULL;    /* Failed to allocate memory. */
   4655     }
   4656 
   4657     framesRead = drwav_read_pcm_frames_s16(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
   4658     if (framesRead != pWav->totalPCMFrameCount) {
   4659         drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
   4660         drwav_uninit(pWav);
   4661         return NULL;    /* There was an error reading the samples. */
   4662     }
   4663 
   4664     drwav_uninit(pWav);
   4665 
   4666     if (sampleRate) {
   4667         *sampleRate = pWav->sampleRate;
   4668     }
   4669     if (channels) {
   4670         *channels = pWav->channels;
   4671     }
   4672     if (totalFrameCount) {
   4673         *totalFrameCount = pWav->totalPCMFrameCount;
   4674     }
   4675 
   4676     return pSampleData;
   4677 }
   4678 
   4679 float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
   4680 {
   4681     drwav_uint64 sampleDataSize;
   4682     float* pSampleData;
   4683     drwav_uint64 framesRead;
   4684 
   4685     DRWAV_ASSERT(pWav != NULL);
   4686 
   4687     sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float);
   4688     if (sampleDataSize > DRWAV_SIZE_MAX) {
   4689         drwav_uninit(pWav);
   4690         return NULL;    /* File's too big. */
   4691     }
   4692 
   4693     pSampleData = (float*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
   4694     if (pSampleData == NULL) {
   4695         drwav_uninit(pWav);
   4696         return NULL;    /* Failed to allocate memory. */
   4697     }
   4698 
   4699     framesRead = drwav_read_pcm_frames_f32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
   4700     if (framesRead != pWav->totalPCMFrameCount) {
   4701         drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
   4702         drwav_uninit(pWav);
   4703         return NULL;    /* There was an error reading the samples. */
   4704     }
   4705 
   4706     drwav_uninit(pWav);
   4707 
   4708     if (sampleRate) {
   4709         *sampleRate = pWav->sampleRate;
   4710     }
   4711     if (channels) {
   4712         *channels = pWav->channels;
   4713     }
   4714     if (totalFrameCount) {
   4715         *totalFrameCount = pWav->totalPCMFrameCount;
   4716     }
   4717 
   4718     return pSampleData;
   4719 }
   4720 
   4721 drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
   4722 {
   4723     drwav_uint64 sampleDataSize;
   4724     drwav_int32* pSampleData;
   4725     drwav_uint64 framesRead;
   4726 
   4727     DRWAV_ASSERT(pWav != NULL);
   4728 
   4729     sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
   4730     if (sampleDataSize > DRWAV_SIZE_MAX) {
   4731         drwav_uninit(pWav);
   4732         return NULL;    /* File's too big. */
   4733     }
   4734 
   4735     pSampleData = (drwav_int32*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
   4736     if (pSampleData == NULL) {
   4737         drwav_uninit(pWav);
   4738         return NULL;    /* Failed to allocate memory. */
   4739     }
   4740 
   4741     framesRead = drwav_read_pcm_frames_s32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
   4742     if (framesRead != pWav->totalPCMFrameCount) {
   4743         drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
   4744         drwav_uninit(pWav);
   4745         return NULL;    /* There was an error reading the samples. */
   4746     }
   4747 
   4748     drwav_uninit(pWav);
   4749 
   4750     if (sampleRate) {
   4751         *sampleRate = pWav->sampleRate;
   4752     }
   4753     if (channels) {
   4754         *channels = pWav->channels;
   4755     }
   4756     if (totalFrameCount) {
   4757         *totalFrameCount = pWav->totalPCMFrameCount;
   4758     }
   4759 
   4760     return pSampleData;
   4761 }
   4762 
   4763 
   4764 
   4765 drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4766 {
   4767     drwav wav;
   4768 
   4769     if (channelsOut) {
   4770         *channelsOut = 0;
   4771     }
   4772     if (sampleRateOut) {
   4773         *sampleRateOut = 0;
   4774     }
   4775     if (totalFrameCountOut) {
   4776         *totalFrameCountOut = 0;
   4777     }
   4778 
   4779     if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
   4780         return NULL;
   4781     }
   4782 
   4783     return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4784 }
   4785 
   4786 float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4787 {
   4788     drwav wav;
   4789 
   4790     if (channelsOut) {
   4791         *channelsOut = 0;
   4792     }
   4793     if (sampleRateOut) {
   4794         *sampleRateOut = 0;
   4795     }
   4796     if (totalFrameCountOut) {
   4797         *totalFrameCountOut = 0;
   4798     }
   4799 
   4800     if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
   4801         return NULL;
   4802     }
   4803 
   4804     return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4805 }
   4806 
   4807 drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4808 {
   4809     drwav wav;
   4810 
   4811     if (channelsOut) {
   4812         *channelsOut = 0;
   4813     }
   4814     if (sampleRateOut) {
   4815         *sampleRateOut = 0;
   4816     }
   4817     if (totalFrameCountOut) {
   4818         *totalFrameCountOut = 0;
   4819     }
   4820 
   4821     if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
   4822         return NULL;
   4823     }
   4824 
   4825     return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4826 }
   4827 
   4828 #ifndef DR_WAV_NO_STDIO
   4829 drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4830 {
   4831     drwav wav;
   4832 
   4833     if (channelsOut) {
   4834         *channelsOut = 0;
   4835     }
   4836     if (sampleRateOut) {
   4837         *sampleRateOut = 0;
   4838     }
   4839     if (totalFrameCountOut) {
   4840         *totalFrameCountOut = 0;
   4841     }
   4842 
   4843     if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
   4844         return NULL;
   4845     }
   4846 
   4847     return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4848 }
   4849 
   4850 float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4851 {
   4852     drwav wav;
   4853 
   4854     if (channelsOut) {
   4855         *channelsOut = 0;
   4856     }
   4857     if (sampleRateOut) {
   4858         *sampleRateOut = 0;
   4859     }
   4860     if (totalFrameCountOut) {
   4861         *totalFrameCountOut = 0;
   4862     }
   4863 
   4864     if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
   4865         return NULL;
   4866     }
   4867 
   4868     return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4869 }
   4870 
   4871 drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4872 {
   4873     drwav wav;
   4874 
   4875     if (channelsOut) {
   4876         *channelsOut = 0;
   4877     }
   4878     if (sampleRateOut) {
   4879         *sampleRateOut = 0;
   4880     }
   4881     if (totalFrameCountOut) {
   4882         *totalFrameCountOut = 0;
   4883     }
   4884 
   4885     if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
   4886         return NULL;
   4887     }
   4888 
   4889     return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4890 }
   4891 
   4892 
   4893 drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4894 {
   4895     drwav wav;
   4896 
   4897     if (sampleRateOut) {
   4898         *sampleRateOut = 0;
   4899     }
   4900     if (channelsOut) {
   4901         *channelsOut = 0;
   4902     }
   4903     if (totalFrameCountOut) {
   4904         *totalFrameCountOut = 0;
   4905     }
   4906 
   4907     if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
   4908         return NULL;
   4909     }
   4910 
   4911     return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4912 }
   4913 
   4914 float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4915 {
   4916     drwav wav;
   4917 
   4918     if (sampleRateOut) {
   4919         *sampleRateOut = 0;
   4920     }
   4921     if (channelsOut) {
   4922         *channelsOut = 0;
   4923     }
   4924     if (totalFrameCountOut) {
   4925         *totalFrameCountOut = 0;
   4926     }
   4927 
   4928     if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
   4929         return NULL;
   4930     }
   4931 
   4932     return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4933 }
   4934 
   4935 drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4936 {
   4937     drwav wav;
   4938 
   4939     if (sampleRateOut) {
   4940         *sampleRateOut = 0;
   4941     }
   4942     if (channelsOut) {
   4943         *channelsOut = 0;
   4944     }
   4945     if (totalFrameCountOut) {
   4946         *totalFrameCountOut = 0;
   4947     }
   4948 
   4949     if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
   4950         return NULL;
   4951     }
   4952 
   4953     return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4954 }
   4955 #endif
   4956 
   4957 drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4958 {
   4959     drwav wav;
   4960 
   4961     if (channelsOut) {
   4962         *channelsOut = 0;
   4963     }
   4964     if (sampleRateOut) {
   4965         *sampleRateOut = 0;
   4966     }
   4967     if (totalFrameCountOut) {
   4968         *totalFrameCountOut = 0;
   4969     }
   4970 
   4971     if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
   4972         return NULL;
   4973     }
   4974 
   4975     return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4976 }
   4977 
   4978 float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   4979 {
   4980     drwav wav;
   4981 
   4982     if (channelsOut) {
   4983         *channelsOut = 0;
   4984     }
   4985     if (sampleRateOut) {
   4986         *sampleRateOut = 0;
   4987     }
   4988     if (totalFrameCountOut) {
   4989         *totalFrameCountOut = 0;
   4990     }
   4991 
   4992     if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
   4993         return NULL;
   4994     }
   4995 
   4996     return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   4997 }
   4998 
   4999 drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
   5000 {
   5001     drwav wav;
   5002 
   5003     if (channelsOut) {
   5004         *channelsOut = 0;
   5005     }
   5006     if (sampleRateOut) {
   5007         *sampleRateOut = 0;
   5008     }
   5009     if (totalFrameCountOut) {
   5010         *totalFrameCountOut = 0;
   5011     }
   5012 
   5013     if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
   5014         return NULL;
   5015     }
   5016 
   5017     return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
   5018 }
   5019 #endif  /* DR_WAV_NO_CONVERSION_API */
   5020 
   5021 
   5022 void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
   5023 {
   5024     if (pAllocationCallbacks != NULL) {
   5025         drwav__free_from_callbacks(p, pAllocationCallbacks);
   5026     } else {
   5027         drwav__free_default(p, NULL);
   5028     }
   5029 }
   5030 
   5031 #endif  /* DR_WAV_IMPLEMENTATION */
   5032 
   5033 /*
   5034 REVISION HISTORY
   5035 ================
   5036 v0.11.1 - 2019-10-07
   5037   - Internal code clean up.
   5038 
   5039 v0.11.0 - 2019-10-06
   5040   - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
   5041     routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
   5042     - drwav_init()
   5043     - drwav_init_ex()
   5044     - drwav_init_file()
   5045     - drwav_init_file_ex()
   5046     - drwav_init_file_w()
   5047     - drwav_init_file_w_ex()
   5048     - drwav_init_memory()
   5049     - drwav_init_memory_ex()
   5050     - drwav_init_write()
   5051     - drwav_init_write_sequential()
   5052     - drwav_init_write_sequential_pcm_frames()
   5053     - drwav_init_file_write()
   5054     - drwav_init_file_write_sequential()
   5055     - drwav_init_file_write_sequential_pcm_frames()
   5056     - drwav_init_file_write_w()
   5057     - drwav_init_file_write_sequential_w()
   5058     - drwav_init_file_write_sequential_pcm_frames_w()
   5059     - drwav_init_memory_write()
   5060     - drwav_init_memory_write_sequential()
   5061     - drwav_init_memory_write_sequential_pcm_frames()
   5062     - drwav_open_and_read_pcm_frames_s16()
   5063     - drwav_open_and_read_pcm_frames_f32()
   5064     - drwav_open_and_read_pcm_frames_s32()
   5065     - drwav_open_file_and_read_pcm_frames_s16()
   5066     - drwav_open_file_and_read_pcm_frames_f32()
   5067     - drwav_open_file_and_read_pcm_frames_s32()
   5068     - drwav_open_file_and_read_pcm_frames_s16_w()
   5069     - drwav_open_file_and_read_pcm_frames_f32_w()
   5070     - drwav_open_file_and_read_pcm_frames_s32_w()
   5071     - drwav_open_memory_and_read_pcm_frames_s16()
   5072     - drwav_open_memory_and_read_pcm_frames_f32()
   5073     - drwav_open_memory_and_read_pcm_frames_s32()
   5074     Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
   5075     DRWAV_MALLOC, DRWAV_REALLOC and DRWAV_FREE.
   5076   - Add support for reading and writing PCM frames in an explicit endianness. New APIs:
   5077     - drwav_read_pcm_frames_le()
   5078     - drwav_read_pcm_frames_be()
   5079     - drwav_read_pcm_frames_s16le()
   5080     - drwav_read_pcm_frames_s16be()
   5081     - drwav_read_pcm_frames_f32le()
   5082     - drwav_read_pcm_frames_f32be()
   5083     - drwav_read_pcm_frames_s32le()
   5084     - drwav_read_pcm_frames_s32be()
   5085     - drwav_write_pcm_frames_le()
   5086     - drwav_write_pcm_frames_be()
   5087   - Remove deprecated APIs.
   5088   - API CHANGE: The following APIs now return native-endian data. Previously they returned little-endian data.
   5089     - drwav_read_pcm_frames()
   5090     - drwav_read_pcm_frames_s16()
   5091     - drwav_read_pcm_frames_s32()
   5092     - drwav_read_pcm_frames_f32()
   5093     - drwav_open_and_read_pcm_frames_s16()
   5094     - drwav_open_and_read_pcm_frames_s32()
   5095     - drwav_open_and_read_pcm_frames_f32()
   5096     - drwav_open_file_and_read_pcm_frames_s16()
   5097     - drwav_open_file_and_read_pcm_frames_s32()
   5098     - drwav_open_file_and_read_pcm_frames_f32()
   5099     - drwav_open_file_and_read_pcm_frames_s16_w()
   5100     - drwav_open_file_and_read_pcm_frames_s32_w()
   5101     - drwav_open_file_and_read_pcm_frames_f32_w()
   5102     - drwav_open_memory_and_read_pcm_frames_s16()
   5103     - drwav_open_memory_and_read_pcm_frames_s32()
   5104     - drwav_open_memory_and_read_pcm_frames_f32()
   5105 
   5106 v0.10.1 - 2019-08-31
   5107   - Correctly handle partial trailing ADPCM blocks.
   5108 
   5109 v0.10.0 - 2019-08-04
   5110   - Remove deprecated APIs.
   5111   - Add wchar_t variants for file loading APIs:
   5112       drwav_init_file_w()
   5113       drwav_init_file_ex_w()
   5114       drwav_init_file_write_w()
   5115       drwav_init_file_write_sequential_w()
   5116   - Add drwav_target_write_size_bytes() which calculates the total size in bytes of a WAV file given a format and sample count.
   5117   - Add APIs for specifying the PCM frame count instead of the sample count when opening in sequential write mode:
   5118       drwav_init_write_sequential_pcm_frames()
   5119       drwav_init_file_write_sequential_pcm_frames()
   5120       drwav_init_file_write_sequential_pcm_frames_w()
   5121       drwav_init_memory_write_sequential_pcm_frames()
   5122   - Deprecate drwav_open*() and drwav_close():
   5123       drwav_open()
   5124       drwav_open_ex()
   5125       drwav_open_write()
   5126       drwav_open_write_sequential()
   5127       drwav_open_file()
   5128       drwav_open_file_ex()
   5129       drwav_open_file_write()
   5130       drwav_open_file_write_sequential()
   5131       drwav_open_memory()
   5132       drwav_open_memory_ex()
   5133       drwav_open_memory_write()
   5134       drwav_open_memory_write_sequential()
   5135       drwav_close()
   5136   - Minor documentation updates.
   5137 
   5138 v0.9.2 - 2019-05-21
   5139   - Fix warnings.
   5140 
   5141 v0.9.1 - 2019-05-05
   5142   - Add support for C89.
   5143   - Change license to choice of public domain or MIT-0.
   5144 
   5145 v0.9.0 - 2018-12-16
   5146   - API CHANGE: Add new reading APIs for reading by PCM frames instead of samples. Old APIs have been deprecated and
   5147     will be removed in v0.10.0. Deprecated APIs and their replacements:
   5148       drwav_read()                     -> drwav_read_pcm_frames()
   5149       drwav_read_s16()                 -> drwav_read_pcm_frames_s16()
   5150       drwav_read_f32()                 -> drwav_read_pcm_frames_f32()
   5151       drwav_read_s32()                 -> drwav_read_pcm_frames_s32()
   5152       drwav_seek_to_sample()           -> drwav_seek_to_pcm_frame()
   5153       drwav_write()                    -> drwav_write_pcm_frames()
   5154       drwav_open_and_read_s16()        -> drwav_open_and_read_pcm_frames_s16()
   5155       drwav_open_and_read_f32()        -> drwav_open_and_read_pcm_frames_f32()
   5156       drwav_open_and_read_s32()        -> drwav_open_and_read_pcm_frames_s32()
   5157       drwav_open_file_and_read_s16()   -> drwav_open_file_and_read_pcm_frames_s16()
   5158       drwav_open_file_and_read_f32()   -> drwav_open_file_and_read_pcm_frames_f32()
   5159       drwav_open_file_and_read_s32()   -> drwav_open_file_and_read_pcm_frames_s32()
   5160       drwav_open_memory_and_read_s16() -> drwav_open_memory_and_read_pcm_frames_s16()
   5161       drwav_open_memory_and_read_f32() -> drwav_open_memory_and_read_pcm_frames_f32()
   5162       drwav_open_memory_and_read_s32() -> drwav_open_memory_and_read_pcm_frames_s32()
   5163       drwav::totalSampleCount          -> drwav::totalPCMFrameCount
   5164   - API CHANGE: Rename drwav_open_and_read_file_*() to drwav_open_file_and_read_*().
   5165   - API CHANGE: Rename drwav_open_and_read_memory_*() to drwav_open_memory_and_read_*().
   5166   - Add built-in support for smpl chunks.
   5167   - Add support for firing a callback for each chunk in the file at initialization time.
   5168     - This is enabled through the drwav_init_ex(), etc. family of APIs.
   5169   - Handle invalid FMT chunks more robustly.
   5170 
   5171 v0.8.5 - 2018-09-11
   5172   - Const correctness.
   5173   - Fix a potential stack overflow.
   5174 
   5175 v0.8.4 - 2018-08-07
   5176   - Improve 64-bit detection.
   5177 
   5178 v0.8.3 - 2018-08-05
   5179   - Fix C++ build on older versions of GCC.
   5180 
   5181 v0.8.2 - 2018-08-02
   5182   - Fix some big-endian bugs.
   5183 
   5184 v0.8.1 - 2018-06-29
   5185   - Add support for sequential writing APIs.
   5186   - Disable seeking in write mode.
   5187   - Fix bugs with Wave64.
   5188   - Fix typos.
   5189 
   5190 v0.8 - 2018-04-27
   5191   - Bug fix.
   5192   - Start using major.minor.revision versioning.
   5193 
   5194 v0.7f - 2018-02-05
   5195   - Restrict ADPCM formats to a maximum of 2 channels.
   5196 
   5197 v0.7e - 2018-02-02
   5198   - Fix a crash.
   5199 
   5200 v0.7d - 2018-02-01
   5201   - Fix a crash.
   5202 
   5203 v0.7c - 2018-02-01
   5204   - Set drwav.bytesPerSample to 0 for all compressed formats.
   5205   - Fix a crash when reading 16-bit floating point WAV files. In this case dr_wav will output silence for
   5206     all format conversion reading APIs (*_s16, *_s32, *_f32 APIs).
   5207   - Fix some divide-by-zero errors.
   5208 
   5209 v0.7b - 2018-01-22
   5210   - Fix errors with seeking of compressed formats.
   5211   - Fix compilation error when DR_WAV_NO_CONVERSION_API
   5212 
   5213 v0.7a - 2017-11-17
   5214   - Fix some GCC warnings.
   5215 
   5216 v0.7 - 2017-11-04
   5217   - Add writing APIs.
   5218 
   5219 v0.6 - 2017-08-16
   5220   - API CHANGE: Rename dr_* types to drwav_*.
   5221   - Add support for custom implementations of malloc(), realloc(), etc.
   5222   - Add support for Microsoft ADPCM.
   5223   - Add support for IMA ADPCM (DVI, format code 0x11).
   5224   - Optimizations to drwav_read_s16().
   5225   - Bug fixes.
   5226 
   5227 v0.5g - 2017-07-16
   5228   - Change underlying type for booleans to unsigned.
   5229 
   5230 v0.5f - 2017-04-04
   5231   - Fix a minor bug with drwav_open_and_read_s16() and family.
   5232 
   5233 v0.5e - 2016-12-29
   5234   - Added support for reading samples as signed 16-bit integers. Use the _s16() family of APIs for this.
   5235   - Minor fixes to documentation.
   5236 
   5237 v0.5d - 2016-12-28
   5238   - Use drwav_int* and drwav_uint* sized types to improve compiler support.
   5239 
   5240 v0.5c - 2016-11-11
   5241   - Properly handle JUNK chunks that come before the FMT chunk.
   5242 
   5243 v0.5b - 2016-10-23
   5244   - A minor change to drwav_bool8 and drwav_bool32 types.
   5245 
   5246 v0.5a - 2016-10-11
   5247   - Fixed a bug with drwav_open_and_read() and family due to incorrect argument ordering.
   5248   - Improve A-law and mu-law efficiency.
   5249 
   5250 v0.5 - 2016-09-29
   5251   - API CHANGE. Swap the order of "channels" and "sampleRate" parameters in drwav_open_and_read*(). Rationale for this is to
   5252     keep it consistent with dr_audio and dr_flac.
   5253 
   5254 v0.4b - 2016-09-18
   5255   - Fixed a typo in documentation.
   5256 
   5257 v0.4a - 2016-09-18
   5258   - Fixed a typo.
   5259   - Change date format to ISO 8601 (YYYY-MM-DD)
   5260 
   5261 v0.4 - 2016-07-13
   5262   - API CHANGE. Make onSeek consistent with dr_flac.
   5263   - API CHANGE. Rename drwav_seek() to drwav_seek_to_sample() for clarity and consistency with dr_flac.
   5264   - Added support for Sony Wave64.
   5265 
   5266 v0.3a - 2016-05-28
   5267   - API CHANGE. Return drwav_bool32 instead of int in onSeek callback.
   5268   - Fixed a memory leak.
   5269 
   5270 v0.3 - 2016-05-22
   5271   - Lots of API changes for consistency.
   5272 
   5273 v0.2a - 2016-05-16
   5274   - Fixed Linux/GCC build.
   5275 
   5276 v0.2 - 2016-05-11
   5277   - Added support for reading data as signed 32-bit PCM for consistency with dr_flac.
   5278 
   5279 v0.1a - 2016-05-07
   5280   - Fixed a bug in drwav_open_file() where the file handle would not be closed if the loader failed to initialize.
   5281 
   5282 v0.1 - 2016-05-04
   5283   - Initial versioned release.
   5284 */
   5285 
   5286 /*
   5287 This software is available as a choice of the following licenses. Choose
   5288 whichever you prefer.
   5289 
   5290 ===============================================================================
   5291 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
   5292 ===============================================================================
   5293 This is free and unencumbered software released into the public domain.
   5294 
   5295 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
   5296 software, either in source code form or as a compiled binary, for any purpose,
   5297 commercial or non-commercial, and by any means.
   5298 
   5299 In jurisdictions that recognize copyright laws, the author or authors of this
   5300 software dedicate any and all copyright interest in the software to the public
   5301 domain. We make this dedication for the benefit of the public at large and to
   5302 the detriment of our heirs and successors. We intend this dedication to be an
   5303 overt act of relinquishment in perpetuity of all present and future rights to
   5304 this software under copyright law.
   5305 
   5306 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   5307 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   5308 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   5309 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   5310 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   5311 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   5312 
   5313 For more information, please refer to <http://unlicense.org/>
   5314 
   5315 ===============================================================================
   5316 ALTERNATIVE 2 - MIT No Attribution
   5317 ===============================================================================
   5318 Copyright 2018 David Reid
   5319 
   5320 Permission is hereby granted, free of charge, to any person obtaining a copy of
   5321 this software and associated documentation files (the "Software"), to deal in
   5322 the Software without restriction, including without limitation the rights to
   5323 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   5324 of the Software, and to permit persons to whom the Software is furnished to do
   5325 so.
   5326 
   5327 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   5328 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   5329 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   5330 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   5331 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   5332 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   5333 SOFTWARE.
   5334 */