diff --git a/examples/dr_wav.h b/examples/dr_wav.h index b24abddd..386e2f03 100644 --- a/examples/dr_wav.h +++ b/examples/dr_wav.h @@ -1,5 +1,5 @@ // WAV audio loader. Public domain. See "unlicense" statement at the end of this file. -// dr_wav - v0.5a - 2016-10-11 +// dr_wav - v0.5e - 2016-12-29 // // David Reid - mackron@gmail.com @@ -17,7 +17,7 @@ // // Error opening WAV file. // } // -// int32_t* pDecodedInterleavedSamples = malloc(wav.totalSampleCount * sizeof(int32_t)); +// dr_int32* pDecodedInterleavedSamples = malloc(wav.totalSampleCount * sizeof(dr_int32)); // size_t numberOfSamplesActuallyDecoded = drwav_read_s32(&wav, wav.totalSampleCount, pDecodedInterleavedSamples); // // ... @@ -39,7 +39,7 @@ // // unsigned int channels; // unsigned int sampleRate; -// uint64_t totalSampleCount; +// dr_uint64 totalSampleCount; // float* pSampleData = drwav_open_and_read_file_s32("my_song.wav", &channels, &sampleRate, &totalSampleCount); // if (pSampleData == NULL) { // // Error opening and reading WAV file. @@ -96,7 +96,6 @@ #ifndef dr_wav_h #define dr_wav_h -#include #include #ifndef DR_SIZED_TYPES_DEFINED @@ -121,8 +120,8 @@ typedef uint32_t dr_uint32; typedef int64_t dr_int64; typedef uint64_t dr_uint64; #endif -typedef int8_t dr_bool8; -typedef int32_t dr_bool32; +typedef dr_int8 dr_bool8; +typedef dr_int32 dr_bool32; #define DR_TRUE 1 #define DR_FALSE 0 #endif @@ -154,8 +153,7 @@ typedef enum // Callback for when data is read. Return value is the number of bytes actually read. typedef size_t (* drwav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); -// Callback for when data needs to be seeked. Offset is always relative to the current position. Return value -// is DR_TRUE on success; fale on failure. +// Callback for when data needs to be seeked. Return value is true on success; false on failure. typedef dr_bool32 (* drwav_seek_proc)(void* pUserData, int offset, drwav_seek_origin origin); // Structure for internal use. Only used for loaders opened with drwav_open_memory. @@ -200,7 +198,6 @@ typedef struct // The sub-format, exactly as specified by the wave file. unsigned char subFormat[16]; - } drwav_fmt; typedef struct @@ -239,34 +236,36 @@ typedef struct // The total number of samples making up the audio data. Use * to calculate // the required size of a buffer to hold the entire audio data. - uint64_t totalSampleCount; + dr_uint64 totalSampleCount; // The number of bytes remaining in the data chunk. - uint64_t bytesRemaining; + dr_uint64 bytesRemaining; // A hack to avoid a malloc() when opening a decoder with drwav_open_memory(). drwav__memory_stream memoryStream; - } drwav; // Initializes a pre-allocated drwav object. // -// +// Returns true if successful; false otherwise. dr_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData); // Uninitializes the given drwav object. Use this only for objects initialized with drwav_init(). void drwav_uninit(drwav* pWav); -// Opens a .wav file using the given callbacks. +// Opens a wav file using the given callbacks. // // Returns null on error. Close the loader with drwav_close(). +// +// This is different from drwav_init() in that it will allocate the drwav object for you via malloc() before +// initializing it. drwav* drwav_open(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData); -// Closes the given drwav object. Use this only for objects created with drwav_open(). +// Uninitializes and deletes the the given drwav object. Use this only for objects created with drwav_open(). void drwav_close(drwav* pWav); @@ -288,45 +287,53 @@ size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut); // // This function will only work when sample data is of a fixed size. If you are using an unusual // format which uses variable sized samples, consider using drwav_read_raw(), but don't combine them. -uint64_t drwav_read(drwav* pWav, uint64_t samplesToRead, void* pBufferOut); +dr_uint64 drwav_read(drwav* pWav, dr_uint64 samplesToRead, void* pBufferOut); // Seeks to the given sample. // // The return value is DR_FALSE if an error occurs, DR_TRUE if successful. -dr_bool32 drwav_seek_to_sample(drwav* pWav, uint64_t sample); +dr_bool32 drwav_seek_to_sample(drwav* pWav, dr_uint64 sample); //// Convertion Utilities //// #ifndef DR_WAV_NO_CONVERSION_API +// Reads a chunk of audio data and converts it to signed 16-bit PCM samples. +// +// Returns the number of samples actually read. +// +// If the return value is less than it means the end of the file has been reached. +dr_uint64 drwav_read_s16(drwav* pWav, dr_uint64 samplesToRead, dr_int16* pBufferOut); + + // Reads a chunk of audio data and converts it to IEEE 32-bit floating point samples. // // Returns the number of samples actually read. // // If the return value is less than it means the end of the file has been reached. -uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut); +dr_uint64 drwav_read_f32(drwav* pWav, dr_uint64 samplesToRead, float* pBufferOut); // Low-level function for converting unsigned 8-bit PCM samples to IEEE 32-bit floating point samples. -void drwav_u8_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_u8_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting signed 16-bit PCM samples to IEEE 32-bit floating point samples. -void drwav_s16_to_f32(float* pOut, const int16_t* pIn, size_t sampleCount); +void drwav_s16_to_f32(float* pOut, const dr_int16* pIn, size_t sampleCount); // Low-level function for converting signed 24-bit PCM samples to IEEE 32-bit floating point samples. -void drwav_s24_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_s24_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting signed 32-bit PCM samples to IEEE 32-bit floating point samples. -void drwav_s32_to_f32(float* pOut, const int32_t* pIn, size_t sampleCount); +void drwav_s32_to_f32(float* pOut, const dr_int32* pIn, size_t sampleCount); // Low-level function for converting IEEE 64-bit floating point samples to IEEE 32-bit floating point samples. void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount); // Low-level function for converting A-law samples to IEEE 32-bit floating point samples. -void drwav_alaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_alaw_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting u-law samples to IEEE 32-bit floating point samples. -void drwav_ulaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_ulaw_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount); // Reads a chunk of audio data and converts it to signed 32-bit PCM samples. @@ -334,28 +341,28 @@ void drwav_ulaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount); // Returns the number of samples actually read. // // If the return value is less than it means the end of the file has been reached. -uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut); +dr_uint64 drwav_read_s32(drwav* pWav, dr_uint64 samplesToRead, dr_int32* pBufferOut); // Low-level function for converting unsigned 8-bit PCM samples to signed 32-bit PCM samples. -void drwav_u8_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_u8_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting signed 16-bit PCM samples to signed 32-bit PCM samples. -void drwav_s16_to_s32(int32_t* pOut, const int16_t* pIn, size_t sampleCount); +void drwav_s16_to_s32(dr_int32* pOut, const dr_int16* pIn, size_t sampleCount); // Low-level function for converting signed 24-bit PCM samples to signed 32-bit PCM samples. -void drwav_s24_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_s24_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting IEEE 32-bit floating point samples to signed 32-bit PCM samples. -void drwav_f32_to_s32(int32_t* pOut, const float* pIn, size_t sampleCount); +void drwav_f32_to_s32(dr_int32* pOut, const float* pIn, size_t sampleCount); // Low-level function for converting IEEE 64-bit floating point samples to signed 32-bit PCM samples. -void drwav_f64_to_s32(int32_t* pOut, const double* pIn, size_t sampleCount); +void drwav_f64_to_s32(dr_int32* pOut, const double* pIn, size_t sampleCount); // Low-level function for converting A-law samples to signed 32-bit PCM samples. -void drwav_alaw_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_alaw_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount); // Low-level function for converting u-law samples to signed 32-bit PCM samples. -void drwav_ulaw_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount); +void drwav_ulaw_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount); #endif //DR_WAV_NO_CONVERSION_API @@ -400,17 +407,20 @@ drwav* drwav_open_memory(const void* data, size_t dataSize); #ifndef DR_WAV_NO_CONVERSION_API // Opens and reads a wav file in a single operation. -float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); -int32_t* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +dr_int16* drwav_open_and_read_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +dr_int32* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); #ifndef DR_WAV_NO_STDIO // Opens an decodes a wav file in a single operation. -float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); -int32_t* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +dr_int16* drwav_open_and_read_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +dr_int32* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); #endif // Opens an decodes a wav file from a block of memory in a single operation. -float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); -int32_t* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +dr_int16* drwav_open_and_read_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); +dr_int32* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount); #endif // Frees data that was allocated internally by dr_wav. @@ -438,15 +448,16 @@ void drwav_free(void* pDataReturnedByOpenAndRead); #include #endif -static const uint8_t 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 -static const uint8_t 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 -static const uint8_t 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 -static const uint8_t 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 +static const dr_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 +static const dr_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 +static const dr_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 +static const dr_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 +static const dr_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 -static dr_bool32 drwav__guid_equal(const uint8_t a[16], const uint8_t b[16]) +static dr_bool32 drwav__guid_equal(const dr_uint8 a[16], const dr_uint8 b[16]) { - const uint32_t* a32 = (const uint32_t*)a; - const uint32_t* b32 = (const uint32_t*)b; + const dr_uint32* a32 = (const dr_uint32*)a; + const dr_uint32* b32 = (const dr_uint32*)b; return a32[0] == b32[0] && @@ -491,20 +502,20 @@ static unsigned int drwav__bytes_to_u32(const unsigned char* data) } } -static uint64_t drwav__bytes_to_u64(const unsigned char* data) +static dr_uint64 drwav__bytes_to_u64(const unsigned char* data) { if (drwav__is_little_endian()) { return - ((uint64_t)data[0] << 0ULL) | ((uint64_t)data[1] << 8ULL) | ((uint64_t)data[2] << 16ULL) | ((uint64_t)data[3] << 24ULL) | - ((uint64_t)data[4] << 32ULL) | ((uint64_t)data[5] << 40ULL) | ((uint64_t)data[6] << 48ULL) | ((uint64_t)data[7] << 56ULL); + ((dr_uint64)data[0] << 0ULL) | ((dr_uint64)data[1] << 8ULL) | ((dr_uint64)data[2] << 16ULL) | ((dr_uint64)data[3] << 24ULL) | + ((dr_uint64)data[4] << 32ULL) | ((dr_uint64)data[5] << 40ULL) | ((dr_uint64)data[6] << 48ULL) | ((dr_uint64)data[7] << 56ULL); } else { return - ((uint64_t)data[7] << 0ULL) | ((uint64_t)data[6] << 8ULL) | ((uint64_t)data[5] << 16ULL) | ((uint64_t)data[4] << 24ULL) | - ((uint64_t)data[3] << 32ULL) | ((uint64_t)data[2] << 40ULL) | ((uint64_t)data[1] << 48ULL) | ((uint64_t)data[0] << 56ULL); + ((dr_uint64)data[7] << 0ULL) | ((dr_uint64)data[6] << 8ULL) | ((dr_uint64)data[5] << 16ULL) | ((dr_uint64)data[4] << 24ULL) | + ((dr_uint64)data[3] << 32ULL) | ((dr_uint64)data[2] << 40ULL) | ((dr_uint64)data[1] << 48ULL) | ((dr_uint64)data[0] << 56ULL); } } -static void drwav__bytes_to_guid(const unsigned char* data, uint8_t* guid) +static void drwav__bytes_to_guid(const unsigned char* data, dr_uint8* guid) { for (int i = 0; i < 16; ++i) { guid[i] = data[i]; @@ -516,12 +527,12 @@ typedef struct { union { - uint8_t fourcc[4]; - uint8_t guid[16]; + dr_uint8 fourcc[4]; + dr_uint8 guid[16]; } id; // The size in bytes of the chunk. - uint64_t sizeInBytes; + dr_uint64 sizeInBytes; // RIFF = 2 byte alignment. // W64 = 8 byte alignment. @@ -560,6 +571,26 @@ static dr_bool32 drwav__read_chunk_header(drwav_read_proc onRead, void* pUserDat return DR_TRUE; } +static dr_bool32 drwav__seek_forward(drwav_seek_proc onSeek, dr_uint64 offset, void* pUserData) +{ + dr_uint64 bytesRemainingToSeek = offset; + while (bytesRemainingToSeek > 0) { + if (bytesRemainingToSeek > 0x7FFFFFFF) { + if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) { + return DR_FALSE; + } + bytesRemainingToSeek -= 0x7FFFFFFF; + } else { + if (!onSeek(pUserData, (int)bytesRemainingToSeek, drwav_seek_origin_current)) { + return DR_FALSE; + } + bytesRemainingToSeek = 0; + } + } + + return DR_TRUE; +} + static dr_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_fmt* fmtOut) { @@ -568,6 +599,17 @@ static dr_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, return DR_FALSE; } + + // Skip junk chunks. + if ((container == drwav_container_riff && drwav__fourcc_equal(header.id.fourcc, "JUNK")) || (container == drwav_container_w64 && drwav__guid_equal(header.id.guid, drwavGUID_W64_JUNK))) { + if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) { + return DR_FALSE; + } + + return drwav__read_fmt(onRead, onSeek, pUserData, container, fmtOut); + } + + // Validation. if (container == drwav_container_riff) { if (!drwav__fourcc_equal(header.id.fourcc, "fmt ")) { @@ -727,7 +769,7 @@ static dr_bool32 drwav__on_seek_memory(void* pUserData, int offset, drwav_seek_o } } } else { - if ((uint32_t)offset <= memory->dataSize) { + if ((dr_uint32)offset <= memory->dataSize) { memory->currentReadPos = offset; } else { memory->currentReadPos = memory->dataSize; // Trying to seek too far forward. @@ -794,7 +836,7 @@ dr_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek pWav->container = drwav_container_w64; // Check the rest of the GUID for validity. - uint8_t riff2[12]; + dr_uint8 riff2[12]; if (onRead(pUserData, riff2, sizeof(riff2)) != sizeof(riff2)) { return DR_FALSE; } @@ -840,7 +882,7 @@ dr_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek return DR_FALSE; } - uint8_t wave[16]; + dr_uint8 wave[16]; if (onRead(pUserData, wave, sizeof(wave)) != sizeof(wave)) { return DR_FALSE; } @@ -866,7 +908,7 @@ dr_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek // The next chunk we care about is the "data" chunk. This is not necessarily the next chunk so we'll need to loop. - uint64_t dataSize; + dr_uint64 dataSize; for (;;) { drwav__chunk_header header; @@ -889,21 +931,7 @@ dr_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek // Make sure we seek past the padding. dataSize += header.paddingSize; - - uint64_t bytesRemainingToSeek = dataSize; - while (bytesRemainingToSeek > 0) { - if (bytesRemainingToSeek > 0x7FFFFFFF) { - if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) { - return DR_FALSE; - } - bytesRemainingToSeek -= 0x7FFFFFFF; - } else { - if (!onSeek(pUserData, (int)bytesRemainingToSeek, drwav_seek_origin_current)) { - return DR_FALSE; - } - bytesRemainingToSeek = 0; - } - } + drwav__seek_forward(onSeek, dataSize, pUserData); } // At this point we should be sitting on the first byte of the raw audio data. @@ -977,7 +1005,7 @@ size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut) return bytesRead; } -uint64_t drwav_read(drwav* pWav, uint64_t samplesToRead, void* pBufferOut) +dr_uint64 drwav_read(drwav* pWav, dr_uint64 samplesToRead, void* pBufferOut) { if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) { return 0; @@ -992,7 +1020,7 @@ uint64_t drwav_read(drwav* pWav, uint64_t samplesToRead, void* pBufferOut) return bytesRead / pWav->bytesPerSample; } -dr_bool32 drwav_seek_to_sample(drwav* pWav, uint64_t sample) +dr_bool32 drwav_seek_to_sample(drwav* pWav, dr_uint64 sample) { // Seeking should be compatible with wave files > 2GB. @@ -1011,13 +1039,13 @@ dr_bool32 drwav_seek_to_sample(drwav* pWav, uint64_t sample) } - uint64_t totalSizeInBytes = pWav->totalSampleCount * pWav->bytesPerSample; + dr_uint64 totalSizeInBytes = pWav->totalSampleCount * pWav->bytesPerSample; assert(totalSizeInBytes >= pWav->bytesRemaining); - uint64_t currentBytePos = totalSizeInBytes - pWav->bytesRemaining; - uint64_t targetBytePos = sample * pWav->bytesPerSample; + dr_uint64 currentBytePos = totalSizeInBytes - pWav->bytesRemaining; + dr_uint64 targetBytePos = sample * pWav->bytesPerSample; - uint64_t offset; + dr_uint64 offset; int direction; if (currentBytePos < targetBytePos) { // Offset forward. @@ -1083,6 +1111,33 @@ static unsigned short g_drwavMulawTable[256] = { 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040, 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000 }; + +dr_uint64 drwav_read_s16(drwav* pWav, dr_uint64 samplesToRead, dr_int16* pBufferOut) +{ + // TODO: Optimize me. This is a temporary implementation for the moment. + dr_uint64 totalSamplesRead = 0; + + while (samplesToRead > 0) { + dr_int32 samples32[4096]; + dr_uint64 samplesJustRead = drwav_read_s32(pWav, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) { + break; // Reached the end. + } + + // s32 -> s16 + for (dr_uint64 i = 0; i < samplesJustRead; ++i) { + pBufferOut[i] = (dr_int16)(samples32[i] >> 16); + } + + totalSamplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + + return totalSamplesRead; +} + + static int drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t sampleCount, unsigned short bytesPerSample) { if (pOut == NULL || pIn == NULL) { @@ -1098,7 +1153,7 @@ static int drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t sampl // Slightly more optimal implementation for common formats. if (bytesPerSample == 2) { - drwav_s16_to_f32(pOut, (const int16_t*)pIn, sampleCount); + drwav_s16_to_f32(pOut, (const dr_int16*)pIn, sampleCount); return 1; } if (bytesPerSample == 3) { @@ -1106,7 +1161,7 @@ static int drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t sampl return 1; } if (bytesPerSample == 4) { - drwav_s32_to_f32(pOut, (const int32_t*)pIn, sampleCount); + drwav_s32_to_f32(pOut, (const dr_int32*)pIn, sampleCount); return 1; } @@ -1146,7 +1201,7 @@ static int drwav__ieee_to_f32(float* pOut, const unsigned char* pIn, size_t samp } -uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) +dr_uint64 drwav_read_f32(drwav* pWav, dr_uint64 samplesToRead, float* pBufferOut) { if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) { return 0; @@ -1165,14 +1220,14 @@ uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) // Slow path. Need to read and convert. - uint64_t totalSamplesRead = 0; + dr_uint64 totalSamplesRead = 0; if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) { unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1192,7 +1247,7 @@ uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1212,7 +1267,7 @@ uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1232,7 +1287,7 @@ uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1250,7 +1305,7 @@ uint64_t drwav_read_f32(drwav* pWav, uint64_t samplesToRead, float* pBufferOut) return totalSamplesRead; } -void drwav_u8_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_u8_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1261,7 +1316,7 @@ void drwav_u8_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) } } -void drwav_s16_to_f32(float* pOut, const int16_t* pIn, size_t sampleCount) +void drwav_s16_to_f32(float* pOut, const dr_int16* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1272,7 +1327,7 @@ void drwav_s16_to_f32(float* pOut, const int16_t* pIn, size_t sampleCount) } } -void drwav_s24_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_s24_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1288,7 +1343,7 @@ void drwav_s24_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) } } -void drwav_s32_to_f32(float* pOut, const int32_t* pIn, size_t sampleCount) +void drwav_s32_to_f32(float* pOut, const dr_int32* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1310,7 +1365,7 @@ void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount) } } -void drwav_alaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_alaw_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1321,7 +1376,7 @@ void drwav_alaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) } } -void drwav_ulaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_ulaw_to_f32(float* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1334,7 +1389,7 @@ void drwav_ulaw_to_f32(float* pOut, const uint8_t* pIn, size_t sampleCount) -static int drwav__pcm_to_s32(int32_t* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample) +static int drwav__pcm_to_s32(dr_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample) { if (pOut == NULL || pIn == NULL) { return 0; @@ -1349,7 +1404,7 @@ static int drwav__pcm_to_s32(int32_t* pOut, const unsigned char* pIn, size_t tot // Slightly more optimal implementation for common formats. if (bytesPerSample == 2) { - drwav_s16_to_s32(pOut, (const int16_t*)pIn, totalSampleCount); + drwav_s16_to_s32(pOut, (const dr_int16*)pIn, totalSampleCount); return 1; } if (bytesPerSample == 3) { @@ -1358,7 +1413,7 @@ static int drwav__pcm_to_s32(int32_t* pOut, const unsigned char* pIn, size_t tot } if (bytesPerSample == 4) { for (unsigned int i = 0; i < totalSampleCount; ++i) { - *pOut++ = ((int32_t*)pIn)[i]; + *pOut++ = ((dr_int32*)pIn)[i]; } return 1; } @@ -1381,7 +1436,7 @@ static int drwav__pcm_to_s32(int32_t* pOut, const unsigned char* pIn, size_t tot return 1; } -static int drwav__ieee_to_s32(int32_t* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample) +static int drwav__ieee_to_s32(dr_int32* pOut, const unsigned char* pIn, size_t totalSampleCount, unsigned short bytesPerSample) { if (pOut == NULL || pIn == NULL) { return 0; @@ -1396,7 +1451,7 @@ static int drwav__ieee_to_s32(int32_t* pOut, const unsigned char* pIn, size_t to } } -uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut) +dr_uint64 drwav_read_s32(drwav* pWav, dr_uint64 samplesToRead, dr_int32* pBufferOut) { if (pWav == NULL || samplesToRead == 0 || pBufferOut == NULL) { return 0; @@ -1409,20 +1464,20 @@ uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut // Don't try to read more samples than can potentially fit in the output buffer. - if (samplesToRead * sizeof(int32_t) > SIZE_MAX) { - samplesToRead = SIZE_MAX / sizeof(int32_t); + if (samplesToRead * sizeof(dr_int32) > SIZE_MAX) { + samplesToRead = SIZE_MAX / sizeof(dr_int32); } // Slow path. Need to read and convert. - uint64_t totalSamplesRead = 0; + dr_uint64 totalSamplesRead = 0; if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) { unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1442,7 +1497,7 @@ uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1462,7 +1517,7 @@ uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1482,7 +1537,7 @@ uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut unsigned char sampleData[4096]; while (samplesToRead > 0) { - uint64_t samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); + dr_uint64 samplesRead = drwav_read(pWav, drwav_min(samplesToRead, sizeof(sampleData)/pWav->bytesPerSample), sampleData); if (samplesRead == 0) { break; } @@ -1500,7 +1555,7 @@ uint64_t drwav_read_s32(drwav* pWav, uint64_t samplesToRead, int32_t* pBufferOut return totalSamplesRead; } -void drwav_u8_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_u8_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1511,7 +1566,7 @@ void drwav_u8_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) } } -void drwav_s16_to_s32(int32_t* pOut, const int16_t* pIn, size_t sampleCount) +void drwav_s16_to_s32(dr_int32* pOut, const dr_int16* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1522,7 +1577,7 @@ void drwav_s16_to_s32(int32_t* pOut, const int16_t* pIn, size_t sampleCount) } } -void drwav_s24_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_s24_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; @@ -1533,63 +1588,93 @@ void drwav_s24_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) unsigned int s1 = pIn[i*3 + 1]; unsigned int s2 = pIn[i*3 + 2]; - int32_t sample32 = (int32_t)((s0 << 8) | (s1 << 16) | (s2 << 24)); + dr_int32 sample32 = (dr_int32)((s0 << 8) | (s1 << 16) | (s2 << 24)); *pOut++ = sample32; } } -void drwav_f32_to_s32(int32_t* pOut, const float* pIn, size_t sampleCount) +void drwav_f32_to_s32(dr_int32* pOut, const float* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; } for (size_t i = 0; i < sampleCount; ++i) { - *pOut++ = (int32_t)(2147483648.0 * pIn[i]); + *pOut++ = (dr_int32)(2147483648.0 * pIn[i]); } } -void drwav_f64_to_s32(int32_t* pOut, const double* pIn, size_t sampleCount) +void drwav_f64_to_s32(dr_int32* pOut, const double* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; } for (size_t i = 0; i < sampleCount; ++i) { - *pOut++ = (int32_t)(2147483648.0 * pIn[i]); + *pOut++ = (dr_int32)(2147483648.0 * pIn[i]); } } -void drwav_alaw_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_alaw_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; } for (size_t i = 0; i < sampleCount; ++i) { - *pOut++ = ((int32_t)g_drwavAlawTable[pIn[i]]) << 16; + *pOut++ = ((dr_int32)g_drwavAlawTable[pIn[i]]) << 16; } } -void drwav_ulaw_to_s32(int32_t* pOut, const uint8_t* pIn, size_t sampleCount) +void drwav_ulaw_to_s32(dr_int32* pOut, const dr_uint8* pIn, size_t sampleCount) { if (pOut == NULL || pIn == NULL) { return; } for (size_t i= 0; i < sampleCount; ++i) { - *pOut++ = ((int32_t)g_drwavMulawTable[pIn[i]]) << 16; + *pOut++ = ((dr_int32)g_drwavMulawTable[pIn[i]]) << 16; } } - -float* drwav__read_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int16* drwav__read_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { assert(pWav != NULL); - uint64_t sampleDataSize = pWav->totalSampleCount * sizeof(float); + dr_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(float); + if (sampleDataSize > SIZE_MAX) { + drwav_uninit(pWav); + return NULL; // File's too big. + } + + dr_int16* pSampleData = (dr_int16*)malloc((size_t)(pWav->totalSampleCount * sizeof(dr_int16))); // <-- Safe cast due to the check above. + if (pSampleData == NULL) { + drwav_uninit(pWav); + return NULL; // Failed to allocate memory. + } + + dr_uint64 samplesRead = drwav_read_s16(pWav, (size_t)pWav->totalSampleCount, pSampleData); + if (samplesRead != pWav->totalSampleCount) { + free(pSampleData); + drwav_uninit(pWav); + return NULL; // There was an error reading the samples. + } + + drwav_uninit(pWav); + + if (sampleRate) *sampleRate = pWav->sampleRate; + if (channels) *channels = pWav->channels; + if (totalSampleCount) *totalSampleCount = pWav->totalSampleCount; + return pSampleData; +} + +float* drwav__read_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) +{ + assert(pWav != NULL); + + dr_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(float); if (sampleDataSize > SIZE_MAX) { drwav_uninit(pWav); return NULL; // File's too big. @@ -1601,7 +1686,7 @@ float* drwav__read_and_close_f32(drwav* pWav, unsigned int* channels, unsigned i return NULL; // Failed to allocate memory. } - uint64_t samplesRead = drwav_read_f32(pWav, (size_t)pWav->totalSampleCount, pSampleData); + dr_uint64 samplesRead = drwav_read_f32(pWav, (size_t)pWav->totalSampleCount, pSampleData); if (samplesRead != pWav->totalSampleCount) { free(pSampleData); drwav_uninit(pWav); @@ -1616,23 +1701,23 @@ float* drwav__read_and_close_f32(drwav* pWav, unsigned int* channels, unsigned i return pSampleData; } -int32_t* drwav__read_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int32* drwav__read_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { assert(pWav != NULL); - uint64_t sampleDataSize = pWav->totalSampleCount * sizeof(int32_t); + dr_uint64 sampleDataSize = pWav->totalSampleCount * sizeof(dr_int32); if (sampleDataSize > SIZE_MAX) { drwav_uninit(pWav); return NULL; // File's too big. } - int32_t* pSampleData = (int32_t*)malloc((size_t)(pWav->totalSampleCount * sizeof(int32_t))); // <-- Safe cast due to the check above. + dr_int32* pSampleData = (dr_int32*)malloc((size_t)(pWav->totalSampleCount * sizeof(dr_int32))); // <-- Safe cast due to the check above. if (pSampleData == NULL) { drwav_uninit(pWav); return NULL; // Failed to allocate memory. } - uint64_t samplesRead = drwav_read_s32(pWav, (size_t)pWav->totalSampleCount, pSampleData); + dr_uint64 samplesRead = drwav_read_s32(pWav, (size_t)pWav->totalSampleCount, pSampleData); if (samplesRead != pWav->totalSampleCount) { free(pSampleData); drwav_uninit(pWav); @@ -1648,8 +1733,21 @@ int32_t* drwav__read_and_close_s32(drwav* pWav, unsigned int* channels, unsigned } +dr_int16* drwav_open_and_read_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; -float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) + drwav wav; + if (!drwav_init(&wav, onRead, onSeek, pUserData)) { + return NULL; + } + + return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount); +} + +float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1663,7 +1761,7 @@ float* drwav_open_and_read_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, v return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount); } -int32_t* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int32* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1678,7 +1776,21 @@ int32_t* drwav_open_and_read_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, } #ifndef DR_WAV_NO_STDIO -float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int16* drwav_open_and_read_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drwav wav; + if (!drwav_init_file(&wav, filename)) { + return NULL; + } + + return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount); +} + +float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1692,7 +1804,7 @@ float* drwav_open_and_read_file_f32(const char* filename, unsigned int* channels return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount); } -int32_t* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int32* drwav_open_and_read_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1707,7 +1819,21 @@ int32_t* drwav_open_and_read_file_s32(const char* filename, unsigned int* channe } #endif -float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int16* drwav_open_and_read_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drwav wav; + if (!drwav_init_memory(&wav, data, dataSize)) { + return NULL; + } + + return drwav__read_and_close_s16(&wav, channels, sampleRate, totalSampleCount); +} + +float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1721,7 +1847,7 @@ float* drwav_open_and_read_memory_f32(const void* data, size_t dataSize, unsigne return drwav__read_and_close_f32(&wav, channels, sampleRate, totalSampleCount); } -int32_t* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +dr_int32* drwav_open_and_read_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, dr_uint64* totalSampleCount) { if (sampleRate) *sampleRate = 0; if (channels) *channels = 0; @@ -1747,6 +1873,19 @@ void drwav_free(void* pDataReturnedByOpenAndRead) // REVISION HISTORY // +// v0.5e - 2016-12-29 +// - Added support for reading samples as signed 16-bit integers. Use the _s16() family of APIs for this. +// - Minor fixes to documentation. +// +// v0.5d - 2016-12-28 +// - Use dr_int*/dr_uint* sized types to improve compiler support. +// +// v0.5c - 2016-11-11 +// - Properly handle JUNK chunks that come before the FMT chunk. +// +// v0.5b - 2016-10-23 +// - A minor change to dr_bool8 and dr_bool32 types. +// // v0.5a - 2016-10-11 // - Fixed a bug with drwav_open_and_read() and family due to incorrect argument ordering. // - Improve A-law and mu-law efficiency. diff --git a/examples/simple_capture.c b/examples/simple_capture.c index 3ba17c41..44017473 100644 --- a/examples/simple_capture.c +++ b/examples/simple_capture.c @@ -9,7 +9,7 @@ mal_uint32 capturedSampleCount = 0; -float* pCapturedSamples = NULL; +mal_int16* pCapturedSamples = NULL; mal_uint32 playbackSample = 0; void on_recv_frames(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples) @@ -17,12 +17,12 @@ void on_recv_frames(mal_device* pDevice, mal_uint32 frameCount, const void* pSam mal_uint32 sampleCount = frameCount * pDevice->channels; mal_uint32 newCapturedSampleCount = capturedSampleCount + sampleCount; - float* pNewCapturedSamples = (float*)realloc(pCapturedSamples, newCapturedSampleCount * sizeof(float)); + mal_int16* pNewCapturedSamples = (mal_int16*)realloc(pCapturedSamples, newCapturedSampleCount * sizeof(mal_int16)); if (pNewCapturedSamples == NULL) { return; } - memcpy(pNewCapturedSamples + capturedSampleCount, pSamples, sampleCount * sizeof(float)); + memcpy(pNewCapturedSamples + capturedSampleCount, pSamples, sampleCount * sizeof(mal_int16)); pCapturedSamples = pNewCapturedSamples; capturedSampleCount = newCapturedSampleCount; @@ -39,7 +39,7 @@ mal_uint32 on_send_frames(mal_device* pDevice, mal_uint32 frameCount, void* pSam return 0; } - memcpy(pSamples, pCapturedSamples + playbackSample, samplesToRead * sizeof(float)); + memcpy(pSamples, pCapturedSamples + playbackSample, samplesToRead * sizeof(mal_int16)); playbackSample += samplesToRead; return samplesToRead / pDevice->channels; @@ -54,7 +54,7 @@ int main() } mal_device_config config; - config.format = mal_format_f32; + config.format = mal_format_s16; config.channels = 2; config.sampleRate = 48000; config.bufferSizeInFrames = 0; // Use default. diff --git a/examples/simple_playback.c b/examples/simple_playback.c index 46a6fc51..b0df49b9 100644 --- a/examples/simple_playback.c +++ b/examples/simple_playback.c @@ -14,7 +14,7 @@ mal_uint32 on_send_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, return 0; } - return (mal_uint32)drwav_read_f32(pWav, frameCount * pDevice->channels, (float*)pSamples) / pDevice->channels; + return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels; } int main(int argc, char** argv) @@ -38,7 +38,7 @@ int main(int argc, char** argv) // In this example we use the default playback device with a default buffer size and period count. mal_device_config config; - config.format = mal_format_f32; + config.format = mal_format_s16; config.channels = wav.channels; config.sampleRate = wav.sampleRate; config.bufferSizeInFrames = 0; // Use default.