mirror of
https://github.com/raysan5/raylib.git
synced 2025-09-06 03:18:14 +00:00
update dr_libs
This commit is contained in:
462
src/external/dr_flac.h
vendored
462
src/external/dr_flac.h
vendored
@@ -1,121 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
|
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||||
dr_flac - v0.12.42 - 2023-11-02
|
dr_flac - v0.13.0 - TBD
|
||||||
|
|
||||||
David Reid - mackron@gmail.com
|
David Reid - mackron@gmail.com
|
||||||
|
|
||||||
GitHub: https://github.com/mackron/dr_libs
|
GitHub: https://github.com/mackron/dr_libs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
RELEASE NOTES - v0.12.0
|
|
||||||
=======================
|
|
||||||
Version 0.12.0 has breaking API changes including changes to the existing API and the removal of deprecated APIs.
|
|
||||||
|
|
||||||
|
|
||||||
Improved Client-Defined Memory Allocation
|
|
||||||
-----------------------------------------
|
|
||||||
The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
|
|
||||||
existing system of DRFLAC_MALLOC, DRFLAC_REALLOC and DRFLAC_FREE are still in place and will be used by default when no custom
|
|
||||||
allocation callbacks are specified.
|
|
||||||
|
|
||||||
To use the new system, you pass in a pointer to a drflac_allocation_callbacks object to drflac_open() and family, like this:
|
|
||||||
|
|
||||||
void* my_malloc(size_t sz, void* pUserData)
|
|
||||||
{
|
|
||||||
return malloc(sz);
|
|
||||||
}
|
|
||||||
void* my_realloc(void* p, size_t sz, void* pUserData)
|
|
||||||
{
|
|
||||||
return realloc(p, sz);
|
|
||||||
}
|
|
||||||
void my_free(void* p, void* pUserData)
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
drflac_allocation_callbacks allocationCallbacks;
|
|
||||||
allocationCallbacks.pUserData = &myData;
|
|
||||||
allocationCallbacks.onMalloc = my_malloc;
|
|
||||||
allocationCallbacks.onRealloc = my_realloc;
|
|
||||||
allocationCallbacks.onFree = my_free;
|
|
||||||
drflac* pFlac = drflac_open_file("my_file.flac", &allocationCallbacks);
|
|
||||||
|
|
||||||
The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
|
|
||||||
|
|
||||||
Passing in null for the allocation callbacks object will cause dr_flac to use defaults which is the same as DRFLAC_MALLOC,
|
|
||||||
DRFLAC_REALLOC and DRFLAC_FREE and the equivalent of how it worked in previous versions.
|
|
||||||
|
|
||||||
Every API that opens a drflac object now takes this extra parameter. These include the following:
|
|
||||||
|
|
||||||
drflac_open()
|
|
||||||
drflac_open_relaxed()
|
|
||||||
drflac_open_with_metadata()
|
|
||||||
drflac_open_with_metadata_relaxed()
|
|
||||||
drflac_open_file()
|
|
||||||
drflac_open_file_with_metadata()
|
|
||||||
drflac_open_memory()
|
|
||||||
drflac_open_memory_with_metadata()
|
|
||||||
drflac_open_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_and_read_pcm_frames_f32()
|
|
||||||
drflac_open_file_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_file_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_file_and_read_pcm_frames_f32()
|
|
||||||
drflac_open_memory_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_memory_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_memory_and_read_pcm_frames_f32()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Optimizations
|
|
||||||
-------------
|
|
||||||
Seeking performance has been greatly improved. A new binary search based seeking algorithm has been introduced which significantly
|
|
||||||
improves performance over the brute force method which was used when no seek table was present. Seek table based seeking also takes
|
|
||||||
advantage of the new binary search seeking system to further improve performance there as well. Note that this depends on CRC which
|
|
||||||
means it will be disabled when DR_FLAC_NO_CRC is used.
|
|
||||||
|
|
||||||
The SSE4.1 pipeline has been cleaned up and optimized. You should see some improvements with decoding speed of 24-bit files in
|
|
||||||
particular. 16-bit streams should also see some improvement.
|
|
||||||
|
|
||||||
drflac_read_pcm_frames_s16() has been optimized. Previously this sat on top of drflac_read_pcm_frames_s32() and performed it's s32
|
|
||||||
to s16 conversion in a second pass. This is now all done in a single pass. This includes SSE2 and ARM NEON optimized paths.
|
|
||||||
|
|
||||||
A minor optimization has been implemented for drflac_read_pcm_frames_s32(). This will now use an SSE2 optimized pipeline for stereo
|
|
||||||
channel reconstruction which is the last part of the decoding process.
|
|
||||||
|
|
||||||
The ARM build has seen a few improvements. The CLZ (count leading zeroes) and REV (byte swap) instructions are now used when
|
|
||||||
compiling with GCC and Clang which is achieved using inline assembly. The CLZ instruction requires ARM architecture version 5 at
|
|
||||||
compile time and the REV instruction requires ARM architecture version 6.
|
|
||||||
|
|
||||||
An ARM NEON optimized pipeline has been implemented. To enable this you'll need to add -mfpu=neon to the command line when compiling.
|
|
||||||
|
|
||||||
|
|
||||||
Removed APIs
|
|
||||||
------------
|
|
||||||
The following APIs were deprecated in version 0.11.0 and have been completely removed in version 0.12.0:
|
|
||||||
|
|
||||||
drflac_read_s32() -> drflac_read_pcm_frames_s32()
|
|
||||||
drflac_read_s16() -> drflac_read_pcm_frames_s16()
|
|
||||||
drflac_read_f32() -> drflac_read_pcm_frames_f32()
|
|
||||||
drflac_seek_to_sample() -> drflac_seek_to_pcm_frame()
|
|
||||||
drflac_open_and_decode_s32() -> drflac_open_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_and_decode_s16() -> drflac_open_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_and_decode_f32() -> drflac_open_and_read_pcm_frames_f32()
|
|
||||||
drflac_open_and_decode_file_s32() -> drflac_open_file_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_and_decode_file_s16() -> drflac_open_file_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_and_decode_file_f32() -> drflac_open_file_and_read_pcm_frames_f32()
|
|
||||||
drflac_open_and_decode_memory_s32() -> drflac_open_memory_and_read_pcm_frames_s32()
|
|
||||||
drflac_open_and_decode_memory_s16() -> drflac_open_memory_and_read_pcm_frames_s16()
|
|
||||||
drflac_open_and_decode_memory_f32() -> drflac_open_memroy_and_read_pcm_frames_f32()
|
|
||||||
|
|
||||||
Prior versions of dr_flac operated on a per-sample basis whereas now it operates on PCM frames. The removed APIs all relate
|
|
||||||
to the old per-sample APIs. You now need to use the "pcm_frame" versions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
@@ -179,7 +70,7 @@ reports metadata to the application through the use of a callback, and every met
|
|||||||
|
|
||||||
The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
|
The main opening APIs (`drflac_open()`, etc.) will fail if the header is not present. The presents a problem in certain scenarios such as broadcast style
|
||||||
streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
|
streams or internet radio where the header may not be present because the user has started playback mid-stream. To handle this, use the relaxed APIs:
|
||||||
|
|
||||||
`drflac_open_relaxed()`
|
`drflac_open_relaxed()`
|
||||||
`drflac_open_with_metadata_relaxed()`
|
`drflac_open_with_metadata_relaxed()`
|
||||||
|
|
||||||
@@ -234,8 +125,8 @@ extern "C" {
|
|||||||
#define DRFLAC_XSTRINGIFY(x) DRFLAC_STRINGIFY(x)
|
#define DRFLAC_XSTRINGIFY(x) DRFLAC_STRINGIFY(x)
|
||||||
|
|
||||||
#define DRFLAC_VERSION_MAJOR 0
|
#define DRFLAC_VERSION_MAJOR 0
|
||||||
#define DRFLAC_VERSION_MINOR 12
|
#define DRFLAC_VERSION_MINOR 13
|
||||||
#define DRFLAC_VERSION_REVISION 42
|
#define DRFLAC_VERSION_REVISION 0
|
||||||
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
|
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
|
||||||
|
|
||||||
#include <stddef.h> /* For size_t. */
|
#include <stddef.h> /* For size_t. */
|
||||||
@@ -348,11 +239,11 @@ but also more memory. In my testing there is diminishing returns after about 4KB
|
|||||||
#define DRFLAC_64BIT
|
#define DRFLAC_64BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(_M_X64)
|
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
|
||||||
#define DRFLAC_X64
|
#define DRFLAC_X64
|
||||||
#elif defined(__i386) || defined(_M_IX86)
|
#elif defined(__i386) || defined(_M_IX86)
|
||||||
#define DRFLAC_X86
|
#define DRFLAC_X86
|
||||||
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
|
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||||
#define DRFLAC_ARM
|
#define DRFLAC_ARM
|
||||||
#endif
|
#endif
|
||||||
/* End Architecture Detection */
|
/* End Architecture Detection */
|
||||||
@@ -406,8 +297,9 @@ typedef enum
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
drflac_seek_origin_start,
|
DRFLAC_SEEK_SET,
|
||||||
drflac_seek_origin_current
|
DRFLAC_SEEK_CUR,
|
||||||
|
DRFLAC_SEEK_END
|
||||||
} drflac_seek_origin;
|
} drflac_seek_origin;
|
||||||
|
|
||||||
/* The order of members in this structure is important because we map this directly to the raw data within the SEEKTABLE metadata block. */
|
/* The order of members in this structure is important because we map this directly to the raw data within the SEEKTABLE metadata block. */
|
||||||
@@ -547,7 +439,7 @@ offset (in)
|
|||||||
The number of bytes to move, relative to the origin. Will never be negative.
|
The number of bytes to move, relative to the origin. Will never be negative.
|
||||||
|
|
||||||
origin (in)
|
origin (in)
|
||||||
The origin of the seek - the current position or the start of the stream.
|
The origin of the seek - the current position, the start of the stream, or the end of the stream.
|
||||||
|
|
||||||
|
|
||||||
Return Value
|
Return Value
|
||||||
@@ -557,14 +449,32 @@ Whether or not the seek was successful.
|
|||||||
|
|
||||||
Remarks
|
Remarks
|
||||||
-------
|
-------
|
||||||
The offset will never be negative. Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be
|
Seeking relative to the start and the current position must always be supported. If seeking from the end of the stream is not supported, return DRFLAC_FALSE.
|
||||||
either drflac_seek_origin_start or drflac_seek_origin_current.
|
|
||||||
|
|
||||||
When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
|
When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
|
||||||
and handled by returning DRFLAC_FALSE.
|
and handled by returning DRFLAC_FALSE.
|
||||||
*/
|
*/
|
||||||
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
|
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Callback for when the current position in the stream needs to be retrieved.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
pUserData (in)
|
||||||
|
The user data that was passed to drflac_open() and family.
|
||||||
|
|
||||||
|
pCursor (out)
|
||||||
|
A pointer to a variable to receive the current position in the stream.
|
||||||
|
|
||||||
|
|
||||||
|
Return Value
|
||||||
|
------------
|
||||||
|
Whether or not the operation was successful.
|
||||||
|
*/
|
||||||
|
typedef drflac_bool32 (* drflac_tell_proc)(void* pUserData, drflac_int64* pCursor);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Callback for when a metadata block is read.
|
Callback for when a metadata block is read.
|
||||||
|
|
||||||
@@ -603,6 +513,9 @@ typedef struct
|
|||||||
/* The function to call when the current read position needs to be moved. */
|
/* The function to call when the current read position needs to be moved. */
|
||||||
drflac_seek_proc onSeek;
|
drflac_seek_proc onSeek;
|
||||||
|
|
||||||
|
/* The function to call when the current read position needs to be retrieved. */
|
||||||
|
drflac_tell_proc onTell;
|
||||||
|
|
||||||
/* The user data to pass around to onRead and onSeek. */
|
/* The user data to pass around to onRead and onSeek. */
|
||||||
void* pUserData;
|
void* pUserData;
|
||||||
|
|
||||||
@@ -828,7 +741,7 @@ drflac_open_memory()
|
|||||||
drflac_open_with_metadata()
|
drflac_open_with_metadata()
|
||||||
drflac_close()
|
drflac_close()
|
||||||
*/
|
*/
|
||||||
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Opens a FLAC stream with relaxed validation of the header block.
|
Opens a FLAC stream with relaxed validation of the header block.
|
||||||
@@ -869,7 +782,7 @@ force your `onRead` callback to return 0, which dr_flac will use as an indicator
|
|||||||
|
|
||||||
Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
|
Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
|
||||||
*/
|
*/
|
||||||
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
|
Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.).
|
||||||
@@ -926,7 +839,7 @@ drflac_open_memory_with_metadata()
|
|||||||
drflac_open()
|
drflac_open()
|
||||||
drflac_close()
|
drflac_close()
|
||||||
*/
|
*/
|
||||||
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present.
|
The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present.
|
||||||
@@ -936,7 +849,7 @@ See Also
|
|||||||
drflac_open_with_metadata()
|
drflac_open_with_metadata()
|
||||||
drflac_open_relaxed()
|
drflac_open_relaxed()
|
||||||
*/
|
*/
|
||||||
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Closes the given FLAC decoder.
|
Closes the given FLAC decoder.
|
||||||
@@ -1234,13 +1147,13 @@ read samples into a dynamically sized buffer on the heap until no samples are le
|
|||||||
|
|
||||||
Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
|
Do not call this function on a broadcast type of stream (like internet radio streams and whatnot).
|
||||||
*/
|
*/
|
||||||
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
|
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
|
||||||
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
|
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
|
||||||
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
|
||||||
|
|
||||||
#ifndef DR_FLAC_NO_STDIO
|
#ifndef DR_FLAC_NO_STDIO
|
||||||
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
|
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
|
||||||
@@ -2960,25 +2873,25 @@ static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFro
|
|||||||
*/
|
*/
|
||||||
if (offsetFromStart > 0x7FFFFFFF) {
|
if (offsetFromStart > 0x7FFFFFFF) {
|
||||||
drflac_uint64 bytesRemaining = offsetFromStart;
|
drflac_uint64 bytesRemaining = offsetFromStart;
|
||||||
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
|
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
bytesRemaining -= 0x7FFFFFFF;
|
bytesRemaining -= 0x7FFFFFFF;
|
||||||
|
|
||||||
while (bytesRemaining > 0x7FFFFFFF) {
|
while (bytesRemaining > 0x7FFFFFFF) {
|
||||||
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
|
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
bytesRemaining -= 0x7FFFFFFF;
|
bytesRemaining -= 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRemaining > 0) {
|
if (bytesRemaining > 0) {
|
||||||
if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) {
|
if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) {
|
if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5393,6 +5306,12 @@ static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe
|
|||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Default to 0 for the LPC order. It's important that we always set this to 0 for non LPC
|
||||||
|
and FIXED subframes because we'll be using it in a generic validation check later.
|
||||||
|
*/
|
||||||
|
pSubframe->lpcOrder = 0;
|
||||||
|
|
||||||
type = (header & 0x7E) >> 1;
|
type = (header & 0x7E) >> 1;
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
|
pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT;
|
||||||
@@ -5465,6 +5384,18 @@ static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame,
|
|||||||
|
|
||||||
pSubframe->pSamplesS32 = pDecodedSamplesOut;
|
pSubframe->pSamplesS32 = pDecodedSamplesOut;
|
||||||
|
|
||||||
|
/*
|
||||||
|
pDecodedSamplesOut will be pointing to a buffer that was allocated with enough memory to store
|
||||||
|
maxBlockSizeInPCMFrames samples (as specified in the FLAC header). We need to guard against an
|
||||||
|
overflow here. At a higher level we are checking maxBlockSizeInPCMFrames from the header, but
|
||||||
|
here we need to do an additional check to ensure this frame's block size fully encompasses any
|
||||||
|
warmup samples which is determined by the LPC order. For non LPC and FIXED subframes, the LPC
|
||||||
|
order will be have been set to 0 in drflac__read_subframe_header().
|
||||||
|
*/
|
||||||
|
if (frame->header.blockSizeInPCMFrames < pSubframe->lpcOrder) {
|
||||||
|
return DRFLAC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (pSubframe->subframeType)
|
switch (pSubframe->subframeType)
|
||||||
{
|
{
|
||||||
case DRFLAC_SUBFRAME_CONSTANT:
|
case DRFLAC_SUBFRAME_CONSTANT:
|
||||||
@@ -6312,6 +6243,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
drflac_read_proc onRead;
|
drflac_read_proc onRead;
|
||||||
drflac_seek_proc onSeek;
|
drflac_seek_proc onSeek;
|
||||||
|
drflac_tell_proc onTell;
|
||||||
drflac_meta_proc onMeta;
|
drflac_meta_proc onMeta;
|
||||||
drflac_container container;
|
drflac_container container;
|
||||||
void* pUserData;
|
void* pUserData;
|
||||||
@@ -6479,7 +6411,7 @@ static void drflac__free_from_callbacks(void* p, const drflac_allocation_callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeekpointCount, drflac_allocation_callbacks* pAllocationCallbacks)
|
static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeekpointCount, drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
|
We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
|
||||||
@@ -6489,6 +6421,8 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
drflac_uint64 seektablePos = 0;
|
drflac_uint64 seektablePos = 0;
|
||||||
drflac_uint32 seektableSize = 0;
|
drflac_uint32 seektableSize = 0;
|
||||||
|
|
||||||
|
(void)onTell;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
drflac_metadata metadata;
|
drflac_metadata metadata;
|
||||||
drflac_uint8 isLastBlock = 0;
|
drflac_uint8 isLastBlock = 0;
|
||||||
@@ -6702,10 +6636,10 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
|
|
||||||
/* Skip to the index point count */
|
/* Skip to the index point count */
|
||||||
pRunningData += 35;
|
pRunningData += 35;
|
||||||
|
|
||||||
indexCount = pRunningData[0];
|
indexCount = pRunningData[0];
|
||||||
pRunningData += 1;
|
pRunningData += 1;
|
||||||
|
|
||||||
bufferSize += indexCount * sizeof(drflac_cuesheet_track_index);
|
bufferSize += indexCount * sizeof(drflac_cuesheet_track_index);
|
||||||
|
|
||||||
/* Quick validation check. */
|
/* Quick validation check. */
|
||||||
@@ -6840,7 +6774,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
metadata.data.padding.unused = 0;
|
metadata.data.padding.unused = 0;
|
||||||
|
|
||||||
/* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */
|
/* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */
|
||||||
if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
|
||||||
isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
|
isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
|
||||||
} else {
|
} else {
|
||||||
onMeta(pUserDataMD, &metadata);
|
onMeta(pUserDataMD, &metadata);
|
||||||
@@ -6852,7 +6786,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
{
|
{
|
||||||
/* Invalid chunk. Just skip over this one. */
|
/* Invalid chunk. Just skip over this one. */
|
||||||
if (onMeta) {
|
if (onMeta) {
|
||||||
if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
|
||||||
isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
|
isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6886,7 +6820,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
|
|
||||||
/* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */
|
/* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */
|
||||||
if (onMeta == NULL && blockSize > 0) {
|
if (onMeta == NULL && blockSize > 0) {
|
||||||
if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
|
||||||
isLastBlock = DRFLAC_TRUE;
|
isLastBlock = DRFLAC_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7220,6 +7154,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */
|
drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */
|
||||||
drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */
|
drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */
|
||||||
|
drflac_tell_proc onTell; /* The original onTell callback from drflac_open() and family. */
|
||||||
void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */
|
void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */
|
||||||
drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */
|
drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */
|
||||||
drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */
|
drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */
|
||||||
@@ -7241,32 +7176,32 @@ static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut,
|
|||||||
|
|
||||||
static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
|
static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
|
||||||
{
|
{
|
||||||
if (origin == drflac_seek_origin_start) {
|
if (origin == DRFLAC_SEEK_SET) {
|
||||||
if (offset <= 0x7FFFFFFF) {
|
if (offset <= 0x7FFFFFFF) {
|
||||||
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) {
|
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
oggbs->currentBytePos = offset;
|
oggbs->currentBytePos = offset;
|
||||||
|
|
||||||
return DRFLAC_TRUE;
|
return DRFLAC_TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
|
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
oggbs->currentBytePos = offset;
|
oggbs->currentBytePos = offset;
|
||||||
|
|
||||||
return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current);
|
return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, DRFLAC_SEEK_CUR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (offset > 0x7FFFFFFF) {
|
while (offset > 0x7FFFFFFF) {
|
||||||
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) {
|
if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
oggbs->currentBytePos += 0x7FFFFFFF;
|
oggbs->currentBytePos += 0x7FFFFFFF;
|
||||||
offset -= 0x7FFFFFFF;
|
offset -= 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) { /* <-- Safe cast thanks to the loop above. */
|
if (!oggbs->onSeek(oggbs->pUserData, (int)offset, DRFLAC_SEEK_CUR)) { /* <-- Safe cast thanks to the loop above. */
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
oggbs->currentBytePos += offset;
|
oggbs->currentBytePos += offset;
|
||||||
@@ -7298,7 +7233,7 @@ static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_og
|
|||||||
|
|
||||||
if (header.serialNumber != oggbs->serialNumber) {
|
if (header.serialNumber != oggbs->serialNumber) {
|
||||||
/* It's not a FLAC page. Skip it. */
|
/* It's not a FLAC page. Skip it. */
|
||||||
if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) {
|
if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -7384,7 +7319,7 @@ static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
|
|||||||
At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
|
At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
|
||||||
want to load the next page and keep searching for the end of the packet.
|
want to load the next page and keep searching for the end of the packet.
|
||||||
*/
|
*/
|
||||||
drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current);
|
drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, DRFLAC_SEEK_CUR);
|
||||||
oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
|
oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
|
||||||
|
|
||||||
if (atEndOfPage) {
|
if (atEndOfPage) {
|
||||||
@@ -7462,8 +7397,8 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
|
|||||||
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
|
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
|
||||||
|
|
||||||
/* Seeking is always forward which makes things a lot simpler. */
|
/* Seeking is always forward which makes things a lot simpler. */
|
||||||
if (origin == drflac_seek_origin_start) {
|
if (origin == DRFLAC_SEEK_SET) {
|
||||||
if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) {
|
if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7471,38 +7406,50 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
|
|||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current);
|
return drflac__on_seek_ogg(pUserData, offset, DRFLAC_SEEK_CUR);
|
||||||
}
|
} else if (origin == DRFLAC_SEEK_CUR) {
|
||||||
|
while (bytesSeeked < offset) {
|
||||||
|
int bytesRemainingToSeek = offset - bytesSeeked;
|
||||||
|
DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
|
||||||
|
|
||||||
DRFLAC_ASSERT(origin == drflac_seek_origin_current);
|
if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
|
||||||
|
bytesSeeked += bytesRemainingToSeek;
|
||||||
|
(void)bytesSeeked; /* <-- Silence a dead store warning emitted by Clang Static Analyzer. */
|
||||||
|
oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while (bytesSeeked < offset) {
|
/* If we get here it means some of the requested data is contained in the next pages. */
|
||||||
int bytesRemainingToSeek = offset - bytesSeeked;
|
if (oggbs->bytesRemainingInPage > 0) {
|
||||||
DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
|
bytesSeeked += (int)oggbs->bytesRemainingInPage;
|
||||||
|
oggbs->bytesRemainingInPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
|
DRFLAC_ASSERT(bytesRemainingToSeek > 0);
|
||||||
bytesSeeked += bytesRemainingToSeek;
|
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
|
||||||
(void)bytesSeeked; /* <-- Silence a dead store warning emitted by Clang Static Analyzer. */
|
/* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
|
||||||
oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
|
return DRFLAC_FALSE;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get here it means some of the requested data is contained in the next pages. */
|
|
||||||
if (oggbs->bytesRemainingInPage > 0) {
|
|
||||||
bytesSeeked += (int)oggbs->bytesRemainingInPage;
|
|
||||||
oggbs->bytesRemainingInPage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DRFLAC_ASSERT(bytesRemainingToSeek > 0);
|
|
||||||
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
|
|
||||||
/* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
|
|
||||||
return DRFLAC_FALSE;
|
|
||||||
}
|
}
|
||||||
|
} else if (origin == DRFLAC_SEEK_END) {
|
||||||
|
/* Seeking to the end is not supported. */
|
||||||
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DRFLAC_TRUE;
|
return DRFLAC_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static drflac_bool32 drflac__on_tell_ogg(void* pUserData, drflac_int64* pCursor)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Not implemented for Ogg containers because we don't currently track the byte position of the logical bitstream. To support this, we'll need
|
||||||
|
to track the position in drflac__on_read_ogg and drflac__on_seek_ogg.
|
||||||
|
*/
|
||||||
|
(void)pUserData;
|
||||||
|
(void)pCursor;
|
||||||
|
return DRFLAC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
|
static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex)
|
||||||
{
|
{
|
||||||
@@ -7525,7 +7472,7 @@ static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64
|
|||||||
runningGranulePosition = 0;
|
runningGranulePosition = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
|
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
|
||||||
drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
|
drflac_oggbs__seek_physical(oggbs, originalBytePos, DRFLAC_SEEK_SET);
|
||||||
return DRFLAC_FALSE; /* Never did find that sample... */
|
return DRFLAC_FALSE; /* Never did find that sample... */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7559,7 +7506,7 @@ static drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64
|
|||||||
a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
|
a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
|
||||||
we find the one containing the target sample.
|
we find the one containing the target sample.
|
||||||
*/
|
*/
|
||||||
if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) {
|
if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, DRFLAC_SEEK_SET)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
|
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
|
||||||
@@ -7726,7 +7673,7 @@ static drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_r
|
|||||||
The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
|
The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to
|
||||||
be handling it in a generic way based on the serial number and packet types.
|
be handling it in a generic way based on the serial number and packet types.
|
||||||
*/
|
*/
|
||||||
if (!onSeek(pUserData, 2, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, 2, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7783,18 +7730,18 @@ static drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_r
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Not a FLAC header. Skip it. */
|
/* Not a FLAC header. Skip it. */
|
||||||
if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, bytesRemainingInPage, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Not a FLAC header. Seek past the entire page and move on to the next. */
|
/* Not a FLAC header. Seek past the entire page and move on to the next. */
|
||||||
if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, bytesRemainingInPage, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, pageBodySize, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7819,18 +7766,19 @@ static drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_r
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
|
static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD)
|
||||||
{
|
{
|
||||||
drflac_bool32 relaxed;
|
drflac_bool32 relaxed;
|
||||||
drflac_uint8 id[4];
|
drflac_uint8 id[4];
|
||||||
|
|
||||||
if (pInit == NULL || onRead == NULL || onSeek == NULL) {
|
if (pInit == NULL || onRead == NULL || onSeek == NULL) { /* <-- onTell is optional. */
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
|
DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
|
||||||
pInit->onRead = onRead;
|
pInit->onRead = onRead;
|
||||||
pInit->onSeek = onSeek;
|
pInit->onSeek = onSeek;
|
||||||
|
pInit->onTell = onTell;
|
||||||
pInit->onMeta = onMeta;
|
pInit->onMeta = onMeta;
|
||||||
pInit->container = container;
|
pInit->container = container;
|
||||||
pInit->pUserData = pUserData;
|
pInit->pUserData = pUserData;
|
||||||
@@ -7838,6 +7786,7 @@ static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_p
|
|||||||
|
|
||||||
pInit->bs.onRead = onRead;
|
pInit->bs.onRead = onRead;
|
||||||
pInit->bs.onSeek = onSeek;
|
pInit->bs.onSeek = onSeek;
|
||||||
|
pInit->bs.onTell = onTell;
|
||||||
pInit->bs.pUserData = pUserData;
|
pInit->bs.pUserData = pUserData;
|
||||||
drflac__reset_cache(&pInit->bs);
|
drflac__reset_cache(&pInit->bs);
|
||||||
|
|
||||||
@@ -7870,7 +7819,7 @@ static drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_p
|
|||||||
headerSize += 10;
|
headerSize += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) {
|
if (!onSeek(pUserData, headerSize, DRFLAC_SEEK_CUR)) {
|
||||||
return DRFLAC_FALSE; /* Failed to seek past the tag. */
|
return DRFLAC_FALSE; /* Failed to seek past the tag. */
|
||||||
}
|
}
|
||||||
pInit->runningFilePos += headerSize;
|
pInit->runningFilePos += headerSize;
|
||||||
@@ -7922,7 +7871,7 @@ static void drflac__init_from_info(drflac* pFlac, const drflac_init_info* pInit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
|
static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
drflac_init_info init;
|
drflac_init_info init;
|
||||||
drflac_uint32 allocationSize;
|
drflac_uint32 allocationSize;
|
||||||
@@ -7940,7 +7889,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
/* CPU support first. */
|
/* CPU support first. */
|
||||||
drflac__init_cpu_caps();
|
drflac__init_cpu_caps();
|
||||||
|
|
||||||
if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
|
if (!drflac__init_private(&init, onRead, onSeek, onTell, onMeta, container, pUserData, pUserDataMD)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7996,6 +7945,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
DRFLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
|
DRFLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
|
||||||
pOggbs->onRead = onRead;
|
pOggbs->onRead = onRead;
|
||||||
pOggbs->onSeek = onSeek;
|
pOggbs->onSeek = onSeek;
|
||||||
|
pOggbs->onTell = onTell;
|
||||||
pOggbs->pUserData = pUserData;
|
pOggbs->pUserData = pUserData;
|
||||||
pOggbs->currentBytePos = init.oggFirstBytePos;
|
pOggbs->currentBytePos = init.oggFirstBytePos;
|
||||||
pOggbs->firstBytePos = init.oggFirstBytePos;
|
pOggbs->firstBytePos = init.oggFirstBytePos;
|
||||||
@@ -8016,17 +7966,19 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
if (init.hasMetadataBlocks) {
|
if (init.hasMetadataBlocks) {
|
||||||
drflac_read_proc onReadOverride = onRead;
|
drflac_read_proc onReadOverride = onRead;
|
||||||
drflac_seek_proc onSeekOverride = onSeek;
|
drflac_seek_proc onSeekOverride = onSeek;
|
||||||
|
drflac_tell_proc onTellOverride = onTell;
|
||||||
void* pUserDataOverride = pUserData;
|
void* pUserDataOverride = pUserData;
|
||||||
|
|
||||||
#ifndef DR_FLAC_NO_OGG
|
#ifndef DR_FLAC_NO_OGG
|
||||||
if (init.container == drflac_container_ogg) {
|
if (init.container == drflac_container_ogg) {
|
||||||
onReadOverride = drflac__on_read_ogg;
|
onReadOverride = drflac__on_read_ogg;
|
||||||
onSeekOverride = drflac__on_seek_ogg;
|
onSeekOverride = drflac__on_seek_ogg;
|
||||||
|
onTellOverride = drflac__on_tell_ogg;
|
||||||
pUserDataOverride = (void*)pOggbs;
|
pUserDataOverride = (void*)pOggbs;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
|
if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onTellOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
|
||||||
#ifndef DR_FLAC_NO_OGG
|
#ifndef DR_FLAC_NO_OGG
|
||||||
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
|
drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
|
||||||
#endif
|
#endif
|
||||||
@@ -8061,6 +8013,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
/* The Ogg bistream needs to be layered on top of the original bitstream. */
|
/* The Ogg bistream needs to be layered on top of the original bitstream. */
|
||||||
pFlac->bs.onRead = drflac__on_read_ogg;
|
pFlac->bs.onRead = drflac__on_read_ogg;
|
||||||
pFlac->bs.onSeek = drflac__on_seek_ogg;
|
pFlac->bs.onSeek = drflac__on_seek_ogg;
|
||||||
|
pFlac->bs.onTell = drflac__on_tell_ogg;
|
||||||
pFlac->bs.pUserData = (void*)pInternalOggbs;
|
pFlac->bs.pUserData = (void*)pInternalOggbs;
|
||||||
pFlac->_oggbs = (void*)pInternalOggbs;
|
pFlac->_oggbs = (void*)pInternalOggbs;
|
||||||
}
|
}
|
||||||
@@ -8087,7 +8040,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
|
DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
|
||||||
|
|
||||||
/* Seek to the seektable, then just read directly into our seektable buffer. */
|
/* Seek to the seektable, then just read directly into our seektable buffer. */
|
||||||
if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
|
if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, DRFLAC_SEEK_SET)) {
|
||||||
drflac_uint32 iSeekpoint;
|
drflac_uint32 iSeekpoint;
|
||||||
|
|
||||||
for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
|
for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
|
||||||
@@ -8105,7 +8058,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We need to seek back to where we were. If this fails it's a critical error. */
|
/* We need to seek back to where we were. If this fails it's a critical error. */
|
||||||
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
|
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, DRFLAC_SEEK_SET)) {
|
||||||
drflac__free_from_callbacks(pFlac, &allocationCallbacks);
|
drflac__free_from_callbacks(pFlac, &allocationCallbacks);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -8276,7 +8229,7 @@ static drflac_result drflac_result_from_errno(int e)
|
|||||||
#ifdef ENOSYS
|
#ifdef ENOSYS
|
||||||
case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
|
case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENOTEMPTY
|
#if defined(ENOTEMPTY) && ENOTEMPTY != EEXIST /* In AIX, ENOTEMPTY and EEXIST use the same value. */
|
||||||
case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
|
case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ELOOP
|
#ifdef ELOOP
|
||||||
@@ -8727,11 +8680,41 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt
|
|||||||
|
|
||||||
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
|
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
|
||||||
{
|
{
|
||||||
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
|
int whence = SEEK_SET;
|
||||||
|
if (origin == DRFLAC_SEEK_CUR) {
|
||||||
|
whence = SEEK_CUR;
|
||||||
|
} else if (origin == DRFLAC_SEEK_END) {
|
||||||
|
whence = SEEK_END;
|
||||||
|
}
|
||||||
|
|
||||||
return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
|
return fseek((FILE*)pUserData, offset, whence) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static drflac_bool32 drflac__on_tell_stdio(void* pUserData, drflac_int64* pCursor)
|
||||||
|
{
|
||||||
|
FILE* pFileStdio = (FILE*)pUserData;
|
||||||
|
drflac_int64 result;
|
||||||
|
|
||||||
|
/* These were all validated at a higher level. */
|
||||||
|
DRFLAC_ASSERT(pFileStdio != NULL);
|
||||||
|
DRFLAC_ASSERT(pCursor != NULL);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER > 1200
|
||||||
|
result = _ftelli64(pFileStdio);
|
||||||
|
#else
|
||||||
|
result = ftell(pFileStdio);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
result = ftell(pFileStdio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pCursor = result;
|
||||||
|
|
||||||
|
return DRFLAC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
@@ -8742,7 +8725,7 @@ DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocati
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
|
pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -8761,7 +8744,7 @@ DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_all
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
|
pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -8780,7 +8763,7 @@ DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
return pFlac;
|
return pFlac;
|
||||||
@@ -8799,7 +8782,7 @@ DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, dr
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, drflac__on_tell_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
return pFlac;
|
return pFlac;
|
||||||
@@ -8834,28 +8817,45 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by
|
|||||||
static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
|
static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin)
|
||||||
{
|
{
|
||||||
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
|
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
|
||||||
|
drflac_int64 newCursor;
|
||||||
|
|
||||||
DRFLAC_ASSERT(memoryStream != NULL);
|
DRFLAC_ASSERT(memoryStream != NULL);
|
||||||
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
|
|
||||||
|
|
||||||
if (offset > (drflac_int64)memoryStream->dataSize) {
|
newCursor = memoryStream->currentReadPos;
|
||||||
|
|
||||||
|
if (origin == DRFLAC_SEEK_SET) {
|
||||||
|
newCursor = 0;
|
||||||
|
} else if (origin == DRFLAC_SEEK_CUR) {
|
||||||
|
newCursor = (drflac_int64)memoryStream->currentReadPos;
|
||||||
|
} else if (origin == DRFLAC_SEEK_END) {
|
||||||
|
newCursor = (drflac_int64)memoryStream->dataSize;
|
||||||
|
} else {
|
||||||
|
DRFLAC_ASSERT(!"Invalid seek origin");
|
||||||
return DRFLAC_FALSE;
|
return DRFLAC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (origin == drflac_seek_origin_current) {
|
newCursor += offset;
|
||||||
if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
|
|
||||||
memoryStream->currentReadPos += offset;
|
if (newCursor < 0) {
|
||||||
} else {
|
return DRFLAC_FALSE; /* Trying to seek prior to the start of the buffer. */
|
||||||
return DRFLAC_FALSE; /* Trying to seek too far forward. */
|
}
|
||||||
}
|
if ((size_t)newCursor > memoryStream->dataSize) {
|
||||||
} else {
|
return DRFLAC_FALSE; /* Trying to seek beyond the end of the buffer. */
|
||||||
if ((drflac_uint32)offset <= memoryStream->dataSize) {
|
|
||||||
memoryStream->currentReadPos = offset;
|
|
||||||
} else {
|
|
||||||
return DRFLAC_FALSE; /* Trying to seek too far forward. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memoryStream->currentReadPos = (size_t)newCursor;
|
||||||
|
|
||||||
|
return DRFLAC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static drflac_bool32 drflac__on_tell_memory(void* pUserData, drflac_int64* pCursor)
|
||||||
|
{
|
||||||
|
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
|
||||||
|
|
||||||
|
DRFLAC_ASSERT(memoryStream != NULL);
|
||||||
|
DRFLAC_ASSERT(pCursor != NULL);
|
||||||
|
|
||||||
|
*pCursor = (drflac_int64)memoryStream->currentReadPos;
|
||||||
return DRFLAC_TRUE;
|
return DRFLAC_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8867,7 +8867,7 @@ DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const
|
|||||||
memoryStream.data = (const drflac_uint8*)pData;
|
memoryStream.data = (const drflac_uint8*)pData;
|
||||||
memoryStream.dataSize = dataSize;
|
memoryStream.dataSize = dataSize;
|
||||||
memoryStream.currentReadPos = 0;
|
memoryStream.currentReadPos = 0;
|
||||||
pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, &memoryStream, pAllocationCallbacks);
|
pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, drflac__on_tell_memory, &memoryStream, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -8898,7 +8898,7 @@ DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t da
|
|||||||
memoryStream.data = (const drflac_uint8*)pData;
|
memoryStream.data = (const drflac_uint8*)pData;
|
||||||
memoryStream.dataSize = dataSize;
|
memoryStream.dataSize = dataSize;
|
||||||
memoryStream.currentReadPos = 0;
|
memoryStream.currentReadPos = 0;
|
||||||
pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, drflac__on_tell_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -8923,22 +8923,22 @@ DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t da
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
|
return drflac_open_with_metadata_private(onRead, onSeek, onTell, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
|
||||||
}
|
}
|
||||||
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
|
return drflac_open_with_metadata_private(onRead, onSeek, onTell, NULL, container, pUserData, pUserData, pAllocationCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
|
return drflac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
|
||||||
}
|
}
|
||||||
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
|
return drflac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRFLAC_API void drflac_close(drflac* pFlac)
|
DRFLAC_API void drflac_close(drflac* pFlac)
|
||||||
@@ -11770,7 +11770,7 @@ DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
|
|||||||
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
|
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
|
||||||
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
|
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
|
||||||
|
|
||||||
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
drflac* pFlac;
|
drflac* pFlac;
|
||||||
|
|
||||||
@@ -11784,7 +11784,7 @@ DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc on
|
|||||||
*totalPCMFrameCountOut = 0;
|
*totalPCMFrameCountOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -11792,7 +11792,7 @@ DRFLAC_API drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc on
|
|||||||
return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
|
return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
drflac* pFlac;
|
drflac* pFlac;
|
||||||
|
|
||||||
@@ -11806,7 +11806,7 @@ DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc on
|
|||||||
*totalPCMFrameCountOut = 0;
|
*totalPCMFrameCountOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -11814,7 +11814,7 @@ DRFLAC_API drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc on
|
|||||||
return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
|
return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut, const drflac_allocation_callbacks* pAllocationCallbacks)
|
||||||
{
|
{
|
||||||
drflac* pFlac;
|
drflac* pFlac;
|
||||||
|
|
||||||
@@ -11828,7 +11828,7 @@ DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, d
|
|||||||
*totalPCMFrameCountOut = 0;
|
*totalPCMFrameCountOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFlac = drflac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
|
pFlac = drflac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
|
||||||
if (pFlac == NULL) {
|
if (pFlac == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -12077,6 +12077,26 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
|
|||||||
/*
|
/*
|
||||||
REVISION HISTORY
|
REVISION HISTORY
|
||||||
================
|
================
|
||||||
|
v0.13.0 - TBD
|
||||||
|
- API CHANGE: Seek origin enums have been renamed to match the naming convention used by other dr_libs libraries:
|
||||||
|
- drflac_seek_origin_start -> DRFLAC_SEEK_SET
|
||||||
|
- drflac_seek_origin_current -> DRFLAC_SEEK_CUR
|
||||||
|
- DRFLAC_SEEK_END (new)
|
||||||
|
- API CHANGE: A new seek origin has been added to allow seeking from the end of the file. If you implement your own `onSeek` callback, you should now detect and handle `DRFLAC_SEEK_END`. If seeking to the end is not supported, return `DRFLAC_FALSE`. If you only use `*_open_file()` or `*_open_memory()`, you need not change anything.
|
||||||
|
- API CHANGE: An `onTell` callback has been added to the following functions:
|
||||||
|
- drflac_open()
|
||||||
|
- drflac_open_relaxed()
|
||||||
|
- drflac_open_with_metadata()
|
||||||
|
- drflac_open_with_metadata_relaxed()
|
||||||
|
- drflac_open_and_read_pcm_frames_s32()
|
||||||
|
- drflac_open_and_read_pcm_frames_s16()
|
||||||
|
- drflac_open_and_read_pcm_frames_f32()
|
||||||
|
- Fix compilation for AIX OS.
|
||||||
|
|
||||||
|
v0.12.43 - 2024-12-17
|
||||||
|
- Fix a possible buffer overflow during decoding.
|
||||||
|
- Improve detection of ARM64EC
|
||||||
|
|
||||||
v0.12.42 - 2023-11-02
|
v0.12.42 - 2023-11-02
|
||||||
- Fix build for ARMv6-M.
|
- Fix build for ARMv6-M.
|
||||||
- Fix a compilation warning with GCC.
|
- Fix a compilation warning with GCC.
|
||||||
|
899
src/external/dr_mp3.h
vendored
899
src/external/dr_mp3.h
vendored
File diff suppressed because it is too large
Load Diff
492
src/external/dr_wav.h
vendored
492
src/external/dr_wav.h
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user