XUGFJVFEZPC3CCIFBIGADUC7TOYF5LN2OZ4UWKC4KMFVA7VSDUHQC
engine. The current global time time in PCM frames can be retrieved with `ma_engine_get_time()`.
The engine's global time can be changed with `ma_engine_set_time()` for synchronization purposes if
required. Note that scheduling a start time still requires an explicit call to `ma_sound_start()`
before anything will play:
engine. The current global time time in PCM frames can be retrieved with
`ma_engine_get_time_in_pcm_frames()`. The engine's global time can be changed with
`ma_engine_set_time_in_pcm_frames()` for synchronization purposes if required. Note that scheduling
a start time still requires an explicit call to `ma_sound_start()` before anything will play:
ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 2);
ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time_in_pcm_frames(&engine) + (ma_engine_get_sample_rate(&engine) * 2);
This will require linking with `-framework CoreFoundation -framework CoreAudio -framework AudioUnit`.
Alternatively, if you would rather keep using runtime linking you can add the following to your
entitlements.xcent file:
This will require linking with `-framework CoreFoundation -framework CoreAudio -framework AudioToolbox`.
If you get errors about AudioToolbox, try with `-framework AudioUnit` instead. You may get this when
using older versions of iOS. Alternatively, if you would rather keep using runtime linking you can
add the following to your entitlements.xcent file:
-sAUDIO_WORKLET=1 -sWASM_WORKERS=1 -sASYNCIFY
An example for compiling with AudioWorklet support might look like this:
emcc program.c -o bin/program.html -DMA_ENABLE_AUDIO_WORKLETS -sAUDIO_WORKLET=1 -sWASM_WORKERS=1 -sASYNCIFY
To run locally, you'll need to use emrun:
emrun bin/program.html
+----------------------------------+--------------------------------------------------------------------+
| MA_NO_RESOURCE_MANAGER | Disables the resource manager. When using the engine this will |
| | also disable the following functions: |
| | |
| | ``` |
| | ma_sound_init_from_file() |
| | ma_sound_init_from_file_w() |
| | ma_sound_init_copy() |
| | ma_engine_play_sound_ex() |
| | ma_engine_play_sound() |
| | ``` |
| | |
| | The only way to initialize a `ma_sound` object is to initialize it |
| | from a data source. |
+----------------------------------+--------------------------------------------------------------------+
| MA_NO_NODE_GRAPH | Disables the node graph API. This will also disable the engine API |
| | because it depends on the node graph. |
+----------------------------------+--------------------------------------------------------------------+
| MA_NO_ENGINE | Disables the engine API. |
the data source to only play one of those sub-sounds.
the data source to only play one of those sub-sounds. Note that once the range is set, everything
that takes a position, such as cursors and loop points, should always be relatvie to the start of
the range. When the range is set, any previously defined loop point will be reset.
Note that the `loop` parameter is set to false in the example above. When this is set to true, only
the current data source will be looped. You can loop the entire chain by linking in a loop like so:
Note that when looping is enabled, only the current data source will be looped. You can loop the
entire chain by linking in a loop like so:
instances of the same sound simultaneously. Instead, initialize multiple data sources for each
instance. This can be extremely inefficient depending on the data source and can result in
glitching due to subtle changes to the state of internal filters.
instances of the same sound simultaneously. This can be extremely inefficient depending on the type
of data source and can result in glitching due to subtle changes to the state of internal filters.
Instead, initialize multiple data sources for each instance.
When loading a sound from a file path, the engine will reference count the file to prevent it from
being loaded if it's already in memory. When you uninitialize a sound, the reference count will be
decremented, and if it hits zero, the sound will be unloaded from memory. This reference counting
system is not used for streams. The engine will use a 64-bit hash of the file name when comparing
file paths which means there's a small chance you might encounter a name collision. If this is an
issue, you'll need to use a different name for one of the colliding file paths, or just not load
from files and instead load from a data source.
You can use `ma_sound_init_copy()` to initialize a copy of another sound. Note, however, that this
only works for sounds that were initialized with `ma_sound_init_from_file()` and without the
`MA_SOUND_FLAG_STREAM` flag.
ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 1));
ma_sound_set_start_time_in_pcm_frames(&sound, ma_engine_get_time_in_pcm_frames(&engine) + (ma_engine_get_sample_rate(&engine) * 1));
ma_sound_set_stop_time_in_pcm_frames(&sound, ma_engine_get_time(&engine) + (ma_engine_get_sample_rate(&engine) * 2));
ma_sound_set_stop_time_in_pcm_frames(&sound, ma_engine_get_time_in_pcm_frames(&engine) + (ma_engine_get_sample_rate(&engine) * 2));
current time with `ma_engine_get_time()`. The engine's global time is incremented automatically as
audio data is read, but it can be reset with `ma_engine_set_time()` in case it needs to be
resynchronized for some reason.
current time with `ma_engine_get_time_in_pcm_frames()`. The engine's global time is incremented
automatically as audio data is read, but it can be reset with `ma_engine_set_time_in_pcm_frames()`
in case it needs to be resynchronized for some reason.
sound this should never return true.
sound this should never return true. Alternatively, you can configure a callback that will be fired
when the sound reaches the end. Note that the callback is fired from the audio thread which means
you cannot be uninitializing sound from the callback. To set the callback you can use
`ma_sound_set_end_callback()`. Alternatively, if you're using `ma_sound_init_ex()`, you can pass it
into the config like so:
```c
soundConfig.endCallback = my_end_callback;
soundConfig.pEndCallbackUserData = pMyEndCallbackUserData;
```
The end callback is declared like so:
```c
void my_end_callback(void* pUserData, ma_sound* pSound)
{
...
}
```
due to the random nature of the hash. The disadvantage is that file names are case-sensitive. If
this is an issue, you should normalize your file names to upper- or lower-case before initializing
your data sources.
due to the random nature of the hash. The disadvantages are that file names are case-sensitive and
there's a small chance of name collisions. If case-sensitivity is an issue, you should normalize
your file names to upper- or lower-case before initializing your data sources. If name collisions
become an issue, you'll need to change the name of one of the colliding names or just not use the
resource manager.
my_custom_node_process_pcm_frames, // The function that will be called process your custom node. This is where you'd implement your effect processing.
my_custom_node_process_pcm_frames, // The function that will be called to process your custom node. This is where you'd implement your effect processing.
| | attachments. This is useful for effects like |
| | attachments. When a node has at least one input |
| | bus, but there are no inputs attached or the |
| | inputs do not deliver any data, the node's |
| | processing callback will not get fired. This flag |
| | will make it so the callback is always fired |
| | regardless of whether or not any input data is |
| | received. This is useful for effects like |
| | original data sources have reached their ends. |
| | original data sources have reached their ends. It |
| | may also be useful for nodes that must always |
| | have their processing callback fired when there |
| | are no inputs attached. |
devices and can be used independently. The following formats are supported:
+---------+------------------+----------+
| Format | Decoding Backend | Built-In |
+---------+------------------+----------+
| WAV | dr_wav | Yes |
| MP3 | dr_mp3 | Yes |
| FLAC | dr_flac | Yes |
| Vorbis | stb_vorbis | No |
+---------+------------------+----------+
Vorbis is supported via stb_vorbis which can be enabled by including the header section before the
implementation of miniaudio, like the following:
```c
#define STB_VORBIS_HEADER_ONLY
#include "extras/stb_vorbis.c" // Enables Vorbis decoding.
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
// The stb_vorbis implementation must come after the implementation of miniaudio.
#undef STB_VORBIS_HEADER_ONLY
#include "extras/stb_vorbis.c"
```
devices and can be used independently. Built-in support is included for the following formats:
Built-in decoders are amalgamated into the implementation section of miniaudio. You can disable the
built-in decoders by specifying one or more of the following options before the miniaudio
implementation:
You can disable the built-in decoders by specifying one or more of the following options before the
miniaudio implementation:
Disabling built-in decoding libraries is useful if you use these libraries independantly of the
`ma_decoder` API.
miniaudio supports the ability to plug in custom decoders. See the section below for details on how
to use custom decoders.
The `ma_encoding` API is used for writing audio files. The only supported output format is WAV
which is achieved via dr_wav which is amalgamated into the implementation section of miniaudio.
The `ma_encoding` API is used for writing audio files. The only supported output format is WAV.
The amplitude, seed, and type can be changed dynamically with `ma_noise_set_amplitude()`,
`ma_noise_set_seed()`, and `ma_noise_set_type()` respectively.
The amplitude and seed can be changed dynamically with `ma_noise_set_amplitude()` and
`ma_noise_set_seed()` respectively.
The following backends are supported by miniaudio.
The following backends are supported by miniaudio. These are listed in order of default priority.
When no backend is specified when initializing a context or device, miniaudio will attempt to use
each of these backends in the order listed in the table below.
Note that backends that are not usable by the build target will not be included in the build. For
example, ALSA, which is specific to Linux, will not be included in the Windows build.
16.1. High Level API
16.1. Low Level API
-------------------
- In the data callback, if your data is already clipped prior to copying it into the output buffer,
set the `noClip` config option in the device config to true. This will disable miniaudio's built
in clipping function.
- By default, miniaudio will pre-silence the data callback's output buffer. If you know that you
will always write valid data to the output buffer you can disable pre-silencing by setting the
`noPreSilence` config option in the device config to true.
16.2. High Level API
- If a sound does not require spatialization, disable it by initialzing the sound with the
`MA_SOUND_FLAG_NO_SPATIALIZATION` flag. It can be renabled again post-initialization with
- If a sound does not require spatialization, disable it by initializing the sound with the
`MA_SOUND_FLAG_NO_SPATIALIZATION` flag. It can be re-enabled again post-initialization with
- If you know all of your sounds will always be the same sample rate, set the engine's sample
rate to match that of the sounds. Likewise, if you're using a self-managed resource manager,
consider setting the decoded sample rate to match your sounds. By configuring everything to
use a consistent sample rate, sample rate conversion can be avoided.
- The contents of the output buffer passed into the data callback will always be pre-initialized to
silence unless the `noPreSilencedOutputBuffer` config variable in `ma_device_config` is set to
true, in which case it'll be undefined which will require you to write something to the entire
buffer.
- By default miniaudio will automatically clip samples. This only applies when the playback sample
format is configured as `ma_format_f32`. If you are doing clipping yourself, you can disable this
overhead by setting `noClip` to true in the device config.
- Note that GCC and Clang requires `-msse2`, `-mavx2`, etc. for SIMD optimizations.
- The sndio backend is currently only enabled on OpenBSD builds.
- The audio(4) backend is supported on OpenBSD, but you may need to disable sndiod before you can
use it.
typedef void (* ma_proc)(void);
/*
ma_proc is annoying because when compiling with GCC we get pendantic warnings about converting
between `void*` and `void (*)()`. We can't use `void (*)()` with MSVC however, because we'll get
warning C4191 about "type cast between incompatible function types". To work around this I'm going
to use a different data type depending on the compiler.
*/
#if defined(__GNUC__)
typedef void (*ma_proc)(void);
#else
typedef void* ma_proc;
#endif
#if defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))
#if defined(MA_FORCE_UWP) || (defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)))
#if defined(__has_c_attribute)
#if __has_c_attribute(fallthrough)
#define MA_FALLTHROUGH [[fallthrough]]
#endif
#endif
#if !defined(MA_FALLTHROUGH) && defined(__has_attribute) && (defined(__clang__) || defined(__GNUC__))
#if __has_attribute(fallthrough)
#define MA_FALLTHROUGH __attribute__((fallthrough))
#endif
#endif
#if !defined(MA_FALLTHROUGH)
#define MA_FALLTHROUGH ((void)0)
#endif
#if !defined(MA_API)
#if defined(MA_DLL)
#if defined(_WIN32)
#define MA_DLL_IMPORT __declspec(dllimport)
#define MA_DLL_EXPORT __declspec(dllexport)
#define MA_DLL_PRIVATE static
/* MA_DLL is not officially supported. You're on your own if you want to use this. */
#if defined(MA_DLL)
#if defined(_WIN32)
#define MA_DLL_IMPORT __declspec(dllimport)
#define MA_DLL_EXPORT __declspec(dllexport)
#define MA_DLL_PRIVATE static
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define MA_DLL_IMPORT __attribute__((visibility("default")))
#define MA_DLL_EXPORT __attribute__((visibility("default")))
#define MA_DLL_PRIVATE __attribute__((visibility("hidden")))
#if defined(__GNUC__) && __GNUC__ >= 4
#define MA_DLL_IMPORT __attribute__((visibility("default")))
#define MA_DLL_EXPORT __attribute__((visibility("default")))
#define MA_DLL_PRIVATE __attribute__((visibility("hidden")))
#else
#define MA_DLL_IMPORT
#define MA_DLL_EXPORT
#define MA_DLL_PRIVATE static
#endif
#define MA_DLL_IMPORT
#define MA_DLL_EXPORT
#define MA_DLL_PRIVATE static
/*
Special wchar_t type to ensure any structures in the public sections that reference it have a
consistent size across all platforms.
On Windows, wchar_t is 2 bytes, whereas everywhere else it's 4 bytes. Since Windows likes to use
wchar_t for it's IDs, we need a special explicitly sized wchar type that is always 2 bytes on all
platforms.
*/
#if !defined(MA_POSIX) && defined(MA_WIN32)
typedef wchar_t ma_wchar_win32;
#else
typedef ma_uint16 ma_wchar_win32;
#endif
MA_FORMAT_NOT_SUPPORTED = -100,
MA_DEVICE_TYPE_NOT_SUPPORTED = -101,
MA_SHARE_MODE_NOT_SUPPORTED = -102,
MA_NO_BACKEND = -103,
MA_NO_DEVICE = -104,
MA_API_NOT_FOUND = -105,
MA_INVALID_DEVICE_CONFIG = -106,
MA_LOOP = -107,
MA_FORMAT_NOT_SUPPORTED = -200,
MA_DEVICE_TYPE_NOT_SUPPORTED = -201,
MA_SHARE_MODE_NOT_SUPPORTED = -202,
MA_NO_BACKEND = -203,
MA_NO_DEVICE = -204,
MA_API_NOT_FOUND = -205,
MA_INVALID_DEVICE_CONFIG = -206,
MA_LOOP = -207,
MA_BACKEND_NOT_ENABLED = -208,
MA_DEVICE_NOT_INITIALIZED = -200,
MA_DEVICE_ALREADY_INITIALIZED = -201,
MA_DEVICE_NOT_STARTED = -202,
MA_DEVICE_NOT_STOPPED = -203,
MA_DEVICE_NOT_INITIALIZED = -300,
MA_DEVICE_ALREADY_INITIALIZED = -301,
MA_DEVICE_NOT_STARTED = -302,
MA_DEVICE_NOT_STOPPED = -303,
MA_FAILED_TO_INIT_BACKEND = -300,
MA_FAILED_TO_OPEN_BACKEND_DEVICE = -301,
MA_FAILED_TO_START_BACKEND_DEVICE = -302,
MA_FAILED_TO_STOP_BACKEND_DEVICE = -303
MA_FAILED_TO_INIT_BACKEND = -400,
MA_FAILED_TO_OPEN_BACKEND_DEVICE = -401,
MA_FAILED_TO_START_BACKEND_DEVICE = -402,
MA_FAILED_TO_STOP_BACKEND_DEVICE = -403
/*
Atomics.
These are typesafe structures to prevent errors as a result of forgetting to reference variables atomically. It's too
easy to introduce subtle bugs where you accidentally do a regular assignment instead of an atomic load/store, etc. By
using a struct we can enforce the use of atomics at compile time.
These types are declared in the header section because we need to reference them in structs below, but functions for
using them are only exposed in the implementation section. I do not want these to be part of the public API.
There's a few downsides to this system. The first is that you need to declare a new struct for each type. Below are
some macros to help with the declarations. They will be named like so:
ma_atomic_uint32 - atomic ma_uint32
ma_atomic_int32 - atomic ma_int32
ma_atomic_uint64 - atomic ma_uint64
ma_atomic_float - atomic float
ma_atomic_bool32 - atomic ma_bool32
The other downside is that atomic pointers are extremely messy. You need to declare a new struct for each specific
type of pointer you need to make atomic. For example, an atomic ma_node* will look like this:
MA_ATOMIC_SAFE_TYPE_IMPL_PTR(node)
Which will declare a type struct that's named like so:
ma_atomic_ptr_node
Functions to use the atomic types are declared in the implementation section. All atomic functions are prefixed with
the name of the struct. For example:
ma_atomic_uint32_set() - Atomic store of ma_uint32
ma_atomic_uint32_get() - Atomic load of ma_uint32
etc.
For pointer types it's the same, which makes them a bit messy to use due to the length of each function name, but in
return you get type safety and enforcement of atomic operations.
*/
#define MA_ATOMIC_SAFE_TYPE_DECL(c89TypeExtension, typeSize, type) \
typedef struct \
{ \
MA_ATOMIC(typeSize, ma_##type) value; \
} ma_atomic_##type; \
/* Thread priorities should be ordered such that the default priority of the worker thread is 0. */
typedef enum
{
ma_thread_priority_idle = -5,
ma_thread_priority_lowest = -4,
ma_thread_priority_low = -3,
ma_thread_priority_normal = -2,
ma_thread_priority_high = -1,
ma_thread_priority_highest = 0,
ma_thread_priority_realtime = 1,
ma_thread_priority_default = 0
} ma_thread_priority;
/* Thread priorities should be ordered such that the default priority of the worker thread is 0. */
typedef enum
{
ma_thread_priority_idle = -5,
ma_thread_priority_lowest = -4,
ma_thread_priority_low = -3,
ma_thread_priority_normal = -2,
ma_thread_priority_high = -1,
ma_thread_priority_highest = 0,
ma_thread_priority_realtime = 1,
ma_thread_priority_default = 0
} ma_thread_priority;
#if defined(MA_WIN32)
typedef ma_handle ma_event;
#endif
#if defined(MA_POSIX)
typedef struct
{
ma_uint32 value;
ma_pthread_mutex_t lock;
ma_pthread_cond_t cond;
} ma_event;
#endif /* MA_POSIX */
#if defined(MA_POSIX)
typedef struct
{
ma_uint32 value;
ma_pthread_mutex_t lock;
ma_pthread_cond_t cond;
} ma_event;
#elif defined(MA_WIN32)
typedef ma_handle ma_event;
#endif
#if defined(MA_WIN32)
typedef ma_handle ma_semaphore;
#endif
#if defined(MA_POSIX)
typedef struct
{
int value;
ma_pthread_mutex_t lock;
ma_pthread_cond_t cond;
} ma_semaphore;
#endif /* MA_POSIX */
#if defined(MA_POSIX)
typedef struct
{
int value;
ma_pthread_mutex_t lock;
ma_pthread_cond_t cond;
} ma_semaphore;
#elif defined(MA_WIN32)
typedef ma_handle ma_semaphore;
#endif
/* MA_NO_THREADING is set which means threading is disabled. Threading is required by some API families. If any of these are enabled we need to throw an error. */
#ifndef MA_NO_DEVICE_IO
#error "MA_NO_THREADING cannot be used without MA_NO_DEVICE_IO";
#endif
/* MA_NO_THREADING is set which means threading is disabled. Threading is required by some API families. If any of these are enabled we need to throw an error. */
#ifndef MA_NO_DEVICE_IO
#error "MA_NO_THREADING cannot be used without MA_NO_DEVICE_IO";
#endif
ma_uint64 cursorInFrames; /* The current time in frames. Incremented by ma_fader_process_pcm_frames(). */
ma_int64 cursorInFrames; /* The current time in frames. Incremented by ma_fader_process_pcm_frames(). Signed because it'll be offset by startOffsetInFrames in set_fade_ex(). */
MA_API float ma_fader_get_current_volume(ma_fader* pFader);
MA_API void ma_fader_set_fade_ex(ma_fader* pFader, float volumeBeg, float volumeEnd, ma_uint64 lengthInFrames, ma_int64 startOffsetInFrames);
MA_API float ma_fader_get_current_volume(const ma_fader* pFader);
ma_vec3f position; /* The absolute position of the listener. */
ma_vec3f direction; /* The direction the listener is facing. The world up vector is config.worldUp. */
ma_vec3f velocity;
ma_atomic_vec3f position; /* The absolute position of the listener. */
ma_atomic_vec3f direction; /* The direction the listener is facing. The world up vector is config.worldUp. */
ma_atomic_vec3f velocity;
float minSpatializationChannelGain; /* The minimal scaling factor to apply to channel gains when accounting for the direction of the sound relative to the listener. Must be in the range of 0..1. Smaller values means more aggressive directional panning, larger values means more subtle directional panning. */
/*
Find a channel position in the given channel map. Returns MA_TRUE if the channel is found; MA_FALSE otherwise. The
index of the channel is output to `pChannelIndex`.
The channel map buffer must have a capacity of at least `channels`.
*/
MA_API ma_bool32 ma_channel_map_find_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition, ma_uint32* pChannelIndex);
This is for printing and debugging purposes, not serialization/deserialization.
Returns the length of the string, not including the null terminator.
*/
MA_API size_t ma_channel_map_to_string(const ma_channel* pChannelMap, ma_uint32 channels, char* pBufferOut, size_t bufferCap);
/*
Retrieves a human readable version of a channel position.
*/
MA_API const char* ma_channel_position_to_string(ma_channel channel);
/************************************************************************************************************************************************************
Data Source
************************************************************************************************************************************************************/
typedef void ma_data_source;
#define MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT 0x00000001
typedef struct
{
ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
ma_result (* onSetLooping)(ma_data_source* pDataSource, ma_bool32 isLooping);
ma_uint32 flags;
} ma_data_source_vtable;
typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source* pDataSource);
typedef struct
{
const ma_data_source_vtable* vtable;
} ma_data_source_config;
MA_API ma_data_source_config ma_data_source_config_init(void);
typedef struct
{
const ma_data_source_vtable* vtable;
ma_uint64 rangeBegInFrames;
ma_uint64 rangeEndInFrames; /* Set to -1 for unranged (default). */
ma_uint64 loopBegInFrames; /* Relative to rangeBegInFrames. */
ma_uint64 loopEndInFrames; /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
ma_data_source* pCurrent; /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
ma_data_source* pNext; /* When set to NULL, onGetNext will be used. */
ma_data_source_get_next_proc onGetNext; /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
MA_ATOMIC(4, ma_bool32) isLooping;
} ma_data_source_base;
MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_data_source* pDataSource);
MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
MA_API ma_result ma_data_source_get_cursor_in_seconds(ma_data_source* pDataSource, float* pCursor);
MA_API ma_result ma_data_source_get_length_in_seconds(ma_data_source* pDataSource, float* pLength);
MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool32 isLooping);
MA_API ma_bool32 ma_data_source_is_looping(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
MA_API ma_data_source* ma_data_source_get_current(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
MA_API ma_data_source* ma_data_source_get_next(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(const ma_data_source* pDataSource);
typedef struct
{
ma_data_source_base ds;
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint64 cursor;
ma_uint64 sizeInFrames;
const void* pData;
} ma_audio_buffer_ref;
MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, const void* pData, ma_uint64 sizeInFrames, ma_audio_buffer_ref* pAudioBufferRef);
MA_API void ma_audio_buffer_ref_uninit(ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint64 sizeInFrames;
const void* pData; /* If set to NULL, will allocate a block of memory for you. */
ma_allocation_callbacks allocationCallbacks;
} ma_audio_buffer_config;
MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint64 sizeInFrames, const void* pData, const ma_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
ma_audio_buffer_ref ref;
ma_allocation_callbacks allocationCallbacks;
ma_bool32 ownsData; /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
ma_uint8 _pExtraData[1]; /* For allocating a buffer with the memory located directly after the other memory of the structure. */
} ma_audio_buffer;
MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_alloc_and_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer** ppAudioBuffer); /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);
/*
Paged Audio Buffer
==================
A paged audio buffer is made up of a linked list of pages. It's expandable, but not shrinkable. It
can be used for cases where audio data is streamed in asynchronously while allowing data to be read
at the same time.
This is lock-free, but not 100% thread safe. You can append a page and read from the buffer across
simultaneously across different threads, however only one thread at a time can append, and only one
thread at a time can read and seek.
*/
typedef struct ma_paged_audio_buffer_page ma_paged_audio_buffer_page;
struct ma_paged_audio_buffer_page
{
MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pNext;
ma_uint64 sizeInFrames;
ma_uint8 pAudioData[1];
};
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_paged_audio_buffer_page head; /* Dummy head for the lock-free algorithm. Always has a size of 0. */
MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pTail; /* Never null. Initially set to &head. */
} ma_paged_audio_buffer_data;
MA_API ma_result ma_paged_audio_buffer_data_init(ma_format format, ma_uint32 channels, ma_paged_audio_buffer_data* pData);
MA_API void ma_paged_audio_buffer_data_uninit(ma_paged_audio_buffer_data* pData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_head(ma_paged_audio_buffer_data* pData);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_tail(ma_paged_audio_buffer_data* pData);
MA_API ma_result ma_paged_audio_buffer_data_get_length_in_pcm_frames(ma_paged_audio_buffer_data* pData, ma_uint64* pLength);
MA_API ma_result ma_paged_audio_buffer_data_allocate_page(ma_paged_audio_buffer_data* pData, ma_uint64 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks, ma_paged_audio_buffer_page** ppPage);
MA_API ma_result ma_paged_audio_buffer_data_free_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_paged_audio_buffer_data_append_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage);
MA_API ma_result ma_paged_audio_buffer_data_allocate_and_append_page(ma_paged_audio_buffer_data* pData, ma_uint32 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
ma_paged_audio_buffer_data* pData; /* Must not be null. */
} ma_paged_audio_buffer_config;
MA_API ma_paged_audio_buffer_config ma_paged_audio_buffer_config_init(ma_paged_audio_buffer_data* pData);
typedef struct
{
ma_data_source_base ds;
ma_paged_audio_buffer_data* pData; /* Audio data is read from here. Cannot be null. */
ma_paged_audio_buffer_page* pCurrent;
ma_uint64 relativeCursor; /* Relative to the current page. */
ma_uint64 absoluteCursor;
} ma_paged_audio_buffer;
MA_API ma_result ma_paged_audio_buffer_init(const ma_paged_audio_buffer_config* pConfig, ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API void ma_paged_audio_buffer_uninit(ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API ma_result ma_paged_audio_buffer_read_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead); /* Returns MA_AT_END if no more pages available. */
MA_API ma_result ma_paged_audio_buffer_seek_to_pcm_frame(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_paged_audio_buffer_get_cursor_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pLength);
#define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */
/* Don't enable JACK here if compiling with Cosmopolitan. It'll be enabled in the Linux section below. */
#if !defined(__COSMOPOLITAN__)
#define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */
#endif
ma_aaudio_usage_announcement, /* AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT */
ma_aaudio_usage_emergency, /* AAUDIO_SYSTEM_USAGE_EMERGENCY */
ma_aaudio_usage_safety, /* AAUDIO_SYSTEM_USAGE_SAFETY */
ma_aaudio_usage_vehicle_status, /* AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS */
ma_aaudio_usage_media, /* AAUDIO_USAGE_MEDIA */
ma_aaudio_usage_voice_communication, /* AAUDIO_USAGE_VOICE_COMMUNICATION */
ma_aaudio_usage_voice_communication_signalling, /* AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING */
ma_aaudio_usage_game, /* AAUDIO_USAGE_GAME */
ma_aaudio_usage_media, /* AAUDIO_USAGE_MEDIA */
ma_aaudio_usage_notification, /* AAUDIO_USAGE_NOTIFICATION */
ma_aaudio_usage_notification_event, /* AAUDIO_USAGE_NOTIFICATION_EVENT */
ma_aaudio_usage_notification_ringtone, /* AAUDIO_USAGE_NOTIFICATION_RINGTONE */
ma_aaudio_usage_voice_communication, /* AAUDIO_USAGE_VOICE_COMMUNICATION */
ma_aaudio_usage_voice_communication_signalling /* AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING */
ma_aaudio_usage_emergency, /* AAUDIO_SYSTEM_USAGE_EMERGENCY */
ma_aaudio_usage_safety, /* AAUDIO_SYSTEM_USAGE_SAFETY */
ma_aaudio_usage_vehicle_status, /* AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS */
ma_aaudio_usage_announcement /* AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT */
ma_aaudio_content_type_music, /* AAUDIO_CONTENT_TYPE_MUSIC */
ma_aaudio_content_type_sonification, /* AAUDIO_CONTENT_TYPE_SONIFICATION */
ma_aaudio_content_type_speech /* AAUDIO_CONTENT_TYPE_SPEECH */
ma_aaudio_content_type_sonification /* AAUDIO_CONTENT_TYPE_SONIFICATION */
typedef enum
{
ma_aaudio_allow_capture_default = 0, /* Leaves the allowed capture policy unset. */
ma_aaudio_allow_capture_by_all, /* AAUDIO_ALLOW_CAPTURE_BY_ALL */
ma_aaudio_allow_capture_by_system, /* AAUDIO_ALLOW_CAPTURE_BY_SYSTEM */
ma_aaudio_allow_capture_by_none /* AAUDIO_ALLOW_CAPTURE_BY_NONE */
} ma_aaudio_allowed_capture_policy;
ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
ma_bool8 noAutoStreamRouting; /* Disables automatic stream routing. */
ma_bool8 noHardwareOffloading; /* Disables WASAPI's hardware offloading feature. */
ma_wasapi_usage usage; /* When configured, uses Avrt APIs to set the thread characteristics. */
ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
ma_bool8 noAutoStreamRouting; /* Disables automatic stream routing. */
ma_bool8 noHardwareOffloading; /* Disables WASAPI's hardware offloading feature. */
ma_uint32 loopbackProcessID; /* The process ID to include or exclude for loopback mode. Set to 0 to capture audio from all processes. Ignored when an explicit device ID is specified. */
ma_bool8 loopbackProcessExclude; /* When set to true, excludes the process specified by loopbackProcessID. By default, the process will be included. */
sample rate will need to be determined before calculating the period size in frames. On output, all members of the `ma_device_data_format`
sample rate will need to be determined before calculating the period size in frames. On output, all members of the `ma_device_descriptor`
encounted. Do not start or stop the device here. That will be handled from outside the `onDeviceDataLoop()` callback.
encountered. Do not start or stop the device here. That will be handled from outside the `onDeviceDataLoop()` callback.
ma_handle pthreadSO;
ma_proc pthread_create;
ma_proc pthread_join;
ma_proc pthread_mutex_init;
ma_proc pthread_mutex_destroy;
ma_proc pthread_mutex_lock;
ma_proc pthread_mutex_unlock;
ma_proc pthread_cond_init;
ma_proc pthread_cond_destroy;
ma_proc pthread_cond_wait;
ma_proc pthread_cond_signal;
ma_proc pthread_attr_init;
ma_proc pthread_attr_destroy;
ma_proc pthread_attr_setschedpolicy;
ma_proc pthread_attr_getschedparam;
ma_proc pthread_attr_setschedparam;
int _unused;
MA_ATOMIC(4, ma_device_state) state; /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
ma_atomic_device_state state; /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
MA_ATOMIC(4, float) masterVolumeFactor; /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
ma_atomic_float masterVolumeFactor; /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
MA_ATOMIC(4, ma_bool32) isStartedCapture; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
MA_ATOMIC(4, ma_bool32) isStartedPlayback; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
ma_atomic_bool32 isStartedCapture; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
ma_atomic_bool32 isStartedPlayback; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
ma_uint32 loopbackProcessID;
ma_bool8 loopbackProcessExclude;
int indexPlayback; /* We use a factory on the JavaScript side to manage devices and use an index for JS/C interop. */
int indexCapture;
/* AudioWorklets path. */
/* EMSCRIPTEN_WEBAUDIO_T */ int audioContext;
/* EMSCRIPTEN_WEBAUDIO_T */ int audioWorklet;
float* pIntermediaryBuffer;
void* pStackBuffer;
ma_result initResult; /* Set to MA_BUSY while initialization is in progress. */
int deviceIndex; /* We store the device in a list on the JavaScript side. This is used to map our C object to the JS object. */
MA_ATOMIC(4, ma_bool32) isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */
ma_atomic_bool32 isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */
Allows miniaudio to fire the data callback with any frame count. When this is set to true, the data callback will be fired with a consistent frame
count as specified by `periodSizeInFrames` or `periodSizeInMilliseconds`. When set to false, miniaudio will fire the callback with whatever the
backend requests, which could be anything.
Allows miniaudio to fire the data callback with any frame count. When this is set to false (the default), the data callback will be fired with a
consistent frame count as specified by `periodSizeInFrames` or `periodSizeInMilliseconds`. When set to true, miniaudio will fire the callback with
whatever the backend requests, which could be anything.
The linear resampler applies a low-pass filter as part of it's procesing for anti-aliasing. This setting controls the order of the filter. The higher
The linear resampler applies a low-pass filter as part of it's processing for anti-aliasing. This setting controls the order of the filter. The higher
/**************************************************************************************************
Data Source
**************************************************************************************************/
typedef void ma_data_source;
#define MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT 0x00000001
typedef struct
{
ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
ma_result (* onSetLooping)(ma_data_source* pDataSource, ma_bool32 isLooping);
ma_uint32 flags;
} ma_data_source_vtable;
typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source* pDataSource);
typedef struct
{
const ma_data_source_vtable* vtable;
} ma_data_source_config;
MA_API ma_data_source_config ma_data_source_config_init(void);
typedef struct
{
const ma_data_source_vtable* vtable;
ma_uint64 rangeBegInFrames;
ma_uint64 rangeEndInFrames; /* Set to -1 for unranged (default). */
ma_uint64 loopBegInFrames; /* Relative to rangeBegInFrames. */
ma_uint64 loopEndInFrames; /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
ma_data_source* pCurrent; /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
ma_data_source* pNext; /* When set to NULL, onGetNext will be used. */
ma_data_source_get_next_proc onGetNext; /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
MA_ATOMIC(4, ma_bool32) isLooping;
} ma_data_source_base;
MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_data_source* pDataSource);
MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
MA_API ma_result ma_data_source_get_cursor_in_seconds(ma_data_source* pDataSource, float* pCursor);
MA_API ma_result ma_data_source_get_length_in_seconds(ma_data_source* pDataSource, float* pLength);
MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool32 isLooping);
MA_API ma_bool32 ma_data_source_is_looping(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
MA_API ma_data_source* ma_data_source_get_current(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
MA_API ma_data_source* ma_data_source_get_next(const ma_data_source* pDataSource);
MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(const ma_data_source* pDataSource);
typedef struct
{
ma_data_source_base ds;
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint64 cursor;
ma_uint64 sizeInFrames;
const void* pData;
} ma_audio_buffer_ref;
MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, const void* pData, ma_uint64 sizeInFrames, ma_audio_buffer_ref* pAudioBufferRef);
MA_API void ma_audio_buffer_ref_uninit(ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint64 sizeInFrames;
const void* pData; /* If set to NULL, will allocate a block of memory for you. */
ma_allocation_callbacks allocationCallbacks;
} ma_audio_buffer_config;
MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint64 sizeInFrames, const void* pData, const ma_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
ma_audio_buffer_ref ref;
ma_allocation_callbacks allocationCallbacks;
ma_bool32 ownsData; /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
ma_uint8 _pExtraData[1]; /* For allocating a buffer with the memory located directly after the other memory of the structure. */
} ma_audio_buffer;
MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_alloc_and_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer** ppAudioBuffer); /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer);
MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength);
MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);
Paged Audio Buffer
==================
A paged audio buffer is made up of a linked list of pages. It's expandable, but not shrinkable. It
can be used for cases where audio data is streamed in asynchronously while allowing data to be read
at the same time.
Mixes the specified number of frames in floating point format with a volume factor.
This is lock-free, but not 100% thread safe. You can append a page and read from the buffer across
simultaneously across different threads, however only one thread at a time can append, and only one
thread at a time can read and seek.
This will run on an optimized path when the volume is equal to 1.
typedef struct ma_paged_audio_buffer_page ma_paged_audio_buffer_page;
struct ma_paged_audio_buffer_page
{
MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pNext;
ma_uint64 sizeInFrames;
ma_uint8 pAudioData[1];
};
MA_API ma_result ma_mix_pcm_frames_f32(float* pDst, const float* pSrc, ma_uint64 frameCount, ma_uint32 channels, float volume);
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_paged_audio_buffer_page head; /* Dummy head for the lock-free algorithm. Always has a size of 0. */
MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pTail; /* Never null. Initially set to &head. */
} ma_paged_audio_buffer_data;
MA_API ma_result ma_paged_audio_buffer_data_init(ma_format format, ma_uint32 channels, ma_paged_audio_buffer_data* pData);
MA_API void ma_paged_audio_buffer_data_uninit(ma_paged_audio_buffer_data* pData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_head(ma_paged_audio_buffer_data* pData);
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_tail(ma_paged_audio_buffer_data* pData);
MA_API ma_result ma_paged_audio_buffer_data_get_length_in_pcm_frames(ma_paged_audio_buffer_data* pData, ma_uint64* pLength);
MA_API ma_result ma_paged_audio_buffer_data_allocate_page(ma_paged_audio_buffer_data* pData, ma_uint64 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks, ma_paged_audio_buffer_page** ppPage);
MA_API ma_result ma_paged_audio_buffer_data_free_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_result ma_paged_audio_buffer_data_append_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage);
MA_API ma_result ma_paged_audio_buffer_data_allocate_and_append_page(ma_paged_audio_buffer_data* pData, ma_uint32 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks);
typedef struct
{
ma_paged_audio_buffer_data* pData; /* Must not be null. */
} ma_paged_audio_buffer_config;
MA_API ma_paged_audio_buffer_config ma_paged_audio_buffer_config_init(ma_paged_audio_buffer_data* pData);
typedef struct
{
ma_data_source_base ds;
ma_paged_audio_buffer_data* pData; /* Audio data is read from here. Cannot be null. */
ma_paged_audio_buffer_page* pCurrent;
ma_uint64 relativeCursor; /* Relative to the current page. */
ma_uint64 absoluteCursor;
} ma_paged_audio_buffer;
MA_API ma_result ma_paged_audio_buffer_init(const ma_paged_audio_buffer_config* pConfig, ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API void ma_paged_audio_buffer_uninit(ma_paged_audio_buffer* pPagedAudioBuffer);
MA_API ma_result ma_paged_audio_buffer_read_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead); /* Returns MA_AT_END if no more pages available. */
MA_API ma_result ma_paged_audio_buffer_seek_to_pcm_frame(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64 frameIndex);
MA_API ma_result ma_paged_audio_buffer_get_cursor_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pCursor);
MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pLength);
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
double dutyCycle;
double amplitude;
double frequency;
} ma_pulsewave_config;
MA_API ma_pulsewave_config ma_pulsewave_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double dutyCycle, double amplitude, double frequency);
typedef struct
{
ma_waveform waveform;
ma_pulsewave_config config;
} ma_pulsewave;
MA_API ma_result ma_pulsewave_init(const ma_pulsewave_config* pConfig, ma_pulsewave* pWaveform);
MA_API void ma_pulsewave_uninit(ma_pulsewave* pWaveform);
MA_API ma_result ma_pulsewave_read_pcm_frames(ma_pulsewave* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_pulsewave_seek_to_pcm_frame(ma_pulsewave* pWaveform, ma_uint64 frameIndex);
MA_API ma_result ma_pulsewave_set_amplitude(ma_pulsewave* pWaveform, double amplitude);
MA_API ma_result ma_pulsewave_set_frequency(ma_pulsewave* pWaveform, double frequency);
MA_API ma_result ma_pulsewave_set_sample_rate(ma_pulsewave* pWaveform, ma_uint32 sampleRate);
MA_API ma_result ma_pulsewave_set_duty_cycle(ma_pulsewave* pWaveform, double dutyCycle);
ma_bool32 isConnectorInitialized; /* Used for asynchronous loading to ensure we don't try to initialize the connector multiple times while waiting for the node to fully load. */
ma_atomic_bool32 isConnectorInitialized; /* Used for asynchronous loading to ensure we don't try to initialize the connector multiple times while waiting for the node to fully load. */
MA_ATOMIC(1, ma_uint8) inputNodeInputBusIndex; /* The index of the input bus on the input. Required for detaching. */
ma_uint8 inputNodeInputBusIndex; /* The index of the input bus on the input. Required for detaching. Will only be used within the spinlock so does not need to be atomic. */
/* Splitter Node. 1 input, 2 outputs. Used for splitting/copying a stream so it can be as input into two separate output nodes. */
/* Splitter Node. 1 input, many outputs. Used for splitting/copying a stream so it can be as input into two separate output nodes. */
MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT = 0x00000010, /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
MA_SOUND_FLAG_NO_PITCH = 0x00000020, /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
MA_SOUND_FLAG_NO_SPATIALIZATION = 0x00000040 /* Disable spatialization. */
MA_SOUND_FLAG_UNKNOWN_LENGTH = 0x00000010, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
/* ma_sound specific flags. */
MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT = 0x00001000, /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
MA_SOUND_FLAG_NO_PITCH = 0x00002000, /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
MA_SOUND_FLAG_NO_SPATIALIZATION = 0x00004000 /* Disable spatialization. */
ma_bool8 isPitchDisabled; /* Pitching can be explicitly disable with MA_SOUND_FLAG_NO_PITCH to optimize processing. */
ma_uint32 volumeSmoothTimeInPCMFrames; /* The number of frames to smooth over volume changes. Defaults to 0 in which case no smoothing is used. */
ma_mono_expansion_mode monoExpansionMode;
ma_bool8 isPitchDisabled; /* Pitching can be explicitly disabled with MA_SOUND_FLAG_NO_PITCH to optimize processing. */
/* When setting a fade, it's not done immediately in ma_sound_set_fade(). It's deferred to the audio thread which means we need to store the settings here. */
struct
{
ma_atomic_float volumeBeg;
ma_atomic_float volumeEnd;
ma_atomic_uint64 fadeLengthInFrames; /* <-- Defaults to (~(ma_uint64)0) which is used to indicate that no fade should be applied. */
ma_atomic_uint64 absoluteGlobalTimeInFrames; /* <-- The time to start the fade. */
} fadeSettings;
ma_fence* pDoneFence; /* Released when the resource manager has finished decoding the entire sound. Not used with streams. */
ma_sound_end_proc endCallback; /* Fired when the sound reaches the end. Will be fired from the audio thread. Do not restart, uninitialize or otherwise change the state of the sound from here. Instead fire an event or set a variable to indicate to a different thread to change the start of the sound. Will not be fired in response to a scheduled stop with ma_sound_set_stop_time_*(). */
void* pEndCallbackUserData;
#ifndef MA_NO_RESOURCE_MANAGER
ma_resource_manager_pipeline_notifications initNotifications;
#endif
ma_fence* pDoneFence; /* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
MA_API ma_sound_config ma_sound_config_init(void);
MA_API ma_sound_config ma_sound_config_init(void); /* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
MA_API ma_sound_config ma_sound_config_init_2(ma_engine* pEngine); /* Will be renamed to ma_sound_config_init() in version 0.12. */
MA_API ma_sound_group_config ma_sound_group_config_init(void);
MA_API ma_sound_group_config ma_sound_group_config_init(void); /* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
MA_API ma_sound_group_config ma_sound_group_config_init_2(ma_engine* pEngine); /* Will be renamed to ma_sound_config_init() in version 0.12. */
ma_device* pDevice; /* If set, the caller is responsible for calling ma_engine_data_callback() in the device's data callback. */
ma_device_id* pPlaybackDeviceID; /* The ID of the playback device to use with the default listener. */
ma_device* pDevice; /* If set, the caller is responsible for calling ma_engine_data_callback() in the device's data callback. */
ma_device_id* pPlaybackDeviceID; /* The ID of the playback device to use with the default listener. */
ma_device_data_proc dataCallback; /* Can be null. Can be used to provide a custom device data callback. */
ma_device_notification_proc notificationCallback;
ma_log* pLog; /* When set to NULL, will use the context's log. */
ma_uint32 listenerCount; /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
ma_uint32 channels; /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
ma_uint32 sampleRate; /* The sample rate. When set to 0 will use the native channel count of the device. */
ma_uint32 periodSizeInFrames; /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
ma_uint32 periodSizeInMilliseconds; /* Used if periodSizeInFrames is unset. */
ma_uint32 gainSmoothTimeInFrames; /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
ma_uint32 gainSmoothTimeInMilliseconds; /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
ma_log* pLog; /* When set to NULL, will use the context's log. */
ma_uint32 listenerCount; /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
ma_uint32 channels; /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
ma_uint32 sampleRate; /* The sample rate. When set to 0 will use the native channel count of the device. */
ma_uint32 periodSizeInFrames; /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
ma_uint32 periodSizeInMilliseconds; /* Used if periodSizeInFrames is unset. */
ma_uint32 gainSmoothTimeInFrames; /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
ma_uint32 gainSmoothTimeInMilliseconds; /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
ma_uint32 defaultVolumeSmoothTimeInPCMFrames; /* Defaults to 0. Controls the default amount of smoothing to apply to volume changes to sounds. High values means more smoothing at the expense of high latency (will take longer to reach the new volume). */
ma_bool32 noAutoStart; /* When set to true, requires an explicit call to ma_engine_start(). This is false by default, meaning the engine will be started automatically in ma_engine_init(). */
ma_bool32 noDevice; /* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
ma_mono_expansion_mode monoExpansionMode; /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
ma_vfs* pResourceManagerVFS; /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */
ma_bool32 noAutoStart; /* When set to true, requires an explicit call to ma_engine_start(). This is false by default, meaning the engine will be started automatically in ma_engine_init(). */
ma_bool32 noDevice; /* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
ma_mono_expansion_mode monoExpansionMode; /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
ma_vfs* pResourceManagerVFS; /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */
ma_engine_process_proc onProcess; /* Fired at the end of each call to ma_engine_read_pcm_frames(). For engine's that manage their own internal device (the default configuration), this will be fired from the audio thread, and you do not need to call ma_engine_read_pcm_frames() manually in order to trigger this. */
void* pProcessUserData; /* User data that's passed into onProcess. */
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine);
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime);
MA_API ma_uint64 ma_engine_get_time_in_pcm_frames(const ma_engine* pEngine);
MA_API ma_uint64 ma_engine_get_time_in_milliseconds(const ma_engine* pEngine);
MA_API ma_result ma_engine_set_time_in_pcm_frames(ma_engine* pEngine, ma_uint64 globalTime);
MA_API ma_result ma_engine_set_time_in_milliseconds(ma_engine* pEngine, ma_uint64 globalTime);
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine); /* Deprecated. Use ma_engine_get_time_in_pcm_frames(). Will be removed in version 0.12. */
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime); /* Deprecated. Use ma_engine_set_time_in_pcm_frames(). Will be removed in version 0.12. */
MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */
MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */
MA_API float ma_sound_get_current_fade_volume(ma_sound* pSound);
MA_API void ma_sound_set_fade_start_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames, ma_uint64 absoluteGlobalTimeInFrames);
MA_API void ma_sound_set_fade_start_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds, ma_uint64 absoluteGlobalTimeInMilliseconds);
MA_API float ma_sound_get_current_fade_volume(const ma_sound* pSound);
MA_API void ma_sound_set_stop_time_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInFrames, ma_uint64 fadeLengthInFrames);
MA_API void ma_sound_set_stop_time_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInMilliseconds, ma_uint64 fadeLengthInMilliseconds);
#include <limits.h> /* For INT_MAX */
#include <math.h> /* sin(), etc. */
#include <limits.h> /* For INT_MAX */
#include <math.h> /* sin(), etc. */
#include <stdlib.h> /* For malloc(), free(), wcstombs(). */
#include <string.h> /* For memset() */
#ifdef MA_WIN32
#include <windows.h>
#else
#include <stdlib.h> /* For malloc(), free(), wcstombs(). */
#include <string.h> /* For memset() */
#if defined(MA_WIN32)
#include <windows.h>
/*
There's a possibility that WIN32_LEAN_AND_MEAN has been defined which will exclude some symbols
such as STGM_READ and CLSCTL_ALL. We need to check these and define them ourselves if they're
unavailable.
*/
#ifndef STGM_READ
#define STGM_READ 0x00000000L
#endif
#ifndef CLSCTX_ALL
#define CLSCTX_ALL 23
#endif
/* IUnknown is used by both the WASAPI and DirectSound backends. It easier to just declare our version here. */
typedef struct ma_IUnknown ma_IUnknown;
#endif
#if !defined(MA_WIN32)
#define MA_SIMD_NONE 0
#define MA_SIMD_SSE2 1
#define MA_SIMD_AVX2 2
#define MA_SIMD_NEON 3
#ifndef MA_PREFERRED_SIMD
# if defined(MA_SUPPORT_SSE2) && defined(MA_PREFER_SSE2)
#define MA_PREFERRED_SIMD MA_SIMD_SSE2
#elif defined(MA_SUPPORT_AVX2) && defined(MA_PREFER_AVX2)
#define MA_PREFERRED_SIMD MA_SIMD_AVX2
#elif defined(MA_SUPPORT_NEON) && defined(MA_PREFER_NEON)
#define MA_PREFERRED_SIMD MA_SIMD_NEON
#else
#define MA_PREFERRED_SIMD MA_SIMD_NONE
#endif
#endif
#if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
#if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
#if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
#if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
#ifdef MA_WIN32
#define MA_REALLOC(p, sz) (((sz) > 0) ? ((p) ? HeapReAlloc(GetProcessHeap(), 0, (p), (sz)) : HeapAlloc(GetProcessHeap(), 0, (sz))) : ((VOID*)(size_t)(HeapFree(GetProcessHeap(), 0, (p)) & 0)))
#else
#define MA_REALLOC(p, sz) realloc((p), (sz))
#define MA_REALLOC(p, sz) realloc((p), (sz))
#ifndef MA_FREE
#ifdef MA_WIN32
#define MA_FREE(p) HeapFree(GetProcessHeap(), 0, (p))
#else
#define MA_FREE(p) free((p))
#endif
#endif
static MA_INLINE void ma_zero_memory_default(void* p, size_t sz)
{
if (p == NULL) {
MA_ASSERT(sz == 0); /* If this is triggered there's an error with the calling code. */
return;
}
if (sz > 0) {
memset(p, 0, sz);
}
}
#ifdef MA_WIN32
#define MA_MOVE_MEMORY(dst, src, sz) MoveMemory((dst), (src), (sz))
#else
#define MA_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz))
#endif
#endif
#ifndef MA_ASSERT
#ifdef MA_WIN32
#define MA_ASSERT(condition) assert(condition)
#else
#define MA_ASSERT(condition) assert(condition)
#endif
#define MA_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz))
#define ma_countof(x) (sizeof(x) / sizeof(x[0]))
#define ma_max(x, y) (((x) > (y)) ? (x) : (y))
#define ma_min(x, y) (((x) < (y)) ? (x) : (y))
#define ma_abs(x) (((x) > 0) ? (x) : -(x))
#define ma_clamp(x, lo, hi) (ma_max(lo, ma_min(x, hi)))
#define ma_offset_ptr(p, offset) (((ma_uint8*)(p)) + (offset))
#define ma_align(x, a) ((x + (a-1)) & ~(a-1))
#define ma_align_64(x) ma_align(x, 8)
#define ma_countof(x) (sizeof(x) / sizeof(x[0]))
#define ma_max(x, y) (((x) > (y)) ? (x) : (y))
#define ma_min(x, y) (((x) < (y)) ? (x) : (y))
#define ma_abs(x) (((x) > 0) ? (x) : -(x))
#define ma_clamp(x, lo, hi) (ma_max(lo, ma_min(x, hi)))
#define ma_offset_ptr(p, offset) (((ma_uint8*)(p)) + (offset))
#define ma_align(x, a) ((x + (a-1)) & ~(a-1))
#define ma_align_64(x) ma_align(x, 8)
https://web.archive.org/web/20221211012522/https://stackoverflow.com/questions/32687079/getting-fewest-instructions-for-rsqrtss-wrapper
I'm going to do something similar here, but a bit simpler.
*/
#if defined(__GNUC__) || defined(__clang__)
{
float result;
__asm__ __volatile__("rsqrtss %1, %0" : "=x"(result) : "x"(x));
return result;
}
#else
{
return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ps1(x)));
}
#endif
}
#else
{
return 1 / (float)ma_sqrtd(x);
}
#endif
}
switch (e)
{
case 0: return MA_SUCCESS;
#ifdef EPERM
case EPERM: return MA_INVALID_OPERATION;
#endif
#ifdef ENOENT
case ENOENT: return MA_DOES_NOT_EXIST;
#endif
#ifdef ESRCH
case ESRCH: return MA_DOES_NOT_EXIST;
#endif
#ifdef EINTR
case EINTR: return MA_INTERRUPT;
#endif
#ifdef EIO
case EIO: return MA_IO_ERROR;
#endif
#ifdef ENXIO
case ENXIO: return MA_DOES_NOT_EXIST;
#endif
#ifdef E2BIG
case E2BIG: return MA_INVALID_ARGS;
#endif
#ifdef ENOEXEC
case ENOEXEC: return MA_INVALID_FILE;
#endif
#ifdef EBADF
case EBADF: return MA_INVALID_FILE;
#endif
#ifdef ECHILD
case ECHILD: return MA_ERROR;
#endif
#ifdef EAGAIN
case EAGAIN: return MA_UNAVAILABLE;
#endif
#ifdef ENOMEM
case ENOMEM: return MA_OUT_OF_MEMORY;
#endif
#ifdef EACCES
case EACCES: return MA_ACCESS_DENIED;
#endif
#ifdef EFAULT
case EFAULT: return MA_BAD_ADDRESS;
#endif
#ifdef ENOTBLK
case ENOTBLK: return MA_ERROR;
#endif
#ifdef EBUSY
case EBUSY: return MA_BUSY;
#endif
#ifdef EEXIST
case EEXIST: return MA_ALREADY_EXISTS;
#endif
#ifdef EXDEV
case EXDEV: return MA_ERROR;
#endif
#ifdef ENODEV
case ENODEV: return MA_DOES_NOT_EXIST;
#endif
#ifdef ENOTDIR
case ENOTDIR: return MA_NOT_DIRECTORY;
#endif
#ifdef EISDIR
case EISDIR: return MA_IS_DIRECTORY;
#endif
#ifdef EINVAL
case EINVAL: return MA_INVALID_ARGS;
#endif
#ifdef ENFILE
case ENFILE: return MA_TOO_MANY_OPEN_FILES;
#endif
#ifdef EMFILE
case EMFILE: return MA_TOO_MANY_OPEN_FILES;
#endif
#ifdef ENOTTY
case ENOTTY: return MA_INVALID_OPERATION;
#endif
#ifdef ETXTBSY
case ETXTBSY: return MA_BUSY;
#endif
#ifdef EFBIG
case EFBIG: return MA_TOO_BIG;
#endif
#ifdef ENOSPC
case ENOSPC: return MA_NO_SPACE;
#endif
#ifdef ESPIPE
case ESPIPE: return MA_BAD_SEEK;
#endif
#ifdef EROFS
case EROFS: return MA_ACCESS_DENIED;
#endif
#ifdef EMLINK
case EMLINK: return MA_TOO_MANY_LINKS;
#endif
#ifdef EPIPE
case EPIPE: return MA_BAD_PIPE;
#endif
#ifdef EDOM
case EDOM: return MA_OUT_OF_RANGE;
#endif
#ifdef ERANGE
case ERANGE: return MA_OUT_OF_RANGE;
#endif
#ifdef EDEADLK
case EDEADLK: return MA_DEADLOCK;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG: return MA_PATH_TOO_LONG;
#endif
#ifdef ENOLCK
case ENOLCK: return MA_ERROR;
#endif
#ifdef ENOSYS
case ENOSYS: return MA_NOT_IMPLEMENTED;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY: return MA_DIRECTORY_NOT_EMPTY;
#endif
#ifdef ELOOP
case ELOOP: return MA_TOO_MANY_LINKS;
#endif
#ifdef ENOMSG
case ENOMSG: return MA_NO_MESSAGE;
#endif
#ifdef EIDRM
case EIDRM: return MA_ERROR;
#endif
#ifdef ECHRNG
case ECHRNG: return MA_ERROR;
#endif
#ifdef EL2NSYNC
case EL2NSYNC: return MA_ERROR;
#endif
#ifdef EL3HLT
case EL3HLT: return MA_ERROR;
#endif
#ifdef EL3RST
case EL3RST: return MA_ERROR;
#endif
#ifdef ELNRNG
case ELNRNG: return MA_OUT_OF_RANGE;
#endif
#ifdef EUNATCH
case EUNATCH: return MA_ERROR;
#endif
#ifdef ENOCSI
case ENOCSI: return MA_ERROR;
#endif
#ifdef EL2HLT
case EL2HLT: return MA_ERROR;
#endif
#ifdef EBADE
case EBADE: return MA_ERROR;
#endif
#ifdef EBADR
case EBADR: return MA_ERROR;
#endif
#ifdef EXFULL
case EXFULL: return MA_ERROR;
#endif
#ifdef ENOANO
case ENOANO: return MA_ERROR;
#endif
#ifdef EBADRQC
case EBADRQC: return MA_ERROR;
#endif
#ifdef EBADSLT
case EBADSLT: return MA_ERROR;
#endif
#ifdef EBFONT
case EBFONT: return MA_INVALID_FILE;
#endif
#ifdef ENOSTR
case ENOSTR: return MA_ERROR;
#endif
#ifdef ENODATA
case ENODATA: return MA_NO_DATA_AVAILABLE;
#endif
#ifdef ETIME
case ETIME: return MA_TIMEOUT;
#endif
#ifdef ENOSR
case ENOSR: return MA_NO_DATA_AVAILABLE;
#endif
#ifdef ENONET
case ENONET: return MA_NO_NETWORK;
#endif
#ifdef ENOPKG
case ENOPKG: return MA_ERROR;
#endif
#ifdef EREMOTE
case EREMOTE: return MA_ERROR;
#endif
#ifdef ENOLINK
case ENOLINK: return MA_ERROR;
#endif
#ifdef EADV
case EADV: return MA_ERROR;
#endif
#ifdef ESRMNT
case ESRMNT: return MA_ERROR;
#endif
#ifdef ECOMM
case ECOMM: return MA_ERROR;
#endif
#ifdef EPROTO
case EPROTO: return MA_ERROR;
#endif
#ifdef EMULTIHOP
case EMULTIHOP: return MA_ERROR;
#endif
#ifdef EDOTDOT
case EDOTDOT: return MA_ERROR;
#endif
#ifdef EBADMSG
case EBADMSG: return MA_BAD_MESSAGE;
#endif
#ifdef EOVERFLOW
case EOVERFLOW: return MA_TOO_BIG;
#endif
#ifdef ENOTUNIQ
case ENOTUNIQ: return MA_NOT_UNIQUE;
#endif
#ifdef EBADFD
case EBADFD: return MA_ERROR;
#endif
#ifdef EREMCHG
case EREMCHG: return MA_ERROR;
#endif
#ifdef ELIBACC
case ELIBACC: return MA_ACCESS_DENIED;
#endif
#ifdef ELIBBAD
case ELIBBAD: return MA_INVALID_FILE;
#endif
#ifdef ELIBSCN
case ELIBSCN: return MA_INVALID_FILE;
#endif
#ifdef ELIBMAX
case ELIBMAX: return MA_ERROR;
#endif
#ifdef ELIBEXEC
case ELIBEXEC: return MA_ERROR;
#endif
#ifdef EILSEQ
case EILSEQ: return MA_INVALID_DATA;
#endif
#ifdef ERESTART
case ERESTART: return MA_ERROR;
#endif
#ifdef ESTRPIPE
case ESTRPIPE: return MA_ERROR;
#endif
#ifdef EUSERS
case EUSERS: return MA_ERROR;
#endif
#ifdef ENOTSOCK
case ENOTSOCK: return MA_NOT_SOCKET;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ: return MA_NO_ADDRESS;
#endif
#ifdef EMSGSIZE
case EMSGSIZE: return MA_TOO_BIG;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE: return MA_BAD_PROTOCOL;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT: return MA_PROTOCOL_UNAVAILABLE;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT: return MA_PROTOCOL_NOT_SUPPORTED;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT: return MA_SOCKET_NOT_SUPPORTED;
#endif
#ifdef EOPNOTSUPP
case EOPNOTSUPP: return MA_INVALID_OPERATION;
#endif
#ifdef EPFNOSUPPORT
case EPFNOSUPPORT: return MA_PROTOCOL_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT: return MA_ADDRESS_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EADDRINUSE
case EADDRINUSE: return MA_ALREADY_IN_USE;
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: return MA_ERROR;
#endif
#ifdef ENETDOWN
case ENETDOWN: return MA_NO_NETWORK;
#endif
#ifdef ENETUNREACH
case ENETUNREACH: return MA_NO_NETWORK;
#endif
#ifdef ENETRESET
case ENETRESET: return MA_NO_NETWORK;
#endif
#ifdef ECONNABORTED
case ECONNABORTED: return MA_NO_NETWORK;
#endif
#ifdef ECONNRESET
case ECONNRESET: return MA_CONNECTION_RESET;
#endif
#ifdef ENOBUFS
case ENOBUFS: return MA_NO_SPACE;
#endif
#ifdef EISCONN
case EISCONN: return MA_ALREADY_CONNECTED;
#endif
#ifdef ENOTCONN
case ENOTCONN: return MA_NOT_CONNECTED;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: return MA_ERROR;
#endif
#ifdef ETOOMANYREFS
case ETOOMANYREFS: return MA_ERROR;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: return MA_TIMEOUT;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: return MA_CONNECTION_REFUSED;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: return MA_NO_HOST;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: return MA_NO_HOST;
#endif
#ifdef EALREADY
case EALREADY: return MA_IN_PROGRESS;
#endif
#ifdef EINPROGRESS
case EINPROGRESS: return MA_IN_PROGRESS;
#endif
#ifdef ESTALE
case ESTALE: return MA_INVALID_FILE;
#endif
#ifdef EUCLEAN
case EUCLEAN: return MA_ERROR;
#endif
#ifdef ENOTNAM
case ENOTNAM: return MA_ERROR;
#endif
#ifdef ENAVAIL
case ENAVAIL: return MA_ERROR;
#endif
#ifdef EISNAM
case EISNAM: return MA_ERROR;
#endif
#ifdef EREMOTEIO
case EREMOTEIO: return MA_IO_ERROR;
#endif
#ifdef EDQUOT
case EDQUOT: return MA_NO_SPACE;
#endif
#ifdef ENOMEDIUM
case ENOMEDIUM: return MA_DOES_NOT_EXIST;
#endif
#ifdef EMEDIUMTYPE
case EMEDIUMTYPE: return MA_ERROR;
#endif
#ifdef ECANCELED
case ECANCELED: return MA_CANCELLED;
#endif
#ifdef ENOKEY
case ENOKEY: return MA_ERROR;
#endif
#ifdef EKEYEXPIRED
case EKEYEXPIRED: return MA_ERROR;
#endif
#ifdef EKEYREVOKED
case EKEYREVOKED: return MA_ERROR;
#endif
#ifdef EKEYREJECTED
case EKEYREJECTED: return MA_ERROR;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD: return MA_ERROR;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE: return MA_ERROR;
#endif
#ifdef ERFKILL
case ERFKILL: return MA_ERROR;
#endif
#ifdef EHWPOISON
case EHWPOISON: return MA_ERROR;
#endif
default: return MA_ERROR;
if (e == 0) {
return MA_SUCCESS;
}
#ifdef EPERM
else if (e == EPERM) { return MA_INVALID_OPERATION; }
#endif
#ifdef ENOENT
else if (e == ENOENT) { return MA_DOES_NOT_EXIST; }
#endif
#ifdef ESRCH
else if (e == ESRCH) { return MA_DOES_NOT_EXIST; }
#endif
#ifdef EINTR
else if (e == EINTR) { return MA_INTERRUPT; }
#endif
#ifdef EIO
else if (e == EIO) { return MA_IO_ERROR; }
#endif
#ifdef ENXIO
else if (e == ENXIO) { return MA_DOES_NOT_EXIST; }
#endif
#ifdef E2BIG
else if (e == E2BIG) { return MA_INVALID_ARGS; }
#endif
#ifdef ENOEXEC
else if (e == ENOEXEC) { return MA_INVALID_FILE; }
#endif
#ifdef EBADF
else if (e == EBADF) { return MA_INVALID_FILE; }
#endif
#ifdef ECHILD
else if (e == ECHILD) { return MA_ERROR; }
#endif
#ifdef EAGAIN
else if (e == EAGAIN) { return MA_UNAVAILABLE; }
#endif
#ifdef ENOMEM
else if (e == ENOMEM) { return MA_OUT_OF_MEMORY; }
#endif
#ifdef EACCES
else if (e == EACCES) { return MA_ACCESS_DENIED; }
#endif
#ifdef EFAULT
else if (e == EFAULT) { return MA_BAD_ADDRESS; }
#endif
#ifdef ENOTBLK
else if (e == ENOTBLK) { return MA_ERROR; }
#endif
#ifdef EBUSY
else if (e == EBUSY) { return MA_BUSY; }
#endif
#ifdef EEXIST
else if (e == EEXIST) { return MA_ALREADY_EXISTS; }
#endif
#ifdef EXDEV
else if (e == EXDEV) { return MA_ERROR; }
#endif
#ifdef ENODEV
else if (e == ENODEV) { return MA_DOES_NOT_EXIST; }
#endif
#ifdef ENOTDIR
else if (e == ENOTDIR) { return MA_NOT_DIRECTORY; }
#endif
#ifdef EISDIR
else if (e == EISDIR) { return MA_IS_DIRECTORY; }
#endif
#ifdef EINVAL
else if (e == EINVAL) { return MA_INVALID_ARGS; }
#endif
#ifdef ENFILE
else if (e == ENFILE) { return MA_TOO_MANY_OPEN_FILES; }
#endif
#ifdef EMFILE
else if (e == EMFILE) { return MA_TOO_MANY_OPEN_FILES; }
#endif
#ifdef ENOTTY
else if (e == ENOTTY) { return MA_INVALID_OPERATION; }
#endif
#ifdef ETXTBSY
else if (e == ETXTBSY) { return MA_BUSY; }
#endif
#ifdef EFBIG
else if (e == EFBIG) { return MA_TOO_BIG; }
#endif
#ifdef ENOSPC
else if (e == ENOSPC) { return MA_NO_SPACE; }
#endif
#ifdef ESPIPE
else if (e == ESPIPE) { return MA_BAD_SEEK; }
#endif
#ifdef EROFS
else if (e == EROFS) { return MA_ACCESS_DENIED; }
#endif
#ifdef EMLINK
else if (e == EMLINK) { return MA_TOO_MANY_LINKS; }
#endif
#ifdef EPIPE
else if (e == EPIPE) { return MA_BAD_PIPE; }
#endif
#ifdef EDOM
else if (e == EDOM) { return MA_OUT_OF_RANGE; }
#endif
#ifdef ERANGE
else if (e == ERANGE) { return MA_OUT_OF_RANGE; }
#endif
#ifdef EDEADLK
else if (e == EDEADLK) { return MA_DEADLOCK; }
#endif
#ifdef ENAMETOOLONG
else if (e == ENAMETOOLONG) { return MA_PATH_TOO_LONG; }
#endif
#ifdef ENOLCK
else if (e == ENOLCK) { return MA_ERROR; }
#endif
#ifdef ENOSYS
else if (e == ENOSYS) { return MA_NOT_IMPLEMENTED; }
#endif
#ifdef ENOTEMPTY
else if (e == ENOTEMPTY) { return MA_DIRECTORY_NOT_EMPTY; }
#endif
#ifdef ELOOP
else if (e == ELOOP) { return MA_TOO_MANY_LINKS; }
#endif
#ifdef ENOMSG
else if (e == ENOMSG) { return MA_NO_MESSAGE; }
#endif
#ifdef EIDRM
else if (e == EIDRM) { return MA_ERROR; }
#endif
#ifdef ECHRNG
else if (e == ECHRNG) { return MA_ERROR; }
#endif
#ifdef EL2NSYNC
else if (e == EL2NSYNC) { return MA_ERROR; }
#endif
#ifdef EL3HLT
else if (e == EL3HLT) { return MA_ERROR; }
#endif
#ifdef EL3RST
else if (e == EL3RST) { return MA_ERROR; }
#endif
#ifdef ELNRNG
else if (e == ELNRNG) { return MA_OUT_OF_RANGE; }
#endif
#ifdef EUNATCH
else if (e == EUNATCH) { return MA_ERROR; }
#endif
#ifdef ENOCSI
else if (e == ENOCSI) { return MA_ERROR; }
#endif
#ifdef EL2HLT
else if (e == EL2HLT) { return MA_ERROR; }
#endif
#ifdef EBADE
else if (e == EBADE) { return MA_ERROR; }
#endif
#ifdef EBADR
else if (e == EBADR) { return MA_ERROR; }
#endif
#ifdef EXFULL
else if (e == EXFULL) { return MA_ERROR; }
#endif
#ifdef ENOANO
else if (e == ENOANO) { return MA_ERROR; }
#endif
#ifdef EBADRQC
else if (e == EBADRQC) { return MA_ERROR; }
#endif
#ifdef EBADSLT
else if (e == EBADSLT) { return MA_ERROR; }
#endif
#ifdef EBFONT
else if (e == EBFONT) { return MA_INVALID_FILE; }
#endif
#ifdef ENOSTR
else if (e == ENOSTR) { return MA_ERROR; }
#endif
#ifdef ENODATA
else if (e == ENODATA) { return MA_NO_DATA_AVAILABLE; }
#endif
#ifdef ETIME
else if (e == ETIME) { return MA_TIMEOUT; }
#endif
#ifdef ENOSR
else if (e == ENOSR) { return MA_NO_DATA_AVAILABLE; }
#endif
#ifdef ENONET
else if (e == ENONET) { return MA_NO_NETWORK; }
#endif
#ifdef ENOPKG
else if (e == ENOPKG) { return MA_ERROR; }
#endif
#ifdef EREMOTE
else if (e == EREMOTE) { return MA_ERROR; }
#endif
#ifdef ENOLINK
else if (e == ENOLINK) { return MA_ERROR; }
#endif
#ifdef EADV
else if (e == EADV) { return MA_ERROR; }
#endif
#ifdef ESRMNT
else if (e == ESRMNT) { return MA_ERROR; }
#endif
#ifdef ECOMM
else if (e == ECOMM) { return MA_ERROR; }
#endif
#ifdef EPROTO
else if (e == EPROTO) { return MA_ERROR; }
#endif
#ifdef EMULTIHOP
else if (e == EMULTIHOP) { return MA_ERROR; }
#endif
#ifdef EDOTDOT
else if (e == EDOTDOT) { return MA_ERROR; }
#endif
#ifdef EBADMSG
else if (e == EBADMSG) { return MA_BAD_MESSAGE; }
#endif
#ifdef EOVERFLOW
else if (e == EOVERFLOW) { return MA_TOO_BIG; }
#endif
#ifdef ENOTUNIQ
else if (e == ENOTUNIQ) { return MA_NOT_UNIQUE; }
#endif
#ifdef EBADFD
else if (e == EBADFD) { return MA_ERROR; }
#endif
#ifdef EREMCHG
else if (e == EREMCHG) { return MA_ERROR; }
#endif
#ifdef ELIBACC
else if (e == ELIBACC) { return MA_ACCESS_DENIED; }
#endif
#ifdef ELIBBAD
else if (e == ELIBBAD) { return MA_INVALID_FILE; }
#endif
#ifdef ELIBSCN
else if (e == ELIBSCN) { return MA_INVALID_FILE; }
#endif
#ifdef ELIBMAX
else if (e == ELIBMAX) { return MA_ERROR; }
#endif
#ifdef ELIBEXEC
else if (e == ELIBEXEC) { return MA_ERROR; }
#endif
#ifdef EILSEQ
else if (e == EILSEQ) { return MA_INVALID_DATA; }
#endif
#ifdef ERESTART
else if (e == ERESTART) { return MA_ERROR; }
#endif
#ifdef ESTRPIPE
else if (e == ESTRPIPE) { return MA_ERROR; }
#endif
#ifdef EUSERS
else if (e == EUSERS) { return MA_ERROR; }
#endif
#ifdef ENOTSOCK
else if (e == ENOTSOCK) { return MA_NOT_SOCKET; }
#endif
#ifdef EDESTADDRREQ
else if (e == EDESTADDRREQ) { return MA_NO_ADDRESS; }
#endif
#ifdef EMSGSIZE
else if (e == EMSGSIZE) { return MA_TOO_BIG; }
#endif
#ifdef EPROTOTYPE
else if (e == EPROTOTYPE) { return MA_BAD_PROTOCOL; }
#endif
#ifdef ENOPROTOOPT
else if (e == ENOPROTOOPT) { return MA_PROTOCOL_UNAVAILABLE; }
#endif
#ifdef EPROTONOSUPPORT
else if (e == EPROTONOSUPPORT) { return MA_PROTOCOL_NOT_SUPPORTED; }
#endif
#ifdef ESOCKTNOSUPPORT
else if (e == ESOCKTNOSUPPORT) { return MA_SOCKET_NOT_SUPPORTED; }
#endif
#ifdef EOPNOTSUPP
else if (e == EOPNOTSUPP) { return MA_INVALID_OPERATION; }
#endif
#ifdef EPFNOSUPPORT
else if (e == EPFNOSUPPORT) { return MA_PROTOCOL_FAMILY_NOT_SUPPORTED; }
#endif
#ifdef EAFNOSUPPORT
else if (e == EAFNOSUPPORT) { return MA_ADDRESS_FAMILY_NOT_SUPPORTED; }
#endif
#ifdef EADDRINUSE
else if (e == EADDRINUSE) { return MA_ALREADY_IN_USE; }
#endif
#ifdef EADDRNOTAVAIL
else if (e == EADDRNOTAVAIL) { return MA_ERROR; }
#endif
#ifdef ENETDOWN
else if (e == ENETDOWN) { return MA_NO_NETWORK; }
#endif
#ifdef ENETUNREACH
else if (e == ENETUNREACH) { return MA_NO_NETWORK; }
#endif
#ifdef ENETRESET
else if (e == ENETRESET) { return MA_NO_NETWORK; }
#endif
#ifdef ECONNABORTED
else if (e == ECONNABORTED) { return MA_NO_NETWORK; }
#endif
#ifdef ECONNRESET
else if (e == ECONNRESET) { return MA_CONNECTION_RESET; }
#endif
#ifdef ENOBUFS
else if (e == ENOBUFS) { return MA_NO_SPACE; }
#endif
#ifdef EISCONN
else if (e == EISCONN) { return MA_ALREADY_CONNECTED; }
#endif
#ifdef ENOTCONN
else if (e == ENOTCONN) { return MA_NOT_CONNECTED; }
#endif
#ifdef ESHUTDOWN
else if (e == ESHUTDOWN) { return MA_ERROR; }
#endif
#ifdef ETOOMANYREFS
else if (e == ETOOMANYREFS) { return MA_ERROR; }
#endif
#ifdef ETIMEDOUT
else if (e == ETIMEDOUT) { return MA_TIMEOUT; }
#endif
#ifdef ECONNREFUSED
else if (e == ECONNREFUSED) { return MA_CONNECTION_REFUSED; }
#endif
#ifdef EHOSTDOWN
else if (e == EHOSTDOWN) { return MA_NO_HOST; }
#endif
#ifdef EHOSTUNREACH
else if (e == EHOSTUNREACH) { return MA_NO_HOST; }
#endif
#ifdef EALREADY
else if (e == EALREADY) { return MA_IN_PROGRESS; }
#endif
#ifdef EINPROGRESS
else if (e == EINPROGRESS) { return MA_IN_PROGRESS; }
#endif
#ifdef ESTALE
else if (e == ESTALE) { return MA_INVALID_FILE; }
#endif
#ifdef EUCLEAN
else if (e == EUCLEAN) { return MA_ERROR; }
#endif
#ifdef ENOTNAM
else if (e == ENOTNAM) { return MA_ERROR; }
#endif
#ifdef ENAVAIL
else if (e == ENAVAIL) { return MA_ERROR; }
#endif
#ifdef EISNAM
else if (e == EISNAM) { return MA_ERROR; }
#endif
#ifdef EREMOTEIO
else if (e == EREMOTEIO) { return MA_IO_ERROR; }
#endif
#ifdef EDQUOT
else if (e == EDQUOT) { return MA_NO_SPACE; }
#endif
#ifdef ENOMEDIUM
else if (e == ENOMEDIUM) { return MA_DOES_NOT_EXIST; }
#endif
#ifdef EMEDIUMTYPE
else if (e == EMEDIUMTYPE) { return MA_ERROR; }
#endif
#ifdef ECANCELED
else if (e == ECANCELED) { return MA_CANCELLED; }
#endif
#ifdef ENOKEY
else if (e == ENOKEY) { return MA_ERROR; }
#endif
#ifdef EKEYEXPIRED
else if (e == EKEYEXPIRED) { return MA_ERROR; }
#endif
#ifdef EKEYREVOKED
else if (e == EKEYREVOKED) { return MA_ERROR; }
#endif
#ifdef EKEYREJECTED
else if (e == EKEYREJECTED) { return MA_ERROR; }
#endif
#ifdef EOWNERDEAD
else if (e == EOWNERDEAD) { return MA_ERROR; }
#endif
#ifdef ENOTRECOVERABLE
else if (e == ENOTRECOVERABLE) { return MA_ERROR; }
#endif
#ifdef ERFKILL
else if (e == ERFKILL) { return MA_ERROR; }
#endif
#ifdef EHWPOISON
else if (e == EHWPOISON) { return MA_ERROR; }
#endif
else {
return MA_ERROR;
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || ((!defined(_MSC_VER) || _MSC_VER >= 1900) && !defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || ((!defined(_MSC_VER) || _MSC_VER >= 1900) && !defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS)) || (defined(__cplusplus) && __cplusplus >= 201103L)
typedef signed char c89atomic_int8;
typedef unsigned char c89atomic_uint8;
typedef signed short c89atomic_int16;
typedef unsigned short c89atomic_uint16;
typedef signed int c89atomic_int32;
typedef unsigned int c89atomic_uint32;
#if defined(_MSC_VER) && !defined(__clang__)
typedef signed __int64 c89atomic_int64;
typedef unsigned __int64 c89atomic_uint64;
#else
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc++11-long-long"
#endif
#endif
typedef signed long long c89atomic_int64;
typedef unsigned long long c89atomic_uint64;
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc++11-long-long"
#endif
typedef int c89atomic_memory_order;
typedef unsigned char c89atomic_bool;
#if !defined(C89ATOMIC_64BIT) && !defined(C89ATOMIC_32BIT)
#ifdef _WIN32
#ifdef _WIN64
#define C89ATOMIC_64BIT
#else
#define C89ATOMIC_32BIT
#endif
#endif
#endif
#if !defined(C89ATOMIC_64BIT) && !defined(C89ATOMIC_32BIT)
#ifdef __GNUC__
#ifdef __LP64__
#define C89ATOMIC_64BIT
#else
#define C89ATOMIC_32BIT
#endif
#endif
#endif
#if !defined(C89ATOMIC_64BIT) && !defined(C89ATOMIC_32BIT)
#include <stdint.h>
#if INTPTR_MAX == INT64_MAX
#define C89ATOMIC_64BIT
#else
#define C89ATOMIC_32BIT
#endif
#if defined(__x86_64__) || defined(_M_X64)
#define C89ATOMIC_X64
#elif defined(__i386) || defined(_M_IX86)
#define C89ATOMIC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define C89ATOMIC_ARM
#endif
#if defined(_MSC_VER)
#define C89ATOMIC_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define C89ATOMIC_INLINE __inline__ __attribute__((always_inline))
#else
#define C89ATOMIC_INLINE inline __attribute__((always_inline))
#endif
#elif defined(__WATCOMC__) || defined(__DMC__)
#define C89ATOMIC_INLINE __inline
#else
#define C89ATOMIC_INLINE
#endif
#define C89ATOMIC_HAS_8
#define C89ATOMIC_HAS_16
#define C89ATOMIC_HAS_32
#define C89ATOMIC_HAS_64
typedef int ma_atomic_memory_order;
#define MA_ATOMIC_HAS_8
#define MA_ATOMIC_HAS_16
#define MA_ATOMIC_HAS_32
#define MA_ATOMIC_HAS_64
#define c89atomic_memory_order_relaxed 0
#define c89atomic_memory_order_consume 1
#define c89atomic_memory_order_acquire 2
#define c89atomic_memory_order_release 3
#define c89atomic_memory_order_acq_rel 4
#define c89atomic_memory_order_seq_cst 5
#if _MSC_VER < 1600 && defined(C89ATOMIC_X86)
#define C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY
#define MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, ma_atomicType, msvcType) \
ma_atomicType result; \
switch (order) \
{ \
case ma_atomic_memory_order_relaxed: \
{ \
result = (ma_atomicType)intrin##_nf((volatile msvcType*)dst, (msvcType)src); \
} break; \
case ma_atomic_memory_order_consume: \
case ma_atomic_memory_order_acquire: \
{ \
result = (ma_atomicType)intrin##_acq((volatile msvcType*)dst, (msvcType)src); \
} break; \
case ma_atomic_memory_order_release: \
{ \
result = (ma_atomicType)intrin##_rel((volatile msvcType*)dst, (msvcType)src); \
} break; \
case ma_atomic_memory_order_acq_rel: \
case ma_atomic_memory_order_seq_cst: \
default: \
{ \
result = (ma_atomicType)intrin((volatile msvcType*)dst, (msvcType)src); \
} break; \
} \
return result;
#define MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, expected, desired, order, intrin, ma_atomicType, msvcType) \
ma_atomicType result; \
switch (order) \
{ \
case ma_atomic_memory_order_relaxed: \
{ \
result = (ma_atomicType)intrin##_nf((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
} break; \
case ma_atomic_memory_order_consume: \
case ma_atomic_memory_order_acquire: \
{ \
result = (ma_atomicType)intrin##_acq((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
} break; \
case ma_atomic_memory_order_release: \
{ \
result = (ma_atomicType)intrin##_rel((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
} break; \
case ma_atomic_memory_order_acq_rel: \
case ma_atomic_memory_order_seq_cst: \
default: \
{ \
result = (ma_atomicType)intrin((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
} break; \
} \
return result;
#define ma_atomic_memory_order_relaxed 0
#define ma_atomic_memory_order_consume 1
#define ma_atomic_memory_order_acquire 2
#define ma_atomic_memory_order_release 3
#define ma_atomic_memory_order_acq_rel 4
#define ma_atomic_memory_order_seq_cst 5
#if _MSC_VER < 1600 && defined(MA_X86)
#define MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY
#if defined(C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_compare_and_swap_8(volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 desired)
#if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_compare_and_swap_16(volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 desired)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_compare_and_swap_32(volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 desired)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_compare_and_swap_64(volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 desired)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 __stdcall ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
#if defined(C89ATOMIC_HAS_8)
#define c89atomic_compare_and_swap_8( dst, expected, desired) (c89atomic_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)desired, (char)expected)
#if defined(MA_ATOMIC_HAS_8)
#define ma_atomic_compare_and_swap_8( dst, expected, desired) (ma_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)desired, (char)expected)
#if defined(C89ATOMIC_HAS_16)
#define c89atomic_compare_and_swap_16(dst, expected, desired) (c89atomic_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)desired, (short)expected)
#if defined(MA_ATOMIC_HAS_16)
#define ma_atomic_compare_and_swap_16(dst, expected, desired) (ma_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)desired, (short)expected)
#if defined(C89ATOMIC_HAS_32)
#define c89atomic_compare_and_swap_32(dst, expected, desired) (c89atomic_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)desired, (long)expected)
#if defined(MA_ATOMIC_HAS_32)
#define ma_atomic_compare_and_swap_32(dst, expected, desired) (ma_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)desired, (long)expected)
#if defined(C89ATOMIC_HAS_64)
#define c89atomic_compare_and_swap_64(dst, expected, desired) (c89atomic_uint64)_InterlockedCompareExchange64((volatile c89atomic_int64*)dst, (c89atomic_int64)desired, (c89atomic_int64)expected)
#if defined(MA_ATOMIC_HAS_64)
#define ma_atomic_compare_and_swap_64(dst, expected, desired) (ma_uint64)_InterlockedCompareExchange64((volatile ma_int64*)dst, (ma_int64)desired, (ma_int64)expected)
#if defined(C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64) && defined(MA_64BIT)
static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64) && !defined(C89ATOMIC_64BIT)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64) && !defined(MA_64BIT)
static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64) && defined(C89ATOMIC_64BIT)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64) && defined(MA_64BIT)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64) && !defined(C89ATOMIC_64BIT)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64) && !defined(MA_64BIT)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
static C89ATOMIC_INLINE void __stdcall c89atomic_thread_fence(c89atomic_memory_order order)
#if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
static MA_INLINE void __stdcall ma_atomic_thread_fence(ma_atomic_memory_order order)
#if defined(C89ATOMIC_X64)
#define c89atomic_thread_fence(order) __faststorefence(), (void)order
#if defined(MA_X64)
#define ma_atomic_thread_fence(order) __faststorefence(), (void)order
#elif defined(MA_ARM64)
#define ma_atomic_thread_fence(order) __dmb(_ARM64_BARRIER_ISH), (void)order
#define c89atomic_compiler_fence() c89atomic_thread_fence(c89atomic_memory_order_seq_cst)
#define c89atomic_signal_fence(order) c89atomic_thread_fence(order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(volatile const c89atomic_uint8* ptr, c89atomic_memory_order order)
#define ma_atomic_compiler_fence() ma_atomic_thread_fence(ma_atomic_memory_order_seq_cst)
#define ma_atomic_signal_fence(order) ma_atomic_thread_fence(order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(volatile const c89atomic_uint16* ptr, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(volatile const c89atomic_uint32* ptr, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(volatile const c89atomic_uint64* ptr, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
#define c89atomic_store_explicit_8( dst, src, order) (void)c89atomic_exchange_explicit_8 (dst, src, order)
#if defined(MA_ATOMIC_HAS_8)
#define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
#if defined(C89ATOMIC_HAS_16)
#define c89atomic_store_explicit_16(dst, src, order) (void)c89atomic_exchange_explicit_16(dst, src, order)
#if defined(MA_ATOMIC_HAS_16)
#define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
#if defined(C89ATOMIC_HAS_32)
#define c89atomic_store_explicit_32(dst, src, order) (void)c89atomic_exchange_explicit_32(dst, src, order)
#if defined(MA_ATOMIC_HAS_32)
#define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
#if defined(C89ATOMIC_HAS_64)
#define c89atomic_store_explicit_64(dst, src, order) (void)c89atomic_exchange_explicit_64(dst, src, order)
#if defined(MA_ATOMIC_HAS_64)
#define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_sub_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue - src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue - src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_sub_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue - src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue - src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_sub_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_sub_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_and_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue & src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue & src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_and_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue & src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue & src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_and_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_and_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_xor_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue ^ src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue ^ src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_xor_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue ^ src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue ^ src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_xor_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_xor_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
static C89ATOMIC_INLINE c89atomic_uint8 __stdcall c89atomic_fetch_or_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue | src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue | src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_16)
static C89ATOMIC_INLINE c89atomic_uint16 __stdcall c89atomic_fetch_or_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue | src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue | src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
#if defined(C89ATOMIC_HAS_32)
static C89ATOMIC_INLINE c89atomic_uint32 __stdcall c89atomic_fetch_or_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_64)
static C89ATOMIC_INLINE c89atomic_uint64 __stdcall c89atomic_fetch_or_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#if defined(C89ATOMIC_HAS_8)
#define c89atomic_test_and_set_explicit_8( dst, order) c89atomic_exchange_explicit_8 (dst, 1, order)
#if defined(MA_ATOMIC_HAS_8)
#define ma_atomic_test_and_set_explicit_8( dst, order) ma_atomic_exchange_explicit_8 (dst, 1, order)
#if defined(C89ATOMIC_HAS_16)
#define c89atomic_test_and_set_explicit_16(dst, order) c89atomic_exchange_explicit_16(dst, 1, order)
#if defined(MA_ATOMIC_HAS_16)
#define ma_atomic_test_and_set_explicit_16(dst, order) ma_atomic_exchange_explicit_16(dst, 1, order)
#if defined(C89ATOMIC_HAS_32)
#define c89atomic_test_and_set_explicit_32(dst, order) c89atomic_exchange_explicit_32(dst, 1, order)
#if defined(MA_ATOMIC_HAS_32)
#define ma_atomic_test_and_set_explicit_32(dst, order) ma_atomic_exchange_explicit_32(dst, 1, order)
#if defined(C89ATOMIC_HAS_64)
#define c89atomic_test_and_set_explicit_64(dst, order) c89atomic_exchange_explicit_64(dst, 1, order)
#if defined(MA_ATOMIC_HAS_64)
#define ma_atomic_test_and_set_explicit_64(dst, order) ma_atomic_exchange_explicit_64(dst, 1, order)
#if defined(C89ATOMIC_HAS_8)
#define c89atomic_clear_explicit_8( dst, order) c89atomic_store_explicit_8 (dst, 0, order)
#if defined(MA_ATOMIC_HAS_8)
#define ma_atomic_clear_explicit_8( dst, order) ma_atomic_store_explicit_8 (dst, 0, order)
#if defined(C89ATOMIC_HAS_16)
#define c89atomic_clear_explicit_16(dst, order) c89atomic_store_explicit_16(dst, 0, order)
#if defined(MA_ATOMIC_HAS_16)
#define ma_atomic_clear_explicit_16(dst, order) ma_atomic_store_explicit_16(dst, 0, order)
#if defined(C89ATOMIC_HAS_32)
#define c89atomic_clear_explicit_32(dst, order) c89atomic_store_explicit_32(dst, 0, order)
#if defined(MA_ATOMIC_HAS_32)
#define ma_atomic_clear_explicit_32(dst, order) ma_atomic_store_explicit_32(dst, 0, order)
#if defined(C89ATOMIC_HAS_64)
#define c89atomic_clear_explicit_64(dst, order) c89atomic_store_explicit_64(dst, 0, order)
#if defined(MA_ATOMIC_HAS_64)
#define ma_atomic_clear_explicit_64(dst, order) ma_atomic_store_explicit_64(dst, 0, order)
#if defined(C89ATOMIC_HAS_8)
typedef c89atomic_uint8 c89atomic_flag;
#define c89atomic_flag_test_and_set_explicit(ptr, order) (c89atomic_bool)c89atomic_test_and_set_explicit_8(ptr, order)
#define c89atomic_flag_clear_explicit(ptr, order) c89atomic_clear_explicit_8(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) c89atomic_load_explicit_8(ptr, order)
#if defined(MA_ATOMIC_HAS_8)
typedef ma_uint8 ma_atomic_flag;
#define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_8(ptr, order)
#define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_8(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
typedef c89atomic_uint32 c89atomic_flag;
#define c89atomic_flag_test_and_set_explicit(ptr, order) (c89atomic_bool)c89atomic_test_and_set_explicit_32(ptr, order)
#define c89atomic_flag_clear_explicit(ptr, order) c89atomic_clear_explicit_32(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) c89atomic_load_explicit_32(ptr, order)
typedef ma_uint32 ma_atomic_flag;
#define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_32(ptr, order)
#define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_32(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) ma_atomic_load_explicit_32(ptr, order)
#define C89ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE
#define C89ATOMIC_HAS_NATIVE_IS_LOCK_FREE
#define c89atomic_memory_order_relaxed __ATOMIC_RELAXED
#define c89atomic_memory_order_consume __ATOMIC_CONSUME
#define c89atomic_memory_order_acquire __ATOMIC_ACQUIRE
#define c89atomic_memory_order_release __ATOMIC_RELEASE
#define c89atomic_memory_order_acq_rel __ATOMIC_ACQ_REL
#define c89atomic_memory_order_seq_cst __ATOMIC_SEQ_CST
#define c89atomic_compiler_fence() __asm__ __volatile__("":::"memory")
#define c89atomic_thread_fence(order) __atomic_thread_fence(order)
#define c89atomic_signal_fence(order) __atomic_signal_fence(order)
#define c89atomic_is_lock_free_8(ptr) __atomic_is_lock_free(1, ptr)
#define c89atomic_is_lock_free_16(ptr) __atomic_is_lock_free(2, ptr)
#define c89atomic_is_lock_free_32(ptr) __atomic_is_lock_free(4, ptr)
#define c89atomic_is_lock_free_64(ptr) __atomic_is_lock_free(8, ptr)
#define c89atomic_test_and_set_explicit_8( dst, order) __atomic_exchange_n(dst, 1, order)
#define c89atomic_test_and_set_explicit_16(dst, order) __atomic_exchange_n(dst, 1, order)
#define c89atomic_test_and_set_explicit_32(dst, order) __atomic_exchange_n(dst, 1, order)
#define c89atomic_test_and_set_explicit_64(dst, order) __atomic_exchange_n(dst, 1, order)
#define c89atomic_clear_explicit_8( dst, order) __atomic_store_n(dst, 0, order)
#define c89atomic_clear_explicit_16(dst, order) __atomic_store_n(dst, 0, order)
#define c89atomic_clear_explicit_32(dst, order) __atomic_store_n(dst, 0, order)
#define c89atomic_clear_explicit_64(dst, order) __atomic_store_n(dst, 0, order)
#define c89atomic_store_explicit_8( dst, src, order) __atomic_store_n(dst, src, order)
#define c89atomic_store_explicit_16(dst, src, order) __atomic_store_n(dst, src, order)
#define c89atomic_store_explicit_32(dst, src, order) __atomic_store_n(dst, src, order)
#define c89atomic_store_explicit_64(dst, src, order) __atomic_store_n(dst, src, order)
#define c89atomic_load_explicit_8( dst, order) __atomic_load_n(dst, order)
#define c89atomic_load_explicit_16(dst, order) __atomic_load_n(dst, order)
#define c89atomic_load_explicit_32(dst, order) __atomic_load_n(dst, order)
#define c89atomic_load_explicit_64(dst, order) __atomic_load_n(dst, order)
#define c89atomic_exchange_explicit_8( dst, src, order) __atomic_exchange_n(dst, src, order)
#define c89atomic_exchange_explicit_16(dst, src, order) __atomic_exchange_n(dst, src, order)
#define c89atomic_exchange_explicit_32(dst, src, order) __atomic_exchange_n(dst, src, order)
#define c89atomic_exchange_explicit_64(dst, src, order) __atomic_exchange_n(dst, src, order)
#define c89atomic_compare_exchange_strong_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define c89atomic_fetch_add_explicit_8( dst, src, order) __atomic_fetch_add(dst, src, order)
#define c89atomic_fetch_add_explicit_16(dst, src, order) __atomic_fetch_add(dst, src, order)
#define c89atomic_fetch_add_explicit_32(dst, src, order) __atomic_fetch_add(dst, src, order)
#define c89atomic_fetch_add_explicit_64(dst, src, order) __atomic_fetch_add(dst, src, order)
#define c89atomic_fetch_sub_explicit_8( dst, src, order) __atomic_fetch_sub(dst, src, order)
#define c89atomic_fetch_sub_explicit_16(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define c89atomic_fetch_sub_explicit_32(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define c89atomic_fetch_sub_explicit_64(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define c89atomic_fetch_or_explicit_8( dst, src, order) __atomic_fetch_or(dst, src, order)
#define c89atomic_fetch_or_explicit_16(dst, src, order) __atomic_fetch_or(dst, src, order)
#define c89atomic_fetch_or_explicit_32(dst, src, order) __atomic_fetch_or(dst, src, order)
#define c89atomic_fetch_or_explicit_64(dst, src, order) __atomic_fetch_or(dst, src, order)
#define c89atomic_fetch_xor_explicit_8( dst, src, order) __atomic_fetch_xor(dst, src, order)
#define c89atomic_fetch_xor_explicit_16(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define c89atomic_fetch_xor_explicit_32(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define c89atomic_fetch_xor_explicit_64(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define c89atomic_fetch_and_explicit_8( dst, src, order) __atomic_fetch_and(dst, src, order)
#define c89atomic_fetch_and_explicit_16(dst, src, order) __atomic_fetch_and(dst, src, order)
#define c89atomic_fetch_and_explicit_32(dst, src, order) __atomic_fetch_and(dst, src, order)
#define c89atomic_fetch_and_explicit_64(dst, src, order) __atomic_fetch_and(dst, src, order)
#define c89atomic_compare_and_swap_8 (dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_16(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_32(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_64(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
typedef c89atomic_uint8 c89atomic_flag;
#define c89atomic_flag_test_and_set_explicit(dst, order) (c89atomic_bool)__atomic_test_and_set(dst, order)
#define c89atomic_flag_clear_explicit(dst, order) __atomic_clear(dst, order)
#define c89atoimc_flag_load_explicit(ptr, order) c89atomic_load_explicit_8(ptr, order)
#define MA_ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE
#define MA_ATOMIC_HAS_NATIVE_IS_LOCK_FREE
#define ma_atomic_memory_order_relaxed __ATOMIC_RELAXED
#define ma_atomic_memory_order_consume __ATOMIC_CONSUME
#define ma_atomic_memory_order_acquire __ATOMIC_ACQUIRE
#define ma_atomic_memory_order_release __ATOMIC_RELEASE
#define ma_atomic_memory_order_acq_rel __ATOMIC_ACQ_REL
#define ma_atomic_memory_order_seq_cst __ATOMIC_SEQ_CST
#define ma_atomic_compiler_fence() __asm__ __volatile__("":::"memory")
#define ma_atomic_thread_fence(order) __atomic_thread_fence(order)
#define ma_atomic_signal_fence(order) __atomic_signal_fence(order)
#define ma_atomic_is_lock_free_8(ptr) __atomic_is_lock_free(1, ptr)
#define ma_atomic_is_lock_free_16(ptr) __atomic_is_lock_free(2, ptr)
#define ma_atomic_is_lock_free_32(ptr) __atomic_is_lock_free(4, ptr)
#define ma_atomic_is_lock_free_64(ptr) __atomic_is_lock_free(8, ptr)
#define ma_atomic_test_and_set_explicit_8( dst, order) __atomic_exchange_n(dst, 1, order)
#define ma_atomic_test_and_set_explicit_16(dst, order) __atomic_exchange_n(dst, 1, order)
#define ma_atomic_test_and_set_explicit_32(dst, order) __atomic_exchange_n(dst, 1, order)
#define ma_atomic_test_and_set_explicit_64(dst, order) __atomic_exchange_n(dst, 1, order)
#define ma_atomic_clear_explicit_8( dst, order) __atomic_store_n(dst, 0, order)
#define ma_atomic_clear_explicit_16(dst, order) __atomic_store_n(dst, 0, order)
#define ma_atomic_clear_explicit_32(dst, order) __atomic_store_n(dst, 0, order)
#define ma_atomic_clear_explicit_64(dst, order) __atomic_store_n(dst, 0, order)
#define ma_atomic_store_explicit_8( dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_store_explicit_16(dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_store_explicit_32(dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_store_explicit_64(dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_load_explicit_8( dst, order) __atomic_load_n(dst, order)
#define ma_atomic_load_explicit_16(dst, order) __atomic_load_n(dst, order)
#define ma_atomic_load_explicit_32(dst, order) __atomic_load_n(dst, order)
#define ma_atomic_load_explicit_64(dst, order) __atomic_load_n(dst, order)
#define ma_atomic_exchange_explicit_8( dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_exchange_explicit_16(dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_exchange_explicit_32(dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_exchange_explicit_64(dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_compare_exchange_strong_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
#define ma_atomic_fetch_add_explicit_8( dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_add_explicit_16(dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_add_explicit_32(dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_add_explicit_64(dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_sub_explicit_8( dst, src, order) __atomic_fetch_sub(dst, src, order)
#define ma_atomic_fetch_sub_explicit_16(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define ma_atomic_fetch_sub_explicit_32(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define ma_atomic_fetch_sub_explicit_64(dst, src, order) __atomic_fetch_sub(dst, src, order)
#define ma_atomic_fetch_or_explicit_8( dst, src, order) __atomic_fetch_or(dst, src, order)
#define ma_atomic_fetch_or_explicit_16(dst, src, order) __atomic_fetch_or(dst, src, order)
#define ma_atomic_fetch_or_explicit_32(dst, src, order) __atomic_fetch_or(dst, src, order)
#define ma_atomic_fetch_or_explicit_64(dst, src, order) __atomic_fetch_or(dst, src, order)
#define ma_atomic_fetch_xor_explicit_8( dst, src, order) __atomic_fetch_xor(dst, src, order)
#define ma_atomic_fetch_xor_explicit_16(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define ma_atomic_fetch_xor_explicit_32(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define ma_atomic_fetch_xor_explicit_64(dst, src, order) __atomic_fetch_xor(dst, src, order)
#define ma_atomic_fetch_and_explicit_8( dst, src, order) __atomic_fetch_and(dst, src, order)
#define ma_atomic_fetch_and_explicit_16(dst, src, order) __atomic_fetch_and(dst, src, order)
#define ma_atomic_fetch_and_explicit_32(dst, src, order) __atomic_fetch_and(dst, src, order)
#define ma_atomic_fetch_and_explicit_64(dst, src, order) __atomic_fetch_and(dst, src, order)
static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
{
__atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
{
__atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
{
__atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
{
__atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
typedef ma_uint8 ma_atomic_flag;
#define ma_atomic_flag_test_and_set_explicit(dst, order) (ma_bool32)__atomic_test_and_set(dst, order)
#define ma_atomic_flag_clear_explicit(dst, order) __atomic_clear(dst, order)
#define c89atoimc_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
#define c89atomic_memory_order_relaxed 1
#define c89atomic_memory_order_consume 2
#define c89atomic_memory_order_acquire 3
#define c89atomic_memory_order_release 4
#define c89atomic_memory_order_acq_rel 5
#define c89atomic_memory_order_seq_cst 6
#define c89atomic_compiler_fence() __asm__ __volatile__("":::"memory")
#define ma_atomic_memory_order_relaxed 1
#define ma_atomic_memory_order_consume 2
#define ma_atomic_memory_order_acquire 3
#define ma_atomic_memory_order_release 4
#define ma_atomic_memory_order_acq_rel 5
#define ma_atomic_memory_order_seq_cst 6
#define ma_atomic_compiler_fence() __asm__ __volatile__("":::"memory")
#define c89atomic_thread_fence(order) __sync_synchronize(), (void)order
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
#define ma_atomic_thread_fence(order) __sync_synchronize(), (void)order
static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_sub_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_sub_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_sub_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_sub_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_or_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_or_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_or_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_or_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_xor_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_xor_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_xor_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_xor_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_and_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_and_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_and_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_and_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#define c89atomic_compare_and_swap_8( dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_16(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_32(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define c89atomic_compare_and_swap_64(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define ma_atomic_compare_and_swap_8( dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define ma_atomic_compare_and_swap_16(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define ma_atomic_compare_and_swap_32(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#define ma_atomic_compare_and_swap_64(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
#if defined(C89ATOMIC_X86)
#define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory", "cc")
#elif defined(C89ATOMIC_X64)
#define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory", "cc")
#if defined(MA_X86)
#define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory", "cc")
#elif defined(MA_X64)
#define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory", "cc")
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_compare_and_swap_8(volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 desired)
static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_compare_and_swap_16(volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 desired)
static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_compare_and_swap_32(volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 desired)
static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 desired)
static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_exchange_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_exchange_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_exchange_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_exchange_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_add_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_add_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_add_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_add_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_sub_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue - src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue - src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_sub_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue - src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue - src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_sub_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_sub_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_and_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue & src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue & src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_and_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue & src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue & src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_and_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_and_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_xor_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue ^ src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue ^ src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_xor_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue ^ src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue ^ src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_xor_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_xor_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_or_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint8)(oldValue | src);
} while (c89atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint8)(oldValue | src);
} while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_or_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
newValue = (c89atomic_uint16)(oldValue | src);
} while (c89atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
newValue = (ma_uint16)(oldValue | src);
} while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_or_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_or_explicit_64(volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
#define c89atomic_signal_fence(order) c89atomic_thread_fence(order)
static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(volatile const c89atomic_uint8* ptr, c89atomic_memory_order order)
#define ma_atomic_signal_fence(order) ma_atomic_thread_fence(order)
static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(volatile const c89atomic_uint16* ptr, c89atomic_memory_order order)
static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(volatile const c89atomic_uint32* ptr, c89atomic_memory_order order)
static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(volatile const c89atomic_uint64* ptr, c89atomic_memory_order order)
static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
#define c89atomic_store_explicit_8( dst, src, order) (void)c89atomic_exchange_explicit_8 (dst, src, order)
#define c89atomic_store_explicit_16(dst, src, order) (void)c89atomic_exchange_explicit_16(dst, src, order)
#define c89atomic_store_explicit_32(dst, src, order) (void)c89atomic_exchange_explicit_32(dst, src, order)
#define c89atomic_store_explicit_64(dst, src, order) (void)c89atomic_exchange_explicit_64(dst, src, order)
#define c89atomic_test_and_set_explicit_8( dst, order) c89atomic_exchange_explicit_8 (dst, 1, order)
#define c89atomic_test_and_set_explicit_16(dst, order) c89atomic_exchange_explicit_16(dst, 1, order)
#define c89atomic_test_and_set_explicit_32(dst, order) c89atomic_exchange_explicit_32(dst, 1, order)
#define c89atomic_test_and_set_explicit_64(dst, order) c89atomic_exchange_explicit_64(dst, 1, order)
#define c89atomic_clear_explicit_8( dst, order) c89atomic_store_explicit_8 (dst, 0, order)
#define c89atomic_clear_explicit_16(dst, order) c89atomic_store_explicit_16(dst, 0, order)
#define c89atomic_clear_explicit_32(dst, order) c89atomic_store_explicit_32(dst, 0, order)
#define c89atomic_clear_explicit_64(dst, order) c89atomic_store_explicit_64(dst, 0, order)
typedef c89atomic_uint8 c89atomic_flag;
#define c89atomic_flag_test_and_set_explicit(ptr, order) (c89atomic_bool)c89atomic_test_and_set_explicit_8(ptr, order)
#define c89atomic_flag_clear_explicit(ptr, order) c89atomic_clear_explicit_8(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) c89atomic_load_explicit_8(ptr, order)
#define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
#define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
#define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
#define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
#define ma_atomic_test_and_set_explicit_8( dst, order) ma_atomic_exchange_explicit_8 (dst, 1, order)
#define ma_atomic_test_and_set_explicit_16(dst, order) ma_atomic_exchange_explicit_16(dst, 1, order)
#define ma_atomic_test_and_set_explicit_32(dst, order) ma_atomic_exchange_explicit_32(dst, 1, order)
#define ma_atomic_test_and_set_explicit_64(dst, order) ma_atomic_exchange_explicit_64(dst, 1, order)
#define ma_atomic_clear_explicit_8( dst, order) ma_atomic_store_explicit_8 (dst, 0, order)
#define ma_atomic_clear_explicit_16(dst, order) ma_atomic_store_explicit_16(dst, 0, order)
#define ma_atomic_clear_explicit_32(dst, order) ma_atomic_store_explicit_32(dst, 0, order)
#define ma_atomic_clear_explicit_64(dst, order) ma_atomic_store_explicit_64(dst, 0, order)
typedef ma_uint8 ma_atomic_flag;
#define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_8(ptr, order)
#define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_8(ptr, order)
#define c89atoimc_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
#if !defined(C89ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE)
#if defined(C89ATOMIC_HAS_8)
c89atomic_bool c89atomic_compare_exchange_strong_explicit_8(volatile c89atomic_uint8* dst, c89atomic_uint8* expected, c89atomic_uint8 desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
#if !defined(MA_ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE)
#if defined(MA_ATOMIC_HAS_8)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_8(volatile ma_uint8* dst, ma_uint8* expected, ma_uint8 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
expectedValue = c89atomic_load_explicit_8(expected, c89atomic_memory_order_seq_cst);
result = c89atomic_compare_and_swap_8(dst, expectedValue, desired);
expectedValue = ma_atomic_load_explicit_8(expected, ma_atomic_memory_order_seq_cst);
result = ma_atomic_compare_and_swap_8(dst, expectedValue, desired);
#if defined(C89ATOMIC_HAS_16)
c89atomic_bool c89atomic_compare_exchange_strong_explicit_16(volatile c89atomic_uint16* dst, c89atomic_uint16* expected, c89atomic_uint16 desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
#if defined(MA_ATOMIC_HAS_16)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_16(volatile ma_uint16* dst, ma_uint16* expected, ma_uint16 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
expectedValue = c89atomic_load_explicit_16(expected, c89atomic_memory_order_seq_cst);
result = c89atomic_compare_and_swap_16(dst, expectedValue, desired);
expectedValue = ma_atomic_load_explicit_16(expected, ma_atomic_memory_order_seq_cst);
result = ma_atomic_compare_and_swap_16(dst, expectedValue, desired);
#if defined(C89ATOMIC_HAS_32)
c89atomic_bool c89atomic_compare_exchange_strong_explicit_32(volatile c89atomic_uint32* dst, c89atomic_uint32* expected, c89atomic_uint32 desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
#if defined(MA_ATOMIC_HAS_32)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_32(volatile ma_uint32* dst, ma_uint32* expected, ma_uint32 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
expectedValue = c89atomic_load_explicit_32(expected, c89atomic_memory_order_seq_cst);
result = c89atomic_compare_and_swap_32(dst, expectedValue, desired);
expectedValue = ma_atomic_load_explicit_32(expected, ma_atomic_memory_order_seq_cst);
result = ma_atomic_compare_and_swap_32(dst, expectedValue, desired);
#if defined(C89ATOMIC_HAS_64)
c89atomic_bool c89atomic_compare_exchange_strong_explicit_64(volatile c89atomic_uint64* dst, volatile c89atomic_uint64* expected, c89atomic_uint64 desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
#if defined(MA_ATOMIC_HAS_64)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_64(volatile ma_uint64* dst, volatile ma_uint64* expected, ma_uint64 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
expectedValue = c89atomic_load_explicit_64(expected, c89atomic_memory_order_seq_cst);
result = c89atomic_compare_and_swap_64(dst, expectedValue, desired);
expectedValue = ma_atomic_load_explicit_64(expected, ma_atomic_memory_order_seq_cst);
result = ma_atomic_compare_and_swap_64(dst, expectedValue, desired);
#define c89atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_8 (dst, expected, desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8 (dst, expected, desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder)
#if !defined(C89ATOMIC_HAS_NATIVE_IS_LOCK_FREE)
static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_8(volatile void* ptr)
#if !defined(MA_ATOMIC_HAS_NATIVE_IS_LOCK_FREE)
static MA_INLINE ma_bool32 ma_atomic_is_lock_free_8(volatile void* ptr)
static C89ATOMIC_INLINE void* c89atomic_exchange_explicit_ptr(volatile void** dst, void* src, c89atomic_memory_order order)
static MA_INLINE void* ma_atomic_exchange_explicit_ptr(volatile void** dst, void* src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
return c89atomic_compare_exchange_strong_explicit_64((volatile c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)desired, successOrder, failureOrder);
return ma_atomic_compare_exchange_strong_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder);
static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
return c89atomic_compare_exchange_weak_explicit_64((volatile c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)desired, successOrder, failureOrder);
return ma_atomic_compare_exchange_weak_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder);
return (void*)c89atomic_compare_and_swap_64((volatile c89atomic_uint64*)dst, (c89atomic_uint64)expected, (c89atomic_uint64)desired);
return (void*)ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, (ma_uint64)expected, (ma_uint64)desired);
static C89ATOMIC_INLINE void* c89atomic_exchange_explicit_ptr(volatile void** dst, void* src, c89atomic_memory_order order)
static MA_INLINE void* ma_atomic_exchange_explicit_ptr(volatile void** dst, void* src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
return c89atomic_compare_exchange_strong_explicit_32((volatile c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)desired, successOrder, failureOrder);
return ma_atomic_compare_exchange_strong_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder);
static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
return c89atomic_compare_exchange_weak_explicit_32((volatile c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)desired, successOrder, failureOrder);
return ma_atomic_compare_exchange_weak_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder);
return (void*)c89atomic_compare_and_swap_32((volatile c89atomic_uint32*)dst, (c89atomic_uint32)expected, (c89atomic_uint32)desired);
return (void*)ma_atomic_compare_and_swap_32((volatile ma_uint32*)dst, (ma_uint32)expected, (ma_uint32)desired);
#define c89atomic_flag_test_and_set(ptr) c89atomic_flag_test_and_set_explicit(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_flag_clear(ptr) c89atomic_flag_clear_explicit(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_store_ptr(dst, src) c89atomic_store_explicit_ptr((volatile void**)dst, (void*)src, c89atomic_memory_order_seq_cst)
#define c89atomic_load_ptr(ptr) c89atomic_load_explicit_ptr((volatile void**)ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_ptr(dst, src) c89atomic_exchange_explicit_ptr((volatile void**)dst, (void*)src, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_ptr(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_ptr(dst, expected, desired) c89atomic_compare_exchange_weak_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_8( ptr) c89atomic_test_and_set_explicit_8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_16(ptr) c89atomic_test_and_set_explicit_16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_32(ptr) c89atomic_test_and_set_explicit_32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_64(ptr) c89atomic_test_and_set_explicit_64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_8( ptr) c89atomic_clear_explicit_8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_16(ptr) c89atomic_clear_explicit_16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_32(ptr) c89atomic_clear_explicit_32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_64(ptr) c89atomic_clear_explicit_64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_store_8( dst, src) c89atomic_store_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_16(dst, src) c89atomic_store_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_32(dst, src) c89atomic_store_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_64(dst, src) c89atomic_store_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_load_8( ptr) c89atomic_load_explicit_8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_16(ptr) c89atomic_load_explicit_16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_32(ptr) c89atomic_load_explicit_32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_64(ptr) c89atomic_load_explicit_64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_8( dst, src) c89atomic_exchange_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_16(dst, src) c89atomic_exchange_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_32(dst, src) c89atomic_exchange_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_64(dst, src) c89atomic_exchange_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_8( dst, expected, desired) c89atomic_compare_exchange_strong_explicit_8( dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_16(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_16(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_32(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_32(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_64(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_64(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_8( dst, expected, desired) c89atomic_compare_exchange_weak_explicit_8( dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_16( dst, expected, desired) c89atomic_compare_exchange_weak_explicit_16(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_32( dst, expected, desired) c89atomic_compare_exchange_weak_explicit_32(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_64( dst, expected, desired) c89atomic_compare_exchange_weak_explicit_64(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_8( dst, src) c89atomic_fetch_add_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_16(dst, src) c89atomic_fetch_add_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_32(dst, src) c89atomic_fetch_add_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_64(dst, src) c89atomic_fetch_add_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_8( dst, src) c89atomic_fetch_sub_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_16(dst, src) c89atomic_fetch_sub_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_32(dst, src) c89atomic_fetch_sub_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_64(dst, src) c89atomic_fetch_sub_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_8( dst, src) c89atomic_fetch_or_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_16(dst, src) c89atomic_fetch_or_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_32(dst, src) c89atomic_fetch_or_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_64(dst, src) c89atomic_fetch_or_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_8( dst, src) c89atomic_fetch_xor_explicit_8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_16(dst, src) c89atomic_fetch_xor_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_32(dst, src) c89atomic_fetch_xor_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_64(dst, src) c89atomic_fetch_xor_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_8( dst, src) c89atomic_fetch_and_explicit_8 (dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_16(dst, src) c89atomic_fetch_and_explicit_16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_32(dst, src) c89atomic_fetch_and_explicit_32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_64(dst, src) c89atomic_fetch_and_explicit_64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_explicit_i8( ptr, order) (c89atomic_int8 )c89atomic_test_and_set_explicit_8( (c89atomic_uint8* )ptr, order)
#define c89atomic_test_and_set_explicit_i16(ptr, order) (c89atomic_int16)c89atomic_test_and_set_explicit_16((c89atomic_uint16*)ptr, order)
#define c89atomic_test_and_set_explicit_i32(ptr, order) (c89atomic_int32)c89atomic_test_and_set_explicit_32((c89atomic_uint32*)ptr, order)
#define c89atomic_test_and_set_explicit_i64(ptr, order) (c89atomic_int64)c89atomic_test_and_set_explicit_64((c89atomic_uint64*)ptr, order)
#define c89atomic_clear_explicit_i8( ptr, order) c89atomic_clear_explicit_8( (c89atomic_uint8* )ptr, order)
#define c89atomic_clear_explicit_i16(ptr, order) c89atomic_clear_explicit_16((c89atomic_uint16*)ptr, order)
#define c89atomic_clear_explicit_i32(ptr, order) c89atomic_clear_explicit_32((c89atomic_uint32*)ptr, order)
#define c89atomic_clear_explicit_i64(ptr, order) c89atomic_clear_explicit_64((c89atomic_uint64*)ptr, order)
#define c89atomic_store_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_store_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_store_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_store_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_store_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_store_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_store_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_store_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_load_explicit_i8( ptr, order) (c89atomic_int8 )c89atomic_load_explicit_8( (c89atomic_uint8* )ptr, order)
#define c89atomic_load_explicit_i16(ptr, order) (c89atomic_int16)c89atomic_load_explicit_16((c89atomic_uint16*)ptr, order)
#define c89atomic_load_explicit_i32(ptr, order) (c89atomic_int32)c89atomic_load_explicit_32((c89atomic_uint32*)ptr, order)
#define c89atomic_load_explicit_i64(ptr, order) (c89atomic_int64)c89atomic_load_explicit_64((c89atomic_uint64*)ptr, order)
#define c89atomic_exchange_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_exchange_explicit_8 ((c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_exchange_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_exchange_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_exchange_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_exchange_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_exchange_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_exchange_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8* )expected, (c89atomic_uint8 )desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16*)expected, (c89atomic_uint16)desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8* )expected, (c89atomic_uint8 )desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16*)expected, (c89atomic_uint16)desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)desired, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)desired, successOrder, failureOrder)
#define c89atomic_fetch_add_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_add_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_fetch_add_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_add_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_fetch_add_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_add_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_fetch_add_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_add_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_fetch_sub_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_sub_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_fetch_sub_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_sub_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_fetch_sub_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_sub_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_fetch_sub_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_sub_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_fetch_or_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_or_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_fetch_or_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_or_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_fetch_or_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_or_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_fetch_or_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_or_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_fetch_xor_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_xor_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_fetch_xor_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_xor_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_fetch_xor_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_xor_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_fetch_xor_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_xor_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_fetch_and_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_and_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
#define c89atomic_fetch_and_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_and_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
#define c89atomic_fetch_and_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_and_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
#define c89atomic_fetch_and_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_and_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
#define c89atomic_test_and_set_i8( ptr) c89atomic_test_and_set_explicit_i8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_i16(ptr) c89atomic_test_and_set_explicit_i16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_i32(ptr) c89atomic_test_and_set_explicit_i32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_test_and_set_i64(ptr) c89atomic_test_and_set_explicit_i64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_i8( ptr) c89atomic_clear_explicit_i8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_i16(ptr) c89atomic_clear_explicit_i16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_i32(ptr) c89atomic_clear_explicit_i32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_i64(ptr) c89atomic_clear_explicit_i64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_store_i8( dst, src) c89atomic_store_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_i16(dst, src) c89atomic_store_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_i32(dst, src) c89atomic_store_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_i64(dst, src) c89atomic_store_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_load_i8( ptr) c89atomic_load_explicit_i8( ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_i16(ptr) c89atomic_load_explicit_i16(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_i32(ptr) c89atomic_load_explicit_i32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_i64(ptr) c89atomic_load_explicit_i64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_i8( dst, src) c89atomic_exchange_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_i16(dst, src) c89atomic_exchange_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_i32(dst, src) c89atomic_exchange_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_i64(dst, src) c89atomic_exchange_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_i8( dst, expected, desired) c89atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_i16(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_i32(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_strong_i64(dst, expected, desired) c89atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_i8( dst, expected, desired) c89atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_i16(dst, expected, desired) c89atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_i32(dst, expected, desired) c89atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_exchange_weak_i64(dst, expected, desired) c89atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, c89atomic_memory_order_seq_cst, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_i8( dst, src) c89atomic_fetch_add_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_i16(dst, src) c89atomic_fetch_add_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_i32(dst, src) c89atomic_fetch_add_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_add_i64(dst, src) c89atomic_fetch_add_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_i8( dst, src) c89atomic_fetch_sub_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_i16(dst, src) c89atomic_fetch_sub_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_i32(dst, src) c89atomic_fetch_sub_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_sub_i64(dst, src) c89atomic_fetch_sub_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_i8( dst, src) c89atomic_fetch_or_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_i16(dst, src) c89atomic_fetch_or_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_i32(dst, src) c89atomic_fetch_or_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_or_i64(dst, src) c89atomic_fetch_or_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_i8( dst, src) c89atomic_fetch_xor_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_i16(dst, src) c89atomic_fetch_xor_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_i32(dst, src) c89atomic_fetch_xor_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_xor_i64(dst, src) c89atomic_fetch_xor_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_i8( dst, src) c89atomic_fetch_and_explicit_i8( dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_i16(dst, src) c89atomic_fetch_and_explicit_i16(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_i32(dst, src) c89atomic_fetch_and_explicit_i32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_fetch_and_i64(dst, src) c89atomic_fetch_and_explicit_i64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_compare_and_swap_i8( dst, expected, dedsired) (c89atomic_int8 )c89atomic_compare_and_swap_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )expected, (c89atomic_uint8 )dedsired)
#define c89atomic_compare_and_swap_i16(dst, expected, dedsired) (c89atomic_int16)c89atomic_compare_and_swap_16((c89atomic_uint16*)dst, (c89atomic_uint16)expected, (c89atomic_uint16)dedsired)
#define c89atomic_compare_and_swap_i32(dst, expected, dedsired) (c89atomic_int32)c89atomic_compare_and_swap_32((c89atomic_uint32*)dst, (c89atomic_uint32)expected, (c89atomic_uint32)dedsired)
#define c89atomic_compare_and_swap_i64(dst, expected, dedsired) (c89atomic_int64)c89atomic_compare_and_swap_64((c89atomic_uint64*)dst, (c89atomic_uint64)expected, (c89atomic_uint64)dedsired)
#define ma_atomic_flag_test_and_set(ptr) ma_atomic_flag_test_and_set_explicit(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_flag_clear(ptr) ma_atomic_flag_clear_explicit(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_ptr(dst, src) ma_atomic_store_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_ptr(ptr) ma_atomic_load_explicit_ptr((volatile void**)ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_ptr(dst, src) ma_atomic_exchange_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_ptr(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_ptr(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_8( ptr) ma_atomic_test_and_set_explicit_8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_16(ptr) ma_atomic_test_and_set_explicit_16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_32(ptr) ma_atomic_test_and_set_explicit_32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_64(ptr) ma_atomic_test_and_set_explicit_64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_8( ptr) ma_atomic_clear_explicit_8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_16(ptr) ma_atomic_clear_explicit_16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_32(ptr) ma_atomic_clear_explicit_32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_64(ptr) ma_atomic_clear_explicit_64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_8( dst, src) ma_atomic_store_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_16(dst, src) ma_atomic_store_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_32(dst, src) ma_atomic_store_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_64(dst, src) ma_atomic_store_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_8( ptr) ma_atomic_load_explicit_8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_16(ptr) ma_atomic_load_explicit_16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_32(ptr) ma_atomic_load_explicit_32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_64(ptr) ma_atomic_load_explicit_64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_8( dst, src) ma_atomic_exchange_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_16(dst, src) ma_atomic_exchange_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_32(dst, src) ma_atomic_exchange_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_64(dst, src) ma_atomic_exchange_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_8( dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_16(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_8( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_16( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_32( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_64( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_8( dst, src) ma_atomic_fetch_add_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_16(dst, src) ma_atomic_fetch_add_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_32(dst, src) ma_atomic_fetch_add_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_64(dst, src) ma_atomic_fetch_add_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_8( dst, src) ma_atomic_fetch_sub_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_16(dst, src) ma_atomic_fetch_sub_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_32(dst, src) ma_atomic_fetch_sub_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_64(dst, src) ma_atomic_fetch_sub_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_8( dst, src) ma_atomic_fetch_or_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_16(dst, src) ma_atomic_fetch_or_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_32(dst, src) ma_atomic_fetch_or_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_64(dst, src) ma_atomic_fetch_or_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_8( dst, src) ma_atomic_fetch_xor_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_16(dst, src) ma_atomic_fetch_xor_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_32(dst, src) ma_atomic_fetch_xor_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_64(dst, src) ma_atomic_fetch_xor_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_8( dst, src) ma_atomic_fetch_and_explicit_8 (dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_16(dst, src) ma_atomic_fetch_and_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_32(dst, src) ma_atomic_fetch_and_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_64(dst, src) ma_atomic_fetch_and_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_explicit_i8( ptr, order) (ma_int8 )ma_atomic_test_and_set_explicit_8( (ma_uint8* )ptr, order)
#define ma_atomic_test_and_set_explicit_i16(ptr, order) (ma_int16)ma_atomic_test_and_set_explicit_16((ma_uint16*)ptr, order)
#define ma_atomic_test_and_set_explicit_i32(ptr, order) (ma_int32)ma_atomic_test_and_set_explicit_32((ma_uint32*)ptr, order)
#define ma_atomic_test_and_set_explicit_i64(ptr, order) (ma_int64)ma_atomic_test_and_set_explicit_64((ma_uint64*)ptr, order)
#define ma_atomic_clear_explicit_i8( ptr, order) ma_atomic_clear_explicit_8( (ma_uint8* )ptr, order)
#define ma_atomic_clear_explicit_i16(ptr, order) ma_atomic_clear_explicit_16((ma_uint16*)ptr, order)
#define ma_atomic_clear_explicit_i32(ptr, order) ma_atomic_clear_explicit_32((ma_uint32*)ptr, order)
#define ma_atomic_clear_explicit_i64(ptr, order) ma_atomic_clear_explicit_64((ma_uint64*)ptr, order)
#define ma_atomic_store_explicit_i8( dst, src, order) ma_atomic_store_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_store_explicit_i16(dst, src, order) ma_atomic_store_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_store_explicit_i32(dst, src, order) ma_atomic_store_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_store_explicit_i64(dst, src, order) ma_atomic_store_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_load_explicit_i8( ptr, order) (ma_int8 )ma_atomic_load_explicit_8( (ma_uint8* )ptr, order)
#define ma_atomic_load_explicit_i16(ptr, order) (ma_int16)ma_atomic_load_explicit_16((ma_uint16*)ptr, order)
#define ma_atomic_load_explicit_i32(ptr, order) (ma_int32)ma_atomic_load_explicit_32((ma_uint32*)ptr, order)
#define ma_atomic_load_explicit_i64(ptr, order) (ma_int64)ma_atomic_load_explicit_64((ma_uint64*)ptr, order)
#define ma_atomic_exchange_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_exchange_explicit_8 ((ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_exchange_explicit_i16(dst, src, order) (ma_int16)ma_atomic_exchange_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_exchange_explicit_i32(dst, src, order) (ma_int32)ma_atomic_exchange_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_exchange_explicit_i64(dst, src, order) (ma_int64)ma_atomic_exchange_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder)
#define ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder)
#define ma_atomic_fetch_add_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_add_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_add_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_add_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_add_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_add_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_add_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_add_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_fetch_sub_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_sub_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_sub_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_sub_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_sub_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_sub_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_sub_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_sub_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_fetch_or_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_or_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_or_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_or_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_or_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_or_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_or_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_or_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_fetch_xor_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_xor_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_xor_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_xor_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_xor_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_xor_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_xor_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_xor_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_fetch_and_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_and_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_and_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_and_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_and_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_and_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_and_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_and_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
#define ma_atomic_test_and_set_i8( ptr) ma_atomic_test_and_set_explicit_i8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_i16(ptr) ma_atomic_test_and_set_explicit_i16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_i32(ptr) ma_atomic_test_and_set_explicit_i32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_test_and_set_i64(ptr) ma_atomic_test_and_set_explicit_i64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_i8( ptr) ma_atomic_clear_explicit_i8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_i16(ptr) ma_atomic_clear_explicit_i16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_i32(ptr) ma_atomic_clear_explicit_i32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_i64(ptr) ma_atomic_clear_explicit_i64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i8( dst, src) ma_atomic_store_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i16(dst, src) ma_atomic_store_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i32(dst, src) ma_atomic_store_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i64(dst, src) ma_atomic_store_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_i8( ptr) ma_atomic_load_explicit_i8( ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_i16(ptr) ma_atomic_load_explicit_i16(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_i32(ptr) ma_atomic_load_explicit_i32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_i64(ptr) ma_atomic_load_explicit_i64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i8( dst, src) ma_atomic_exchange_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i16(dst, src) ma_atomic_exchange_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i32(dst, src) ma_atomic_exchange_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i64(dst, src) ma_atomic_exchange_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_i8( dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_i16(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_i32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_i64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_i8( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_i16(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_i32(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_i64(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i8( dst, src) ma_atomic_fetch_add_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i16(dst, src) ma_atomic_fetch_add_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i32(dst, src) ma_atomic_fetch_add_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i64(dst, src) ma_atomic_fetch_add_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_i8( dst, src) ma_atomic_fetch_sub_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_i16(dst, src) ma_atomic_fetch_sub_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_i32(dst, src) ma_atomic_fetch_sub_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_i64(dst, src) ma_atomic_fetch_sub_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_i8( dst, src) ma_atomic_fetch_or_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_i16(dst, src) ma_atomic_fetch_or_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_i32(dst, src) ma_atomic_fetch_or_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_i64(dst, src) ma_atomic_fetch_or_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_i8( dst, src) ma_atomic_fetch_xor_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_i16(dst, src) ma_atomic_fetch_xor_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_i32(dst, src) ma_atomic_fetch_xor_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_i64(dst, src) ma_atomic_fetch_xor_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_i8( dst, src) ma_atomic_fetch_and_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_i16(dst, src) ma_atomic_fetch_and_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_i32(dst, src) ma_atomic_fetch_and_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_i64(dst, src) ma_atomic_fetch_and_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_and_swap_i8( dst, expected, dedsired) (ma_int8 )ma_atomic_compare_and_swap_8( (ma_uint8* )dst, (ma_uint8 )expected, (ma_uint8 )dedsired)
#define ma_atomic_compare_and_swap_i16(dst, expected, dedsired) (ma_int16)ma_atomic_compare_and_swap_16((ma_uint16*)dst, (ma_uint16)expected, (ma_uint16)dedsired)
#define ma_atomic_compare_and_swap_i32(dst, expected, dedsired) (ma_int32)ma_atomic_compare_and_swap_32((ma_uint32*)dst, (ma_uint32)expected, (ma_uint32)dedsired)
#define ma_atomic_compare_and_swap_i64(dst, expected, dedsired) (ma_int64)ma_atomic_compare_and_swap_64((ma_uint64*)dst, (ma_uint64)expected, (ma_uint64)dedsired)
} c89atomic_if64;
#define c89atomic_clear_explicit_f32(ptr, order) c89atomic_clear_explicit_32((c89atomic_uint32*)ptr, order)
#define c89atomic_clear_explicit_f64(ptr, order) c89atomic_clear_explicit_64((c89atomic_uint64*)ptr, order)
static C89ATOMIC_INLINE void c89atomic_store_explicit_f32(volatile float* dst, float src, c89atomic_memory_order order)
} ma_atomic_if64;
#define ma_atomic_clear_explicit_f32(ptr, order) ma_atomic_clear_explicit_32((ma_uint32*)ptr, order)
#define ma_atomic_clear_explicit_f64(ptr, order) ma_atomic_clear_explicit_64((ma_uint64*)ptr, order)
static MA_INLINE void ma_atomic_store_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
{
ma_atomic_if32 x;
x.f = src;
ma_atomic_store_explicit_32((volatile ma_uint32*)dst, x.i, order);
}
static MA_INLINE void ma_atomic_store_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
{
ma_atomic_if64 x;
x.f = src;
ma_atomic_store_explicit_64((volatile ma_uint64*)dst, x.i, order);
}
static MA_INLINE float ma_atomic_load_explicit_f32(volatile const float* ptr, ma_atomic_memory_order order)
{
ma_atomic_if32 r;
r.i = ma_atomic_load_explicit_32((volatile const ma_uint32*)ptr, order);
return r.f;
}
static MA_INLINE double ma_atomic_load_explicit_f64(volatile const double* ptr, ma_atomic_memory_order order)
{
ma_atomic_if64 r;
r.i = ma_atomic_load_explicit_64((volatile const ma_uint64*)ptr, order);
return r.f;
}
static MA_INLINE float ma_atomic_exchange_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
{
ma_atomic_if32 r;
ma_atomic_if32 x;
x.f = src;
r.i = ma_atomic_exchange_explicit_32((volatile ma_uint32*)dst, x.i, order);
return r.f;
}
static MA_INLINE double ma_atomic_exchange_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
{
ma_atomic_if64 r;
ma_atomic_if64 x;
x.f = src;
r.i = ma_atomic_exchange_explicit_64((volatile ma_uint64*)dst, x.i, order);
return r.f;
}
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f32(volatile float* dst, float* expected, float desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if32 d;
d.f = desired;
return ma_atomic_compare_exchange_strong_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, d.i, successOrder, failureOrder);
}
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f64(volatile double* dst, double* expected, double desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if64 d;
d.f = desired;
return ma_atomic_compare_exchange_strong_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, d.i, successOrder, failureOrder);
}
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f32(volatile float* dst, float* expected, float desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if32 d;
d.f = desired;
return ma_atomic_compare_exchange_weak_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, d.i, successOrder, failureOrder);
}
static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f64(volatile double* dst, double* expected, double desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if64 d;
d.f = desired;
return ma_atomic_compare_exchange_weak_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, d.i, successOrder, failureOrder);
}
static MA_INLINE float ma_atomic_fetch_add_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
{
ma_atomic_if32 r;
ma_atomic_if32 x;
x.f = src;
r.i = ma_atomic_fetch_add_explicit_32((volatile ma_uint32*)dst, x.i, order);
return r.f;
}
static MA_INLINE double ma_atomic_fetch_add_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
{
ma_atomic_if64 r;
ma_atomic_if64 x;
x.f = src;
r.i = ma_atomic_fetch_add_explicit_64((volatile ma_uint64*)dst, x.i, order);
return r.f;
}
static MA_INLINE float ma_atomic_fetch_sub_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
{
ma_atomic_if32 r;
ma_atomic_if32 x;
x.f = src;
r.i = ma_atomic_fetch_sub_explicit_32((volatile ma_uint32*)dst, x.i, order);
return r.f;
}
static MA_INLINE double ma_atomic_fetch_sub_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
{
ma_atomic_if64 r;
ma_atomic_if64 x;
x.f = src;
r.i = ma_atomic_fetch_sub_explicit_64((volatile ma_uint64*)dst, x.i, order);
return r.f;
}
static MA_INLINE float ma_atomic_fetch_or_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE void c89atomic_store_explicit_f64(volatile double* dst, double src, c89atomic_memory_order order)
static MA_INLINE double ma_atomic_fetch_or_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE double c89atomic_load_explicit_f64(volatile const double* ptr, c89atomic_memory_order order)
static MA_INLINE double ma_atomic_fetch_xor_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE float c89atomic_exchange_explicit_f32(volatile float* dst, float src, c89atomic_memory_order order)
static MA_INLINE float ma_atomic_fetch_and_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
static C89ATOMIC_INLINE double c89atomic_exchange_explicit_f64(volatile double* dst, double src, c89atomic_memory_order order)
static MA_INLINE double ma_atomic_fetch_and_explicit_f64(volatile double* dst, double src, ma_atomic_memory_order order)
#define c89atomic_clear_f32(ptr) (float )c89atomic_clear_explicit_f32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_clear_f64(ptr) (double)c89atomic_clear_explicit_f64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_store_f32(dst, src) c89atomic_store_explicit_f32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_store_f64(dst, src) c89atomic_store_explicit_f64(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_load_f32(ptr) (float )c89atomic_load_explicit_f32(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_load_f64(ptr) (double)c89atomic_load_explicit_f64(ptr, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_f32(dst, src) (float )c89atomic_exchange_explicit_f32(dst, src, c89atomic_memory_order_seq_cst)
#define c89atomic_exchange_f64(dst, src) (double)c89atomic_exchange_explicit_f64(dst, src, c89atomic_memory_order_seq_cst)
typedef c89atomic_flag c89atomic_spinlock;
static C89ATOMIC_INLINE void c89atomic_spinlock_lock(volatile c89atomic_spinlock* pSpinlock)
#define ma_atomic_clear_f32(ptr) (float )ma_atomic_clear_explicit_f32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_clear_f64(ptr) (double)ma_atomic_clear_explicit_f64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_f32(dst, src) ma_atomic_store_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_f64(dst, src) ma_atomic_store_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_f32(ptr) (float )ma_atomic_load_explicit_f32(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_load_f64(ptr) (double)ma_atomic_load_explicit_f64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_f32(dst, src) (float )ma_atomic_exchange_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_f64(dst, src) (double)ma_atomic_exchange_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_f32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_f32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_strong_f64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_f64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_f32(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_f32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_compare_exchange_weak_f64(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_f64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_f32(dst, src) ma_atomic_fetch_add_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_f64(dst, src) ma_atomic_fetch_add_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_f32(dst, src) ma_atomic_fetch_sub_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_f64(dst, src) ma_atomic_fetch_sub_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_f32(dst, src) ma_atomic_fetch_or_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_or_f64(dst, src) ma_atomic_fetch_or_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_f32(dst, src) ma_atomic_fetch_xor_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_xor_f64(dst, src) ma_atomic_fetch_xor_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_f32(dst, src) ma_atomic_fetch_and_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_f64(dst, src) ma_atomic_fetch_and_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
static MA_INLINE float ma_atomic_compare_and_swap_f32(volatile float* dst, float expected, float desired)
{
ma_atomic_if32 r;
ma_atomic_if32 e, d;
e.f = expected;
d.f = desired;
r.i = ma_atomic_compare_and_swap_32((volatile ma_uint32*)dst, e.i, d.i);
return r.f;
}
static MA_INLINE double ma_atomic_compare_and_swap_f64(volatile double* dst, double expected, double desired)
{
ma_atomic_if64 r;
ma_atomic_if64 e, d;
e.f = expected;
d.f = desired;
r.i = ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, e.i, d.i);
return r.f;
}
typedef ma_atomic_flag ma_atomic_spinlock;
static MA_INLINE void ma_atomic_spinlock_lock(volatile ma_atomic_spinlock* pSpinlock)
/* c89atomic.h end */
/* ma_atomic.h end */
#define MA_ATOMIC_SAFE_TYPE_IMPL(c89TypeExtension, type) \
static MA_INLINE ma_##type ma_atomic_##type##_get(ma_atomic_##type* x) \
{ \
return (ma_##type)ma_atomic_load_##c89TypeExtension(&x->value); \
} \
static MA_INLINE void ma_atomic_##type##_set(ma_atomic_##type* x, ma_##type value) \
{ \
ma_atomic_store_##c89TypeExtension(&x->value, value); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_exchange(ma_atomic_##type* x, ma_##type value) \
{ \
return (ma_##type)ma_atomic_exchange_##c89TypeExtension(&x->value, value); \
} \
static MA_INLINE ma_bool32 ma_atomic_##type##_compare_exchange(ma_atomic_##type* x, ma_##type* expected, ma_##type desired) \
{ \
return ma_atomic_compare_exchange_weak_##c89TypeExtension(&x->value, expected, desired); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_fetch_add(ma_atomic_##type* x, ma_##type y) \
{ \
return (ma_##type)ma_atomic_fetch_add_##c89TypeExtension(&x->value, y); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_fetch_sub(ma_atomic_##type* x, ma_##type y) \
{ \
return (ma_##type)ma_atomic_fetch_sub_##c89TypeExtension(&x->value, y); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_fetch_or(ma_atomic_##type* x, ma_##type y) \
{ \
return (ma_##type)ma_atomic_fetch_or_##c89TypeExtension(&x->value, y); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_fetch_xor(ma_atomic_##type* x, ma_##type y) \
{ \
return (ma_##type)ma_atomic_fetch_xor_##c89TypeExtension(&x->value, y); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_fetch_and(ma_atomic_##type* x, ma_##type y) \
{ \
return (ma_##type)ma_atomic_fetch_and_##c89TypeExtension(&x->value, y); \
} \
static MA_INLINE ma_##type ma_atomic_##type##_compare_and_swap(ma_atomic_##type* x, ma_##type expected, ma_##type desired) \
{ \
return (ma_##type)ma_atomic_compare_and_swap_##c89TypeExtension(&x->value, expected, desired); \
} \
#define MA_ATOMIC_SAFE_TYPE_IMPL_PTR(type) \
static MA_INLINE ma_##type* ma_atomic_ptr_##type##_get(ma_atomic_ptr_##type* x) \
{ \
return ma_atomic_load_ptr((void**)&x->value); \
} \
static MA_INLINE void ma_atomic_ptr_##type##_set(ma_atomic_ptr_##type* x, ma_##type* value) \
{ \
ma_atomic_store_ptr((void**)&x->value, (void*)value); \
} \
static MA_INLINE ma_##type* ma_atomic_ptr_##type##_exchange(ma_atomic_ptr_##type* x, ma_##type* value) \
{ \
return ma_atomic_exchange_ptr((void**)&x->value, (void*)value); \
} \
static MA_INLINE ma_bool32 ma_atomic_ptr_##type##_compare_exchange(ma_atomic_ptr_##type* x, ma_##type** expected, ma_##type* desired) \
{ \
return ma_atomic_compare_exchange_weak_ptr((void**)&x->value, (void*)expected, (void*)desired); \
} \
static MA_INLINE ma_##type* ma_atomic_ptr_##type##_compare_and_swap(ma_atomic_ptr_##type* x, ma_##type* expected, ma_##type* desired) \
{ \
return (ma_##type*)ma_atomic_compare_and_swap_ptr((void**)&x->value, (void*)expected, (void*)desired); \
} \
typedef ma_thread_result (MA_THREADCALL * ma_thread_entry_proc)(void* pData);
#ifdef MA_WIN32
static int ma_thread_priority_to_win32(ma_thread_priority priority)
{
switch (priority) {
case ma_thread_priority_idle: return THREAD_PRIORITY_IDLE;
case ma_thread_priority_lowest: return THREAD_PRIORITY_LOWEST;
case ma_thread_priority_low: return THREAD_PRIORITY_BELOW_NORMAL;
case ma_thread_priority_normal: return THREAD_PRIORITY_NORMAL;
case ma_thread_priority_high: return THREAD_PRIORITY_ABOVE_NORMAL;
case ma_thread_priority_highest: return THREAD_PRIORITY_HIGHEST;
case ma_thread_priority_realtime: return THREAD_PRIORITY_TIME_CRITICAL;
default: return THREAD_PRIORITY_NORMAL;
}
}
static ma_result ma_thread_create__win32(ma_thread* pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void* pData)
{
*pThread = CreateThread(NULL, stackSize, entryProc, pData, 0, NULL);
if (*pThread == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
SetThreadPriority((HANDLE)*pThread, ma_thread_priority_to_win32(priority));
return MA_SUCCESS;
}
typedef ma_thread_result (MA_THREADCALL * ma_thread_entry_proc)(void* pData);
static void ma_thread_wait__win32(ma_thread* pThread)
{
WaitForSingleObject((HANDLE)*pThread, INFINITE);
CloseHandle((HANDLE)*pThread);
}
static ma_result ma_mutex_init__win32(ma_mutex* pMutex)
{
*pMutex = CreateEventW(NULL, FALSE, TRUE, NULL);
if (*pMutex == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_mutex_uninit__win32(ma_mutex* pMutex)
{
CloseHandle((HANDLE)*pMutex);
}
static void ma_mutex_lock__win32(ma_mutex* pMutex)
{
WaitForSingleObject((HANDLE)*pMutex, INFINITE);
}
static void ma_mutex_unlock__win32(ma_mutex* pMutex)
{
SetEvent((HANDLE)*pMutex);
}
static ma_result ma_event_init__win32(ma_event* pEvent)
{
*pEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (*pEvent == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_event_uninit__win32(ma_event* pEvent)
{
CloseHandle((HANDLE)*pEvent);
}
static ma_result ma_event_wait__win32(ma_event* pEvent)
{
DWORD result = WaitForSingleObject((HANDLE)*pEvent, INFINITE);
if (result == WAIT_OBJECT_0) {
return MA_SUCCESS;
}
if (result == WAIT_TIMEOUT) {
return MA_TIMEOUT;
}
return ma_result_from_GetLastError(GetLastError());
}
static ma_result ma_event_signal__win32(ma_event* pEvent)
{
BOOL result = SetEvent((HANDLE)*pEvent);
if (result == 0) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static ma_result ma_semaphore_init__win32(int initialValue, ma_semaphore* pSemaphore)
{
*pSemaphore = CreateSemaphoreW(NULL, (LONG)initialValue, LONG_MAX, NULL);
if (*pSemaphore == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_semaphore_uninit__win32(ma_semaphore* pSemaphore)
{
CloseHandle((HANDLE)*pSemaphore);
}
static ma_result ma_semaphore_wait__win32(ma_semaphore* pSemaphore)
{
DWORD result = WaitForSingleObject((HANDLE)*pSemaphore, INFINITE);
if (result == WAIT_OBJECT_0) {
return MA_SUCCESS;
}
if (result == WAIT_TIMEOUT) {
return MA_TIMEOUT;
}
return ma_result_from_GetLastError(GetLastError());
}
static ma_result ma_semaphore_release__win32(ma_semaphore* pSemaphore)
{
BOOL result = ReleaseSemaphore((HANDLE)*pSemaphore, 1, NULL);
if (result == 0) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
#endif
if (priority == ma_thread_priority_idle) {
#ifdef SCHED_IDLE
if (pthread_attr_setschedpolicy(&attr, SCHED_IDLE) == 0) {
scheduler = SCHED_IDLE;
}
#endif
} else if (priority == ma_thread_priority_realtime) {
#ifdef SCHED_FIFO
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0) {
scheduler = SCHED_FIFO;
/* We successfully initialized our attributes object so we can assign the pointer so it's passed into pthread_create(). */
pAttr = &attr;
/* We need to set the scheduler policy. Only do this if the OS supports pthread_attr_setschedpolicy() */
#if !defined(MA_BEOS)
{
if (priority == ma_thread_priority_idle) {
#ifdef SCHED_IDLE
if (pthread_attr_setschedpolicy(&attr, SCHED_IDLE) == 0) {
scheduler = SCHED_IDLE;
}
#endif
} else if (priority == ma_thread_priority_realtime) {
#ifdef SCHED_FIFO
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0) {
scheduler = SCHED_FIFO;
}
#endif
#ifdef MA_LINUX
} else {
scheduler = sched_getscheduler(0);
#endif
#elif defined(MA_WIN32)
static int ma_thread_priority_to_win32(ma_thread_priority priority)
{
switch (priority) {
case ma_thread_priority_idle: return THREAD_PRIORITY_IDLE;
case ma_thread_priority_lowest: return THREAD_PRIORITY_LOWEST;
case ma_thread_priority_low: return THREAD_PRIORITY_BELOW_NORMAL;
case ma_thread_priority_normal: return THREAD_PRIORITY_NORMAL;
case ma_thread_priority_high: return THREAD_PRIORITY_ABOVE_NORMAL;
case ma_thread_priority_highest: return THREAD_PRIORITY_HIGHEST;
case ma_thread_priority_realtime: return THREAD_PRIORITY_TIME_CRITICAL;
default: return THREAD_PRIORITY_NORMAL;
}
}
static ma_result ma_thread_create__win32(ma_thread* pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void* pData)
{
DWORD threadID; /* Not used. Only used for passing into CreateThread() so it doesn't fail on Windows 98. */
*pThread = CreateThread(NULL, stackSize, entryProc, pData, 0, &threadID);
if (*pThread == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
SetThreadPriority((HANDLE)*pThread, ma_thread_priority_to_win32(priority));
return MA_SUCCESS;
}
static void ma_thread_wait__win32(ma_thread* pThread)
{
WaitForSingleObject((HANDLE)*pThread, INFINITE);
CloseHandle((HANDLE)*pThread);
}
static ma_result ma_mutex_init__win32(ma_mutex* pMutex)
{
*pMutex = CreateEventA(NULL, FALSE, TRUE, NULL);
if (*pMutex == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_mutex_uninit__win32(ma_mutex* pMutex)
{
CloseHandle((HANDLE)*pMutex);
}
static void ma_mutex_lock__win32(ma_mutex* pMutex)
{
WaitForSingleObject((HANDLE)*pMutex, INFINITE);
}
static void ma_mutex_unlock__win32(ma_mutex* pMutex)
{
SetEvent((HANDLE)*pMutex);
}
static ma_result ma_event_init__win32(ma_event* pEvent)
{
*pEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
if (*pEvent == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_event_uninit__win32(ma_event* pEvent)
{
CloseHandle((HANDLE)*pEvent);
}
static ma_result ma_event_wait__win32(ma_event* pEvent)
{
DWORD result = WaitForSingleObject((HANDLE)*pEvent, INFINITE);
if (result == WAIT_OBJECT_0) {
return MA_SUCCESS;
}
if (result == WAIT_TIMEOUT) {
return MA_TIMEOUT;
}
return ma_result_from_GetLastError(GetLastError());
}
static ma_result ma_event_signal__win32(ma_event* pEvent)
{
BOOL result = SetEvent((HANDLE)*pEvent);
if (result == 0) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static ma_result ma_semaphore_init__win32(int initialValue, ma_semaphore* pSemaphore)
{
*pSemaphore = CreateSemaphoreW(NULL, (LONG)initialValue, LONG_MAX, NULL);
if (*pSemaphore == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
static void ma_semaphore_uninit__win32(ma_semaphore* pSemaphore)
{
CloseHandle((HANDLE)*pSemaphore);
}
static ma_result ma_semaphore_wait__win32(ma_semaphore* pSemaphore)
{
DWORD result = WaitForSingleObject((HANDLE)*pSemaphore, INFINITE);
if (result == WAIT_OBJECT_0) {
return MA_SUCCESS;
}
if (result == WAIT_TIMEOUT) {
return MA_TIMEOUT;
}
return ma_result_from_GetLastError(GetLastError());
}
static ma_result ma_semaphore_release__win32(ma_semaphore* pSemaphore)
{
BOOL result = ReleaseSemaphore((HANDLE)*pSemaphore, 1, NULL);
if (result == 0) {
return ma_result_from_GetLastError(GetLastError());
}
return MA_SUCCESS;
}
oldBitfield = c89atomic_load_32(&pAllocator->pGroups[iGroup].bitfield); /* <-- This copy must happen. The compiler must not optimize this away. */
oldBitfield = ma_atomic_load_32(&pAllocator->pGroups[iGroup].bitfield); /* <-- This copy must happen. The compiler must not optimize this away. */
oldBitfield = c89atomic_load_32(&pAllocator->pGroups[iGroup].bitfield); /* <-- This copy must happen. The compiler must not optimize this away. */
oldBitfield = ma_atomic_load_32(&pAllocator->pGroups[iGroup].bitfield); /* <-- This copy must happen. The compiler must not optimize this away. */
if (c89atomic_compare_and_swap_32(&pAllocator->pGroups[iGroup].bitfield, oldBitfield, newBitfield) == oldBitfield) {
c89atomic_fetch_sub_32(&pAllocator->count, 1);
if (ma_atomic_compare_and_swap_32(&pAllocator->pGroups[iGroup].bitfield, oldBitfield, newBitfield) == oldBitfield) {
ma_atomic_fetch_sub_32(&pAllocator->count, 1);
return c89atomic_compare_and_swap_64(dst, expected, ma_job_set_refcount(desired, ma_job_extract_refcount(expected) + 1)) == expected;
return ma_atomic_compare_and_swap_64(dst, expected, ma_job_set_refcount(desired, ma_job_extract_refcount(expected) + 1)) == expected;
head = c89atomic_load_64(&pQueue->head);
tail = c89atomic_load_64(&pQueue->tail);
next = c89atomic_load_64(&pQueue->pJobs[ma_job_extract_slot(head)].next);
head = ma_atomic_load_64(&pQueue->head);
tail = ma_atomic_load_64(&pQueue->tail);
next = ma_atomic_load_64(&pQueue->pJobs[ma_job_extract_slot(head)].next);
*******************************************************************************/
#ifdef MA_POSIX
/* No need for dlfcn.h if we're not using runtime linking. */
#ifndef MA_NO_RUNTIME_LINKING
#include <dlfcn.h>
#endif
#endif
MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename)
{
#ifndef MA_NO_RUNTIME_LINKING
ma_handle handle;
ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
#ifdef MA_WIN32
/* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
#if !defined(MA_WIN32_UWP)
handle = (ma_handle)LoadLibraryA(filename);
#else
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
WCHAR filenameW[4096];
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
handle = NULL;
} else {
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
}
#endif
#else
handle = (ma_handle)dlopen(filename, RTLD_NOW);
#endif
/*
I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
backend is a deliberate design choice. Instead I'm logging it as an informational message.
*/
if (handle == NULL) {
ma_log_postf(pLog, MA_LOG_LEVEL_INFO, "Failed to load library: %s\n", filename);
}
return handle;
#else
/* Runtime linking is disabled. */
(void)pLog;
(void)filename;
return NULL;
#endif
}
MA_API void ma_dlclose(ma_log* pLog, ma_handle handle)
{
#ifndef MA_NO_RUNTIME_LINKING
#ifdef MA_WIN32
FreeLibrary((HMODULE)handle);
#else
dlclose((void*)handle);
#endif
(void)pLog;
#else
/* Runtime linking is disabled. */
(void)pLog;
(void)handle;
#endif
}
MA_API ma_proc ma_dlsym(ma_log* pLog, ma_handle handle, const char* symbol)
{
#ifndef MA_NO_RUNTIME_LINKING
ma_proc proc;
ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading symbol: %s\n", symbol);
#ifdef _WIN32
proc = (ma_proc)GetProcAddress((HMODULE)handle, symbol);
#else
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
proc = (ma_proc)dlsym((void*)handle, symbol);
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
#pragma GCC diagnostic pop
#endif
#endif
if (proc == NULL) {
ma_log_postf(pLog, MA_LOG_LEVEL_WARNING, "Failed to load symbol: %s\n", symbol);
}
(void)pLog; /* It's possible for pContext to be unused. */
return proc;
#else
/* Runtime linking is disabled. */
(void)pLog;
(void)handle;
(void)symbol;
return NULL;
#endif
}
/*
Unfortunately using runtime linking for pthreads causes problems. This has occurred for me when testing on FreeBSD. When
using runtime linking, deadlocks can occur (for me it happens when loading data from fread()). It turns out that doing
compile-time linking fixes this. I'm not sure why this happens, but the safest way I can think of to fix this is to simply
disable runtime linking by default. To enable runtime linking, #define this before the implementation of this file. I am
not officially supporting this, but I'm leaving it here in case it's useful for somebody, somewhere.
*/
/*#define MA_USE_RUNTIME_LINKING_FOR_PTHREAD*/
/* Disable run-time linking on certain backends. */
#ifndef MA_NO_RUNTIME_LINKING
#if defined(MA_EMSCRIPTEN)
#define MA_NO_RUNTIME_LINKING
/* No need for dlfcn.h if we're not using runtime linking. */
#ifndef MA_NO_RUNTIME_LINKING
#include <dlfcn.h>
static ma_backend_info gBackendInfo[] = /* Indexed by the backend enum. Must be in the order backends are declared in the ma_backend enum. */
{
{ma_backend_wasapi, "WASAPI"},
{ma_backend_dsound, "DirectSound"},
{ma_backend_winmm, "WinMM"},
{ma_backend_coreaudio, "Core Audio"},
{ma_backend_sndio, "sndio"},
{ma_backend_audio4, "audio(4)"},
{ma_backend_oss, "OSS"},
{ma_backend_pulseaudio, "PulseAudio"},
{ma_backend_alsa, "ALSA"},
{ma_backend_jack, "JACK"},
{ma_backend_aaudio, "AAudio"},
{ma_backend_opensl, "OpenSL|ES"},
{ma_backend_webaudio, "Web Audio"},
{ma_backend_custom, "Custom"},
{ma_backend_null, "Null"}
};
switch (backend)
{
case ma_backend_wasapi: return "WASAPI";
case ma_backend_dsound: return "DirectSound";
case ma_backend_winmm: return "WinMM";
case ma_backend_coreaudio: return "Core Audio";
case ma_backend_sndio: return "sndio";
case ma_backend_audio4: return "audio(4)";
case ma_backend_oss: return "OSS";
case ma_backend_pulseaudio: return "PulseAudio";
case ma_backend_alsa: return "ALSA";
case ma_backend_jack: return "JACK";
case ma_backend_aaudio: return "AAudio";
case ma_backend_opensl: return "OpenSL|ES";
case ma_backend_webaudio: return "Web Audio";
case ma_backend_custom: return "Custom";
case ma_backend_null: return "Null";
default: return "Unknown";
if (backend < 0 || backend >= (int)ma_countof(gBackendInfo)) {
return "Unknown";
}
return gBackendInfo[backend].pName;
}
MA_API ma_result ma_get_backend_from_name(const char* pBackendName, ma_backend* pBackend)
{
size_t iBackend;
if (pBackendName == NULL) {
return MA_INVALID_ARGS;
}
for (iBackend = 0; iBackend < ma_countof(gBackendInfo); iBackend += 1) {
if (ma_strcmp(pBackendName, gBackendInfo[iBackend].pName) == 0) {
if (pBackend != NULL) {
*pBackend = gBackendInfo[iBackend].backend;
}
return MA_SUCCESS;
}
typedef HRESULT (WINAPI * MA_PFN_CoInitializeEx)(LPVOID pvReserved, DWORD dwCoInit);
/* PROPVARIANT */
#define MA_VT_LPWSTR 31
#define MA_VT_BLOB 65
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable:4201) /* nonstandard extension used: nameless struct/union */
#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic" /* For ISO C99 doesn't support unnamed structs/unions [-Wpedantic] */
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc11-extensions" /* anonymous unions are a C11 extension */
#endif
#endif
typedef struct
{
WORD vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
struct
{
ULONG cbSize;
BYTE* pBlobData;
} blob;
WCHAR* pwszVal;
char pad[16]; /* Just to ensure the size of the struct matches the official version. */
};
} MA_PROPVARIANT;
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
#pragma GCC diagnostic pop
#endif
typedef HRESULT (WINAPI * MA_PFN_CoInitialize)(void* pvReserved);
typedef HRESULT (WINAPI * MA_PFN_CoInitializeEx)(void* pvReserved, DWORD dwCoInit);
typedef HRESULT (WINAPI * MA_PFN_CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
typedef void (WINAPI * MA_PFN_CoTaskMemFree)(LPVOID pv);
typedef HRESULT (WINAPI * MA_PFN_PropVariantClear)(PROPVARIANT *pvar);
typedef int (WINAPI * MA_PFN_StringFromGUID2)(const GUID* const rguid, LPOLESTR lpsz, int cchMax);
typedef HRESULT (WINAPI * MA_PFN_CoCreateInstance)(const IID* rclsid, void* pUnkOuter, DWORD dwClsContext, const IID* riid, void* ppv);
typedef void (WINAPI * MA_PFN_CoTaskMemFree)(void* pv);
typedef HRESULT (WINAPI * MA_PFN_PropVariantClear)(MA_PROPVARIANT *pvar);
typedef int (WINAPI * MA_PFN_StringFromGUID2)(const GUID* const rguid, WCHAR* lpsz, int cchMax);
typedef LONG (WINAPI * MA_PFN_RegOpenKeyExA)(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
typedef LONG (WINAPI * MA_PFN_RegCloseKey)(HKEY hKey);
typedef LONG (WINAPI * MA_PFN_RegQueryValueExA)(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
typedef LONG (WINAPI * MA_PFN_RegOpenKeyExA)(HKEY hKey, const char* lpSubKey, DWORD ulOptions, DWORD samDesired, HKEY* phkResult);
typedef LONG (WINAPI * MA_PFN_RegCloseKey)(HKEY hKey);
typedef LONG (WINAPI * MA_PFN_RegQueryValueExA)(HKEY hKey, const char* lpValueName, DWORD* lpReserved, DWORD* lpType, BYTE* lpData, DWORD* lpcbData);
MA_API size_t ma_strlen_WCHAR(const WCHAR* str)
{
size_t len = 0;
while (str[len] != '\0') {
len += 1;
}
return len;
}
MA_API int ma_strcmp_WCHAR(const WCHAR *s1, const WCHAR *s2)
{
while (*s1 != '\0' && *s1 == *s2) {
s1 += 1;
s2 += 1;
}
return *s1 - *s2;
}
MA_API int ma_strcpy_s_WCHAR(WCHAR* dst, size_t dstCap, const WCHAR* src)
{
size_t i;
if (dst == 0) {
return 22;
}
if (dstCap == 0) {
return 34;
}
if (src == 0) {
dst[0] = '\0';
return 22;
}
for (i = 0; i < dstCap && src[i] != '\0'; ++i) {
dst[i] = src[i];
}
if (i < dstCap) {
dst[i] = '\0';
return 0;
}
dst[0] = '\0';
return 34;
}
Dynamic Linking
*******************************************************************************/
MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
{
ma_handle handle;
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
#ifdef _WIN32
#ifdef MA_WIN32_DESKTOP
handle = (ma_handle)LoadLibraryA(filename);
#else
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
WCHAR filenameW[4096];
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
handle = NULL;
} else {
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
}
#endif
#else
handle = (ma_handle)dlopen(filename, RTLD_NOW);
#endif
/*
I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
backend is a deliberate design choice. Instead I'm logging it as an informational message.
*/
if (handle == NULL) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_INFO, "Failed to load library: %s\n", filename);
}
(void)pContext; /* It's possible for pContext to be unused. */
return handle;
}
MA_API void ma_dlclose(ma_context* pContext, ma_handle handle)
{
#ifdef _WIN32
FreeLibrary((HMODULE)handle);
#else
dlclose((void*)handle);
#endif
(void)pContext;
}
MA_API ma_proc ma_dlsym(ma_context* pContext, ma_handle handle, const char* symbol)
{
ma_proc proc;
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Loading symbol: %s\n", symbol);
#ifdef _WIN32
proc = (ma_proc)GetProcAddress((HMODULE)handle, symbol);
#else
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
proc = (ma_proc)dlsym((void*)handle, symbol);
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
#pragma GCC diagnostic pop
#endif
#endif
if (proc == NULL) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_WARNING, "Failed to load symbol: %s\n", symbol);
}
(void)pContext; /* It's possible for pContext to be unused. */
return proc;
}
#if defined(MA_WIN32_DESKTOP)
#define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit)
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
#define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((pContext->win32.CoInitializeEx) ? ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit) : ((MA_PFN_CoInitialize)pContext->win32.CoInitialize)(pvReserved))
#if !defined(WAVE_FORMAT_1M08)
#define WAVE_FORMAT_1M08 0x00000001
#define WAVE_FORMAT_1S08 0x00000002
#define WAVE_FORMAT_1M16 0x00000004
#define WAVE_FORMAT_1S16 0x00000008
#define WAVE_FORMAT_2M08 0x00000010
#define WAVE_FORMAT_2S08 0x00000020
#define WAVE_FORMAT_2M16 0x00000040
#define WAVE_FORMAT_2S16 0x00000080
#define WAVE_FORMAT_4M08 0x00000100
#define WAVE_FORMAT_4S08 0x00000200
#define WAVE_FORMAT_4M16 0x00000400
#define WAVE_FORMAT_4S16 0x00000800
#endif
#define WAVE_FORMAT_44M08 0x00000100
#define WAVE_FORMAT_44S08 0x00000200
#define WAVE_FORMAT_44M16 0x00000400
#define WAVE_FORMAT_44S16 0x00000800
#define WAVE_FORMAT_48M08 0x00001000
#define WAVE_FORMAT_48S08 0x00002000
#define WAVE_FORMAT_48M16 0x00004000
#define WAVE_FORMAT_48S16 0x00008000
#define WAVE_FORMAT_96M08 0x00010000
#define WAVE_FORMAT_96S08 0x00020000
#define WAVE_FORMAT_96M16 0x00040000
#define WAVE_FORMAT_96S16 0x00080000
#define WAVE_FORMAT_44M08 0x00000100
#define WAVE_FORMAT_44S08 0x00000200
#define WAVE_FORMAT_44M16 0x00000400
#define WAVE_FORMAT_44S16 0x00000800
#define WAVE_FORMAT_48M08 0x00001000
#define WAVE_FORMAT_48S08 0x00002000
#define WAVE_FORMAT_48M16 0x00004000
#define WAVE_FORMAT_48S16 0x00008000
#define WAVE_FORMAT_96M08 0x00010000
#define WAVE_FORMAT_96S08 0x00020000
#define WAVE_FORMAT_96M16 0x00040000
#define WAVE_FORMAT_96S16 0x00080000
The SDK that comes with old versions of MSVC (VC6, for example) does not appear to define WAVEFORMATEXTENSIBLE. We
define our own implementation in this case.
Implement our own version of MA_WAVEFORMATEXTENSIBLE so we can avoid a header. Be careful with this
because MA_WAVEFORMATEX has an extra two bytes over standard WAVEFORMATEX due to padding. The
standard version uses tight packing, but for compiler compatibility we're not doing that with ours.
#if (defined(_MSC_VER) && !defined(_WAVEFORMATEXTENSIBLE_)) || defined(__DMC__)
typedef struct
{
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} MA_WAVEFORMATEX;
if (channels == 1 && dwChannelMask == 0) {
pChannelMap[0] = MA_CHANNEL_MONO;
} else if (channels == 2 && dwChannelMask == 0) {
pChannelMap[0] = MA_CHANNEL_FRONT_LEFT;
pChannelMap[1] = MA_CHANNEL_FRONT_RIGHT;
/* If the channel mask is set to 0, just assume a default Win32 channel map. */
if (dwChannelMask == 0) {
ma_channel_map_init_standard(ma_standard_channel_map_microsoft, pChannelMap, channels, channels);
static const IID MA_CLSID_MMDeviceEnumerator_Instance = {0xBCDE0395, 0xE52F, 0x467C, {0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E}}; /* BCDE0395-E52F-467C-8E3D-C4579291692E = __uuidof(MMDeviceEnumerator) */
static const IID MA_IID_IMMDeviceEnumerator_Instance = {0xA95664D2, 0x9614, 0x4F35, {0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6}}; /* A95664D2-9614-4F35-A746-DE8DB63617E6 = __uuidof(IMMDeviceEnumerator) */
#ifdef __cplusplus
#define MA_CLSID_MMDeviceEnumerator MA_CLSID_MMDeviceEnumerator_Instance
#define MA_IID_IMMDeviceEnumerator MA_IID_IMMDeviceEnumerator_Instance
#else
#define MA_CLSID_MMDeviceEnumerator &MA_CLSID_MMDeviceEnumerator_Instance
#define MA_IID_IMMDeviceEnumerator &MA_IID_IMMDeviceEnumerator_Instance
#endif
static const IID MA_CLSID_MMDeviceEnumerator = {0xBCDE0395, 0xE52F, 0x467C, {0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E}}; /* BCDE0395-E52F-467C-8E3D-C4579291692E = __uuidof(MMDeviceEnumerator) */
static const IID MA_IID_IMMDeviceEnumerator = {0xA95664D2, 0x9614, 0x4F35, {0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6}}; /* A95664D2-9614-4F35-A746-DE8DB63617E6 = __uuidof(IMMDeviceEnumerator) */
HRESULT (STDMETHODCALLTYPE * OnDeviceStateChanged) (ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID, DWORD dwNewState);
HRESULT (STDMETHODCALLTYPE * OnDeviceAdded) (ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID);
HRESULT (STDMETHODCALLTYPE * OnDeviceRemoved) (ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID);
HRESULT (STDMETHODCALLTYPE * OnDefaultDeviceChanged)(ma_IMMNotificationClient* pThis, ma_EDataFlow dataFlow, ma_ERole role, LPCWSTR pDefaultDeviceID);
HRESULT (STDMETHODCALLTYPE * OnPropertyValueChanged)(ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID, const PROPERTYKEY key);
HRESULT (STDMETHODCALLTYPE * OnDeviceStateChanged) (ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID, DWORD dwNewState);
HRESULT (STDMETHODCALLTYPE * OnDeviceAdded) (ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID);
HRESULT (STDMETHODCALLTYPE * OnDeviceRemoved) (ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID);
HRESULT (STDMETHODCALLTYPE * OnDefaultDeviceChanged)(ma_IMMNotificationClient* pThis, ma_EDataFlow dataFlow, ma_ERole role, const WCHAR* pDefaultDeviceID);
HRESULT (STDMETHODCALLTYPE * OnPropertyValueChanged)(ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID, const PROPERTYKEY key);
static MA_INLINE HRESULT ma_IMMDeviceEnumerator_GetDevice(ma_IMMDeviceEnumerator* pThis, LPCWSTR pID, ma_IMMDevice** ppDevice) { return pThis->lpVtbl->GetDevice(pThis, pID, ppDevice); }
static MA_INLINE HRESULT ma_IMMDeviceEnumerator_GetDevice(ma_IMMDeviceEnumerator* pThis, const WCHAR* pID, ma_IMMDevice** ppDevice) { return pThis->lpVtbl->GetDevice(pThis, pID, ppDevice); }
HRESULT (STDMETHODCALLTYPE * Activate) (ma_IMMDevice* pThis, const IID* const iid, DWORD dwClsCtx, PROPVARIANT* pActivationParams, void** ppInterface);
HRESULT (STDMETHODCALLTYPE * Activate) (ma_IMMDevice* pThis, const IID* const iid, DWORD dwClsCtx, MA_PROPVARIANT* pActivationParams, void** ppInterface);
static MA_INLINE HRESULT ma_IMMDevice_Activate(ma_IMMDevice* pThis, const IID* const iid, DWORD dwClsCtx, PROPVARIANT* pActivationParams, void** ppInterface) { return pThis->lpVtbl->Activate(pThis, iid, dwClsCtx, pActivationParams, ppInterface); }
static MA_INLINE HRESULT ma_IMMDevice_Activate(ma_IMMDevice* pThis, const IID* const iid, DWORD dwClsCtx, MA_PROPVARIANT* pActivationParams, void** ppInterface) { return pThis->lpVtbl->Activate(pThis, iid, dwClsCtx, pActivationParams, ppInterface); }
static MA_INLINE HRESULT ma_IMMDevice_GetId(ma_IMMDevice* pThis, LPWSTR *pID) { return pThis->lpVtbl->GetId(pThis, pID); }
static MA_INLINE HRESULT ma_IMMDevice_GetId(ma_IMMDevice* pThis, WCHAR** pID) { return pThis->lpVtbl->GetId(pThis, pID); }
HRESULT (STDMETHODCALLTYPE * GetValue)(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, PROPVARIANT* pPropVar);
HRESULT (STDMETHODCALLTYPE * SetValue)(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, const PROPVARIANT* const pPropVar);
HRESULT (STDMETHODCALLTYPE * GetValue)(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, MA_PROPVARIANT* pPropVar);
HRESULT (STDMETHODCALLTYPE * SetValue)(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, const MA_PROPVARIANT* const pPropVar);
static MA_INLINE HRESULT ma_IPropertyStore_GetValue(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, PROPVARIANT* pPropVar) { return pThis->lpVtbl->GetValue(pThis, pKey, pPropVar); }
static MA_INLINE HRESULT ma_IPropertyStore_SetValue(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, const PROPVARIANT* const pPropVar) { return pThis->lpVtbl->SetValue(pThis, pKey, pPropVar); }
static MA_INLINE HRESULT ma_IPropertyStore_GetValue(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, MA_PROPVARIANT* pPropVar) { return pThis->lpVtbl->GetValue(pThis, pKey, pPropVar); }
static MA_INLINE HRESULT ma_IPropertyStore_SetValue(ma_IPropertyStore* pThis, const PROPERTYKEY* const pKey, const MA_PROPVARIANT* const pPropVar) { return pThis->lpVtbl->SetValue(pThis, pKey, pPropVar); }
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient* pThis, WAVEFORMATEX** ppDeviceFormat);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient* pThis, MA_WAVEFORMATEX** ppDeviceFormat);
static MA_INLINE HRESULT ma_IAudioClient_Initialize(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient_Initialize(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient_IsFormatSupported(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient_GetMixFormat(ma_IAudioClient* pThis, WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
static MA_INLINE HRESULT ma_IAudioClient_IsFormatSupported(ma_IAudioClient* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient_GetMixFormat(ma_IAudioClient* pThis, MA_WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient2* pThis, WAVEFORMATEX** ppDeviceFormat);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient2* pThis, MA_WAVEFORMATEX** ppDeviceFormat);
HRESULT (STDMETHODCALLTYPE * GetBufferSizeLimits)(ma_IAudioClient2* pThis, const WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration);
HRESULT (STDMETHODCALLTYPE * GetBufferSizeLimits)(ma_IAudioClient2* pThis, const MA_WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration);
static MA_INLINE HRESULT ma_IAudioClient2_Initialize(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient2_Initialize(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient2_IsFormatSupported(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient2_GetMixFormat(ma_IAudioClient2* pThis, WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
static MA_INLINE HRESULT ma_IAudioClient2_IsFormatSupported(ma_IAudioClient2* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient2_GetMixFormat(ma_IAudioClient2* pThis, MA_WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
static MA_INLINE HRESULT ma_IAudioClient2_GetBufferSizeLimits(ma_IAudioClient2* pThis, const WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration) { return pThis->lpVtbl->GetBufferSizeLimits(pThis, pFormat, eventDriven, pMinBufferDuration, pMaxBufferDuration); }
static MA_INLINE HRESULT ma_IAudioClient2_GetBufferSizeLimits(ma_IAudioClient2* pThis, const MA_WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration) { return pThis->lpVtbl->GetBufferSizeLimits(pThis, pFormat, eventDriven, pMinBufferDuration, pMaxBufferDuration); }
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * Initialize) (ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient3* pThis, WAVEFORMATEX** ppDeviceFormat);
HRESULT (STDMETHODCALLTYPE * IsFormatSupported)(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch);
HRESULT (STDMETHODCALLTYPE * GetMixFormat) (ma_IAudioClient3* pThis, MA_WAVEFORMATEX** ppDeviceFormat);
HRESULT (STDMETHODCALLTYPE * GetBufferSizeLimits)(ma_IAudioClient3* pThis, const WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration);
HRESULT (STDMETHODCALLTYPE * GetBufferSizeLimits)(ma_IAudioClient3* pThis, const MA_WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration);
HRESULT (STDMETHODCALLTYPE * GetSharedModeEnginePeriod) (ma_IAudioClient3* pThis, const WAVEFORMATEX* pFormat, ma_uint32* pDefaultPeriodInFrames, ma_uint32* pFundamentalPeriodInFrames, ma_uint32* pMinPeriodInFrames, ma_uint32* pMaxPeriodInFrames);
HRESULT (STDMETHODCALLTYPE * GetCurrentSharedModeEnginePeriod)(ma_IAudioClient3* pThis, WAVEFORMATEX** ppFormat, ma_uint32* pCurrentPeriodInFrames);
HRESULT (STDMETHODCALLTYPE * InitializeSharedAudioStream) (ma_IAudioClient3* pThis, DWORD streamFlags, ma_uint32 periodInFrames, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
HRESULT (STDMETHODCALLTYPE * GetSharedModeEnginePeriod) (ma_IAudioClient3* pThis, const MA_WAVEFORMATEX* pFormat, ma_uint32* pDefaultPeriodInFrames, ma_uint32* pFundamentalPeriodInFrames, ma_uint32* pMinPeriodInFrames, ma_uint32* pMaxPeriodInFrames);
HRESULT (STDMETHODCALLTYPE * GetCurrentSharedModeEnginePeriod)(ma_IAudioClient3* pThis, MA_WAVEFORMATEX** ppFormat, ma_uint32* pCurrentPeriodInFrames);
HRESULT (STDMETHODCALLTYPE * InitializeSharedAudioStream) (ma_IAudioClient3* pThis, DWORD streamFlags, ma_uint32 periodInFrames, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid);
static MA_INLINE HRESULT ma_IAudioClient3_Initialize(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient3_Initialize(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, DWORD streamFlags, MA_REFERENCE_TIME bufferDuration, MA_REFERENCE_TIME periodicity, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGuid) { return pThis->lpVtbl->Initialize(pThis, shareMode, streamFlags, bufferDuration, periodicity, pFormat, pAudioSessionGuid); }
static MA_INLINE HRESULT ma_IAudioClient3_IsFormatSupported(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, const WAVEFORMATEX* pFormat, WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient3_GetMixFormat(ma_IAudioClient3* pThis, WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
static MA_INLINE HRESULT ma_IAudioClient3_IsFormatSupported(ma_IAudioClient3* pThis, MA_AUDCLNT_SHAREMODE shareMode, const MA_WAVEFORMATEX* pFormat, MA_WAVEFORMATEX** ppClosestMatch) { return pThis->lpVtbl->IsFormatSupported(pThis, shareMode, pFormat, ppClosestMatch); }
static MA_INLINE HRESULT ma_IAudioClient3_GetMixFormat(ma_IAudioClient3* pThis, MA_WAVEFORMATEX** ppDeviceFormat) { return pThis->lpVtbl->GetMixFormat(pThis, ppDeviceFormat); }
static MA_INLINE HRESULT ma_IAudioClient3_GetBufferSizeLimits(ma_IAudioClient3* pThis, const WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration) { return pThis->lpVtbl->GetBufferSizeLimits(pThis, pFormat, eventDriven, pMinBufferDuration, pMaxBufferDuration); }
static MA_INLINE HRESULT ma_IAudioClient3_GetSharedModeEnginePeriod(ma_IAudioClient3* pThis, const WAVEFORMATEX* pFormat, ma_uint32* pDefaultPeriodInFrames, ma_uint32* pFundamentalPeriodInFrames, ma_uint32* pMinPeriodInFrames, ma_uint32* pMaxPeriodInFrames) { return pThis->lpVtbl->GetSharedModeEnginePeriod(pThis, pFormat, pDefaultPeriodInFrames, pFundamentalPeriodInFrames, pMinPeriodInFrames, pMaxPeriodInFrames); }
static MA_INLINE HRESULT ma_IAudioClient3_GetCurrentSharedModeEnginePeriod(ma_IAudioClient3* pThis, WAVEFORMATEX** ppFormat, ma_uint32* pCurrentPeriodInFrames) { return pThis->lpVtbl->GetCurrentSharedModeEnginePeriod(pThis, ppFormat, pCurrentPeriodInFrames); }
static MA_INLINE HRESULT ma_IAudioClient3_InitializeSharedAudioStream(ma_IAudioClient3* pThis, DWORD streamFlags, ma_uint32 periodInFrames, const WAVEFORMATEX* pFormat, const GUID* pAudioSessionGUID) { return pThis->lpVtbl->InitializeSharedAudioStream(pThis, streamFlags, periodInFrames, pFormat, pAudioSessionGUID); }
static MA_INLINE HRESULT ma_IAudioClient3_GetBufferSizeLimits(ma_IAudioClient3* pThis, const MA_WAVEFORMATEX* pFormat, BOOL eventDriven, MA_REFERENCE_TIME* pMinBufferDuration, MA_REFERENCE_TIME* pMaxBufferDuration) { return pThis->lpVtbl->GetBufferSizeLimits(pThis, pFormat, eventDriven, pMinBufferDuration, pMaxBufferDuration); }
static MA_INLINE HRESULT ma_IAudioClient3_GetSharedModeEnginePeriod(ma_IAudioClient3* pThis, const MA_WAVEFORMATEX* pFormat, ma_uint32* pDefaultPeriodInFrames, ma_uint32* pFundamentalPeriodInFrames, ma_uint32* pMinPeriodInFrames, ma_uint32* pMaxPeriodInFrames) { return pThis->lpVtbl->GetSharedModeEnginePeriod(pThis, pFormat, pDefaultPeriodInFrames, pFundamentalPeriodInFrames, pMinPeriodInFrames, pMaxPeriodInFrames); }
static MA_INLINE HRESULT ma_IAudioClient3_GetCurrentSharedModeEnginePeriod(ma_IAudioClient3* pThis, MA_WAVEFORMATEX** ppFormat, ma_uint32* pCurrentPeriodInFrames) { return pThis->lpVtbl->GetCurrentSharedModeEnginePeriod(pThis, ppFormat, pCurrentPeriodInFrames); }
static MA_INLINE HRESULT ma_IAudioClient3_InitializeSharedAudioStream(ma_IAudioClient3* pThis, DWORD streamFlags, ma_uint32 periodInFrames, const MA_WAVEFORMATEX* pFormat, const GUID* pAudioSessionGUID) { return pThis->lpVtbl->InitializeSharedAudioStream(pThis, streamFlags, periodInFrames, pFormat, pAudioSessionGUID); }
#if defined(MA_WIN32_UWP)
/* mmdevapi Functions */
typedef HRESULT (WINAPI * MA_PFN_ActivateAudioInterfaceAsync)(const wchar_t* deviceInterfacePath, const IID* riid, MA_PROPVARIANT* activationParams, ma_IActivateAudioInterfaceCompletionHandler* completionHandler, ma_IActivateAudioInterfaceAsyncOperation** activationOperation);
#endif
/* Avrt Functions */
typedef HANDLE (WINAPI * MA_PFN_AvSetMmThreadCharacteristicsA)(const char* TaskName, DWORD* TaskIndex);
typedef BOOL (WINAPI * MA_PFN_AvRevertMmThreadCharacteristics)(HANDLE AvrtHandle);
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateChanged(ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID, DWORD dwNewState)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateChanged(ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID, DWORD dwNewState)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceAdded(ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceAdded(ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceRemoved(ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceRemoved(ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged(ma_IMMNotificationClient* pThis, ma_EDataFlow dataFlow, ma_ERole role, LPCWSTR pDefaultDeviceID)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged(ma_IMMNotificationClient* pThis, ma_EDataFlow dataFlow, ma_ERole role, const WCHAR* pDefaultDeviceID)
/* We only ever use the eConsole role in miniaudio. */
if (role != ma_eConsole) {
ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting: role != eConsole\n");
(void)role;
/* We only care about devices with the same data flow as the current device. */
if ((pThis->pDevice->type == ma_device_type_playback && dataFlow != ma_eRender) ||
(pThis->pDevice->type == ma_device_type_capture && dataFlow != ma_eCapture) ||
(pThis->pDevice->type == ma_device_type_loopback && dataFlow != ma_eRender)) {
ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting abandoned because dataFlow does match device type.\n");
/* We only care about devices with the same data flow and role as the current device. */
if ((pThis->pDevice->type == ma_device_type_playback && dataFlow != ma_eRender) ||
(pThis->pDevice->type == ma_device_type_capture && dataFlow != ma_eCapture)) {
ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting abandoned because dataFlow does match device type.\n");
return S_OK;
/* We need to consider dataFlow as ma_eCapture if device is ma_device_type_loopback */
if (pThis->pDevice->type == ma_device_type_loopback) {
dataFlow = ma_eCapture;
if (dataFlow == ma_eRender) {
ma_device_reroute__wasapi(pThis->pDevice, ma_device_type_playback);
ma_mutex_lock(&pThis->pDevice->wasapi.rerouteLock);
{
if (dataFlow == ma_eRender) {
ma_device_reroute__wasapi(pThis->pDevice, ma_device_type_playback);
if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedCapture) {
restartDevice = MA_FALSE; /* It's a duplex device and the capture side is detached. We cannot be restarting the device just yet. */
} else {
restartDevice = MA_TRUE; /* It's not a duplex device, or the capture side is also attached so we can go ahead and restart the device. */
if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedCapture) {
restartDevice = MA_FALSE; /* It's a duplex device and the capture side is detached. We cannot be restarting the device just yet. */
}
else {
restartDevice = MA_TRUE; /* It's not a duplex device, or the capture side is also attached so we can go ahead and restart the device. */
}
} else {
ma_device_reroute__wasapi(pThis->pDevice, (pThis->pDevice->type == ma_device_type_loopback) ? ma_device_type_loopback : ma_device_type_capture);
else {
ma_device_reroute__wasapi(pThis->pDevice, (pThis->pDevice->type == ma_device_type_loopback) ? ma_device_type_loopback : ma_device_type_capture);
if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedPlayback) {
restartDevice = MA_FALSE; /* It's a duplex device and the playback side is detached. We cannot be restarting the device just yet. */
} else {
restartDevice = MA_TRUE; /* It's not a duplex device, or the playback side is also attached so we can go ahead and restart the device. */
if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedPlayback) {
restartDevice = MA_FALSE; /* It's a duplex device and the playback side is detached. We cannot be restarting the device just yet. */
}
else {
restartDevice = MA_TRUE; /* It's not a duplex device, or the playback side is also attached so we can go ahead and restart the device. */
}
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnPropertyValueChanged(ma_IMMNotificationClient* pThis, LPCWSTR pDeviceID, const PROPERTYKEY key)
static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnPropertyValueChanged(ma_IMMNotificationClient* pThis, const WCHAR* pDeviceID, const PROPERTYKEY key)
static void ma_add_native_data_format_to_device_info_from_WAVEFORMATEX(const WAVEFORMATEX* pWF, ma_share_mode shareMode, ma_device_info* pInfo)
static void ma_add_native_data_format_to_device_info_from_WAVEFORMATEX(const MA_WAVEFORMATEX* pWF, ma_share_mode shareMode, ma_device_info* pInfo)
wf.Format.wBitsPerSample = (WORD)(ma_get_bytes_per_sample(format)*8);
wf.Format.nBlockAlign = (WORD)(wf.Format.nChannels * wf.Format.wBitsPerSample / 8);
wf.Format.nAvgBytesPerSec = wf.Format.nBlockAlign * wf.Format.nSamplesPerSec;
wf.Samples.wValidBitsPerSample = /*(format == ma_format_s24_32) ? 24 :*/ wf.Format.wBitsPerSample;
wf.wBitsPerSample = (WORD)(ma_get_bytes_per_sample(format)*8);
wf.nBlockAlign = (WORD)(wf.nChannels * wf.wBitsPerSample / 8);
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
wf.Samples.wValidBitsPerSample = /*(format == ma_format_s24_32) ? 24 :*/ wf.wBitsPerSample;
hr = ma_IAudioClient_IsFormatSupported((ma_IAudioClient*)pAudioClient, MA_AUDCLNT_SHAREMODE_EXCLUSIVE, (WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_IsFormatSupported((ma_IAudioClient*)pAudioClient, MA_AUDCLNT_SHAREMODE_EXCLUSIVE, (MA_WAVEFORMATEX*)&wf, NULL);
hr = ma_CoCreateInstance(pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
static LPWSTR ma_context_get_default_device_id_from_IMMDeviceEnumerator__wasapi(ma_context* pContext, ma_IMMDeviceEnumerator* pDeviceEnumerator, ma_device_type deviceType)
static WCHAR* ma_context_get_default_device_id_from_IMMDeviceEnumerator__wasapi(ma_context* pContext, ma_IMMDeviceEnumerator* pDeviceEnumerator, ma_device_type deviceType)
static LPWSTR ma_context_get_default_device_id__wasapi(ma_context* pContext, ma_device_type deviceType) /* Free the returned pointer with ma_CoTaskMemFree() */
static WCHAR* ma_context_get_default_device_id__wasapi(ma_context* pContext, ma_device_type deviceType) /* Free the returned pointer with ma_CoTaskMemFree() */
hr = ma_CoCreateInstance(pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
static ma_result ma_context_get_device_info_from_MMDevice__wasapi(ma_context* pContext, ma_IMMDevice* pMMDevice, LPWSTR pDefaultDeviceID, ma_bool32 onlySimpleInfo, ma_device_info* pInfo)
static ma_result ma_context_get_device_info_from_MMDevice__wasapi(ma_context* pContext, ma_IMMDevice* pMMDevice, WCHAR* pDefaultDeviceID, ma_bool32 onlySimpleInfo, ma_device_info* pInfo)
static ma_result ma_context_get_IAudioClient_Desktop__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_IAudioClient** ppAudioClient, ma_IMMDevice** ppMMDevice)
static ma_result ma_context_get_IAudioClient_Desktop__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, MA_PROPVARIANT* pActivationParams, ma_IAudioClient** ppAudioClient, ma_IMMDevice** ppMMDevice)
static ma_result ma_context_get_IAudioClient_UWP__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_IAudioClient** ppAudioClient, ma_IUnknown** ppActivatedInterface)
static ma_result ma_context_get_IAudioClient_UWP__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, MA_PROPVARIANT* pActivationParams, ma_IAudioClient** ppAudioClient, ma_IUnknown** ppActivatedInterface)
#if defined(__cplusplus)
hr = StringFromIID(iid, &iidStr);
#else
hr = StringFromIID(&iid, &iidStr);
#endif
if (FAILED(hr)) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to convert device IID to string for ActivateAudioInterfaceAsync(). Out of memory.");
return ma_result_from_HRESULT(hr);
#if defined(__cplusplus)
hr = StringFromIID(iid, &iidStr);
#else
hr = StringFromIID(&iid, &iidStr);
#endif
if (FAILED(hr)) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to convert device IID to string for ActivateAudioInterfaceAsync(). Out of memory.\n");
return ma_result_from_HRESULT(hr);
}
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create event for waiting for ActivateAudioInterfaceAsync().");
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create event for waiting for ActivateAudioInterfaceAsync().\n");
#if defined(__cplusplus)
hr = ActivateAudioInterfaceAsync(iidStr, MA_IID_IAudioClient, NULL, (IActivateAudioInterfaceCompletionHandler*)&completionHandler, (IActivateAudioInterfaceAsyncOperation**)&pAsyncOp);
#else
hr = ActivateAudioInterfaceAsync(iidStr, &MA_IID_IAudioClient, NULL, (IActivateAudioInterfaceCompletionHandler*)&completionHandler, (IActivateAudioInterfaceAsyncOperation**)&pAsyncOp);
#endif
hr = ((MA_PFN_ActivateAudioInterfaceAsync)pContext->wasapi.ActivateAudioInterfaceAsync)(iidStr, &MA_IID_IAudioClient, pActivationParams, (ma_IActivateAudioInterfaceCompletionHandler*)&completionHandler, (ma_IActivateAudioInterfaceAsyncOperation**)&pAsyncOp);
/* https://docs.microsoft.com/en-us/windows/win32/api/audioclientactivationparams/ne-audioclientactivationparams-audioclient_activation_type */
typedef enum
{
MA_AUDIOCLIENT_ACTIVATION_TYPE_DEFAULT,
MA_AUDIOCLIENT_ACTIVATION_TYPE_PROCESS_LOOPBACK
} MA_AUDIOCLIENT_ACTIVATION_TYPE;
/* https://docs.microsoft.com/en-us/windows/win32/api/audioclientactivationparams/ne-audioclientactivationparams-process_loopback_mode */
typedef enum
{
MA_PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE,
MA_PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE
} MA_PROCESS_LOOPBACK_MODE;
/* https://docs.microsoft.com/en-us/windows/win32/api/audioclientactivationparams/ns-audioclientactivationparams-audioclient_process_loopback_params */
typedef struct
{
DWORD TargetProcessId;
MA_PROCESS_LOOPBACK_MODE ProcessLoopbackMode;
} MA_AUDIOCLIENT_PROCESS_LOOPBACK_PARAMS;
static ma_result ma_context_get_IAudioClient__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_IAudioClient** ppAudioClient, ma_WASAPIDeviceInterface** ppDeviceInterface)
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable:4201) /* nonstandard extension used: nameless struct/union */
#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic" /* For ISO C99 doesn't support unnamed structs/unions [-Wpedantic] */
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc11-extensions" /* anonymous unions are a C11 extension */
#endif
#endif
/* https://docs.microsoft.com/en-us/windows/win32/api/audioclientactivationparams/ns-audioclientactivationparams-audioclient_activation_params */
typedef struct
{
MA_AUDIOCLIENT_ACTIVATION_TYPE ActivationType;
union
{
MA_AUDIOCLIENT_PROCESS_LOOPBACK_PARAMS ProcessLoopbackParams;
};
} MA_AUDIOCLIENT_ACTIVATION_PARAMS;
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
#pragma GCC diagnostic pop
#endif
#define MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK L"VAD\\Process_Loopback"
static ma_result ma_context_get_IAudioClient__wasapi(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_uint32 loopbackProcessID, ma_bool32 loopbackProcessExclude, ma_IAudioClient** ppAudioClient, ma_WASAPIDeviceInterface** ppDeviceInterface)
ma_result result;
ma_bool32 usingProcessLoopback = MA_FALSE;
MA_AUDIOCLIENT_ACTIVATION_PARAMS audioclientActivationParams;
MA_PROPVARIANT activationParams;
MA_PROPVARIANT* pActivationParams = NULL;
ma_device_id virtualDeviceID;
/* Activation parameters specific to loopback mode. Note that process-specific loopback will only work when a default device ID is specified. */
if (deviceType == ma_device_type_loopback && loopbackProcessID != 0 && pDeviceID == NULL) {
usingProcessLoopback = MA_TRUE;
}
if (usingProcessLoopback) {
MA_ZERO_OBJECT(&audioclientActivationParams);
audioclientActivationParams.ActivationType = MA_AUDIOCLIENT_ACTIVATION_TYPE_PROCESS_LOOPBACK;
audioclientActivationParams.ProcessLoopbackParams.ProcessLoopbackMode = (loopbackProcessExclude) ? MA_PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE : MA_PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE;
audioclientActivationParams.ProcessLoopbackParams.TargetProcessId = (DWORD)loopbackProcessID;
ma_PropVariantInit(&activationParams);
activationParams.vt = MA_VT_BLOB;
activationParams.blob.cbSize = sizeof(audioclientActivationParams);
activationParams.blob.pBlobData = (BYTE*)&audioclientActivationParams;
pActivationParams = &activationParams;
/* When requesting a specific device ID we need to use a special device ID. */
MA_COPY_MEMORY(virtualDeviceID.wasapi, MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK, (wcslen(MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK) + 1) * sizeof(wchar_t)); /* +1 for the null terminator. */
pDeviceID = &virtualDeviceID;
} else {
pActivationParams = NULL; /* No activation parameters required. */
}
return ma_context_get_IAudioClient_Desktop__wasapi(pContext, deviceType, pDeviceID, ppAudioClient, ppDeviceInterface);
result = ma_context_get_IAudioClient_Desktop__wasapi(pContext, deviceType, pDeviceID, pActivationParams, ppAudioClient, ppDeviceInterface);
return ma_context_get_IAudioClient_UWP__wasapi(pContext, deviceType, pDeviceID, ppAudioClient, ppDeviceInterface);
result = ma_context_get_IAudioClient_UWP__wasapi(pContext, deviceType, pDeviceID, pActivationParams, ppAudioClient, ppDeviceInterface);
/*
If loopback mode was requested with a process ID and initialization failed, it could be because it's
trying to run on an older version of Windows where it's not supported. We need to let the caller
know about this with a log message.
*/
if (result != MA_SUCCESS) {
if (usingProcessLoopback) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Loopback mode requested to %s process ID %u, but initialization failed. Support for this feature begins with Windows 10 Build 20348. Confirm your version of Windows or consider not using process-specific loopback.\n", (loopbackProcessExclude) ? "exclude" : "include", loopbackProcessID);
}
}
return result;
hr = ma_CoCreateInstance(pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
result = ma_context_get_IAudioClient__wasapi(pContext, deviceType, pDeviceID, &pData->pAudioClient, &pDeviceInterface);
result = ma_context_get_IAudioClient__wasapi(pContext, deviceType, pDeviceID, pData->loopbackProcessID, pData->loopbackProcessExclude, &pData->pAudioClient, &pDeviceInterface);
WAVEFORMATEXTENSIBLE* pNativeFormat = NULL;
hr = ma_IAudioClient_GetMixFormat((ma_IAudioClient*)pData->pAudioClient, (WAVEFORMATEX**)&pNativeFormat);
MA_WAVEFORMATEXTENSIBLE* pNativeFormat = NULL;
hr = ma_IAudioClient_GetMixFormat((ma_IAudioClient*)pData->pAudioClient, (MA_WAVEFORMATEX**)&pNativeFormat);
result = MA_FORMAT_NOT_SUPPORTED;
/* When using process-specific loopback, GetMixFormat() seems to always fail. */
if (usingProcessLoopback) {
wf.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
wf.nChannels = 2;
wf.nSamplesPerSec = 44100;
wf.wBitsPerSample = 32;
wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
wf.cbSize = sizeof(MA_WAVEFORMATEX);
result = MA_SUCCESS;
} else {
result = MA_FORMAT_NOT_SUPPORTED;
}
MA_COPY_MEMORY(&wf, pNativeFormat, sizeof(wf));
/*
I've seen cases where cbSize will be set to sizeof(WAVEFORMATEX) even though the structure itself
is given the format tag of WAVE_FORMAT_EXTENSIBLE. If the format tag is WAVE_FORMAT_EXTENSIBLE
want to make sure we copy the whole WAVEFORMATEXTENSIBLE structure. Otherwise we'll have to be
safe and only copy the WAVEFORMATEX part.
*/
if (pNativeFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
MA_COPY_MEMORY(&wf, pNativeFormat, sizeof(MA_WAVEFORMATEXTENSIBLE));
} else {
/* I've seen a case where cbSize was set to 0. Assume sizeof(WAVEFORMATEX) in this case. */
size_t cbSize = pNativeFormat->cbSize;
if (cbSize == 0) {
cbSize = sizeof(MA_WAVEFORMATEX);
}
/* Make sure we don't copy more than the capacity of `wf`. */
if (cbSize > sizeof(wf)) {
cbSize = sizeof(wf);
}
MA_COPY_MEMORY(&wf, pNativeFormat, cbSize);
}
wf.Format.nSamplesPerSec = (pData->sampleRateIn != 0) ? pData->sampleRateIn : MA_DEFAULT_SAMPLE_RATE;
wf.Format.nAvgBytesPerSec = wf.Format.nSamplesPerSec * wf.Format.nBlockAlign;
wf.nSamplesPerSec = (pData->sampleRateIn != 0) ? pData->sampleRateIn : MA_DEFAULT_SAMPLE_RATE;
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
/* Get the internal channel map based on the channel mask. */
ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pData->channelsOut, pData->channelMapOut);
/*
Get the internal channel map based on the channel mask. There is a possibility that GetMixFormat() returns
a WAVEFORMATEX instead of a WAVEFORMATEXTENSIBLE, in which case the channel mask will be undefined. In this
case we'll just use the default channel map.
*/
if (wf.wFormatTag == WAVE_FORMAT_EXTENSIBLE || wf.cbSize >= sizeof(MA_WAVEFORMATEXTENSIBLE)) {
ma_channel_mask_to_channel_map__win32(wf.dwChannelMask, pData->channelsOut, pData->channelMapOut);
} else {
ma_channel_map_init_standard(ma_standard_channel_map_microsoft, pData->channelMapOut, ma_countof(pData->channelMapOut), pData->channelsOut);
}
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY, wf.Format.nSamplesPerSec);
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY, wf.nSamplesPerSec);
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE, wf.Format.nSamplesPerSec);
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE, wf.nSamplesPerSec);
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, wf.Format.nSamplesPerSec);
pData->periodSizeInFramesOut = ma_calculate_buffer_size_in_frames_from_milliseconds(pData->periodSizeInMillisecondsIn, wf.nSamplesPerSec);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, bufferDuration, (WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, bufferDuration, (MA_WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, bufferDuration, (WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, bufferDuration, (MA_WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient3_GetSharedModeEnginePeriod(pAudioClient3, (WAVEFORMATEX*)&wf, &defaultPeriodInFrames, &fundamentalPeriodInFrames, &minPeriodInFrames, &maxPeriodInFrames);
hr = ma_IAudioClient3_GetSharedModeEnginePeriod(pAudioClient3, (MA_WAVEFORMATEX*)&wf, &defaultPeriodInFrames, &fundamentalPeriodInFrames, &minPeriodInFrames, &maxPeriodInFrames);
hr = ma_IAudioClient3_InitializeSharedAudioStream(pAudioClient3, streamFlags & ~(MA_AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | MA_AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY), actualPeriodInFrames, (WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient3_InitializeSharedAudioStream(pAudioClient3, streamFlags & ~(MA_AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | MA_AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY), actualPeriodInFrames, (MA_WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, 0, (WAVEFORMATEX*)&wf, NULL);
hr = ma_IAudioClient_Initialize((ma_IAudioClient*)pData->pAudioClient, shareMode, streamFlags, bufferDuration, 0, (const MA_WAVEFORMATEX*)&wf, NULL);
/*
When using process loopback mode, retrieval of the buffer size seems to result in totally
incorrect values. In this case we'll just assume it's the same size as what we requested
when we initialized the client.
*/
if (usingProcessLoopback) {
bufferSizeInFrames = (ma_uint32)((periodDurationInMicroseconds * pData->periodsOut) * pData->sampleRateOut / 1000000);
}
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, pDevice->wasapi.hEventCapture);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, (HANDLE)pDevice->wasapi.hEventCapture);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, pDevice->wasapi.hEventPlayback);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, (HANDLE)pDevice->wasapi.hEventPlayback);
pDevice->wasapi.noAutoConvertSRC = pConfig->wasapi.noAutoConvertSRC;
pDevice->wasapi.noDefaultQualitySRC = pConfig->wasapi.noDefaultQualitySRC;
pDevice->wasapi.noHardwareOffloading = pConfig->wasapi.noHardwareOffloading;
pDevice->wasapi.usage = pConfig->wasapi.usage;
pDevice->wasapi.noAutoConvertSRC = pConfig->wasapi.noAutoConvertSRC;
pDevice->wasapi.noDefaultQualitySRC = pConfig->wasapi.noDefaultQualitySRC;
pDevice->wasapi.noHardwareOffloading = pConfig->wasapi.noHardwareOffloading;
pDevice->wasapi.loopbackProcessID = pConfig->wasapi.loopbackProcessID;
pDevice->wasapi.loopbackProcessExclude = pConfig->wasapi.loopbackProcessExclude;
pDevice->wasapi.hEventCapture = CreateEventW(NULL, FALSE, FALSE, NULL); /* Auto reset, unsignaled by default. */
pDevice->wasapi.hEventCapture = (ma_handle)CreateEventA(NULL, FALSE, FALSE, NULL); /* Auto reset, unsignaled by default. */
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, pDevice->wasapi.hEventCapture);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, (HANDLE)pDevice->wasapi.hEventCapture);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, pDevice->wasapi.hEventPlayback);
ma_IAudioClient_SetEventHandle((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, (HANDLE)pDevice->wasapi.hEventPlayback);
if ((pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.pDeviceID == NULL) {
if ((pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex || pConfig->deviceType == ma_device_type_loopback) && pConfig->capture.pDeviceID == NULL) {
hr = ma_CoCreateInstance(pDevice->pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
ma_mutex_init(&pDevice->wasapi.rerouteLock);
hr = ma_CoCreateInstance(pDevice->pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_FALSE);
c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_FALSE);
ma_atomic_bool32_set(&pDevice->wasapi.isStartedCapture, MA_FALSE);
ma_atomic_bool32_set(&pDevice->wasapi.isStartedPlayback, MA_FALSE);
MA_ASSERT(pDevice != NULL);
if (pDevice->pContext->wasapi.hAvrt) {
const char* pTaskName = ma_to_usage_string__wasapi(pDevice->wasapi.usage);
if (pTaskName) {
DWORD idx = 0;
pDevice->wasapi.hAvrtHandle = (ma_handle)((MA_PFN_AvSetMmThreadCharacteristicsA)pDevice->pContext->wasapi.AvSetMmThreadCharacteristicsA)(pTaskName, &idx);
}
}
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device.");
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device. HRESULT = %d.", (int)hr);
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device.");
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device. HRESULT = %d.", (int)hr);
static ma_result ma_device_stop__wasapi(ma_device* pDevice)
/* Wait for any rerouting to finish before attempting to start the device. */
ma_mutex_lock(&pDevice->wasapi.rerouteLock);
{
result = ma_device_start__wasapi_nolock(pDevice);
}
ma_mutex_unlock(&pDevice->wasapi.rerouteLock);
return result;
}
static ma_result ma_device_stop__wasapi_nolock(ma_device* pDevice)
WaitForSingleObject(pDevice->wasapi.hEventPlayback, waitTime);
ResetEvent(pDevice->wasapi.hEventPlayback); /* Manual reset. */
WaitForSingleObject((HANDLE)pDevice->wasapi.hEventPlayback, waitTime * 1000);
ResetEvent((HANDLE)pDevice->wasapi.hEventPlayback); /* Manual reset. */
}
static ma_result ma_device_stop__wasapi(ma_device* pDevice)
{
ma_result result;
MA_ASSERT(pDevice != NULL);
/* Wait for any rerouting to finish before attempting to stop the device. */
ma_mutex_lock(&pDevice->wasapi.rerouteLock);
{
result = ma_device_stop__wasapi_nolock(pDevice);
}
ma_mutex_unlock(&pDevice->wasapi.rerouteLock);
return result;
/*
There have been reports that indicate that at times the AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY is reported for every
call to IAudioCaptureClient_GetBuffer() above which results in spamming of the debug messages below. To partially
work around this, I'm only outputting these messages when MA_DEBUG_OUTPUT is explicitly defined. The better solution
would be to figure out why the flag is always getting reported.
*/
#if defined(MA_DEBUG_OUTPUT)
{
if (flags != 0) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Capture Flags: %ld\n", flags);
if ((flags & MA_AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY) != 0) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Data discontinuity (possible overrun). Attempting recovery. mappedBufferCaptureCap=%d\n", pDevice->wasapi.mappedBufferCaptureCap);
}
}
}
#endif
If we got an overrun it probably means we're straddling the end of the buffer. In order to prevent
a never-ending sequence of glitches we're going to recover by completely clearing out the capture
buffer.
If we got an overrun it probably means we're straddling the end of the buffer. In normal capture
mode this is the fault of the client application because they're responsible for ensuring data is
processed fast enough. In duplex mode, however, the processing of audio is tied to the playback
device, so this can possibly be the result of a timing de-sync.
In capture mode we're not going to do any kind of recovery because the real fix is for the client
application to process faster. In duplex mode, we'll treat this as a desync and reset the buffers
to prevent a never-ending sequence of glitches due to straddling the end of the buffer.
{
ma_uint32 iterationCount = 4; /* Safety to prevent an infinite loop. */
if (pDevice->type == ma_device_type_duplex) {
/*
Experiment:
If we empty out the *entire* buffer we may end up putting ourselves into an underrun position
which isn't really any better than the overrun we're probably in right now. Instead we'll just
empty out about half.
*/
/*
The buffer has been completely emptied or an error occurred. In this case we'll need
to reset the state of the mapped buffer which will trigger the next iteration to get
a fresh buffer from WASAPI.
*/
pDevice->wasapi.pMappedBufferCapture = NULL;
pDevice->wasapi.mappedBufferCaptureCap = 0;
pDevice->wasapi.mappedBufferCaptureLen = 0;
if (hr == MA_AUDCLNT_S_BUFFER_EMPTY) {
if ((flags & MA_AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY) != 0) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Data discontinuity recovery: Buffer emptied, and data discontinuity still reported.\n");
} else {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Data discontinuity recovery: Buffer emptied.\n");
}
}
if (FAILED(hr)) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Data discontinuity recovery: IAudioCaptureClient_GetBuffer() failed with %ld.\n", hr);
}
}
/* We should not have a valid buffer at this point so make sure everything is empty. */
pDevice->wasapi.pMappedBufferCapture = NULL;
pDevice->wasapi.mappedBufferCaptureCap = 0;
pDevice->wasapi.mappedBufferCaptureLen = 0;
} else {
/* The data is clean. */
pDevice->wasapi.mappedBufferCaptureLen = pDevice->wasapi.mappedBufferCaptureCap;
if (flags != 0) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Capture Flags: %ld\n", flags);
/* If at this point we have a valid buffer mapped, make sure the buffer length is set appropriately. */
if (pDevice->wasapi.pMappedBufferCapture != NULL) {
pDevice->wasapi.mappedBufferCaptureLen = pDevice->wasapi.mappedBufferCaptureCap;
}
if (WaitForSingleObject(pDevice->wasapi.hEventCapture, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
/* Experiment: Use a shorter timeout for loopback mode. */
DWORD timeoutInMilliseconds = MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS;
if (pDevice->type == ma_device_type_loopback) {
timeoutInMilliseconds = 10;
}
if (WaitForSingleObject((HANDLE)pDevice->wasapi.hEventCapture, timeoutInMilliseconds) != WAIT_OBJECT_0) {
if (pContext->wasapi.commandThread != NULL) {
ma_context_command__wasapi cmd = ma_context_init_command__wasapi(MA_CONTEXT_COMMAND_QUIT__WASAPI);
ma_context_post_command__wasapi(pContext, &cmd);
ma_thread_wait(&pContext->wasapi.commandThread);
ma_context_post_command__wasapi(pContext, &cmd);
ma_thread_wait(&pContext->wasapi.commandThread);
/* Only after the thread has been terminated can we uninitialize the sync objects for the command thread. */
ma_semaphore_uninit(&pContext->wasapi.commandSem);
ma_mutex_uninit(&pContext->wasapi.commandLock);
if (pContext->wasapi.hAvrt) {
ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt);
pContext->wasapi.hAvrt = NULL;
}
#if defined(MA_WIN32_UWP)
{
if (pContext->wasapi.hMMDevapi) {
ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi);
pContext->wasapi.hMMDevapi = NULL;
}
_VerifyVersionInfoW = (ma_PFNVerifyVersionInfoW )ma_dlsym(pContext, kernel32DLL, "VerifyVersionInfoW");
_VerSetConditionMask = (ma_PFNVerSetConditionMask)ma_dlsym(pContext, kernel32DLL, "VerSetConditionMask");
_VerifyVersionInfoW = (ma_PFNVerifyVersionInfoW )ma_dlsym(ma_context_get_log(pContext), kernel32DLL, "VerifyVersionInfoW");
_VerSetConditionMask = (ma_PFNVerSetConditionMask)ma_dlsym(ma_context_get_log(pContext), kernel32DLL, "VerSetConditionMask");
#if defined(MA_WIN32_UWP)
{
/* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */
pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll");
if (pContext->wasapi.hMMDevapi) {
pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync");
if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) {
ma_semaphore_uninit(&pContext->wasapi.commandSem);
ma_mutex_uninit(&pContext->wasapi.commandLock);
ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi);
return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */
}
} else {
ma_semaphore_uninit(&pContext->wasapi.commandSem);
ma_mutex_uninit(&pContext->wasapi.commandLock);
return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */
}
}
#endif
/* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */
pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll");
if (pContext->wasapi.hAvrt) {
pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA");
pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics");
/* If either function could not be found, disable use of avrt entirely. */
if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) {
pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL;
pContext->wasapi.AvRevertMmThreadcharacteristics = NULL;
ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt);
pContext->wasapi.hAvrt = NULL;
}
}
HRESULT (STDMETHODCALLTYPE * GetFormat) (ma_IDirectSoundBuffer* pThis, WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten);
HRESULT (STDMETHODCALLTYPE * GetFormat) (ma_IDirectSoundBuffer* pThis, MA_WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten);
static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetFormat(ma_IDirectSoundBuffer* pThis, WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten) { return pThis->lpVtbl->GetFormat(pThis, pFormat, dwSizeAllocated, pSizeWritten); }
static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetFormat(ma_IDirectSoundBuffer* pThis, MA_WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten) { return pThis->lpVtbl->GetFormat(pThis, pFormat, dwSizeAllocated, pSizeWritten); }
static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetFormat(ma_IDirectSoundBuffer* pThis, const WAVEFORMATEX* pFormat) { return pThis->lpVtbl->SetFormat(pThis, pFormat); }
static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetFormat(ma_IDirectSoundBuffer* pThis, const MA_WAVEFORMATEX* pFormat) { return pThis->lpVtbl->SetFormat(pThis, pFormat); }
HRESULT (STDMETHODCALLTYPE * GetFormat) (ma_IDirectSoundCaptureBuffer* pThis, WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten);
HRESULT (STDMETHODCALLTYPE * GetFormat) (ma_IDirectSoundCaptureBuffer* pThis, MA_WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten);
static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetFormat(ma_IDirectSoundCaptureBuffer* pThis, WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten) { return pThis->lpVtbl->GetFormat(pThis, pFormat, dwSizeAllocated, pSizeWritten); }
static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetFormat(ma_IDirectSoundCaptureBuffer* pThis, MA_WAVEFORMATEX* pFormat, DWORD dwSizeAllocated, DWORD* pSizeWritten) { return pThis->lpVtbl->GetFormat(pThis, pFormat, dwSizeAllocated, pSizeWritten); }
typedef BOOL (CALLBACK * ma_DSEnumCallbackAProc) (LPGUID pDeviceGUID, LPCSTR pDeviceDescription, LPCSTR pModule, LPVOID pContext);
typedef HRESULT (WINAPI * ma_DirectSoundCreateProc) (const GUID* pcGuidDevice, ma_IDirectSound** ppDS8, LPUNKNOWN pUnkOuter);
typedef HRESULT (WINAPI * ma_DirectSoundEnumerateAProc) (ma_DSEnumCallbackAProc pDSEnumCallback, LPVOID pContext);
typedef HRESULT (WINAPI * ma_DirectSoundCaptureCreateProc) (const GUID* pcGuidDevice, ma_IDirectSoundCapture** ppDSC8, LPUNKNOWN pUnkOuter);
typedef HRESULT (WINAPI * ma_DirectSoundCaptureEnumerateAProc)(ma_DSEnumCallbackAProc pDSEnumCallback, LPVOID pContext);
typedef BOOL (CALLBACK * ma_DSEnumCallbackAProc) (GUID* pDeviceGUID, const char* pDeviceDescription, const char* pModule, void* pContext);
typedef HRESULT (WINAPI * ma_DirectSoundCreateProc) (const GUID* pcGuidDevice, ma_IDirectSound** ppDS8, ma_IUnknown* pUnkOuter);
typedef HRESULT (WINAPI * ma_DirectSoundEnumerateAProc) (ma_DSEnumCallbackAProc pDSEnumCallback, void* pContext);
typedef HRESULT (WINAPI * ma_DirectSoundCaptureCreateProc) (const GUID* pcGuidDevice, ma_IDirectSoundCapture** ppDSC8, ma_IUnknown* pUnkOuter);
typedef HRESULT (WINAPI * ma_DirectSoundCaptureEnumerateAProc)(ma_DSEnumCallbackAProc pDSEnumCallback, void* pContext);
static BOOL CALLBACK ma_context_enumerate_devices_callback__dsound(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
static BOOL CALLBACK ma_context_enumerate_devices_callback__dsound(GUID* lpGuid, const char* lpcstrDescription, const char* lpcstrModule, void* lpContext)
static BOOL CALLBACK ma_context_get_device_info_callback__dsound(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
static BOOL CALLBACK ma_context_get_device_info_callback__dsound(GUID* lpGuid, const char* lpcstrDescription, const char* lpcstrModule, void* lpContext)
static ma_result ma_config_to_WAVEFORMATEXTENSIBLE(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, const ma_channel* pChannelMap, WAVEFORMATEXTENSIBLE* pWF)
static ma_result ma_config_to_WAVEFORMATEXTENSIBLE(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, const ma_channel* pChannelMap, MA_WAVEFORMATEXTENSIBLE* pWF)
pWF->Format.cbSize = sizeof(*pWF);
pWF->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
pWF->Format.nChannels = (WORD)channels;
pWF->Format.nSamplesPerSec = (DWORD)sampleRate;
pWF->Format.wBitsPerSample = (WORD)(ma_get_bytes_per_sample(format)*8);
pWF->Format.nBlockAlign = (WORD)(pWF->Format.nChannels * pWF->Format.wBitsPerSample / 8);
pWF->Format.nAvgBytesPerSec = pWF->Format.nBlockAlign * pWF->Format.nSamplesPerSec;
pWF->Samples.wValidBitsPerSample = pWF->Format.wBitsPerSample;
pWF->cbSize = sizeof(*pWF);
pWF->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
pWF->nChannels = (WORD)channels;
pWF->nSamplesPerSec = (DWORD)sampleRate;
pWF->wBitsPerSample = (WORD)(ma_get_bytes_per_sample(format)*8);
pWF->nBlockAlign = (WORD)(pWF->nChannels * pWF->wBitsPerSample / 8);
pWF->nAvgBytesPerSec = pWF->nBlockAlign * pWF->nSamplesPerSec;
pWF->Samples.wValidBitsPerSample = pWF->wBitsPerSample;
result = ma_context_get_format_info_for_IDirectSoundCapture__dsound(pDevice->pContext, (ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &wf.Format.nChannels, &wf.Format.wBitsPerSample, &wf.Format.nSamplesPerSec);
result = ma_context_get_format_info_for_IDirectSoundCapture__dsound(pDevice->pContext, (ma_IDirectSoundCapture*)pDevice->dsound.pCapture, &wf.nChannels, &wf.wBitsPerSample, &wf.nSamplesPerSec);
wf.Format.nBlockAlign = (WORD)(wf.Format.nChannels * wf.Format.wBitsPerSample / 8);
wf.Format.nAvgBytesPerSec = wf.Format.nBlockAlign * wf.Format.nSamplesPerSec;
wf.Samples.wValidBitsPerSample = wf.Format.wBitsPerSample;
wf.nBlockAlign = (WORD)(wf.nChannels * wf.wBitsPerSample / 8);
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
wf.Samples.wValidBitsPerSample = wf.wBitsPerSample;
periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__dsound(pDescriptorCapture, wf.Format.nSamplesPerSec, pConfig->performanceProfile);
periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__dsound(pDescriptorCapture, wf.nSamplesPerSec, pConfig->performanceProfile);
descDS.dwBufferBytes = periodSizeInFrames * periodCount * wf.Format.nBlockAlign;
descDS.lpwfxFormat = (WAVEFORMATEX*)&wf;
descDS.dwBufferBytes = periodSizeInFrames * periodCount * wf.nBlockAlign;
descDS.lpwfxFormat = (MA_WAVEFORMATEX*)&wf;
pActualFormat = (WAVEFORMATEXTENSIBLE*)rawdata;
hr = ma_IDirectSoundCaptureBuffer_GetFormat((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, (WAVEFORMATEX*)pActualFormat, sizeof(rawdata), NULL);
pActualFormat = (MA_WAVEFORMATEXTENSIBLE*)rawdata;
hr = ma_IDirectSoundCaptureBuffer_GetFormat((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, (MA_WAVEFORMATEX*)pActualFormat, sizeof(rawdata), NULL);
pDescriptorCapture->format = ma_format_from_WAVEFORMATEX((WAVEFORMATEX*)pActualFormat);
pDescriptorCapture->channels = pActualFormat->Format.nChannels;
pDescriptorCapture->sampleRate = pActualFormat->Format.nSamplesPerSec;
pDescriptorCapture->format = ma_format_from_WAVEFORMATEX((MA_WAVEFORMATEX*)pActualFormat);
pDescriptorCapture->channels = pActualFormat->nChannels;
pDescriptorCapture->sampleRate = pActualFormat->nSamplesPerSec;
/* Look at the speaker configuration to get a better idea on the channel count. */
if (SUCCEEDED(ma_IDirectSound_GetSpeakerConfig((ma_IDirectSound*)pDevice->dsound.pPlayback, &speakerConfig))) {
ma_get_channels_from_speaker_config__dsound(speakerConfig, &wf.Format.nChannels, &wf.dwChannelMask);
}
} else {
/* It does not support stereo, which means we are stuck with mono. */
wf.Format.nChannels = 1;
/* Look at the speaker configuration to get a better idea on the channel count. */
if (SUCCEEDED(ma_IDirectSound_GetSpeakerConfig((ma_IDirectSound*)pDevice->dsound.pPlayback, &speakerConfig))) {
ma_get_channels_from_speaker_config__dsound(speakerConfig, &nativeChannelCount, &nativeChannelMask);
wf.Format.nSamplesPerSec = ma_get_best_sample_rate_within_range(caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate);
wf.nSamplesPerSec = ma_get_best_sample_rate_within_range(caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate);
wf.Format.nBlockAlign = (WORD)(wf.Format.nChannels * wf.Format.wBitsPerSample / 8);
wf.Format.nAvgBytesPerSec = wf.Format.nBlockAlign * wf.Format.nSamplesPerSec;
wf.nBlockAlign = (WORD)(wf.nChannels * wf.wBitsPerSample / 8);
wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
hr = ma_IDirectSoundBuffer_SetFormat((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackPrimaryBuffer, (WAVEFORMATEX*)&wf);
hr = ma_IDirectSoundBuffer_SetFormat((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackPrimaryBuffer, (MA_WAVEFORMATEX*)&wf);
ma_device_uninit__dsound(pDevice);
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to set format of playback device's primary buffer.");
return ma_result_from_HRESULT(hr);
/*
If setting of the format failed we'll try again with some fallback settings. On Windows 98 I have
observed that IEEE_FLOAT does not work. We'll therefore enforce PCM. I also had issues where a
sample rate of 48000 did not work correctly. Not sure if it was a driver issue or not, but will
use 44100 for the sample rate.
*/
wf.cbSize = 18; /* NOTE: Don't use sizeof(MA_WAVEFORMATEX) here because it's got an extra 2 bytes due to padding. */
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.wBitsPerSample = 16;
wf.nChannels = nativeChannelCount;
wf.nSamplesPerSec = 44100;
wf.nBlockAlign = wf.nChannels * (wf.wBitsPerSample / 8);
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
hr = ma_IDirectSoundBuffer_SetFormat((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackPrimaryBuffer, (MA_WAVEFORMATEX*)&wf);
if (FAILED(hr)) {
ma_device_uninit__dsound(pDevice);
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] Failed to set format of playback device's primary buffer.");
return ma_result_from_HRESULT(hr);
}
pActualFormat = (WAVEFORMATEXTENSIBLE*)rawdata;
hr = ma_IDirectSoundBuffer_GetFormat((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackPrimaryBuffer, (WAVEFORMATEX*)pActualFormat, sizeof(rawdata), NULL);
pActualFormat = (MA_WAVEFORMATEXTENSIBLE*)rawdata;
hr = ma_IDirectSoundBuffer_GetFormat((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackPrimaryBuffer, (MA_WAVEFORMATEX*)pActualFormat, sizeof(rawdata), NULL);
pDescriptorPlayback->format = ma_format_from_WAVEFORMATEX((WAVEFORMATEX*)pActualFormat);
pDescriptorPlayback->channels = pActualFormat->Format.nChannels;
pDescriptorPlayback->sampleRate = pActualFormat->Format.nSamplesPerSec;
pDescriptorPlayback->format = ma_format_from_WAVEFORMATEX((MA_WAVEFORMATEX*)pActualFormat);
pDescriptorPlayback->channels = pActualFormat->nChannels;
pDescriptorPlayback->sampleRate = pActualFormat->nSamplesPerSec;
pContext->dsound.DirectSoundCreate = ma_dlsym(ma_context_get_log(pContext), pContext->dsound.hDSoundDLL, "DirectSoundCreate");
pContext->dsound.DirectSoundEnumerateA = ma_dlsym(ma_context_get_log(pContext), pContext->dsound.hDSoundDLL, "DirectSoundEnumerateA");
pContext->dsound.DirectSoundCaptureCreate = ma_dlsym(ma_context_get_log(pContext), pContext->dsound.hDSoundDLL, "DirectSoundCaptureCreate");
pContext->dsound.DirectSoundCaptureEnumerateA = ma_dlsym(ma_context_get_log(pContext), pContext->dsound.hDSoundDLL, "DirectSoundCaptureEnumerateA");
pContext->dsound.DirectSoundCreate = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCreate");
pContext->dsound.DirectSoundEnumerateA = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundEnumerateA");
pContext->dsound.DirectSoundCaptureCreate = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCaptureCreate");
pContext->dsound.DirectSoundCaptureEnumerateA = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCaptureEnumerateA");
/*
We need to support all functions or nothing. DirectSound with Windows 95 seems to not work too
well in my testing. For example, it's missing DirectSoundCaptureEnumerateA(). This is a convenient
place to just disable the DirectSound backend for Windows 95.
*/
if (pContext->dsound.DirectSoundCreate == NULL ||
pContext->dsound.DirectSoundEnumerateA == NULL ||
pContext->dsound.DirectSoundCaptureCreate == NULL ||
pContext->dsound.DirectSoundCaptureEnumerateA == NULL) {
return MA_API_NOT_FOUND;
}
Some older compilers don't have WAVEOUTCAPS2A and WAVEINCAPS2A, so we'll need to write this ourselves. These structures
are exactly the same as the older ones but they have a few GUIDs for manufacturer/product/name identification. I'm keeping
the names the same as the Win32 library for consistency, but namespaced to avoid naming conflicts with the Win32 version.
Some build configurations will exclude the WinMM API. An example is when WIN32_LEAN_AND_MEAN
is defined. We need to define the types and functions we need manually.
#define MA_MMSYSERR_NOERROR 0
#define MA_MMSYSERR_ERROR 1
#define MA_MMSYSERR_BADDEVICEID 2
#define MA_MMSYSERR_INVALHANDLE 5
#define MA_MMSYSERR_NOMEM 7
#define MA_MMSYSERR_INVALFLAG 10
#define MA_MMSYSERR_INVALPARAM 11
#define MA_MMSYSERR_HANDLEBUSY 12
#define MA_CALLBACK_EVENT 0x00050000
#define MA_WAVE_ALLOWSYNC 0x0002
#define MA_WHDR_DONE 0x00000001
#define MA_WHDR_PREPARED 0x00000002
#define MA_WHDR_BEGINLOOP 0x00000004
#define MA_WHDR_ENDLOOP 0x00000008
#define MA_WHDR_INQUEUE 0x00000010
#define MA_MAXPNAMELEN 32
typedef void* MA_HWAVEIN;
typedef void* MA_HWAVEOUT;
typedef UINT MA_MMRESULT;
typedef UINT MA_MMVERSION;
typedef struct
{
WORD wMid;
WORD wPid;
MA_MMVERSION vDriverVersion;
CHAR szPname[MA_MAXPNAMELEN];
DWORD dwFormats;
WORD wChannels;
WORD wReserved1;
} MA_WAVEINCAPSA;
MMVERSION vDriverVersion;
CHAR szPname[MAXPNAMELEN];
MA_MMVERSION vDriverVersion;
CHAR szPname[MA_MAXPNAMELEN];
DWORD dwFormats;
WORD wChannels;
WORD wReserved1;
DWORD dwSupport;
} MA_WAVEOUTCAPSA;
typedef struct tagWAVEHDR
{
char* lpData;
DWORD dwBufferLength;
DWORD dwBytesRecorded;
DWORD_PTR dwUser;
DWORD dwFlags;
DWORD dwLoops;
struct tagWAVEHDR* lpNext;
DWORD_PTR reserved;
} MA_WAVEHDR;
typedef struct
{
WORD wMid;
WORD wPid;
MA_MMVERSION vDriverVersion;
CHAR szPname[MA_MAXPNAMELEN];
typedef UINT (WINAPI * MA_PFN_waveOutGetNumDevs)(void);
typedef MMRESULT (WINAPI * MA_PFN_waveOutGetDevCapsA)(ma_uintptr uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc);
typedef MMRESULT (WINAPI * MA_PFN_waveOutOpen)(LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
typedef MMRESULT (WINAPI * MA_PFN_waveOutClose)(HWAVEOUT hwo);
typedef MMRESULT (WINAPI * MA_PFN_waveOutPrepareHeader)(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveOutUnprepareHeader)(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveOutWrite)(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveOutReset)(HWAVEOUT hwo);
typedef UINT (WINAPI * MA_PFN_waveInGetNumDevs)(void);
typedef MMRESULT (WINAPI * MA_PFN_waveInGetDevCapsA)(ma_uintptr uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic);
typedef MMRESULT (WINAPI * MA_PFN_waveInOpen)(LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
typedef MMRESULT (WINAPI * MA_PFN_waveInClose)(HWAVEIN hwi);
typedef MMRESULT (WINAPI * MA_PFN_waveInPrepareHeader)(HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveInUnprepareHeader)(HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveInAddBuffer)(HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh);
typedef MMRESULT (WINAPI * MA_PFN_waveInStart)(HWAVEIN hwi);
typedef MMRESULT (WINAPI * MA_PFN_waveInReset)(HWAVEIN hwi);
typedef UINT (WINAPI * MA_PFN_waveOutGetNumDevs)(void);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutGetDevCapsA)(ma_uintptr uDeviceID, MA_WAVEOUTCAPSA* pwoc, UINT cbwoc);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutOpen)(MA_HWAVEOUT* phwo, UINT uDeviceID, const MA_WAVEFORMATEX* pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutClose)(MA_HWAVEOUT hwo);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutPrepareHeader)(MA_HWAVEOUT hwo, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutUnprepareHeader)(MA_HWAVEOUT hwo, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutWrite)(MA_HWAVEOUT hwo, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutReset)(MA_HWAVEOUT hwo);
typedef UINT (WINAPI * MA_PFN_waveInGetNumDevs)(void);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInGetDevCapsA)(ma_uintptr uDeviceID, MA_WAVEINCAPSA* pwic, UINT cbwic);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInOpen)(MA_HWAVEIN* phwi, UINT uDeviceID, const MA_WAVEFORMATEX* pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInClose)(MA_HWAVEIN hwi);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInPrepareHeader)(MA_HWAVEIN hwi, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInUnprepareHeader)(MA_HWAVEIN hwi, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInAddBuffer)(MA_HWAVEIN hwi, MA_WAVEHDR* pwh, UINT cbwh);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInStart)(MA_HWAVEIN hwi);
typedef MA_MMRESULT (WINAPI * MA_PFN_waveInReset)(MA_HWAVEIN hwi);
switch (resultMM) {
case MMSYSERR_NOERROR: return MA_SUCCESS;
case MMSYSERR_BADDEVICEID: return MA_INVALID_ARGS;
case MMSYSERR_INVALHANDLE: return MA_INVALID_ARGS;
case MMSYSERR_NOMEM: return MA_OUT_OF_MEMORY;
case MMSYSERR_INVALFLAG: return MA_INVALID_ARGS;
case MMSYSERR_INVALPARAM: return MA_INVALID_ARGS;
case MMSYSERR_HANDLEBUSY: return MA_BUSY;
case MMSYSERR_ERROR: return MA_ERROR;
default: return MA_ERROR;
switch (resultMM)
{
case MA_MMSYSERR_NOERROR: return MA_SUCCESS;
case MA_MMSYSERR_BADDEVICEID: return MA_INVALID_ARGS;
case MA_MMSYSERR_INVALHANDLE: return MA_INVALID_ARGS;
case MA_MMSYSERR_NOMEM: return MA_OUT_OF_MEMORY;
case MA_MMSYSERR_INVALFLAG: return MA_INVALID_ARGS;
case MA_MMSYSERR_INVALPARAM: return MA_INVALID_ARGS;
case MA_MMSYSERR_HANDLEBUSY: return MA_BUSY;
case MA_MMSYSERR_ERROR: return MA_ERROR;
default: return MA_ERROR;
LONG resultWin32 = ((MA_PFN_RegQueryValueExA)pContext->win32.RegQueryValueExA)(hKey, "Name", 0, NULL, (LPBYTE)nameFromReg, (LPDWORD)&nameFromRegSize);
LONG resultWin32 = ((MA_PFN_RegQueryValueExA)pContext->win32.RegQueryValueExA)(hKey, "Name", 0, NULL, (BYTE*)nameFromReg, (DWORD*)&nameFromRegSize);
result = ((MA_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(iPlaybackDevice, (WAVEOUTCAPSA*)&caps, sizeof(caps));
if (result == MMSYSERR_NOERROR) {
result = ((MA_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(iPlaybackDevice, (MA_WAVEOUTCAPSA*)&caps, sizeof(caps));
if (result == MA_MMSYSERR_NOERROR) {
result = ((MA_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(iCaptureDevice, (WAVEINCAPSA*)&caps, sizeof(caps));
if (result == MMSYSERR_NOERROR) {
result = ((MA_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(iCaptureDevice, (MA_WAVEINCAPSA*)&caps, sizeof(caps));
if (result == MA_MMSYSERR_NOERROR) {
result = ((MA_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(winMMDeviceID, (WAVEOUTCAPSA*)&caps, sizeof(caps));
if (result == MMSYSERR_NOERROR) {
result = ((MA_PFN_waveOutGetDevCapsA)pContext->winmm.waveOutGetDevCapsA)(winMMDeviceID, (MA_WAVEOUTCAPSA*)&caps, sizeof(caps));
if (result == MA_MMSYSERR_NOERROR) {
result = ((MA_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(winMMDeviceID, (WAVEINCAPSA*)&caps, sizeof(caps));
if (result == MMSYSERR_NOERROR) {
result = ((MA_PFN_waveInGetDevCapsA)pContext->winmm.waveInGetDevCapsA)(winMMDeviceID, (MA_WAVEINCAPSA*)&caps, sizeof(caps));
if (result == MA_MMSYSERR_NOERROR) {
((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
((MA_PFN_waveOutClose)pDevice->pContext->winmm.waveOutClose)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback);
((MA_PFN_waveOutClose)pDevice->pContext->winmm.waveOutClose)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback);
if (((MA_PFN_waveInGetDevCapsA)pDevice->pContext->winmm.waveInGetDevCapsA)(winMMDeviceIDCapture, &caps, sizeof(caps)) != MMSYSERR_NOERROR) {
if (((MA_PFN_waveInGetDevCapsA)pDevice->pContext->winmm.waveInGetDevCapsA)(winMMDeviceIDCapture, &caps, sizeof(caps)) != MA_MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInOpen)pDevice->pContext->winmm.waveInOpen)((LPHWAVEIN)&pDevice->winmm.hDeviceCapture, winMMDeviceIDCapture, &wf, (DWORD_PTR)pDevice->winmm.hEventCapture, (DWORD_PTR)pDevice, CALLBACK_EVENT | WAVE_ALLOWSYNC);
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInOpen)pDevice->pContext->winmm.waveInOpen)((MA_HWAVEIN*)&pDevice->winmm.hDeviceCapture, winMMDeviceIDCapture, &wf, (DWORD_PTR)pDevice->winmm.hEventCapture, (DWORD_PTR)pDevice, MA_CALLBACK_EVENT | MA_WAVE_ALLOWSYNC);
if (resultMM != MA_MMSYSERR_NOERROR) {
if (((MA_PFN_waveOutGetDevCapsA)pDevice->pContext->winmm.waveOutGetDevCapsA)(winMMDeviceIDPlayback, &caps, sizeof(caps)) != MMSYSERR_NOERROR) {
if (((MA_PFN_waveOutGetDevCapsA)pDevice->pContext->winmm.waveOutGetDevCapsA)(winMMDeviceIDPlayback, &caps, sizeof(caps)) != MA_MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveOutOpen)pDevice->pContext->winmm.waveOutOpen)((LPHWAVEOUT)&pDevice->winmm.hDevicePlayback, winMMDeviceIDPlayback, &wf, (DWORD_PTR)pDevice->winmm.hEventPlayback, (DWORD_PTR)pDevice, CALLBACK_EVENT | WAVE_ALLOWSYNC);
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveOutOpen)pDevice->pContext->winmm.waveOutOpen)((MA_HWAVEOUT*)&pDevice->winmm.hDevicePlayback, winMMDeviceIDPlayback, &wf, (DWORD_PTR)pDevice->winmm.hEventPlayback, (DWORD_PTR)pDevice, MA_CALLBACK_EVENT | MA_WAVE_ALLOWSYNC);
if (resultMM != MA_MMSYSERR_NOERROR) {
heapSize += sizeof(WAVEHDR)*pDescriptorCapture->periodCount + (pDescriptorCapture->periodSizeInFrames * pDescriptorCapture->periodCount * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels));
heapSize += sizeof(MA_WAVEHDR)*pDescriptorCapture->periodCount + (pDescriptorCapture->periodSizeInFrames * pDescriptorCapture->periodCount * ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels));
heapSize += sizeof(WAVEHDR)*pDescriptorPlayback->periodCount + (pDescriptorPlayback->periodSizeInFrames * pDescriptorPlayback->periodCount * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels));
heapSize += sizeof(MA_WAVEHDR)*pDescriptorPlayback->periodCount + (pDescriptorPlayback->periodSizeInFrames * pDescriptorPlayback->periodCount * ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels));
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount));
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(MA_WAVEHDR)*(pDescriptorCapture->periodCount));
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount + pDescriptorPlayback->periodCount));
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(MA_WAVEHDR)*(pDescriptorCapture->periodCount + pDescriptorPlayback->periodCount));
((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].lpData = (LPSTR)(pDevice->winmm.pIntermediaryBufferCapture + (periodSizeInBytes*iPeriod));
((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwBufferLength = periodSizeInBytes;
((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwFlags = 0L;
((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwLoops = 0L;
((MA_PFN_waveInPrepareHeader)pDevice->pContext->winmm.waveInPrepareHeader)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].lpData = (char*)(pDevice->winmm.pIntermediaryBufferCapture + (periodSizeInBytes*iPeriod));
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwBufferLength = periodSizeInBytes;
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwFlags = 0L;
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod].dwLoops = 0L;
((MA_PFN_waveInPrepareHeader)pDevice->pContext->winmm.waveInPrepareHeader)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(MA_WAVEHDR));
The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
The user data of the MA_WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*pDescriptorPlayback->periodCount);
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(MA_WAVEHDR)*pDescriptorPlayback->periodCount);
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount));
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDescriptorCapture->periodCount + pDescriptorPlayback->periodCount)) + (pDescriptorCapture->periodSizeInFrames*pDescriptorCapture->periodCount*ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels));
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData + (sizeof(MA_WAVEHDR)*(pDescriptorCapture->periodCount));
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(MA_WAVEHDR)*(pDescriptorCapture->periodCount + pDescriptorPlayback->periodCount)) + (pDescriptorCapture->periodSizeInFrames*pDescriptorCapture->periodCount*ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels));
((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].lpData = (LPSTR)(pDevice->winmm.pIntermediaryBufferPlayback + (periodSizeInBytes*iPeriod));
((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwBufferLength = periodSizeInBytes;
((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwFlags = 0L;
((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwLoops = 0L;
((MA_PFN_waveOutPrepareHeader)pDevice->pContext->winmm.waveOutPrepareHeader)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(WAVEHDR));
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].lpData = (char*)(pDevice->winmm.pIntermediaryBufferPlayback + (periodSizeInBytes*iPeriod));
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwBufferLength = periodSizeInBytes;
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwFlags = 0L;
((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod].dwLoops = 0L;
((MA_PFN_waveOutPrepareHeader)pDevice->pContext->winmm.waveOutPrepareHeader)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(MA_WAVEHDR));
The user data of the WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
The user data of the MA_WAVEHDR structure is a single flag the controls whether or not it is ready for writing. Consider it to be named "isLocked". A value of 0 means
((MA_PFN_waveInUnprepareHeader)pDevice->pContext->winmm.waveInUnprepareHeader)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));
((MA_PFN_waveInUnprepareHeader)pDevice->pContext->winmm.waveInUnprepareHeader)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(MA_WAVEHDR));
((MA_PFN_waveOutUnprepareHeader)pDevice->pContext->winmm.waveOutUnprepareHeader)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &((WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(WAVEHDR));
((MA_PFN_waveOutUnprepareHeader)pDevice->pContext->winmm.waveOutUnprepareHeader)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRPlayback)[iPeriod], sizeof(MA_WAVEHDR));
resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[iPeriod], sizeof(MA_WAVEHDR));
if (resultMM != MA_MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInStart)pDevice->pContext->winmm.waveInStart)((HWAVEIN)pDevice->winmm.hDeviceCapture);
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInStart)pDevice->pContext->winmm.waveInStart)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture);
if (resultMM != MA_MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInReset)pDevice->pContext->winmm.waveInReset)((HWAVEIN)pDevice->winmm.hDeviceCapture);
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInReset)pDevice->pContext->winmm.waveInReset)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture);
if (resultMM != MA_MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveOutReset)pDevice->pContext->winmm.waveOutReset)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback);
if (resultMM != MA_MMSYSERR_NOERROR) {
pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */
pWAVEHDR[pDevice->winmm.iNextHeaderPlayback].dwFlags &= ~MA_WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */
resultMM = ((MA_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((HWAVEOUT)pDevice->winmm.hDevicePlayback, &pWAVEHDR[pDevice->winmm.iNextHeaderPlayback], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((MA_HWAVEOUT)pDevice->winmm.hDevicePlayback, &pWAVEHDR[pDevice->winmm.iNextHeaderPlayback], sizeof(MA_WAVEHDR));
if (resultMM != MA_MMSYSERR_NOERROR) {
pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags &= ~WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */
pWAVEHDR[pDevice->winmm.iNextHeaderCapture].dwFlags &= ~MA_WHDR_DONE; /* <-- Need to make sure the WHDR_DONE flag is unset. */
resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDeviceCapture, &((LPWAVEHDR)pDevice->winmm.pWAVEHDRCapture)[pDevice->winmm.iNextHeaderCapture], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) {
resultMM = ((MA_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((MA_HWAVEIN)pDevice->winmm.hDeviceCapture, &((MA_WAVEHDR*)pDevice->winmm.pWAVEHDRCapture)[pDevice->winmm.iNextHeaderCapture], sizeof(MA_WAVEHDR));
if (resultMM != MA_MMSYSERR_NOERROR) {
pContext->winmm.waveOutGetNumDevs = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutGetNumDevs");
pContext->winmm.waveOutGetDevCapsA = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutGetDevCapsA");
pContext->winmm.waveOutOpen = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutOpen");
pContext->winmm.waveOutClose = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutClose");
pContext->winmm.waveOutPrepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutPrepareHeader");
pContext->winmm.waveOutUnprepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutUnprepareHeader");
pContext->winmm.waveOutWrite = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutWrite");
pContext->winmm.waveOutReset = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutReset");
pContext->winmm.waveInGetNumDevs = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInGetNumDevs");
pContext->winmm.waveInGetDevCapsA = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInGetDevCapsA");
pContext->winmm.waveInOpen = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInOpen");
pContext->winmm.waveInClose = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInClose");
pContext->winmm.waveInPrepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInPrepareHeader");
pContext->winmm.waveInUnprepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInUnprepareHeader");
pContext->winmm.waveInAddBuffer = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInAddBuffer");
pContext->winmm.waveInStart = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInStart");
pContext->winmm.waveInReset = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInReset");
pContext->winmm.waveOutGetNumDevs = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutGetNumDevs");
pContext->winmm.waveOutGetDevCapsA = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutGetDevCapsA");
pContext->winmm.waveOutOpen = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutOpen");
pContext->winmm.waveOutClose = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutClose");
pContext->winmm.waveOutPrepareHeader = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutPrepareHeader");
pContext->winmm.waveOutUnprepareHeader = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutUnprepareHeader");
pContext->winmm.waveOutWrite = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutWrite");
pContext->winmm.waveOutReset = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveOutReset");
pContext->winmm.waveInGetNumDevs = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInGetNumDevs");
pContext->winmm.waveInGetDevCapsA = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInGetDevCapsA");
pContext->winmm.waveInOpen = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInOpen");
pContext->winmm.waveInClose = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInClose");
pContext->winmm.waveInPrepareHeader = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInPrepareHeader");
pContext->winmm.waveInUnprepareHeader = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInUnprepareHeader");
pContext->winmm.waveInAddBuffer = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInAddBuffer");
pContext->winmm.waveInStart = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInStart");
pContext->winmm.waveInReset = ma_dlsym(ma_context_get_log(pContext), pContext->winmm.hWinMM, "waveInReset");
ma_snd_pcm_chmap_t* pChmap = ((ma_snd_pcm_get_chmap_proc)pDevice->pContext->alsa.snd_pcm_get_chmap)(pPCM);
ma_snd_pcm_chmap_t* pChmap = NULL;
if (pDevice->pContext->alsa.snd_pcm_get_chmap != NULL) {
pChmap = ((ma_snd_pcm_get_chmap_proc)pDevice->pContext->alsa.snd_pcm_get_chmap)(pPCM);
}
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[ALSA] POLLERR detected.");
return ma_result_from_errno(errno);
ma_snd_pcm_state_t state = ((ma_snd_pcm_state_proc)pDevice->pContext->alsa.snd_pcm_state)(pPCM);
if (state == MA_SND_PCM_STATE_XRUN) {
/* The PCM is in a xrun state. This will be recovered from at a higher level. We can disregard this. */
} else {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_WARNING, "[ALSA] POLLERR detected. status = %d\n", ((ma_snd_pcm_state_proc)pDevice->pContext->alsa.snd_pcm_state)(pPCM));
}
pContext->alsa.snd_pcm_open = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_open");
pContext->alsa.snd_pcm_close = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_close");
pContext->alsa.snd_pcm_hw_params_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_sizeof");
pContext->alsa.snd_pcm_hw_params_any = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_any");
pContext->alsa.snd_pcm_hw_params_set_format = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format");
pContext->alsa.snd_pcm_hw_params_set_format_first = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format_first");
pContext->alsa.snd_pcm_hw_params_get_format_mask = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format_mask");
pContext->alsa.snd_pcm_hw_params_set_channels = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels");
pContext->alsa.snd_pcm_hw_params_set_channels_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_near");
pContext->alsa.snd_pcm_hw_params_set_channels_minmax = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_minmax");
pContext->alsa.snd_pcm_hw_params_set_rate_resample = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_resample");
pContext->alsa.snd_pcm_hw_params_set_rate = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate");
pContext->alsa.snd_pcm_hw_params_set_rate_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_near");
pContext->alsa.snd_pcm_hw_params_set_buffer_size_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_buffer_size_near");
pContext->alsa.snd_pcm_hw_params_set_periods_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_periods_near");
pContext->alsa.snd_pcm_hw_params_set_access = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_access");
pContext->alsa.snd_pcm_hw_params_get_format = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format");
pContext->alsa.snd_pcm_hw_params_get_channels = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels");
pContext->alsa.snd_pcm_hw_params_get_channels_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_min");
pContext->alsa.snd_pcm_hw_params_get_channels_max = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_max");
pContext->alsa.snd_pcm_hw_params_get_rate = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate");
pContext->alsa.snd_pcm_hw_params_get_rate_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_min");
pContext->alsa.snd_pcm_hw_params_get_rate_max = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_max");
pContext->alsa.snd_pcm_hw_params_get_buffer_size = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_buffer_size");
pContext->alsa.snd_pcm_hw_params_get_periods = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_periods");
pContext->alsa.snd_pcm_hw_params_get_access = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_access");
pContext->alsa.snd_pcm_hw_params_test_format = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_test_format");
pContext->alsa.snd_pcm_hw_params_test_channels = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_test_channels");
pContext->alsa.snd_pcm_hw_params_test_rate = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_test_rate");
pContext->alsa.snd_pcm_hw_params = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params");
pContext->alsa.snd_pcm_sw_params_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_sizeof");
pContext->alsa.snd_pcm_sw_params_current = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_current");
pContext->alsa.snd_pcm_sw_params_get_boundary = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_get_boundary");
pContext->alsa.snd_pcm_sw_params_set_avail_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_avail_min");
pContext->alsa.snd_pcm_sw_params_set_start_threshold = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_start_threshold");
pContext->alsa.snd_pcm_sw_params_set_stop_threshold = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_stop_threshold");
pContext->alsa.snd_pcm_sw_params = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params");
pContext->alsa.snd_pcm_format_mask_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_format_mask_sizeof");
pContext->alsa.snd_pcm_format_mask_test = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_format_mask_test");
pContext->alsa.snd_pcm_get_chmap = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_get_chmap");
pContext->alsa.snd_pcm_state = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_state");
pContext->alsa.snd_pcm_prepare = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_prepare");
pContext->alsa.snd_pcm_start = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_start");
pContext->alsa.snd_pcm_drop = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_drop");
pContext->alsa.snd_pcm_drain = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_drain");
pContext->alsa.snd_pcm_reset = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_reset");
pContext->alsa.snd_device_name_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_hint");
pContext->alsa.snd_device_name_get_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_get_hint");
pContext->alsa.snd_card_get_index = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_card_get_index");
pContext->alsa.snd_device_name_free_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_free_hint");
pContext->alsa.snd_pcm_mmap_begin = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_mmap_begin");
pContext->alsa.snd_pcm_mmap_commit = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_mmap_commit");
pContext->alsa.snd_pcm_recover = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_recover");
pContext->alsa.snd_pcm_readi = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_readi");
pContext->alsa.snd_pcm_writei = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_writei");
pContext->alsa.snd_pcm_avail = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_avail");
pContext->alsa.snd_pcm_avail_update = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_avail_update");
pContext->alsa.snd_pcm_wait = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_wait");
pContext->alsa.snd_pcm_nonblock = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_nonblock");
pContext->alsa.snd_pcm_info = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info");
pContext->alsa.snd_pcm_info_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info_sizeof");
pContext->alsa.snd_pcm_info_get_name = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info_get_name");
pContext->alsa.snd_pcm_poll_descriptors = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_poll_descriptors");
pContext->alsa.snd_pcm_poll_descriptors_count = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_poll_descriptors_count");
pContext->alsa.snd_pcm_poll_descriptors_revents = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_poll_descriptors_revents");
pContext->alsa.snd_config_update_free_global = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_config_update_free_global");
pContext->alsa.snd_pcm_open = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_open");
pContext->alsa.snd_pcm_close = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_close");
pContext->alsa.snd_pcm_hw_params_sizeof = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_sizeof");
pContext->alsa.snd_pcm_hw_params_any = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_any");
pContext->alsa.snd_pcm_hw_params_set_format = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format");
pContext->alsa.snd_pcm_hw_params_set_format_first = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format_first");
pContext->alsa.snd_pcm_hw_params_get_format_mask = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format_mask");
pContext->alsa.snd_pcm_hw_params_set_channels = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels");
pContext->alsa.snd_pcm_hw_params_set_channels_near = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_near");
pContext->alsa.snd_pcm_hw_params_set_channels_minmax = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_minmax");
pContext->alsa.snd_pcm_hw_params_set_rate_resample = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_resample");
pContext->alsa.snd_pcm_hw_params_set_rate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate");
pContext->alsa.snd_pcm_hw_params_set_rate_near = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_near");
pContext->alsa.snd_pcm_hw_params_set_buffer_size_near = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_buffer_size_near");
pContext->alsa.snd_pcm_hw_params_set_periods_near = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_periods_near");
pContext->alsa.snd_pcm_hw_params_set_access = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_set_access");
pContext->alsa.snd_pcm_hw_params_get_format = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format");
pContext->alsa.snd_pcm_hw_params_get_channels = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels");
pContext->alsa.snd_pcm_hw_params_get_channels_min = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_min");
pContext->alsa.snd_pcm_hw_params_get_channels_max = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_max");
pContext->alsa.snd_pcm_hw_params_get_rate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate");
pContext->alsa.snd_pcm_hw_params_get_rate_min = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_min");
pContext->alsa.snd_pcm_hw_params_get_rate_max = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_max");
pContext->alsa.snd_pcm_hw_params_get_buffer_size = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_buffer_size");
pContext->alsa.snd_pcm_hw_params_get_periods = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_periods");
pContext->alsa.snd_pcm_hw_params_get_access = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_get_access");
pContext->alsa.snd_pcm_hw_params_test_format = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_test_format");
pContext->alsa.snd_pcm_hw_params_test_channels = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_test_channels");
pContext->alsa.snd_pcm_hw_params_test_rate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params_test_rate");
pContext->alsa.snd_pcm_hw_params = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_hw_params");
pContext->alsa.snd_pcm_sw_params_sizeof = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_sizeof");
pContext->alsa.snd_pcm_sw_params_current = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_current");
pContext->alsa.snd_pcm_sw_params_get_boundary = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_get_boundary");
pContext->alsa.snd_pcm_sw_params_set_avail_min = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_set_avail_min");
pContext->alsa.snd_pcm_sw_params_set_start_threshold = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_set_start_threshold");
pContext->alsa.snd_pcm_sw_params_set_stop_threshold = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params_set_stop_threshold");
pContext->alsa.snd_pcm_sw_params = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_sw_params");
pContext->alsa.snd_pcm_format_mask_sizeof = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_format_mask_sizeof");
pContext->alsa.snd_pcm_format_mask_test = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_format_mask_test");
pContext->alsa.snd_pcm_get_chmap = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_get_chmap");
pContext->alsa.snd_pcm_state = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_state");
pContext->alsa.snd_pcm_prepare = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_prepare");
pContext->alsa.snd_pcm_start = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_start");
pContext->alsa.snd_pcm_drop = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_drop");
pContext->alsa.snd_pcm_drain = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_drain");
pContext->alsa.snd_pcm_reset = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_reset");
pContext->alsa.snd_device_name_hint = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_device_name_hint");
pContext->alsa.snd_device_name_get_hint = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_device_name_get_hint");
pContext->alsa.snd_card_get_index = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_card_get_index");
pContext->alsa.snd_device_name_free_hint = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_device_name_free_hint");
pContext->alsa.snd_pcm_mmap_begin = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_mmap_begin");
pContext->alsa.snd_pcm_mmap_commit = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_mmap_commit");
pContext->alsa.snd_pcm_recover = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_recover");
pContext->alsa.snd_pcm_readi = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_readi");
pContext->alsa.snd_pcm_writei = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_writei");
pContext->alsa.snd_pcm_avail = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_avail");
pContext->alsa.snd_pcm_avail_update = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_avail_update");
pContext->alsa.snd_pcm_wait = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_wait");
pContext->alsa.snd_pcm_nonblock = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_nonblock");
pContext->alsa.snd_pcm_info = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_info");
pContext->alsa.snd_pcm_info_sizeof = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_info_sizeof");
pContext->alsa.snd_pcm_info_get_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_info_get_name");
pContext->alsa.snd_pcm_poll_descriptors = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_poll_descriptors");
pContext->alsa.snd_pcm_poll_descriptors_count = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_poll_descriptors_count");
pContext->alsa.snd_pcm_poll_descriptors_revents = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_pcm_poll_descriptors_revents");
pContext->alsa.snd_config_update_free_global = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->alsa.asoundSO, "snd_config_update_free_global");
- We're always using native format/channels/rate regardless of whether or not PulseAudio
supports the format directly through their own data conversion system. I'm doing this to
reduce as much variability from the PulseAudio side as possible because it's seems to be
extremely unreliable at everything it does.
/* Use the requested channel count if we have one. */
if (pDescriptorCapture->channels != 0) {
ss.channels = pDescriptorCapture->channels;
}
/* Use a default channel map. */
((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MA_PA_CHANNEL_MAP_DEFAULT);
/* Use the requested channel count if we have one. */
if (pDescriptorPlayback->channels != 0) {
ss.channels = pDescriptorPlayback->channels;
}
/* Use a default channel map. */
((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MA_PA_CHANNEL_MAP_DEFAULT);
/* Use the requested sample rate if one was specified. */
if (pDescriptorPlayback->sampleRate != 0) {
ss.rate = pDescriptorPlayback->sampleRate;
}
streamFlags = MA_PA_STREAM_START_CORKED | MA_PA_STREAM_ADJUST_LATENCY;
pContext->pulse.pa_mainloop_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_new");
pContext->pulse.pa_mainloop_free = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_free");
pContext->pulse.pa_mainloop_quit = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_quit");
pContext->pulse.pa_mainloop_get_api = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_get_api");
pContext->pulse.pa_mainloop_iterate = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_iterate");
pContext->pulse.pa_mainloop_wakeup = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_wakeup");
pContext->pulse.pa_threaded_mainloop_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_new");
pContext->pulse.pa_threaded_mainloop_free = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_free");
pContext->pulse.pa_threaded_mainloop_start = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_start");
pContext->pulse.pa_threaded_mainloop_stop = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_stop");
pContext->pulse.pa_threaded_mainloop_lock = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_lock");
pContext->pulse.pa_threaded_mainloop_unlock = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_unlock");
pContext->pulse.pa_threaded_mainloop_wait = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_wait");
pContext->pulse.pa_threaded_mainloop_signal = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_signal");
pContext->pulse.pa_threaded_mainloop_accept = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_accept");
pContext->pulse.pa_threaded_mainloop_get_retval = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_get_retval");
pContext->pulse.pa_threaded_mainloop_get_api = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_get_api");
pContext->pulse.pa_threaded_mainloop_in_thread = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_in_thread");
pContext->pulse.pa_threaded_mainloop_set_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_threaded_mainloop_set_name");
pContext->pulse.pa_context_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_new");
pContext->pulse.pa_context_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_unref");
pContext->pulse.pa_context_connect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_connect");
pContext->pulse.pa_context_disconnect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_disconnect");
pContext->pulse.pa_context_set_state_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_set_state_callback");
pContext->pulse.pa_context_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_state");
pContext->pulse.pa_context_get_sink_info_list = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_sink_info_list");
pContext->pulse.pa_context_get_source_info_list = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_source_info_list");
pContext->pulse.pa_context_get_sink_info_by_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_sink_info_by_name");
pContext->pulse.pa_context_get_source_info_by_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_source_info_by_name");
pContext->pulse.pa_operation_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_operation_unref");
pContext->pulse.pa_operation_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_operation_get_state");
pContext->pulse.pa_channel_map_init_extend = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_init_extend");
pContext->pulse.pa_channel_map_valid = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_valid");
pContext->pulse.pa_channel_map_compatible = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_compatible");
pContext->pulse.pa_stream_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_new");
pContext->pulse.pa_stream_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_unref");
pContext->pulse.pa_stream_connect_playback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_connect_playback");
pContext->pulse.pa_stream_connect_record = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_connect_record");
pContext->pulse.pa_stream_disconnect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_disconnect");
pContext->pulse.pa_stream_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_state");
pContext->pulse.pa_stream_get_sample_spec = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_sample_spec");
pContext->pulse.pa_stream_get_channel_map = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_channel_map");
pContext->pulse.pa_stream_get_buffer_attr = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_buffer_attr");
pContext->pulse.pa_stream_set_buffer_attr = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_buffer_attr");
pContext->pulse.pa_stream_get_device_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_device_name");
pContext->pulse.pa_stream_set_write_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_write_callback");
pContext->pulse.pa_stream_set_read_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_read_callback");
pContext->pulse.pa_stream_set_suspended_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_suspended_callback");
pContext->pulse.pa_stream_set_moved_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_moved_callback");
pContext->pulse.pa_stream_is_suspended = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_is_suspended");
pContext->pulse.pa_stream_flush = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_flush");
pContext->pulse.pa_stream_drain = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_drain");
pContext->pulse.pa_stream_is_corked = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_is_corked");
pContext->pulse.pa_stream_cork = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_cork");
pContext->pulse.pa_stream_trigger = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_trigger");
pContext->pulse.pa_stream_begin_write = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_begin_write");
pContext->pulse.pa_stream_write = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_write");
pContext->pulse.pa_stream_peek = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_peek");
pContext->pulse.pa_stream_drop = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_drop");
pContext->pulse.pa_stream_writable_size = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_writable_size");
pContext->pulse.pa_stream_readable_size = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_readable_size");
pContext->pulse.pa_mainloop_new = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_new");
pContext->pulse.pa_mainloop_free = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_free");
pContext->pulse.pa_mainloop_quit = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_quit");
pContext->pulse.pa_mainloop_get_api = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_get_api");
pContext->pulse.pa_mainloop_iterate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_iterate");
pContext->pulse.pa_mainloop_wakeup = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_mainloop_wakeup");
pContext->pulse.pa_threaded_mainloop_new = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_new");
pContext->pulse.pa_threaded_mainloop_free = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_free");
pContext->pulse.pa_threaded_mainloop_start = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_start");
pContext->pulse.pa_threaded_mainloop_stop = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_stop");
pContext->pulse.pa_threaded_mainloop_lock = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_lock");
pContext->pulse.pa_threaded_mainloop_unlock = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_unlock");
pContext->pulse.pa_threaded_mainloop_wait = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_wait");
pContext->pulse.pa_threaded_mainloop_signal = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_signal");
pContext->pulse.pa_threaded_mainloop_accept = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_accept");
pContext->pulse.pa_threaded_mainloop_get_retval = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_get_retval");
pContext->pulse.pa_threaded_mainloop_get_api = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_get_api");
pContext->pulse.pa_threaded_mainloop_in_thread = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_in_thread");
pContext->pulse.pa_threaded_mainloop_set_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_threaded_mainloop_set_name");
pContext->pulse.pa_context_new = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_new");
pContext->pulse.pa_context_unref = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_unref");
pContext->pulse.pa_context_connect = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_connect");
pContext->pulse.pa_context_disconnect = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_disconnect");
pContext->pulse.pa_context_set_state_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_set_state_callback");
pContext->pulse.pa_context_get_state = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_get_state");
pContext->pulse.pa_context_get_sink_info_list = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_get_sink_info_list");
pContext->pulse.pa_context_get_source_info_list = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_get_source_info_list");
pContext->pulse.pa_context_get_sink_info_by_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_get_sink_info_by_name");
pContext->pulse.pa_context_get_source_info_by_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_context_get_source_info_by_name");
pContext->pulse.pa_operation_unref = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_operation_unref");
pContext->pulse.pa_operation_get_state = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_operation_get_state");
pContext->pulse.pa_channel_map_init_extend = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_channel_map_init_extend");
pContext->pulse.pa_channel_map_valid = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_channel_map_valid");
pContext->pulse.pa_channel_map_compatible = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_channel_map_compatible");
pContext->pulse.pa_stream_new = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_new");
pContext->pulse.pa_stream_unref = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_unref");
pContext->pulse.pa_stream_connect_playback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_connect_playback");
pContext->pulse.pa_stream_connect_record = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_connect_record");
pContext->pulse.pa_stream_disconnect = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_disconnect");
pContext->pulse.pa_stream_get_state = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_get_state");
pContext->pulse.pa_stream_get_sample_spec = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_get_sample_spec");
pContext->pulse.pa_stream_get_channel_map = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_get_channel_map");
pContext->pulse.pa_stream_get_buffer_attr = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_get_buffer_attr");
pContext->pulse.pa_stream_set_buffer_attr = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_set_buffer_attr");
pContext->pulse.pa_stream_get_device_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_get_device_name");
pContext->pulse.pa_stream_set_write_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_set_write_callback");
pContext->pulse.pa_stream_set_read_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_set_read_callback");
pContext->pulse.pa_stream_set_suspended_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_set_suspended_callback");
pContext->pulse.pa_stream_set_moved_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_set_moved_callback");
pContext->pulse.pa_stream_is_suspended = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_is_suspended");
pContext->pulse.pa_stream_flush = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_flush");
pContext->pulse.pa_stream_drain = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_drain");
pContext->pulse.pa_stream_is_corked = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_is_corked");
pContext->pulse.pa_stream_cork = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_cork");
pContext->pulse.pa_stream_trigger = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_trigger");
pContext->pulse.pa_stream_begin_write = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_begin_write");
pContext->pulse.pa_stream_write = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_write");
pContext->pulse.pa_stream_peek = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_peek");
pContext->pulse.pa_stream_drop = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_drop");
pContext->pulse.pa_stream_writable_size = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_writable_size");
pContext->pulse.pa_stream_readable_size = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->pulse.pulseSO, "pa_stream_readable_size");
pContext->jack.jack_client_open = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_open");
pContext->jack.jack_client_close = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_close");
pContext->jack.jack_client_name_size = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_name_size");
pContext->jack.jack_set_process_callback = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_set_process_callback");
pContext->jack.jack_set_buffer_size_callback = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_set_buffer_size_callback");
pContext->jack.jack_on_shutdown = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_on_shutdown");
pContext->jack.jack_get_sample_rate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_sample_rate");
pContext->jack.jack_get_buffer_size = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_buffer_size");
pContext->jack.jack_get_ports = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_ports");
pContext->jack.jack_activate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_activate");
pContext->jack.jack_deactivate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_deactivate");
pContext->jack.jack_connect = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_connect");
pContext->jack.jack_port_register = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_register");
pContext->jack.jack_port_name = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_name");
pContext->jack.jack_port_get_buffer = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_get_buffer");
pContext->jack.jack_free = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_free");
pContext->jack.jack_client_open = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_client_open");
pContext->jack.jack_client_close = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_client_close");
pContext->jack.jack_client_name_size = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_client_name_size");
pContext->jack.jack_set_process_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_set_process_callback");
pContext->jack.jack_set_buffer_size_callback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_set_buffer_size_callback");
pContext->jack.jack_on_shutdown = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_on_shutdown");
pContext->jack.jack_get_sample_rate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_get_sample_rate");
pContext->jack.jack_get_buffer_size = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_get_buffer_size");
pContext->jack.jack_get_ports = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_get_ports");
pContext->jack.jack_activate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_activate");
pContext->jack.jack_deactivate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_deactivate");
pContext->jack.jack_connect = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_connect");
pContext->jack.jack_port_register = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_port_register");
pContext->jack.jack_port_name = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_port_name");
pContext->jack.jack_port_get_buffer = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_port_get_buffer");
pContext->jack.jack_free = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->jack.jackSO, "jack_free");
kAudioObjectPropertyElementMaster in miniaudio's case. I don't know of any cases where this would be set to anything different.
kAudioObjectPropertyElementMain in miniaudio's case. I don't know of any cases where this would be set to anything different.
#if (defined(MAC_OS_VERSION_12_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_12_0) || \
(defined(__IPHONE_15_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0)
#define AUDIO_OBJECT_PROPERTY_ELEMENT kAudioObjectPropertyElementMain
#else
/* kAudioObjectPropertyElementMaster is deprecated. */
#define AUDIO_OBJECT_PROPERTY_ELEMENT kAudioObjectPropertyElementMaster
#endif
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation);
pContext->coreaudio.CFStringGetCString = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
pContext->coreaudio.CFRelease = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFRelease");
pContext->coreaudio.CFStringGetCString = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
pContext->coreaudio.CFRelease = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation, "CFRelease");
pContext->coreaudio.AudioObjectGetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
pContext->coreaudio.AudioObjectRemovePropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectRemovePropertyListener");
pContext->coreaudio.AudioObjectGetPropertyData = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
pContext->coreaudio.AudioObjectRemovePropertyListener = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio, "AudioObjectRemovePropertyListener");
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation);
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioToolbox.framework/AudioToolbox");
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit);
pContext->coreaudio.hAudioUnit = ma_dlopen(ma_context_get_log(pContext), "AudioToolbox.framework/AudioToolbox");
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation);
pContext->coreaudio.AudioComponentFindNext = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
pContext->coreaudio.AudioComponentInstanceDispose = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
pContext->coreaudio.AudioComponentInstanceNew = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");
pContext->coreaudio.AudioOutputUnitStart = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioOutputUnitStart");
pContext->coreaudio.AudioOutputUnitStop = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioOutputUnitStop");
pContext->coreaudio.AudioUnitAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitAddPropertyListener");
pContext->coreaudio.AudioUnitGetPropertyInfo = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitGetPropertyInfo");
pContext->coreaudio.AudioUnitGetProperty = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitGetProperty");
pContext->coreaudio.AudioUnitSetProperty = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitSetProperty");
pContext->coreaudio.AudioUnitInitialize = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitInitialize");
pContext->coreaudio.AudioUnitRender = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitRender");
pContext->coreaudio.AudioComponentFindNext = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
pContext->coreaudio.AudioComponentInstanceDispose = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
pContext->coreaudio.AudioComponentInstanceNew = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");
pContext->coreaudio.AudioOutputUnitStart = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioOutputUnitStart");
pContext->coreaudio.AudioOutputUnitStop = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioOutputUnitStop");
pContext->coreaudio.AudioUnitAddPropertyListener = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitAddPropertyListener");
pContext->coreaudio.AudioUnitGetPropertyInfo = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitGetPropertyInfo");
pContext->coreaudio.AudioUnitGetProperty = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitGetProperty");
pContext->coreaudio.AudioUnitSetProperty = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitSetProperty");
pContext->coreaudio.AudioUnitInitialize = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitInitialize");
pContext->coreaudio.AudioUnitRender = ma_dlsym(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit, "AudioUnitRender");
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation);
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hAudioUnit);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreAudio);
ma_dlclose(ma_context_get_log(pContext), pContext->coreaudio.hCoreFoundation);
pContext->sndio.sio_open = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_open");
pContext->sndio.sio_close = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_close");
pContext->sndio.sio_setpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_setpar");
pContext->sndio.sio_getpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_getpar");
pContext->sndio.sio_getcap = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_getcap");
pContext->sndio.sio_write = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_write");
pContext->sndio.sio_read = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_read");
pContext->sndio.sio_start = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_start");
pContext->sndio.sio_stop = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_stop");
pContext->sndio.sio_initpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_initpar");
pContext->sndio.sio_open = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_open");
pContext->sndio.sio_close = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_close");
pContext->sndio.sio_setpar = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_setpar");
pContext->sndio.sio_getpar = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_getpar");
pContext->sndio.sio_getcap = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_getcap");
pContext->sndio.sio_write = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_write");
pContext->sndio.sio_read = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_read");
pContext->sndio.sio_start = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_start");
pContext->sndio.sio_stop = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_stop");
pContext->sndio.sio_initpar = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->sndio.sndioSO, "sio_initpar");
size_t iDevice;
for (iDevice = 0; iDevice < ma_countof(pDefaultDeviceNames); ++iDevice) {
fd = open(pDefaultDeviceNames[iDevice], fdFlags, 0);
for (iDefaultDevice = 0; iDefaultDevice < ma_countof(pDefaultDeviceNames); ++iDefaultDevice) {
fd = open(pDefaultDeviceNames[iDefaultDevice], fdFlags, 0);
for (iDefaultDevice = 0; iDefaultDevice < ma_countof(pDefaultDeviceNames); iDefaultDevice += 1) {
if (ma_strcmp(pDefaultDeviceNames[iDefaultDevice], pDescriptor->pDeviceID->audio4) == 0) {
break;
}
}
if (iDefaultDevice == ma_countof(pDefaultDeviceNames)) {
iDefaultDevice = (size_t)-1;
}
/*
Get the default format from the audioctl file if we're asking for a default device. If we
retrieve it from /dev/audio it'll default to mono 8000Hz.
*/
if (iDefaultDevice != (size_t)-1) {
/* We're using a default device. Get the info from the /dev/audioctl file instead of /dev/audio. */
int fdctl = open(pDefaultDeviceCtlNames[iDefaultDevice], fdFlags, 0);
if (fdctl != -1) {
fdInfoResult = ioctl(fdctl, AUDIO_GETINFO, &fdInfo);
close(fdctl);
}
}
if (fdInfoResult == -1) {
/* We still don't have the default device info so just retrieve it from the main audio device. */
if (ioctl(fd, AUDIO_GETINFO, &fdInfo) < 0) {
close(fd);
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] AUDIO_GETINFO failed.");
return ma_result_from_errno(errno);
}
}
case ma_aaudio_usage_announcement: return MA_AAUDIO_USAGE_MEDIA;
case ma_aaudio_usage_emergency: return MA_AAUDIO_USAGE_VOICE_COMMUNICATION;
case ma_aaudio_usage_safety: return MA_AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
case ma_aaudio_usage_vehicle_status: return MA_AAUDIO_USAGE_ALARM;
case ma_aaudio_usage_alarm: return MA_AAUDIO_USAGE_NOTIFICATION;
case ma_aaudio_usage_assistance_accessibility: return MA_AAUDIO_USAGE_NOTIFICATION_RINGTONE;
case ma_aaudio_usage_assistance_navigation_guidance: return MA_AAUDIO_USAGE_NOTIFICATION_EVENT;
case ma_aaudio_usage_assistance_sonification: return MA_AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
case ma_aaudio_usage_assitant: return MA_AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
case ma_aaudio_usage_game: return MA_AAUDIO_USAGE_ASSISTANCE_SONIFICATION;
case ma_aaudio_usage_media: return MA_AAUDIO_USAGE_GAME;
case ma_aaudio_usage_notification: return MA_AAUDIO_USAGE_ASSISTANT;
case ma_aaudio_usage_notification_event: return MA_AAUDIO_SYSTEM_USAGE_EMERGENCY;
case ma_aaudio_usage_notification_ringtone: return MA_AAUDIO_SYSTEM_USAGE_SAFETY;
case ma_aaudio_usage_voice_communication: return MA_AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS;
case ma_aaudio_usage_voice_communication_signalling: return MA_AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT;
case ma_aaudio_usage_media: return MA_AAUDIO_USAGE_MEDIA;
case ma_aaudio_usage_voice_communication: return MA_AAUDIO_USAGE_VOICE_COMMUNICATION;
case ma_aaudio_usage_voice_communication_signalling: return MA_AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
case ma_aaudio_usage_alarm: return MA_AAUDIO_USAGE_ALARM;
case ma_aaudio_usage_notification: return MA_AAUDIO_USAGE_NOTIFICATION;
case ma_aaudio_usage_notification_ringtone: return MA_AAUDIO_USAGE_NOTIFICATION_RINGTONE;
case ma_aaudio_usage_notification_event: return MA_AAUDIO_USAGE_NOTIFICATION_EVENT;
case ma_aaudio_usage_assistance_accessibility: return MA_AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
case ma_aaudio_usage_assistance_navigation_guidance: return MA_AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
case ma_aaudio_usage_assistance_sonification: return MA_AAUDIO_USAGE_ASSISTANCE_SONIFICATION;
case ma_aaudio_usage_game: return MA_AAUDIO_USAGE_GAME;
case ma_aaudio_usage_assitant: return MA_AAUDIO_USAGE_ASSISTANT;
case ma_aaudio_usage_emergency: return MA_AAUDIO_SYSTEM_USAGE_EMERGENCY;
case ma_aaudio_usage_safety: return MA_AAUDIO_SYSTEM_USAGE_SAFETY;
case ma_aaudio_usage_vehicle_status: return MA_AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS;
case ma_aaudio_usage_announcement: return MA_AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT;
}
static ma_aaudio_allowed_capture_policy_t ma_to_allowed_capture_policy__aaudio(ma_aaudio_allowed_capture_policy allowedCapturePolicy)
{
switch (allowedCapturePolicy) {
case ma_aaudio_allow_capture_by_all: return MA_AAUDIO_ALLOW_CAPTURE_BY_ALL;
case ma_aaudio_allow_capture_by_system: return MA_AAUDIO_ALLOW_CAPTURE_BY_SYSTEM;
case ma_aaudio_allow_capture_by_none: return MA_AAUDIO_ALLOW_CAPTURE_BY_NONE;
default: break;
}
return MA_AAUDIO_ALLOW_CAPTURE_BY_ALL;
From the documentation for AAudio, when a device is disconnected all we can do is stop it. However, we cannot stop it from the callback - we need
to do it from another thread. Therefore we are going to use an event thread for the AAudio backend to do this cleanly and safely.
When we get an error, we'll assume that the stream is in an erroneous state and needs to be restarted. From the documentation,
we cannot do this from the error callback. Therefore we are going to use an event thread for the AAudio backend to do this
cleanly and safely.
if (((MA_PFN_AAudioStream_getState)pDevice->pContext->aaudio.AAudioStream_getState)(pStream) == MA_AAUDIO_STREAM_STATE_DISCONNECTED) {
/* We need to post a job to the job thread for processing. This will reroute the device by reinitializing the stream. */
ma_result result;
ma_job job = ma_job_init(MA_JOB_TYPE_DEVICE_AAUDIO_REROUTE);
job.data.device.aaudio.reroute.pDevice = pDevice;
job = ma_job_init(MA_JOB_TYPE_DEVICE_AAUDIO_REROUTE);
job.data.device.aaudio.reroute.pDevice = pDevice;
if (pStream == pDevice->aaudio.pStreamCapture) {
job.data.device.aaudio.reroute.deviceType = ma_device_type_capture;
} else {
job.data.device.aaudio.reroute.deviceType = ma_device_type_playback;
}
if (pStream == pDevice->aaudio.pStreamCapture) {
job.data.device.aaudio.reroute.deviceType = ma_device_type_capture;
}
else {
job.data.device.aaudio.reroute.deviceType = ma_device_type_playback;
}
result = ma_device_job_thread_post(&pDevice->pContext->aaudio.jobThread, &job);
if (result != MA_SUCCESS) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Failed to post job for rerouting.\n");
return;
}
result = ma_device_job_thread_post(&pDevice->pContext->aaudio.jobThread, &job);
if (result != MA_SUCCESS) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Failed to post job for rerouting.\n");
return;
AAudio is annoying when it comes to it's buffer calculation stuff because it doesn't let you
retrieve the actual sample rate until after you've opened the stream. But you need to configure
the buffer capacity before you open the stream... :/
To solve, we're just going to assume MA_DEFAULT_SAMPLE_RATE (48000) and move on.
There have been reports where setting the frames per data callback results in an error
later on from Android. To address this, I'm experimenting with simply not setting it on
anything from Android 11 and earlier. Suggestions welcome on how we might be able to make
this more targetted.
bufferCapacityInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, pDescriptor->sampleRate, pConfig->performanceProfile) * pDescriptor->periodCount;
if (!pConfig->aaudio.enableCompatibilityWorkarounds || ma_android_sdk_version() > 30) {
/*
AAudio is annoying when it comes to it's buffer calculation stuff because it doesn't let you
retrieve the actual sample rate until after you've opened the stream. But you need to configure
the buffer capacity before you open the stream... :/
((MA_PFN_AAudioStreamBuilder_setBufferCapacityInFrames)pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames)(pBuilder, bufferCapacityInFrames);
((MA_PFN_AAudioStreamBuilder_setFramesPerDataCallback)pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback)(pBuilder, bufferCapacityInFrames / pDescriptor->periodCount);
To solve, we're just going to assume MA_DEFAULT_SAMPLE_RATE (48000) and move on.
*/
ma_uint32 bufferCapacityInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, pDescriptor->sampleRate, pConfig->performanceProfile) * pDescriptor->periodCount;
((MA_PFN_AAudioStreamBuilder_setBufferCapacityInFrames)pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames)(pBuilder, bufferCapacityInFrames);
((MA_PFN_AAudioStreamBuilder_setFramesPerDataCallback)pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback)(pBuilder, bufferCapacityInFrames / pDescriptor->periodCount);
}
}
if (pConfig->aaudio.allowedCapturePolicy != ma_aaudio_allow_capture_default && pContext->aaudio.AAudioStreamBuilder_setAllowedCapturePolicy != NULL) {
((MA_PFN_AAudioStreamBuilder_setAllowedCapturePolicy)pContext->aaudio.AAudioStreamBuilder_setAllowedCapturePolicy)(pBuilder, ma_to_allowed_capture_policy__aaudio(pConfig->aaudio.allowedCapturePolicy));
pContext->aaudio.AAudio_createStreamBuilder = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudio_createStreamBuilder");
pContext->aaudio.AAudioStreamBuilder_delete = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_delete");
pContext->aaudio.AAudioStreamBuilder_setDeviceId = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDeviceId");
pContext->aaudio.AAudioStreamBuilder_setDirection = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDirection");
pContext->aaudio.AAudioStreamBuilder_setSharingMode = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSharingMode");
pContext->aaudio.AAudioStreamBuilder_setFormat = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFormat");
pContext->aaudio.AAudioStreamBuilder_setChannelCount = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setChannelCount");
pContext->aaudio.AAudioStreamBuilder_setSampleRate = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSampleRate");
pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setBufferCapacityInFrames");
pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFramesPerDataCallback");
pContext->aaudio.AAudioStreamBuilder_setDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDataCallback");
pContext->aaudio.AAudioStreamBuilder_setErrorCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setErrorCallback");
pContext->aaudio.AAudioStreamBuilder_setPerformanceMode = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setPerformanceMode");
pContext->aaudio.AAudioStreamBuilder_setUsage = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setUsage");
pContext->aaudio.AAudioStreamBuilder_setContentType = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setContentType");
pContext->aaudio.AAudioStreamBuilder_setInputPreset = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setInputPreset");
pContext->aaudio.AAudioStreamBuilder_openStream = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_openStream");
pContext->aaudio.AAudioStream_close = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_close");
pContext->aaudio.AAudioStream_getState = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getState");
pContext->aaudio.AAudioStream_waitForStateChange = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_waitForStateChange");
pContext->aaudio.AAudioStream_getFormat = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFormat");
pContext->aaudio.AAudioStream_getChannelCount = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getChannelCount");
pContext->aaudio.AAudioStream_getSampleRate = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getSampleRate");
pContext->aaudio.AAudioStream_getBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getBufferCapacityInFrames");
pContext->aaudio.AAudioStream_getFramesPerDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFramesPerDataCallback");
pContext->aaudio.AAudioStream_getFramesPerBurst = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFramesPerBurst");
pContext->aaudio.AAudioStream_requestStart = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_requestStart");
pContext->aaudio.AAudioStream_requestStop = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_requestStop");
pContext->aaudio.AAudio_createStreamBuilder = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudio_createStreamBuilder");
pContext->aaudio.AAudioStreamBuilder_delete = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_delete");
pContext->aaudio.AAudioStreamBuilder_setDeviceId = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDeviceId");
pContext->aaudio.AAudioStreamBuilder_setDirection = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDirection");
pContext->aaudio.AAudioStreamBuilder_setSharingMode = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSharingMode");
pContext->aaudio.AAudioStreamBuilder_setFormat = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFormat");
pContext->aaudio.AAudioStreamBuilder_setChannelCount = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setChannelCount");
pContext->aaudio.AAudioStreamBuilder_setSampleRate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSampleRate");
pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setBufferCapacityInFrames");
pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFramesPerDataCallback");
pContext->aaudio.AAudioStreamBuilder_setDataCallback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDataCallback");
pContext->aaudio.AAudioStreamBuilder_setErrorCallback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setErrorCallback");
pContext->aaudio.AAudioStreamBuilder_setPerformanceMode = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setPerformanceMode");
pContext->aaudio.AAudioStreamBuilder_setUsage = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setUsage");
pContext->aaudio.AAudioStreamBuilder_setContentType = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setContentType");
pContext->aaudio.AAudioStreamBuilder_setInputPreset = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setInputPreset");
pContext->aaudio.AAudioStreamBuilder_setAllowedCapturePolicy = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_setAllowedCapturePolicy");
pContext->aaudio.AAudioStreamBuilder_openStream = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStreamBuilder_openStream");
pContext->aaudio.AAudioStream_close = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_close");
pContext->aaudio.AAudioStream_getState = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getState");
pContext->aaudio.AAudioStream_waitForStateChange = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_waitForStateChange");
pContext->aaudio.AAudioStream_getFormat = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getFormat");
pContext->aaudio.AAudioStream_getChannelCount = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getChannelCount");
pContext->aaudio.AAudioStream_getSampleRate = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getSampleRate");
pContext->aaudio.AAudioStream_getBufferCapacityInFrames = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getBufferCapacityInFrames");
pContext->aaudio.AAudioStream_getFramesPerDataCallback = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getFramesPerDataCallback");
pContext->aaudio.AAudioStream_getFramesPerBurst = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_getFramesPerBurst");
pContext->aaudio.AAudioStream_requestStart = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_requestStart");
pContext->aaudio.AAudioStream_requestStop = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->aaudio.hAAudio, "AAudioStream_requestStop");
/* In playback mode (no duplex) we need to load some initial buffers. In duplex mode we need to enqueu silent buffers. */
/* In playback mode (no duplex) we need to load some initial buffers. In duplex mode we need to enqueue silent buffers. */
pContext->opensl.slCreateEngine = (ma_proc)ma_dlsym(pContext, pContext->opensl.libOpenSLES, "slCreateEngine");
pContext->opensl.slCreateEngine = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->opensl.libOpenSLES, "slCreateEngine");
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 32)))
#include <emscripten/webaudio.h>
#define MA_SUPPORT_AUDIO_WORKLETS
#endif
/*
TODO: Version 0.12: Swap this logic around so that AudioWorklets are used by default. Add MA_NO_AUDIO_WORKLETS.
*/
#if defined(MA_ENABLE_AUDIO_WORKLETS) && defined(MA_SUPPORT_AUDIO_WORKLETS)
#define MA_USE_AUDIO_WORKLETS
#endif
/* The thread stack size must be a multiple of 16. */
#ifndef MA_AUDIO_WORKLETS_THREAD_STACK_SIZE
#define MA_AUDIO_WORKLETS_THREAD_STACK_SIZE 16384
#endif
void* EMSCRIPTEN_KEEPALIVE ma_malloc_emscripten(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks)
{
return ma_malloc(sz, pAllocationCallbacks);
}
void EMSCRIPTEN_KEEPALIVE ma_free_emscripten(void* p, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_free(p, pAllocationCallbacks);
}
/* Make sure all nodes are disconnected and marked for collection. */
if (device.scriptNode !== undefined) {
device.scriptNode.onaudioprocess = function(e) {}; /* We want to reset the callback to ensure it doesn't get called after AudioContext.close() has returned. Shouldn't happen since we're disconnecting, but just to be safe... */
device.scriptNode.disconnect();
device.scriptNode = undefined;
}
if (device.streamNode !== undefined) {
device.streamNode.disconnect();
device.streamNode = undefined;
}
if (device.streamNode !== undefined) {
device.streamNode.disconnect();
device.streamNode = undefined;
}
}, pDevice->webaudio.deviceIndex);
/*
Stop the device. I think there is a chance the callback could get fired after calling this, hence why we want
to clear the callback before closing.
*/
device.webaudio.close();
device.webaudio = undefined;
emscripten_destroy_web_audio_node(pDevice->webaudio.audioWorklet);
emscripten_destroy_audio_context(pDevice->webaudio.audioContext);
ma_free(pDevice->webaudio.pStackBuffer, &pDevice->pContext->allocationCallbacks);
}
#else
{
EM_ASM({
var device = miniaudio.get_device_by_index($0);
/* Can't forget to free the intermediary buffer. This is the buffer that's shared between JavaScript and C. */
if (device.intermediaryBuffer !== undefined) {
Module._free(device.intermediaryBuffer);
device.intermediaryBuffer = undefined;
device.intermediaryBufferView = undefined;
device.intermediaryBufferSizeInBytes = undefined;
}
/* Make sure all nodes are disconnected and marked for collection. */
if (device.scriptNode !== undefined) {
device.scriptNode.onaudioprocess = function(e) {}; /* We want to reset the callback to ensure it doesn't get called after AudioContext.close() has returned. Shouldn't happen since we're disconnecting, but just to be safe... */
device.scriptNode.disconnect();
device.scriptNode = undefined;
}
/* Make sure the device is untracked so the slot can be reused later. */
miniaudio.untrack_device_by_index($0);
}, deviceIndex, deviceType);
}
if (device.streamNode !== undefined) {
device.streamNode.disconnect();
device.streamNode = undefined;
}
static ma_result ma_device_uninit__webaudio(ma_device* pDevice)
{
MA_ASSERT(pDevice != NULL);
/*
Stop the device. I think there is a chance the callback could get fired after calling this, hence why we want
to clear the callback before closing.
*/
device.webaudio.close();
device.webaudio = undefined;
}, pDevice->webaudio.deviceIndex);
}
#endif
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture);
}
/* Clean up the device on the JS side. */
EM_ASM({
miniaudio.untrack_device_by_index($0);
}, pDevice->webaudio.deviceIndex);
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_playback, pDevice->webaudio.indexPlayback);
}
ma_free(pDevice->webaudio.pIntermediaryBuffer, &pDevice->pContext->allocationCallbacks);
There have been reports of the default buffer size being too small on some browsers. There have been reports of the default buffer
size being too small on some browsers. If we're using default buffer size, we'll make sure the period size is a big biffer than our
standard defaults.
There have been reports of the default buffer size being too small on some browsers. If we're using
the default buffer size, we'll make sure the period size is bigger than our standard defaults.
int deviceIndex;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint32 periodSizeInFrames;
ma_device* pDevice;
const ma_device_config* pConfig;
ma_device_descriptor* pDescriptorPlayback;
ma_device_descriptor* pDescriptorCapture;
} ma_audio_worklet_thread_initialized_data;
static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const AudioSampleFrame* pInputs, int outputCount, AudioSampleFrame* pOutputs, int paramCount, const AudioParamFrame* pParams, void* pUserData)
{
ma_device* pDevice = (ma_device*)pUserData;
ma_uint32 frameCount;
/* We're going to calculate some stuff in C just to simplify the JS code. */
channels = (pDescriptor->channels > 0) ? pDescriptor->channels : MA_DEFAULT_CHANNELS;
sampleRate = (pDescriptor->sampleRate > 0) ? pDescriptor->sampleRate : MA_DEFAULT_SAMPLE_RATE;
periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__webaudio(pDescriptor, sampleRate, pConfig->performanceProfile);
/*
The Emscripten documentation says that it'll always be 128 frames being passed in. Hard coding it like that feels
like a very bad idea to me. Even if it's hard coded in the backend, the API and documentation should always refer
to variables instead of a hard coded number. In any case, will follow along for the time being.
Unfortunately the audio data is not interleaved so we'll need to convert it before we give the data to miniaudio
for further processing.
*/
frameCount = 128;
if (inputCount > 0) {
/* Input data needs to be interleaved before we hand it to the client. */
for (ma_uint32 iChannel = 0; iChannel < pDevice->capture.internalChannels; iChannel += 1) {
for (ma_uint32 iFrame = 0; iFrame < frameCount; iFrame += 1) {
pDevice->webaudio.pIntermediaryBuffer[iFrame*pDevice->capture.internalChannels + iChannel] = pInputs[0].data[frameCount*iChannel + iFrame];
}
}
/* We create the device on the JavaScript side and reference it using an index. We use this to make it possible to reference the device between JavaScript and C. */
deviceIndex = EM_ASM_INT({
var channels = $0;
var sampleRate = $1;
var bufferSize = $2; /* In PCM frames. */
var isCapture = $3;
var pDevice = $4;
if (outputCount > 0) {
/* If it's a capture-only device, we'll need to output silence. */
if (pDevice->type == ma_device_type_capture) {
MA_ZERO_MEMORY(pOutputs[0].data, frameCount * pDevice->playback.internalChannels * sizeof(float));
} else {
ma_device_process_pcm_frames_playback__webaudio(pDevice, frameCount, pDevice->webaudio.pIntermediaryBuffer);
if (typeof(window.miniaudio) === 'undefined') {
return -1; /* Context not initialized. */
/* We've read the data from the client. Now we need to deinterleave the buffer and output to the output buffer. */
for (ma_uint32 iChannel = 0; iChannel < pDevice->playback.internalChannels; iChannel += 1) {
for (ma_uint32 iFrame = 0; iFrame < frameCount; iFrame += 1) {
pOutputs[0].data[frameCount*iChannel + iFrame] = pDevice->webaudio.pIntermediaryBuffer[iFrame*pDevice->playback.internalChannels + iChannel];
}
}
/*
We need an intermediary buffer which we use for JavaScript and C interop. This buffer stores interleaved f32 PCM data. Because it's passed between
JavaScript and C it needs to be allocated and freed using Module._malloc() and Module._free().
*/
device.intermediaryBufferSizeInBytes = channels * bufferSize * 4;
device.intermediaryBuffer = Module._malloc(device.intermediaryBufferSizeInBytes);
device.intermediaryBufferView = new Float32Array(Module.HEAPF32.buffer, device.intermediaryBuffer, device.intermediaryBufferSizeInBytes);
static void ma_audio_worklet_processor_created__webaudio(EMSCRIPTEN_WEBAUDIO_T audioContext, EM_BOOL success, void* pUserData)
{
ma_audio_worklet_thread_initialized_data* pParameters = (ma_audio_worklet_thread_initialized_data*)pUserData;
EmscriptenAudioWorkletNodeCreateOptions audioWorkletOptions;
int channels = 0;
size_t intermediaryBufferSizeInFrames;
int sampleRate;
/*
Both playback and capture devices use a ScriptProcessorNode for performing per-sample operations.
if (success == EM_FALSE) {
pParameters->pDevice->webaudio.initResult = MA_ERROR;
ma_free(pParameters, &pParameters->pDevice->pContext->allocationCallbacks);
return;
}
ScriptProcessorNode is actually deprecated so this is likely to be temporary. The way this works for playback is very simple. You just set a callback
that's periodically fired, just like a normal audio callback function. But apparently this design is "flawed" and is now deprecated in favour of
something called AudioWorklets which _forces_ you to load a _separate_ .js file at run time... nice... Hopefully ScriptProcessorNode will continue to
work for years to come, but this may need to change to use AudioSourceBufferNode instead, which I think is what Emscripten uses for it's built-in SDL
implementation. I'll be avoiding that insane AudioWorklet API like the plague...
/* The next step is to initialize the audio worklet node. */
MA_ZERO_OBJECT(&audioWorkletOptions);
For capture it is a bit unintuitive. We use the ScriptProccessorNode _only_ to get the raw PCM data. It is connected to an AudioContext just like the
playback case, however we just output silence to the AudioContext instead of passing any real data. It would make more sense to me to use the
MediaRecorder API, but unfortunately you need to specify a MIME time (Opus, Vorbis, etc.) for the binary blob that's returned to the client, but I've
been unable to figure out how to get this as raw PCM. The closest I can think is to use the MIME type for WAV files and just parse it, but I don't know
how well this would work. Although ScriptProccessorNode is deprecated, in practice it seems to have pretty good browser support so I'm leaving it like
this for now. If anyone knows how I could get raw PCM data using the MediaRecorder API please let me know!
*/
device.scriptNode = device.webaudio.createScriptProcessor(bufferSize, (isCapture) ? channels : 0, (isCapture) ? 0 : channels);
/*
The way channel counts work with Web Audio is confusing. As far as I can tell, there's no way to know the channel
count from MediaStreamAudioSourceNode (what we use for capture)? The only way to have control is to configure an
output channel count on the capture side. This is slightly confusing for capture mode because intuitively you
wouldn't actually connect an output to an input-only node, but this is what we'll have to do in order to have
proper control over the channel count. In the capture case, we'll have to output silence to it's output node.
*/
if (pParameters->pConfig->deviceType == ma_device_type_capture) {
channels = (int)((pParameters->pDescriptorCapture->channels > 0) ? pParameters->pDescriptorCapture->channels : MA_DEFAULT_CHANNELS);
audioWorkletOptions.numberOfInputs = 1;
} else {
channels = (int)((pParameters->pDescriptorPlayback->channels > 0) ? pParameters->pDescriptorPlayback->channels : MA_DEFAULT_CHANNELS);
if (isCapture) {
device.scriptNode.onaudioprocess = function(e) {
if (device.intermediaryBuffer === undefined) {
return; /* This means the device has been uninitialized. */
}
if (pParameters->pConfig->deviceType == ma_device_type_duplex) {
audioWorkletOptions.numberOfInputs = 1;
} else {
audioWorkletOptions.numberOfInputs = 0;
}
}
if (device.intermediaryBufferView.length == 0) {
/* Recreate intermediaryBufferView when losing reference to the underlying buffer, probably due to emscripten resizing heap. */
device.intermediaryBufferView = new Float32Array(Module.HEAPF32.buffer, device.intermediaryBuffer, device.intermediaryBufferSizeInBytes);
}
audioWorkletOptions.numberOfOutputs = 1;
audioWorkletOptions.outputChannelCounts = &channels;
/* Make sure silence it output to the AudioContext destination. Not doing this will cause sound to come out of the speakers! */
for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
e.outputBuffer.getChannelData(iChannel).fill(0.0);
}
/* There are some situations where we may want to send silence to the client. */
var sendSilence = false;
if (device.streamNode === undefined) {
sendSilence = true;
}
/*
Now that we know the channel count to use we can allocate the intermediary buffer. The
intermediary buffer is used for interleaving and deinterleaving.
*/
intermediaryBufferSizeInFrames = 128;
/* Sanity check. This will never happen, right? */
if (e.inputBuffer.numberOfChannels != channels) {
console.log("Capture: Channel count mismatch. " + e.inputBufer.numberOfChannels + " != " + channels + ". Sending silence.");
sendSilence = true;
}
pParameters->pDevice->webaudio.pIntermediaryBuffer = (float*)ma_malloc(intermediaryBufferSizeInFrames * (ma_uint32)channels * sizeof(float), &pParameters->pDevice->pContext->allocationCallbacks);
if (pParameters->pDevice->webaudio.pIntermediaryBuffer == NULL) {
pParameters->pDevice->webaudio.initResult = MA_OUT_OF_MEMORY;
ma_free(pParameters, &pParameters->pDevice->pContext->allocationCallbacks);
return;
}
/* This looped design guards against the situation where e.inputBuffer is a different size to the original buffer size. Should never happen in practice. */
var totalFramesProcessed = 0;
while (totalFramesProcessed < e.inputBuffer.length) {
var framesRemaining = e.inputBuffer.length - totalFramesProcessed;
var framesToProcess = framesRemaining;
if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
}
/* We need to do the reverse of the playback case. We need to interleave the input data and copy it into the intermediary buffer. Then we send it to the client. */
if (sendSilence) {
device.intermediaryBufferView.fill(0.0);
} else {
for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
for (var iChannel = 0; iChannel < e.inputBuffer.numberOfChannels; ++iChannel) {
device.intermediaryBufferView[iFrame*channels + iChannel] = e.inputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame];
}
}
}
pParameters->pDevice->webaudio.audioWorklet = emscripten_create_wasm_audio_worklet_node(audioContext, "miniaudio", &audioWorkletOptions, &ma_audio_worklet_process_callback__webaudio, pParameters->pDevice);
/* Send data to the client from our intermediary buffer. */
ccall("ma_device_process_pcm_frames_capture__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);
/* With the audio worklet initialized we can now attach it to the graph. */
if (pParameters->pConfig->deviceType == ma_device_type_capture || pParameters->pConfig->deviceType == ma_device_type_duplex) {
ma_result attachmentResult = EM_ASM_INT({
var getUserMediaResult = 0;
var audioWorklet = emscriptenGetAudioObject($0);
var audioContext = emscriptenGetAudioObject($1);
device.streamNode = device.webaudio.createMediaStreamSource(stream);
device.streamNode.connect(device.scriptNode);
device.scriptNode.connect(device.webaudio.destination);
audioContext.streamNode = audioContext.createMediaStreamSource(stream);
audioContext.streamNode.connect(audioWorklet);
audioWorklet.connect(audioContext.destination);
getUserMediaResult = 0; /* 0 = MA_SUCCESS */
if(device.intermediaryBufferView.length == 0) {
/* Recreate intermediaryBufferView when losing reference to the underlying buffer, probably due to emscripten resizing heap. */
device.intermediaryBufferView = new Float32Array(Module.HEAPF32.buffer, device.intermediaryBuffer, device.intermediaryBufferSizeInBytes);
}
return getUserMediaResult;
}, pParameters->pDevice->webaudio.audioWorklet, audioContext);
var outputSilence = false;
if (attachmentResult != MA_SUCCESS) {
ma_log_postf(ma_device_get_log(pParameters->pDevice), MA_LOG_LEVEL_ERROR, "Web Audio: Failed to connect capture node.");
emscripten_destroy_web_audio_node(pParameters->pDevice->webaudio.audioWorklet);
pParameters->pDevice->webaudio.initResult = attachmentResult;
ma_free(pParameters, &pParameters->pDevice->pContext->allocationCallbacks);
return;
}
}
/* Sanity check. This will never happen, right? */
if (e.outputBuffer.numberOfChannels != channels) {
console.log("Playback: Channel count mismatch. " + e.outputBufer.numberOfChannels + " != " + channels + ". Outputting silence.");
outputSilence = true;
return;
}
/* If it's playback only we can now attach the worklet node to the graph. This has already been done for the duplex case. */
if (pParameters->pConfig->deviceType == ma_device_type_playback) {
ma_result attachmentResult = EM_ASM_INT({
var audioWorklet = emscriptenGetAudioObject($0);
var audioContext = emscriptenGetAudioObject($1);
audioWorklet.connect(audioContext.destination);
return 0; /* 0 = MA_SUCCESS */
}, pParameters->pDevice->webaudio.audioWorklet, audioContext);
/* This looped design guards against the situation where e.outputBuffer is a different size to the original buffer size. Should never happen in practice. */
var totalFramesProcessed = 0;
while (totalFramesProcessed < e.outputBuffer.length) {
var framesRemaining = e.outputBuffer.length - totalFramesProcessed;
var framesToProcess = framesRemaining;
if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) {
framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4);
}
if (attachmentResult != MA_SUCCESS) {
ma_log_postf(ma_device_get_log(pParameters->pDevice), MA_LOG_LEVEL_ERROR, "Web Audio: Failed to connect playback node.");
pParameters->pDevice->webaudio.initResult = attachmentResult;
ma_free(pParameters, &pParameters->pDevice->pContext->allocationCallbacks);
return;
}
}
/* Read data from the client into our intermediary buffer. */
ccall("ma_device_process_pcm_frames_playback__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]);
/* We need to update the descriptors so that they reflect the internal data format. Both capture and playback should be the same. */
sampleRate = EM_ASM_INT({ return emscriptenGetAudioObject($0).sampleRate; }, audioContext);
/* At this point we'll have data in our intermediary buffer which we now need to deinterleave and copy over to the output buffers. */
if (outputSilence) {
for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
e.outputBuffer.getChannelData(iChannel).fill(0.0);
}
} else {
for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
var outputBuffer = e.outputBuffer.getChannelData(iChannel);
var intermediaryBuffer = device.intermediaryBufferView;
for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) {
outputBuffer[totalFramesProcessed + iFrame] = intermediaryBuffer[iFrame*channels + iChannel];
}
}
}
if (pParameters->pDescriptorCapture != NULL) {
pParameters->pDescriptorCapture->format = ma_format_f32;
pParameters->pDescriptorCapture->channels = (ma_uint32)channels;
pParameters->pDescriptorCapture->sampleRate = (ma_uint32)sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_webaudio, pParameters->pDescriptorCapture->channelMap, ma_countof(pParameters->pDescriptorCapture->channelMap), pParameters->pDescriptorCapture->channels);
pParameters->pDescriptorCapture->periodSizeInFrames = intermediaryBufferSizeInFrames;
pParameters->pDescriptorCapture->periodCount = 1;
}
totalFramesProcessed += framesToProcess;
}
};
if (pParameters->pDescriptorPlayback != NULL) {
pParameters->pDescriptorPlayback->format = ma_format_f32;
pParameters->pDescriptorPlayback->channels = (ma_uint32)channels;
pParameters->pDescriptorPlayback->sampleRate = (ma_uint32)sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_webaudio, pParameters->pDescriptorPlayback->channelMap, ma_countof(pParameters->pDescriptorPlayback->channelMap), pParameters->pDescriptorPlayback->channels);
pParameters->pDescriptorPlayback->periodSizeInFrames = intermediaryBufferSizeInFrames;
pParameters->pDescriptorPlayback->periodCount = 1;
}
device.scriptNode.connect(device.webaudio.destination);
}
/* At this point we're done and we can return. */
ma_log_postf(ma_device_get_log(pParameters->pDevice), MA_LOG_LEVEL_DEBUG, "AudioWorklets: Created worklet node: %d\n", pParameters->pDevice->webaudio.audioWorklet);
pParameters->pDevice->webaudio.initResult = MA_SUCCESS;
ma_free(pParameters, &pParameters->pDevice->pContext->allocationCallbacks);
}
return miniaudio.track_device(device);
}, channels, sampleRate, periodSizeInFrames, deviceType == ma_device_type_capture, pDevice);
static void ma_audio_worklet_thread_initialized__webaudio(EMSCRIPTEN_WEBAUDIO_T audioContext, EM_BOOL success, void* pUserData)
{
ma_audio_worklet_thread_initialized_data* pParameters = (ma_audio_worklet_thread_initialized_data*)pUserData;
WebAudioWorkletProcessorCreateOptions workletProcessorOptions;
pDescriptor->format = ma_format_f32;
pDescriptor->channels = channels;
ma_channel_map_init_standard(ma_standard_channel_map_webaudio, pDescriptor->channelMap, ma_countof(pDescriptor->channelMap), pDescriptor->channels);
pDescriptor->sampleRate = EM_ASM_INT({ return miniaudio.get_device_by_index($0).webaudio.sampleRate; }, deviceIndex);
pDescriptor->periodSizeInFrames = periodSizeInFrames;
pDescriptor->periodCount = 1;
MA_ZERO_OBJECT(&workletProcessorOptions);
workletProcessorOptions.name = "miniaudio"; /* I'm not entirely sure what to call this. Does this need to be globally unique, or does it need only be unique for a given AudioContext? */
/*
With AudioWorklets we'll have just a single AudioContext. I'm not sure why I'm not doing this for ScriptProcessorNode so
it might be worthwhile to look into that as well.
*/
#if defined(MA_USE_AUDIO_WORKLETS)
{
EmscriptenWebAudioCreateAttributes audioContextAttributes;
ma_audio_worklet_thread_initialized_data* pInitParameters;
void* pStackBuffer;
if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
result = ma_device_init_by_type__webaudio(pDevice, pConfig, pDescriptorCapture, ma_device_type_capture);
if (result != MA_SUCCESS) {
return result;
if (pConfig->performanceProfile == ma_performance_profile_conservative) {
audioContextAttributes.latencyHint = MA_WEBAUDIO_LATENCY_HINT_PLAYBACK;
} else {
audioContextAttributes.latencyHint = MA_WEBAUDIO_LATENCY_HINT_INTERACTIVE;
}
/*
In my testing, Firefox does not seem to capture audio data properly if the sample rate is set
to anything other than 48K. This does not seem to be the case for other browsers. For this reason,
if the device type is anything other than playback, we'll leave the sample rate as-is and let the
browser pick the appropriate rate for us.
*/
if (pConfig->deviceType == ma_device_type_playback) {
audioContextAttributes.sampleRate = pDescriptorPlayback->sampleRate;
} else {
audioContextAttributes.sampleRate = 0;
}
/* It's not clear if this can return an error. None of the tests in the Emscripten repository check for this, so neither am I for now. */
pDevice->webaudio.audioContext = emscripten_create_audio_context(&audioContextAttributes);
/*
With the context created we can now create the worklet. We can only have a single worklet per audio
context which means we'll need to craft this appropriately to handle duplex devices correctly.
*/
/*
We now need to create a worker thread. This is a bit weird because we need to allocate our
own buffer for the thread's stack. The stack needs to be aligned to 16 bytes. I'm going to
allocate this on the heap to keep it simple.
*/
pStackBuffer = ma_aligned_malloc(MA_AUDIO_WORKLETS_THREAD_STACK_SIZE, 16, &pDevice->pContext->allocationCallbacks);
if (pStackBuffer == NULL) {
emscripten_destroy_audio_context(pDevice->webaudio.audioContext);
return MA_OUT_OF_MEMORY;
}
/* Our thread initialization parameters need to be allocated on the heap so they don't go out of scope. */
pInitParameters = (ma_audio_worklet_thread_initialized_data*)ma_malloc(sizeof(*pInitParameters), &pDevice->pContext->allocationCallbacks);
if (pInitParameters == NULL) {
ma_free(pStackBuffer, &pDevice->pContext->allocationCallbacks);
emscripten_destroy_audio_context(pDevice->webaudio.audioContext);
return MA_OUT_OF_MEMORY;
}
pInitParameters->pDevice = pDevice;
pInitParameters->pConfig = pConfig;
pInitParameters->pDescriptorPlayback = pDescriptorPlayback;
pInitParameters->pDescriptorCapture = pDescriptorCapture;
/*
We need to flag the device as not yet initialized so we can wait on it later. Unfortunately all of
the Emscripten WebAudio stuff is asynchronous.
*/
pDevice->webaudio.initResult = MA_BUSY;
{
emscripten_start_wasm_audio_worklet_thread_async(pDevice->webaudio.audioContext, pStackBuffer, MA_AUDIO_WORKLETS_THREAD_STACK_SIZE, ma_audio_worklet_thread_initialized__webaudio, pInitParameters);
}
while (pDevice->webaudio.initResult == MA_BUSY) { emscripten_sleep(1); } /* We must wait for initialization to complete. We're just spinning here. The emscripten_sleep() call is why we need to build with `-sASYNCIFY`. */
/* Initialization is now complete. Descriptors were updated when the worklet was initialized. */
if (pDevice->webaudio.initResult != MA_SUCCESS) {
ma_free(pStackBuffer, &pDevice->pContext->allocationCallbacks);
emscripten_destroy_audio_context(pDevice->webaudio.audioContext);
return pDevice->webaudio.initResult;
/* We need to add an entry to the miniaudio.devices list on the JS side so we can do some JS/C interop. */
pDevice->webaudio.deviceIndex = EM_ASM_INT({
return miniaudio.track_device({
webaudio: emscriptenGetAudioObject($0),
state: 1 /* 1 = ma_device_state_stopped */
});
}, pDevice->webaudio.audioContext);
return MA_SUCCESS;
#else
{
/* ScriptProcessorNode. This path requires us to do almost everything in JS, but we'll do as much as we can in C. */
ma_uint32 deviceIndex;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint32 periodSizeInFrames;
/* The channel count will depend on the device type. If it's a capture, use it's, otherwise use the playback side. */
if (pConfig->deviceType == ma_device_type_capture) {
channels = (pDescriptorCapture->channels > 0) ? pDescriptorCapture->channels : MA_DEFAULT_CHANNELS;
} else {
channels = (pDescriptorPlayback->channels > 0) ? pDescriptorPlayback->channels : MA_DEFAULT_CHANNELS;
}
/*
When testing in Firefox, I've seen it where capture mode fails if the sample rate is changed to anything other than it's
native rate. For this reason we're leaving the sample rate untouched for capture devices.
*/
if (pConfig->deviceType == ma_device_type_playback) {
sampleRate = pDescriptorPlayback->sampleRate;
} else {
sampleRate = 0; /* Let the browser decide when capturing. */
}
/* The period size needs to be a power of 2. */
if (pConfig->deviceType == ma_device_type_capture) {
periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__webaudio(pDescriptorCapture, sampleRate, pConfig->performanceProfile);
} else {
periodSizeInFrames = ma_calculate_period_size_in_frames_from_descriptor__webaudio(pDescriptorPlayback, sampleRate, pConfig->performanceProfile);
}
/* We need an intermediary buffer for doing interleaving and deinterleaving. */
pDevice->webaudio.pIntermediaryBuffer = (float*)ma_malloc(periodSizeInFrames * channels * sizeof(float), &pDevice->pContext->allocationCallbacks);
if (pDevice->webaudio.pIntermediaryBuffer == NULL) {
return MA_OUT_OF_MEMORY;
}
deviceIndex = EM_ASM_INT({
var deviceType = $0;
var channels = $1;
var sampleRate = $2;
var bufferSize = $3;
var pIntermediaryBuffer = $4;
var pDevice = $5;
if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
result = ma_device_init_by_type__webaudio(pDevice, pConfig, pDescriptorPlayback, ma_device_type_playback);
if (result != MA_SUCCESS) {
if (pConfig->deviceType == ma_device_type_duplex) {
ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture);
if (typeof(window.miniaudio) === 'undefined') {
return -1; /* Context not initialized. */
}
var device = {};
/* First thing we need is an AudioContext. */
var audioContextOptions = {};
if (deviceType == window.miniaudio.device_type.playback) {
audioContextOptions.sampleRate = sampleRate;
}
device.webaudio = new (window.AudioContext || window.webkitAudioContext)(audioContextOptions);
device.webaudio.suspend(); /* The AudioContext must be created in a suspended state. */
device.state = window.miniaudio.device_state.stopped;
/*
We need to create a ScriptProcessorNode. The channel situation is the same as the AudioWorklet path in that we
need to specify an output and configure the channel count there.
*/
var channelCountIn = 0;
var channelCountOut = channels;
if (deviceType != window.miniaudio.device_type.playback) {
channelCountIn = channels;
}
device.scriptNode = device.webaudio.createScriptProcessor(bufferSize, channelCountIn, channelCountOut);
/* The node processing callback. */
device.scriptNode.onaudioprocess = function(e) {
if (device.intermediaryBufferView == null || device.intermediaryBufferView.length == 0) {
device.intermediaryBufferView = new Float32Array(Module.HEAPF32.buffer, pIntermediaryBuffer, bufferSize * channels);
}
/* Do the capture side first. */
if (deviceType == miniaudio.device_type.capture || deviceType == miniaudio.device_type.duplex) {
/* The data must be interleaved before being processed miniaudio. */
for (var iChannel = 0; iChannel < channels; iChannel += 1) {
var inputBuffer = e.inputBuffer.getChannelData(iChannel);
var intermediaryBuffer = device.intermediaryBufferView;
for (var iFrame = 0; iFrame < bufferSize; iFrame += 1) {
intermediaryBuffer[iFrame*channels + iChannel] = inputBuffer[iFrame];
}
}
_ma_device_process_pcm_frames_capture__webaudio(pDevice, bufferSize, pIntermediaryBuffer);
}
if (deviceType == miniaudio.device_type.playback || deviceType == miniaudio.device_type.duplex) {
_ma_device_process_pcm_frames_playback__webaudio(pDevice, bufferSize, pIntermediaryBuffer);
for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
var outputBuffer = e.outputBuffer.getChannelData(iChannel);
var intermediaryBuffer = device.intermediaryBufferView;
for (var iFrame = 0; iFrame < bufferSize; iFrame += 1) {
outputBuffer[iFrame] = intermediaryBuffer[iFrame*channels + iChannel];
}
}
} else {
/* It's a capture-only device. Make sure the output is silenced. */
for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) {
e.outputBuffer.getChannelData(iChannel).fill(0.0);
}
}
};
/* Now we need to connect our node to the graph. */
if (deviceType == miniaudio.device_type.capture || deviceType == miniaudio.device_type.duplex) {
navigator.mediaDevices.getUserMedia({audio:true, video:false})
.then(function(stream) {
device.streamNode = device.webaudio.createMediaStreamSource(stream);
device.streamNode.connect(device.scriptNode);
device.scriptNode.connect(device.webaudio.destination);
})
.catch(function(error) {
console.log("Failed to get user media: " + error);
});
}
if (deviceType == miniaudio.device_type.playback) {
device.scriptNode.connect(device.webaudio.destination);
return result;
return miniaudio.track_device(device);
}, pConfig->deviceType, channels, sampleRate, periodSizeInFrames, pDevice->webaudio.pIntermediaryBuffer, pDevice);
if (deviceIndex < 0) {
return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
}
pDevice->webaudio.deviceIndex = deviceIndex;
/* Grab the sample rate from the audio context directly. */
sampleRate = (ma_uint32)EM_ASM_INT({ return miniaudio.get_device_by_index($0).webaudio.sampleRate; }, deviceIndex);
if (pDescriptorCapture != NULL) {
pDescriptorCapture->format = ma_format_f32;
pDescriptorCapture->channels = channels;
pDescriptorCapture->sampleRate = sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_webaudio, pDescriptorCapture->channelMap, ma_countof(pDescriptorCapture->channelMap), pDescriptorCapture->channels);
pDescriptorCapture->periodSizeInFrames = periodSizeInFrames;
pDescriptorCapture->periodCount = 1;
}
if (pDescriptorPlayback != NULL) {
pDescriptorPlayback->format = ma_format_f32;
pDescriptorPlayback->channels = channels;
pDescriptorPlayback->sampleRate = sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_webaudio, pDescriptorPlayback->channelMap, ma_countof(pDescriptorPlayback->channelMap), pDescriptorPlayback->channels);
pDescriptorPlayback->periodSizeInFrames = periodSizeInFrames;
pDescriptorPlayback->periodCount = 1;
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
EM_ASM({
var device = miniaudio.get_device_by_index($0);
device.webaudio.resume();
device.state = 2; /* ma_device_state_started */
}, pDevice->webaudio.indexPlayback);
}
EM_ASM({
var device = miniaudio.get_device_by_index($0);
device.webaudio.resume();
device.state = miniaudio.device_state.started;
}, pDevice->webaudio.deviceIndex);
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
EM_ASM({
var device = miniaudio.get_device_by_index($0);
device.webaudio.suspend();
device.state = 1; /* ma_device_state_stopped */
}, pDevice->webaudio.indexCapture);
}
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
EM_ASM({
var device = miniaudio.get_device_by_index($0);
device.webaudio.suspend();
device.state = 1; /* ma_device_state_stopped */
}, pDevice->webaudio.indexPlayback);
}
EM_ASM({
var device = miniaudio.get_device_by_index($0);
device.webaudio.suspend();
device.state = miniaudio.device_state.stopped;
}, pDevice->webaudio.deviceIndex);
/* Nothing needs to be done here. */
(void)pContext;
(void)pContext; /* Unused. */
/* Remove the global miniaudio object from window if there are no more references to it. */
EM_ASM({
if (typeof(window.miniaudio) !== 'undefined') {
window.miniaudio.referenceCount -= 1;
if (window.miniaudio.referenceCount === 0) {
delete window.miniaudio;
}
}
});
window.miniaudio = {};
miniaudio.devices = []; /* Device cache for mapping devices to indexes for JavaScript/C interop. */
window.miniaudio = {
referenceCount: 0
};
/* Device types. */
window.miniaudio.device_type = {};
window.miniaudio.device_type.playback = $0;
window.miniaudio.device_type.capture = $1;
window.miniaudio.device_type.duplex = $2;
/* Device states. */
window.miniaudio.device_state = {};
window.miniaudio.device_state.stopped = $3;
window.miniaudio.device_state.started = $4;
/* Device cache for mapping devices to indexes for JavaScript/C interop. */
miniaudio.devices = [];
}
static ma_bool32 ma_context_is_backend_asynchronous(ma_context* pContext)
{
MA_ASSERT(pContext != NULL);
if (pContext->callbacks.onDeviceRead == NULL && pContext->callbacks.onDeviceWrite == NULL) {
if (pContext->callbacks.onDeviceDataLoop == NULL) {
return MA_TRUE;
} else {
return MA_FALSE;
}
} else {
return MA_FALSE;
}
converterConfig.formatIn = pDevice->capture.internalFormat;
converterConfig.channelsIn = pDevice->capture.internalChannels;
converterConfig.sampleRateIn = pDevice->capture.internalSampleRate;
converterConfig.pChannelMapIn = pDevice->capture.internalChannelMap;
converterConfig.formatOut = pDevice->capture.format;
converterConfig.channelsOut = pDevice->capture.channels;
converterConfig.sampleRateOut = pDevice->sampleRate;
converterConfig.pChannelMapOut = pDevice->capture.channelMap;
converterConfig.channelMixMode = pDevice->capture.channelMixMode;
converterConfig.allowDynamicSampleRate = MA_FALSE;
converterConfig.resampling.algorithm = pDevice->resampling.algorithm;
converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
converterConfig.resampling.pBackendVTable = pDevice->resampling.pBackendVTable;
converterConfig.resampling.pBackendUserData = pDevice->resampling.pBackendUserData;
converterConfig.formatIn = pDevice->capture.internalFormat;
converterConfig.channelsIn = pDevice->capture.internalChannels;
converterConfig.sampleRateIn = pDevice->capture.internalSampleRate;
converterConfig.pChannelMapIn = pDevice->capture.internalChannelMap;
converterConfig.formatOut = pDevice->capture.format;
converterConfig.channelsOut = pDevice->capture.channels;
converterConfig.sampleRateOut = pDevice->sampleRate;
converterConfig.pChannelMapOut = pDevice->capture.channelMap;
converterConfig.channelMixMode = pDevice->capture.channelMixMode;
converterConfig.calculateLFEFromSpatialChannels = pDevice->capture.calculateLFEFromSpatialChannels;
converterConfig.allowDynamicSampleRate = MA_FALSE;
converterConfig.resampling.algorithm = pDevice->resampling.algorithm;
converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
converterConfig.resampling.pBackendVTable = pDevice->resampling.pBackendVTable;
converterConfig.resampling.pBackendUserData = pDevice->resampling.pBackendUserData;
converterConfig.formatIn = pDevice->playback.format;
converterConfig.channelsIn = pDevice->playback.channels;
converterConfig.sampleRateIn = pDevice->sampleRate;
converterConfig.pChannelMapIn = pDevice->playback.channelMap;
converterConfig.formatOut = pDevice->playback.internalFormat;
converterConfig.channelsOut = pDevice->playback.internalChannels;
converterConfig.sampleRateOut = pDevice->playback.internalSampleRate;
converterConfig.pChannelMapOut = pDevice->playback.internalChannelMap;
converterConfig.channelMixMode = pDevice->playback.channelMixMode;
converterConfig.allowDynamicSampleRate = MA_FALSE;
converterConfig.resampling.algorithm = pDevice->resampling.algorithm;
converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
converterConfig.resampling.pBackendVTable = pDevice->resampling.pBackendVTable;
converterConfig.resampling.pBackendUserData = pDevice->resampling.pBackendUserData;
converterConfig.formatIn = pDevice->playback.format;
converterConfig.channelsIn = pDevice->playback.channels;
converterConfig.sampleRateIn = pDevice->sampleRate;
converterConfig.pChannelMapIn = pDevice->playback.channelMap;
converterConfig.formatOut = pDevice->playback.internalFormat;
converterConfig.channelsOut = pDevice->playback.internalChannels;
converterConfig.sampleRateOut = pDevice->playback.internalSampleRate;
converterConfig.pChannelMapOut = pDevice->playback.internalChannelMap;
converterConfig.channelMixMode = pDevice->playback.channelMixMode;
converterConfig.calculateLFEFromSpatialChannels = pDevice->playback.calculateLFEFromSpatialChannels;
converterConfig.allowDynamicSampleRate = MA_FALSE;
converterConfig.resampling.algorithm = pDevice->resampling.algorithm;
converterConfig.resampling.linear.lpfOrder = pDevice->resampling.linear.lpfOrder;
converterConfig.resampling.pBackendVTable = pDevice->resampling.pBackendVTable;
converterConfig.resampling.pBackendUserData = pDevice->resampling.pBackendUserData;
In playback mode, if the data converter does not support retrieval of the required number of
input frames given a number of output frames, we need to fall back to a heap-allocated cache.
If the device is doing playback (ma_device_type_playback or ma_device_type_duplex), there's
a couple of situations where we'll need a heap allocated cache.
The first is a duplex device for backends that use a callback for data delivery. The reason
this is needed is that the input stage needs to have a buffer to place the input data while it
waits for the playback stage, after which the miniaudio data callback will get fired. This is
not needed for backends that use a blocking API because miniaudio manages temporary buffers on
the stack to achieve this.
The other situation is when the data converter does not have the ability to query the number
of input frames that are required in order to process a given number of output frames. When
performing data conversion, it's useful if miniaudio know exactly how many frames it needs
from the client in order to generate a given number of output frames. This way, only exactly
the number of frames are needed to be read from the client which means no cache is necessary.
On the other hand, if miniaudio doesn't know how many frames to read, it is forced to read
in fixed sized chunks and then cache any residual unused input frames, those of which will be
processed at a later stage.
if (deviceType == ma_device_type_duplex || ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, 1, &unused) != MA_SUCCESS) {
if (pDevice->type == ma_device_type_duplex || /* Duplex. backend may decide to use ma_device_handle_backend_data_callback() which will require this cache. */
ma_data_converter_get_required_input_frame_count(&pDevice->playback.converter, 1, &unused) != MA_SUCCESS) /* Data conversion required input frame calculation not supported. */
{
pNewInputCache = ma_realloc(pDevice->playback.pInputCache, (size_t)newInputCacheSizeInBytes, &pDevice->pContext->allocationCallbacks);
pNewInputCache = ma_realloc(pDevice->playback.pInputCache, (size_t)newInputCacheSizeInBytes, &pDevice->pContext->allocationCallbacks);
#ifdef MA_WIN32_DESKTOP
ma_CoUninitialize(pContext);
ma_dlclose(pContext, pContext->win32.hUser32DLL);
ma_dlclose(pContext, pContext->win32.hOle32DLL);
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
if (pContext->win32.CoInitializeResult == S_OK) {
ma_CoUninitialize(pContext);
}
#if defined(MA_WIN32_DESKTOP)
ma_dlclose(ma_context_get_log(pContext), pContext->win32.hUser32DLL);
ma_dlclose(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL);
#endif
ma_dlclose(ma_context_get_log(pContext), pContext->win32.hOle32DLL);
#ifdef MA_WIN32_DESKTOP
/* Ole32.dll */
pContext->win32.hOle32DLL = ma_dlopen(pContext, "ole32.dll");
if (pContext->win32.hOle32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoInitializeEx");
pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoUninitialize");
pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoCreateInstance");
pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoTaskMemFree");
pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "PropVariantClear");
pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "StringFromGUID2");
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
#if defined(MA_WIN32_DESKTOP)
/* User32.dll */
pContext->win32.hUser32DLL = ma_dlopen(ma_context_get_log(pContext), "user32.dll");
if (pContext->win32.hUser32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
/* Advapi32.dll */
pContext->win32.hAdvapi32DLL = ma_dlopen(ma_context_get_log(pContext), "advapi32.dll");
if (pContext->win32.hAdvapi32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegCloseKey");
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
#endif
/* Advapi32.dll */
pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
if (pContext->win32.hAdvapi32DLL == NULL) {
/* Ole32.dll */
pContext->win32.hOle32DLL = ma_dlopen(ma_context_get_log(pContext), "ole32.dll");
if (pContext->win32.hOle32DLL == NULL) {
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
pContext->win32.CoInitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitialize");
pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitializeEx");
pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoUninitialize");
pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoCreateInstance");
pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoTaskMemFree");
pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "PropVariantClear");
pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "StringFromGUID2");
#else
(void)pContext; /* Unused. */
for (i = 0; i < sizeof(libpthreadFileNames) / sizeof(libpthreadFileNames[0]); ++i) {
pContext->posix.pthreadSO = ma_dlopen(pContext, libpthreadFileNames[i]);
if (pContext->posix.pthreadSO != NULL) {
break;
}
}
if (pContext->posix.pthreadSO == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
pContext->posix.pthread_create = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_create");
pContext->posix.pthread_join = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_join");
pContext->posix.pthread_mutex_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_init");
pContext->posix.pthread_mutex_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_destroy");
pContext->posix.pthread_mutex_lock = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_lock");
pContext->posix.pthread_mutex_unlock = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_unlock");
pContext->posix.pthread_cond_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_init");
pContext->posix.pthread_cond_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_destroy");
pContext->posix.pthread_cond_wait = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_wait");
pContext->posix.pthread_cond_signal = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_signal");
pContext->posix.pthread_attr_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_init");
pContext->posix.pthread_attr_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_destroy");
pContext->posix.pthread_attr_setschedpolicy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_setschedpolicy");
pContext->posix.pthread_attr_getschedparam = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_getschedparam");
pContext->posix.pthread_attr_setschedparam = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_setschedparam");
#else
pContext->posix.pthread_create = (ma_proc)pthread_create;
pContext->posix.pthread_join = (ma_proc)pthread_join;
pContext->posix.pthread_mutex_init = (ma_proc)pthread_mutex_init;
pContext->posix.pthread_mutex_destroy = (ma_proc)pthread_mutex_destroy;
pContext->posix.pthread_mutex_lock = (ma_proc)pthread_mutex_lock;
pContext->posix.pthread_mutex_unlock = (ma_proc)pthread_mutex_unlock;
pContext->posix.pthread_cond_init = (ma_proc)pthread_cond_init;
pContext->posix.pthread_cond_destroy = (ma_proc)pthread_cond_destroy;
pContext->posix.pthread_cond_wait = (ma_proc)pthread_cond_wait;
pContext->posix.pthread_cond_signal = (ma_proc)pthread_cond_signal;
pContext->posix.pthread_attr_init = (ma_proc)pthread_attr_init;
pContext->posix.pthread_attr_destroy = (ma_proc)pthread_attr_destroy;
#if !defined(__EMSCRIPTEN__)
pContext->posix.pthread_attr_setschedpolicy = (ma_proc)pthread_attr_setschedpolicy;
pContext->posix.pthread_attr_getschedparam = (ma_proc)pthread_attr_getschedparam;
pContext->posix.pthread_attr_setschedparam = (ma_proc)pthread_attr_setschedparam;
#endif
#endif
}
static ma_bool32 ma_context_is_backend_asynchronous(ma_context* pContext)
{
MA_ASSERT(pContext != NULL);
if (pContext->callbacks.onDeviceRead == NULL && pContext->callbacks.onDeviceWrite == NULL) {
if (pContext->callbacks.onDeviceDataLoop == NULL) {
return MA_TRUE;
} else {
return MA_FALSE;
}
} else {
return MA_FALSE;
}
result = MA_NO_BACKEND;
/* Getting here means the onContextInit callback is not set which means the backend is not enabled. Special case for the custom backend. */
if (backend != ma_backend_custom) {
result = MA_BACKEND_NOT_ENABLED;
} else {
#if !defined(MA_HAS_CUSTOM)
result = MA_BACKEND_NOT_ENABLED;
#else
result = MA_NO_BACKEND;
#endif
}
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Failed to initialize %s backend.\n", ma_get_backend_name(backend));
if (result == MA_BACKEND_NOT_ENABLED) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "%s backend is disabled.\n", ma_get_backend_name(backend));
} else {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Failed to initialize %s backend.\n", ma_get_backend_name(backend));
}
*ppCaptureDeviceInfos = pContext->pDeviceInfos + pContext->playbackDeviceInfoCount; /* Capture devices come after playback devices. */
*ppCaptureDeviceInfos = pContext->pDeviceInfos;
/* Capture devices come after playback devices. */
if (pContext->playbackDeviceInfoCount > 0) {
/* Conditional, because NULL+0 is undefined behavior. */
*ppCaptureDeviceInfos += pContext->playbackDeviceInfoCount;
}
{
char channelMapStr[1024];
ma_channel_map_to_string(pDevice->capture.internalChannelMap, pDevice->capture.internalChannels, channelMapStr, sizeof(channelMapStr));
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, " Channel Map In: {%s}\n", channelMapStr);
ma_channel_map_to_string(pDevice->capture.channelMap, pDevice->capture.channels, channelMapStr, sizeof(channelMapStr));
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, " Channel Map Out: {%s}\n", channelMapStr);
}
{
char channelMapStr[1024];
ma_channel_map_to_string(pDevice->playback.channelMap, pDevice->playback.channels, channelMapStr, sizeof(channelMapStr));
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, " Channel Map In: {%s}\n", channelMapStr);
ma_channel_map_to_string(pDevice->playback.internalChannelMap, pDevice->playback.internalChannels, channelMapStr, sizeof(channelMapStr));
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, " Channel Map Out: {%s}\n", channelMapStr);
}
/*
This is a hack for iOS. If the context config is null, there's a good chance the
`ma_device_init(NULL, &deviceConfig, pDevice);` pattern is being used. In this
case, set the session category based on the device type.
*/
#if defined(MA_APPLE_MOBILE)
ma_context_config contextConfig;
if (pContextConfig == NULL) {
contextConfig = ma_context_config_init();
switch (pConfig->deviceType) {
case ma_device_type_duplex: {
contextConfig.coreaudio.sessionCategory = ma_ios_session_category_play_and_record;
} break;
case ma_device_type_capture: {
contextConfig.coreaudio.sessionCategory = ma_ios_session_category_record;
} break;
case ma_device_type_playback:
default: {
contextConfig.coreaudio.sessionCategory = ma_ios_session_category_playback;
} break;
}
pContextConfig = &contextConfig;
}
#endif
/*
This is a safety measure to ensure the internal buffer has been cleared so any leftover
does not get played the next time the device starts. Ideally this should be drained by
the backend first.
*/
pDevice->playback.intermediaryBufferLen = 0;
pDevice->playback.inputCacheConsumed = 0;
pDevice->playback.inputCacheRemaining = 0;
return (ma_device_state)c89atomic_load_i32((ma_int32*)&pDevice->state); /* Naughty cast to get rid of a const warning. */
return ma_atomic_device_state_get((ma_atomic_device_state*)&pDevice->state); /* Naughty cast to get rid of a const warning. */
}
MA_API ma_result ma_mix_pcm_frames_f32(float* pDst, const float* pSrc, ma_uint64 frameCount, ma_uint32 channels, float volume)
{
ma_uint64 iSample;
ma_uint64 sampleCount;
if (pDst == NULL || pSrc == NULL || channels == 0) {
return MA_INVALID_ARGS;
}
if (volume == 0) {
return MA_SUCCESS; /* No changes if the volume is 0. */
}
sampleCount = frameCount * channels;
if (volume == 1) {
for (iSample = 0; iSample < sampleCount; iSample += 1) {
pDst[iSample] += pSrc[iSample];
}
} else {
for (iSample = 0; iSample < sampleCount; iSample += 1) {
pDst[iSample] += ma_apply_volume_unclipped_f32(pSrc[iSample], volume);
}
}
return MA_SUCCESS;
#if defined(MA_SUPPORT_AVX2)
static MA_INLINE void ma_pcm_f32_to_s16__avx2(void* dst, const void* src, ma_uint64 count, ma_dither_mode ditherMode)
{
ma_uint64 i;
ma_uint64 i16;
ma_uint64 count16;
ma_int16* dst_s16;
const float* src_f32;
float ditherMin;
float ditherMax;
/* Both the input and output buffers need to be aligned to 32 bytes. */
if ((((ma_uintptr)dst & 31) != 0) || (((ma_uintptr)src & 31) != 0)) {
ma_pcm_f32_to_s16__optimized(dst, src, count, ditherMode);
return;
}
dst_s16 = (ma_int16*)dst;
src_f32 = (const float*)src;
ditherMin = 0;
ditherMax = 0;
if (ditherMode != ma_dither_mode_none) {
ditherMin = 1.0f / -32768;
ditherMax = 1.0f / 32767;
}
i = 0;
/* AVX2. AVX2 allows us to output 16 s16's at a time which means our loop is unrolled 16 times. */
count16 = count >> 4;
for (i16 = 0; i16 < count16; i16 += 1) {
__m256 d0;
__m256 d1;
__m256 x0;
__m256 x1;
__m256i i0;
__m256i i1;
__m256i p0;
__m256i p1;
__m256i r;
if (ditherMode == ma_dither_mode_none) {
d0 = _mm256_set1_ps(0);
d1 = _mm256_set1_ps(0);
} else if (ditherMode == ma_dither_mode_rectangle) {
d0 = _mm256_set_ps(
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax)
);
d1 = _mm256_set_ps(
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax),
ma_dither_f32_rectangle(ditherMin, ditherMax)
);
} else {
d0 = _mm256_set_ps(
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax)
);
d1 = _mm256_set_ps(
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax),
ma_dither_f32_triangle(ditherMin, ditherMax)
);
}
x0 = *((__m256*)(src_f32 + i) + 0);
x1 = *((__m256*)(src_f32 + i) + 1);
x0 = _mm256_add_ps(x0, d0);
x1 = _mm256_add_ps(x1, d1);
x0 = _mm256_mul_ps(x0, _mm256_set1_ps(32767.0f));
x1 = _mm256_mul_ps(x1, _mm256_set1_ps(32767.0f));
/* Computing the final result is a little more complicated for AVX2 than SSE2. */
i0 = _mm256_cvttps_epi32(x0);
i1 = _mm256_cvttps_epi32(x1);
p0 = _mm256_permute2x128_si256(i0, i1, 0 | 32);
p1 = _mm256_permute2x128_si256(i0, i1, 1 | 48);
r = _mm256_packs_epi32(p0, p1);
_mm256_stream_si256(((__m256i*)(dst_s16 + i)), r);
i += 16;
}
/* Leftover. */
for (; i < count; i += 1) {
float x = src_f32[i];
x = x + ma_dither_f32(ditherMode, ditherMin, ditherMax);
x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */
x = x * 32767.0f; /* -1..1 to -32767..32767 */
dst_s16[i] = (ma_int16)x;
}
}
#endif /* AVX2 */
MA_API ma_result ma_gainer_process_pcm_frames(ma_gainer* pGainer, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
static /*__attribute__((noinline))*/ ma_result ma_gainer_process_pcm_frames_internal(ma_gainer * pGainer, void* MA_RESTRICT pFramesOut, const void* MA_RESTRICT pFramesIn, ma_uint64 frameCount)
float* pFramesOutF32 = (float*)pFramesOut;
const float* pFramesInF32 = (const float*)pFramesIn;
ma_uint64 interpolatedFrameCount;
MA_ASSERT(pGainer != NULL);
/*
We don't necessarily need to apply a linear interpolation for the entire frameCount frames. When
linear interpolation is not needed we can do a simple volume adjustment which will be more
efficient than a lerp with an alpha value of 1.
To do this, all we need to do is determine how many frames need to have a lerp applied. Then we
just process that number of frames with linear interpolation. After that we run on an optimized
path which just applies the new gains without a lerp.
*/
if (pGainer->t >= pGainer->config.smoothTimeInFrames) {
interpolatedFrameCount = 0;
} else {
interpolatedFrameCount = pGainer->t - pGainer->config.smoothTimeInFrames;
if (interpolatedFrameCount > frameCount) {
interpolatedFrameCount = frameCount;
}
}
if (pGainer == NULL) {
return MA_INVALID_ARGS;
/*
Start off with our interpolated frames. When we do this, we'll adjust frameCount and our pointers
so that the fast path can work naturally without consideration of the interpolated path.
*/
if (interpolatedFrameCount > 0) {
/* We can allow the input and output buffers to be null in which case we'll just update the internal timer. */
if (pFramesOut != NULL && pFramesIn != NULL) {
/*
All we're really doing here is moving the old gains towards the new gains. We don't want to
be modifying the gains inside the ma_gainer object because that will break things. Instead
we can make a copy here on the stack. For extreme channel counts we can fall back to a slower
implementation which just uses a standard lerp.
*/
float* pFramesOutF32 = (float*)pFramesOut;
const float* pFramesInF32 = (const float*)pFramesIn;
float a = (float)pGainer->t / pGainer->config.smoothTimeInFrames;
float d = 1.0f / pGainer->config.smoothTimeInFrames;
if (pGainer->config.channels <= 32) {
float pRunningGain[32];
float pRunningGainDelta[32]; /* Could this be heap-allocated as part of the ma_gainer object? */
/* Initialize the running gain. */
for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
float t = (pGainer->pNewGains[iChannel] - pGainer->pOldGains[iChannel]) * pGainer->masterVolume;
pRunningGainDelta[iChannel] = t * d;
pRunningGain[iChannel] = (pGainer->pOldGains[iChannel] * pGainer->masterVolume) + (t * a);
}
iFrame = 0;
/* Optimized paths for common channel counts. This is mostly just experimenting with some SIMD ideas. It's not necessarily final. */
if (pGainer->config.channels == 2) {
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
ma_uint64 unrolledLoopCount = interpolatedFrameCount >> 1;
/* Expand some arrays so we can have a clean SIMD loop below. */
__m128 runningGainDelta0 = _mm_set_ps(pRunningGainDelta[1], pRunningGainDelta[0], pRunningGainDelta[1], pRunningGainDelta[0]);
__m128 runningGain0 = _mm_set_ps(pRunningGain[1] + pRunningGainDelta[1], pRunningGain[0] + pRunningGainDelta[0], pRunningGain[1], pRunningGain[0]);
for (; iFrame < unrolledLoopCount; iFrame += 1) {
_mm_storeu_ps(&pFramesOutF32[iFrame*4 + 0], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*4 + 0]), runningGain0));
runningGain0 = _mm_add_ps(runningGain0, runningGainDelta0);
}
iFrame = unrolledLoopCount << 1;
} else
#endif
{
/*
Two different scalar implementations here. Clang (and I assume GCC) will vectorize
both of these, but the bottom version results in a nicer vectorization with less
instructions emitted. The problem, however, is that the bottom version runs slower
when compiled with MSVC. The top version will be partially vectorized by MSVC.
*/
#if defined(_MSC_VER) && !defined(__clang__)
ma_uint64 unrolledLoopCount = interpolatedFrameCount >> 1;
/* Expand some arrays so we can have a clean 4x SIMD operation in the loop. */
pRunningGainDelta[2] = pRunningGainDelta[0];
pRunningGainDelta[3] = pRunningGainDelta[1];
pRunningGain[2] = pRunningGain[0] + pRunningGainDelta[0];
pRunningGain[3] = pRunningGain[1] + pRunningGainDelta[1];
for (; iFrame < unrolledLoopCount; iFrame += 1) {
pFramesOutF32[iFrame*4 + 0] = pFramesInF32[iFrame*4 + 0] * pRunningGain[0];
pFramesOutF32[iFrame*4 + 1] = pFramesInF32[iFrame*4 + 1] * pRunningGain[1];
pFramesOutF32[iFrame*4 + 2] = pFramesInF32[iFrame*4 + 2] * pRunningGain[2];
pFramesOutF32[iFrame*4 + 3] = pFramesInF32[iFrame*4 + 3] * pRunningGain[3];
/* Move the running gain forward towards the new gain. */
pRunningGain[0] += pRunningGainDelta[0];
pRunningGain[1] += pRunningGainDelta[1];
pRunningGain[2] += pRunningGainDelta[2];
pRunningGain[3] += pRunningGainDelta[3];
}
iFrame = unrolledLoopCount << 1;
#else
for (; iFrame < interpolatedFrameCount; iFrame += 1) {
for (iChannel = 0; iChannel < 2; iChannel += 1) {
pFramesOutF32[iFrame*2 + iChannel] = pFramesInF32[iFrame*2 + iChannel] * pRunningGain[iChannel];
}
for (iChannel = 0; iChannel < 2; iChannel += 1) {
pRunningGain[iChannel] += pRunningGainDelta[iChannel];
}
}
#endif
}
} else if (pGainer->config.channels == 6) {
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
/*
For 6 channels things are a bit more complicated because 6 isn't cleanly divisible by 4. We need to do 2 frames
at a time, meaning we'll be doing 12 samples in a group. Like the stereo case we'll need to expand some arrays
so we can do clean 4x SIMD operations.
*/
ma_uint64 unrolledLoopCount = interpolatedFrameCount >> 1;
/* Expand some arrays so we can have a clean SIMD loop below. */
__m128 runningGainDelta0 = _mm_set_ps(pRunningGainDelta[3], pRunningGainDelta[2], pRunningGainDelta[1], pRunningGainDelta[0]);
__m128 runningGainDelta1 = _mm_set_ps(pRunningGainDelta[1], pRunningGainDelta[0], pRunningGainDelta[5], pRunningGainDelta[4]);
__m128 runningGainDelta2 = _mm_set_ps(pRunningGainDelta[5], pRunningGainDelta[4], pRunningGainDelta[3], pRunningGainDelta[2]);
__m128 runningGain0 = _mm_set_ps(pRunningGain[3], pRunningGain[2], pRunningGain[1], pRunningGain[0]);
__m128 runningGain1 = _mm_set_ps(pRunningGain[1] + pRunningGainDelta[1], pRunningGain[0] + pRunningGainDelta[0], pRunningGain[5], pRunningGain[4]);
__m128 runningGain2 = _mm_set_ps(pRunningGain[5] + pRunningGainDelta[5], pRunningGain[4] + pRunningGainDelta[4], pRunningGain[3] + pRunningGainDelta[3], pRunningGain[2] + pRunningGainDelta[2]);
for (; iFrame < unrolledLoopCount; iFrame += 1) {
_mm_storeu_ps(&pFramesOutF32[iFrame*12 + 0], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*12 + 0]), runningGain0));
_mm_storeu_ps(&pFramesOutF32[iFrame*12 + 4], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*12 + 4]), runningGain1));
_mm_storeu_ps(&pFramesOutF32[iFrame*12 + 8], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*12 + 8]), runningGain2));
runningGain0 = _mm_add_ps(runningGain0, runningGainDelta0);
runningGain1 = _mm_add_ps(runningGain1, runningGainDelta1);
runningGain2 = _mm_add_ps(runningGain2, runningGainDelta2);
}
iFrame = unrolledLoopCount << 1;
} else
#endif
{
for (; iFrame < interpolatedFrameCount; iFrame += 1) {
for (iChannel = 0; iChannel < 6; iChannel += 1) {
pFramesOutF32[iFrame*6 + iChannel] = pFramesInF32[iFrame*6 + iChannel] * pRunningGain[iChannel];
}
/* Move the running gain forward towards the new gain. */
for (iChannel = 0; iChannel < 6; iChannel += 1) {
pRunningGain[iChannel] += pRunningGainDelta[iChannel];
}
}
}
} else if (pGainer->config.channels == 8) {
/* For 8 channels we can just go over frame by frame and do all eight channels as 2 separate 4x SIMD operations. */
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
__m128 runningGainDelta0 = _mm_loadu_ps(&pRunningGainDelta[0]);
__m128 runningGainDelta1 = _mm_loadu_ps(&pRunningGainDelta[4]);
__m128 runningGain0 = _mm_loadu_ps(&pRunningGain[0]);
__m128 runningGain1 = _mm_loadu_ps(&pRunningGain[4]);
for (; iFrame < interpolatedFrameCount; iFrame += 1) {
_mm_storeu_ps(&pFramesOutF32[iFrame*8 + 0], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*8 + 0]), runningGain0));
_mm_storeu_ps(&pFramesOutF32[iFrame*8 + 4], _mm_mul_ps(_mm_loadu_ps(&pFramesInF32[iFrame*8 + 4]), runningGain1));
runningGain0 = _mm_add_ps(runningGain0, runningGainDelta0);
runningGain1 = _mm_add_ps(runningGain1, runningGainDelta1);
}
} else
#endif
{
/* This is crafted so that it auto-vectorizes when compiled with Clang. */
for (; iFrame < interpolatedFrameCount; iFrame += 1) {
for (iChannel = 0; iChannel < 8; iChannel += 1) {
pFramesOutF32[iFrame*8 + iChannel] = pFramesInF32[iFrame*8 + iChannel] * pRunningGain[iChannel];
}
/* Move the running gain forward towards the new gain. */
for (iChannel = 0; iChannel < 8; iChannel += 1) {
pRunningGain[iChannel] += pRunningGainDelta[iChannel];
}
}
}
}
for (; iFrame < interpolatedFrameCount; iFrame += 1) {
for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
pFramesOutF32[iFrame*pGainer->config.channels + iChannel] = pFramesInF32[iFrame*pGainer->config.channels + iChannel] * pRunningGain[iChannel];
pRunningGain[iChannel] += pRunningGainDelta[iChannel];
}
}
} else {
/* Slower path for extreme channel counts where we can't fit enough on the stack. We could also move this to the heap as part of the ma_gainer object which might even be better since it'll only be updated when the gains actually change. */
for (iFrame = 0; iFrame < interpolatedFrameCount; iFrame += 1) {
for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
pFramesOutF32[iFrame*pGainer->config.channels + iChannel] = pFramesInF32[iFrame*pGainer->config.channels + iChannel] * ma_mix_f32_fast(pGainer->pOldGains[iChannel], pGainer->pNewGains[iChannel], a) * pGainer->masterVolume;
}
a += d;
}
}
}
/* Make sure the timer is updated. */
pGainer->t = (ma_uint32)ma_min(pGainer->t + interpolatedFrameCount, pGainer->config.smoothTimeInFrames);
/* Adjust our arguments so the next part can work normally. */
frameCount -= interpolatedFrameCount;
pFramesOut = ma_offset_ptr(pFramesOut, interpolatedFrameCount * sizeof(float));
pFramesIn = ma_offset_ptr(pFramesIn, interpolatedFrameCount * sizeof(float));
}
/* All we need to do here is apply the new gains using an optimized path. */
if (pFramesOut != NULL && pFramesIn != NULL) {
if (pGainer->config.channels <= 32) {
float gains[32];
for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
gains[iChannel] = pGainer->pNewGains[iChannel] * pGainer->masterVolume;
}
ma_copy_and_apply_volume_factor_per_channel_f32((float*)pFramesOut, (const float*)pFramesIn, frameCount, pGainer->config.channels, gains);
} else {
/* Slow path. Too many channels to fit on the stack. Need to apply a master volume as a separate path. */
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannel = 0; iChannel < pGainer->config.channels; iChannel += 1) {
((float*)pFramesOut)[iFrame*pGainer->config.channels + iChannel] = ((const float*)pFramesIn)[iFrame*pGainer->config.channels + iChannel] * pGainer->pNewGains[iChannel] * pGainer->masterVolume;
}
}
}
pFramesOutF32[iChannel] = pFramesInF32[iChannel] * ma_mix_f32_fast(pGainer->pOldGains[iChannel], pGainer->pNewGains[iChannel], a);
pFramesOutF32[iChannel] = pFramesInF32[iChannel] * ma_mix_f32_fast(pGainer->pOldGains[iChannel], pGainer->pNewGains[iChannel], a) * pGainer->masterVolume;
pFramesOutF32[iFrame*pGainer->config.channels + iChannel] = pFramesInF32[iFrame*pGainer->config.channels + iChannel] * ma_gainer_calculate_current_gain(pGainer, iChannel);
pFramesOutF32[iFrame * pGainer->config.channels + iChannel] = pFramesInF32[iFrame * pGainer->config.channels + iChannel] * ma_gainer_calculate_current_gain(pGainer, iChannel) * pGainer->masterVolume;
}
MA_API ma_result ma_gainer_process_pcm_frames(ma_gainer* pGainer, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
if (pGainer == NULL) {
return MA_INVALID_ARGS;
}
/*
ma_gainer_process_pcm_frames_internal() marks pFramesOut and pFramesIn with MA_RESTRICT which
helps with auto-vectorization.
*/
return ma_gainer_process_pcm_frames_internal(pGainer, pFramesOut, pFramesIn, frameCount);
return MA_SUCCESS;
}
MA_API ma_result ma_gainer_set_master_volume(ma_gainer* pGainer, float volume)
{
if (pGainer == NULL) {
return MA_INVALID_ARGS;
}
pGainer->masterVolume = volume;
return MA_SUCCESS;
}
MA_API ma_result ma_gainer_get_master_volume(const ma_gainer* pGainer, float* pVolume)
{
if (pGainer == NULL || pVolume == NULL) {
return MA_INVALID_ARGS;
}
/* If the cursor is still negative we need to just copy the absolute number of those frames, but no more than frameCount. */
if (pFader->cursorInFrames < 0) {
ma_uint64 absCursorInFrames = (ma_uint64)0 - pFader->cursorInFrames;
if (absCursorInFrames > frameCount) {
absCursorInFrames = frameCount;
}
/*
For now we need to clamp frameCount so that the cursor never overflows 32-bits. This is required for
the conversion to a float which we use for the linear interpolation. This might be changed later.
*/
if (frameCount + pFader->cursorInFrames > UINT_MAX) {
frameCount = UINT_MAX - pFader->cursorInFrames;
ma_copy_pcm_frames(pFramesOut, pFramesIn, absCursorInFrames, pFader->config.format, pFader->config.channels);
pFader->cursorInFrames += absCursorInFrames;
frameCount -= absCursorInFrames;
pFramesOut = ma_offset_ptr(pFramesOut, ma_get_bytes_per_frame(pFader->config.format, pFader->config.channels)*absCursorInFrames);
pFramesIn = ma_offset_ptr(pFramesIn, ma_get_bytes_per_frame(pFader->config.format, pFader->config.channels)*absCursorInFrames);
/* Optimized path if volumeBeg and volumeEnd are equal. */
if (pFader->volumeBeg == pFader->volumeEnd) {
if (pFader->volumeBeg == 1) {
/* Straight copy. */
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels);
} else {
/* Copy with volume. */
ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeEnd);
if (pFader->cursorInFrames >= 0) {
/*
For now we need to clamp frameCount so that the cursor never overflows 32-bits. This is required for
the conversion to a float which we use for the linear interpolation. This might be changed later.
*/
if (frameCount + pFader->cursorInFrames > UINT_MAX) {
frameCount = UINT_MAX - pFader->cursorInFrames;
} else {
/* Slower path. Volumes are different, so may need to do an interpolation. */
if (pFader->cursorInFrames >= pFader->lengthInFrames) {
/* Fast path. We've gone past the end of the fade period so just apply the end volume to all samples. */
ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeEnd);
/* Optimized path if volumeBeg and volumeEnd are equal. */
if (pFader->volumeBeg == pFader->volumeEnd) {
if (pFader->volumeBeg == 1) {
/* Straight copy. */
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels);
} else {
/* Copy with volume. */
ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeBeg);
}
/* Slow path. This is where we do the actual fading. */
ma_uint64 iFrame;
ma_uint32 iChannel;
/* Slower path. Volumes are different, so may need to do an interpolation. */
if ((ma_uint64)pFader->cursorInFrames >= pFader->lengthInFrames) {
/* Fast path. We've gone past the end of the fade period so just apply the end volume to all samples. */
ma_copy_and_apply_volume_and_clip_pcm_frames(pFramesOut, pFramesIn, frameCount, pFader->config.format, pFader->config.channels, pFader->volumeEnd);
} else {
/* Slow path. This is where we do the actual fading. */
ma_uint64 iFrame;
ma_uint32 iChannel;
/* For now we only support f32. Support for other formats will be added later. */
if (pFader->config.format == ma_format_f32) {
const float* pFramesInF32 = (const float*)pFramesIn;
/* */ float* pFramesOutF32 = ( float*)pFramesOut;
/* For now we only support f32. Support for other formats might be added later. */
if (pFader->config.format == ma_format_f32) {
const float* pFramesInF32 = (const float*)pFramesIn;
/* */ float* pFramesOutF32 = ( float*)pFramesOut;
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
float a = (ma_uint32)ma_min(pFader->cursorInFrames + iFrame, pFader->lengthInFrames) / (float)((ma_uint32)pFader->lengthInFrames); /* Safe cast due to the frameCount clamp at the top of this function. */
float volume = ma_mix_f32_fast(pFader->volumeBeg, pFader->volumeEnd, a);
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
float a = (ma_uint32)ma_min(pFader->cursorInFrames + iFrame, pFader->lengthInFrames) / (float)((ma_uint32)pFader->lengthInFrames); /* Safe cast due to the frameCount clamp at the top of this function. */
float volume = ma_mix_f32_fast(pFader->volumeBeg, pFader->volumeEnd, a);
for (iChannel = 0; iChannel < pFader->config.channels; iChannel += 1) {
pFramesOutF32[iFrame*pFader->config.channels + iChannel] = pFramesInF32[iFrame*pFader->config.channels + iChannel] * volume;
for (iChannel = 0; iChannel < pFader->config.channels; iChannel += 1) {
pFramesOutF32[iFrame*pFader->config.channels + iChannel] = pFramesInF32[iFrame*pFader->config.channels + iChannel] * volume;
}
MA_API void ma_atomic_vec3f_set(ma_atomic_vec3f* v, ma_vec3f value)
{
ma_spinlock_lock(&v->lock);
{
v->v = value;
}
ma_spinlock_unlock(&v->lock);
}
MA_API ma_vec3f ma_atomic_vec3f_get(ma_atomic_vec3f* v)
{
ma_vec3f r;
ma_spinlock_lock(&v->lock);
{
r = v->v;
}
ma_spinlock_unlock(&v->lock);
return r;
}
pListener->position = ma_vec3f_init_3f(0, 0, 0);
pListener->direction = ma_vec3f_init_3f(0, 0, -1);
pListener->velocity = ma_vec3f_init_3f(0, 0, 0);
ma_atomic_vec3f_init(&pListener->position, ma_vec3f_init_3f(0, 0, 0));
ma_atomic_vec3f_init(&pListener->direction, ma_vec3f_init_3f(0, 0, -1));
ma_atomic_vec3f_init(&pListener->velocity, ma_vec3f_init_3f(0, 0, 0));
pSpatializer->position = ma_vec3f_init_3f(0, 0, 0);
pSpatializer->direction = ma_vec3f_init_3f(0, 0, -1);
pSpatializer->velocity = ma_vec3f_init_3f(0, 0, 0);
ma_atomic_vec3f_init(&pSpatializer->position, ma_vec3f_init_3f(0, 0, 0));
ma_atomic_vec3f_init(&pSpatializer->direction, ma_vec3f_init_3f(0, 0, -1));
ma_atomic_vec3f_init(&pSpatializer->velocity, ma_vec3f_init_3f(0, 0, 0));
/*
The gain needs to be applied per-channel here. The spatialization code below will be changing the per-channel
gains which will then eventually be passed into the gainer which will deal with smoothing the gain transitions
to avoid harsh changes in gain.
*/
for (iChannel = 0; iChannel < channelsOut; iChannel += 1) {
pSpatializer->pNewChannelGainsOut[iChannel] = gain;
}
/*
Convert to our output channel count. If the listener is disabled we just output silence here. We cannot ignore
the whole section of code here because we need to update some internal spatialization state.
*/
if (ma_spatializer_listener_is_enabled(pListener)) {
ma_channel_map_apply_f32((float*)pFramesOut, pChannelMapOut, channelsOut, (const float*)pFramesIn, pChannelMapIn, channelsIn, frameCount, ma_channel_mix_mode_rectangular, ma_mono_expansion_mode_default);
} else {
ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, pSpatializer->channelsOut);
}
*/
for (iChannel = 0; iChannel < channelsOut; iChannel += 1) {
pSpatializer->pNewChannelGainsOut[iChannel] = gain;
}
/*
Convert to our output channel count. If the listener is disabled we just output silence here. We cannot ignore
the whole section of code here because we need to update some internal spatialization state.
if (ma_spatializer_listener_is_enabled(pListener)) {
ma_channel_map_apply_f32((float*)pFramesOut, pChannelMapOut, channelsOut, (const float*)pFramesIn, pChannelMapIn, channelsIn, frameCount, ma_channel_mix_mode_rectangular, ma_mono_expansion_mode_default);
} else {
ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, pSpatializer->channelsOut);
}
pSpatializer->dopplerPitch = ma_doppler_pitch(ma_vec3f_sub(pListener->position, pSpatializer->position), pSpatializer->velocity, listenerVel, speedOfSound, dopplerFactor);
pSpatializer->dopplerPitch = ma_doppler_pitch(ma_vec3f_sub(ma_spatializer_listener_get_position(pListener), ma_spatializer_get_position(pSpatializer)), ma_spatializer_get_velocity(pSpatializer), listenerVel, speedOfSound, dopplerFactor);
return ma_gainer_set_master_volume(&pSpatializer->gainer, volume);
}
MA_API ma_result ma_spatializer_get_master_volume(const ma_spatializer* pSpatializer, float* pVolume)
{
if (pSpatializer == NULL) {
return MA_INVALID_ARGS;
}
return ma_gainer_get_master_volume(&pSpatializer->gainer, pVolume);
}
c89atomic_exchange_f32(&pSpatializer->coneInnerAngleInRadians, innerAngleInRadians);
c89atomic_exchange_f32(&pSpatializer->coneOuterAngleInRadians, outerAngleInRadians);
c89atomic_exchange_f32(&pSpatializer->coneOuterGain, outerGain);
ma_atomic_exchange_f32(&pSpatializer->coneInnerAngleInRadians, innerAngleInRadians);
ma_atomic_exchange_f32(&pSpatializer->coneOuterAngleInRadians, outerAngleInRadians);
ma_atomic_exchange_f32(&pSpatializer->coneOuterGain, outerGain);
m[0][0] = axisX.x; m[1][0] = axisX.y; m[2][0] = axisX.z; m[3][0] = -ma_vec3f_dot(axisX, pListener->position);
m[0][1] = axisY.x; m[1][1] = axisY.y; m[2][1] = axisY.z; m[3][1] = -ma_vec3f_dot(axisY, pListener->position);
m[0][2] = -axisZ.x; m[1][2] = -axisZ.y; m[2][2] = -axisZ.z; m[3][2] = -ma_vec3f_dot(ma_vec3f_neg(axisZ), pListener->position);
m[0][0] = axisX.x; m[1][0] = axisX.y; m[2][0] = axisX.z; m[3][0] = -ma_vec3f_dot(axisX, listenerPosition);
m[0][1] = axisY.x; m[1][1] = axisY.y; m[2][1] = axisY.z; m[3][1] = -ma_vec3f_dot(axisY, listenerPosition);
m[0][2] = -axisZ.x; m[1][2] = -axisZ.y; m[2][2] = -axisZ.z; m[3][2] = -ma_vec3f_dot(ma_vec3f_neg(axisZ), listenerPosition);
/* Filter. */
ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pResampler->x1.s16, pResampler->x1.s16);
/* Filter. Do not apply filtering if sample rates are the same or else you'll get dangerous glitching. */
if (pResampler->config.sampleRateIn != pResampler->config.sampleRateOut) {
ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pResampler->x1.s16, pResampler->x1.s16);
}
/* Filter. */
ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pFramesOutS16, pFramesOutS16);
/* Filter. Do not apply filtering if sample rates are the same or else you'll get dangerous glitching. */
if (pResampler->config.sampleRateIn != pResampler->config.sampleRateOut) {
ma_lpf_process_pcm_frame_s16(&pResampler->lpf, pFramesOutS16, pFramesOutS16);
}
/* Filter. */
ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pResampler->x1.f32, pResampler->x1.f32);
/* Filter. Do not apply filtering if sample rates are the same or else you'll get dangerous glitching. */
if (pResampler->config.sampleRateIn != pResampler->config.sampleRateOut) {
ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pResampler->x1.f32, pResampler->x1.f32);
}
/* Filter. */
ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pFramesOutF32, pFramesOutF32);
/* Filter. Do not apply filtering if sample rates are the same or else you'll get dangerous glitching. */
if (pResampler->config.sampleRateIn != pResampler->config.sampleRateOut) {
ma_lpf_process_pcm_frame_f32(&pResampler->lpf, pFramesOutF32, pFramesOutF32);
}
static ma_uint32 ma_channel_map_get_spatial_channel_count(const ma_channel* pChannelMap, ma_uint32 channels)
{
ma_uint32 spatialChannelCount = 0;
ma_uint32 iChannel;
MA_ASSERT(pChannelMap != NULL);
MA_ASSERT(channels > 0);
for (iChannel = 0; iChannel < channels; ++iChannel) {
if (ma_is_spatial_channel_position(ma_channel_map_get_channel(pChannelMap, channels, iChannel))) {
spatialChannelCount++;
}
}
return spatialChannelCount;
}
static ma_result ma_channel_map_apply_mono_in_f32(float* pFramesOut, const ma_channel* pChannelMapOut, ma_uint32 channelsOut, const float* pFramesIn, ma_uint64 frameCount, ma_mono_expansion_mode monoExpansionMode)
static ma_result ma_channel_map_apply_mono_in_f32(float* MA_RESTRICT pFramesOut, const ma_channel* pChannelMapOut, ma_uint32 channelsOut, const float* MA_RESTRICT pFramesIn, ma_uint64 frameCount, ma_mono_expansion_mode monoExpansionMode)
ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
if (channelOut != MA_CHANNEL_NONE) {
pFramesOut[iChannelOut] = pFramesIn[0];
channelPositions[iChannelOut] = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
if (channelPositions[iChannelOut] == MA_CHANNEL_NONE) {
hasEmptyChannel = MA_TRUE;
if (hasEmptyChannel == MA_FALSE) {
/*
Faster path when there's no MA_CHANNEL_NONE channel positions. This should hopefully
help the compiler with auto-vectorization.m
*/
if (channelsOut == 2) {
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
/* We want to do two frames in each iteration. */
ma_uint64 unrolledFrameCount = frameCount >> 1;
pFramesOut += channelsOut;
pFramesIn += 1;
for (iFrame = 0; iFrame < unrolledFrameCount; iFrame += 1) {
__m128 in0 = _mm_set1_ps(pFramesIn[iFrame*2 + 0]);
__m128 in1 = _mm_set1_ps(pFramesIn[iFrame*2 + 1]);
_mm_storeu_ps(&pFramesOut[iFrame*4 + 0], _mm_shuffle_ps(in1, in0, _MM_SHUFFLE(0, 0, 0, 0)));
}
/* Tail. */
iFrame = unrolledFrameCount << 1;
goto generic_on_fastpath;
} else
#endif
{
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < 2; iChannelOut += 1) {
pFramesOut[iFrame*2 + iChannelOut] = pFramesIn[iFrame];
}
}
}
} else if (channelsOut == 6) {
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
/* We want to do two frames in each iteration so we can have a multiple of 4 samples. */
ma_uint64 unrolledFrameCount = frameCount >> 1;
for (iFrame = 0; iFrame < unrolledFrameCount; iFrame += 1) {
__m128 in0 = _mm_set1_ps(pFramesIn[iFrame*2 + 0]);
__m128 in1 = _mm_set1_ps(pFramesIn[iFrame*2 + 1]);
_mm_storeu_ps(&pFramesOut[iFrame*12 + 0], in0);
_mm_storeu_ps(&pFramesOut[iFrame*12 + 4], _mm_shuffle_ps(in1, in0, _MM_SHUFFLE(0, 0, 0, 0)));
_mm_storeu_ps(&pFramesOut[iFrame*12 + 8], in1);
}
/* Tail. */
iFrame = unrolledFrameCount << 1;
goto generic_on_fastpath;
} else
#endif
{
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < 6; iChannelOut += 1) {
pFramesOut[iFrame*6 + iChannelOut] = pFramesIn[iFrame];
}
}
}
} else if (channelsOut == 8) {
#if defined(MA_SUPPORT_SSE2)
if (ma_has_sse2()) {
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
__m128 in = _mm_set1_ps(pFramesIn[iFrame]);
_mm_storeu_ps(&pFramesOut[iFrame*8 + 0], in);
_mm_storeu_ps(&pFramesOut[iFrame*8 + 4], in);
}
} else
#endif
{
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < 8; iChannelOut += 1) {
pFramesOut[iFrame*8 + iChannelOut] = pFramesIn[iFrame];
}
}
}
} else {
iFrame = 0;
#if defined(MA_SUPPORT_SSE2) /* For silencing a warning with non-x86 builds. */
generic_on_fastpath:
#endif
{
for (; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
pFramesOut[iFrame*channelsOut + iChannelOut] = pFramesIn[iFrame];
}
}
}
}
} else {
/* Slow path. Need to handle MA_CHANNEL_NONE. */
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
if (channelPositions[iChannelOut] != MA_CHANNEL_NONE) {
pFramesOut[iFrame*channelsOut + iChannelOut] = pFramesIn[iFrame];
}
}
}
}
} else {
/* Slow path. Too many channels to store on the stack. */
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
ma_channel channelOut = ma_channel_map_get_channel(pChannelMapOut, channelsOut, iChannelOut);
if (channelOut != MA_CHANNEL_NONE) {
pFramesOut[iFrame*channelsOut + iChannelOut] = pFramesIn[iFrame];
}
}
}
iFrame = 0;
/* Experiment: Try an optimized unroll for some specific cases to see how it improves performance. RESULT: Good gains. */
if (channelsOut == 8) {
/* Experiment 2: Expand the inner loop to see what kind of different it makes. RESULT: Small, but worthwhile gain. */
if (channelsIn == 2) {
for (; iFrame < frameCount; iFrame += 1) {
float accumulation[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
accumulation[0] += pFramesIn[iFrame*2 + 0] * weights[0][0];
accumulation[1] += pFramesIn[iFrame*2 + 0] * weights[1][0];
accumulation[2] += pFramesIn[iFrame*2 + 0] * weights[2][0];
accumulation[3] += pFramesIn[iFrame*2 + 0] * weights[3][0];
accumulation[4] += pFramesIn[iFrame*2 + 0] * weights[4][0];
accumulation[5] += pFramesIn[iFrame*2 + 0] * weights[5][0];
accumulation[6] += pFramesIn[iFrame*2 + 0] * weights[6][0];
accumulation[7] += pFramesIn[iFrame*2 + 0] * weights[7][0];
accumulation[0] += pFramesIn[iFrame*2 + 1] * weights[0][1];
accumulation[1] += pFramesIn[iFrame*2 + 1] * weights[1][1];
accumulation[2] += pFramesIn[iFrame*2 + 1] * weights[2][1];
accumulation[3] += pFramesIn[iFrame*2 + 1] * weights[3][1];
accumulation[4] += pFramesIn[iFrame*2 + 1] * weights[4][1];
accumulation[5] += pFramesIn[iFrame*2 + 1] * weights[5][1];
accumulation[6] += pFramesIn[iFrame*2 + 1] * weights[6][1];
accumulation[7] += pFramesIn[iFrame*2 + 1] * weights[7][1];
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
pFramesOut[iFrame*8 + 0] = accumulation[0];
pFramesOut[iFrame*8 + 1] = accumulation[1];
pFramesOut[iFrame*8 + 2] = accumulation[2];
pFramesOut[iFrame*8 + 3] = accumulation[3];
pFramesOut[iFrame*8 + 4] = accumulation[4];
pFramesOut[iFrame*8 + 5] = accumulation[5];
pFramesOut[iFrame*8 + 6] = accumulation[6];
pFramesOut[iFrame*8 + 7] = accumulation[7];
}
} else {
/* When outputting to 8 channels, we can do everything in groups of two 4x SIMD operations. */
for (; iFrame < frameCount; iFrame += 1) {
float accumulation[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
accumulation[0] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[0][iChannelIn];
accumulation[1] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[1][iChannelIn];
accumulation[2] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[2][iChannelIn];
accumulation[3] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[3][iChannelIn];
accumulation[4] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[4][iChannelIn];
accumulation[5] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[5][iChannelIn];
accumulation[6] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[6][iChannelIn];
accumulation[7] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[7][iChannelIn];
}
pFramesOut[iFrame*8 + 0] = accumulation[0];
pFramesOut[iFrame*8 + 1] = accumulation[1];
pFramesOut[iFrame*8 + 2] = accumulation[2];
pFramesOut[iFrame*8 + 3] = accumulation[3];
pFramesOut[iFrame*8 + 4] = accumulation[4];
pFramesOut[iFrame*8 + 5] = accumulation[5];
pFramesOut[iFrame*8 + 6] = accumulation[6];
pFramesOut[iFrame*8 + 7] = accumulation[7];
}
}
} else if (channelsOut == 6) {
/*
When outputting to 6 channels we unfortunately don't have a nice multiple of 4 to do 4x SIMD operations. Instead we'll
expand our weights and do two frames at a time.
*/
for (; iFrame < frameCount; iFrame += 1) {
float accumulation[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
accumulation[0] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[0][iChannelIn];
accumulation[1] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[1][iChannelIn];
accumulation[2] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[2][iChannelIn];
accumulation[3] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[3][iChannelIn];
accumulation[4] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[4][iChannelIn];
accumulation[5] += pFramesIn[iFrame*channelsIn + iChannelIn] * weights[5][iChannelIn];
}
pFramesOut[iFrame*6 + 0] = accumulation[0];
pFramesOut[iFrame*6 + 1] = accumulation[1];
pFramesOut[iFrame*6 + 2] = accumulation[2];
pFramesOut[iFrame*6 + 3] = accumulation[3];
pFramesOut[iFrame*6 + 4] = accumulation[4];
pFramesOut[iFrame*6 + 5] = accumulation[5];
}
}
/* Leftover frames. */
for (; iFrame < frameCount; iFrame += 1) {
accumulation += pFramesIn[iChannelIn] * ma_calculate_channel_position_rectangular_weight(channelOut, channelIn);
accumulation += pFramesIn[iFrame*channelsIn + iChannelIn] * ma_calculate_channel_position_rectangular_weight(channelOut, channelIn);
/* In all cases we need to make sure all channels that are present in both channel maps have a 1:1 mapping. */
for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
ma_channel channelPosIn = ma_channel_map_get_channel(pConverter->pChannelMapIn, pConverter->channelsIn, iChannelIn);
for (iChannelOut = 0; iChannelOut < pConverter->channelsOut; ++iChannelOut) {
ma_channel channelPosOut = ma_channel_map_get_channel(pConverter->pChannelMapOut, pConverter->channelsOut, iChannelOut);
if (channelPosIn == channelPosOut) {
float weight = 1;
if (pConverter->format == ma_format_f32) {
pConverter->weights.f32[iChannelIn][iChannelOut] = weight;
} else {
pConverter->weights.s16[iChannelIn][iChannelOut] = ma_channel_converter_float_to_fixed(weight);
}
}
}
}
/* In simple mode, excess channels need to be silenced or dropped. */
ma_uint32 iChannel;
for (iChannel = 0; iChannel < ma_min(pConverter->channelsIn, pConverter->channelsOut); iChannel += 1) {
if (pConverter->format == ma_format_f32) {
if (pConverter->weights.f32[iChannel][iChannel] == 0) {
pConverter->weights.f32[iChannel][iChannel] = 1;
}
} else {
if (pConverter->weights.s16[iChannel][iChannel] == 0) {
pConverter->weights.s16[iChannel][iChannel] = ma_channel_converter_float_to_fixed(1);
}
}
}
/*
In simple mode, only set weights for channels that have exactly matching types, leave the rest at
zero. The 1:1 mappings have already been covered before this switch statement.
*/
}
}
}
}
}
}
}
/* If LFE is in the output channel map but was not present in the input channel map, configure its weight now */
if (pConfig->calculateLFEFromSpatialChannels) {
if (!ma_channel_map_contains_channel_position(pConverter->channelsIn, pConverter->pChannelMapIn, MA_CHANNEL_LFE)) {
ma_uint32 spatialChannelCount = ma_channel_map_get_spatial_channel_count(pConverter->pChannelMapIn, pConverter->channelsIn);
ma_uint32 iChannelOutLFE;
if (spatialChannelCount > 0 && ma_channel_map_find_channel_position(pConverter->channelsOut, pConverter->pChannelMapOut, MA_CHANNEL_LFE, &iChannelOutLFE)) {
const float weightForLFE = 1.0f / spatialChannelCount;
for (iChannelIn = 0; iChannelIn < pConverter->channelsIn; ++iChannelIn) {
const ma_channel channelPosIn = ma_channel_map_get_channel(pConverter->pChannelMapIn, pConverter->channelsIn, iChannelIn);
if (ma_is_spatial_channel_position(channelPosIn)) {
if (pConverter->format == ma_format_f32) {
if (pConverter->weights.f32[iChannelIn][iChannelOutLFE] == 0) {
pConverter->weights.f32[iChannelIn][iChannelOutLFE] = weightForLFE;
for (iChannel = 0; iChannel < channels; iChannel += 1) {
const char* pChannelStr = ma_channel_position_to_string(ma_channel_map_get_channel(pChannelMap, channels, iChannel));
size_t channelStrLen = strlen(pChannelStr);
/* Append the string if necessary. */
if (pBufferOut != NULL && bufferCap > len + channelStrLen) {
MA_COPY_MEMORY(pBufferOut + len, pChannelStr, channelStrLen);
}
len += channelStrLen;
/* Append a space if it's not the last item. */
if (iChannel+1 < channels) {
if (pBufferOut != NULL && bufferCap > len + 1) {
pBufferOut[len] = ' ';
}
len += 1;
}
}
/* Null terminate. Don't increment the length here. */
if (pBufferOut != NULL && bufferCap > len + 1) {
pBufferOut[len] = '\0';
}
return len;
}
MA_API const char* ma_channel_position_to_string(ma_channel channel)
{
switch (channel)
{
case MA_CHANNEL_NONE : return "CHANNEL_NONE";
case MA_CHANNEL_MONO : return "CHANNEL_MONO";
case MA_CHANNEL_FRONT_LEFT : return "CHANNEL_FRONT_LEFT";
case MA_CHANNEL_FRONT_RIGHT : return "CHANNEL_FRONT_RIGHT";
case MA_CHANNEL_FRONT_CENTER : return "CHANNEL_FRONT_CENTER";
case MA_CHANNEL_LFE : return "CHANNEL_LFE";
case MA_CHANNEL_BACK_LEFT : return "CHANNEL_BACK_LEFT";
case MA_CHANNEL_BACK_RIGHT : return "CHANNEL_BACK_RIGHT";
case MA_CHANNEL_FRONT_LEFT_CENTER : return "CHANNEL_FRONT_LEFT_CENTER ";
case MA_CHANNEL_FRONT_RIGHT_CENTER: return "CHANNEL_FRONT_RIGHT_CENTER";
case MA_CHANNEL_BACK_CENTER : return "CHANNEL_BACK_CENTER";
case MA_CHANNEL_SIDE_LEFT : return "CHANNEL_SIDE_LEFT";
case MA_CHANNEL_SIDE_RIGHT : return "CHANNEL_SIDE_RIGHT";
case MA_CHANNEL_TOP_CENTER : return "CHANNEL_TOP_CENTER";
case MA_CHANNEL_TOP_FRONT_LEFT : return "CHANNEL_TOP_FRONT_LEFT";
case MA_CHANNEL_TOP_FRONT_CENTER : return "CHANNEL_TOP_FRONT_CENTER";
case MA_CHANNEL_TOP_FRONT_RIGHT : return "CHANNEL_TOP_FRONT_RIGHT";
case MA_CHANNEL_TOP_BACK_LEFT : return "CHANNEL_TOP_BACK_LEFT";
case MA_CHANNEL_TOP_BACK_CENTER : return "CHANNEL_TOP_BACK_CENTER";
case MA_CHANNEL_TOP_BACK_RIGHT : return "CHANNEL_TOP_BACK_RIGHT";
case MA_CHANNEL_AUX_0 : return "CHANNEL_AUX_0";
case MA_CHANNEL_AUX_1 : return "CHANNEL_AUX_1";
case MA_CHANNEL_AUX_2 : return "CHANNEL_AUX_2";
case MA_CHANNEL_AUX_3 : return "CHANNEL_AUX_3";
case MA_CHANNEL_AUX_4 : return "CHANNEL_AUX_4";
case MA_CHANNEL_AUX_5 : return "CHANNEL_AUX_5";
case MA_CHANNEL_AUX_6 : return "CHANNEL_AUX_6";
case MA_CHANNEL_AUX_7 : return "CHANNEL_AUX_7";
case MA_CHANNEL_AUX_8 : return "CHANNEL_AUX_8";
case MA_CHANNEL_AUX_9 : return "CHANNEL_AUX_9";
case MA_CHANNEL_AUX_10 : return "CHANNEL_AUX_10";
case MA_CHANNEL_AUX_11 : return "CHANNEL_AUX_11";
case MA_CHANNEL_AUX_12 : return "CHANNEL_AUX_12";
case MA_CHANNEL_AUX_13 : return "CHANNEL_AUX_13";
case MA_CHANNEL_AUX_14 : return "CHANNEL_AUX_14";
case MA_CHANNEL_AUX_15 : return "CHANNEL_AUX_15";
case MA_CHANNEL_AUX_16 : return "CHANNEL_AUX_16";
case MA_CHANNEL_AUX_17 : return "CHANNEL_AUX_17";
case MA_CHANNEL_AUX_18 : return "CHANNEL_AUX_18";
case MA_CHANNEL_AUX_19 : return "CHANNEL_AUX_19";
case MA_CHANNEL_AUX_20 : return "CHANNEL_AUX_20";
case MA_CHANNEL_AUX_21 : return "CHANNEL_AUX_21";
case MA_CHANNEL_AUX_22 : return "CHANNEL_AUX_22";
case MA_CHANNEL_AUX_23 : return "CHANNEL_AUX_23";
case MA_CHANNEL_AUX_24 : return "CHANNEL_AUX_24";
case MA_CHANNEL_AUX_25 : return "CHANNEL_AUX_25";
case MA_CHANNEL_AUX_26 : return "CHANNEL_AUX_26";
case MA_CHANNEL_AUX_27 : return "CHANNEL_AUX_27";
case MA_CHANNEL_AUX_28 : return "CHANNEL_AUX_28";
case MA_CHANNEL_AUX_29 : return "CHANNEL_AUX_29";
case MA_CHANNEL_AUX_30 : return "CHANNEL_AUX_30";
case MA_CHANNEL_AUX_31 : return "CHANNEL_AUX_31";
default: break;
}
return "UNKNOWN";
}
c89atomic_exchange_32(&pRB->encodedReadOffset, ma_rb__construct_offset(newReadOffsetLoopFlag, newReadOffsetInBytes));
ma_atomic_exchange_32(&pRB->encodedReadOffset, ma_rb__construct_offset(newReadOffsetLoopFlag, newReadOffsetInBytes));
c89atomic_exchange_32(&pRB->encodedWriteOffset, ma_rb__construct_offset(newWriteOffsetLoopFlag, newWriteOffsetInBytes));
ma_atomic_exchange_32(&pRB->encodedWriteOffset, ma_rb__construct_offset(newWriteOffsetLoopFlag, newWriteOffsetInBytes));
c89atomic_exchange_32(&pRB->encodedReadOffset, ma_rb__construct_offset(newReadOffsetInBytes, newReadOffsetLoopFlag));
ma_atomic_exchange_32(&pRB->encodedReadOffset, ma_rb__construct_offset(newReadOffsetInBytes, newReadOffsetLoopFlag));
c89atomic_exchange_32(&pRB->encodedWriteOffset, ma_rb__construct_offset(newWriteOffsetInBytes, newWriteOffsetLoopFlag));
ma_atomic_exchange_32(&pRB->encodedWriteOffset, ma_rb__construct_offset(newWriteOffsetInBytes, newWriteOffsetLoopFlag));
static ma_result ma_pcm_rb_data_source__on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
/* Since there's no notion of an end, we don't ever want to return MA_AT_END here. But it is possible to return 0. */
ma_pcm_rb* pRB = (ma_pcm_rb*)pDataSource;
ma_result result;
ma_uint64 totalFramesRead;
MA_ASSERT(pRB != NULL);
/* We need to run this in a loop since the ring buffer itself may loop. */
totalFramesRead = 0;
while (totalFramesRead < frameCount) {
void* pMappedBuffer;
ma_uint32 mappedFrameCount;
ma_uint64 framesToRead = frameCount - totalFramesRead;
if (framesToRead > 0xFFFFFFFF) {
framesToRead = 0xFFFFFFFF;
}
mappedFrameCount = (ma_uint32)framesToRead;
result = ma_pcm_rb_acquire_read(pRB, &mappedFrameCount, &pMappedBuffer);
if (result != MA_SUCCESS) {
break;
}
if (mappedFrameCount == 0) {
break; /* <-- End of ring buffer. */
}
ma_copy_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, pRB->format, pRB->channels), pMappedBuffer, mappedFrameCount, pRB->format, pRB->channels);
result = ma_pcm_rb_commit_read(pRB, mappedFrameCount);
if (result != MA_SUCCESS) {
break;
}
totalFramesRead += mappedFrameCount;
}
*pFramesRead = totalFramesRead;
return MA_SUCCESS;
}
static ma_result ma_pcm_rb_data_source__on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_pcm_rb* pRB = (ma_pcm_rb*)pDataSource;
MA_ASSERT(pRB != NULL);
if (pFormat != NULL) {
*pFormat = pRB->format;
}
if (pChannels != NULL) {
*pChannels = pRB->channels;
}
if (pSampleRate != NULL) {
*pSampleRate = pRB->sampleRate;
}
/* Just assume the default channel map. */
if (pChannelMap != NULL) {
ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pRB->channels);
}
return MA_SUCCESS;
}
static ma_data_source_vtable ma_gRBDataSourceVTable =
{
ma_pcm_rb_data_source__on_read,
NULL, /* onSeek */
ma_pcm_rb_data_source__on_get_data_format,
NULL, /* onGetCursor */
NULL, /* onGetLength */
NULL, /* onSetLooping */
0
};
pRB->format = format;
pRB->channels = channels;
pRB->format = format;
pRB->channels = channels;
pRB->sampleRate = 0; /* The sample rate is not passed in as a parameter. */
/* The PCM ring buffer is a data source. We need to get that set up as well. */
{
ma_data_source_config dataSourceConfig = ma_data_source_config_init();
dataSourceConfig.vtable = &ma_gRBDataSourceVTable;
result = ma_data_source_init(&dataSourceConfig, &pRB->ds);
if (result != MA_SUCCESS) {
ma_rb_uninit(&pRB->rb);
return result;
}
}
pDataSourceBase->rangeBegInFrames = 0;
pDataSourceBase->rangeEndInFrames = ~((ma_uint64)0);
pDataSourceBase->loopBegInFrames = 0;
pDataSourceBase->loopEndInFrames = ~((ma_uint64)0);
pDataSourceBase->rangeBegInFrames = MA_DATA_SOURCE_DEFAULT_RANGE_BEG;
pDataSourceBase->rangeEndInFrames = MA_DATA_SOURCE_DEFAULT_RANGE_END;
pDataSourceBase->loopBegInFrames = MA_DATA_SOURCE_DEFAULT_LOOP_POINT_BEG;
pDataSourceBase->loopEndInFrames = MA_DATA_SOURCE_DEFAULT_LOOP_POINT_END;
*pCursor = cursorInPCMFrames / (float)sampleRate;
/* VC6 does not support division of unsigned 64-bit integers with floating point numbers. Need to use a signed number. This shouldn't effect anything in practice. */
*pCursor = (ma_int64)cursorInPCMFrames / (float)sampleRate;
*pLength = lengthInPCMFrames / (float)sampleRate;
/* VC6 does not support division of unsigned 64-bit integers with floating point numbers. Need to use a signed number. This shouldn't effect anything in practice. */
*pLength = (ma_int64)lengthInPCMFrames / (float)sampleRate;
The loop points need to be updated. We'll be storing the loop points relative to the range. We'll update
these so that they maintain their absolute positioning. The loop points will then be clamped to the range.
We may need to adjust the position of the cursor to ensure it's clamped to the range. Grab it now
so we can calculate it's absolute position before we change the range.
loopBegAbsolute = pDataSourceBase->loopBegInFrames + pDataSourceBase->rangeBegInFrames;
loopEndAbsolute = pDataSourceBase->loopEndInFrames + ((pDataSourceBase->loopEndInFrames != ~((ma_uint64)0)) ? pDataSourceBase->rangeBegInFrames : 0);
result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &relativeCursor);
if (result == MA_SUCCESS) {
doSeekAdjustment = MA_TRUE;
absoluteCursor = relativeCursor + pDataSourceBase->rangeBegInFrames;
} else {
/*
We couldn't get the position of the cursor. It probably means the data source has no notion
of a cursor. We'll just leave it at position 0. Don't treat this as an error.
*/
doSeekAdjustment = MA_FALSE;
relativeCursor = 0;
absoluteCursor = 0;
}
/* Make the loop points relative again, and make sure they're clamped to within the range. */
if (loopBegAbsolute > pDataSourceBase->rangeBegInFrames) {
pDataSourceBase->loopBegInFrames = loopBegAbsolute - pDataSourceBase->rangeBegInFrames;
} else {
pDataSourceBase->loopBegInFrames = 0;
}
/*
The commented out logic below was intended to maintain loop points in response to a change in the
range. However, this is not useful because it results in the sound breaking when you move the range
outside of the old loop points. I'm simplifying this by simply resetting the loop points. The
caller is expected to update their loop points if they change the range.
if (pDataSourceBase->loopBegInFrames > pDataSourceBase->rangeEndInFrames) {
pDataSourceBase->loopBegInFrames = pDataSourceBase->rangeEndInFrames;
}
In practice this should be mostly a non-issue because the majority of the time the range will be
set once right after initialization.
*/
pDataSourceBase->loopBegInFrames = 0;
pDataSourceBase->loopEndInFrames = ~((ma_uint64)0);
/* Only need to update the loop end point if it's not -1. */
if (loopEndAbsolute != ~((ma_uint64)0)) {
if (loopEndAbsolute > pDataSourceBase->rangeBegInFrames) {
pDataSourceBase->loopEndInFrames = loopEndAbsolute - pDataSourceBase->rangeBegInFrames;
} else {
pDataSourceBase->loopEndInFrames = 0;
}
if (pDataSourceBase->loopEndInFrames > pDataSourceBase->rangeEndInFrames && pDataSourceBase->loopEndInFrames) {
pDataSourceBase->loopEndInFrames = pDataSourceBase->rangeEndInFrames;
}
}
/* If the new range is past the current cursor position we need to seek to it. */
result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &cursor);
if (result == MA_SUCCESS) {
/* Seek to within range. Note that our seek positions here are relative to the new range. */
if (cursor < rangeBegInFrames) {
/*
Seek to within range. Note that our seek positions here are relative to the new range. We don't want
do do this if we failed to retrieve the cursor earlier on because it probably means the data source
has no notion of a cursor. In practice the seek would probably fail (which we silently ignore), but
I'm just not even going to attempt it.
*/
if (doSeekAdjustment) {
if (absoluteCursor < rangeBegInFrames) {
for (pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pData->head.pNext); pPage != NULL; pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pPage->pNext)) {
for (pPage = (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(&pData->head.pNext); pPage != NULL; pPage = (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(&pPage->pNext)) {
ma_paged_audio_buffer_page* pNext = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pPagedAudioBuffer->pCurrent->pNext);
ma_paged_audio_buffer_page* pNext = (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(&pPagedAudioBuffer->pCurrent->pNext);
for (pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&ma_paged_audio_buffer_data_get_head(pPagedAudioBuffer->pData)->pNext); pPage != NULL; pPage = (ma_paged_audio_buffer_page*)c89atomic_load_ptr(&pPage->pNext)) {
for (pPage = (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(&ma_paged_audio_buffer_data_get_head(pPagedAudioBuffer->pData)->pNext); pPage != NULL; pPage = (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(&pPage->pNext)) {
if (frameIndex < pageRangeEnd || (frameIndex == pageRangeEnd && pPage == (ma_paged_audio_buffer_page*)c89atomic_load_ptr(ma_paged_audio_buffer_data_get_tail(pPagedAudioBuffer->pData)))) { /* A small edge case - allow seeking to the very end of the buffer. */
if (frameIndex < pageRangeEnd || (frameIndex == pageRangeEnd && pPage == (ma_paged_audio_buffer_page*)ma_atomic_load_ptr(ma_paged_audio_buffer_data_get_tail(pPagedAudioBuffer->pData)))) { /* A small edge case - allow seeking to the very end of the buffer. */
static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePath, const wchar_t* pFilePathW, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_result result;
ma_vfs_file file;
ma_file_info info;
void* pData;
size_t bytesRead;
#if !defined(MA_USE_WIN32_FILEIO) && (defined(MA_WIN32) && defined(MA_WIN32_DESKTOP) && !defined(MA_NO_WIN32_FILEIO) && !defined(MA_POSIX))
#define MA_USE_WIN32_FILEIO
#endif
if (ppData != NULL) {
*ppData = NULL;
}
if (pSize != NULL) {
*pSize = 0;
}
#if defined(MA_USE_WIN32_FILEIO)
/*
We need to dynamically load SetFilePointer or SetFilePointerEx because older versions of Windows do
not have the Ex version. We therefore need to do some dynamic branching depending on what's available.
if (ppData == NULL) {
return MA_INVALID_ARGS;
}
We load these when we load our first file from the default VFS. It's left open for the life of the
program and is left to the OS to uninitialize when the program terminates.
*/
typedef DWORD (__stdcall * ma_SetFilePointer_proc)(HANDLE hFile, LONG lDistanceToMove, LONG* lpDistanceToMoveHigh, DWORD dwMoveMethod);
typedef BOOL (__stdcall * ma_SetFilePointerEx_proc)(HANDLE hFile, LARGE_INTEGER liDistanceToMove, LARGE_INTEGER* lpNewFilePointer, DWORD dwMoveMethod);
if (pFilePath != NULL) {
result = ma_vfs_open(pVFS, pFilePath, MA_OPEN_MODE_READ, &file);
} else {
result = ma_vfs_open_w(pVFS, pFilePathW, MA_OPEN_MODE_READ, &file);
}
if (result != MA_SUCCESS) {
return result;
}
static ma_handle hKernel32DLL = NULL;
static ma_SetFilePointer_proc ma_SetFilePointer = NULL;
static ma_SetFilePointerEx_proc ma_SetFilePointerEx = NULL;
result = ma_vfs_info(pVFS, file, &info);
if (result != MA_SUCCESS) {
ma_vfs_close(pVFS, file);
return result;
static void ma_win32_fileio_init(void)
{
if (hKernel32DLL == NULL) {
hKernel32DLL = ma_dlopen(NULL, "kernel32.dll");
if (hKernel32DLL != NULL) {
ma_SetFilePointer = (ma_SetFilePointer_proc) ma_dlsym(NULL, hKernel32DLL, "SetFilePointer");
ma_SetFilePointerEx = (ma_SetFilePointerEx_proc)ma_dlsym(NULL, hKernel32DLL, "SetFilePointerEx");
}
if (info.sizeInBytes > MA_SIZE_MAX) {
ma_vfs_close(pVFS, file);
return MA_TOO_BIG;
}
pData = ma_malloc((size_t)info.sizeInBytes, pAllocationCallbacks); /* Safe cast. */
if (pData == NULL) {
ma_vfs_close(pVFS, file);
return result;
}
result = ma_vfs_read(pVFS, file, pData, (size_t)info.sizeInBytes, &bytesRead); /* Safe cast. */
ma_vfs_close(pVFS, file);
if (result != MA_SUCCESS) {
ma_free(pData, pAllocationCallbacks);
return result;
}
if (pSize != NULL) {
*pSize = bytesRead;
}
MA_ASSERT(ppData != NULL);
*ppData = pData;
return MA_SUCCESS;
MA_API ma_result ma_vfs_open_and_read_file(ma_vfs* pVFS, const char* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
return ma_vfs_open_and_read_file_ex(pVFS, pFilePath, NULL, ppData, pSize, pAllocationCallbacks);
}
MA_API ma_result ma_vfs_open_and_read_file_w(ma_vfs* pVFS, const wchar_t* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
return ma_vfs_open_and_read_file_ex(pVFS, NULL, pFilePath, ppData, pSize, pAllocationCallbacks);
}
#if defined(MA_WIN32) && defined(MA_WIN32_DESKTOP) && !defined(MA_NO_WIN32_FILEIO)
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(__DMC__)
/* No SetFilePointerEx() so restrict to 31 bits. */
if (origin > 0x7FFFFFFF) {
return MA_OUT_OF_RANGE;
if (ma_SetFilePointerEx != NULL) {
result = ma_SetFilePointerEx((HANDLE)file, liDistanceToMove, NULL, dwMoveMethod);
} else if (ma_SetFilePointer != NULL) {
/* No SetFilePointerEx() so restrict to 31 bits. */
if (origin > 0x7FFFFFFF) {
return MA_OUT_OF_RANGE;
}
result = ma_SetFilePointer((HANDLE)file, (LONG)liDistanceToMove.QuadPart, NULL, dwMoveMethod);
} else {
return MA_NOT_IMPLEMENTED;
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(__DMC__)
result = SetFilePointer((HANDLE)file, (LONG)liZero.QuadPart, &tell, FILE_CURRENT);
liTell.QuadPart = tell;
#else
result = SetFilePointerEx((HANDLE)file, liZero, &liTell, FILE_CURRENT);
#endif
if (ma_SetFilePointerEx != NULL) {
result = ma_SetFilePointerEx((HANDLE)file, liZero, &liTell, FILE_CURRENT);
} else if (ma_SetFilePointer != NULL) {
LONG tell;
result = ma_SetFilePointer((HANDLE)file, (LONG)liZero.QuadPart, &tell, FILE_CURRENT);
liTell.QuadPart = tell;
} else {
return MA_NOT_IMPLEMENTED;
}
}
}
static ma_result ma_vfs_open_and_read_file_ex(ma_vfs* pVFS, const char* pFilePath, const wchar_t* pFilePathW, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_result result;
ma_vfs_file file;
ma_file_info info;
void* pData;
size_t bytesRead;
if (ppData != NULL) {
*ppData = NULL;
}
if (pSize != NULL) {
*pSize = 0;
if (ppData == NULL) {
return MA_INVALID_ARGS;
}
if (pFilePath != NULL) {
result = ma_vfs_or_default_open(pVFS, pFilePath, MA_OPEN_MODE_READ, &file);
} else {
result = ma_vfs_or_default_open_w(pVFS, pFilePathW, MA_OPEN_MODE_READ, &file);
}
if (result != MA_SUCCESS) {
return result;
}
result = ma_vfs_or_default_info(pVFS, file, &info);
if (result != MA_SUCCESS) {
ma_vfs_or_default_close(pVFS, file);
return result;
}
if (info.sizeInBytes > MA_SIZE_MAX) {
ma_vfs_or_default_close(pVFS, file);
return MA_TOO_BIG;
}
pData = ma_malloc((size_t)info.sizeInBytes, pAllocationCallbacks); /* Safe cast. */
if (pData == NULL) {
ma_vfs_or_default_close(pVFS, file);
return result;
}
result = ma_vfs_or_default_read(pVFS, file, pData, (size_t)info.sizeInBytes, &bytesRead); /* Safe cast. */
ma_vfs_or_default_close(pVFS, file);
if (result != MA_SUCCESS) {
ma_free(pData, pAllocationCallbacks);
return result;
}
if (pSize != NULL) {
*pSize = bytesRead;
}
MA_ASSERT(ppData != NULL);
*ppData = pData;
return MA_SUCCESS;
#define DRWAV_STRINGIFY(x) #x
#define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x)
#define DRWAV_VERSION_MAJOR 0
#define DRWAV_VERSION_MINOR 13
#define DRWAV_VERSION_REVISION 6
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
#define MA_DR_WAV_STRINGIFY(x) #x
#define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x)
#define MA_DR_WAV_VERSION_MAJOR 0
#define MA_DR_WAV_VERSION_MINOR 13
#define MA_DR_WAV_VERSION_REVISION 12
#define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION)
typedef signed char drwav_int8;
typedef unsigned char drwav_uint8;
typedef signed short drwav_int16;
typedef unsigned short drwav_uint16;
typedef signed int drwav_int32;
typedef unsigned int drwav_uint32;
#if defined(_MSC_VER) && !defined(__clang__)
typedef signed __int64 drwav_int64;
typedef unsigned __int64 drwav_uint64;
#else
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc++11-long-long"
#endif
#endif
typedef signed long long drwav_int64;
typedef unsigned long long drwav_uint64;
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#endif
#endif
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
typedef drwav_uint64 drwav_uintptr;
#else
typedef drwav_uint32 drwav_uintptr;
#endif
typedef drwav_uint8 drwav_bool8;
typedef drwav_uint32 drwav_bool32;
#define DRWAV_TRUE 1
#define DRWAV_FALSE 0
#if !defined(DRWAV_API)
#if defined(DRWAV_DLL)
#if defined(_WIN32)
#define DRWAV_DLL_IMPORT __declspec(dllimport)
#define DRWAV_DLL_EXPORT __declspec(dllexport)
#define DRWAV_DLL_PRIVATE static
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DRWAV_DLL_IMPORT __attribute__((visibility("default")))
#define DRWAV_DLL_EXPORT __attribute__((visibility("default")))
#define DRWAV_DLL_PRIVATE __attribute__((visibility("hidden")))
#else
#define DRWAV_DLL_IMPORT
#define DRWAV_DLL_EXPORT
#define DRWAV_DLL_PRIVATE static
#endif
#endif
#if defined(DR_WAV_IMPLEMENTATION) || defined(DRWAV_IMPLEMENTATION)
#define DRWAV_API DRWAV_DLL_EXPORT
#else
#define DRWAV_API DRWAV_DLL_IMPORT
#endif
#define DRWAV_PRIVATE DRWAV_DLL_PRIVATE
#else
#define DRWAV_API extern
#define DRWAV_PRIVATE static
#endif
#endif
typedef drwav_int32 drwav_result;
#define DRWAV_SUCCESS 0
#define DRWAV_ERROR -1
#define DRWAV_INVALID_ARGS -2
#define DRWAV_INVALID_OPERATION -3
#define DRWAV_OUT_OF_MEMORY -4
#define DRWAV_OUT_OF_RANGE -5
#define DRWAV_ACCESS_DENIED -6
#define DRWAV_DOES_NOT_EXIST -7
#define DRWAV_ALREADY_EXISTS -8
#define DRWAV_TOO_MANY_OPEN_FILES -9
#define DRWAV_INVALID_FILE -10
#define DRWAV_TOO_BIG -11
#define DRWAV_PATH_TOO_LONG -12
#define DRWAV_NAME_TOO_LONG -13
#define DRWAV_NOT_DIRECTORY -14
#define DRWAV_IS_DIRECTORY -15
#define DRWAV_DIRECTORY_NOT_EMPTY -16
#define DRWAV_END_OF_FILE -17
#define DRWAV_NO_SPACE -18
#define DRWAV_BUSY -19
#define DRWAV_IO_ERROR -20
#define DRWAV_INTERRUPT -21
#define DRWAV_UNAVAILABLE -22
#define DRWAV_ALREADY_IN_USE -23
#define DRWAV_BAD_ADDRESS -24
#define DRWAV_BAD_SEEK -25
#define DRWAV_BAD_PIPE -26
#define DRWAV_DEADLOCK -27
#define DRWAV_TOO_MANY_LINKS -28
#define DRWAV_NOT_IMPLEMENTED -29
#define DRWAV_NO_MESSAGE -30
#define DRWAV_BAD_MESSAGE -31
#define DRWAV_NO_DATA_AVAILABLE -32
#define DRWAV_INVALID_DATA -33
#define DRWAV_TIMEOUT -34
#define DRWAV_NO_NETWORK -35
#define DRWAV_NOT_UNIQUE -36
#define DRWAV_NOT_SOCKET -37
#define DRWAV_NO_ADDRESS -38
#define DRWAV_BAD_PROTOCOL -39
#define DRWAV_PROTOCOL_UNAVAILABLE -40
#define DRWAV_PROTOCOL_NOT_SUPPORTED -41
#define DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED -42
#define DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED -43
#define DRWAV_SOCKET_NOT_SUPPORTED -44
#define DRWAV_CONNECTION_RESET -45
#define DRWAV_ALREADY_CONNECTED -46
#define DRWAV_NOT_CONNECTED -47
#define DRWAV_CONNECTION_REFUSED -48
#define DRWAV_NO_HOST -49
#define DRWAV_IN_PROGRESS -50
#define DRWAV_CANCELLED -51
#define DRWAV_MEMORY_ALREADY_MAPPED -52
#define DRWAV_AT_END -53
#define DR_WAVE_FORMAT_PCM 0x1
#define DR_WAVE_FORMAT_ADPCM 0x2
#define DR_WAVE_FORMAT_IEEE_FLOAT 0x3
#define DR_WAVE_FORMAT_ALAW 0x6
#define DR_WAVE_FORMAT_MULAW 0x7
#define DR_WAVE_FORMAT_DVI_ADPCM 0x11
#define DR_WAVE_FORMAT_EXTENSIBLE 0xFFFE
#define DRWAV_SEQUENTIAL 0x00000001
DRWAV_API void drwav_version(drwav_uint32* pMajor, drwav_uint32* pMinor, drwav_uint32* pRevision);
DRWAV_API const char* drwav_version_string(void);
#define MA_DR_WAVE_FORMAT_PCM 0x1
#define MA_DR_WAVE_FORMAT_ADPCM 0x2
#define MA_DR_WAVE_FORMAT_IEEE_FLOAT 0x3
#define MA_DR_WAVE_FORMAT_ALAW 0x6
#define MA_DR_WAVE_FORMAT_MULAW 0x7
#define MA_DR_WAVE_FORMAT_DVI_ADPCM 0x11
#define MA_DR_WAVE_FORMAT_EXTENSIBLE 0xFFFE
#define MA_DR_WAV_SEQUENTIAL 0x00000001
#define MA_DR_WAV_WITH_METADATA 0x00000002
MA_API void ma_dr_wav_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision);
MA_API const char* ma_dr_wav_version_string(void);
drwav_uint16 formatTag;
drwav_uint16 channels;
drwav_uint32 sampleRate;
drwav_uint32 avgBytesPerSec;
drwav_uint16 blockAlign;
drwav_uint16 bitsPerSample;
drwav_uint16 extendedSize;
drwav_uint16 validBitsPerSample;
drwav_uint32 channelMask;
drwav_uint8 subFormat[16];
} drwav_fmt;
DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt* pFMT);
typedef size_t (* drwav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef size_t (* drwav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
typedef drwav_bool32 (* drwav_seek_proc)(void* pUserData, int offset, drwav_seek_origin origin);
typedef drwav_uint64 (* drwav_chunk_proc)(void* pChunkUserData, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_chunk_header* pChunkHeader, drwav_container container, const drwav_fmt* pFMT);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drwav_allocation_callbacks;
ma_uint16 formatTag;
ma_uint16 channels;
ma_uint32 sampleRate;
ma_uint32 avgBytesPerSec;
ma_uint16 blockAlign;
ma_uint16 bitsPerSample;
ma_uint16 extendedSize;
ma_uint16 validBitsPerSample;
ma_uint32 channelMask;
ma_uint8 subFormat[16];
} ma_dr_wav_fmt;
MA_API ma_uint16 ma_dr_wav_fmt_get_format(const ma_dr_wav_fmt* pFMT);
typedef size_t (* ma_dr_wav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef size_t (* ma_dr_wav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
typedef ma_bool32 (* ma_dr_wav_seek_proc)(void* pUserData, int offset, ma_dr_wav_seek_origin origin);
typedef ma_uint64 (* ma_dr_wav_chunk_proc)(void* pChunkUserData, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pReadSeekUserData, const ma_dr_wav_chunk_header* pChunkHeader, ma_dr_wav_container container, const ma_dr_wav_fmt* pFMT);
drwav_container container;
drwav_uint32 format;
drwav_uint32 channels;
drwav_uint32 sampleRate;
drwav_uint32 bitsPerSample;
} drwav_data_format;
ma_dr_wav_container container;
ma_uint32 format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint32 bitsPerSample;
} ma_dr_wav_data_format;
drwav_metadata_type_none = 0,
drwav_metadata_type_unknown = 1 << 0,
drwav_metadata_type_smpl = 1 << 1,
drwav_metadata_type_inst = 1 << 2,
drwav_metadata_type_cue = 1 << 3,
drwav_metadata_type_acid = 1 << 4,
drwav_metadata_type_bext = 1 << 5,
drwav_metadata_type_list_label = 1 << 6,
drwav_metadata_type_list_note = 1 << 7,
drwav_metadata_type_list_labelled_cue_region = 1 << 8,
drwav_metadata_type_list_info_software = 1 << 9,
drwav_metadata_type_list_info_copyright = 1 << 10,
drwav_metadata_type_list_info_title = 1 << 11,
drwav_metadata_type_list_info_artist = 1 << 12,
drwav_metadata_type_list_info_comment = 1 << 13,
drwav_metadata_type_list_info_date = 1 << 14,
drwav_metadata_type_list_info_genre = 1 << 15,
drwav_metadata_type_list_info_album = 1 << 16,
drwav_metadata_type_list_info_tracknumber = 1 << 17,
drwav_metadata_type_list_all_info_strings = drwav_metadata_type_list_info_software
| drwav_metadata_type_list_info_copyright
| drwav_metadata_type_list_info_title
| drwav_metadata_type_list_info_artist
| drwav_metadata_type_list_info_comment
| drwav_metadata_type_list_info_date
| drwav_metadata_type_list_info_genre
| drwav_metadata_type_list_info_album
| drwav_metadata_type_list_info_tracknumber,
drwav_metadata_type_list_all_adtl = drwav_metadata_type_list_label
| drwav_metadata_type_list_note
| drwav_metadata_type_list_labelled_cue_region,
drwav_metadata_type_all = -2,
drwav_metadata_type_all_including_unknown = -1
} drwav_metadata_type;
ma_dr_wav_metadata_type_none = 0,
ma_dr_wav_metadata_type_unknown = 1 << 0,
ma_dr_wav_metadata_type_smpl = 1 << 1,
ma_dr_wav_metadata_type_inst = 1 << 2,
ma_dr_wav_metadata_type_cue = 1 << 3,
ma_dr_wav_metadata_type_acid = 1 << 4,
ma_dr_wav_metadata_type_bext = 1 << 5,
ma_dr_wav_metadata_type_list_label = 1 << 6,
ma_dr_wav_metadata_type_list_note = 1 << 7,
ma_dr_wav_metadata_type_list_labelled_cue_region = 1 << 8,
ma_dr_wav_metadata_type_list_info_software = 1 << 9,
ma_dr_wav_metadata_type_list_info_copyright = 1 << 10,
ma_dr_wav_metadata_type_list_info_title = 1 << 11,
ma_dr_wav_metadata_type_list_info_artist = 1 << 12,
ma_dr_wav_metadata_type_list_info_comment = 1 << 13,
ma_dr_wav_metadata_type_list_info_date = 1 << 14,
ma_dr_wav_metadata_type_list_info_genre = 1 << 15,
ma_dr_wav_metadata_type_list_info_album = 1 << 16,
ma_dr_wav_metadata_type_list_info_tracknumber = 1 << 17,
ma_dr_wav_metadata_type_list_all_info_strings = ma_dr_wav_metadata_type_list_info_software
| ma_dr_wav_metadata_type_list_info_copyright
| ma_dr_wav_metadata_type_list_info_title
| ma_dr_wav_metadata_type_list_info_artist
| ma_dr_wav_metadata_type_list_info_comment
| ma_dr_wav_metadata_type_list_info_date
| ma_dr_wav_metadata_type_list_info_genre
| ma_dr_wav_metadata_type_list_info_album
| ma_dr_wav_metadata_type_list_info_tracknumber,
ma_dr_wav_metadata_type_list_all_adtl = ma_dr_wav_metadata_type_list_label
| ma_dr_wav_metadata_type_list_note
| ma_dr_wav_metadata_type_list_labelled_cue_region,
ma_dr_wav_metadata_type_all = -2,
ma_dr_wav_metadata_type_all_including_unknown = -1
} ma_dr_wav_metadata_type;
drwav_smpl_loop_type_forward = 0,
drwav_smpl_loop_type_pingpong = 1,
drwav_smpl_loop_type_backward = 2
} drwav_smpl_loop_type;
ma_dr_wav_smpl_loop_type_forward = 0,
ma_dr_wav_smpl_loop_type_pingpong = 1,
ma_dr_wav_smpl_loop_type_backward = 2
} ma_dr_wav_smpl_loop_type;
drwav_uint32 cuePointId;
drwav_uint32 type;
drwav_uint32 firstSampleByteOffset;
drwav_uint32 lastSampleByteOffset;
drwav_uint32 sampleFraction;
drwav_uint32 playCount;
} drwav_smpl_loop;
ma_uint32 cuePointId;
ma_uint32 type;
ma_uint32 firstSampleByteOffset;
ma_uint32 lastSampleByteOffset;
ma_uint32 sampleFraction;
ma_uint32 playCount;
} ma_dr_wav_smpl_loop;
drwav_uint32 manufacturerId;
drwav_uint32 productId;
drwav_uint32 samplePeriodNanoseconds;
drwav_uint32 midiUnityNote;
drwav_uint32 midiPitchFraction;
drwav_uint32 smpteFormat;
drwav_uint32 smpteOffset;
drwav_uint32 sampleLoopCount;
drwav_uint32 samplerSpecificDataSizeInBytes;
drwav_smpl_loop* pLoops;
drwav_uint8* pSamplerSpecificData;
} drwav_smpl;
ma_uint32 manufacturerId;
ma_uint32 productId;
ma_uint32 samplePeriodNanoseconds;
ma_uint32 midiUnityNote;
ma_uint32 midiPitchFraction;
ma_uint32 smpteFormat;
ma_uint32 smpteOffset;
ma_uint32 sampleLoopCount;
ma_uint32 samplerSpecificDataSizeInBytes;
ma_dr_wav_smpl_loop* pLoops;
ma_uint8* pSamplerSpecificData;
} ma_dr_wav_smpl;
drwav_int8 midiUnityNote;
drwav_int8 fineTuneCents;
drwav_int8 gainDecibels;
drwav_int8 lowNote;
drwav_int8 highNote;
drwav_int8 lowVelocity;
drwav_int8 highVelocity;
} drwav_inst;
ma_int8 midiUnityNote;
ma_int8 fineTuneCents;
ma_int8 gainDecibels;
ma_int8 lowNote;
ma_int8 highNote;
ma_int8 lowVelocity;
ma_int8 highVelocity;
} ma_dr_wav_inst;
drwav_uint32 id;
drwav_uint32 playOrderPosition;
drwav_uint8 dataChunkId[4];
drwav_uint32 chunkStart;
drwav_uint32 blockStart;
drwav_uint32 sampleByteOffset;
} drwav_cue_point;
ma_uint32 id;
ma_uint32 playOrderPosition;
ma_uint8 dataChunkId[4];
ma_uint32 chunkStart;
ma_uint32 blockStart;
ma_uint32 sampleByteOffset;
} ma_dr_wav_cue_point;
drwav_acid_flag_one_shot = 1,
drwav_acid_flag_root_note_set = 2,
drwav_acid_flag_stretch = 4,
drwav_acid_flag_disk_based = 8,
drwav_acid_flag_acidizer = 16
} drwav_acid_flag;
ma_dr_wav_acid_flag_one_shot = 1,
ma_dr_wav_acid_flag_root_note_set = 2,
ma_dr_wav_acid_flag_stretch = 4,
ma_dr_wav_acid_flag_disk_based = 8,
ma_dr_wav_acid_flag_acidizer = 16
} ma_dr_wav_acid_flag;
drwav_uint32 codingHistorySize;
drwav_uint8* pUMID;
drwav_uint16 loudnessValue;
drwav_uint16 loudnessRange;
drwav_uint16 maxTruePeakLevel;
drwav_uint16 maxMomentaryLoudness;
drwav_uint16 maxShortTermLoudness;
} drwav_bext;
ma_uint32 codingHistorySize;
ma_uint8* pUMID;
ma_uint16 loudnessValue;
ma_uint16 loudnessRange;
ma_uint16 maxTruePeakLevel;
ma_uint16 maxMomentaryLoudness;
ma_uint16 maxShortTermLoudness;
} ma_dr_wav_bext;
drwav_uint32 cuePointId;
drwav_uint32 sampleLength;
drwav_uint8 purposeId[4];
drwav_uint16 country;
drwav_uint16 language;
drwav_uint16 dialect;
drwav_uint16 codePage;
drwav_uint32 stringLength;
ma_uint32 cuePointId;
ma_uint32 sampleLength;
ma_uint8 purposeId[4];
ma_uint16 country;
ma_uint16 language;
ma_uint16 dialect;
ma_uint16 codePage;
ma_uint32 stringLength;
drwav_metadata_location_invalid,
drwav_metadata_location_top_level,
drwav_metadata_location_inside_info_list,
drwav_metadata_location_inside_adtl_list
} drwav_metadata_location;
ma_dr_wav_metadata_location_invalid,
ma_dr_wav_metadata_location_top_level,
ma_dr_wav_metadata_location_inside_info_list,
ma_dr_wav_metadata_location_inside_adtl_list
} ma_dr_wav_metadata_location;
drwav_uint8 id[4];
drwav_metadata_location chunkLocation;
drwav_uint32 dataSizeInBytes;
drwav_uint8* pData;
} drwav_unknown_metadata;
ma_uint8 id[4];
ma_dr_wav_metadata_location chunkLocation;
ma_uint32 dataSizeInBytes;
ma_uint8* pData;
} ma_dr_wav_unknown_metadata;
drwav_cue cue;
drwav_smpl smpl;
drwav_acid acid;
drwav_inst inst;
drwav_bext bext;
drwav_list_label_or_note labelOrNote;
drwav_list_labelled_cue_region labelledCueRegion;
drwav_list_info_text infoText;
drwav_unknown_metadata unknown;
ma_dr_wav_cue cue;
ma_dr_wav_smpl smpl;
ma_dr_wav_acid acid;
ma_dr_wav_inst inst;
ma_dr_wav_bext bext;
ma_dr_wav_list_label_or_note labelOrNote;
ma_dr_wav_list_labelled_cue_region labelledCueRegion;
ma_dr_wav_list_info_text infoText;
ma_dr_wav_unknown_metadata unknown;
drwav_allocation_callbacks allocationCallbacks;
drwav_container container;
drwav_fmt fmt;
drwav_uint32 sampleRate;
drwav_uint16 channels;
drwav_uint16 bitsPerSample;
drwav_uint16 translatedFormatTag;
drwav_uint64 totalPCMFrameCount;
drwav_uint64 dataChunkDataSize;
drwav_uint64 dataChunkDataPos;
drwav_uint64 bytesRemaining;
drwav_uint64 readCursorInPCMFrames;
drwav_uint64 dataChunkDataSizeTargetWrite;
drwav_bool32 isSequentialWrite;
drwav_metadata_type allowedMetadataTypes;
drwav_metadata* pMetadata;
drwav_uint32 metadataCount;
drwav__memory_stream memoryStream;
drwav__memory_stream_write memoryStreamWrite;
ma_allocation_callbacks allocationCallbacks;
ma_dr_wav_container container;
ma_dr_wav_fmt fmt;
ma_uint32 sampleRate;
ma_uint16 channels;
ma_uint16 bitsPerSample;
ma_uint16 translatedFormatTag;
ma_uint64 totalPCMFrameCount;
ma_uint64 dataChunkDataSize;
ma_uint64 dataChunkDataPos;
ma_uint64 bytesRemaining;
ma_uint64 readCursorInPCMFrames;
ma_uint64 dataChunkDataSizeTargetWrite;
ma_bool32 isSequentialWrite;
ma_dr_wav_metadata* pMetadata;
ma_uint32 metadataCount;
ma_dr_wav__memory_stream memoryStream;
ma_dr_wav__memory_stream_write memoryStreamWrite;
drwav_uint32 bytesRemainingInBlock;
drwav_uint16 predictor[2];
drwav_int32 delta[2];
drwav_int32 cachedFrames[4];
drwav_uint32 cachedFrameCount;
drwav_int32 prevFrames[2][2];
ma_uint32 bytesRemainingInBlock;
ma_uint16 predictor[2];
ma_int32 delta[2];
ma_int32 cachedFrames[4];
ma_uint32 cachedFrameCount;
ma_int32 prevFrames[2][2];
drwav_uint32 bytesRemainingInBlock;
drwav_int32 predictor[2];
drwav_int32 stepIndex[2];
drwav_int32 cachedFrames[16];
drwav_uint32 cachedFrameCount;
ma_uint32 bytesRemainingInBlock;
ma_int32 predictor[2];
ma_int32 stepIndex[2];
ma_int32 cachedFrames[16];
ma_uint32 cachedFrameCount;
} drwav;
DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata, drwav_uint32 metadataCount);
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalFrameCount, drwav_metadata* pMetadata, drwav_uint32 metadataCount);
DRWAV_API drwav_metadata* drwav_take_ownership_of_metadata(drwav* pWav);
DRWAV_API drwav_result drwav_uninit(drwav* pWav);
DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex);
DRWAV_API drwav_result drwav_get_cursor_in_pcm_frames(drwav* pWav, drwav_uint64* pCursor);
DRWAV_API drwav_result drwav_get_length_in_pcm_frames(drwav* pWav, drwav_uint64* pLength);
DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut);
DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut);
DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
struct
{
ma_bool8 isLE;
ma_bool8 isUnsigned;
} aiff;
} ma_dr_wav;
MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write_sequential(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write_sequential_pcm_frames(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write_with_metadata(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks, ma_dr_wav_metadata* pMetadata, ma_uint32 metadataCount);
MA_API ma_uint64 ma_dr_wav_target_write_size_bytes(const ma_dr_wav_data_format* pFormat, ma_uint64 totalFrameCount, ma_dr_wav_metadata* pMetadata, ma_uint32 metadataCount);
MA_API ma_dr_wav_metadata* ma_dr_wav_take_ownership_of_metadata(ma_dr_wav* pWav);
MA_API ma_result ma_dr_wav_uninit(ma_dr_wav* pWav);
MA_API size_t ma_dr_wav_read_raw(ma_dr_wav* pWav, size_t bytesToRead, void* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames(ma_dr_wav* pWav, ma_uint64 framesToRead, void* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_le(ma_dr_wav* pWav, ma_uint64 framesToRead, void* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_be(ma_dr_wav* pWav, ma_uint64 framesToRead, void* pBufferOut);
MA_API ma_bool32 ma_dr_wav_seek_to_pcm_frame(ma_dr_wav* pWav, ma_uint64 targetFrameIndex);
MA_API ma_result ma_dr_wav_get_cursor_in_pcm_frames(ma_dr_wav* pWav, ma_uint64* pCursor);
MA_API ma_result ma_dr_wav_get_length_in_pcm_frames(ma_dr_wav* pWav, ma_uint64* pLength);
MA_API size_t ma_dr_wav_write_raw(ma_dr_wav* pWav, size_t bytesToWrite, const void* pData);
MA_API ma_uint64 ma_dr_wav_write_pcm_frames(ma_dr_wav* pWav, ma_uint64 framesToWrite, const void* pData);
MA_API ma_uint64 ma_dr_wav_write_pcm_frames_le(ma_dr_wav* pWav, ma_uint64 framesToWrite, const void* pData);
MA_API ma_uint64 ma_dr_wav_write_pcm_frames_be(ma_dr_wav* pWav, ma_uint64 framesToWrite, const void* pData);
#ifndef MA_DR_WAV_NO_CONVERSION_API
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s16(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s16le(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s16be(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut);
MA_API void ma_dr_wav_u8_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s24_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s32_to_s16(ma_int16* pOut, const ma_int32* pIn, size_t sampleCount);
MA_API void ma_dr_wav_f32_to_s16(ma_int16* pOut, const float* pIn, size_t sampleCount);
MA_API void ma_dr_wav_f64_to_s16(ma_int16* pOut, const double* pIn, size_t sampleCount);
MA_API void ma_dr_wav_alaw_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_mulaw_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_f32(ma_dr_wav* pWav, ma_uint64 framesToRead, float* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_f32le(ma_dr_wav* pWav, ma_uint64 framesToRead, float* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_f32be(ma_dr_wav* pWav, ma_uint64 framesToRead, float* pBufferOut);
MA_API void ma_dr_wav_u8_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s16_to_f32(float* pOut, const ma_int16* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s24_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s32_to_f32(float* pOut, const ma_int32* pIn, size_t sampleCount);
MA_API void ma_dr_wav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
MA_API void ma_dr_wav_alaw_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_mulaw_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s32(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s32le(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut);
MA_API ma_uint64 ma_dr_wav_read_pcm_frames_s32be(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut);
MA_API void ma_dr_wav_u8_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s16_to_s32(ma_int32* pOut, const ma_int16* pIn, size_t sampleCount);
MA_API void ma_dr_wav_s24_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_f32_to_s32(ma_int32* pOut, const float* pIn, size_t sampleCount);
MA_API void ma_dr_wav_f64_to_s32(ma_int32* pOut, const double* pIn, size_t sampleCount);
MA_API void ma_dr_wav_alaw_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t sampleCount);
MA_API void ma_dr_wav_mulaw_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t sampleCount);
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_t* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_WAV_NO_STDIO
MA_API ma_bool32 ma_dr_wav_init_file(ma_dr_wav* pWav, const char* filename, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_ex(ma_dr_wav* pWav, const char* filename, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_ex_w(ma_dr_wav* pWav, const wchar_t* filename, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_with_metadata(ma_dr_wav* pWav, const char* filename, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_with_metadata_w(ma_dr_wav* pWav, const wchar_t* filename, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_pcm_frames(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_pcm_frames_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_WAV_NO_CONVERSION_API
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory(ma_dr_wav* pWav, const void* data, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_ex(ma_dr_wav* pWav, const void* data, size_t dataSize, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_with_metadata(ma_dr_wav* pWav, const void* data, size_t dataSize, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_write(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential_pcm_frames(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_WAV_NO_CONVERSION_API
MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_WAV_NO_STDIO
MA_API ma_int16* ma_dr_wav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_wav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_wav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_wav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_wav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_wav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_wav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_wav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_wav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
DRWAV_API drwav_uint16 drwav_bytes_to_u16(const drwav_uint8* data);
DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8* data);
DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8* data);
DRWAV_API drwav_int32 drwav_bytes_to_s32(const drwav_uint8* data);
DRWAV_API drwav_uint64 drwav_bytes_to_u64(const drwav_uint8* data);
DRWAV_API drwav_int64 drwav_bytes_to_s64(const drwav_uint8* data);
DRWAV_API float drwav_bytes_to_f32(const drwav_uint8* data);
DRWAV_API drwav_bool32 drwav_guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16]);
DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b);
MA_API void ma_dr_wav_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_uint16 ma_dr_wav_bytes_to_u16(const ma_uint8* data);
MA_API ma_int16 ma_dr_wav_bytes_to_s16(const ma_uint8* data);
MA_API ma_uint32 ma_dr_wav_bytes_to_u32(const ma_uint8* data);
MA_API ma_int32 ma_dr_wav_bytes_to_s32(const ma_uint8* data);
MA_API ma_uint64 ma_dr_wav_bytes_to_u64(const ma_uint8* data);
MA_API ma_int64 ma_dr_wav_bytes_to_s64(const ma_uint8* data);
MA_API float ma_dr_wav_bytes_to_f32(const ma_uint8* data);
MA_API ma_bool32 ma_dr_wav_guid_equal(const ma_uint8 a[16], const ma_uint8 b[16]);
MA_API ma_bool32 ma_dr_wav_fourcc_equal(const ma_uint8* a, const char* b);
#define DRFLAC_STRINGIFY(x) #x
#define DRFLAC_XSTRINGIFY(x) DRFLAC_STRINGIFY(x)
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12
#define DRFLAC_VERSION_REVISION 38
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
#define MA_DR_FLAC_STRINGIFY(x) #x
#define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x)
#define MA_DR_FLAC_VERSION_MAJOR 0
#define MA_DR_FLAC_VERSION_MINOR 12
#define MA_DR_FLAC_VERSION_REVISION 41
#define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION)
typedef signed char drflac_int8;
typedef unsigned char drflac_uint8;
typedef signed short drflac_int16;
typedef unsigned short drflac_uint16;
typedef signed int drflac_int32;
typedef unsigned int drflac_uint32;
#if defined(_MSC_VER) && !defined(__clang__)
typedef signed __int64 drflac_int64;
typedef unsigned __int64 drflac_uint64;
#else
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc++11-long-long"
#endif
#endif
typedef signed long long drflac_int64;
typedef unsigned long long drflac_uint64;
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#endif
#endif
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
typedef drflac_uint64 drflac_uintptr;
#else
typedef drflac_uint32 drflac_uintptr;
#endif
typedef drflac_uint8 drflac_bool8;
typedef drflac_uint32 drflac_bool32;
#define DRFLAC_TRUE 1
#define DRFLAC_FALSE 0
#if !defined(DRFLAC_API)
#if defined(DRFLAC_DLL)
#if defined(_WIN32)
#define DRFLAC_DLL_IMPORT __declspec(dllimport)
#define DRFLAC_DLL_EXPORT __declspec(dllexport)
#define DRFLAC_DLL_PRIVATE static
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DRFLAC_DLL_IMPORT __attribute__((visibility("default")))
#define DRFLAC_DLL_EXPORT __attribute__((visibility("default")))
#define DRFLAC_DLL_PRIVATE __attribute__((visibility("hidden")))
#else
#define DRFLAC_DLL_IMPORT
#define DRFLAC_DLL_EXPORT
#define DRFLAC_DLL_PRIVATE static
#endif
#endif
#if defined(DR_FLAC_IMPLEMENTATION) || defined(DRFLAC_IMPLEMENTATION)
#define DRFLAC_API DRFLAC_DLL_EXPORT
#else
#define DRFLAC_API DRFLAC_DLL_IMPORT
#endif
#define DRFLAC_PRIVATE DRFLAC_DLL_PRIVATE
#else
#define DRFLAC_API extern
#define DRFLAC_PRIVATE static
#endif
#endif
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision);
DRFLAC_API const char* drflac_version_string(void);
#ifndef DR_FLAC_BUFFER_SIZE
#define DR_FLAC_BUFFER_SIZE 4096
MA_API void ma_dr_flac_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision);
MA_API const char* ma_dr_flac_version_string(void);
#ifndef MA_DR_FLAC_BUFFER_SIZE
#define MA_DR_FLAC_BUFFER_SIZE 4096
#define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO 0
#define DRFLAC_METADATA_BLOCK_TYPE_PADDING 1
#define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION 2
#define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3
#define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4
#define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET 5
#define DRFLAC_METADATA_BLOCK_TYPE_PICTURE 6
#define DRFLAC_METADATA_BLOCK_TYPE_INVALID 127
#define DRFLAC_PICTURE_TYPE_OTHER 0
#define DRFLAC_PICTURE_TYPE_FILE_ICON 1
#define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON 2
#define DRFLAC_PICTURE_TYPE_COVER_FRONT 3
#define DRFLAC_PICTURE_TYPE_COVER_BACK 4
#define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE 5
#define DRFLAC_PICTURE_TYPE_MEDIA 6
#define DRFLAC_PICTURE_TYPE_LEAD_ARTIST 7
#define DRFLAC_PICTURE_TYPE_ARTIST 8
#define DRFLAC_PICTURE_TYPE_CONDUCTOR 9
#define DRFLAC_PICTURE_TYPE_BAND 10
#define DRFLAC_PICTURE_TYPE_COMPOSER 11
#define DRFLAC_PICTURE_TYPE_LYRICIST 12
#define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION 13
#define DRFLAC_PICTURE_TYPE_DURING_RECORDING 14
#define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE 15
#define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE 16
#define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17
#define DRFLAC_PICTURE_TYPE_ILLUSTRATION 18
#define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE 19
#define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_STREAMINFO 0
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_PADDING 1
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_APPLICATION 2
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_CUESHEET 5
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_PICTURE 6
#define MA_DR_FLAC_METADATA_BLOCK_TYPE_INVALID 127
#define MA_DR_FLAC_PICTURE_TYPE_OTHER 0
#define MA_DR_FLAC_PICTURE_TYPE_FILE_ICON 1
#define MA_DR_FLAC_PICTURE_TYPE_OTHER_FILE_ICON 2
#define MA_DR_FLAC_PICTURE_TYPE_COVER_FRONT 3
#define MA_DR_FLAC_PICTURE_TYPE_COVER_BACK 4
#define MA_DR_FLAC_PICTURE_TYPE_LEAFLET_PAGE 5
#define MA_DR_FLAC_PICTURE_TYPE_MEDIA 6
#define MA_DR_FLAC_PICTURE_TYPE_LEAD_ARTIST 7
#define MA_DR_FLAC_PICTURE_TYPE_ARTIST 8
#define MA_DR_FLAC_PICTURE_TYPE_CONDUCTOR 9
#define MA_DR_FLAC_PICTURE_TYPE_BAND 10
#define MA_DR_FLAC_PICTURE_TYPE_COMPOSER 11
#define MA_DR_FLAC_PICTURE_TYPE_LYRICIST 12
#define MA_DR_FLAC_PICTURE_TYPE_RECORDING_LOCATION 13
#define MA_DR_FLAC_PICTURE_TYPE_DURING_RECORDING 14
#define MA_DR_FLAC_PICTURE_TYPE_DURING_PERFORMANCE 15
#define MA_DR_FLAC_PICTURE_TYPE_SCREEN_CAPTURE 16
#define MA_DR_FLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17
#define MA_DR_FLAC_PICTURE_TYPE_ILLUSTRATION 18
#define MA_DR_FLAC_PICTURE_TYPE_BAND_LOGOTYPE 19
#define MA_DR_FLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20
drflac_uint16 minBlockSizeInPCMFrames;
drflac_uint16 maxBlockSizeInPCMFrames;
drflac_uint32 minFrameSizeInPCMFrames;
drflac_uint32 maxFrameSizeInPCMFrames;
drflac_uint32 sampleRate;
drflac_uint8 channels;
drflac_uint8 bitsPerSample;
drflac_uint64 totalPCMFrameCount;
drflac_uint8 md5[16];
} drflac_streaminfo;
ma_uint16 minBlockSizeInPCMFrames;
ma_uint16 maxBlockSizeInPCMFrames;
ma_uint32 minFrameSizeInPCMFrames;
ma_uint32 maxFrameSizeInPCMFrames;
ma_uint32 sampleRate;
ma_uint8 channels;
ma_uint8 bitsPerSample;
ma_uint64 totalPCMFrameCount;
ma_uint8 md5[16];
} ma_dr_flac_streaminfo;
drflac_uint32 width;
drflac_uint32 height;
drflac_uint32 colorDepth;
drflac_uint32 indexColorCount;
drflac_uint32 pictureDataSize;
const drflac_uint8* pPictureData;
ma_uint32 width;
ma_uint32 height;
ma_uint32 colorDepth;
ma_uint32 indexColorCount;
ma_uint32 pictureDataSize;
const ma_uint8* pPictureData;
} drflac_metadata;
typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drflac_allocation_callbacks;
} ma_dr_flac_metadata;
typedef size_t (* ma_dr_flac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef ma_bool32 (* ma_dr_flac_seek_proc)(void* pUserData, int offset, ma_dr_flac_seek_origin origin);
typedef void (* ma_dr_flac_meta_proc)(void* pUserData, ma_dr_flac_metadata* pMetadata);
drflac_cache_t unalignedCache;
drflac_uint32 nextL2Line;
drflac_uint32 consumedBits;
drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
drflac_cache_t cache;
drflac_uint16 crc16;
drflac_cache_t crc16Cache;
drflac_uint32 crc16CacheIgnoredBytes;
} drflac_bs;
ma_dr_flac_cache_t unalignedCache;
ma_uint32 nextL2Line;
ma_uint32 consumedBits;
ma_dr_flac_cache_t cacheL2[MA_DR_FLAC_BUFFER_SIZE/sizeof(ma_dr_flac_cache_t)];
ma_dr_flac_cache_t cache;
ma_uint16 crc16;
ma_dr_flac_cache_t crc16Cache;
ma_uint32 crc16CacheIgnoredBytes;
} ma_dr_flac_bs;
drflac_uint8 subframeType;
drflac_uint8 wastedBitsPerSample;
drflac_uint8 lpcOrder;
drflac_int32* pSamplesS32;
} drflac_subframe;
ma_uint8 subframeType;
ma_uint8 wastedBitsPerSample;
ma_uint8 lpcOrder;
ma_int32* pSamplesS32;
} ma_dr_flac_subframe;
drflac_uint64 pcmFrameNumber;
drflac_uint32 flacFrameNumber;
drflac_uint32 sampleRate;
drflac_uint16 blockSizeInPCMFrames;
drflac_uint8 channelAssignment;
drflac_uint8 bitsPerSample;
drflac_uint8 crc8;
} drflac_frame_header;
ma_uint64 pcmFrameNumber;
ma_uint32 flacFrameNumber;
ma_uint32 sampleRate;
ma_uint16 blockSizeInPCMFrames;
ma_uint8 channelAssignment;
ma_uint8 bitsPerSample;
ma_uint8 crc8;
} ma_dr_flac_frame_header;
drflac_allocation_callbacks allocationCallbacks;
drflac_uint32 sampleRate;
drflac_uint8 channels;
drflac_uint8 bitsPerSample;
drflac_uint16 maxBlockSizeInPCMFrames;
drflac_uint64 totalPCMFrameCount;
drflac_container container;
drflac_uint32 seekpointCount;
drflac_frame currentFLACFrame;
drflac_uint64 currentPCMFrame;
drflac_uint64 firstFLACFramePosInBytes;
drflac__memory_stream memoryStream;
drflac_int32* pDecodedSamples;
drflac_seekpoint* pSeekpoints;
ma_allocation_callbacks allocationCallbacks;
ma_uint32 sampleRate;
ma_uint8 channels;
ma_uint8 bitsPerSample;
ma_uint16 maxBlockSizeInPCMFrames;
ma_uint64 totalPCMFrameCount;
ma_dr_flac_container container;
ma_uint32 seekpointCount;
ma_dr_flac_frame currentFLACFrame;
ma_uint64 currentPCMFrame;
ma_uint64 firstFLACFramePosInBytes;
ma_dr_flac__memory_stream memoryStream;
ma_int32* pDecodedSamples;
ma_dr_flac_seekpoint* pSeekpoints;
drflac_bool32 _noSeekTableSeek : 1;
drflac_bool32 _noBinarySearchSeek : 1;
drflac_bool32 _noBruteForceSeek : 1;
drflac_bs bs;
drflac_uint8 pExtraData[1];
} drflac;
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_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* 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_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 void drflac_close(drflac* pFlac);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut);
DRFLAC_API drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
ma_bool32 _noSeekTableSeek : 1;
ma_bool32 _noBinarySearchSeek : 1;
ma_bool32 _noBruteForceSeek : 1;
ma_dr_flac_bs bs;
ma_uint8 pExtraData[1];
} ma_dr_flac;
MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API void ma_dr_flac_close(ma_dr_flac* pFlac);
MA_API ma_uint64 ma_dr_flac_read_pcm_frames_s32(ma_dr_flac* pFlac, ma_uint64 framesToRead, ma_int32* pBufferOut);
MA_API ma_uint64 ma_dr_flac_read_pcm_frames_s16(ma_dr_flac* pFlac, ma_uint64 framesToRead, ma_int16* pBufferOut);
MA_API ma_uint64 ma_dr_flac_read_pcm_frames_f32(ma_dr_flac* pFlac, ma_uint64 framesToRead, float* pBufferOut);
MA_API ma_bool32 ma_dr_flac_seek_to_pcm_frame(ma_dr_flac* pFlac, ma_uint64 pcmFrameIndex);
#ifndef MA_DR_FLAC_NO_STDIO
MA_API ma_dr_flac* ma_dr_flac_open_file(const char* pFileName, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_file_w(const wchar_t* pFileName, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata(const char* pFileName, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata_w(const wchar_t* pFileName, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
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_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 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);
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_memory(const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_memory_with_metadata(const void* pData, size_t dataSize, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_FLAC_NO_STDIO
MA_API ma_int32* ma_dr_flac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_flac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_flac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
DRFLAC_API void drflac_free(void* p, const drflac_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int32* ma_dr_flac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_flac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_flac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API void ma_dr_flac_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
} drflac_vorbis_comment_iterator;
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
} ma_dr_flac_vorbis_comment_iterator;
MA_API void ma_dr_flac_init_vorbis_comment_iterator(ma_dr_flac_vorbis_comment_iterator* pIter, ma_uint32 commentCount, const void* pComments);
MA_API const char* ma_dr_flac_next_vorbis_comment(ma_dr_flac_vorbis_comment_iterator* pIter, ma_uint32* pCommentLengthOut);
drflac_bool8 isAudio;
drflac_bool8 preEmphasis;
drflac_uint8 indexCount;
const drflac_cuesheet_track_index* pIndexPoints;
} drflac_cuesheet_track;
DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData);
DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack);
ma_bool8 isAudio;
ma_bool8 preEmphasis;
ma_uint8 indexCount;
const ma_dr_flac_cuesheet_track_index* pIndexPoints;
} ma_dr_flac_cuesheet_track;
MA_API void ma_dr_flac_init_cuesheet_track_iterator(ma_dr_flac_cuesheet_track_iterator* pIter, ma_uint32 trackCount, const void* pTrackData);
MA_API ma_bool32 ma_dr_flac_next_cuesheet_track(ma_dr_flac_cuesheet_track_iterator* pIter, ma_dr_flac_cuesheet_track* pCuesheetTrack);
#define DRMP3_STRINGIFY(x) #x
#define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x)
#define DRMP3_VERSION_MAJOR 0
#define DRMP3_VERSION_MINOR 6
#define DRMP3_VERSION_REVISION 33
#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
#define MA_DR_MP3_STRINGIFY(x) #x
#define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x)
#define MA_DR_MP3_VERSION_MAJOR 0
#define MA_DR_MP3_VERSION_MINOR 6
#define MA_DR_MP3_VERSION_REVISION 37
#define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION)
typedef signed char drmp3_int8;
typedef unsigned char drmp3_uint8;
typedef signed short drmp3_int16;
typedef unsigned short drmp3_uint16;
typedef signed int drmp3_int32;
typedef unsigned int drmp3_uint32;
#if defined(_MSC_VER) && !defined(__clang__)
typedef signed __int64 drmp3_int64;
typedef unsigned __int64 drmp3_uint64;
#else
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wc++11-long-long"
#endif
#endif
typedef signed long long drmp3_int64;
typedef unsigned long long drmp3_uint64;
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#endif
#endif
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
typedef drmp3_uint64 drmp3_uintptr;
#else
typedef drmp3_uint32 drmp3_uintptr;
#endif
typedef drmp3_uint8 drmp3_bool8;
typedef drmp3_uint32 drmp3_bool32;
#define DRMP3_TRUE 1
#define DRMP3_FALSE 0
#if !defined(DRMP3_API)
#if defined(DRMP3_DLL)
#if defined(_WIN32)
#define DRMP3_DLL_IMPORT __declspec(dllimport)
#define DRMP3_DLL_EXPORT __declspec(dllexport)
#define DRMP3_DLL_PRIVATE static
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DRMP3_DLL_IMPORT __attribute__((visibility("default")))
#define DRMP3_DLL_EXPORT __attribute__((visibility("default")))
#define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden")))
#else
#define DRMP3_DLL_IMPORT
#define DRMP3_DLL_EXPORT
#define DRMP3_DLL_PRIVATE static
#endif
#endif
#if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
#define DRMP3_API DRMP3_DLL_EXPORT
#else
#define DRMP3_API DRMP3_DLL_IMPORT
#endif
#define DRMP3_PRIVATE DRMP3_DLL_PRIVATE
#else
#define DRMP3_API extern
#define DRMP3_PRIVATE static
#endif
#endif
typedef drmp3_int32 drmp3_result;
#define DRMP3_SUCCESS 0
#define DRMP3_ERROR -1
#define DRMP3_INVALID_ARGS -2
#define DRMP3_INVALID_OPERATION -3
#define DRMP3_OUT_OF_MEMORY -4
#define DRMP3_OUT_OF_RANGE -5
#define DRMP3_ACCESS_DENIED -6
#define DRMP3_DOES_NOT_EXIST -7
#define DRMP3_ALREADY_EXISTS -8
#define DRMP3_TOO_MANY_OPEN_FILES -9
#define DRMP3_INVALID_FILE -10
#define DRMP3_TOO_BIG -11
#define DRMP3_PATH_TOO_LONG -12
#define DRMP3_NAME_TOO_LONG -13
#define DRMP3_NOT_DIRECTORY -14
#define DRMP3_IS_DIRECTORY -15
#define DRMP3_DIRECTORY_NOT_EMPTY -16
#define DRMP3_END_OF_FILE -17
#define DRMP3_NO_SPACE -18
#define DRMP3_BUSY -19
#define DRMP3_IO_ERROR -20
#define DRMP3_INTERRUPT -21
#define DRMP3_UNAVAILABLE -22
#define DRMP3_ALREADY_IN_USE -23
#define DRMP3_BAD_ADDRESS -24
#define DRMP3_BAD_SEEK -25
#define DRMP3_BAD_PIPE -26
#define DRMP3_DEADLOCK -27
#define DRMP3_TOO_MANY_LINKS -28
#define DRMP3_NOT_IMPLEMENTED -29
#define DRMP3_NO_MESSAGE -30
#define DRMP3_BAD_MESSAGE -31
#define DRMP3_NO_DATA_AVAILABLE -32
#define DRMP3_INVALID_DATA -33
#define DRMP3_TIMEOUT -34
#define DRMP3_NO_NETWORK -35
#define DRMP3_NOT_UNIQUE -36
#define DRMP3_NOT_SOCKET -37
#define DRMP3_NO_ADDRESS -38
#define DRMP3_BAD_PROTOCOL -39
#define DRMP3_PROTOCOL_UNAVAILABLE -40
#define DRMP3_PROTOCOL_NOT_SUPPORTED -41
#define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42
#define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43
#define DRMP3_SOCKET_NOT_SUPPORTED -44
#define DRMP3_CONNECTION_RESET -45
#define DRMP3_ALREADY_CONNECTED -46
#define DRMP3_NOT_CONNECTED -47
#define DRMP3_CONNECTION_REFUSED -48
#define DRMP3_NO_HOST -49
#define DRMP3_IN_PROGRESS -50
#define DRMP3_CANCELLED -51
#define DRMP3_MEMORY_ALREADY_MAPPED -52
#define DRMP3_AT_END -53
#define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
#define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
#ifdef _MSC_VER
#define DRMP3_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRMP3_GNUC_INLINE_HINT __inline__
#else
#define DRMP3_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRMP3_INLINE __inline
#else
#define DRMP3_INLINE
#endif
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
DRMP3_API const char* drmp3_version_string(void);
#define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
#define MA_DR_MP3_MAX_SAMPLES_PER_FRAME (MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
MA_API void ma_dr_mp3_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision);
MA_API const char* ma_dr_mp3_version_string(void);
drmp3_uint8 header[4], reserv_buf[511];
} drmp3dec;
DRMP3_API void drmp3dec_init(drmp3dec *dec);
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
ma_uint8 header[4], reserv_buf[511];
} ma_dr_mp3dec;
MA_API void ma_dr_mp3dec_init(ma_dr_mp3dec *dec);
MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int mp3_bytes, void *pcm, ma_dr_mp3dec_frame_info *info);
MA_API void ma_dr_mp3dec_f32_to_s16(const float *in, ma_int16 *out, size_t num_samples);
drmp3_uint64 seekPosInBytes;
drmp3_uint64 pcmFrameIndex;
drmp3_uint16 mp3FramesToDiscard;
drmp3_uint16 pcmFramesToDiscard;
} drmp3_seek_point;
typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
ma_dr_mp3_seek_origin_start,
ma_dr_mp3_seek_origin_current
} ma_dr_mp3_seek_origin;
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
ma_uint64 seekPosInBytes;
ma_uint64 pcmFrameIndex;
ma_uint16 mp3FramesToDiscard;
ma_uint16 pcmFramesToDiscard;
} ma_dr_mp3_seek_point;
typedef size_t (* ma_dr_mp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef ma_bool32 (* ma_dr_mp3_seek_proc)(void* pUserData, int offset, ma_dr_mp3_seek_origin origin);
drmp3dec decoder;
drmp3dec_frame_info frameInfo;
drmp3_uint32 channels;
drmp3_uint32 sampleRate;
drmp3_read_proc onRead;
drmp3_seek_proc onSeek;
ma_dr_mp3dec decoder;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_dr_mp3_read_proc onRead;
ma_dr_mp3_seek_proc onSeek;
drmp3_allocation_callbacks allocationCallbacks;
drmp3_uint32 mp3FrameChannels;
drmp3_uint32 mp3FrameSampleRate;
drmp3_uint32 pcmFramesConsumedInMP3Frame;
drmp3_uint32 pcmFramesRemainingInMP3Frame;
drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME];
drmp3_uint64 currentPCMFrame;
drmp3_uint64 streamCursor;
drmp3_seek_point* pSeekPoints;
drmp3_uint32 seekPointCount;
ma_allocation_callbacks allocationCallbacks;
ma_uint32 mp3FrameChannels;
ma_uint32 mp3FrameSampleRate;
ma_uint32 pcmFramesConsumedInMP3Frame;
ma_uint32 pcmFramesRemainingInMP3Frame;
ma_uint8 pcmFrames[sizeof(float)*MA_DR_MP3_MAX_SAMPLES_PER_FRAME];
ma_uint64 currentPCMFrame;
ma_uint64 streamCursor;
ma_dr_mp3_seek_point* pSeekPoints;
ma_uint32 seekPointCount;
} drmp3;
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
} ma_dr_mp3;
MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_MP3_NO_STDIO
MA_API ma_bool32 ma_dr_mp3_init_file(ma_dr_mp3* pMP3, const char* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_mp3_init_file_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks);
DRMP3_API void drmp3_uninit(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
MA_API void ma_dr_mp3_uninit(ma_dr_mp3* pMP3);
MA_API ma_uint64 ma_dr_mp3_read_pcm_frames_f32(ma_dr_mp3* pMP3, ma_uint64 framesToRead, float* pBufferOut);
MA_API ma_uint64 ma_dr_mp3_read_pcm_frames_s16(ma_dr_mp3* pMP3, ma_uint64 framesToRead, ma_int16* pBufferOut);
MA_API ma_bool32 ma_dr_mp3_seek_to_pcm_frame(ma_dr_mp3* pMP3, ma_uint64 frameIndex);
MA_API ma_uint64 ma_dr_mp3_get_pcm_frame_count(ma_dr_mp3* pMP3);
MA_API ma_uint64 ma_dr_mp3_get_mp3_frame_count(ma_dr_mp3* pMP3);
MA_API ma_bool32 ma_dr_mp3_get_mp3_and_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint64* pMP3FrameCount, ma_uint64* pPCMFrameCount);
MA_API ma_bool32 ma_dr_mp3_calculate_seek_points(ma_dr_mp3* pMP3, ma_uint32* pSeekPointCount, ma_dr_mp3_seek_point* pSeekPoints);
MA_API ma_bool32 ma_dr_mp3_bind_seek_table(ma_dr_mp3* pMP3, ma_uint32 seekPointCount, ma_dr_mp3_seek_point* pSeekPoints);
MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_mp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_mp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_MP3_NO_STDIO
MA_API float* ma_dr_mp3_open_file_and_read_pcm_frames_f32(const char* filePath, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_mp3_open_file_and_read_pcm_frames_s16(const char* filePath, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
MA_API void* ma_dr_mp3_malloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API void ma_dr_mp3_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
static ma_result ma_decoder_init_from_vtable(const ma_decoding_backend_vtable* pVTable, void* pVTableUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
static ma_result ma_decoder_init_from_vtable__internal(const ma_decoding_backend_vtable* pVTable, void* pVTableUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
static ma_result ma_decoder_init_from_file__internal(const ma_decoding_backend_vtable* pVTable, void* pVTableUserData, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
ma_decoding_backend_config backendConfig;
ma_data_source* pBackend;
MA_ASSERT(pVTable != NULL);
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL);
result = pVTable->onInitFile(pVTableUserData, pFilePath, &backendConfig, &pDecoder->allocationCallbacks, &pBackend);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the backend from this vtable. */
}
/* Getting here means we were able to initialize the backend so we can now initialize the decoder. */
pDecoder->pBackend = pBackend;
pDecoder->pBackendVTable = pVTable;
pDecoder->pBackendUserData = pConfig->pCustomBackendUserData;
return MA_SUCCESS;
}
static ma_result ma_decoder_init_from_file_w__internal(const ma_decoding_backend_vtable* pVTable, void* pVTableUserData, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
ma_decoding_backend_config backendConfig;
ma_data_source* pBackend;
MA_ASSERT(pVTable != NULL);
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL);
if (pVTable->onInitFileW == NULL) {
return MA_NOT_IMPLEMENTED;
}
backendConfig = ma_decoding_backend_config_init(pConfig->format, pConfig->seekPointCount);
result = pVTable->onInitFileW(pVTableUserData, pFilePath, &backendConfig, &pDecoder->allocationCallbacks, &pBackend);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the backend from this vtable. */
}
/* Getting here means we were able to initialize the backend so we can now initialize the decoder. */
pDecoder->pBackend = pBackend;
pDecoder->pBackendVTable = pVTable;
pDecoder->pBackendUserData = pConfig->pCustomBackendUserData;
return MA_SUCCESS;
}
static ma_result ma_decoder_init_from_memory__internal(const ma_decoding_backend_vtable* pVTable, void* pVTableUserData, const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
ma_decoding_backend_config backendConfig;
ma_data_source* pBackend;
MA_ASSERT(pVTable != NULL);
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL);
if (pVTable->onInitMemory == NULL) {
return MA_NOT_IMPLEMENTED;
}
backendConfig = ma_decoding_backend_config_init(pConfig->format, pConfig->seekPointCount);
result = pVTable->onInitMemory(pVTableUserData, pData, dataSize, &backendConfig, &pDecoder->allocationCallbacks, &pBackend);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the backend from this vtable. */
}
/* Getting here means we were able to initialize the backend so we can now initialize the decoder. */
pDecoder->pBackend = pBackend;
pDecoder->pBackendVTable = pVTable;
pDecoder->pBackendUserData = pConfig->pCustomBackendUserData;
return MA_SUCCESS;
}
if (pVTable != NULL && pVTable->onInit != NULL) {
result = ma_decoder_init_from_vtable(pVTable, pConfig->pCustomBackendUserData, pConfig, pDecoder);
if (pVTable != NULL) {
result = ma_decoder_init_from_vtable__internal(pVTable, pConfig->pCustomBackendUserData, pConfig, pDecoder);
}
} else {
/* No vtable. */
}
}
/* Getting here means we couldn't find a backend. */
return MA_NO_BACKEND;
}
static ma_result ma_decoder_init_custom_from_file__internal(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result = MA_NO_BACKEND;
size_t ivtable;
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL);
if (pConfig->ppCustomBackendVTables == NULL) {
return MA_NO_BACKEND;
}
/* The order each backend is listed is what defines the priority. */
for (ivtable = 0; ivtable < pConfig->customBackendCount; ivtable += 1) {
const ma_decoding_backend_vtable* pVTable = pConfig->ppCustomBackendVTables[ivtable];
if (pVTable != NULL) {
result = ma_decoder_init_from_file__internal(pVTable, pConfig->pCustomBackendUserData, pFilePath, pConfig, pDecoder);
if (result == MA_SUCCESS) {
return MA_SUCCESS;
if (pConfig->ppCustomBackendVTables == NULL) {
return MA_NO_BACKEND;
}
/* The order each backend is listed is what defines the priority. */
for (ivtable = 0; ivtable < pConfig->customBackendCount; ivtable += 1) {
const ma_decoding_backend_vtable* pVTable = pConfig->ppCustomBackendVTables[ivtable];
if (pVTable != NULL) {
result = ma_decoder_init_from_file_w__internal(pVTable, pConfig->pCustomBackendUserData, pFilePath, pConfig, pDecoder);
if (result == MA_SUCCESS) {
return MA_SUCCESS;
}
} else {
/* No vtable. */
}
}
/* Getting here means we couldn't find a backend. */
return MA_NO_BACKEND;
}
static ma_result ma_decoder_init_custom_from_memory__internal(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result = MA_NO_BACKEND;
size_t ivtable;
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL);
if (pConfig->ppCustomBackendVTables == NULL) {
return MA_NO_BACKEND;
}
/* The order each backend is listed is what defines the priority. */
for (ivtable = 0; ivtable < pConfig->customBackendCount; ivtable += 1) {
const ma_decoding_backend_vtable* pVTable = pConfig->ppCustomBackendVTables[ivtable];
if (pVTable != NULL) {
result = ma_decoder_init_from_memory__internal(pVTable, pConfig->pCustomBackendUserData, pData, dataSize, pConfig, pDecoder);
if (result == MA_SUCCESS) {
return MA_SUCCESS;
}
} else {
/* No vtable. */
}
}
/* Getting here means we couldn't find a backend. */
return MA_NO_BACKEND;
}
static drwav_allocation_callbacks drwav_allocation_callbacks_from_miniaudio(const ma_allocation_callbacks* pAllocationCallbacks)
{
drwav_allocation_callbacks callbacks;
if (pAllocationCallbacks != NULL) {
callbacks.onMalloc = pAllocationCallbacks->onMalloc;
callbacks.onRealloc = pAllocationCallbacks->onRealloc;
callbacks.onFree = pAllocationCallbacks->onFree;
callbacks.pUserData = pAllocationCallbacks->pUserData;
} else {
callbacks.onMalloc = ma__malloc_default;
callbacks.onRealloc = ma__realloc_default;
callbacks.onFree = ma__free_default;
callbacks.pUserData = NULL;
}
return callbacks;
}
}
return MA_SUCCESS;
}
static ma_result ma_wav_post_init(ma_wav* pWav)
{
/*
If an explicit format was not specified, try picking the closest match based on the internal
format. The format needs to be supported by miniaudio.
*/
if (pWav->format == ma_format_unknown) {
switch (pWav->dr.translatedFormatTag)
{
case MA_DR_WAVE_FORMAT_PCM:
{
if (pWav->dr.bitsPerSample == 8) {
pWav->format = ma_format_u8;
} else if (pWav->dr.bitsPerSample == 16) {
pWav->format = ma_format_s16;
} else if (pWav->dr.bitsPerSample == 24) {
pWav->format = ma_format_s24;
} else if (pWav->dr.bitsPerSample == 32) {
pWav->format = ma_format_s32;
}
} break;
case MA_DR_WAVE_FORMAT_IEEE_FLOAT:
{
if (pWav->dr.bitsPerSample == 32) {
pWav->format = ma_format_f32;
}
} break;
default: break;
}
/* Fall back to f32 if we couldn't find anything. */
if (pWav->format == ma_format_unknown) {
pWav->format = ma_format_f32;
}
wavResult = drwav_init(&pWav->dr, ma_wav_dr_callback__read, ma_wav_dr_callback__seek, pWav, &wavAllocationCallbacks);
wavResult = ma_dr_wav_init(&pWav->dr, ma_wav_dr_callback__read, ma_wav_dr_callback__seek, pWav, pAllocationCallbacks);
/*
If an explicit format was not specified, try picking the closest match based on the internal
format. The format needs to be supported by miniaudio.
*/
if (pWav->format == ma_format_unknown) {
switch (pWav->dr.translatedFormatTag)
{
case DR_WAVE_FORMAT_PCM:
{
if (pWav->dr.bitsPerSample == 8) {
pWav->format = ma_format_u8;
} else if (pWav->dr.bitsPerSample == 16) {
pWav->format = ma_format_s16;
} else if (pWav->dr.bitsPerSample == 24) {
pWav->format = ma_format_s24;
} else if (pWav->dr.bitsPerSample == 32) {
pWav->format = ma_format_s32;
}
} break;
ma_wav_post_init(pWav);
drwav_result wavResult = drwav_get_cursor_in_pcm_frames(&pWav->dr, pCursor);
if (wavResult != DRWAV_SUCCESS) {
return (ma_result)wavResult; /* dr_wav result codes map to miniaudio's. */
ma_result wavResult = ma_dr_wav_get_cursor_in_pcm_frames(&pWav->dr, pCursor);
if (wavResult != MA_SUCCESS) {
return (ma_result)wavResult; /* ma_dr_wav result codes map to miniaudio's. */
drwav_result wavResult = drwav_get_length_in_pcm_frames(&pWav->dr, pLength);
if (wavResult != DRWAV_SUCCESS) {
return (ma_result)wavResult; /* dr_wav result codes map to miniaudio's. */
ma_result wavResult = ma_dr_wav_get_length_in_pcm_frames(&pWav->dr, pLength);
if (wavResult != MA_SUCCESS) {
return (ma_result)wavResult; /* ma_dr_wav result codes map to miniaudio's. */
#endif /* dr_wav_h */
static ma_result ma_decoder_init_wav_from_file__internal(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file__internal(&g_ma_decoding_backend_vtable_wav, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_wav_from_file_w__internal(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file_w__internal(&g_ma_decoding_backend_vtable_wav, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_wav_from_memory__internal(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_memory__internal(&g_ma_decoding_backend_vtable_wav, NULL, pData, dataSize, pConfig, pDecoder);
}
#endif /* ma_dr_wav_h */
static drflac_allocation_callbacks drflac_allocation_callbacks_from_miniaudio(const ma_allocation_callbacks* pAllocationCallbacks)
{
drflac_allocation_callbacks callbacks;
if (pAllocationCallbacks != NULL) {
callbacks.onMalloc = pAllocationCallbacks->onMalloc;
callbacks.onRealloc = pAllocationCallbacks->onRealloc;
callbacks.onFree = pAllocationCallbacks->onFree;
callbacks.pUserData = pAllocationCallbacks->pUserData;
} else {
callbacks.onMalloc = ma__malloc_default;
callbacks.onRealloc = ma__realloc_default;
callbacks.onFree = ma__free_default;
callbacks.pUserData = NULL;
}
return callbacks;
}
drflac_allocation_callbacks flacAllocationCallbacks = drflac_allocation_callbacks_from_miniaudio(pAllocationCallbacks);
pFlac->dr = drflac_open(ma_flac_dr_callback__read, ma_flac_dr_callback__seek, pFlac, &flacAllocationCallbacks);
pFlac->dr = ma_dr_flac_open(ma_flac_dr_callback__read, ma_flac_dr_callback__seek, pFlac, pAllocationCallbacks);
drflac_allocation_callbacks flacAllocationCallbacks = drflac_allocation_callbacks_from_miniaudio(pAllocationCallbacks);
pFlac->dr = drflac_open_file(pFilePath, &flacAllocationCallbacks);
pFlac->dr = ma_dr_flac_open_file(pFilePath, pAllocationCallbacks);
drflac_allocation_callbacks flacAllocationCallbacks = drflac_allocation_callbacks_from_miniaudio(pAllocationCallbacks);
pFlac->dr = drflac_open_file_w(pFilePath, &flacAllocationCallbacks);
pFlac->dr = ma_dr_flac_open_file_w(pFilePath, pAllocationCallbacks);
drflac_allocation_callbacks flacAllocationCallbacks = drflac_allocation_callbacks_from_miniaudio(pAllocationCallbacks);
pFlac->dr = drflac_open_memory(pData, dataSize, &flacAllocationCallbacks);
pFlac->dr = ma_dr_flac_open_memory(pData, dataSize, pAllocationCallbacks);
return ma_decoder_init_from_vtable(&g_ma_decoding_backend_vtable_flac, NULL, pConfig, pDecoder);
return ma_decoder_init_from_file__internal(&g_ma_decoding_backend_vtable_flac, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_flac_from_file_w__internal(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file_w__internal(&g_ma_decoding_backend_vtable_flac, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_flac_from_memory__internal(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_memory__internal(&g_ma_decoding_backend_vtable_flac, NULL, pData, dataSize, pConfig, pDecoder);
drmp3 dr;
drmp3_uint32 seekPointCount;
drmp3_seek_point* pSeekPoints; /* Only used if seek table generation is used. */
ma_dr_mp3 dr;
ma_uint32 seekPointCount;
ma_dr_mp3_seek_point* pSeekPoints; /* Only used if seek table generation is used. */
static drmp3_allocation_callbacks drmp3_allocation_callbacks_from_miniaudio(const ma_allocation_callbacks* pAllocationCallbacks)
{
drmp3_allocation_callbacks callbacks;
if (pAllocationCallbacks != NULL) {
callbacks.onMalloc = pAllocationCallbacks->onMalloc;
callbacks.onRealloc = pAllocationCallbacks->onRealloc;
callbacks.onFree = pAllocationCallbacks->onFree;
callbacks.pUserData = pAllocationCallbacks->pUserData;
} else {
callbacks.onMalloc = ma__malloc_default;
callbacks.onRealloc = ma__realloc_default;
callbacks.onFree = ma__free_default;
callbacks.pUserData = NULL;
}
return callbacks;
}
static ma_result ma_mp3_post_init(ma_mp3* pMP3, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_result result;
result = ma_mp3_generate_seek_table(pMP3, pConfig, pAllocationCallbacks);
if (result != MA_SUCCESS) {
return result;
}
return MA_SUCCESS;
}
mp3Result = drmp3_init(&pMP3->dr, ma_mp3_dr_callback__read, ma_mp3_dr_callback__seek, pMP3, &mp3AllocationCallbacks);
mp3Result = ma_dr_mp3_init(&pMP3->dr, ma_mp3_dr_callback__read, ma_mp3_dr_callback__seek, pMP3, pAllocationCallbacks);
#endif /* dr_mp3_h */
static ma_result ma_decoder_init_mp3_from_file__internal(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file__internal(&g_ma_decoding_backend_vtable_mp3, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_mp3_from_file_w__internal(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file_w__internal(&g_ma_decoding_backend_vtable_mp3, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_mp3_from_memory__internal(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_memory__internal(&g_ma_decoding_backend_vtable_mp3, NULL, pData, dataSize, pConfig, pDecoder);
}
#endif /* ma_dr_mp3_h */
return MA_SUCCESS;
}
static ma_result ma_stbvorbis_init_internal_decoder_push(ma_stbvorbis* pVorbis)
{
ma_result result;
stb_vorbis* stb;
size_t dataSize = 0;
size_t dataCapacity = 0;
ma_uint8* pData = NULL; /* <-- Must be initialized to NULL. */
for (;;) {
int vorbisError;
int consumedDataSize; /* <-- Fill by stb_vorbis_open_pushdata(). */
size_t bytesRead;
ma_uint8* pNewData;
/* Allocate memory for the new chunk. */
dataCapacity += MA_VORBIS_DATA_CHUNK_SIZE;
pNewData = (ma_uint8*)ma_realloc(pData, dataCapacity, &pVorbis->allocationCallbacks);
if (pNewData == NULL) {
ma_free(pData, &pVorbis->allocationCallbacks);
return MA_OUT_OF_MEMORY;
}
pData = pNewData;
/* Read in the next chunk. */
result = pVorbis->onRead(pVorbis->pReadSeekTellUserData, ma_offset_ptr(pData, dataSize), (dataCapacity - dataSize), &bytesRead);
dataSize += bytesRead;
if (result != MA_SUCCESS) {
ma_free(pData, &pVorbis->allocationCallbacks);
return result;
}
/* We have a maximum of 31 bits with stb_vorbis. */
if (dataSize > INT_MAX) {
ma_free(pData, &pVorbis->allocationCallbacks);
return MA_TOO_BIG;
}
stb = stb_vorbis_open_pushdata(pData, (int)dataSize, &consumedDataSize, &vorbisError, NULL);
if (stb != NULL) {
/*
Successfully opened the Vorbis decoder. We might have some leftover unprocessed
data so we'll need to move that down to the front.
*/
dataSize -= (size_t)consumedDataSize; /* Consume the data. */
MA_MOVE_MEMORY(pData, ma_offset_ptr(pData, consumedDataSize), dataSize);
/*
We need to track the start point so we can seek back to the start of the audio
data when seeking.
*/
pVorbis->push.audioStartOffsetInBytes = consumedDataSize;
break;
} else {
/* Failed to open the decoder. */
if (vorbisError == VORBIS_need_more_data) {
continue;
} else {
ma_free(pData, &pVorbis->allocationCallbacks);
return MA_ERROR; /* Failed to open the stb_vorbis decoder. */
}
}
}
MA_ASSERT(stb != NULL);
pVorbis->stb = stb;
pVorbis->push.pData = pData;
pVorbis->push.dataSize = dataSize;
pVorbis->push.dataCapacity = dataCapacity;
stb_vorbis* stb;
size_t dataSize = 0;
size_t dataCapacity = 0;
ma_uint8* pData = NULL; /* <-- Must be initialized to NULL. */
for (;;) {
int vorbisError;
int consumedDataSize; /* <-- Fill by stb_vorbis_open_pushdata(). */
size_t bytesRead;
ma_uint8* pNewData;
/* Allocate memory for the new chunk. */
dataCapacity += MA_VORBIS_DATA_CHUNK_SIZE;
pNewData = (ma_uint8*)ma_realloc(pData, dataCapacity, pAllocationCallbacks);
if (pNewData == NULL) {
ma_free(pData, pAllocationCallbacks);
return MA_OUT_OF_MEMORY;
}
pData = pNewData;
/* Read in the next chunk. */
result = pVorbis->onRead(pVorbis->pReadSeekTellUserData, ma_offset_ptr(pData, dataSize), (dataCapacity - dataSize), &bytesRead);
dataSize += bytesRead;
if (result != MA_SUCCESS) {
ma_free(pData, pAllocationCallbacks);
return result;
}
/* We have a maximum of 31 bits with stb_vorbis. */
if (dataSize > INT_MAX) {
ma_free(pData, pAllocationCallbacks);
return MA_TOO_BIG;
}
stb = stb_vorbis_open_pushdata(pData, (int)dataSize, &consumedDataSize, &vorbisError, NULL);
if (stb != NULL) {
/*
Successfully opened the Vorbis decoder. We might have some leftover unprocessed
data so we'll need to move that down to the front.
*/
dataSize -= (size_t)consumedDataSize; /* Consume the data. */
MA_MOVE_MEMORY(pData, ma_offset_ptr(pData, consumedDataSize), dataSize);
break;
} else {
/* Failed to open the decoder. */
if (vorbisError == VORBIS_need_more_data) {
continue;
} else {
ma_free(pData, pAllocationCallbacks);
return MA_ERROR; /* Failed to open the stb_vorbis decoder. */
}
}
result = ma_stbvorbis_init_internal_decoder_push(pVorbis);
if (result != MA_SUCCESS) {
return result;
/*
This is terribly inefficient because stb_vorbis does not have a good seeking solution with it's push API. Currently this just performs
a full decode right from the start of the stream. Later on I'll need to write a layer that goes through all of the Ogg pages until we
find the one containing the sample we need. Then we know exactly where to seek for stb_vorbis.
/* If we're seeking backwards, we need to seek back to the start and then brute-force forward. */
if (frameIndex < pVorbis->cursor) {
if (frameIndex > 0x7FFFFFFF) {
return MA_INVALID_ARGS; /* Trying to seek beyond the 32-bit maximum of stb_vorbis. */
}
/*
This is wildly inefficient due to me having trouble getting sample exact seeking working
robustly with stb_vorbis_flush_pushdata(). The only way I can think to make this work
perfectly is to reinitialize the decoder. Note that we only enter this path when seeking
backwards. This will hopefully be removed once we get our own Vorbis decoder implemented.
*/
stb_vorbis_close(pVorbis->stb);
ma_free(pVorbis->push.pData, &pVorbis->allocationCallbacks);
/* Seek to the start of the file to begin with. */
result = pVorbis->onSeek(pVorbis->pReadSeekTellUserData, 0, ma_seek_origin_start);
if (result != MA_SUCCESS) {
return result;
}
/* Seek to the start of the file. */
result = pVorbis->onSeek(pVorbis->pReadSeekTellUserData, 0, ma_seek_origin_start);
if (result != MA_SUCCESS) {
return result;
}
{
return ma_decoder_init_from_vtable__internal(&g_ma_decoding_backend_vtable_stbvorbis, NULL, pConfig, pDecoder);
}
static ma_result ma_decoder_init_vorbis_from_file__internal(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_file__internal(&g_ma_decoding_backend_vtable_stbvorbis, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_vorbis_from_file_w__internal(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
return ma_decoder_init_from_vtable(&g_ma_decoding_backend_vtable_stbvorbis, NULL, pConfig, pDecoder);
return ma_decoder_init_from_file_w__internal(&g_ma_decoding_backend_vtable_stbvorbis, NULL, pFilePath, pConfig, pDecoder);
}
static ma_result ma_decoder_init_vorbis_from_memory__internal(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
return ma_decoder_init_from_memory__internal(&g_ma_decoding_backend_vtable_stbvorbis, NULL, pData, dataSize, pConfig, pDecoder);
static ma_result ma_decoder__preinit_memory(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
static ma_result ma_decoder__preinit_memory_wrapper(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
}
if (pData == NULL || dataSize == 0) {
return MA_INVALID_ARGS;
}
/* If the backend has support for loading from a file path we'll want to use that. If that all fails we'll fall back to the VFS path. */
result = MA_NO_BACKEND;
if (config.encodingFormat != ma_encoding_format_unknown) {
#ifdef MA_HAS_WAV
if (config.encodingFormat == ma_encoding_format_wav) {
result = ma_decoder_init_wav_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (config.encodingFormat == ma_encoding_format_flac) {
result = ma_decoder_init_flac_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (config.encodingFormat == ma_encoding_format_mp3) {
result = ma_decoder_init_mp3_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (config.encodingFormat == ma_encoding_format_vorbis) {
result = ma_decoder_init_vorbis_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
return ma_decoder_init__internal(ma_decoder__on_read_memory, ma_decoder__on_seek_memory, NULL, &config, pDecoder);
/*
We use trial and error to open a decoder. We prioritize custom decoders so that if they
implement the same encoding format they take priority over the built-in decoders.
*/
result = ma_decoder_init_custom_from_memory__internal(pData, dataSize, &config, pDecoder);
/*
If we get to this point and we still haven't found a decoder, and the caller has requested a
specific encoding format, there's no hope for it. Abort.
*/
if (result != MA_SUCCESS && config.encodingFormat != ma_encoding_format_unknown) {
return MA_NO_BACKEND;
}
/* Use trial and error for stock decoders. */
if (result != MA_SUCCESS) {
#ifdef MA_HAS_WAV
if (result != MA_SUCCESS) {
result = ma_decoder_init_wav_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (result != MA_SUCCESS) {
result = ma_decoder_init_flac_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (result != MA_SUCCESS) {
result = ma_decoder_init_mp3_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (result != MA_SUCCESS) {
result = ma_decoder_init_vorbis_from_memory__internal(pData, dataSize, &config, pDecoder);
}
#endif
}
}
/*
If at this point we still haven't successfully initialized the decoder it most likely means
the backend doesn't have an implementation for loading from a file path. We'll try using
miniaudio's built-in file IO for loading file.
*/
if (result == MA_SUCCESS) {
/* Initialization was successful. Finish up. */
result = ma_decoder__postinit(&config, pDecoder);
if (result != MA_SUCCESS) {
/*
The backend was initialized successfully, but for some reason post-initialization failed. This is most likely
due to an out of memory error. We're going to abort with an error here and not try to recover.
*/
if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) {
pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks);
}
return result;
}
} else {
/* Probably no implementation for loading from a block of memory. Use miniaudio's abstraction instead. */
result = ma_decoder__preinit_memory_wrapper(pData, dataSize, &config, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
result = ma_decoder_init__internal(ma_decoder__on_read_memory, ma_decoder__on_seek_memory, NULL, &config, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
}
return MA_SUCCESS;
static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
result = ma_decoder__preinit(NULL, NULL, NULL, NULL, pConfig, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
if (pFilePath == NULL || pFilePath[0] == '\0') {
return MA_INVALID_ARGS;
}
return MA_SUCCESS;
}
return ma_decoder_init_vfs(NULL, pFilePath, pConfig, pDecoder);
ma_result result;
ma_decoder_config config;
config = ma_decoder_config_init_copy(pConfig);
result = ma_decoder__preinit_file(pFilePath, &config, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
/* If the backend has support for loading from a file path we'll want to use that. If that all fails we'll fall back to the VFS path. */
result = MA_NO_BACKEND;
if (config.encodingFormat != ma_encoding_format_unknown) {
#ifdef MA_HAS_WAV
if (config.encodingFormat == ma_encoding_format_wav) {
result = ma_decoder_init_wav_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (config.encodingFormat == ma_encoding_format_flac) {
result = ma_decoder_init_flac_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (config.encodingFormat == ma_encoding_format_mp3) {
result = ma_decoder_init_mp3_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (config.encodingFormat == ma_encoding_format_vorbis) {
result = ma_decoder_init_vorbis_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
}
if (result != MA_SUCCESS) {
/* Getting here means we weren't able to initialize a decoder of a specific encoding format. */
/*
We use trial and error to open a decoder. We prioritize custom decoders so that if they
implement the same encoding format they take priority over the built-in decoders.
*/
result = ma_decoder_init_custom_from_file__internal(pFilePath, &config, pDecoder);
/*
If we get to this point and we still haven't found a decoder, and the caller has requested a
specific encoding format, there's no hope for it. Abort.
*/
if (result != MA_SUCCESS && config.encodingFormat != ma_encoding_format_unknown) {
return MA_NO_BACKEND;
}
/* First try loading based on the file extension so we don't waste time opening and closing files. */
#ifdef MA_HAS_WAV
if (result != MA_SUCCESS && ma_path_extension_equal(pFilePath, "wav")) {
result = ma_decoder_init_wav_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (result != MA_SUCCESS && ma_path_extension_equal(pFilePath, "flac")) {
result = ma_decoder_init_flac_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (result != MA_SUCCESS && ma_path_extension_equal(pFilePath, "mp3")) {
result = ma_decoder_init_mp3_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (result != MA_SUCCESS && ma_path_extension_equal(pFilePath, "ogg")) {
result = ma_decoder_init_vorbis_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
/*
If we still haven't got a result just use trial and error. Custom decoders have already been attempted, so here we
need only iterate over our stock decoders.
*/
if (result != MA_SUCCESS) {
#ifdef MA_HAS_WAV
if (result != MA_SUCCESS) {
result = ma_decoder_init_wav_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (result != MA_SUCCESS) {
result = ma_decoder_init_flac_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (result != MA_SUCCESS) {
result = ma_decoder_init_mp3_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (result != MA_SUCCESS) {
result = ma_decoder_init_vorbis_from_file__internal(pFilePath, &config, pDecoder);
}
#endif
}
}
/*
If at this point we still haven't successfully initialized the decoder it most likely means
the backend doesn't have an implementation for loading from a file path. We'll try using
miniaudio's built-in file IO for loading file.
*/
if (result == MA_SUCCESS) {
/* Initialization was successful. Finish up. */
result = ma_decoder__postinit(&config, pDecoder);
if (result != MA_SUCCESS) {
/*
The backend was initialized successfully, but for some reason post-initialization failed. This is most likely
due to an out of memory error. We're going to abort with an error here and not try to recover.
*/
if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) {
pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks);
}
return result;
}
} else {
/* Probably no implementation for loading from a file path. Use miniaudio's file IO instead. */
result = ma_decoder_init_vfs(NULL, pFilePath, pConfig, pDecoder);
if (result != MA_SUCCESS) {
return MA_SUCCESS;
}
}
return MA_SUCCESS;
}
static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
result = ma_decoder__preinit(NULL, NULL, NULL, NULL, pConfig, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
if (pFilePath == NULL || pFilePath[0] == '\0') {
return MA_INVALID_ARGS;
}
return MA_SUCCESS;
return ma_decoder_init_vfs_w(NULL, pFilePath, pConfig, pDecoder);
ma_result result;
ma_decoder_config config;
config = ma_decoder_config_init_copy(pConfig);
result = ma_decoder__preinit_file_w(pFilePath, &config, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
/* If the backend has support for loading from a file path we'll want to use that. If that all fails we'll fall back to the VFS path. */
result = MA_NO_BACKEND;
if (config.encodingFormat != ma_encoding_format_unknown) {
#ifdef MA_HAS_WAV
if (config.encodingFormat == ma_encoding_format_wav) {
result = ma_decoder_init_wav_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (config.encodingFormat == ma_encoding_format_flac) {
result = ma_decoder_init_flac_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (config.encodingFormat == ma_encoding_format_mp3) {
result = ma_decoder_init_mp3_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (config.encodingFormat == ma_encoding_format_vorbis) {
result = ma_decoder_init_vorbis_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
}
if (result != MA_SUCCESS) {
/* Getting here means we weren't able to initialize a decoder of a specific encoding format. */
/*
We use trial and error to open a decoder. We prioritize custom decoders so that if they
implement the same encoding format they take priority over the built-in decoders.
*/
result = ma_decoder_init_custom_from_file_w__internal(pFilePath, &config, pDecoder);
/*
If we get to this point and we still haven't found a decoder, and the caller has requested a
specific encoding format, there's no hope for it. Abort.
*/
if (result != MA_SUCCESS && config.encodingFormat != ma_encoding_format_unknown) {
return MA_NO_BACKEND;
}
/* First try loading based on the file extension so we don't waste time opening and closing files. */
#ifdef MA_HAS_WAV
if (result != MA_SUCCESS && ma_path_extension_equal_w(pFilePath, L"wav")) {
result = ma_decoder_init_wav_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (result != MA_SUCCESS && ma_path_extension_equal_w(pFilePath, L"flac")) {
result = ma_decoder_init_flac_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (result != MA_SUCCESS && ma_path_extension_equal_w(pFilePath, L"mp3")) {
result = ma_decoder_init_mp3_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (result != MA_SUCCESS && ma_path_extension_equal_w(pFilePath, L"ogg")) {
result = ma_decoder_init_vorbis_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
/*
If we still haven't got a result just use trial and error. Custom decoders have already been attempted, so here we
need only iterate over our stock decoders.
*/
if (result != MA_SUCCESS) {
#ifdef MA_HAS_WAV
if (result != MA_SUCCESS) {
result = ma_decoder_init_wav_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_FLAC
if (result != MA_SUCCESS) {
result = ma_decoder_init_flac_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_MP3
if (result != MA_SUCCESS) {
result = ma_decoder_init_mp3_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
#ifdef MA_HAS_VORBIS
if (result != MA_SUCCESS) {
result = ma_decoder_init_vorbis_from_file_w__internal(pFilePath, &config, pDecoder);
}
#endif
}
}
/*
If at this point we still haven't successfully initialized the decoder it most likely means
the backend doesn't have an implementation for loading from a file path. We'll try using
miniaudio's built-in file IO for loading file.
*/
if (result == MA_SUCCESS) {
/* Initialization was successful. Finish up. */
result = ma_decoder__postinit(&config, pDecoder);
if (result != MA_SUCCESS) {
/*
The backend was initialized successfully, but for some reason post-initialization failed. This is most likely
due to an out of memory error. We're going to abort with an error here and not try to recover.
*/
if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) {
pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks);
}
return result;
}
} else {
/* Probably no implementation for loading from a file path. Use miniaudio's file IO instead. */
result = ma_decoder_init_vfs_w(NULL, pFilePath, pConfig, pDecoder);
if (result != MA_SUCCESS) {
return MA_SUCCESS;
}
}
return MA_SUCCESS;
result = pEncoder->onSeek(pEncoder, offset, (origin == drwav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
result = pEncoder->onSeek(pEncoder, offset, (origin == ma_dr_wav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
if (!drwav_init_write(pWav, &wavFormat, ma_encoder__internal_on_write_wav, ma_encoder__internal_on_seek_wav, pEncoder, &allocationCallbacks)) {
if (!ma_dr_wav_init_write(pWav, &wavFormat, ma_encoder__internal_on_write_wav, ma_encoder__internal_on_seek_wav, pEncoder, &allocationCallbacks)) {
static void ma_waveform_read_pcm_frames__square(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount)
static void ma_waveform_read_pcm_frames__square(ma_waveform* pWaveform, double dutyCycle, void* pFramesOut, ma_uint64 frameCount)
}
MA_API ma_pulsewave_config ma_pulsewave_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double dutyCycle, double amplitude, double frequency)
{
ma_pulsewave_config config;
MA_ZERO_OBJECT(&config);
config.format = format;
config.channels = channels;
config.sampleRate = sampleRate;
config.dutyCycle = dutyCycle;
config.amplitude = amplitude;
config.frequency = frequency;
return config;
MA_API ma_result ma_pulsewave_init(const ma_pulsewave_config* pConfig, ma_pulsewave* pWaveform)
{
ma_result result;
ma_waveform_config config;
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
MA_ZERO_OBJECT(pWaveform);
config = ma_waveform_config_init(
pConfig->format,
pConfig->channels,
pConfig->sampleRate,
ma_waveform_type_square,
pConfig->amplitude,
pConfig->frequency
);
return result;
}
MA_API void ma_pulsewave_uninit(ma_pulsewave* pWaveform)
{
if (pWaveform == NULL) {
return;
}
ma_waveform_uninit(&pWaveform->waveform);
}
MA_API ma_result ma_pulsewave_read_pcm_frames(ma_pulsewave* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
if (pFramesRead != NULL) {
*pFramesRead = 0;
}
if (frameCount == 0) {
return MA_INVALID_ARGS;
}
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
if (pFramesOut != NULL) {
ma_waveform_read_pcm_frames__square(&pWaveform->waveform, pWaveform->config.dutyCycle, pFramesOut, frameCount);
} else {
pWaveform->waveform.time += pWaveform->waveform.advance * (ma_int64)frameCount; /* Cast to int64 required for VC6. Won't affect anything in practice. */
}
if (pFramesRead != NULL) {
*pFramesRead = frameCount;
}
return MA_SUCCESS;
}
MA_API ma_result ma_pulsewave_seek_to_pcm_frame(ma_pulsewave* pWaveform, ma_uint64 frameIndex)
{
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
ma_waveform_seek_to_pcm_frame(&pWaveform->waveform, frameIndex);
return MA_SUCCESS;
}
MA_API ma_result ma_pulsewave_set_amplitude(ma_pulsewave* pWaveform, double amplitude)
{
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
pWaveform->config.amplitude = amplitude;
ma_waveform_set_amplitude(&pWaveform->waveform, amplitude);
return MA_SUCCESS;
}
MA_API ma_result ma_pulsewave_set_frequency(ma_pulsewave* pWaveform, double frequency)
{
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
pWaveform->config.frequency = frequency;
ma_waveform_set_frequency(&pWaveform->waveform, frequency);
return MA_SUCCESS;
}
MA_API ma_result ma_pulsewave_set_sample_rate(ma_pulsewave* pWaveform, ma_uint32 sampleRate)
{
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
pWaveform->config.sampleRate = sampleRate;
ma_waveform_set_sample_rate(&pWaveform->waveform, sampleRate);
return MA_SUCCESS;
}
MA_API ma_result ma_pulsewave_set_duty_cycle(ma_pulsewave* pWaveform, double dutyCycle)
{
if (pWaveform == NULL) {
return MA_INVALID_ARGS;
}
pWaveform->config.dutyCycle = dutyCycle;
return MA_SUCCESS;
}
pNoise->config.type = type;
return MA_SUCCESS;
/*
This function should never have been implemented in the first place. Changing the type dynamically is not
supported. Instead you need to uninitialize and reinitiailize a fresh `ma_noise` object. This function
will be removed in version 0.12.
*/
MA_ASSERT(MA_FALSE);
(void)type;
return MA_INVALID_OPERATION;
result = ma_thread_create(&pResourceManager->jobThreads[iJobThread], ma_thread_priority_normal, 0, ma_resource_manager_job_thread, pResourceManager, &pResourceManager->config.allocationCallbacks);
result = ma_thread_create(&pResourceManager->jobThreads[iJobThread], ma_thread_priority_normal, pResourceManager->config.jobThreadStackSize, ma_resource_manager_job_thread, pResourceManager, &pResourceManager->config.allocationCallbacks);
config.rangeEndInPCMFrames = ~((ma_uint64)0);
config.loopPointEndInPCMFrames = ~((ma_uint64)0);
config.rangeBegInPCMFrames = MA_DATA_SOURCE_DEFAULT_RANGE_BEG;
config.rangeEndInPCMFrames = MA_DATA_SOURCE_DEFAULT_RANGE_END;
config.loopPointBegInPCMFrames = MA_DATA_SOURCE_DEFAULT_LOOP_POINT_BEG;
config.loopPointEndInPCMFrames = MA_DATA_SOURCE_DEFAULT_LOOP_POINT_END;
config.isLooping = MA_FALSE;
Make sure the looping state is set before returning in order to handle the case where the
loop state was set on the data buffer before the connector was initialized.
The resource manager supports the ability to set the range and loop settings via a config at
initialization time. This results in an case where the ranges could be set explicitly via
ma_data_source_set_*() before we get to this point here. If this happens, we'll end up
hitting a case where we just override those settings which results in what feels like a bug.
To address this we only change the relevant properties if they're not equal to defaults. If
they're equal to defaults there's no need to change them anyway. If they're *not* set to the
default values, we can assume the user has set the range and loop settings via the config. If
they're doing their own calls to ma_data_source_set_*() in addition to setting them via the
config, that's entirely on the caller and any synchronization issue becomes their problem.
ma_data_source_set_range_in_pcm_frames(pDataBuffer, pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
ma_data_source_set_loop_point_in_pcm_frames(pDataBuffer, pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
ma_data_source_set_looping(pDataBuffer, pConfig->isLooping);
if (pConfig->rangeBegInPCMFrames != MA_DATA_SOURCE_DEFAULT_RANGE_BEG || pConfig->rangeEndInPCMFrames != MA_DATA_SOURCE_DEFAULT_RANGE_END) {
ma_data_source_set_range_in_pcm_frames(pDataBuffer, pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
}
if (pConfig->loopPointBegInPCMFrames != MA_DATA_SOURCE_DEFAULT_LOOP_POINT_BEG || pConfig->loopPointEndInPCMFrames != MA_DATA_SOURCE_DEFAULT_LOOP_POINT_END) {
ma_data_source_set_loop_point_in_pcm_frames(pDataBuffer, pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
}
if (pConfig->isLooping != MA_FALSE) {
ma_data_source_set_looping(pDataBuffer, pConfig->isLooping);
}
result = ma_resource_manager_post_job(pResourceManager, &job);
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
result = ma_job_process(&job);
} else {
result = ma_resource_manager_post_job(pResourceManager, &job);
}
ma_resource_manager_inline_notification_init(pResourceManager, pInitNotification);
ma_resource_manager_inline_notification_uninit(pInitNotification);
} else {
/* These will have been freed by the job thread, but with WAIT_INIT they will already have happend sinced the job has already been handled. */
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
result = ma_resource_manager_post_job(pResourceManager, &job);
/* If we need to wait for initialization to complete we can just process the job in place. */
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
result = ma_job_process(&job);
} else {
result = ma_resource_manager_post_job(pResourceManager, &job);
}
/*
If we've got a seek scheduled we'll want to do that before reading. However, for paged buffers, there's
a chance that the sound hasn't yet been decoded up to the seek point will result in the seek failing. If
this happens, we need to keep the seek scheduled and return MA_BUSY.
*/
if (result == MA_BAD_SEEK && ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_decoded_paged) {
pDataBuffer->seekToCursorOnNextRead = MA_TRUE; /* Keep the seek scheduled. We just haven't loaded enough data yet to do the seek properly. */
return MA_BUSY;
}
c89atomic_exchange_32(&pDataStream->pageFrameCount[pageIndex], (ma_uint32)totalFramesReadForThisPage);
c89atomic_exchange_32(&pDataStream->isPageValid[pageIndex], MA_TRUE);
ma_atomic_exchange_32(&pDataStream->pageFrameCount[pageIndex], (ma_uint32)totalFramesReadForThisPage);
ma_atomic_exchange_32(&pDataStream->isPageValid[pageIndex], MA_TRUE);
ma_resource_manager_data_stream_set_absolute_cursor(pDataStream, c89atomic_load_64(&pDataStream->absoluteCursor) + frameCount);
ma_resource_manager_data_stream_set_absolute_cursor(pDataStream, ma_atomic_load_64(&pDataStream->absoluteCursor) + frameCount);
if (c89atomic_load_32(&pDataStream->seekCounter) == 0) {
if (c89atomic_load_64(&pDataStream->absoluteCursor) == frameIndex) {
if (ma_atomic_load_32(&pDataStream->seekCounter) == 0) {
if (ma_atomic_load_64(&pDataStream->absoluteCursor) == frameIndex) {
c89atomic_exchange_32(&pDataStream->isPageValid[0], MA_FALSE);
c89atomic_exchange_32(&pDataStream->isPageValid[1], MA_FALSE);
ma_atomic_exchange_32(&pDataStream->isPageValid[0], MA_FALSE);
ma_atomic_exchange_32(&pDataStream->isPageValid[1], MA_FALSE);
return c89atomic_load_32((ma_bool32*)&pDataStream->isLooping); /* Naughty const-cast. Value won't change from here in practice (maybe from another thread). */
return ma_atomic_load_32((ma_bool32*)&pDataStream->isLooping); /* Naughty const-cast. Value won't change from here in practice (maybe from another thread). */
if (c89atomic_load_32(&pDataStream->isPageValid[pageIndex0])) {
availableFrames += c89atomic_load_32(&pDataStream->pageFrameCount[pageIndex0]) - relativeCursor;
if (c89atomic_load_32(&pDataStream->isPageValid[pageIndex1])) {
availableFrames += c89atomic_load_32(&pDataStream->pageFrameCount[pageIndex1]);
if (ma_atomic_load_32(&pDataStream->isPageValid[pageIndex0])) {
availableFrames += ma_atomic_load_32(&pDataStream->pageFrameCount[pageIndex0]) - relativeCursor;
if (ma_atomic_load_32(&pDataStream->isPageValid[pageIndex1])) {
availableFrames += ma_atomic_load_32(&pDataStream->pageFrameCount[pageIndex1]);
c89atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1);
ma_atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1);
/* A busy result should be considered successful from the point of view of the job system. */
if (result == MA_BUSY) {
result = MA_SUCCESS;
}
sampleCount = frameCount * channels;
if (volume == 1) {
for (iSample = 0; iSample < sampleCount; iSample += 1) {
pDst[iSample] += pSrc[iSample];
}
} else {
for (iSample = 0; iSample < sampleCount; iSample += 1) {
pDst[iSample] += ma_apply_volume_unclipped_f32(pSrc[iSample], volume);
}
}
return MA_SUCCESS;
}
ma_node_output_bus* pOldPrev = (ma_node_output_bus*)c89atomic_load_ptr(&pOutputBus->pPrev);
ma_node_output_bus* pOldNext = (ma_node_output_bus*)c89atomic_load_ptr(&pOutputBus->pNext);
ma_node_output_bus* pOldPrev = (ma_node_output_bus*)ma_atomic_load_ptr(&pOutputBus->pPrev);
ma_node_output_bus* pOldNext = (ma_node_output_bus*)ma_atomic_load_ptr(&pOutputBus->pNext);
c89atomic_exchange_ptr(&pOldPrev->pNext, pOldNext); /* <-- This is where the output bus is detached from the list. */
ma_atomic_exchange_ptr(&pOldPrev->pNext, pOldNext); /* <-- This is where the output bus is detached from the list. */
c89atomic_exchange_ptr(&pOutputBus->pNext, NULL); /* Using atomic exchanges here, mainly for the benefit of analysis tools which don't always recognize spinlocks. */
c89atomic_exchange_ptr(&pOutputBus->pPrev, NULL); /* As above. */
ma_atomic_exchange_ptr(&pOutputBus->pNext, NULL); /* Using atomic exchanges here, mainly for the benefit of analysis tools which don't always recognize spinlocks. */
ma_atomic_exchange_ptr(&pOutputBus->pPrev, NULL); /* As above. */
c89atomic_exchange_ptr(&pInputBus->head.pNext, pOutputBus); /* <-- This is where the output bus is actually attached to the input bus. */
ma_atomic_exchange_ptr(&pInputBus->head.pNext, pOutputBus); /* <-- This is where the output bus is actually attached to the input bus. */
if (pConfig->vtable->inputBusCount != 1 || pConfig->vtable->outputBusCount != 1) {
return MA_INVALID_ARGS; /* Passthrough nodes must have exactly 1 input bus and 1 output bus. */
if ((pConfig->vtable->inputBusCount != 0 && pConfig->vtable->inputBusCount != 1) || pConfig->vtable->outputBusCount != 1) {
return MA_INVALID_ARGS; /* Passthrough nodes must have exactly 1 output bus and either 0 or 1 input bus. */
for (pOutputBus = (ma_node_output_bus*)c89atomic_load_ptr(&pInputBus->head.pNext); pOutputBus != NULL; pOutputBus = (ma_node_output_bus*)c89atomic_load_ptr(&pOutputBus->pNext)) {
for (pOutputBus = (ma_node_output_bus*)ma_atomic_load_ptr(&pInputBus->head.pNext); pOutputBus != NULL; pOutputBus = (ma_node_output_bus*)ma_atomic_load_ptr(&pOutputBus->pNext)) {
/*
If it's a passthrough we won't be expecting the callback to output anything, so we'll
need to pre-silence the output buffer.
*/
if ((pNodeBase->vtable->flags & MA_NODE_FLAG_PASSTHROUGH) != 0) {
ma_silence_pcm_frames(pFramesOut, frameCount, ma_format_f32, ma_node_get_output_channels(pNode, outputBusIndex));
}
NULL, /* onGetRequiredInputFrameCount */
1, /* 1 input bus. */
2, /* 2 output buses. */
NULL, /* onGetRequiredInputFrameCount */
1, /* 1 input bus. */
MA_NODE_BUS_COUNT_UNKNOWN, /* The output bus count is specified on a per-node basis. */
/* Fire any callbacks or events. */
if (atEnd) {
if (pSound->endCallback != NULL) {
pSound->endCallback(pSound->pEndCallbackUserData, pSound);
}
}
}
static ma_bool32 ma_sound_get_at_end(const ma_sound* pSound)
{
MA_ASSERT(pSound != NULL);
return ma_atomic_load_32(&pSound->atEnd);
}
static ma_result ma_engine_node_set_volume(ma_engine_node* pEngineNode, float volume)
{
if (pEngineNode == NULL) {
return MA_INVALID_ARGS;
}
ma_atomic_float_set(&pEngineNode->volume, volume);
/* If we're not smoothing we should bypass the volume gainer entirely. */
if (pEngineNode->volumeSmoothTimeInPCMFrames == 0) {
/* We should always have an active spatializer because it can be enabled and disabled dynamically. We can just use that for hodling our volume. */
ma_spatializer_set_master_volume(&pEngineNode->spatializer, volume);
} else {
/* We're using volume smoothing, so apply the master volume to the gainer. */
ma_gainer_set_gain(&pEngineNode->volumeGainer, volume);
}
return MA_SUCCESS;
}
static ma_result ma_engine_node_get_volume(const ma_engine_node* pEngineNode, float* pVolume)
{
if (pVolume == NULL) {
return MA_INVALID_ARGS;
}
*pVolume = 0.0f;
if (pEngineNode == NULL) {
return MA_INVALID_ARGS;
}
*pVolume = ma_atomic_float_get((ma_atomic_float*)&pEngineNode->volume);
return MA_SUCCESS;
}
isPitchingEnabled = ma_engine_node_is_pitching_enabled(pEngineNode);
isFadingEnabled = pEngineNode->fader.volumeBeg != 1 || pEngineNode->fader.volumeEnd != 1;
isSpatializationEnabled = ma_engine_node_is_spatialization_enabled(pEngineNode);
isPanningEnabled = pEngineNode->panner.pan != 0 && channelsOut != 1;
/* Update the fader if applicable. */
{
ma_uint64 fadeLengthInFrames = ma_atomic_uint64_get(&pEngineNode->fadeSettings.fadeLengthInFrames);
if (fadeLengthInFrames != ~(ma_uint64)0) {
float fadeVolumeBeg = ma_atomic_float_get(&pEngineNode->fadeSettings.volumeBeg);
float fadeVolumeEnd = ma_atomic_float_get(&pEngineNode->fadeSettings.volumeEnd);
ma_int64 fadeStartOffsetInFrames = (ma_int64)ma_atomic_uint64_get(&pEngineNode->fadeSettings.absoluteGlobalTimeInFrames);
if (fadeStartOffsetInFrames == (ma_int64)(~(ma_uint64)0)) {
fadeStartOffsetInFrames = 0;
} else {
fadeStartOffsetInFrames -= ma_engine_get_time(pEngineNode->pEngine);
}
ma_fader_set_fade_ex(&pEngineNode->fader, fadeVolumeBeg, fadeVolumeEnd, fadeLengthInFrames, fadeStartOffsetInFrames);
/* Reset the fade length so we don't erroneously apply it again. */
ma_atomic_uint64_set(&pEngineNode->fadeSettings.fadeLengthInFrames, ~(ma_uint64)0);
}
}
isPitchingEnabled = ma_engine_node_is_pitching_enabled(pEngineNode);
isFadingEnabled = pEngineNode->fader.volumeBeg != 1 || pEngineNode->fader.volumeEnd != 1;
isSpatializationEnabled = ma_engine_node_is_spatialization_enabled(pEngineNode);
isPanningEnabled = pEngineNode->panner.pan != 0 && channelsOut != 1;
isVolumeSmoothingEnabled = pEngineNode->volumeSmoothTimeInPCMFrames > 0;
Note that we're always running the resampler. If we try to be clever and skip resampling
when the pitch is 1, we'll get a glitch when we move away from 1, back to 1, and then
away from 1 again. We'll want to implement any pitch=1 optimizations in the resampler
itself.
Note that we're always running the resampler if pitching is enabled, even when the pitch
is 1. If we try to be clever and skip resampling when the pitch is 1, we'll get a glitch
when we move away from 1, back to 1, and then away from 1 again. We'll want to implement
any pitch=1 optimizations in the resampler itself.
isWorkingBufferValid = MA_TRUE;
}
}
/*
If we're using smoothing, we won't be applying volume via the spatializer, but instead from a ma_gainer. In this case
we'll want to apply our volume now.
*/
if (isVolumeSmoothingEnabled) {
if (isWorkingBufferValid) {
ma_gainer_process_pcm_frames(&pEngineNode->volumeGainer, pWorkingBuffer, pWorkingBuffer, framesJustProcessedOut);
} else {
ma_gainer_process_pcm_frames(&pEngineNode->volumeGainer, pWorkingBuffer, pRunningFramesIn, framesJustProcessedOut);
iListener = ma_engine_find_closest_listener(pEngineNode->pEngine, pEngineNode->spatializer.position.x, pEngineNode->spatializer.position.y, pEngineNode->spatializer.position.z);
ma_vec3f spatializerPosition = ma_spatializer_get_position(&pEngineNode->spatializer);
iListener = ma_engine_find_closest_listener(pEngineNode->pEngine, spatializerPosition.x, spatializerPosition.y, spatializerPosition.z);
/* No spatialization, but we still need to do channel conversion. */
/* No spatialization, but we still need to do channel conversion and master volume. */
float volume;
ma_engine_node_get_volume(pEngineNode, &volume); /* Should never fail. */
ma_copy_pcm_frames(pRunningFramesOut, pWorkingBuffer, framesJustProcessedOut, ma_format_f32, channelsOut);
if (isVolumeSmoothingEnabled) {
/* Volume has already been applied. Just copy straight to the output buffer. */
ma_copy_pcm_frames(pRunningFramesOut, pWorkingBuffer, framesJustProcessedOut * channelsOut, ma_format_f32, channelsOut);
} else {
/* Volume has not been applied yet. Copy and apply volume in the same pass. */
ma_copy_and_apply_volume_factor_f32(pRunningFramesOut, pWorkingBuffer, framesJustProcessedOut * channelsOut, volume);
}
ma_channel_map_apply_f32(pRunningFramesOut, NULL, channelsOut, pWorkingBuffer, NULL, channelsIn, framesJustProcessedOut, ma_channel_mix_mode_simple, pEngineNode->pEngine->monoExpansionMode);
ma_channel_map_apply_f32(pRunningFramesOut, NULL, channelsOut, pWorkingBuffer, NULL, channelsIn, framesJustProcessedOut, ma_channel_mix_mode_simple, pEngineNode->monoExpansionMode);
/* If we're using smoothing, the volume will have already been applied. */
if (!isVolumeSmoothingEnabled) {
ma_apply_volume_factor_f32(pRunningFramesOut, framesJustProcessedOut * channelsOut, volume);
}
/* Gainer. Will not be used if we are not using smoothing. */
if (pConfig->volumeSmoothTimeInPCMFrames > 0) {
gainerConfig = ma_gainer_config_init(channelsIn, pConfig->volumeSmoothTimeInPCMFrames);
result = ma_gainer_get_heap_size(&gainerConfig, &tempHeapSize);
if (result != MA_SUCCESS) {
return result;
}
pHeapLayout->gainerOffset = pHeapLayout->sizeInBytes;
pHeapLayout->sizeInBytes += ma_align_64(tempHeapSize);
}
pEngineNode->pEngine = pConfig->pEngine;
pEngineNode->sampleRate = (pConfig->sampleRate > 0) ? pConfig->sampleRate : ma_engine_get_sample_rate(pEngineNode->pEngine);
pEngineNode->pitch = 1;
pEngineNode->oldPitch = 1;
pEngineNode->oldDopplerPitch = 1;
pEngineNode->isPitchDisabled = pConfig->isPitchDisabled;
pEngineNode->isSpatializationDisabled = pConfig->isSpatializationDisabled;
pEngineNode->pinnedListenerIndex = pConfig->pinnedListenerIndex;
pEngineNode->pEngine = pConfig->pEngine;
pEngineNode->sampleRate = (pConfig->sampleRate > 0) ? pConfig->sampleRate : ma_engine_get_sample_rate(pEngineNode->pEngine);
pEngineNode->volumeSmoothTimeInPCMFrames = pConfig->volumeSmoothTimeInPCMFrames;
pEngineNode->monoExpansionMode = pConfig->monoExpansionMode;
ma_atomic_float_set(&pEngineNode->volume, 1);
pEngineNode->pitch = 1;
pEngineNode->oldPitch = 1;
pEngineNode->oldDopplerPitch = 1;
pEngineNode->isPitchDisabled = pConfig->isPitchDisabled;
pEngineNode->isSpatializationDisabled = pConfig->isSpatializationDisabled;
pEngineNode->pinnedListenerIndex = pConfig->pinnedListenerIndex;
ma_atomic_float_set(&pEngineNode->fadeSettings.volumeBeg, 1);
ma_atomic_float_set(&pEngineNode->fadeSettings.volumeEnd, 1);
ma_atomic_uint64_set(&pEngineNode->fadeSettings.fadeLengthInFrames, (~(ma_uint64)0));
ma_atomic_uint64_set(&pEngineNode->fadeSettings.absoluteGlobalTimeInFrames, (~(ma_uint64)0)); /* <-- Indicates that the fade should start immediately. */
/*
If the sample rate of the sound is different to the engine, make sure pitching is enabled so that the resampler
is activated. Not doing this will result in the sound not being resampled if MA_SOUND_FLAG_NO_PITCH is used.
*/
if (pEngineNode->sampleRate != ma_engine_get_sample_rate(pEngineNode->pEngine)) {
pEngineNode->isPitchDisabled = MA_FALSE;
}
}
/* We'll need a gainer for smoothing out volume changes if we have a non-zero smooth time. We apply this before converting to the output channel count. */
if (pConfig->volumeSmoothTimeInPCMFrames > 0) {
gainerConfig = ma_gainer_config_init(channelsIn, pConfig->volumeSmoothTimeInPCMFrames);
result = ma_gainer_init_preallocated(&gainerConfig, ma_offset_ptr(pHeap, heapLayout.gainerOffset), &pEngineNode->volumeGainer);
if (result != MA_SUCCESS) {
goto error3;
}
return ma_node_graph_read_pcm_frames(&pEngine->nodeGraph, pFramesOut, frameCount, pFramesRead);
ma_result result;
ma_uint64 framesRead = 0;
if (pFramesRead != NULL) {
*pFramesRead = 0;
}
result = ma_node_graph_read_pcm_frames(&pEngine->nodeGraph, pFramesOut, frameCount, &framesRead);
if (result != MA_SUCCESS) {
return result;
}
if (pFramesRead != NULL) {
*pFramesRead = framesRead;
}
if (pEngine->onProcess) {
pEngine->onProcess(pEngine->pProcessUserData, (float*)pFramesOut, framesRead); /* Safe cast to float* because the engine always works on floating point samples. */
}
return MA_SUCCESS;
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime)
MA_API ma_uint64 ma_engine_get_time_in_milliseconds(const ma_engine* pEngine)
{
return ma_engine_get_time_in_pcm_frames(pEngine) * 1000 / ma_engine_get_sample_rate(pEngine);
}
MA_API ma_result ma_engine_set_time_in_pcm_frames(ma_engine* pEngine, ma_uint64 globalTime)
}
MA_API ma_result ma_engine_set_time_in_milliseconds(ma_engine* pEngine, ma_uint64 globalTime)
{
return ma_engine_set_time_in_pcm_frames(pEngine, globalTime * ma_engine_get_sample_rate(pEngine) / 1000);
}
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine)
{
return ma_engine_get_time_in_pcm_frames(pEngine);
return ma_node_set_output_bus_volume(ma_node_graph_get_endpoint(&pEngine->nodeGraph), 0, ma_volume_db_to_linear(gainDB));
MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB)
{
return ma_engine_set_volume(pEngine, ma_volume_db_to_linear(gainDB));
float len2 = ma_vec3f_len2(ma_vec3f_sub(pEngine->listeners[iListener].position, ma_vec3f_init_3f(absolutePosX, absolutePosY, absolutePosZ)));
float len2 = ma_vec3f_len2(ma_vec3f_sub(ma_spatializer_listener_get_position(&pEngine->listeners[iListener]), ma_vec3f_init_3f(absolutePosX, absolutePosY, absolutePosZ)));
engineNodeConfig.channelsIn = pConfig->channelsIn;
engineNodeConfig.channelsOut = pConfig->channelsOut;
engineNodeConfig.channelsIn = pConfig->channelsIn;
engineNodeConfig.channelsOut = pConfig->channelsOut;
engineNodeConfig.volumeSmoothTimeInPCMFrames = pConfig->volumeSmoothTimeInPCMFrames;
engineNodeConfig.monoExpansionMode = pConfig->monoExpansionMode;
if (engineNodeConfig.volumeSmoothTimeInPCMFrames == 0) {
engineNodeConfig.volumeSmoothTimeInPCMFrames = pEngine->defaultVolumeSmoothTimeInPCMFrames;
}
notifications = ma_resource_manager_pipeline_notifications_init();
notifications.done.pFence = pConfig->pDoneFence;
/* Removed in 0.12. Set pDoneFence on the notifications. */
notifications = pConfig->initNotifications;
if (pConfig->pDoneFence != NULL && notifications.done.pFence == NULL) {
notifications.done.pFence = pConfig->pDoneFence;
}
config = ma_sound_config_init();
config.pDataSource = pSound->pResourceManagerDataSource;
config.flags = flags;
config.pInitialAttachment = pGroup;
config = ma_sound_config_init_2(pEngine);
config.pDataSource = pSound->pResourceManagerDataSource;
config.flags = flags;
config.pInitialAttachment = pGroup;
config.monoExpansionMode = pExistingSound->engineNode.monoExpansionMode;
config.volumeSmoothTimeInPCMFrames = pExistingSound->engineNode.volumeSmoothTimeInPCMFrames;
return MA_SUCCESS;
}
MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames)
{
if (pSound == NULL) {
return MA_INVALID_ARGS;
}
/* Stopping with a fade out requires us to schedule the stop into the future by the fade length. */
ma_sound_set_stop_time_with_fade_in_pcm_frames(pSound, ma_engine_get_time(ma_sound_get_engine(pSound)) + fadeLengthInFrames, fadeLengthInFrames);
MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInMilliseconds)
{
ma_uint64 sampleRate;
if (pSound == NULL) {
return MA_INVALID_ARGS;
}
sampleRate = ma_engine_get_sample_rate(ma_sound_get_engine(pSound));
return ma_sound_stop_with_fade_in_pcm_frames(pSound, (fadeLengthInMilliseconds * sampleRate) / 1000);
}
c89atomic_exchange_explicit_32(&pSound->engineNode.isSpatializationDisabled, !enabled, c89atomic_memory_order_release);
ma_atomic_exchange_explicit_32(&pSound->engineNode.isSpatializationDisabled, !enabled, ma_atomic_memory_order_release);
c89atomic_exchange_explicit_32(&pSound->engineNode.pinnedListenerIndex, listenerIndex, c89atomic_memory_order_release);
ma_atomic_exchange_explicit_32(&pSound->engineNode.pinnedListenerIndex, listenerIndex, ma_atomic_memory_order_release);
MA_API float ma_sound_get_current_fade_volume(ma_sound* pSound)
MA_API void ma_sound_set_fade_start_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames, ma_uint64 absoluteGlobalTimeInFrames)
{
if (pSound == NULL) {
return;
}
/*
We don't want to update the fader at this point because we need to use the engine's current time
to derive the fader's start offset. The timer is being updated on the audio thread so in order to
do this as accurately as possible we'll need to defer this to the audio thread.
*/
ma_atomic_float_set(&pSound->engineNode.fadeSettings.volumeBeg, volumeBeg);
ma_atomic_float_set(&pSound->engineNode.fadeSettings.volumeEnd, volumeEnd);
ma_atomic_uint64_set(&pSound->engineNode.fadeSettings.fadeLengthInFrames, fadeLengthInFrames);
ma_atomic_uint64_set(&pSound->engineNode.fadeSettings.absoluteGlobalTimeInFrames, absoluteGlobalTimeInFrames);
}
MA_API void ma_sound_set_fade_start_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds, ma_uint64 absoluteGlobalTimeInMilliseconds)
{
ma_uint32 sampleRate;
if (pSound == NULL) {
return;
}
sampleRate = ma_engine_get_sample_rate(ma_sound_get_engine(pSound));
ma_sound_set_fade_start_in_pcm_frames(pSound, volumeBeg, volumeEnd, (fadeLengthInMilliseconds * sampleRate) / 1000, (absoluteGlobalTimeInMilliseconds * sampleRate) / 1000);
}
MA_API float ma_sound_get_current_fade_volume(const ma_sound* pSound)
MA_API void ma_sound_set_stop_time_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInFrames, ma_uint64 fadeLengthInFrames)
{
if (pSound == NULL) {
return;
}
if (fadeLengthInFrames > 0) {
if (fadeLengthInFrames > stopAbsoluteGlobalTimeInFrames) {
fadeLengthInFrames = stopAbsoluteGlobalTimeInFrames;
}
ma_sound_set_fade_start_in_pcm_frames(pSound, -1, 0, fadeLengthInFrames, stopAbsoluteGlobalTimeInFrames - fadeLengthInFrames);
}
ma_node_set_state_time(pSound, ma_node_state_stopped, stopAbsoluteGlobalTimeInFrames);
}
MA_API void ma_sound_set_stop_time_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInMilliseconds, ma_uint64 fadeLengthInMilliseconds)
{
ma_uint32 sampleRate;
if (pSound == NULL) {
return;
}
sampleRate = ma_engine_get_sample_rate(ma_sound_get_engine(pSound));
ma_sound_set_stop_time_with_fade_in_pcm_frames(pSound, (stopAbsoluteGlobalTimeInMilliseconds * sampleRate) / 1000, (fadeLengthInMilliseconds * sampleRate) / 1000);
}
return ma_node_get_state_by_time(pSound, ma_engine_get_time(ma_sound_get_engine(pSound))) == ma_node_state_started;
return ma_node_get_state_by_time(pSound, ma_engine_get_time_in_pcm_frames(ma_sound_get_engine(pSound))) == ma_node_state_started;
All code below is auto-generated from a tool. This mostly consists of decoding backend implementations such as dr_wav, dr_flac, etc. If you find a bug in the
All code below is auto-generated from a tool. This mostly consists of decoding backend implementations such as ma_dr_wav, ma_dr_flac, etc. If you find a bug in the
#if !defined(DR_WAV_IMPLEMENTATION) && !defined(DRWAV_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#if !defined(MA_DR_WAV_IMPLEMENTATION) && !defined(MA_DR_WAV_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#define drwav_countof(x) (sizeof(x) / sizeof(x[0]))
#define drwav_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
#define drwav_min(a, b) (((a) < (b)) ? (a) : (b))
#define drwav_max(a, b) (((a) > (b)) ? (a) : (b))
#define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x))))
#define drwav_offset_ptr(p, offset) (((drwav_uint8*)(p)) + (offset))
#define DRWAV_MAX_SIMD_VECTOR_SIZE 64
#if defined(__x86_64__) || defined(_M_X64)
#define DRWAV_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRWAV_X86
#elif defined(__arm__) || defined(_M_ARM)
#define DRWAV_ARM
#endif
#ifdef _MSC_VER
#define DRWAV_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRWAV_GNUC_INLINE_HINT __inline__
#else
#define DRWAV_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRWAV_INLINE DRWAV_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRWAV_INLINE DRWAV_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRWAV_INLINE __inline
#else
#define DRWAV_INLINE
#endif
#if defined(SIZE_MAX)
#define DRWAV_SIZE_MAX SIZE_MAX
#else
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
#define DRWAV_SIZE_MAX ((drwav_uint64)0xFFFFFFFFFFFFFFFF)
#else
#define DRWAV_SIZE_MAX 0xFFFFFFFF
#endif
#endif
#define ma_dr_wav_countof(x) (sizeof(x) / sizeof(x[0]))
#define ma_dr_wav_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
#define ma_dr_wav_min(a, b) (((a) < (b)) ? (a) : (b))
#define ma_dr_wav_max(a, b) (((a) > (b)) ? (a) : (b))
#define ma_dr_wav_clamp(x, lo, hi) (ma_dr_wav_max((lo), ma_dr_wav_min((hi), (x))))
#define ma_dr_wav_offset_ptr(p, offset) (((ma_uint8*)(p)) + (offset))
#define MA_DR_WAV_MAX_SIMD_VECTOR_SIZE 32
#define MA_DR_WAV_INT64_MIN ((ma_int64)0x80000000 << 32)
#define MA_DR_WAV_INT64_MAX ((((ma_int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
#define DRWAV_HAS_BYTESWAP16_INTRINSIC
#define DRWAV_HAS_BYTESWAP32_INTRINSIC
#define DRWAV_HAS_BYTESWAP64_INTRINSIC
#define MA_DR_WAV_HAS_BYTESWAP16_INTRINSIC
#define MA_DR_WAV_HAS_BYTESWAP32_INTRINSIC
#define MA_DR_WAV_HAS_BYTESWAP64_INTRINSIC
static const drwav_uint8 drwavGUID_W64_RIFF[16] = {0x72,0x69,0x66,0x66, 0x2E,0x91, 0xCF,0x11, 0xA5,0xD6, 0x28,0xDB,0x04,0xC1,0x00,0x00};
static const drwav_uint8 drwavGUID_W64_WAVE[16] = {0x77,0x61,0x76,0x65, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const drwav_uint8 drwavGUID_W64_FMT [16] = {0x66,0x6D,0x74,0x20, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const drwav_uint8 drwavGUID_W64_FACT[16] = {0x66,0x61,0x63,0x74, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const drwav_uint8 drwavGUID_W64_DATA[16] = {0x64,0x61,0x74,0x61, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static DRWAV_INLINE int drwav__is_little_endian(void)
static const ma_uint8 ma_dr_wavGUID_W64_RIFF[16] = {0x72,0x69,0x66,0x66, 0x2E,0x91, 0xCF,0x11, 0xA5,0xD6, 0x28,0xDB,0x04,0xC1,0x00,0x00};
static const ma_uint8 ma_dr_wavGUID_W64_WAVE[16] = {0x77,0x61,0x76,0x65, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const ma_uint8 ma_dr_wavGUID_W64_FMT [16] = {0x66,0x6D,0x74,0x20, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const ma_uint8 ma_dr_wavGUID_W64_FACT[16] = {0x66,0x61,0x63,0x74, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static const ma_uint8 ma_dr_wavGUID_W64_DATA[16] = {0x64,0x61,0x74,0x61, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};
static MA_INLINE int ma_dr_wav__is_little_endian(void)
return ((n & ((drwav_uint64)0xFF000000 << 32)) >> 56) |
((n & ((drwav_uint64)0x00FF0000 << 32)) >> 40) |
((n & ((drwav_uint64)0x0000FF00 << 32)) >> 24) |
((n & ((drwav_uint64)0x000000FF << 32)) >> 8) |
((n & ((drwav_uint64)0xFF000000 )) << 8) |
((n & ((drwav_uint64)0x00FF0000 )) << 24) |
((n & ((drwav_uint64)0x0000FF00 )) << 40) |
((n & ((drwav_uint64)0x000000FF )) << 56);
return ((n & ((ma_uint64)0xFF000000 << 32)) >> 56) |
((n & ((ma_uint64)0x00FF0000 << 32)) >> 40) |
((n & ((ma_uint64)0x0000FF00 << 32)) >> 24) |
((n & ((ma_uint64)0x000000FF << 32)) >> 8) |
((n & ((ma_uint64)0xFF000000 )) << 8) |
((n & ((ma_uint64)0x00FF0000 )) << 24) |
((n & ((ma_uint64)0x0000FF00 )) << 40) |
((n & ((ma_uint64)0x000000FF )) << 56);
static DRWAV_INLINE void drwav__bswap_samples_ieee(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
MA_PRIVATE MA_INLINE ma_uint16 ma_dr_wav_bytes_to_u16_le(const ma_uint8* data)
{
return ((ma_uint16)data[0] << 0) | ((ma_uint16)data[1] << 8);
}
MA_PRIVATE MA_INLINE ma_uint16 ma_dr_wav_bytes_to_u16_be(const ma_uint8* data)
switch (bytesPerSample)
{
#if 0
case 2:
{
drwav__bswap_samples_f16((drwav_float16*)pSamples, sampleCount);
} break;
#endif
case 4:
{
drwav__bswap_samples_f32((float*)pSamples, sampleCount);
} break;
case 8:
{
drwav__bswap_samples_f64((double*)pSamples, sampleCount);
} break;
default:
{
DRWAV_ASSERT(DRWAV_FALSE);
} break;
return ((ma_uint16)data[1] << 0) | ((ma_uint16)data[0] << 8);
}
MA_PRIVATE MA_INLINE ma_uint16 ma_dr_wav_bytes_to_u16_ex(const ma_uint8* data, ma_dr_wav_container container)
{
if (ma_dr_wav_is_container_be(container)) {
return ma_dr_wav_bytes_to_u16_be(data);
} else {
return ma_dr_wav_bytes_to_u16_le(data);
static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample, drwav_uint16 format)
MA_PRIVATE MA_INLINE ma_uint32 ma_dr_wav_bytes_to_u32_le(const ma_uint8* data)
{
return ((ma_uint32)data[0] << 0) | ((ma_uint32)data[1] << 8) | ((ma_uint32)data[2] << 16) | ((ma_uint32)data[3] << 24);
}
MA_PRIVATE MA_INLINE ma_uint32 ma_dr_wav_bytes_to_u32_be(const ma_uint8* data)
{
return ((ma_uint32)data[3] << 0) | ((ma_uint32)data[2] << 8) | ((ma_uint32)data[1] << 16) | ((ma_uint32)data[0] << 24);
}
MA_PRIVATE MA_INLINE ma_uint32 ma_dr_wav_bytes_to_u32_ex(const ma_uint8* data, ma_dr_wav_container container)
{
if (ma_dr_wav_is_container_be(container)) {
return ma_dr_wav_bytes_to_u32_be(data);
} else {
return ma_dr_wav_bytes_to_u32_le(data);
}
}
MA_PRIVATE ma_int64 ma_dr_wav_aiff_extented_to_s64(const ma_uint8* data)
switch (format)
{
case DR_WAVE_FORMAT_PCM:
{
drwav__bswap_samples_pcm(pSamples, sampleCount, bytesPerSample);
} break;
case DR_WAVE_FORMAT_IEEE_FLOAT:
{
drwav__bswap_samples_ieee(pSamples, sampleCount, bytesPerSample);
} break;
case DR_WAVE_FORMAT_ALAW:
case DR_WAVE_FORMAT_MULAW:
{
drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
} break;
case DR_WAVE_FORMAT_ADPCM:
case DR_WAVE_FORMAT_DVI_ADPCM:
default:
{
DRWAV_ASSERT(DRWAV_FALSE);
} break;
ma_uint32 exponent = ((ma_uint32)data[0] << 8) | data[1];
ma_uint64 hi = ((ma_uint64)data[2] << 24) | ((ma_uint64)data[3] << 16) | ((ma_uint64)data[4] << 8) | ((ma_uint64)data[5] << 0);
ma_uint64 lo = ((ma_uint64)data[6] << 24) | ((ma_uint64)data[7] << 16) | ((ma_uint64)data[8] << 8) | ((ma_uint64)data[9] << 0);
ma_uint64 significand = (hi << 32) | lo;
int sign = exponent >> 15;
exponent &= 0x7FFF;
if (exponent == 0 && significand == 0) {
return 0;
} else if (exponent == 0x7FFF) {
return sign ? MA_DR_WAV_INT64_MIN : MA_DR_WAV_INT64_MAX;
}
exponent -= 16383;
if (exponent > 63) {
return sign ? MA_DR_WAV_INT64_MIN : MA_DR_WAV_INT64_MAX;
} else if (exponent < 1) {
return 0;
}
significand >>= (63 - exponent);
if (sign) {
return -(ma_int64)significand;
} else {
return (ma_int64)significand;
DRWAV_PRIVATE void* drwav__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE void* ma_dr_wav__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_PRIVATE drwav_allocation_callbacks drwav_copy_allocation_callbacks_or_defaults(const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_allocation_callbacks ma_dr_wav_copy_allocation_callbacks_or_defaults(const ma_allocation_callbacks* pAllocationCallbacks)
allocationCallbacks.onMalloc = drwav__malloc_default;
allocationCallbacks.onRealloc = drwav__realloc_default;
allocationCallbacks.onFree = drwav__free_default;
allocationCallbacks.onMalloc = ma_dr_wav__malloc_default;
allocationCallbacks.onRealloc = ma_dr_wav__realloc_default;
allocationCallbacks.onFree = ma_dr_wav__free_default;
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_uint64 samplesToRead, ma_int16* pBufferOut);
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint64 samplesToRead, ma_int16* pBufferOut);
MA_PRIVATE ma_bool32 ma_dr_wav_init_write__internal(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount);
MA_PRIVATE ma_result ma_dr_wav__read_chunk_header(ma_dr_wav_read_proc onRead, void* pUserData, ma_dr_wav_container container, ma_uint64* pRunningBytesReadOut, ma_dr_wav_chunk_header* pHeaderOut)
if (container == drwav_container_riff || container == drwav_container_rf64) {
drwav_uint8 sizeInBytes[4];
if (container == ma_dr_wav_container_riff || container == ma_dr_wav_container_rifx || container == ma_dr_wav_container_rf64 || container == ma_dr_wav_container_aiff) {
ma_uint8 sizeInBytes[4];
pHeaderOut->sizeInBytes = drwav_bytes_to_u32(sizeInBytes);
pHeaderOut->paddingSize = drwav__chunk_padding_size_riff(pHeaderOut->sizeInBytes);
pHeaderOut->sizeInBytes = ma_dr_wav_bytes_to_u32_ex(sizeInBytes, container);
pHeaderOut->paddingSize = ma_dr_wav__chunk_padding_size_riff(pHeaderOut->sizeInBytes);
pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes) - 24;
pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
pHeaderOut->sizeInBytes = ma_dr_wav_bytes_to_u64(sizeInBytes) - 24;
pHeaderOut->paddingSize = ma_dr_wav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
DRWAV_PRIVATE drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_fmt* fmtOut)
MA_PRIVATE size_t ma_dr_wav__on_read(ma_dr_wav_read_proc onRead, void* pUserData, void* pBufferOut, size_t bytesToRead, ma_uint64* pCursor)
drwav_chunk_header header;
drwav_uint8 fmt[16];
if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
return DRWAV_FALSE;
}
while (((container == drwav_container_riff || container == drwav_container_rf64) && !drwav_fourcc_equal(header.id.fourcc, "fmt ")) || (container == drwav_container_w64 && !drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) {
return DRWAV_FALSE;
}
*pRunningBytesReadOut += header.sizeInBytes + header.paddingSize;
if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
return DRWAV_FALSE;
}
}
if (container == drwav_container_riff || container == drwav_container_rf64) {
if (!drwav_fourcc_equal(header.id.fourcc, "fmt ")) {
return DRWAV_FALSE;
}
} else {
if (!drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT)) {
return DRWAV_FALSE;
}
}
if (onRead(pUserData, fmt, sizeof(fmt)) != sizeof(fmt)) {
return DRWAV_FALSE;
}
*pRunningBytesReadOut += sizeof(fmt);
fmtOut->formatTag = drwav_bytes_to_u16(fmt + 0);
fmtOut->channels = drwav_bytes_to_u16(fmt + 2);
fmtOut->sampleRate = drwav_bytes_to_u32(fmt + 4);
fmtOut->avgBytesPerSec = drwav_bytes_to_u32(fmt + 8);
fmtOut->blockAlign = drwav_bytes_to_u16(fmt + 12);
fmtOut->bitsPerSample = drwav_bytes_to_u16(fmt + 14);
fmtOut->extendedSize = 0;
fmtOut->validBitsPerSample = 0;
fmtOut->channelMask = 0;
DRWAV_ZERO_MEMORY(fmtOut->subFormat, sizeof(fmtOut->subFormat));
if (header.sizeInBytes > 16) {
drwav_uint8 fmt_cbSize[2];
int bytesReadSoFar = 0;
if (onRead(pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) {
return DRWAV_FALSE;
}
*pRunningBytesReadOut += sizeof(fmt_cbSize);
bytesReadSoFar = 18;
fmtOut->extendedSize = drwav_bytes_to_u16(fmt_cbSize);
if (fmtOut->extendedSize > 0) {
if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
if (fmtOut->extendedSize != 22) {
return DRWAV_FALSE;
}
}
if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
drwav_uint8 fmtext[22];
if (onRead(pUserData, fmtext, fmtOut->extendedSize) != fmtOut->extendedSize) {
return DRWAV_FALSE;
}
fmtOut->validBitsPerSample = drwav_bytes_to_u16(fmtext + 0);
fmtOut->channelMask = drwav_bytes_to_u32(fmtext + 2);
drwav_bytes_to_guid(fmtext + 6, fmtOut->subFormat);
} else {
if (!onSeek(pUserData, fmtOut->extendedSize, drwav_seek_origin_current)) {
return DRWAV_FALSE;
}
}
*pRunningBytesReadOut += fmtOut->extendedSize;
bytesReadSoFar += fmtOut->extendedSize;
}
if (!onSeek(pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current)) {
return DRWAV_FALSE;
}
*pRunningBytesReadOut += (header.sizeInBytes - bytesReadSoFar);
}
if (header.paddingSize > 0) {
if (!onSeek(pUserData, header.paddingSize, drwav_seek_origin_current)) {
return DRWAV_FALSE;
}
*pRunningBytesReadOut += header.paddingSize;
}
return DRWAV_TRUE;
}
DRWAV_PRIVATE size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor)
{
DRWAV_PRIVATE drwav_bool32 drwav__on_seek(drwav_seek_proc onSeek, void* pUserData, int offset, drwav_seek_origin origin, drwav_uint64* pCursor)
MA_PRIVATE ma_bool32 ma_dr_wav__on_seek(ma_dr_wav_seek_proc onSeek, void* pUserData, int offset, ma_dr_wav_seek_origin origin, ma_uint64* pCursor)
#define DRWAV_SMPL_BYTES 36
#define DRWAV_SMPL_LOOP_BYTES 24
#define DRWAV_INST_BYTES 7
#define DRWAV_ACID_BYTES 24
#define DRWAV_CUE_BYTES 4
#define DRWAV_BEXT_BYTES 602
#define DRWAV_BEXT_DESCRIPTION_BYTES 256
#define DRWAV_BEXT_ORIGINATOR_NAME_BYTES 32
#define DRWAV_BEXT_ORIGINATOR_REF_BYTES 32
#define DRWAV_BEXT_RESERVED_BYTES 180
#define DRWAV_BEXT_UMID_BYTES 64
#define DRWAV_CUE_POINT_BYTES 24
#define DRWAV_LIST_LABEL_OR_NOTE_BYTES 4
#define DRWAV_LIST_LABELLED_TEXT_BYTES 20
#define DRWAV_METADATA_ALIGNMENT 8
#define MA_DR_WAV_SMPL_BYTES 36
#define MA_DR_WAV_SMPL_LOOP_BYTES 24
#define MA_DR_WAV_INST_BYTES 7
#define MA_DR_WAV_ACID_BYTES 24
#define MA_DR_WAV_CUE_BYTES 4
#define MA_DR_WAV_BEXT_BYTES 602
#define MA_DR_WAV_BEXT_DESCRIPTION_BYTES 256
#define MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES 32
#define MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES 32
#define MA_DR_WAV_BEXT_RESERVED_BYTES 180
#define MA_DR_WAV_BEXT_UMID_BYTES 64
#define MA_DR_WAV_CUE_POINT_BYTES 24
#define MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES 4
#define MA_DR_WAV_LIST_LABELLED_TEXT_BYTES 20
#define MA_DR_WAV_METADATA_ALIGNMENT 8
drwav__metadata_parser_stage stage;
drwav_metadata *pMetadata;
drwav_uint32 metadataCount;
drwav_uint8 *pData;
drwav_uint8 *pDataCursor;
drwav_uint64 metadataCursor;
drwav_uint64 extraCapacity;
} drwav__metadata_parser;
DRWAV_PRIVATE size_t drwav__metadata_memory_capacity(drwav__metadata_parser* pParser)
ma_dr_wav__metadata_parser_stage stage;
ma_dr_wav_metadata *pMetadata;
ma_uint32 metadataCount;
ma_uint8 *pData;
ma_uint8 *pDataCursor;
ma_uint64 metadataCursor;
ma_uint64 extraCapacity;
} ma_dr_wav__metadata_parser;
MA_PRIVATE size_t ma_dr_wav__metadata_memory_capacity(ma_dr_wav__metadata_parser* pParser)
drwav_uint64 cap = sizeof(drwav_metadata) * (drwav_uint64)pParser->metadataCount + pParser->extraCapacity;
if (cap > DRWAV_SIZE_MAX) {
ma_uint64 cap = sizeof(ma_dr_wav_metadata) * (ma_uint64)pParser->metadataCount + pParser->extraCapacity;
if (cap > MA_SIZE_MAX) {
DRWAV_PRIVATE void drwav__metadata_request_extra_memory_for_stage_2(drwav__metadata_parser* pParser, size_t bytes, size_t align)
MA_PRIVATE void ma_dr_wav__metadata_request_extra_memory_for_stage_2(ma_dr_wav__metadata_parser* pParser, size_t bytes, size_t align)
DRWAV_PRIVATE drwav_result drwav__metadata_alloc(drwav__metadata_parser* pParser, drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_result ma_dr_wav__metadata_alloc(ma_dr_wav__metadata_parser* pParser, ma_allocation_callbacks* pAllocationCallbacks)
pParser->pData = (drwav_uint8*)pAllocationCallbacks->onMalloc(drwav__metadata_memory_capacity(pParser), pAllocationCallbacks->pUserData);
pParser->pData = (ma_uint8*)pAllocationCallbacks->onMalloc(ma_dr_wav__metadata_memory_capacity(pParser), pAllocationCallbacks->pUserData);
pParser->pMetadata = (drwav_metadata*)drwav__metadata_get_memory(pParser, sizeof(drwav_metadata) * pParser->metadataCount, 1);
pParser->pMetadata = (ma_dr_wav_metadata*)ma_dr_wav__metadata_get_memory(pParser, sizeof(ma_dr_wav_metadata) * pParser->metadataCount, 1);
DRWAV_PRIVATE size_t drwav__metadata_parser_read(drwav__metadata_parser* pParser, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor)
MA_PRIVATE size_t ma_dr_wav__metadata_parser_read(ma_dr_wav__metadata_parser* pParser, void* pBufferOut, size_t bytesToRead, ma_uint64* pCursor)
DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata* pMetadata)
MA_PRIVATE ma_uint64 ma_dr_wav__read_smpl_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, const ma_dr_wav_chunk_header* pChunkHeader, ma_dr_wav_metadata* pMetadata)
drwav_uint8 smplHeaderData[DRWAV_SMPL_BYTES];
drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
DRWAV_ASSERT(pChunkHeader != NULL);
if (bytesJustRead == sizeof(smplHeaderData)) {
drwav_uint32 iSampleLoop;
pMetadata->type = drwav_metadata_type_smpl;
pMetadata->data.smpl.manufacturerId = drwav_bytes_to_u32(smplHeaderData + 0);
pMetadata->data.smpl.productId = drwav_bytes_to_u32(smplHeaderData + 4);
pMetadata->data.smpl.samplePeriodNanoseconds = drwav_bytes_to_u32(smplHeaderData + 8);
pMetadata->data.smpl.midiUnityNote = drwav_bytes_to_u32(smplHeaderData + 12);
pMetadata->data.smpl.midiPitchFraction = drwav_bytes_to_u32(smplHeaderData + 16);
pMetadata->data.smpl.smpteFormat = drwav_bytes_to_u32(smplHeaderData + 20);
pMetadata->data.smpl.smpteOffset = drwav_bytes_to_u32(smplHeaderData + 24);
pMetadata->data.smpl.sampleLoopCount = drwav_bytes_to_u32(smplHeaderData + 28);
pMetadata->data.smpl.samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(smplHeaderData + 32);
if (pMetadata->data.smpl.sampleLoopCount == (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES) {
pMetadata->data.smpl.pLoops = (drwav_smpl_loop*)drwav__metadata_get_memory(pParser, sizeof(drwav_smpl_loop) * pMetadata->data.smpl.sampleLoopCount, DRWAV_METADATA_ALIGNMENT);
ma_uint8 smplHeaderData[MA_DR_WAV_SMPL_BYTES];
ma_uint64 totalBytesRead = 0;
size_t bytesJustRead;
if (pMetadata == NULL) {
return 0;
}
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
MA_DR_WAV_ASSERT(pChunkHeader != NULL);
if (pMetadata != NULL && bytesJustRead == sizeof(smplHeaderData)) {
ma_uint32 iSampleLoop;
pMetadata->type = ma_dr_wav_metadata_type_smpl;
pMetadata->data.smpl.manufacturerId = ma_dr_wav_bytes_to_u32(smplHeaderData + 0);
pMetadata->data.smpl.productId = ma_dr_wav_bytes_to_u32(smplHeaderData + 4);
pMetadata->data.smpl.samplePeriodNanoseconds = ma_dr_wav_bytes_to_u32(smplHeaderData + 8);
pMetadata->data.smpl.midiUnityNote = ma_dr_wav_bytes_to_u32(smplHeaderData + 12);
pMetadata->data.smpl.midiPitchFraction = ma_dr_wav_bytes_to_u32(smplHeaderData + 16);
pMetadata->data.smpl.smpteFormat = ma_dr_wav_bytes_to_u32(smplHeaderData + 20);
pMetadata->data.smpl.smpteOffset = ma_dr_wav_bytes_to_u32(smplHeaderData + 24);
pMetadata->data.smpl.sampleLoopCount = ma_dr_wav_bytes_to_u32(smplHeaderData + 28);
pMetadata->data.smpl.samplerSpecificDataSizeInBytes = ma_dr_wav_bytes_to_u32(smplHeaderData + 32);
if (pMetadata->data.smpl.sampleLoopCount == (pChunkHeader->sizeInBytes - MA_DR_WAV_SMPL_BYTES) / MA_DR_WAV_SMPL_LOOP_BYTES) {
pMetadata->data.smpl.pLoops = (ma_dr_wav_smpl_loop*)ma_dr_wav__metadata_get_memory(pParser, sizeof(ma_dr_wav_smpl_loop) * pMetadata->data.smpl.sampleLoopCount, MA_DR_WAV_METADATA_ALIGNMENT);
drwav_uint8 smplLoopData[DRWAV_SMPL_LOOP_BYTES];
bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);
ma_uint8 smplLoopData[MA_DR_WAV_SMPL_LOOP_BYTES];
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);
pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0);
pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4);
pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 8);
pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 12);
pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16);
pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20);
pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = ma_dr_wav_bytes_to_u32(smplLoopData + 0);
pMetadata->data.smpl.pLoops[iSampleLoop].type = ma_dr_wav_bytes_to_u32(smplLoopData + 4);
pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 8);
pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 12);
pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = ma_dr_wav_bytes_to_u32(smplLoopData + 16);
pMetadata->data.smpl.pLoops[iSampleLoop].playCount = ma_dr_wav_bytes_to_u32(smplLoopData + 20);
pMetadata->data.smpl.pSamplerSpecificData = drwav__metadata_get_memory(pParser, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, 1);
DRWAV_ASSERT(pMetadata->data.smpl.pSamplerSpecificData != NULL);
drwav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
pMetadata->data.smpl.pSamplerSpecificData = ma_dr_wav__metadata_get_memory(pParser, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, 1);
MA_DR_WAV_ASSERT(pMetadata->data.smpl.pSamplerSpecificData != NULL);
ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata* pMetadata)
MA_PRIVATE ma_uint64 ma_dr_wav__read_cue_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, const ma_dr_wav_chunk_header* pChunkHeader, ma_dr_wav_metadata* pMetadata)
drwav_uint8 cueHeaderSectionData[DRWAV_CUE_BYTES];
drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueHeaderSectionData, sizeof(cueHeaderSectionData), &totalBytesRead);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 cueHeaderSectionData[MA_DR_WAV_CUE_BYTES];
ma_uint64 totalBytesRead = 0;
size_t bytesJustRead;
if (pMetadata == NULL) {
return 0;
}
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, cueHeaderSectionData, sizeof(cueHeaderSectionData), &totalBytesRead);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
pMetadata->type = drwav_metadata_type_cue;
pMetadata->data.cue.cuePointCount = drwav_bytes_to_u32(cueHeaderSectionData);
if (pMetadata->data.cue.cuePointCount == (pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES) {
pMetadata->data.cue.pCuePoints = (drwav_cue_point*)drwav__metadata_get_memory(pParser, sizeof(drwav_cue_point) * pMetadata->data.cue.cuePointCount, DRWAV_METADATA_ALIGNMENT);
DRWAV_ASSERT(pMetadata->data.cue.pCuePoints != NULL);
pMetadata->type = ma_dr_wav_metadata_type_cue;
pMetadata->data.cue.cuePointCount = ma_dr_wav_bytes_to_u32(cueHeaderSectionData);
if (pMetadata->data.cue.cuePointCount == (pChunkHeader->sizeInBytes - MA_DR_WAV_CUE_BYTES) / MA_DR_WAV_CUE_POINT_BYTES) {
pMetadata->data.cue.pCuePoints = (ma_dr_wav_cue_point*)ma_dr_wav__metadata_get_memory(pParser, sizeof(ma_dr_wav_cue_point) * pMetadata->data.cue.cuePointCount, MA_DR_WAV_METADATA_ALIGNMENT);
MA_DR_WAV_ASSERT(pMetadata->data.cue.pCuePoints != NULL);
drwav_uint8 cuePointData[DRWAV_CUE_POINT_BYTES];
bytesJustRead = drwav__metadata_parser_read(pParser, cuePointData, sizeof(cuePointData), &totalBytesRead);
ma_uint8 cuePointData[MA_DR_WAV_CUE_POINT_BYTES];
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, cuePointData, sizeof(cuePointData), &totalBytesRead);
pMetadata->data.cue.pCuePoints[iCuePoint].id = drwav_bytes_to_u32(cuePointData + 0);
pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition = drwav_bytes_to_u32(cuePointData + 4);
pMetadata->data.cue.pCuePoints[iCuePoint].id = ma_dr_wav_bytes_to_u32(cuePointData + 0);
pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition = ma_dr_wav_bytes_to_u32(cuePointData + 4);
pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12);
pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16);
pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = drwav_bytes_to_u32(cuePointData + 20);
pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = ma_dr_wav_bytes_to_u32(cuePointData + 12);
pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = ma_dr_wav_bytes_to_u32(cuePointData + 16);
pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = ma_dr_wav_bytes_to_u32(cuePointData + 20);
DRWAV_PRIVATE drwav_uint64 drwav__read_inst_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata)
MA_PRIVATE ma_uint64 ma_dr_wav__read_inst_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, ma_dr_wav_metadata* pMetadata)
drwav_uint8 instData[DRWAV_INST_BYTES];
drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, instData, sizeof(instData), NULL);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 instData[MA_DR_WAV_INST_BYTES];
ma_uint64 bytesRead;
if (pMetadata == NULL) {
return 0;
}
bytesRead = ma_dr_wav__metadata_parser_read(pParser, instData, sizeof(instData), NULL);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
pMetadata->type = drwav_metadata_type_inst;
pMetadata->data.inst.midiUnityNote = (drwav_int8)instData[0];
pMetadata->data.inst.fineTuneCents = (drwav_int8)instData[1];
pMetadata->data.inst.gainDecibels = (drwav_int8)instData[2];
pMetadata->data.inst.lowNote = (drwav_int8)instData[3];
pMetadata->data.inst.highNote = (drwav_int8)instData[4];
pMetadata->data.inst.lowVelocity = (drwav_int8)instData[5];
pMetadata->data.inst.highVelocity = (drwav_int8)instData[6];
pMetadata->type = ma_dr_wav_metadata_type_inst;
pMetadata->data.inst.midiUnityNote = (ma_int8)instData[0];
pMetadata->data.inst.fineTuneCents = (ma_int8)instData[1];
pMetadata->data.inst.gainDecibels = (ma_int8)instData[2];
pMetadata->data.inst.lowNote = (ma_int8)instData[3];
pMetadata->data.inst.highNote = (ma_int8)instData[4];
pMetadata->data.inst.lowVelocity = (ma_int8)instData[5];
pMetadata->data.inst.highVelocity = (ma_int8)instData[6];
DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata)
MA_PRIVATE ma_uint64 ma_dr_wav__read_acid_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, ma_dr_wav_metadata* pMetadata)
drwav_uint8 acidData[DRWAV_ACID_BYTES];
drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, acidData, sizeof(acidData), NULL);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 acidData[MA_DR_WAV_ACID_BYTES];
ma_uint64 bytesRead;
if (pMetadata == NULL) {
return 0;
}
bytesRead = ma_dr_wav__metadata_parser_read(pParser, acidData, sizeof(acidData), NULL);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
pMetadata->type = drwav_metadata_type_acid;
pMetadata->data.acid.flags = drwav_bytes_to_u32(acidData + 0);
pMetadata->data.acid.midiUnityNote = drwav_bytes_to_u16(acidData + 4);
pMetadata->data.acid.reserved1 = drwav_bytes_to_u16(acidData + 6);
pMetadata->data.acid.reserved2 = drwav_bytes_to_f32(acidData + 8);
pMetadata->data.acid.numBeats = drwav_bytes_to_u32(acidData + 12);
pMetadata->data.acid.meterDenominator = drwav_bytes_to_u16(acidData + 16);
pMetadata->data.acid.meterNumerator = drwav_bytes_to_u16(acidData + 18);
pMetadata->data.acid.tempo = drwav_bytes_to_f32(acidData + 20);
pMetadata->type = ma_dr_wav_metadata_type_acid;
pMetadata->data.acid.flags = ma_dr_wav_bytes_to_u32(acidData + 0);
pMetadata->data.acid.midiUnityNote = ma_dr_wav_bytes_to_u16(acidData + 4);
pMetadata->data.acid.reserved1 = ma_dr_wav_bytes_to_u16(acidData + 6);
pMetadata->data.acid.reserved2 = ma_dr_wav_bytes_to_f32(acidData + 8);
pMetadata->data.acid.numBeats = ma_dr_wav_bytes_to_u32(acidData + 12);
pMetadata->data.acid.meterDenominator = ma_dr_wav_bytes_to_u16(acidData + 16);
pMetadata->data.acid.meterNumerator = ma_dr_wav_bytes_to_u16(acidData + 18);
pMetadata->data.acid.tempo = ma_dr_wav_bytes_to_f32(acidData + 20);
char* result = (char*)drwav__metadata_get_memory(pParser, len + 1, 1);
DRWAV_ASSERT(result != NULL);
DRWAV_COPY_MEMORY(result, str, len);
char* result = (char*)ma_dr_wav__metadata_get_memory(pParser, len + 1, 1);
MA_DR_WAV_ASSERT(result != NULL);
MA_DR_WAV_COPY_MEMORY(result, str, len);
} drwav_buffer_reader;
DRWAV_PRIVATE drwav_result drwav_buffer_reader_init(const void* pBuffer, size_t sizeInBytes, drwav_buffer_reader* pReader)
} ma_dr_wav_buffer_reader;
MA_PRIVATE ma_result ma_dr_wav_buffer_reader_init(const void* pBuffer, size_t sizeInBytes, ma_dr_wav_buffer_reader* pReader)
DRWAV_PRIVATE drwav_result drwav_buffer_reader_read(drwav_buffer_reader* pReader, void* pDst, size_t bytesToRead, size_t* pBytesRead)
MA_PRIVATE ma_result ma_dr_wav_buffer_reader_read(ma_dr_wav_buffer_reader* pReader, void* pDst, size_t bytesToRead, size_t* pBytesRead)
result = drwav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != DRWAV_SUCCESS || bytesRead != sizeof(*pDst)) {
result = ma_dr_wav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != MA_SUCCESS || bytesRead != sizeof(*pDst)) {
result = drwav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != DRWAV_SUCCESS || bytesRead != sizeof(*pDst)) {
result = ma_dr_wav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != MA_SUCCESS || bytesRead != sizeof(*pDst)) {
DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata, drwav_uint64 chunkSize)
MA_PRIVATE ma_uint64 ma_dr_wav__read_bext_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, ma_dr_wav_metadata* pMetadata, ma_uint64 chunkSize)
drwav_uint8 bextData[DRWAV_BEXT_BYTES];
size_t bytesRead = drwav__metadata_parser_read(pParser, bextData, sizeof(bextData), NULL);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 bextData[MA_DR_WAV_BEXT_BYTES];
size_t bytesRead = ma_dr_wav__metadata_parser_read(pParser, bextData, sizeof(bextData), NULL);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
pMetadata->type = drwav_metadata_type_bext;
if (drwav_buffer_reader_init(bextData, bytesRead, &reader) == DRWAV_SUCCESS) {
pMetadata->data.bext.pDescription = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_DESCRIPTION_BYTES);
drwav_buffer_reader_seek(&reader, DRWAV_BEXT_DESCRIPTION_BYTES);
pMetadata->data.bext.pOriginatorName = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
drwav_buffer_reader_seek(&reader, DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
pMetadata->data.bext.pOriginatorReference = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_ORIGINATOR_REF_BYTES);
drwav_buffer_reader_seek(&reader, DRWAV_BEXT_ORIGINATOR_REF_BYTES);
drwav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate), NULL);
drwav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime), NULL);
drwav_buffer_reader_read_u32(&reader, &timeReferenceLow);
drwav_buffer_reader_read_u32(&reader, &timeReferenceHigh);
pMetadata->data.bext.timeReference = ((drwav_uint64)timeReferenceHigh << 32) + timeReferenceLow;
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.version);
pMetadata->data.bext.pUMID = drwav__metadata_get_memory(pParser, DRWAV_BEXT_UMID_BYTES, 1);
drwav_buffer_reader_read(&reader, pMetadata->data.bext.pUMID, DRWAV_BEXT_UMID_BYTES, NULL);
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessValue);
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessRange);
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxTruePeakLevel);
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxMomentaryLoudness);
drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxShortTermLoudness);
DRWAV_ASSERT((drwav_offset_ptr(drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_RESERVED_BYTES)) == (bextData + DRWAV_BEXT_BYTES));
extraBytes = (size_t)(chunkSize - DRWAV_BEXT_BYTES);
pMetadata->type = ma_dr_wav_metadata_type_bext;
if (ma_dr_wav_buffer_reader_init(bextData, bytesRead, &reader) == MA_SUCCESS) {
pMetadata->data.bext.pDescription = ma_dr_wav__metadata_copy_string(pParser, (const char*)ma_dr_wav_buffer_reader_ptr(&reader), MA_DR_WAV_BEXT_DESCRIPTION_BYTES);
ma_dr_wav_buffer_reader_seek(&reader, MA_DR_WAV_BEXT_DESCRIPTION_BYTES);
pMetadata->data.bext.pOriginatorName = ma_dr_wav__metadata_copy_string(pParser, (const char*)ma_dr_wav_buffer_reader_ptr(&reader), MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES);
ma_dr_wav_buffer_reader_seek(&reader, MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES);
pMetadata->data.bext.pOriginatorReference = ma_dr_wav__metadata_copy_string(pParser, (const char*)ma_dr_wav_buffer_reader_ptr(&reader), MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES);
ma_dr_wav_buffer_reader_seek(&reader, MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES);
ma_dr_wav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate), NULL);
ma_dr_wav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime), NULL);
ma_dr_wav_buffer_reader_read_u32(&reader, &timeReferenceLow);
ma_dr_wav_buffer_reader_read_u32(&reader, &timeReferenceHigh);
pMetadata->data.bext.timeReference = ((ma_uint64)timeReferenceHigh << 32) + timeReferenceLow;
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.version);
pMetadata->data.bext.pUMID = ma_dr_wav__metadata_get_memory(pParser, MA_DR_WAV_BEXT_UMID_BYTES, 1);
ma_dr_wav_buffer_reader_read(&reader, pMetadata->data.bext.pUMID, MA_DR_WAV_BEXT_UMID_BYTES, NULL);
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessValue);
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessRange);
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxTruePeakLevel);
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxMomentaryLoudness);
ma_dr_wav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxShortTermLoudness);
MA_DR_WAV_ASSERT((ma_dr_wav_offset_ptr(ma_dr_wav_buffer_reader_ptr(&reader), MA_DR_WAV_BEXT_RESERVED_BYTES)) == (bextData + MA_DR_WAV_BEXT_BYTES));
extraBytes = (size_t)(chunkSize - MA_DR_WAV_BEXT_BYTES);
pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__strlen(pMetadata->data.bext.pCodingHistory);
pMetadata->data.bext.pCodingHistory = (char*)ma_dr_wav__metadata_get_memory(pParser, extraBytes + 1, 1);
MA_DR_WAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
bytesRead += ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.codingHistorySize = (ma_uint32)ma_dr_wav__strlen(pMetadata->data.bext.pCodingHistory);
DRWAV_PRIVATE drwav_uint64 drwav__read_list_label_or_note_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata, drwav_uint64 chunkSize, drwav_metadata_type type)
MA_PRIVATE ma_uint64 ma_dr_wav__read_list_label_or_note_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, ma_dr_wav_metadata* pMetadata, ma_uint64 chunkSize, ma_dr_wav_metadata_type type)
drwav_uint8 cueIDBuffer[DRWAV_LIST_LABEL_OR_NOTE_BYTES];
drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueIDBuffer, sizeof(cueIDBuffer), &totalBytesRead);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 cueIDBuffer[MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES];
ma_uint64 totalBytesRead = 0;
size_t bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, cueIDBuffer, sizeof(cueIDBuffer), &totalBytesRead);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
pMetadata->data.labelOrNote.cuePointId = drwav_bytes_to_u32(cueIDBuffer);
sizeIncludingNullTerminator = (drwav_uint32)chunkSize - DRWAV_LIST_LABEL_OR_NOTE_BYTES;
pMetadata->data.labelOrNote.cuePointId = ma_dr_wav_bytes_to_u32(cueIDBuffer);
sizeIncludingNullTerminator = (ma_uint32)chunkSize - MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES;
pMetadata->data.labelOrNote.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
drwav__metadata_parser_read(pParser, pMetadata->data.labelOrNote.pString, sizeIncludingNullTerminator, &totalBytesRead);
pMetadata->data.labelOrNote.pString = (char*)ma_dr_wav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
MA_DR_WAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.labelOrNote.pString, sizeIncludingNullTerminator, &totalBytesRead);
DRWAV_PRIVATE drwav_uint64 drwav__read_list_labelled_cue_region_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata, drwav_uint64 chunkSize)
MA_PRIVATE ma_uint64 ma_dr_wav__read_list_labelled_cue_region_to_metadata_obj(ma_dr_wav__metadata_parser* pParser, ma_dr_wav_metadata* pMetadata, ma_uint64 chunkSize)
drwav_uint8 buffer[DRWAV_LIST_LABELLED_TEXT_BYTES];
drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &totalBytesRead);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
ma_uint8 buffer[MA_DR_WAV_LIST_LABELLED_TEXT_BYTES];
ma_uint64 totalBytesRead = 0;
size_t bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, buffer, sizeof(buffer), &totalBytesRead);
MA_DR_WAV_ASSERT(pParser->stage == ma_dr_wav__metadata_parser_stage_read);
drwav_uint32 sizeIncludingNullTerminator;
pMetadata->type = drwav_metadata_type_list_labelled_cue_region;
pMetadata->data.labelledCueRegion.cuePointId = drwav_bytes_to_u32(buffer + 0);
pMetadata->data.labelledCueRegion.sampleLength = drwav_bytes_to_u32(buffer + 4);
ma_uint32 sizeIncludingNullTerminator;
pMetadata->type = ma_dr_wav_metadata_type_list_labelled_cue_region;
pMetadata->data.labelledCueRegion.cuePointId = ma_dr_wav_bytes_to_u32(buffer + 0);
pMetadata->data.labelledCueRegion.sampleLength = ma_dr_wav_bytes_to_u32(buffer + 4);
pMetadata->data.labelledCueRegion.country = drwav_bytes_to_u16(buffer + 12);
pMetadata->data.labelledCueRegion.language = drwav_bytes_to_u16(buffer + 14);
pMetadata->data.labelledCueRegion.dialect = drwav_bytes_to_u16(buffer + 16);
pMetadata->data.labelledCueRegion.codePage = drwav_bytes_to_u16(buffer + 18);
sizeIncludingNullTerminator = (drwav_uint32)chunkSize - DRWAV_LIST_LABELLED_TEXT_BYTES;
pMetadata->data.labelledCueRegion.country = ma_dr_wav_bytes_to_u16(buffer + 12);
pMetadata->data.labelledCueRegion.language = ma_dr_wav_bytes_to_u16(buffer + 14);
pMetadata->data.labelledCueRegion.dialect = ma_dr_wav_bytes_to_u16(buffer + 16);
pMetadata->data.labelledCueRegion.codePage = ma_dr_wav_bytes_to_u16(buffer + 18);
sizeIncludingNullTerminator = (ma_uint32)chunkSize - MA_DR_WAV_LIST_LABELLED_TEXT_BYTES;
pMetadata->data.labelledCueRegion.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
DRWAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL);
drwav__metadata_parser_read(pParser, pMetadata->data.labelledCueRegion.pString, sizeIncludingNullTerminator, &totalBytesRead);
pMetadata->data.labelledCueRegion.pString = (char*)ma_dr_wav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
MA_DR_WAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL);
ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.labelledCueRegion.pString, sizeIncludingNullTerminator, &totalBytesRead);
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_info_text_chunk(drwav__metadata_parser* pParser, drwav_uint64 chunkSize, drwav_metadata_type type)
MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_info_text_chunk(ma_dr_wav__metadata_parser* pParser, ma_uint64 chunkSize, ma_dr_wav_metadata_type type)
drwav_uint64 bytesRead = 0;
drwav_uint32 stringSizeWithNullTerminator = (drwav_uint32)chunkSize;
if (pParser->stage == drwav__metadata_parser_stage_count) {
ma_uint64 bytesRead = 0;
ma_uint32 stringSizeWithNullTerminator = (ma_uint32)chunkSize;
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
pMetadata->data.infoText.pString = (char*)drwav__metadata_get_memory(pParser, stringSizeWithNullTerminator, 1);
DRWAV_ASSERT(pMetadata->data.infoText.pString != NULL);
bytesRead = drwav__metadata_parser_read(pParser, pMetadata->data.infoText.pString, (size_t)stringSizeWithNullTerminator, NULL);
pMetadata->data.infoText.pString = (char*)ma_dr_wav__metadata_get_memory(pParser, stringSizeWithNullTerminator, 1);
MA_DR_WAV_ASSERT(pMetadata->data.infoText.pString != NULL);
bytesRead = ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.infoText.pString, (size_t)stringSizeWithNullTerminator, NULL);
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata_parser* pParser, const drwav_uint8* pChunkId, drwav_uint64 chunkSize, drwav_metadata_location location)
MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_unknown_chunk(ma_dr_wav__metadata_parser* pParser, const ma_uint8* pChunkId, ma_uint64 chunkSize, ma_dr_wav_metadata_location location)
if (drwav_fourcc_equal(pChunkId, "data") || drwav_fourcc_equal(pChunkId, "fmt") || drwav_fourcc_equal(pChunkId, "fact")) {
if (ma_dr_wav_fourcc_equal(pChunkId, "data") || ma_dr_wav_fourcc_equal(pChunkId, "fmt ") || ma_dr_wav_fourcc_equal(pChunkId, "fact")) {
drwav_metadata* pMetadata = &pParser->pMetadata[pParser->metadataCursor];
pMetadata->type = drwav_metadata_type_unknown;
ma_dr_wav_metadata* pMetadata = &pParser->pMetadata[pParser->metadataCursor];
pMetadata->type = ma_dr_wav_metadata_type_unknown;
pMetadata->data.unknown.dataSizeInBytes = (drwav_uint32)chunkSize;
pMetadata->data.unknown.pData = (drwav_uint8 *)drwav__metadata_get_memory(pParser, (size_t)chunkSize, 1);
DRWAV_ASSERT(pMetadata->data.unknown.pData != NULL);
bytesRead = drwav__metadata_parser_read(pParser, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes, NULL);
pMetadata->data.unknown.dataSizeInBytes = (ma_uint32)chunkSize;
pMetadata->data.unknown.pData = (ma_uint8 *)ma_dr_wav__metadata_get_memory(pParser, (size_t)chunkSize, 1);
MA_DR_WAV_ASSERT(pMetadata->data.unknown.pData != NULL);
bytesRead = ma_dr_wav__metadata_parser_read(pParser, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes, NULL);
DRWAV_PRIVATE drwav_bool32 drwav__chunk_matches(drwav_metadata_type allowedMetadataTypes, const drwav_uint8* pChunkID, drwav_metadata_type type, const char* pID)
MA_PRIVATE ma_bool32 ma_dr_wav__chunk_matches(ma_dr_wav_metadata_type allowedMetadataTypes, const ma_uint8* pChunkID, ma_dr_wav_metadata_type type, const char* pID)
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata_type allowedMetadataTypes)
MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_chunk(ma_dr_wav__metadata_parser* pParser, const ma_dr_wav_chunk_header* pChunkHeader, ma_dr_wav_metadata_type allowedMetadataTypes)
const drwav_uint8 *pChunkID = pChunkHeader->id.fourcc;
drwav_uint64 bytesRead = 0;
if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_smpl, "smpl")) {
if (pChunkHeader->sizeInBytes >= DRWAV_SMPL_BYTES) {
if (pParser->stage == drwav__metadata_parser_stage_count) {
drwav_uint8 buffer[4];
const ma_uint8 *pChunkID = pChunkHeader->id.fourcc;
ma_uint64 bytesRead = 0;
if (ma_dr_wav__chunk_matches(allowedMetadataTypes, pChunkID, ma_dr_wav_metadata_type_smpl, "smpl")) {
if (pChunkHeader->sizeInBytes >= MA_DR_WAV_SMPL_BYTES) {
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
ma_uint8 buffer[4];
drwav_uint32 loopCount = drwav_bytes_to_u32(buffer);
drwav_uint64 calculatedLoopCount;
calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
ma_uint32 loopCount = ma_dr_wav_bytes_to_u32(buffer);
ma_uint64 calculatedLoopCount;
calculatedLoopCount = (pChunkHeader->sizeInBytes - MA_DR_WAV_SMPL_BYTES) / MA_DR_WAV_SMPL_LOOP_BYTES;
drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_smpl_loop) * loopCount, DRWAV_METADATA_ALIGNMENT);
drwav__metadata_request_extra_memory_for_stage_2(pParser, samplerSpecificDataSizeInBytes, 1);
ma_dr_wav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(ma_dr_wav_smpl_loop) * loopCount, MA_DR_WAV_METADATA_ALIGNMENT);
ma_dr_wav__metadata_request_extra_memory_for_stage_2(pParser, samplerSpecificDataSizeInBytes, 1);
} else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_inst, "inst")) {
if (pChunkHeader->sizeInBytes == DRWAV_INST_BYTES) {
if (pParser->stage == drwav__metadata_parser_stage_count) {
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, pChunkID, ma_dr_wav_metadata_type_inst, "inst")) {
if (pChunkHeader->sizeInBytes == MA_DR_WAV_INST_BYTES) {
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
} else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_acid, "acid")) {
if (pChunkHeader->sizeInBytes == DRWAV_ACID_BYTES) {
if (pParser->stage == drwav__metadata_parser_stage_count) {
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, pChunkID, ma_dr_wav_metadata_type_acid, "acid")) {
if (pChunkHeader->sizeInBytes == MA_DR_WAV_ACID_BYTES) {
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
} else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_cue, "cue ")) {
if (pChunkHeader->sizeInBytes >= DRWAV_CUE_BYTES) {
if (pParser->stage == drwav__metadata_parser_stage_count) {
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, pChunkID, ma_dr_wav_metadata_type_cue, "cue ")) {
if (pChunkHeader->sizeInBytes >= MA_DR_WAV_CUE_BYTES) {
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
cueCount = (size_t)(pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES;
drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_cue_point) * cueCount, DRWAV_METADATA_ALIGNMENT);
cueCount = (size_t)(pChunkHeader->sizeInBytes - MA_DR_WAV_CUE_BYTES) / MA_DR_WAV_CUE_POINT_BYTES;
ma_dr_wav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(ma_dr_wav_cue_point) * cueCount, MA_DR_WAV_METADATA_ALIGNMENT);
} else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_bext, "bext")) {
if (pChunkHeader->sizeInBytes >= DRWAV_BEXT_BYTES) {
if (pParser->stage == drwav__metadata_parser_stage_count) {
char buffer[DRWAV_BEXT_DESCRIPTION_BYTES + 1];
size_t allocSizeNeeded = DRWAV_BEXT_UMID_BYTES;
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, pChunkID, ma_dr_wav_metadata_type_bext, "bext")) {
if (pChunkHeader->sizeInBytes >= MA_DR_WAV_BEXT_BYTES) {
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
char buffer[MA_DR_WAV_BEXT_DESCRIPTION_BYTES + 1];
size_t allocSizeNeeded = MA_DR_WAV_BEXT_UMID_BYTES;
buffer[DRWAV_BEXT_DESCRIPTION_BYTES] = '\0';
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_DESCRIPTION_BYTES, &bytesRead);
if (bytesJustRead != DRWAV_BEXT_DESCRIPTION_BYTES) {
buffer[MA_DR_WAV_BEXT_DESCRIPTION_BYTES] = '\0';
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, buffer, MA_DR_WAV_BEXT_DESCRIPTION_BYTES, &bytesRead);
if (bytesJustRead != MA_DR_WAV_BEXT_DESCRIPTION_BYTES) {
allocSizeNeeded += drwav__strlen(buffer) + 1;
buffer[DRWAV_BEXT_ORIGINATOR_NAME_BYTES] = '\0';
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_NAME_BYTES, &bytesRead);
if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_NAME_BYTES) {
allocSizeNeeded += ma_dr_wav__strlen(buffer) + 1;
buffer[MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES] = '\0';
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, buffer, MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES, &bytesRead);
if (bytesJustRead != MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES) {
allocSizeNeeded += drwav__strlen(buffer) + 1;
buffer[DRWAV_BEXT_ORIGINATOR_REF_BYTES] = '\0';
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_REF_BYTES, &bytesRead);
if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_REF_BYTES) {
allocSizeNeeded += ma_dr_wav__strlen(buffer) + 1;
buffer[MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES] = '\0';
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, buffer, MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES, &bytesRead);
if (bytesJustRead != MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES) {
allocSizeNeeded += drwav__strlen(buffer) + 1;
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES;
drwav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
allocSizeNeeded += ma_dr_wav__strlen(buffer) + 1;
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - MA_DR_WAV_BEXT_BYTES;
ma_dr_wav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
bytesRead = drwav__read_bext_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], pChunkHeader->sizeInBytes);
bytesRead = ma_dr_wav__read_bext_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], pChunkHeader->sizeInBytes);
} else if (drwav_fourcc_equal(pChunkID, "LIST") || drwav_fourcc_equal(pChunkID, "list")) {
drwav_metadata_location listType = drwav_metadata_location_invalid;
} else if (ma_dr_wav_fourcc_equal(pChunkID, "LIST") || ma_dr_wav_fourcc_equal(pChunkID, "list")) {
ma_dr_wav_metadata_location listType = ma_dr_wav_metadata_location_invalid;
drwav_uint8 subchunkId[4];
drwav_uint8 subchunkSizeBuffer[4];
drwav_uint64 subchunkDataSize;
drwav_uint64 subchunkBytesRead = 0;
drwav_uint64 bytesJustRead = drwav__metadata_parser_read(pParser, subchunkId, sizeof(subchunkId), &bytesRead);
ma_uint8 subchunkId[4];
ma_uint8 subchunkSizeBuffer[4];
ma_uint64 subchunkDataSize;
ma_uint64 subchunkBytesRead = 0;
ma_uint64 bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, subchunkId, sizeof(subchunkId), &bytesRead);
subchunkDataSize = drwav_bytes_to_u32(subchunkSizeBuffer);
if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_label, "labl") || drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_note, "note")) {
if (subchunkDataSize >= DRWAV_LIST_LABEL_OR_NOTE_BYTES) {
drwav_uint64 stringSizeWithNullTerm = subchunkDataSize - DRWAV_LIST_LABEL_OR_NOTE_BYTES;
if (pParser->stage == drwav__metadata_parser_stage_count) {
subchunkDataSize = ma_dr_wav_bytes_to_u32(subchunkSizeBuffer);
if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_label, "labl") || ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_note, "note")) {
if (subchunkDataSize >= MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES) {
ma_uint64 stringSizeWithNullTerm = subchunkDataSize - MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES;
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
subchunkBytesRead = drwav__read_list_label_or_note_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize, drwav_fourcc_equal(subchunkId, "labl") ? drwav_metadata_type_list_label : drwav_metadata_type_list_note);
subchunkBytesRead = ma_dr_wav__read_list_label_or_note_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize, ma_dr_wav_fourcc_equal(subchunkId, "labl") ? ma_dr_wav_metadata_type_list_label : ma_dr_wav_metadata_type_list_note);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_labelled_cue_region, "ltxt")) {
if (subchunkDataSize >= DRWAV_LIST_LABELLED_TEXT_BYTES) {
drwav_uint64 stringSizeWithNullTerminator = subchunkDataSize - DRWAV_LIST_LABELLED_TEXT_BYTES;
if (pParser->stage == drwav__metadata_parser_stage_count) {
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_labelled_cue_region, "ltxt")) {
if (subchunkDataSize >= MA_DR_WAV_LIST_LABELLED_TEXT_BYTES) {
ma_uint64 stringSizeWithNullTerminator = subchunkDataSize - MA_DR_WAV_LIST_LABELLED_TEXT_BYTES;
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
subchunkBytesRead = drwav__read_list_labelled_cue_region_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize);
subchunkBytesRead = ma_dr_wav__read_list_labelled_cue_region_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_software, "ISFT")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_software);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_copyright, "ICOP")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_copyright);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_title, "INAM")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_title);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_artist, "IART")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_artist);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_comment, "ICMT")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_comment);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_date, "ICRD")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_date);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_genre, "IGNR")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_genre);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_album, "IPRD")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_album);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_tracknumber, "ITRK")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_tracknumber);
} else if ((allowedMetadataTypes & drwav_metadata_type_unknown) != 0) {
subchunkBytesRead = drwav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_software, "ISFT")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_software);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_copyright, "ICOP")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_copyright);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_title, "INAM")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_title);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_artist, "IART")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_artist);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_comment, "ICMT")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_comment);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_date, "ICRD")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_date);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_genre, "IGNR")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_genre);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_album, "IPRD")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_album);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_tracknumber, "ITRK")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_tracknumber);
} else if ((allowedMetadataTypes & ma_dr_wav_metadata_type_unknown) != 0) {
subchunkBytesRead = ma_dr_wav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType);
drwav_uint64 bytesToSeek = subchunkDataSize - subchunkBytesRead;
if (!pParser->onSeek(pParser->pReadSeekUserData, (int)bytesToSeek, drwav_seek_origin_current)) {
ma_uint64 bytesToSeek = subchunkDataSize - subchunkBytesRead;
if (!pParser->onSeek(pParser->pReadSeekUserData, (int)bytesToSeek, ma_dr_wav_seek_origin_current)) {
} else if ((allowedMetadataTypes & drwav_metadata_type_unknown) != 0) {
bytesRead = drwav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, drwav_metadata_location_top_level);
} else if ((allowedMetadataTypes & ma_dr_wav_metadata_type_unknown) != 0) {
bytesRead = ma_dr_wav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, ma_dr_wav_metadata_location_top_level);
DRWAV_PRIVATE drwav_bool32 drwav_preinit(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_bool32 ma_dr_wav_preinit(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pReadSeekUserData, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags)
MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags)
drwav_bool32 foundDataChunk;
drwav_uint64 dataChunkSize = 0;
drwav_uint64 sampleCountFromFactChunk = 0;
drwav_uint64 chunkSize;
drwav__metadata_parser metadataParser;
ma_uint64 dataChunkSize = 0;
ma_uint64 sampleCountFromFactChunk = 0;
ma_uint64 metadataStartPos;
ma_dr_wav__metadata_parser metadataParser;
ma_bool8 isProcessingMetadata = MA_FALSE;
ma_bool8 foundChunk_fmt = MA_FALSE;
ma_bool8 foundChunk_data = MA_FALSE;
ma_bool8 isAIFCFormType = MA_FALSE;
ma_uint64 aiffFrameCount = 0;
sequential = (flags & DRWAV_SEQUENTIAL) != 0;
if (drwav__on_read(pWav->onRead, pWav->pUserData, riff, sizeof(riff), &cursor) != sizeof(riff)) {
return DRWAV_FALSE;
sequential = (flags & MA_DR_WAV_SEQUENTIAL) != 0;
MA_DR_WAV_ZERO_OBJECT(&fmt);
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, riff, sizeof(riff), &cursor) != sizeof(riff)) {
return MA_FALSE;
if (drwav_fourcc_equal(riff, "RIFF")) {
pWav->container = drwav_container_riff;
} else if (drwav_fourcc_equal(riff, "riff")) {
if (ma_dr_wav_fourcc_equal(riff, "RIFF")) {
pWav->container = ma_dr_wav_container_riff;
} else if (ma_dr_wav_fourcc_equal(riff, "RIFX")) {
pWav->container = ma_dr_wav_container_rifx;
} else if (ma_dr_wav_fourcc_equal(riff, "riff")) {
drwav_uint8 riff2[12];
pWav->container = drwav_container_w64;
if (drwav__on_read(pWav->onRead, pWav->pUserData, riff2, sizeof(riff2), &cursor) != sizeof(riff2)) {
return DRWAV_FALSE;
ma_uint8 riff2[12];
pWav->container = ma_dr_wav_container_w64;
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, riff2, sizeof(riff2), &cursor) != sizeof(riff2)) {
return MA_FALSE;
} else if (drwav_fourcc_equal(riff, "RF64")) {
pWav->container = drwav_container_rf64;
} else if (ma_dr_wav_fourcc_equal(riff, "RF64")) {
pWav->container = ma_dr_wav_container_rf64;
} else if (ma_dr_wav_fourcc_equal(riff, "FORM")) {
pWav->container = ma_dr_wav_container_aiff;
if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
drwav_uint8 chunkSizeBytes[4];
drwav_uint8 wave[4];
if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
return DRWAV_FALSE;
if (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx || pWav->container == ma_dr_wav_container_rf64) {
ma_uint8 chunkSizeBytes[4];
ma_uint8 wave[4];
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
return MA_FALSE;
if (pWav->container == drwav_container_riff) {
if (drwav_bytes_to_u32(chunkSizeBytes) < 36) {
return DRWAV_FALSE;
if (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx) {
if (ma_dr_wav_bytes_to_u32_ex(chunkSizeBytes, pWav->container) < 36) {
return MA_FALSE;
if (drwav_bytes_to_u32(chunkSizeBytes) != 0xFFFFFFFF) {
return DRWAV_FALSE;
}
return MA_FALSE;
}
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
return MA_FALSE;
}
if (!ma_dr_wav_fourcc_equal(wave, "WAVE")) {
return MA_FALSE;
}
} else if (pWav->container == ma_dr_wav_container_w64) {
ma_uint8 chunkSizeBytes[8];
ma_uint8 wave[16];
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
return MA_FALSE;
}
if (ma_dr_wav_bytes_to_u64(chunkSizeBytes) < 80) {
return MA_FALSE;
if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
return DRWAV_FALSE;
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
return MA_FALSE;
} else {
drwav_uint8 chunkSizeBytes[8];
drwav_uint8 wave[16];
if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
return DRWAV_FALSE;
} else if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint8 chunkSizeBytes[4];
ma_uint8 aiff[4];
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
return MA_FALSE;
if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
return DRWAV_FALSE;
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, aiff, sizeof(aiff), &cursor) != sizeof(aiff)) {
return MA_FALSE;
if (!drwav_guid_equal(wave, drwavGUID_W64_WAVE)) {
return DRWAV_FALSE;
if (ma_dr_wav_fourcc_equal(aiff, "AIFF")) {
isAIFCFormType = MA_FALSE;
} else if (ma_dr_wav_fourcc_equal(aiff, "AIFC")) {
isAIFCFormType = MA_TRUE;
} else {
return MA_FALSE;
if (pWav->container == drwav_container_rf64) {
drwav_uint8 sizeBytes[8];
drwav_uint64 bytesRemainingInChunk;
drwav_chunk_header header;
drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
if (result != DRWAV_SUCCESS) {
return DRWAV_FALSE;
if (pWav->container == ma_dr_wav_container_rf64) {
ma_uint8 sizeBytes[8];
ma_uint64 bytesRemainingInChunk;
ma_dr_wav_chunk_header header;
result = ma_dr_wav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
if (result != MA_SUCCESS) {
return MA_FALSE;
if (drwav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
return DRWAV_FALSE;
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
return MA_FALSE;
dataChunkSize = drwav_bytes_to_u64(sizeBytes);
if (drwav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
return DRWAV_FALSE;
dataChunkSize = ma_dr_wav_bytes_to_u64(sizeBytes);
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
return MA_FALSE;
sampleCountFromFactChunk = drwav_bytes_to_u64(sizeBytes);
if (!drwav__seek_forward(pWav->onSeek, bytesRemainingInChunk, pWav->pUserData)) {
return DRWAV_FALSE;
sampleCountFromFactChunk = ma_dr_wav_bytes_to_u64(sizeBytes);
if (!ma_dr_wav__seek_forward(pWav->onSeek, bytesRemainingInChunk, pWav->pUserData)) {
return MA_FALSE;
if (!drwav__read_fmt(pWav->onRead, pWav->onSeek, pWav->pUserData, pWav->container, &cursor, &fmt)) {
return DRWAV_FALSE;
metadataStartPos = cursor;
isProcessingMetadata = !sequential && ((flags & MA_DR_WAV_WITH_METADATA) != 0);
if (pWav->container != ma_dr_wav_container_riff && pWav->container != ma_dr_wav_container_rf64) {
isProcessingMetadata = MA_FALSE;
if ((fmt.sampleRate == 0 || fmt.sampleRate > DRWAV_MAX_SAMPLE_RATE) ||
(fmt.channels == 0 || fmt.channels > DRWAV_MAX_CHANNELS) ||
(fmt.bitsPerSample == 0 || fmt.bitsPerSample > DRWAV_MAX_BITS_PER_SAMPLE) ||
fmt.blockAlign == 0) {
return DRWAV_FALSE;
}
translatedFormatTag = fmt.formatTag;
if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
translatedFormatTag = drwav_bytes_to_u16(fmt.subFormat + 0);
}
DRWAV_ZERO_MEMORY(&metadataParser, sizeof(metadataParser));
if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) {
drwav_uint64 cursorForMetadata = cursor;
MA_DR_WAV_ZERO_MEMORY(&metadataParser, sizeof(metadataParser));
if (isProcessingMetadata) {
metadataParser.stage = drwav__metadata_parser_stage_count;
for (;;) {
drwav_result result;
drwav_uint64 bytesRead;
drwav_uint64 remainingBytes;
drwav_chunk_header header;
result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursorForMetadata, &header);
if (result != DRWAV_SUCCESS) {
break;
}
bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes);
DRWAV_ASSERT(bytesRead <= header.sizeInBytes);
remainingBytes = header.sizeInBytes - bytesRead + header.paddingSize;
if (!drwav__seek_forward(pWav->onSeek, remainingBytes, pWav->pUserData)) {
break;
}
cursorForMetadata += remainingBytes;
}
if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
return DRWAV_FALSE;
}
drwav__metadata_alloc(&metadataParser, &pWav->allocationCallbacks);
metadataParser.stage = drwav__metadata_parser_stage_read;
metadataParser.stage = ma_dr_wav__metadata_parser_stage_count;
drwav_chunk_header header;
drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
if (result != DRWAV_SUCCESS) {
if (!foundDataChunk) {
return DRWAV_FALSE;
} else {
break;
}
ma_dr_wav_chunk_header header;
ma_uint64 chunkSize;
result = ma_dr_wav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
if (result != MA_SUCCESS) {
break;
drwav_uint64 callbackBytesRead = onChunk(pChunkUserData, pWav->onRead, pWav->onSeek, pWav->pUserData, &header, pWav->container, &fmt);
ma_uint64 callbackBytesRead = onChunk(pChunkUserData, pWav->onRead, pWav->onSeek, pWav->pUserData, &header, pWav->container, &fmt);
if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) {
drwav_uint64 bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes);
if (bytesRead > 0) {
if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
return DRWAV_FALSE;
if (((pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx || pWav->container == ma_dr_wav_container_rf64) && ma_dr_wav_fourcc_equal(header.id.fourcc, "fmt ")) ||
((pWav->container == ma_dr_wav_container_w64) && ma_dr_wav_guid_equal(header.id.guid, ma_dr_wavGUID_W64_FMT))) {
ma_uint8 fmtData[16];
foundChunk_fmt = MA_TRUE;
if (pWav->onRead(pWav->pUserData, fmtData, sizeof(fmtData)) != sizeof(fmtData)) {
return MA_FALSE;
}
cursor += sizeof(fmtData);
fmt.formatTag = ma_dr_wav_bytes_to_u16_ex(fmtData + 0, pWav->container);
fmt.channels = ma_dr_wav_bytes_to_u16_ex(fmtData + 2, pWav->container);
fmt.sampleRate = ma_dr_wav_bytes_to_u32_ex(fmtData + 4, pWav->container);
fmt.avgBytesPerSec = ma_dr_wav_bytes_to_u32_ex(fmtData + 8, pWav->container);
fmt.blockAlign = ma_dr_wav_bytes_to_u16_ex(fmtData + 12, pWav->container);
fmt.bitsPerSample = ma_dr_wav_bytes_to_u16_ex(fmtData + 14, pWav->container);
fmt.extendedSize = 0;
fmt.validBitsPerSample = 0;
fmt.channelMask = 0;
MA_DR_WAV_ZERO_MEMORY(fmt.subFormat, sizeof(fmt.subFormat));
if (header.sizeInBytes > 16) {
ma_uint8 fmt_cbSize[2];
int bytesReadSoFar = 0;
if (pWav->onRead(pWav->pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) {
return MA_FALSE;
cursor += sizeof(fmt_cbSize);
bytesReadSoFar = 18;
fmt.extendedSize = ma_dr_wav_bytes_to_u16_ex(fmt_cbSize, pWav->container);
if (fmt.extendedSize > 0) {
if (fmt.formatTag == MA_DR_WAVE_FORMAT_EXTENSIBLE) {
if (fmt.extendedSize != 22) {
return MA_FALSE;
}
}
if (fmt.formatTag == MA_DR_WAVE_FORMAT_EXTENSIBLE) {
ma_uint8 fmtext[22];
if (pWav->onRead(pWav->pUserData, fmtext, fmt.extendedSize) != fmt.extendedSize) {
return MA_FALSE;
}
fmt.validBitsPerSample = ma_dr_wav_bytes_to_u16_ex(fmtext + 0, pWav->container);
fmt.channelMask = ma_dr_wav_bytes_to_u32_ex(fmtext + 2, pWav->container);
ma_dr_wav_bytes_to_guid(fmtext + 6, fmt.subFormat);
} else {
if (pWav->onSeek(pWav->pUserData, fmt.extendedSize, ma_dr_wav_seek_origin_current) == MA_FALSE) {
return MA_FALSE;
}
}
cursor += fmt.extendedSize;
bytesReadSoFar += fmt.extendedSize;
}
if (pWav->onSeek(pWav->pUserData, (int)(header.sizeInBytes - bytesReadSoFar), ma_dr_wav_seek_origin_current) == MA_FALSE) {
return MA_FALSE;
}
cursor += (header.sizeInBytes - bytesReadSoFar);
}
if (!foundDataChunk) {
pWav->dataChunkDataPos = cursor;
}
chunkSize = header.sizeInBytes;
if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
if (drwav_fourcc_equal(header.id.fourcc, "data")) {
foundDataChunk = DRWAV_TRUE;
if (pWav->container != drwav_container_rf64) {
dataChunkSize = chunkSize;
if (header.paddingSize > 0) {
if (ma_dr_wav__seek_forward(pWav->onSeek, header.paddingSize, pWav->pUserData) == MA_FALSE) {
break;
} else {
if (drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA)) {
foundDataChunk = DRWAV_TRUE;
continue;
}
if (((pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx || pWav->container == ma_dr_wav_container_rf64) && ma_dr_wav_fourcc_equal(header.id.fourcc, "data")) ||
((pWav->container == ma_dr_wav_container_w64) && ma_dr_wav_guid_equal(header.id.guid, ma_dr_wavGUID_W64_DATA))) {
foundChunk_data = MA_TRUE;
pWav->dataChunkDataPos = cursor;
if (pWav->container != ma_dr_wav_container_rf64) {
}
if (foundDataChunk && sequential) {
break;
if (sequential || !isProcessingMetadata) {
break;
} else {
chunkSize += header.paddingSize;
if (ma_dr_wav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == MA_FALSE) {
break;
}
cursor += chunkSize;
continue;
}
if (pWav->container == drwav_container_riff) {
if (drwav_fourcc_equal(header.id.fourcc, "fact")) {
drwav_uint32 sampleCount;
if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCount, 4, &cursor) != 4) {
return DRWAV_FALSE;
if (((pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx || pWav->container == ma_dr_wav_container_rf64) && ma_dr_wav_fourcc_equal(header.id.fourcc, "fact")) ||
((pWav->container == ma_dr_wav_container_w64) && ma_dr_wav_guid_equal(header.id.guid, ma_dr_wavGUID_W64_FACT))) {
if (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx) {
ma_uint8 sampleCount[4];
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, &sampleCount, 4, &cursor) != 4) {
return MA_FALSE;
if (!foundDataChunk) {
pWav->dataChunkDataPos = cursor;
}
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
sampleCountFromFactChunk = sampleCount;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
sampleCountFromFactChunk = ma_dr_wav_bytes_to_u32_ex(sampleCount, pWav->container);
}
} else if (pWav->container == drwav_container_w64) {
if (drwav_guid_equal(header.id.guid, drwavGUID_W64_FACT)) {
if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCountFromFactChunk, 8, &cursor) != 8) {
return DRWAV_FALSE;
} else if (pWav->container == ma_dr_wav_container_w64) {
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, &sampleCountFromFactChunk, 8, &cursor) != 8) {
return MA_FALSE;
if (!foundDataChunk) {
pWav->dataChunkDataPos = cursor;
} else if (pWav->container == ma_dr_wav_container_rf64) {
}
chunkSize += header.paddingSize;
if (ma_dr_wav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == MA_FALSE) {
break;
}
cursor += chunkSize;
continue;
}
if (pWav->container == ma_dr_wav_container_aiff && ma_dr_wav_fourcc_equal(header.id.fourcc, "COMM")) {
ma_uint8 commData[24];
ma_uint32 commDataBytesToRead;
ma_uint16 channels;
ma_uint32 frameCount;
ma_uint16 sampleSizeInBits;
ma_int64 sampleRate;
ma_uint16 compressionFormat;
foundChunk_fmt = MA_TRUE;
if (isAIFCFormType) {
commDataBytesToRead = 24;
if (header.sizeInBytes < commDataBytesToRead) {
return MA_FALSE;
} else if (pWav->container == drwav_container_rf64) {
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, commData, commDataBytesToRead, &cursor) != commDataBytesToRead) {
return MA_FALSE;
}
channels = ma_dr_wav_bytes_to_u16_ex (commData + 0, pWav->container);
frameCount = ma_dr_wav_bytes_to_u32_ex (commData + 2, pWav->container);
sampleSizeInBits = ma_dr_wav_bytes_to_u16_ex (commData + 6, pWav->container);
sampleRate = ma_dr_wav_aiff_extented_to_s64(commData + 8);
if (sampleRate < 0 || sampleRate > 0xFFFFFFFF) {
return MA_FALSE;
}
if (isAIFCFormType) {
const ma_uint8* type = commData + 18;
if (ma_dr_wav_fourcc_equal(type, "NONE")) {
compressionFormat = MA_DR_WAVE_FORMAT_PCM;
} else if (ma_dr_wav_fourcc_equal(type, "raw ")) {
compressionFormat = MA_DR_WAVE_FORMAT_PCM;
if (sampleSizeInBits == 8) {
pWav->aiff.isUnsigned = MA_TRUE;
}
} else if (ma_dr_wav_fourcc_equal(type, "sowt")) {
compressionFormat = MA_DR_WAVE_FORMAT_PCM;
pWav->aiff.isLE = MA_TRUE;
} else if (ma_dr_wav_fourcc_equal(type, "fl32") || ma_dr_wav_fourcc_equal(type, "fl64") || ma_dr_wav_fourcc_equal(type, "FL32") || ma_dr_wav_fourcc_equal(type, "FL64")) {
compressionFormat = MA_DR_WAVE_FORMAT_IEEE_FLOAT;
} else if (ma_dr_wav_fourcc_equal(type, "alaw") || ma_dr_wav_fourcc_equal(type, "ALAW")) {
compressionFormat = MA_DR_WAVE_FORMAT_ALAW;
} else if (ma_dr_wav_fourcc_equal(type, "ulaw") || ma_dr_wav_fourcc_equal(type, "ULAW")) {
compressionFormat = MA_DR_WAVE_FORMAT_MULAW;
} else if (ma_dr_wav_fourcc_equal(type, "ima4")) {
compressionFormat = MA_DR_WAVE_FORMAT_DVI_ADPCM;
sampleSizeInBits = 4;
return MA_FALSE;
} else {
return MA_FALSE;
}
} else {
compressionFormat = MA_DR_WAVE_FORMAT_PCM;
}
aiffFrameCount = frameCount;
fmt.formatTag = compressionFormat;
fmt.channels = channels;
fmt.sampleRate = (ma_uint32)sampleRate;
fmt.bitsPerSample = sampleSizeInBits;
fmt.blockAlign = (ma_uint16)(fmt.channels * fmt.bitsPerSample / 8);
fmt.avgBytesPerSec = fmt.blockAlign * fmt.sampleRate;
if (fmt.blockAlign == 0 && compressionFormat == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
fmt.blockAlign = 34 * fmt.channels;
}
if (compressionFormat == MA_DR_WAVE_FORMAT_ALAW || compressionFormat == MA_DR_WAVE_FORMAT_MULAW) {
if (fmt.bitsPerSample > 8) {
fmt.bitsPerSample = 8;
fmt.blockAlign = fmt.channels;
}
}
fmt.bitsPerSample += (fmt.bitsPerSample & 7);
if (isAIFCFormType) {
if (ma_dr_wav__seek_forward(pWav->onSeek, (chunkSize - commDataBytesToRead), pWav->pUserData) == MA_FALSE) {
return MA_FALSE;
}
cursor += (chunkSize - commDataBytesToRead);
}
continue;
if (pWav->container == ma_dr_wav_container_aiff && ma_dr_wav_fourcc_equal(header.id.fourcc, "SSND")) {
ma_uint8 offsetAndBlockSizeData[8];
ma_uint32 offset;
foundChunk_data = MA_TRUE;
if (ma_dr_wav__on_read(pWav->onRead, pWav->pUserData, offsetAndBlockSizeData, sizeof(offsetAndBlockSizeData), &cursor) != sizeof(offsetAndBlockSizeData)) {
return MA_FALSE;
}
offset = ma_dr_wav_bytes_to_u32_ex(offsetAndBlockSizeData + 0, pWav->container);
if (ma_dr_wav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == MA_FALSE) {
return MA_FALSE;
}
cursor += offset;
pWav->dataChunkDataPos = cursor;
dataChunkSize = chunkSize;
if (sequential || !isProcessingMetadata) {
break;
} else {
if (ma_dr_wav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == MA_FALSE) {
break;
}
cursor += chunkSize;
continue;
}
}
if (isProcessingMetadata) {
ma_uint64 metadataBytesRead;
metadataBytesRead = ma_dr_wav__metadata_process_chunk(&metadataParser, &header, ma_dr_wav_metadata_type_all_including_unknown);
MA_DR_WAV_ASSERT(metadataBytesRead <= header.sizeInBytes);
if (ma_dr_wav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData) == MA_FALSE) {
break;
}
}
if (!foundDataChunk) {
pWav->dataChunkDataPos = cursor;
}
}
if (!foundChunk_fmt || !foundChunk_data) {
return MA_FALSE;
}
if ((fmt.sampleRate == 0 || fmt.sampleRate > MA_DR_WAV_MAX_SAMPLE_RATE ) ||
(fmt.channels == 0 || fmt.channels > MA_DR_WAV_MAX_CHANNELS ) ||
(fmt.bitsPerSample == 0 || fmt.bitsPerSample > MA_DR_WAV_MAX_BITS_PER_SAMPLE) ||
fmt.blockAlign == 0) {
return MA_FALSE;
pWav->pMetadata = metadataParser.pMetadata;
pWav->metadataCount = metadataParser.metadataCount;
if (!foundDataChunk) {
return DRWAV_FALSE;
translatedFormatTag = fmt.formatTag;
if (translatedFormatTag == MA_DR_WAVE_FORMAT_EXTENSIBLE) {
translatedFormatTag = ma_dr_wav_bytes_to_u16_ex(fmt.subFormat + 0, pWav->container);
if (isProcessingMetadata && metadataParser.metadataCount > 0) {
if (ma_dr_wav__seek_from_start(pWav->onSeek, metadataStartPos, pWav->pUserData) == MA_FALSE) {
return MA_FALSE;
}
result = ma_dr_wav__metadata_alloc(&metadataParser, &pWav->allocationCallbacks);
if (result != MA_SUCCESS) {
return MA_FALSE;
}
metadataParser.stage = ma_dr_wav__metadata_parser_stage_read;
for (;;) {
ma_dr_wav_chunk_header header;
ma_uint64 metadataBytesRead;
result = ma_dr_wav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
if (result != MA_SUCCESS) {
break;
}
metadataBytesRead = ma_dr_wav__metadata_process_chunk(&metadataParser, &header, ma_dr_wav_metadata_type_all_including_unknown);
if (ma_dr_wav__seek_forward(pWav->onSeek, (header.sizeInBytes + header.paddingSize) - metadataBytesRead, pWav->pUserData) == MA_FALSE) {
ma_dr_wav_free(metadataParser.pMetadata, &pWav->allocationCallbacks);
return MA_FALSE;
}
}
pWav->pMetadata = metadataParser.pMetadata;
pWav->metadataCount = metadataParser.metadataCount;
}
if (dataChunkSize == 0xFFFFFFFF && (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx) && pWav->isSequentialWrite == MA_FALSE) {
dataChunkSize = 0;
for (;;) {
ma_uint8 temp[4096];
size_t bytesRead = pWav->onRead(pWav->pUserData, temp, sizeof(temp));
dataChunkSize += bytesRead;
if (bytesRead < sizeof(temp)) {
break;
}
}
}
if (ma_dr_wav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData) == MA_FALSE) {
ma_dr_wav_free(pWav->pMetadata, &pWav->allocationCallbacks);
return MA_FALSE;
}
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
drwav_uint64 totalBlockHeaderSizeInBytes;
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
ma_uint64 totalBlockHeaderSizeInBytes;
ma_uint64 blockCount = dataChunkSize / fmt.blockAlign;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
drwav_uint64 totalBlockHeaderSizeInBytes;
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
ma_uint64 totalBlockHeaderSizeInBytes;
ma_uint64 blockCount = dataChunkSize / fmt.blockAlign;
#ifdef DR_WAV_LIBSNDFILE_COMPAT
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
ma_uint64 blockCount = dataChunkSize / fmt.blockAlign;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
ma_uint64 blockCount = dataChunkSize / fmt.blockAlign;
DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->onWrite != NULL);
if (!drwav__is_little_endian()) {
value = drwav__bswap16(value);
MA_DR_WAV_ASSERT(pWav != NULL);
MA_DR_WAV_ASSERT(pWav->onWrite != NULL);
if (!ma_dr_wav__is_little_endian()) {
value = ma_dr_wav__bswap16(value);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->onWrite != NULL);
if (!drwav__is_little_endian()) {
value = drwav__bswap32(value);
MA_DR_WAV_ASSERT(pWav != NULL);
MA_DR_WAV_ASSERT(pWav->onWrite != NULL);
if (!ma_dr_wav__is_little_endian()) {
value = ma_dr_wav__bswap32(value);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->onWrite != NULL);
if (!drwav__is_little_endian()) {
value = drwav__bswap64(value);
MA_DR_WAV_ASSERT(pWav != NULL);
MA_DR_WAV_ASSERT(pWav->onWrite != NULL);
if (!ma_dr_wav__is_little_endian()) {
value = ma_dr_wav__bswap64(value);
DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata* pMetadatas, drwav_uint32 metadataCount)
MA_PRIVATE size_t ma_dr_wav__write_or_count_metadata(ma_dr_wav* pWav, ma_dr_wav_metadata* pMetadatas, ma_uint32 metadataCount)
drwav_metadata* pMetadata = &pMetadatas[iMetadata];
drwav_uint32 chunkSize = 0;
if ((pMetadata->type & drwav_metadata_type_list_all_info_strings) || (pMetadata->type == drwav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == drwav_metadata_location_inside_info_list)) {
hasListInfo = DRWAV_TRUE;
ma_dr_wav_metadata* pMetadata = &pMetadatas[iMetadata];
ma_uint32 chunkSize = 0;
if ((pMetadata->type & ma_dr_wav_metadata_type_list_all_info_strings) || (pMetadata->type == ma_dr_wav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == ma_dr_wav_metadata_location_inside_info_list)) {
hasListInfo = MA_TRUE;
if ((pMetadata->type & drwav_metadata_type_list_all_adtl) || (pMetadata->type == drwav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == drwav_metadata_location_inside_adtl_list)) {
hasListAdtl = DRWAV_TRUE;
if ((pMetadata->type & ma_dr_wav_metadata_type_list_all_adtl) || (pMetadata->type == ma_dr_wav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == ma_dr_wav_metadata_location_inside_adtl_list)) {
hasListAdtl = MA_TRUE;
drwav_uint32 iLoop;
chunkSize = DRWAV_SMPL_BYTES + DRWAV_SMPL_LOOP_BYTES * pMetadata->data.smpl.sampleLoopCount + pMetadata->data.smpl.samplerSpecificDataSizeInBytes;
bytesWritten += drwav__write_or_count(pWav, "smpl", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.manufacturerId);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.productId);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.samplePeriodNanoseconds);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiUnityNote);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiPitchFraction);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteFormat);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.sampleLoopCount);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.samplerSpecificDataSizeInBytes);
ma_uint32 iLoop;
chunkSize = MA_DR_WAV_SMPL_BYTES + MA_DR_WAV_SMPL_LOOP_BYTES * pMetadata->data.smpl.sampleLoopCount + pMetadata->data.smpl.samplerSpecificDataSizeInBytes;
bytesWritten += ma_dr_wav__write_or_count(pWav, "smpl", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.manufacturerId);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.productId);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.samplePeriodNanoseconds);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiUnityNote);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiPitchFraction);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteFormat);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteOffset);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.sampleLoopCount);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.samplerSpecificDataSizeInBytes);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleByteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleByteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleByteOffset);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleByteOffset);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount);
bytesWritten += drwav__write(pWav, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes);
chunkSize = DRWAV_INST_BYTES;
bytesWritten += drwav__write_or_count(pWav, "inst", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.midiUnityNote, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.fineTuneCents, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.gainDecibels, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.lowNote, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.highNote, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.lowVelocity, 1);
bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.highVelocity, 1);
chunkSize = MA_DR_WAV_INST_BYTES;
bytesWritten += ma_dr_wav__write_or_count(pWav, "inst", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.midiUnityNote, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.fineTuneCents, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.gainDecibels, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.lowNote, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.highNote, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.lowVelocity, 1);
bytesWritten += ma_dr_wav__write_or_count(pWav, &pMetadata->data.inst.highVelocity, 1);
drwav_uint32 iCuePoint;
chunkSize = DRWAV_CUE_BYTES + DRWAV_CUE_POINT_BYTES * pMetadata->data.cue.cuePointCount;
bytesWritten += drwav__write_or_count(pWav, "cue ", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.cuePointCount);
ma_uint32 iCuePoint;
chunkSize = MA_DR_WAV_CUE_BYTES + MA_DR_WAV_CUE_POINT_BYTES * pMetadata->data.cue.cuePointCount;
bytesWritten += ma_dr_wav__write_or_count(pWav, "cue ", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.cuePointCount);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].id);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].id);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset);
chunkSize = DRWAV_ACID_BYTES;
bytesWritten += drwav__write_or_count(pWav, "acid", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.flags);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.midiUnityNote);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.reserved1);
bytesWritten += drwav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.reserved2);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.numBeats);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterDenominator);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterNumerator);
bytesWritten += drwav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.tempo);
chunkSize = MA_DR_WAV_ACID_BYTES;
bytesWritten += ma_dr_wav__write_or_count(pWav, "acid", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.flags);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.midiUnityNote);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.reserved1);
bytesWritten += ma_dr_wav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.reserved2);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.numBeats);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterDenominator);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterNumerator);
bytesWritten += ma_dr_wav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.tempo);
char reservedBuf[DRWAV_BEXT_RESERVED_BYTES];
drwav_uint32 timeReferenceLow;
drwav_uint32 timeReferenceHigh;
chunkSize = DRWAV_BEXT_BYTES + pMetadata->data.bext.codingHistorySize;
bytesWritten += drwav__write_or_count(pWav, "bext", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pDescription, DRWAV_BEXT_DESCRIPTION_BYTES);
bytesWritten += drwav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pOriginatorName, DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
bytesWritten += drwav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pOriginatorReference, DRWAV_BEXT_ORIGINATOR_REF_BYTES);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate));
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime));
timeReferenceLow = (drwav_uint32)(pMetadata->data.bext.timeReference & 0xFFFFFFFF);
timeReferenceHigh = (drwav_uint32)(pMetadata->data.bext.timeReference >> 32);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, timeReferenceLow);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, timeReferenceHigh);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.version);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pUMID, DRWAV_BEXT_UMID_BYTES);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessValue);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessRange);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxTruePeakLevel);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxMomentaryLoudness);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxShortTermLoudness);
DRWAV_ZERO_MEMORY(reservedBuf, sizeof(reservedBuf));
bytesWritten += drwav__write_or_count(pWav, reservedBuf, sizeof(reservedBuf));
char reservedBuf[MA_DR_WAV_BEXT_RESERVED_BYTES];
ma_uint32 timeReferenceLow;
ma_uint32 timeReferenceHigh;
chunkSize = MA_DR_WAV_BEXT_BYTES + pMetadata->data.bext.codingHistorySize;
bytesWritten += ma_dr_wav__write_or_count(pWav, "bext", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pDescription, MA_DR_WAV_BEXT_DESCRIPTION_BYTES);
bytesWritten += ma_dr_wav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pOriginatorName, MA_DR_WAV_BEXT_ORIGINATOR_NAME_BYTES);
bytesWritten += ma_dr_wav__write_or_count_string_to_fixed_size_buf(pWav, pMetadata->data.bext.pOriginatorReference, MA_DR_WAV_BEXT_ORIGINATOR_REF_BYTES);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate));
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime));
timeReferenceLow = (ma_uint32)(pMetadata->data.bext.timeReference & 0xFFFFFFFF);
timeReferenceHigh = (ma_uint32)(pMetadata->data.bext.timeReference >> 32);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, timeReferenceLow);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, timeReferenceHigh);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.version);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.bext.pUMID, MA_DR_WAV_BEXT_UMID_BYTES);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessValue);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessRange);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxTruePeakLevel);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxMomentaryLoudness);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxShortTermLoudness);
MA_DR_WAV_ZERO_MEMORY(reservedBuf, sizeof(reservedBuf));
bytesWritten += ma_dr_wav__write_or_count(pWav, reservedBuf, sizeof(reservedBuf));
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pCodingHistory, pMetadata->data.bext.codingHistorySize);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.bext.pCodingHistory, pMetadata->data.bext.codingHistorySize);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes);
drwav_metadata* pMetadata = &pMetadatas[iMetadata];
if ((pMetadata->type & drwav_metadata_type_list_all_info_strings)) {
ma_dr_wav_metadata* pMetadata = &pMetadatas[iMetadata];
if ((pMetadata->type & ma_dr_wav_metadata_type_list_all_info_strings)) {
} else if (pMetadata->type == drwav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == drwav_metadata_location_inside_info_list) {
} else if (pMetadata->type == ma_dr_wav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == ma_dr_wav_metadata_location_inside_info_list) {
bytesWritten += drwav__write_or_count(pWav, "LIST", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count(pWav, "INFO", 4);
bytesWritten += ma_dr_wav__write_or_count(pWav, "LIST", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, "INFO", 4);
drwav_metadata* pMetadata = &pMetadatas[iMetadata];
drwav_uint32 subchunkSize = 0;
if (pMetadata->type & drwav_metadata_type_list_all_info_strings) {
ma_dr_wav_metadata* pMetadata = &pMetadatas[iMetadata];
ma_uint32 subchunkSize = 0;
if (pMetadata->type & ma_dr_wav_metadata_type_list_all_info_strings) {
case drwav_metadata_type_list_info_software: pID = "ISFT"; break;
case drwav_metadata_type_list_info_copyright: pID = "ICOP"; break;
case drwav_metadata_type_list_info_title: pID = "INAM"; break;
case drwav_metadata_type_list_info_artist: pID = "IART"; break;
case drwav_metadata_type_list_info_comment: pID = "ICMT"; break;
case drwav_metadata_type_list_info_date: pID = "ICRD"; break;
case drwav_metadata_type_list_info_genre: pID = "IGNR"; break;
case drwav_metadata_type_list_info_album: pID = "IPRD"; break;
case drwav_metadata_type_list_info_tracknumber: pID = "ITRK"; break;
case ma_dr_wav_metadata_type_list_info_software: pID = "ISFT"; break;
case ma_dr_wav_metadata_type_list_info_copyright: pID = "ICOP"; break;
case ma_dr_wav_metadata_type_list_info_title: pID = "INAM"; break;
case ma_dr_wav_metadata_type_list_info_artist: pID = "IART"; break;
case ma_dr_wav_metadata_type_list_info_comment: pID = "ICMT"; break;
case ma_dr_wav_metadata_type_list_info_date: pID = "ICRD"; break;
case ma_dr_wav_metadata_type_list_info_genre: pID = "IGNR"; break;
case ma_dr_wav_metadata_type_list_info_album: pID = "IPRD"; break;
case ma_dr_wav_metadata_type_list_info_tracknumber: pID = "ITRK"; break;
bytesWritten += drwav__write_or_count(pWav, pID, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.infoText.pString, pMetadata->data.infoText.stringLength);
bytesWritten += drwav__write_or_count_byte(pWav, '\0');
bytesWritten += ma_dr_wav__write_or_count(pWav, pID, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.infoText.pString, pMetadata->data.infoText.stringLength);
bytesWritten += ma_dr_wav__write_or_count_byte(pWav, '\0');
} else if (pMetadata->type == drwav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == drwav_metadata_location_inside_info_list) {
} else if (pMetadata->type == ma_dr_wav_metadata_type_unknown && pMetadata->data.unknown.chunkLocation == ma_dr_wav_metadata_location_inside_info_list) {
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.unknown.dataSizeInBytes);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.unknown.dataSizeInBytes);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
bytesWritten += drwav__write_or_count(pWav, "LIST", 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += drwav__write_or_count(pWav, "adtl", 4);
bytesWritten += ma_dr_wav__write_or_count(pWav, "LIST", 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, chunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, "adtl", 4);
DRWAV_ASSERT(pID != NULL);
DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
subchunkSize = DRWAV_LIST_LABEL_OR_NOTE_BYTES;
bytesWritten += drwav__write_or_count(pWav, pID, 4);
MA_DR_WAV_ASSERT(pID != NULL);
MA_DR_WAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
subchunkSize = MA_DR_WAV_LIST_LABEL_OR_NOTE_BYTES;
bytesWritten += ma_dr_wav__write_or_count(pWav, pID, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelOrNote.cuePointId);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelOrNote.pString, pMetadata->data.labelOrNote.stringLength);
bytesWritten += drwav__write_or_count_byte(pWav, '\0');
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelOrNote.cuePointId);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.labelOrNote.pString, pMetadata->data.labelOrNote.stringLength);
bytesWritten += ma_dr_wav__write_or_count_byte(pWav, '\0');
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.cuePointId);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.sampleLength);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelledCueRegion.purposeId, 4);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.country);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.language);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.dialect);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.codePage);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.cuePointId);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.sampleLength);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.labelledCueRegion.purposeId, 4);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.country);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.language);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.dialect);
bytesWritten += ma_dr_wav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.codePage);
DRWAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelledCueRegion.pString, pMetadata->data.labelledCueRegion.stringLength);
bytesWritten += drwav__write_or_count_byte(pWav, '\0');
MA_DR_WAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.labelledCueRegion.pString, pMetadata->data.labelledCueRegion.stringLength);
bytesWritten += ma_dr_wav__write_or_count_byte(pWav, '\0');
DRWAV_ASSERT(pMetadata->data.unknown.pData != NULL);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
MA_DR_WAV_ASSERT(pMetadata->data.unknown.pData != NULL);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, subchunkSize);
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
DRWAV_PRIVATE drwav_uint32 drwav__riff_chunk_size_riff(drwav_uint64 dataChunkSize, drwav_metadata* pMetadata, drwav_uint32 metadataCount)
MA_PRIVATE ma_uint32 ma_dr_wav__riff_chunk_size_riff(ma_uint64 dataChunkSize, ma_dr_wav_metadata* pMetadata, ma_uint32 metadataCount)
drwav_uint64 chunkSize = 4 + 24 + (drwav_uint64)drwav__write_or_count_metadata(NULL, pMetadata, metadataCount) + 8 + dataChunkSize + drwav__chunk_padding_size_riff(dataChunkSize);
ma_uint64 chunkSize = 4 + 24 + (ma_uint64)ma_dr_wav__write_or_count_metadata(NULL, pMetadata, metadataCount) + 8 + dataChunkSize + ma_dr_wav__chunk_padding_size_riff(dataChunkSize);
DRWAV_PRIVATE drwav_uint64 drwav__riff_chunk_size_rf64(drwav_uint64 dataChunkSize, drwav_metadata *metadata, drwav_uint32 numMetadata)
MA_PRIVATE ma_uint64 ma_dr_wav__riff_chunk_size_rf64(ma_uint64 dataChunkSize, ma_dr_wav_metadata *metadata, ma_uint32 numMetadata)
drwav_uint64 chunkSize = 4 + 36 + 24 + (drwav_uint64)drwav__write_or_count_metadata(NULL, metadata, numMetadata) + 8 + dataChunkSize + drwav__chunk_padding_size_riff(dataChunkSize);
ma_uint64 chunkSize = 4 + 36 + 24 + (ma_uint64)ma_dr_wav__write_or_count_metadata(NULL, metadata, numMetadata) + 8 + dataChunkSize + ma_dr_wav__chunk_padding_size_riff(dataChunkSize);
DRWAV_PRIVATE drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_format* pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_bool32 ma_dr_wav_preinit_write(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_bool32 isSequential, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) / 8);
pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) / 8);
pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
pWav->fmt.avgBytesPerSec = (ma_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) / 8);
pWav->fmt.blockAlign = (ma_uint16)((pFormat->channels * pFormat->bitsPerSample) / 8);
pWav->fmt.bitsPerSample = (ma_uint16)pFormat->bitsPerSample;
DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
MA_PRIVATE ma_bool32 ma_dr_wav_init_write__internal(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount)
if (pFormat->container == drwav_container_riff) {
drwav_uint32 chunkSizeRIFF = 28 + (drwav_uint32)initialDataChunkSize;
runningPos += drwav__write(pWav, "RIFF", 4);
runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeRIFF);
runningPos += drwav__write(pWav, "WAVE", 4);
} else if (pFormat->container == drwav_container_w64) {
drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize;
runningPos += drwav__write(pWav, drwavGUID_W64_RIFF, 16);
runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeRIFF);
runningPos += drwav__write(pWav, drwavGUID_W64_WAVE, 16);
} else if (pFormat->container == drwav_container_rf64) {
runningPos += drwav__write(pWav, "RF64", 4);
runningPos += drwav__write_u32ne_to_le(pWav, 0xFFFFFFFF);
runningPos += drwav__write(pWav, "WAVE", 4);
if (pFormat->container == ma_dr_wav_container_riff) {
ma_uint32 chunkSizeRIFF = 28 + (ma_uint32)initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, "RIFF", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, chunkSizeRIFF);
runningPos += ma_dr_wav__write(pWav, "WAVE", 4);
} else if (pFormat->container == ma_dr_wav_container_w64) {
ma_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, ma_dr_wavGUID_W64_RIFF, 16);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, chunkSizeRIFF);
runningPos += ma_dr_wav__write(pWav, ma_dr_wavGUID_W64_WAVE, 16);
} else if (pFormat->container == ma_dr_wav_container_rf64) {
runningPos += ma_dr_wav__write(pWav, "RF64", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, 0xFFFFFFFF);
runningPos += ma_dr_wav__write(pWav, "WAVE", 4);
} else {
return MA_FALSE;
if (pFormat->container == drwav_container_rf64) {
drwav_uint32 initialds64ChunkSize = 28;
drwav_uint64 initialRiffChunkSize = 8 + initialds64ChunkSize + initialDataChunkSize;
runningPos += drwav__write(pWav, "ds64", 4);
runningPos += drwav__write_u32ne_to_le(pWav, initialds64ChunkSize);
runningPos += drwav__write_u64ne_to_le(pWav, initialRiffChunkSize);
runningPos += drwav__write_u64ne_to_le(pWav, initialDataChunkSize);
runningPos += drwav__write_u64ne_to_le(pWav, totalSampleCount);
runningPos += drwav__write_u32ne_to_le(pWav, 0);
if (pFormat->container == ma_dr_wav_container_rf64) {
ma_uint32 initialds64ChunkSize = 28;
ma_uint64 initialRiffChunkSize = 8 + initialds64ChunkSize + initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, "ds64", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, initialds64ChunkSize);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, initialRiffChunkSize);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, initialDataChunkSize);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, totalSampleCount);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, 0);
runningPos += drwav__write(pWav, "fmt ", 4);
runningPos += drwav__write_u32ne_to_le(pWav, (drwav_uint32)chunkSizeFMT);
} else if (pFormat->container == drwav_container_w64) {
runningPos += ma_dr_wav__write(pWav, "fmt ", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, (ma_uint32)chunkSizeFMT);
} else if (pFormat->container == ma_dr_wav_container_w64) {
runningPos += drwav__write(pWav, drwavGUID_W64_FMT, 16);
runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeFMT);
runningPos += ma_dr_wav__write(pWav, ma_dr_wavGUID_W64_FMT, 16);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, chunkSizeFMT);
runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.formatTag);
runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.channels);
runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.sampleRate);
runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.avgBytesPerSec);
runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.blockAlign);
runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.bitsPerSample);
if (!pWav->isSequentialWrite && pWav->pMetadata != NULL && pWav->metadataCount > 0 && (pFormat->container == drwav_container_riff || pFormat->container == drwav_container_rf64)) {
runningPos += drwav__write_or_count_metadata(pWav, pWav->pMetadata, pWav->metadataCount);
runningPos += ma_dr_wav__write_u16ne_to_le(pWav, pWav->fmt.formatTag);
runningPos += ma_dr_wav__write_u16ne_to_le(pWav, pWav->fmt.channels);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, pWav->fmt.sampleRate);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, pWav->fmt.avgBytesPerSec);
runningPos += ma_dr_wav__write_u16ne_to_le(pWav, pWav->fmt.blockAlign);
runningPos += ma_dr_wav__write_u16ne_to_le(pWav, pWav->fmt.bitsPerSample);
if (!pWav->isSequentialWrite && pWav->pMetadata != NULL && pWav->metadataCount > 0 && (pFormat->container == ma_dr_wav_container_riff || pFormat->container == ma_dr_wav_container_rf64)) {
runningPos += ma_dr_wav__write_or_count_metadata(pWav, pWav->pMetadata, pWav->metadataCount);
if (pFormat->container == drwav_container_riff) {
drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize;
runningPos += drwav__write(pWav, "data", 4);
runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeDATA);
} else if (pFormat->container == drwav_container_w64) {
drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize;
runningPos += drwav__write(pWav, drwavGUID_W64_DATA, 16);
runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeDATA);
} else if (pFormat->container == drwav_container_rf64) {
runningPos += drwav__write(pWav, "data", 4);
runningPos += drwav__write_u32ne_to_le(pWav, 0xFFFFFFFF);
if (pFormat->container == ma_dr_wav_container_riff) {
ma_uint32 chunkSizeDATA = (ma_uint32)initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, "data", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, chunkSizeDATA);
} else if (pFormat->container == ma_dr_wav_container_w64) {
ma_uint64 chunkSizeDATA = 24 + initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, ma_dr_wavGUID_W64_DATA, 16);
runningPos += ma_dr_wav__write_u64ne_to_le(pWav, chunkSizeDATA);
} else if (pFormat->container == ma_dr_wav_container_rf64) {
runningPos += ma_dr_wav__write(pWav, "data", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, 0xFFFFFFFF);
DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_write(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit_write(pWav, pFormat, MA_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_write_sequential(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
if (!drwav_preinit_write(pWav, pFormat, DRWAV_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit_write(pWav, pFormat, MA_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_write_sequential_pcm_frames(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
return ma_dr_wav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata, drwav_uint32 metadataCount)
MA_API ma_bool32 ma_dr_wav_init_write_with_metadata(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks, ma_dr_wav_metadata* pMetadata, ma_uint32 metadataCount)
if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit_write(pWav, pFormat, MA_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalFrameCount, drwav_metadata* pMetadata, drwav_uint32 metadataCount)
MA_API ma_uint64 ma_dr_wav_target_write_size_bytes(const ma_dr_wav_data_format* pFormat, ma_uint64 totalFrameCount, ma_dr_wav_metadata* pMetadata, ma_uint32 metadataCount)
drwav_uint64 targetDataSizeBytes = (drwav_uint64)((drwav_int64)totalFrameCount * pFormat->channels * pFormat->bitsPerSample/8.0);
drwav_uint64 riffChunkSizeBytes;
drwav_uint64 fileSizeBytes = 0;
if (pFormat->container == drwav_container_riff) {
riffChunkSizeBytes = drwav__riff_chunk_size_riff(targetDataSizeBytes, pMetadata, metadataCount);
ma_uint64 targetDataSizeBytes = (ma_uint64)((ma_int64)totalFrameCount * pFormat->channels * pFormat->bitsPerSample/8.0);
ma_uint64 riffChunkSizeBytes;
ma_uint64 fileSizeBytes = 0;
if (pFormat->container == ma_dr_wav_container_riff) {
riffChunkSizeBytes = ma_dr_wav__riff_chunk_size_riff(targetDataSizeBytes, pMetadata, metadataCount);
} else if (pFormat->container == drwav_container_w64) {
riffChunkSizeBytes = drwav__riff_chunk_size_w64(targetDataSizeBytes);
} else if (pFormat->container == ma_dr_wav_container_w64) {
riffChunkSizeBytes = ma_dr_wav__riff_chunk_size_w64(targetDataSizeBytes);
} else if (pFormat->container == drwav_container_rf64) {
riffChunkSizeBytes = drwav__riff_chunk_size_rf64(targetDataSizeBytes, pMetadata, metadataCount);
} else if (pFormat->container == ma_dr_wav_container_rf64) {
riffChunkSizeBytes = ma_dr_wav__riff_chunk_size_rf64(targetDataSizeBytes, pMetadata, metadataCount);
switch (e)
{
case 0: return DRWAV_SUCCESS;
#ifdef EPERM
case EPERM: return DRWAV_INVALID_OPERATION;
#endif
#ifdef ENOENT
case ENOENT: return DRWAV_DOES_NOT_EXIST;
#endif
#ifdef ESRCH
case ESRCH: return DRWAV_DOES_NOT_EXIST;
#endif
#ifdef EINTR
case EINTR: return DRWAV_INTERRUPT;
#endif
#ifdef EIO
case EIO: return DRWAV_IO_ERROR;
#endif
#ifdef ENXIO
case ENXIO: return DRWAV_DOES_NOT_EXIST;
#endif
#ifdef E2BIG
case E2BIG: return DRWAV_INVALID_ARGS;
#endif
#ifdef ENOEXEC
case ENOEXEC: return DRWAV_INVALID_FILE;
#endif
#ifdef EBADF
case EBADF: return DRWAV_INVALID_FILE;
#endif
#ifdef ECHILD
case ECHILD: return DRWAV_ERROR;
#endif
#ifdef EAGAIN
case EAGAIN: return DRWAV_UNAVAILABLE;
#endif
#ifdef ENOMEM
case ENOMEM: return DRWAV_OUT_OF_MEMORY;
#endif
#ifdef EACCES
case EACCES: return DRWAV_ACCESS_DENIED;
#endif
#ifdef EFAULT
case EFAULT: return DRWAV_BAD_ADDRESS;
#endif
#ifdef ENOTBLK
case ENOTBLK: return DRWAV_ERROR;
#endif
#ifdef EBUSY
case EBUSY: return DRWAV_BUSY;
#endif
#ifdef EEXIST
case EEXIST: return DRWAV_ALREADY_EXISTS;
#endif
#ifdef EXDEV
case EXDEV: return DRWAV_ERROR;
#endif
#ifdef ENODEV
case ENODEV: return DRWAV_DOES_NOT_EXIST;
#endif
#ifdef ENOTDIR
case ENOTDIR: return DRWAV_NOT_DIRECTORY;
#endif
#ifdef EISDIR
case EISDIR: return DRWAV_IS_DIRECTORY;
#endif
#ifdef EINVAL
case EINVAL: return DRWAV_INVALID_ARGS;
#endif
#ifdef ENFILE
case ENFILE: return DRWAV_TOO_MANY_OPEN_FILES;
#endif
#ifdef EMFILE
case EMFILE: return DRWAV_TOO_MANY_OPEN_FILES;
#endif
#ifdef ENOTTY
case ENOTTY: return DRWAV_INVALID_OPERATION;
#endif
#ifdef ETXTBSY
case ETXTBSY: return DRWAV_BUSY;
#endif
#ifdef EFBIG
case EFBIG: return DRWAV_TOO_BIG;
#endif
#ifdef ENOSPC
case ENOSPC: return DRWAV_NO_SPACE;
#endif
#ifdef ESPIPE
case ESPIPE: return DRWAV_BAD_SEEK;
#endif
#ifdef EROFS
case EROFS: return DRWAV_ACCESS_DENIED;
#endif
#ifdef EMLINK
case EMLINK: return DRWAV_TOO_MANY_LINKS;
#endif
#ifdef EPIPE
case EPIPE: return DRWAV_BAD_PIPE;
#endif
#ifdef EDOM
case EDOM: return DRWAV_OUT_OF_RANGE;
#endif
#ifdef ERANGE
case ERANGE: return DRWAV_OUT_OF_RANGE;
#endif
#ifdef EDEADLK
case EDEADLK: return DRWAV_DEADLOCK;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG: return DRWAV_PATH_TOO_LONG;
#endif
#ifdef ENOLCK
case ENOLCK: return DRWAV_ERROR;
#endif
#ifdef ENOSYS
case ENOSYS: return DRWAV_NOT_IMPLEMENTED;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY: return DRWAV_DIRECTORY_NOT_EMPTY;
#endif
#ifdef ELOOP
case ELOOP: return DRWAV_TOO_MANY_LINKS;
#endif
#ifdef ENOMSG
case ENOMSG: return DRWAV_NO_MESSAGE;
#endif
#ifdef EIDRM
case EIDRM: return DRWAV_ERROR;
#endif
#ifdef ECHRNG
case ECHRNG: return DRWAV_ERROR;
#endif
#ifdef EL2NSYNC
case EL2NSYNC: return DRWAV_ERROR;
#endif
#ifdef EL3HLT
case EL3HLT: return DRWAV_ERROR;
#endif
#ifdef EL3RST
case EL3RST: return DRWAV_ERROR;
#endif
#ifdef ELNRNG
case ELNRNG: return DRWAV_OUT_OF_RANGE;
#endif
#ifdef EUNATCH
case EUNATCH: return DRWAV_ERROR;
#endif
#ifdef ENOCSI
case ENOCSI: return DRWAV_ERROR;
#endif
#ifdef EL2HLT
case EL2HLT: return DRWAV_ERROR;
#endif
#ifdef EBADE
case EBADE: return DRWAV_ERROR;
#endif
#ifdef EBADR
case EBADR: return DRWAV_ERROR;
#endif
#ifdef EXFULL
case EXFULL: return DRWAV_ERROR;
#endif
#ifdef ENOANO
case ENOANO: return DRWAV_ERROR;
#endif
#ifdef EBADRQC
case EBADRQC: return DRWAV_ERROR;
#endif
#ifdef EBADSLT
case EBADSLT: return DRWAV_ERROR;
#endif
#ifdef EBFONT
case EBFONT: return DRWAV_INVALID_FILE;
#endif
#ifdef ENOSTR
case ENOSTR: return DRWAV_ERROR;
#endif
#ifdef ENODATA
case ENODATA: return DRWAV_NO_DATA_AVAILABLE;
#endif
#ifdef ETIME
case ETIME: return DRWAV_TIMEOUT;
#endif
#ifdef ENOSR
case ENOSR: return DRWAV_NO_DATA_AVAILABLE;
#endif
#ifdef ENONET
case ENONET: return DRWAV_NO_NETWORK;
#endif
#ifdef ENOPKG
case ENOPKG: return DRWAV_ERROR;
#endif
#ifdef EREMOTE
case EREMOTE: return DRWAV_ERROR;
#endif
#ifdef ENOLINK
case ENOLINK: return DRWAV_ERROR;
#endif
#ifdef EADV
case EADV: return DRWAV_ERROR;
#endif
#ifdef ESRMNT
case ESRMNT: return DRWAV_ERROR;
#endif
#ifdef ECOMM
case ECOMM: return DRWAV_ERROR;
#endif
#ifdef EPROTO
case EPROTO: return DRWAV_ERROR;
#endif
#ifdef EMULTIHOP
case EMULTIHOP: return DRWAV_ERROR;
#endif
#ifdef EDOTDOT
case EDOTDOT: return DRWAV_ERROR;
#endif
#ifdef EBADMSG
case EBADMSG: return DRWAV_BAD_MESSAGE;
#endif
#ifdef EOVERFLOW
case EOVERFLOW: return DRWAV_TOO_BIG;
#endif
#ifdef ENOTUNIQ
case ENOTUNIQ: return DRWAV_NOT_UNIQUE;
#endif
#ifdef EBADFD
case EBADFD: return DRWAV_ERROR;
#endif
#ifdef EREMCHG
case EREMCHG: return DRWAV_ERROR;
#endif
#ifdef ELIBACC
case ELIBACC: return DRWAV_ACCESS_DENIED;
#endif
#ifdef ELIBBAD
case ELIBBAD: return DRWAV_INVALID_FILE;
#endif
#ifdef ELIBSCN
case ELIBSCN: return DRWAV_INVALID_FILE;
#endif
#ifdef ELIBMAX
case ELIBMAX: return DRWAV_ERROR;
#endif
#ifdef ELIBEXEC
case ELIBEXEC: return DRWAV_ERROR;
#endif
#ifdef EILSEQ
case EILSEQ: return DRWAV_INVALID_DATA;
#endif
#ifdef ERESTART
case ERESTART: return DRWAV_ERROR;
#endif
#ifdef ESTRPIPE
case ESTRPIPE: return DRWAV_ERROR;
#endif
#ifdef EUSERS
case EUSERS: return DRWAV_ERROR;
#endif
#ifdef ENOTSOCK
case ENOTSOCK: return DRWAV_NOT_SOCKET;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ: return DRWAV_NO_ADDRESS;
#endif
#ifdef EMSGSIZE
case EMSGSIZE: return DRWAV_TOO_BIG;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE: return DRWAV_BAD_PROTOCOL;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT: return DRWAV_PROTOCOL_UNAVAILABLE;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT: return DRWAV_PROTOCOL_NOT_SUPPORTED;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT: return DRWAV_SOCKET_NOT_SUPPORTED;
#endif
#ifdef EOPNOTSUPP
case EOPNOTSUPP: return DRWAV_INVALID_OPERATION;
#endif
#ifdef EPFNOSUPPORT
case EPFNOSUPPORT: return DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT: return DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EADDRINUSE
case EADDRINUSE: return DRWAV_ALREADY_IN_USE;
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: return DRWAV_ERROR;
#endif
#ifdef ENETDOWN
case ENETDOWN: return DRWAV_NO_NETWORK;
#endif
#ifdef ENETUNREACH
case ENETUNREACH: return DRWAV_NO_NETWORK;
#endif
#ifdef ENETRESET
case ENETRESET: return DRWAV_NO_NETWORK;
#endif
#ifdef ECONNABORTED
case ECONNABORTED: return DRWAV_NO_NETWORK;
#endif
#ifdef ECONNRESET
case ECONNRESET: return DRWAV_CONNECTION_RESET;
#endif
#ifdef ENOBUFS
case ENOBUFS: return DRWAV_NO_SPACE;
#endif
#ifdef EISCONN
case EISCONN: return DRWAV_ALREADY_CONNECTED;
#endif
#ifdef ENOTCONN
case ENOTCONN: return DRWAV_NOT_CONNECTED;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: return DRWAV_ERROR;
#endif
#ifdef ETOOMANYREFS
case ETOOMANYREFS: return DRWAV_ERROR;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: return DRWAV_TIMEOUT;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: return DRWAV_CONNECTION_REFUSED;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: return DRWAV_NO_HOST;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: return DRWAV_NO_HOST;
#endif
#ifdef EALREADY
case EALREADY: return DRWAV_IN_PROGRESS;
#endif
#ifdef EINPROGRESS
case EINPROGRESS: return DRWAV_IN_PROGRESS;
#endif
#ifdef ESTALE
case ESTALE: return DRWAV_INVALID_FILE;
#endif
#ifdef EUCLEAN
case EUCLEAN: return DRWAV_ERROR;
#endif
#ifdef ENOTNAM
case ENOTNAM: return DRWAV_ERROR;
#endif
#ifdef ENAVAIL
case ENAVAIL: return DRWAV_ERROR;
#endif
#ifdef EISNAM
case EISNAM: return DRWAV_ERROR;
#endif
#ifdef EREMOTEIO
case EREMOTEIO: return DRWAV_IO_ERROR;
#endif
#ifdef EDQUOT
case EDQUOT: return DRWAV_NO_SPACE;
#endif
#ifdef ENOMEDIUM
case ENOMEDIUM: return DRWAV_DOES_NOT_EXIST;
#endif
#ifdef EMEDIUMTYPE
case EMEDIUMTYPE: return DRWAV_ERROR;
#endif
#ifdef ECANCELED
case ECANCELED: return DRWAV_CANCELLED;
#endif
#ifdef ENOKEY
case ENOKEY: return DRWAV_ERROR;
#endif
#ifdef EKEYEXPIRED
case EKEYEXPIRED: return DRWAV_ERROR;
#endif
#ifdef EKEYREVOKED
case EKEYREVOKED: return DRWAV_ERROR;
#endif
#ifdef EKEYREJECTED
case EKEYREJECTED: return DRWAV_ERROR;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD: return DRWAV_ERROR;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE: return DRWAV_ERROR;
#endif
#ifdef ERFKILL
case ERFKILL: return DRWAV_ERROR;
#endif
#ifdef EHWPOISON
case EHWPOISON: return DRWAV_ERROR;
#endif
default: return DRWAV_ERROR;
}
}
DRWAV_PRIVATE drwav_result drwav_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err;
#endif
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRWAV_INVALID_ARGS;
}
#if defined(_MSC_VER) && _MSC_VER >= 1400
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drwav_result_from_errno(err);
}
#else
#if defined(_WIN32) || defined(__APPLE__)
*ppFile = fopen(pFilePath, pOpenMode);
#else
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
*ppFile = fopen64(pFilePath, pOpenMode);
#else
*ppFile = fopen(pFilePath, pOpenMode);
#endif
#endif
if (*ppFile == NULL) {
drwav_result result = drwav_result_from_errno(errno);
if (result == DRWAV_SUCCESS) {
result = DRWAV_ERROR;
}
return result;
}
#endif
return DRWAV_SUCCESS;
}
#if defined(_WIN32)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define DRWAV_HAS_WFOPEN
#endif
#endif
DRWAV_PRIVATE drwav_result drwav_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drwav_allocation_callbacks* pAllocationCallbacks)
{
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRWAV_INVALID_ARGS;
}
#if defined(DRWAV_HAS_WFOPEN)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drwav_result_from_errno(err);
}
#else
*ppFile = _wfopen(pFilePath, pOpenMode);
if (*ppFile == NULL) {
return drwav_result_from_errno(errno);
}
#endif
(void)pAllocationCallbacks;
}
#else
{
mbstate_t mbs;
size_t lenMB;
const wchar_t* pFilePathTemp = pFilePath;
char* pFilePathMB = NULL;
char pOpenModeMB[32] = {0};
DRWAV_ZERO_OBJECT(&mbs);
lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
if (lenMB == (size_t)-1) {
return drwav_result_from_errno(errno);
}
pFilePathMB = (char*)drwav__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
if (pFilePathMB == NULL) {
return DRWAV_OUT_OF_MEMORY;
}
pFilePathTemp = pFilePath;
DRWAV_ZERO_OBJECT(&mbs);
wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
{
size_t i = 0;
for (;;) {
if (pOpenMode[i] == 0) {
pOpenModeMB[i] = '\0';
break;
}
pOpenModeMB[i] = (char)pOpenMode[i];
i += 1;
}
}
*ppFile = fopen(pFilePathMB, pOpenModeMB);
drwav__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
}
if (*ppFile == NULL) {
return DRWAV_ERROR;
}
#endif
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file(ma_dr_wav* pWav, const char* filename, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFile, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, drwav_metadata_type allowedMetadataTypes, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_bool32 ma_dr_wav_init_file__internal_FILE(ma_dr_wav* pWav, FILE* pFile, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
drwav_bool32 result;
result = drwav_preinit(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRWAV_TRUE) {
ma_bool32 result;
result = ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_stdio, ma_dr_wav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != MA_TRUE) {
pWav->allowedMetadataTypes = allowedMetadataTypes;
result = drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
if (result != DRWAV_TRUE) {
result = ma_dr_wav_init__internal(pWav, onChunk, pChunkUserData, flags);
if (result != MA_TRUE) {
DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_ex(ma_dr_wav* pWav, const char* filename, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks);
return ma_dr_wav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_WCHAR
MA_API ma_bool32 ma_dr_wav_init_file_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_ex_w(ma_dr_wav* pWav, const wchar_t* filename, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks);
return ma_dr_wav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
#endif
MA_API ma_bool32 ma_dr_wav_init_file_with_metadata(ma_dr_wav* pWav, const char* filename, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks);
return ma_dr_wav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags | MA_DR_WAV_WITH_METADATA, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_t* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_WCHAR
MA_API ma_bool32 ma_dr_wav_init_file_with_metadata_w(ma_dr_wav* pWav, const wchar_t* filename, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks);
return ma_dr_wav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags | MA_DR_WAV_WITH_METADATA, pAllocationCallbacks);
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal_FILE(drwav* pWav, FILE* pFile, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
#endif
MA_PRIVATE ma_bool32 ma_dr_wav_init_file_write__internal_FILE(ma_dr_wav* pWav, FILE* pFile, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_bool32 isSequential, const ma_allocation_callbacks* pAllocationCallbacks)
drwav_bool32 result;
result = drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRWAV_TRUE) {
ma_bool32 result;
result = ma_dr_wav_preinit_write(pWav, pFormat, isSequential, ma_dr_wav__on_write_stdio, ma_dr_wav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != MA_TRUE) {
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_bool32 ma_dr_wav_init_file_write__internal(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_bool32 isSequential, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
return ma_dr_wav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write_w__internal(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_WCHAR
MA_PRIVATE ma_bool32 ma_dr_wav_init_file_write_w__internal(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_bool32 isSequential, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
return ma_dr_wav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
#endif
MA_API ma_bool32 ma_dr_wav_init_file_write(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_pcm_frames(ma_dr_wav* pWav, const char* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
return ma_dr_wav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_WCHAR
MA_API ma_bool32 ma_dr_wav_init_file_write_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
return ma_dr_wav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, MA_TRUE, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_file_write_sequential_pcm_frames_w(ma_dr_wav* pWav, const wchar_t* filename, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
return ma_dr_wav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->memoryStreamWrite.dataCapacity >= pWav->memoryStreamWrite.currentWritePos);
MA_DR_WAV_ASSERT(pWav != NULL);
MA_DR_WAV_ASSERT(pWav->memoryStreamWrite.dataCapacity >= pWav->memoryStreamWrite.currentWritePos);
pNewData = drwav__realloc_from_callbacks(*pWav->memoryStreamWrite.ppData, newDataCapacity, pWav->memoryStreamWrite.dataCapacity, &pWav->allocationCallbacks);
pNewData = ma_dr_wav__realloc_from_callbacks(*pWav->memoryStreamWrite.ppData, newDataCapacity, pWav->memoryStreamWrite.dataCapacity, &pWav->allocationCallbacks);
DRWAV_COPY_MEMORY(((drwav_uint8*)(*pWav->memoryStreamWrite.ppData)) + pWav->memoryStreamWrite.currentWritePos, pDataIn, bytesToWrite);
MA_DR_WAV_COPY_MEMORY(((ma_uint8*)(*pWav->memoryStreamWrite.ppData)) + pWav->memoryStreamWrite.currentWritePos, pDataIn, bytesToWrite);
DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory(ma_dr_wav* pWav, const void* data, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory_ex(ma_dr_wav* pWav, const void* data, size_t dataSize, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
if (!drwav_preinit(pWav, drwav__on_read_memory, drwav__on_seek_memory, pWav, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, pWav, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory_with_metadata(ma_dr_wav* pWav, const void* data, size_t dataSize, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
if (!drwav_preinit(pWav, drwav__on_read_memory, drwav__on_seek_memory, pWav, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, pWav, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_PRIVATE drwav_bool32 drwav_init_memory_write__internal(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_PRIVATE ma_bool32 ma_dr_wav_init_memory_write__internal(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_bool32 isSequential, const ma_allocation_callbacks* pAllocationCallbacks)
if (!drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_memory, drwav__on_seek_memory_write, pWav, pAllocationCallbacks)) {
return DRWAV_FALSE;
if (!ma_dr_wav_preinit_write(pWav, pFormat, isSequential, ma_dr_wav__on_write_memory, ma_dr_wav__on_seek_memory_write, pWav, pAllocationCallbacks)) {
return MA_FALSE;
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory_write(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
return ma_dr_wav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, MA_TRUE, pAllocationCallbacks);
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential_pcm_frames(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
return drwav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
return ma_dr_wav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
drwav_uint32 paddingSize = 0;
if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
paddingSize = drwav__chunk_padding_size_riff(pWav->dataChunkDataSize);
ma_uint32 paddingSize = 0;
if (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rf64) {
paddingSize = ma_dr_wav__chunk_padding_size_riff(pWav->dataChunkDataSize);
if (pWav->container == drwav_container_riff) {
if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) {
drwav_uint32 riffChunkSize = drwav__riff_chunk_size_riff(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
drwav__write_u32ne_to_le(pWav, riffChunkSize);
if (pWav->container == ma_dr_wav_container_riff) {
if (pWav->onSeek(pWav->pUserData, 4, ma_dr_wav_seek_origin_start)) {
ma_uint32 riffChunkSize = ma_dr_wav__riff_chunk_size_riff(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
ma_dr_wav__write_u32ne_to_le(pWav, riffChunkSize);
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 4, drwav_seek_origin_start)) {
drwav_uint32 dataChunkSize = drwav__data_chunk_size_riff(pWav->dataChunkDataSize);
drwav__write_u32ne_to_le(pWav, dataChunkSize);
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 4, ma_dr_wav_seek_origin_start)) {
ma_uint32 dataChunkSize = ma_dr_wav__data_chunk_size_riff(pWav->dataChunkDataSize);
ma_dr_wav__write_u32ne_to_le(pWav, dataChunkSize);
} else if (pWav->container == drwav_container_w64) {
if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) {
drwav_uint64 riffChunkSize = drwav__riff_chunk_size_w64(pWav->dataChunkDataSize);
drwav__write_u64ne_to_le(pWav, riffChunkSize);
} else if (pWav->container == ma_dr_wav_container_w64) {
if (pWav->onSeek(pWav->pUserData, 16, ma_dr_wav_seek_origin_start)) {
ma_uint64 riffChunkSize = ma_dr_wav__riff_chunk_size_w64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, riffChunkSize);
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 8, drwav_seek_origin_start)) {
drwav_uint64 dataChunkSize = drwav__data_chunk_size_w64(pWav->dataChunkDataSize);
drwav__write_u64ne_to_le(pWav, dataChunkSize);
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 8, ma_dr_wav_seek_origin_start)) {
ma_uint64 dataChunkSize = ma_dr_wav__data_chunk_size_w64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, dataChunkSize);
if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 0, drwav_seek_origin_start)) {
drwav_uint64 riffChunkSize = drwav__riff_chunk_size_rf64(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
drwav__write_u64ne_to_le(pWav, riffChunkSize);
if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 0, ma_dr_wav_seek_origin_start)) {
ma_uint64 riffChunkSize = ma_dr_wav__riff_chunk_size_rf64(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
ma_dr_wav__write_u64ne_to_le(pWav, riffChunkSize);
if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 8, drwav_seek_origin_start)) {
drwav_uint64 dataChunkSize = drwav__data_chunk_size_rf64(pWav->dataChunkDataSize);
drwav__write_u64ne_to_le(pWav, dataChunkSize);
if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 8, ma_dr_wav_seek_origin_start)) {
ma_uint64 dataChunkSize = ma_dr_wav__data_chunk_size_rf64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, dataChunkSize);
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
framesRemainingInFile = pWav->totalPCMFrameCount - pWav->readCursorInPCMFrames;
if (framesToRead > framesRemainingInFile) {
framesToRead = framesRemainingInFile;
}
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
if (drwav__is_little_endian()) {
return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
ma_uint64 framesRead = 0;
if (ma_dr_wav_is_container_be(pWav->container)) {
if (pWav->container != ma_dr_wav_container_aiff || pWav->aiff.isLE == MA_FALSE) {
if (ma_dr_wav__is_little_endian()) {
framesRead = ma_dr_wav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
} else {
framesRead = ma_dr_wav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
}
goto post_process;
}
}
if (ma_dr_wav__is_little_endian()) {
framesRead = ma_dr_wav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
framesRead = ma_dr_wav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
}
post_process:
{
if (pWav->container == ma_dr_wav_container_aiff && pWav->bitsPerSample == 8 && pWav->aiff.isUnsigned == MA_FALSE) {
if (pBufferOut != NULL) {
ma_uint64 iSample;
for (iSample = 0; iSample < framesRead * pWav->channels; iSample += 1) {
((ma_uint8*)pBufferOut)[iSample] += 128;
}
}
}
if (drwav__is_compressed_format_tag(pWav->translatedFormatTag)) {
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
DRWAV_ZERO_OBJECT(&pWav->msadpcm);
} else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
DRWAV_ZERO_OBJECT(&pWav->ima);
if (ma_dr_wav__is_compressed_format_tag(pWav->translatedFormatTag)) {
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
MA_DR_WAV_ZERO_OBJECT(&pWav->msadpcm);
} else if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
MA_DR_WAV_ZERO_OBJECT(&pWav->ima);
drwav_uint64 framesRead = 0;
drwav_uint64 framesToRead = offsetInFrames;
if (framesToRead > drwav_countof(devnull)/pWav->channels) {
framesToRead = drwav_countof(devnull)/pWav->channels;
ma_uint64 framesRead = 0;
ma_uint64 framesToRead = offsetInFrames;
if (framesToRead > ma_dr_wav_countof(devnull)/pWav->channels) {
framesToRead = ma_dr_wav_countof(devnull)/pWav->channels;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
framesRead = drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
} else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
framesRead = drwav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
framesRead = ma_dr_wav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
} else if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
framesRead = ma_dr_wav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
drwav_uint64 totalSizeInBytes;
drwav_uint64 currentBytePos;
drwav_uint64 targetBytePos;
drwav_uint64 offset;
drwav_uint32 bytesPerFrame;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalSizeInBytes;
ma_uint64 currentBytePos;
ma_uint64 targetBytePos;
ma_uint64 offset;
ma_uint32 bytesPerFrame;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX);
bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
MA_DR_WAV_ASSERT(bytesToWriteThisIteration <= MA_SIZE_MAX);
bytesJustWritten = ma_dr_wav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
if (bytesToWriteThisIteration > ((drwav_uint64)sampleCount)*bytesPerSample) {
bytesToWriteThisIteration = ((drwav_uint64)sampleCount)*bytesPerSample;
if (bytesToWriteThisIteration > ((ma_uint64)sampleCount)*bytesPerSample) {
bytesToWriteThisIteration = ((ma_uint64)sampleCount)*bytesPerSample;
DRWAV_COPY_MEMORY(temp, pRunningData, (size_t)bytesToWriteThisIteration);
drwav__bswap_samples(temp, sampleCount, bytesPerSample, pWav->translatedFormatTag);
bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
MA_DR_WAV_COPY_MEMORY(temp, pRunningData, (size_t)bytesToWriteThisIteration);
ma_dr_wav__bswap_samples(temp, sampleCount, bytesPerSample);
bytesJustWritten = ma_dr_wav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
pWav->msadpcm.delta[0] = drwav_bytes_to_s16(header + 1);
pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav_bytes_to_s16(header + 3);
pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav_bytes_to_s16(header + 5);
pWav->msadpcm.delta[0] = ma_dr_wav_bytes_to_s16(header + 1);
pWav->msadpcm.prevFrames[0][1] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 3);
pWav->msadpcm.prevFrames[0][0] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 5);
pWav->msadpcm.delta[0] = drwav_bytes_to_s16(header + 2);
pWav->msadpcm.delta[1] = drwav_bytes_to_s16(header + 4);
pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav_bytes_to_s16(header + 6);
pWav->msadpcm.prevFrames[1][1] = (drwav_int32)drwav_bytes_to_s16(header + 8);
pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav_bytes_to_s16(header + 10);
pWav->msadpcm.prevFrames[1][0] = (drwav_int32)drwav_bytes_to_s16(header + 12);
pWav->msadpcm.delta[0] = ma_dr_wav_bytes_to_s16(header + 2);
pWav->msadpcm.delta[1] = ma_dr_wav_bytes_to_s16(header + 4);
pWav->msadpcm.prevFrames[0][1] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 6);
pWav->msadpcm.prevFrames[1][1] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 8);
pWav->msadpcm.prevFrames[0][0] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 10);
pWav->msadpcm.prevFrames[1][0] = (ma_int32)ma_dr_wav_bytes_to_s16(header + 12);
pBufferOut[iSample] = (drwav_int16)pWav->msadpcm.cachedFrames[(drwav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
pBufferOut[iSample] = (ma_int16)pWav->msadpcm.cachedFrames[(ma_dr_wav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
static drwav_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
drwav_uint8 nibbles;
drwav_int32 nibble0;
drwav_int32 nibble1;
static ma_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
static ma_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
ma_uint8 nibbles;
ma_int32 nibble0;
ma_int32 nibble1;
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
if (header[2] >= drwav_countof(stepTable)) {
pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, drwav_seek_origin_current);
if (header[2] >= ma_dr_wav_countof(stepTable)) {
pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, ma_dr_wav_seek_origin_current);
pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0];
pWav->ima.predictor[0] = (ma_int16)ma_dr_wav_bytes_to_u16(header + 0);
pWav->ima.stepIndex[0] = ma_dr_wav_clamp(header[2], 0, (ma_int32)ma_dr_wav_countof(stepTable)-1);
pWav->ima.cachedFrames[ma_dr_wav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0];
if (header[2] >= drwav_countof(stepTable) || header[6] >= drwav_countof(stepTable)) {
pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, drwav_seek_origin_current);
if (header[2] >= ma_dr_wav_countof(stepTable) || header[6] >= ma_dr_wav_countof(stepTable)) {
pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, ma_dr_wav_seek_origin_current);
pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.predictor[1] = drwav_bytes_to_s16(header + 4);
pWav->ima.stepIndex[1] = drwav_clamp(header[6], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
pWav->ima.predictor[0] = ma_dr_wav_bytes_to_s16(header + 0);
pWav->ima.stepIndex[0] = ma_dr_wav_clamp(header[2], 0, (ma_int32)ma_dr_wav_countof(stepTable)-1);
pWav->ima.predictor[1] = ma_dr_wav_bytes_to_s16(header + 4);
pWav->ima.stepIndex[1] = ma_dr_wav_clamp(header[6], 0, (ma_int32)ma_dr_wav_countof(stepTable)-1);
pWav->ima.cachedFrames[ma_dr_wav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
pWav->ima.cachedFrames[ma_dr_wav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
pBufferOut[iSample] = (drwav_int16)pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
pBufferOut[iSample] = (ma_int16)pWav->ima.cachedFrames[(ma_dr_wav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
drwav_uint8 nibble0 = ((nibbles[iByte] & 0x0F) >> 0);
drwav_uint8 nibble1 = ((nibbles[iByte] & 0xF0) >> 4);
drwav_int32 step = stepTable[pWav->ima.stepIndex[iChannel]];
drwav_int32 predictor = pWav->ima.predictor[iChannel];
drwav_int32 diff = step >> 3;
ma_uint8 nibble0 = ((nibbles[iByte] & 0x0F) >> 0);
ma_uint8 nibble1 = ((nibbles[iByte] & 0xF0) >> 4);
ma_int32 step = stepTable[pWav->ima.stepIndex[iChannel]];
ma_int32 predictor = pWav->ima.predictor[iChannel];
ma_int32 diff = step >> 3;
pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble0], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+0)*pWav->channels + iChannel] = predictor;
pWav->ima.stepIndex[iChannel] = ma_dr_wav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble0], 0, (ma_int32)ma_dr_wav_countof(stepTable)-1);
pWav->ima.cachedFrames[(ma_dr_wav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+0)*pWav->channels + iChannel] = predictor;
pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble1], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+1)*pWav->channels + iChannel] = predictor;
pWav->ima.stepIndex[iChannel] = ma_dr_wav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble1], 0, (ma_int32)ma_dr_wav_countof(stepTable)-1);
pWav->ima.cachedFrames[(ma_dr_wav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+1)*pWav->channels + iChannel] = predictor;
DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__pcm_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
DRWAV_PRIVATE void drwav__ieee_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__ieee_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__pcm(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
if ((pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
return ma_dr_wav_read_pcm_frames(pWav, framesToRead, pBufferOut);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ieee(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__alaw(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__mulaw(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
if (framesToRead * pWav->channels * sizeof(drwav_int16) > DRWAV_SIZE_MAX) {
framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int16) / pWav->channels;
if (framesToRead * pWav->channels * sizeof(ma_int16) > MA_SIZE_MAX) {
framesToRead = MA_SIZE_MAX / sizeof(ma_int16) / pWav->channels;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
return drwav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_PCM) {
return ma_dr_wav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
return drwav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_IEEE_FLOAT) {
return ma_dr_wav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
return drwav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ALAW) {
return ma_dr_wav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
return drwav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_MULAW) {
return ma_dr_wav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
return drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM) {
return ma_dr_wav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
return ma_dr_wav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_FALSE) {
ma_dr_wav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_TRUE) {
ma_dr_wav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
int x = ((int)(((unsigned int)(((const drwav_uint8*)pIn)[i*3+0]) << 8) | ((unsigned int)(((const drwav_uint8*)pIn)[i*3+1]) << 16) | ((unsigned int)(((const drwav_uint8*)pIn)[i*3+2])) << 24)) >> 8;
int x = ((int)(((unsigned int)(((const ma_uint8*)pIn)[i*3+0]) << 8) | ((unsigned int)(((const ma_uint8*)pIn)[i*3+1]) << 16) | ((unsigned int)(((const ma_uint8*)pIn)[i*3+2])) << 24)) >> 8;
DRWAV_PRIVATE void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__pcm_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
DRWAV_PRIVATE void drwav__ieee_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__ieee_to_f32(float* pOut, const ma_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_f32__msadpcm_ima(ma_dr_wav* pWav, ma_uint64 framesToRead, float* pBufferOut)
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, ma_dr_wav_countof(samples16)/pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
MA_DR_WAV_ASSERT(framesRead <= framesToReadThisIteration);
ma_dr_wav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
return ma_dr_wav_read_pcm_frames(pWav, framesToRead, pBufferOut);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
if (framesToRead * pWav->channels * sizeof(float) > DRWAV_SIZE_MAX) {
framesToRead = DRWAV_SIZE_MAX / sizeof(float) / pWav->channels;
if (framesToRead * pWav->channels * sizeof(float) > MA_SIZE_MAX) {
framesToRead = MA_SIZE_MAX / sizeof(float) / pWav->channels;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_PCM) {
return ma_dr_wav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_f32__msadpcm_ima(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
return ma_dr_wav_read_pcm_frames_f32__msadpcm_ima(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_IEEE_FLOAT) {
return ma_dr_wav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
return drwav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ALAW) {
return ma_dr_wav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_MULAW) {
return ma_dr_wav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_FALSE) {
ma_dr_wav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_TRUE) {
ma_dr_wav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
drwav_uint32 a = ((drwav_uint32)(pIn[i*3+0]) << 8);
drwav_uint32 b = ((drwav_uint32)(pIn[i*3+1]) << 16);
drwav_uint32 c = ((drwav_uint32)(pIn[i*3+2]) << 24);
x = (double)((drwav_int32)(a | b | c) >> 8);
ma_uint32 a = ((ma_uint32)(pIn[i*3+0]) << 8);
ma_uint32 b = ((ma_uint32)(pIn[i*3+1]) << 16);
ma_uint32 c = ((ma_uint32)(pIn[i*3+2]) << 24);
x = (double)((ma_int32)(a | b | c) >> 8);
DRWAV_PRIVATE void drwav__pcm_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__pcm_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
DRWAV_PRIVATE void drwav__ieee_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
MA_PRIVATE void ma_dr_wav__ieee_to_s32(ma_int32* pOut, const ma_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s32__pcm(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
return ma_dr_wav_read_pcm_frames(pWav, framesToRead, pBufferOut);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s32__msadpcm_ima(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut)
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, ma_dr_wav_countof(samples16)/pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
MA_DR_WAV_ASSERT(framesRead <= framesToReadThisIteration);
ma_dr_wav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s32__ieee(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s32__alaw(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s32__mulaw(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int32* pBufferOut)
drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
ma_uint64 totalFramesRead;
ma_uint8 sampleData[4096] = {0};
ma_uint32 bytesPerFrame;
ma_uint32 bytesPerSample;
ma_uint64 samplesRead;
bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
ma_uint64 framesToReadThisIteration = ma_dr_wav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
ma_dr_wav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
#ifdef MA_DR_WAV_LIBSNDFILE_COMPAT
{
if (pWav->container == ma_dr_wav_container_aiff) {
ma_uint64 iSample;
for (iSample = 0; iSample < samplesRead; iSample += 1) {
pBufferOut[iSample] = -pBufferOut[iSample];
}
}
}
#endif
if (framesToRead * pWav->channels * sizeof(drwav_int32) > DRWAV_SIZE_MAX) {
framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int32) / pWav->channels;
if (framesToRead * pWav->channels * sizeof(ma_int32) > MA_SIZE_MAX) {
framesToRead = MA_SIZE_MAX / sizeof(ma_int32) / pWav->channels;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_PCM) {
return ma_dr_wav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_s32__msadpcm_ima(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_DVI_ADPCM) {
return ma_dr_wav_read_pcm_frames_s32__msadpcm_ima(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_IEEE_FLOAT) {
return ma_dr_wav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW) {
return drwav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_ALAW) {
return ma_dr_wav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
if (pWav->translatedFormatTag == MA_DR_WAVE_FORMAT_MULAW) {
return ma_dr_wav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_FALSE) {
ma_dr_wav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
ma_uint64 framesRead = ma_dr_wav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL && ma_dr_wav__is_little_endian() == MA_TRUE) {
ma_dr_wav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
DRWAV_PRIVATE drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
MA_PRIVATE ma_int16* ma_dr_wav__read_pcm_frames_and_close_s16(ma_dr_wav* pWav, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalFrameCount)
drwav_uint64 sampleDataSize;
drwav_int16* pSampleData;
drwav_uint64 framesRead;
DRWAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
if (sampleDataSize > DRWAV_SIZE_MAX) {
drwav_uninit(pWav);
ma_uint64 sampleDataSize;
ma_int16* pSampleData;
ma_uint64 framesRead;
MA_DR_WAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int16);
if (sampleDataSize > MA_SIZE_MAX) {
ma_dr_wav_uninit(pWav);
DRWAV_PRIVATE float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
MA_PRIVATE float* ma_dr_wav__read_pcm_frames_and_close_f32(ma_dr_wav* pWav, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalFrameCount)
DRWAV_PRIVATE drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
MA_PRIVATE ma_int32* ma_dr_wav__read_pcm_frames_and_close_s32(ma_dr_wav* pWav, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalFrameCount)
drwav_uint64 sampleDataSize;
drwav_int32* pSampleData;
drwav_uint64 framesRead;
DRWAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
if (sampleDataSize > DRWAV_SIZE_MAX) {
drwav_uninit(pWav);
ma_uint64 sampleDataSize;
ma_int32* pSampleData;
ma_uint64 framesRead;
MA_DR_WAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int32);
if (sampleDataSize > MA_SIZE_MAX) {
ma_dr_wav_uninit(pWav);
DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
#ifndef DR_WAV_NO_STDIO
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_STDIO
MA_API ma_int16* ma_dr_wav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_wav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int32* ma_dr_wav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_WAV_NO_WCHAR
MA_API ma_int16* ma_dr_wav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_wav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int32* ma_dr_wav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
#endif
MA_API ma_int16* ma_dr_wav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_wav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int32* ma_dr_wav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
((drwav_uint64)data[0] << 0) | ((drwav_uint64)data[1] << 8) | ((drwav_uint64)data[2] << 16) | ((drwav_uint64)data[3] << 24) |
((drwav_uint64)data[4] << 32) | ((drwav_uint64)data[5] << 40) | ((drwav_uint64)data[6] << 48) | ((drwav_uint64)data[7] << 56);
((ma_uint64)data[0] << 0) | ((ma_uint64)data[1] << 8) | ((ma_uint64)data[2] << 16) | ((ma_uint64)data[3] << 24) |
((ma_uint64)data[4] << 32) | ((ma_uint64)data[5] << 40) | ((ma_uint64)data[6] << 48) | ((ma_uint64)data[7] << 56);
#if !defined(DR_FLAC_IMPLEMENTATION) && !defined(DRFLAC_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#if !defined(MA_DR_FLAC_IMPLEMENTATION) && !defined(MA_DR_FLAC_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#ifdef _MSC_VER
#define DRFLAC_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRFLAC_GNUC_INLINE_HINT __inline__
#else
#define DRFLAC_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRFLAC_INLINE __inline
#else
#define DRFLAC_INLINE
#endif
#if defined(__x86_64__) || defined(_M_X64)
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
#if !defined(DR_FLAC_NO_SIMD)
#if defined(DRFLAC_X64) || defined(DRFLAC_X86)
#if !defined(MA_DR_FLAC_NO_SIMD)
#if defined(MA_X64) || defined(MA_X86)
#if !defined(DRFLAC_SUPPORT_SSE2) && !defined(DRFLAC_NO_SSE2) && __has_include(<emmintrin.h>)
#define DRFLAC_SUPPORT_SSE2
#if !defined(MA_DR_FLAC_SUPPORT_SSE2) && !defined(MA_DR_FLAC_NO_SSE2) && __has_include(<emmintrin.h>)
#define MA_DR_FLAC_SUPPORT_SSE2
#if !defined(DRFLAC_SUPPORT_SSE41) && !defined(DRFLAC_NO_SSE41) && __has_include(<smmintrin.h>)
#define DRFLAC_SUPPORT_SSE41
#if !defined(MA_DR_FLAC_SUPPORT_SSE41) && !defined(MA_DR_FLAC_NO_SSE41) && __has_include(<smmintrin.h>)
#define MA_DR_FLAC_SUPPORT_SSE41
#if defined(DRFLAC_ARM)
#if !defined(DRFLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
#define DRFLAC_SUPPORT_NEON
#if defined(MA_ARM)
#if !defined(MA_DR_FLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64))
#define MA_DR_FLAC_SUPPORT_NEON
#if defined(DRFLAC_SUPPORT_SSE2)
#if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE2)
#if defined(DRFLAC_X64)
return DRFLAC_TRUE;
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
#if (defined(MA_X64) || defined(MA_X86)) && !defined(MA_DR_FLAC_NO_SSE2)
#if defined(MA_X64)
return MA_TRUE;
#if defined(DRFLAC_SUPPORT_SSE41)
#if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41)
#if defined(DRFLAC_X64)
return DRFLAC_TRUE;
#elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE4_1__)
return DRFLAC_TRUE;
#if defined(MA_DR_FLAC_SUPPORT_SSE41)
#if (defined(MA_X64) || defined(MA_X86)) && !defined(MA_DR_FLAC_NO_SSE41)
#if defined(__SSE4_1__) || defined(__AVX__)
return MA_TRUE;
#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) && !defined(__clang__)
#define DRFLAC_HAS_LZCNT_INTRINSIC
#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(MA_X86) || defined(MA_X64)) && !defined(__clang__)
#define MA_DR_FLAC_HAS_LZCNT_INTRINSIC
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
#define MA_DR_FLAC_HAS_BYTESWAP16_INTRINSIC
#define MA_DR_FLAC_HAS_BYTESWAP32_INTRINSIC
#define MA_DR_FLAC_HAS_BYTESWAP64_INTRINSIC
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
extern __inline drflac_uint16 _watcom_bswap16(drflac_uint16);
extern __inline drflac_uint32 _watcom_bswap32(drflac_uint32);
extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
#define MA_DR_FLAC_HAS_BYTESWAP16_INTRINSIC
#define MA_DR_FLAC_HAS_BYTESWAP32_INTRINSIC
#define MA_DR_FLAC_HAS_BYTESWAP64_INTRINSIC
extern __inline ma_uint16 _watcom_bswap16(ma_uint16);
extern __inline ma_uint32 _watcom_bswap32(ma_uint32);
extern __inline ma_uint64 _watcom_bswap64(ma_uint64);
#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64
typedef drflac_int32 drflac_result;
#define DRFLAC_SUCCESS 0
#define DRFLAC_ERROR -1
#define DRFLAC_INVALID_ARGS -2
#define DRFLAC_INVALID_OPERATION -3
#define DRFLAC_OUT_OF_MEMORY -4
#define DRFLAC_OUT_OF_RANGE -5
#define DRFLAC_ACCESS_DENIED -6
#define DRFLAC_DOES_NOT_EXIST -7
#define DRFLAC_ALREADY_EXISTS -8
#define DRFLAC_TOO_MANY_OPEN_FILES -9
#define DRFLAC_INVALID_FILE -10
#define DRFLAC_TOO_BIG -11
#define DRFLAC_PATH_TOO_LONG -12
#define DRFLAC_NAME_TOO_LONG -13
#define DRFLAC_NOT_DIRECTORY -14
#define DRFLAC_IS_DIRECTORY -15
#define DRFLAC_DIRECTORY_NOT_EMPTY -16
#define DRFLAC_END_OF_FILE -17
#define DRFLAC_NO_SPACE -18
#define DRFLAC_BUSY -19
#define DRFLAC_IO_ERROR -20
#define DRFLAC_INTERRUPT -21
#define DRFLAC_UNAVAILABLE -22
#define DRFLAC_ALREADY_IN_USE -23
#define DRFLAC_BAD_ADDRESS -24
#define DRFLAC_BAD_SEEK -25
#define DRFLAC_BAD_PIPE -26
#define DRFLAC_DEADLOCK -27
#define DRFLAC_TOO_MANY_LINKS -28
#define DRFLAC_NOT_IMPLEMENTED -29
#define DRFLAC_NO_MESSAGE -30
#define DRFLAC_BAD_MESSAGE -31
#define DRFLAC_NO_DATA_AVAILABLE -32
#define DRFLAC_INVALID_DATA -33
#define DRFLAC_TIMEOUT -34
#define DRFLAC_NO_NETWORK -35
#define DRFLAC_NOT_UNIQUE -36
#define DRFLAC_NOT_SOCKET -37
#define DRFLAC_NO_ADDRESS -38
#define DRFLAC_BAD_PROTOCOL -39
#define DRFLAC_PROTOCOL_UNAVAILABLE -40
#define DRFLAC_PROTOCOL_NOT_SUPPORTED -41
#define DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED -42
#define DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED -43
#define DRFLAC_SOCKET_NOT_SUPPORTED -44
#define DRFLAC_CONNECTION_RESET -45
#define DRFLAC_ALREADY_CONNECTED -46
#define DRFLAC_NOT_CONNECTED -47
#define DRFLAC_CONNECTION_REFUSED -48
#define DRFLAC_NO_HOST -49
#define DRFLAC_IN_PROGRESS -50
#define DRFLAC_CANCELLED -51
#define DRFLAC_MEMORY_ALREADY_MAPPED -52
#define DRFLAC_AT_END -53
#define DRFLAC_CRC_MISMATCH -128
#define DRFLAC_SUBFRAME_CONSTANT 0
#define DRFLAC_SUBFRAME_VERBATIM 1
#define DRFLAC_SUBFRAME_FIXED 8
#define DRFLAC_SUBFRAME_LPC 32
#define DRFLAC_SUBFRAME_RESERVED 255
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0
#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1
#define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0
#define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8
#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision)
#define MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE 64
#define MA_DR_FLAC_SUBFRAME_CONSTANT 0
#define MA_DR_FLAC_SUBFRAME_VERBATIM 1
#define MA_DR_FLAC_SUBFRAME_FIXED 8
#define MA_DR_FLAC_SUBFRAME_LPC 32
#define MA_DR_FLAC_SUBFRAME_RESERVED 255
#define MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0
#define MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1
#define MA_DR_FLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0
#define MA_DR_FLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8
#define MA_DR_FLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9
#define MA_DR_FLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
#define MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES 18
#define MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES 36
#define MA_DR_FLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES 12
#define ma_dr_flac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
MA_API void ma_dr_flac_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision)
#ifndef DRFLAC_NO_CPUID
static drflac_bool32 drflac__gIsSSE2Supported = DRFLAC_FALSE;
static drflac_bool32 drflac__gIsSSE41Supported = DRFLAC_FALSE;
DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps(void)
#ifndef MA_DR_FLAC_NO_CPUID
static ma_bool32 ma_dr_flac__gIsSSE2Supported = MA_FALSE;
static ma_bool32 ma_dr_flac__gIsSSE41Supported = MA_FALSE;
MA_DR_FLAC_NO_THREAD_SANITIZE static void ma_dr_flac__init_cpu_caps(void)
drflac__gIsSSE2Supported = drflac_has_sse2();
drflac__gIsSSE41Supported = drflac_has_sse41();
isCPUCapsInitialized = DRFLAC_TRUE;
ma_dr_flac__gIsSSE2Supported = ma_dr_flac_has_sse2();
ma_dr_flac__gIsSSE41Supported = ma_dr_flac_has_sse41();
isCPUCapsInitialized = MA_TRUE;
drflac__gIsNEONSupported = drflac__has_neon();
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
drflac__gIsLZCNTSupported = DRFLAC_TRUE;
ma_dr_flac__gIsNEONSupported = ma_dr_flac__has_neon();
#if defined(MA_DR_FLAC_HAS_LZCNT_INTRINSIC) && defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
ma_dr_flac__gIsLZCNTSupported = MA_TRUE;
return ((n & ((drflac_uint64)0xFF000000 << 32)) >> 56) |
((n & ((drflac_uint64)0x00FF0000 << 32)) >> 40) |
((n & ((drflac_uint64)0x0000FF00 << 32)) >> 24) |
((n & ((drflac_uint64)0x000000FF << 32)) >> 8) |
((n & ((drflac_uint64)0xFF000000 )) << 8) |
((n & ((drflac_uint64)0x00FF0000 )) << 24) |
((n & ((drflac_uint64)0x0000FF00 )) << 40) |
((n & ((drflac_uint64)0x000000FF )) << 56);
return ((n & ((ma_uint64)0xFF000000 << 32)) >> 56) |
((n & ((ma_uint64)0x00FF0000 << 32)) >> 40) |
((n & ((ma_uint64)0x0000FF00 << 32)) >> 24) |
((n & ((ma_uint64)0x000000FF << 32)) >> 8) |
((n & ((ma_uint64)0xFF000000 )) << 8) |
((n & ((ma_uint64)0x00FF0000 )) << 24) |
((n & ((ma_uint64)0x0000FF00 )) << 40) |
((n & ((ma_uint64)0x000000FF )) << 56);
drflac_uint32 wholeBytes;
drflac_uint32 leftoverBits;
drflac_uint64 leftoverDataMask;
static drflac_uint64 leftoverDataMaskTable[8] = {
ma_uint32 wholeBytes;
ma_uint32 leftoverBits;
ma_uint64 leftoverDataMask;
static ma_uint64 leftoverDataMaskTable[8] = {
case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (drflac_uint8)((crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]);
case 4: crc = ma_dr_flac_crc8_byte(crc, (ma_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = ma_dr_flac_crc8_byte(crc, (ma_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = ma_dr_flac_crc8_byte(crc, (ma_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = ma_dr_flac_crc8_byte(crc, (ma_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (ma_uint8)((crc << leftoverBits) ^ ma_dr_flac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]);
#ifdef DRFLAC_64BIT
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
#ifdef MA_64BIT
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 56) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 48) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 40) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 32) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 24) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 16) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 8) & 0xFF));
crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 0) & 0xFF));
#ifdef DRFLAC_64BIT
case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF));
case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF));
case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF));
case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF));
#ifdef MA_64BIT
case 8: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 56) & 0xFF));
case 7: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 48) & 0xFF));
case 6: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 40) & 0xFF));
case 5: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 32) & 0xFF));
case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF));
case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF));
case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF));
case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF));
case 4: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 24) & 0xFF));
case 3: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 16) & 0xFF));
case 2: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 8) & 0xFF));
case 1: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data >> 0) & 0xFF));
drflac_uint32 wholeBytes;
drflac_uint32 leftoverBits;
drflac_uint64 leftoverDataMask;
static drflac_uint64 leftoverDataMaskTable[8] = {
ma_uint32 wholeBytes;
ma_uint32 leftoverBits;
ma_uint64 leftoverDataMask;
static ma_uint64 leftoverDataMaskTable[8] = {
case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
case 4: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ ma_dr_flac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
drflac_uint32 wholeBytes;
drflac_uint32 leftoverBits;
drflac_uint64 leftoverDataMask;
static drflac_uint64 leftoverDataMaskTable[8] = {
ma_uint32 wholeBytes;
ma_uint32 leftoverBits;
ma_uint64 leftoverDataMask;
static ma_uint64 leftoverDataMaskTable[8] = {
case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits)));
case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
case 8: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits)));
case 7: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
case 6: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
case 5: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
case 4: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits)));
case 3: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits)));
case 2: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits)));
case 1: crc = ma_dr_flac_crc16_byte(crc, (ma_uint8)((data & (((ma_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits)));
case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ ma_dr_flac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
#define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache))
#define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(drflac_cache_t)0) >> (_bitCount)))
#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1)))
#define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
#ifndef DR_FLAC_NO_CRC
static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs)
#define MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache))
#define MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
#define MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs) (MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
#define MA_DR_FLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(ma_dr_flac_cache_t)0) >> (_bitCount)))
#define MA_DR_FLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
#define MA_DR_FLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & MA_DR_FLAC_CACHE_L1_SELECTION_MASK(_bitCount))
#define MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (MA_DR_FLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> MA_DR_FLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
#define MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(MA_DR_FLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (MA_DR_FLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)-1)))
#define MA_DR_FLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
#define MA_DR_FLAC_CACHE_L2_LINE_COUNT(bs) (MA_DR_FLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
#define MA_DR_FLAC_CACHE_L2_LINES_REMAINING(bs) (MA_DR_FLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
#ifndef MA_DR_FLAC_NO_CRC
static MA_INLINE void ma_dr_flac__reset_crc16(ma_dr_flac_bs* bs)
bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes);
bs->crc16 = ma_dr_flac_crc16_bytes(bs->crc16, bs->crc16Cache, MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes);
DRFLAC_ASSERT((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
drflac__update_crc16(bs);
MA_DR_FLAC_ASSERT((MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
if (MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs) == 0) {
ma_dr_flac__update_crc16(bs);
bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes);
bs->crc16 = ma_dr_flac_crc16_bytes(bs->crc16, bs->crc16Cache >> MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes);
alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs);
bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs));
alignedL1LineCount = bytesRead / MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs);
bs->unalignedByteCount = bytesRead - (alignedL1LineCount * MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs));
DRFLAC_ASSERT(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_BITS_REMAINING(bs));
MA_DR_FLAC_ASSERT(bytesRead < MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs));
bs->consumedBits = (ma_uint32)(MA_DR_FLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
bs->cache = ma_dr_flac__be2host__cache_line(bs->unalignedCache);
bs->cache &= MA_DR_FLAC_CACHE_L1_SELECTION_MASK(MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs));
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResultOut != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 32);
if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
if (!drflac__reload_cache(bs)) {
return DRFLAC_FALSE;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResultOut != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 32);
if (bs->consumedBits == MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)) {
if (!ma_dr_flac__reload_cache(bs)) {
return MA_FALSE;
if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
#ifdef DRFLAC_64BIT
*pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
if (bitCount <= MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs)) {
#ifdef MA_64BIT
*pResultOut = (ma_uint32)MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
*pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
if (bitCount < MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)) {
*pResultOut = (ma_uint32)MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs);
drflac_uint32 bitCountLo = bitCount - bitCountHi;
drflac_uint32 resultHi;
DRFLAC_ASSERT(bitCountHi > 0);
DRFLAC_ASSERT(bitCountHi < 32);
resultHi = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
if (!drflac__reload_cache(bs)) {
return DRFLAC_FALSE;
ma_uint32 bitCountHi = MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs);
ma_uint32 bitCountLo = bitCount - bitCountHi;
ma_uint32 resultHi;
MA_DR_FLAC_ASSERT(bitCountHi > 0);
MA_DR_FLAC_ASSERT(bitCountHi < 32);
resultHi = (ma_uint32)MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi);
if (!ma_dr_flac__reload_cache(bs)) {
return MA_FALSE;
drflac_uint32 result;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 32);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_uint32 result;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResult != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 32);
if (!ma_dr_flac__read_uint32(bs, bitCount, &result)) {
return MA_FALSE;
#ifdef DRFLAC_64BIT
static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut)
#ifdef MA_64BIT
static ma_bool32 ma_dr_flac__read_uint64(ma_dr_flac_bs* bs, unsigned int bitCount, ma_uint64* pResultOut)
drflac_uint32 resultHi;
drflac_uint32 resultLo;
DRFLAC_ASSERT(bitCount <= 64);
DRFLAC_ASSERT(bitCount > 32);
if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
return DRFLAC_FALSE;
ma_uint32 resultHi;
ma_uint32 resultLo;
MA_DR_FLAC_ASSERT(bitCount <= 64);
MA_DR_FLAC_ASSERT(bitCount > 32);
if (!ma_dr_flac__read_uint32(bs, bitCount - 32, &resultHi)) {
return MA_FALSE;
drflac_uint64 result;
drflac_uint64 signbit;
DRFLAC_ASSERT(bitCount <= 64);
if (!drflac__read_uint64(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_uint64 result;
ma_uint64 signbit;
MA_DR_FLAC_ASSERT(bitCount <= 64);
if (!ma_dr_flac__read_uint64(bs, bitCount, &result)) {
return MA_FALSE;
drflac_uint32 result;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 16);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_uint32 result;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResult != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 16);
if (!ma_dr_flac__read_uint32(bs, bitCount, &result)) {
return MA_FALSE;
drflac_int32 result;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 16);
if (!drflac__read_int32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_int32 result;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResult != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 16);
if (!ma_dr_flac__read_int32(bs, bitCount, &result)) {
return MA_FALSE;
drflac_uint32 result;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 8);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_uint32 result;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResult != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 8);
if (!ma_dr_flac__read_uint32(bs, bitCount, &result)) {
return MA_FALSE;
drflac_int32 result;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 8);
if (!drflac__read_int32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
ma_int32 result;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pResult != NULL);
MA_DR_FLAC_ASSERT(bitCount > 0);
MA_DR_FLAC_ASSERT(bitCount <= 8);
if (!ma_dr_flac__read_int32(bs, bitCount, &result)) {
return MA_FALSE;
#ifdef DRFLAC_64BIT
while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
drflac_uint64 bin;
if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
return DRFLAC_FALSE;
#ifdef MA_64BIT
while (bitsToSeek >= MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)) {
ma_uint64 bin;
if (!ma_dr_flac__read_uint64(bs, MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
return MA_FALSE;
while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
drflac_uint32 bin;
if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
return DRFLAC_FALSE;
while (bitsToSeek >= MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)) {
ma_uint32 bin;
if (!ma_dr_flac__read_uint32(bs, MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs), &bin)) {
return MA_FALSE;
DRFLAC_ASSERT(bs != NULL);
if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
return DRFLAC_FALSE;
MA_DR_FLAC_ASSERT(bs != NULL);
if (!ma_dr_flac__seek_bits(bs, MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) {
return MA_FALSE;
#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(__clang__)
#define DRFLAC_IMPLEMENT_CLZ_MSVC
#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(MA_X64) || defined(MA_X86)) && !defined(__clang__)
#define MA_DR_FLAC_IMPLEMENT_CLZ_MSVC
#ifdef DRFLAC_64BIT
if ((x & ((drflac_uint64)0xFFFFFFFF << 32)) == 0) { n = 32; x <<= 32; }
if ((x & ((drflac_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; }
if ((x & ((drflac_uint64)0xFF000000 << 32)) == 0) { n += 8; x <<= 8; }
if ((x & ((drflac_uint64)0xF0000000 << 32)) == 0) { n += 4; x <<= 4; }
#ifdef MA_64BIT
if ((x & ((ma_uint64)0xFFFFFFFF << 32)) == 0) { n = 32; x <<= 32; }
if ((x & ((ma_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; }
if ((x & ((ma_uint64)0xFF000000 << 32)) == 0) { n += 8; x <<= 8; }
if ((x & ((ma_uint64)0xF0000000 << 32)) == 0) { n += 4; x <<= 4; }
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
return DRFLAC_TRUE;
#if defined(MA_DR_FLAC_HAS_LZCNT_INTRINSIC) && defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
return MA_TRUE;
#elif defined(__MRC__)
return MA_TRUE;
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
#pragma aux drflac__clz_watcom = \
#ifdef MA_DR_FLAC_IMPLEMENT_CLZ_WATCOM
static __inline ma_uint32 ma_dr_flac__clz_watcom (ma_uint32);
#ifdef MA_DR_FLAC_IMPLEMENT_CLZ_WATCOM_LZCNT
#pragma aux ma_dr_flac__clz_watcom_lzcnt = \
"db 0F3h, 0Fh, 0BDh, 0C0h" \
parm [eax] \
value [eax] \
modify nomemory;
#else
#pragma aux ma_dr_flac__clz_watcom = \
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
return drflac__clz_msvc(x);
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
return (x == 0) ? sizeof(x)*8 : drflac__clz_watcom(x);
#ifdef MA_DR_FLAC_IMPLEMENT_CLZ_MSVC
return ma_dr_flac__clz_msvc(x);
#elif defined(MA_DR_FLAC_IMPLEMENT_CLZ_WATCOM_LZCNT)
return ma_dr_flac__clz_watcom_lzcnt(x);
#elif defined(MA_DR_FLAC_IMPLEMENT_CLZ_WATCOM)
return (x == 0) ? sizeof(x)*8 : ma_dr_flac__clz_watcom(x);
#elif defined(__MRC__)
return __cntlzw(x);
zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
if (!drflac__reload_cache(bs)) {
return DRFLAC_FALSE;
zeroCounter += (ma_uint32)MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs);
if (!ma_dr_flac__reload_cache(bs)) {
return MA_FALSE;
*pOffsetOut = zeroCounter + (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs) - 1;
if (!drflac__reload_cache(bs)) {
return DRFLAC_FALSE;
*pOffsetOut = zeroCounter + (ma_uint32)MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs) - 1;
if (!ma_dr_flac__reload_cache(bs)) {
return MA_FALSE;
drflac_uint64 bytesRemaining = offsetFromStart;
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) {
return DRFLAC_FALSE;
ma_uint64 bytesRemaining = offsetFromStart;
if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, ma_dr_flac_seek_origin_start)) {
return MA_FALSE;
static DRFLAC_INLINE drflac_bool32 drflac__use_64_bit_prediction(drflac_uint32 bitsPerSample, drflac_uint32 order, drflac_uint32 precision)
static MA_INLINE ma_bool32 ma_dr_flac__use_64_bit_prediction(ma_uint32 bitsPerSample, ma_uint32 order, ma_uint32 precision)
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
static MA_INLINE ma_int32 ma_dr_flac__calculate_prediction_32(ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pDecodedSamples)
static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
static MA_INLINE ma_int32 ma_dr_flac__calculate_prediction_64(ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pDecodedSamples)
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (ma_int64)pDecodedSamples[-8];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (ma_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (ma_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (ma_int64)pDecodedSamples[-10];
prediction += coefficients[10] * (ma_int64)pDecodedSamples[-11];
prediction += coefficients[11] * (ma_int64)pDecodedSamples[-12];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (ma_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (ma_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (ma_int64)pDecodedSamples[-10];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (ma_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (ma_int64)pDecodedSamples[-9];
prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10];
prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
prediction = coefficients[0] * (ma_int64)pDecodedSamples[-1];
prediction += coefficients[1] * (ma_int64)pDecodedSamples[-2];
prediction += coefficients[2] * (ma_int64)pDecodedSamples[-3];
prediction += coefficients[3] * (ma_int64)pDecodedSamples[-4];
prediction += coefficients[4] * (ma_int64)pDecodedSamples[-5];
prediction += coefficients[5] * (ma_int64)pDecodedSamples[-6];
prediction += coefficients[6] * (ma_int64)pDecodedSamples[-7];
prediction += coefficients[7] * (ma_int64)pDecodedSamples[-8];
prediction += coefficients[8] * (ma_int64)pDecodedSamples[-9];
prediction += coefficients[9] * (ma_int64)pDecodedSamples[-10];
prediction += coefficients[10] * (ma_int64)pDecodedSamples[-11];
case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32];
case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31];
case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30];
case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29];
case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28];
case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27];
case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26];
case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25];
case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24];
case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23];
case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22];
case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21];
case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20];
case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19];
case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18];
case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17];
case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16];
case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15];
case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14];
case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13];
case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12];
case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11];
case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10];
case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9];
case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8];
case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7];
case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6];
case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5];
case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4];
case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3];
case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2];
case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1];
case 32: prediction += coefficients[31] * (ma_int64)pDecodedSamples[-32];
case 31: prediction += coefficients[30] * (ma_int64)pDecodedSamples[-31];
case 30: prediction += coefficients[29] * (ma_int64)pDecodedSamples[-30];
case 29: prediction += coefficients[28] * (ma_int64)pDecodedSamples[-29];
case 28: prediction += coefficients[27] * (ma_int64)pDecodedSamples[-28];
case 27: prediction += coefficients[26] * (ma_int64)pDecodedSamples[-27];
case 26: prediction += coefficients[25] * (ma_int64)pDecodedSamples[-26];
case 25: prediction += coefficients[24] * (ma_int64)pDecodedSamples[-25];
case 24: prediction += coefficients[23] * (ma_int64)pDecodedSamples[-24];
case 23: prediction += coefficients[22] * (ma_int64)pDecodedSamples[-23];
case 22: prediction += coefficients[21] * (ma_int64)pDecodedSamples[-22];
case 21: prediction += coefficients[20] * (ma_int64)pDecodedSamples[-21];
case 20: prediction += coefficients[19] * (ma_int64)pDecodedSamples[-20];
case 19: prediction += coefficients[18] * (ma_int64)pDecodedSamples[-19];
case 18: prediction += coefficients[17] * (ma_int64)pDecodedSamples[-18];
case 17: prediction += coefficients[16] * (ma_int64)pDecodedSamples[-17];
case 16: prediction += coefficients[15] * (ma_int64)pDecodedSamples[-16];
case 15: prediction += coefficients[14] * (ma_int64)pDecodedSamples[-15];
case 14: prediction += coefficients[13] * (ma_int64)pDecodedSamples[-14];
case 13: prediction += coefficients[12] * (ma_int64)pDecodedSamples[-13];
case 12: prediction += coefficients[11] * (ma_int64)pDecodedSamples[-12];
case 11: prediction += coefficients[10] * (ma_int64)pDecodedSamples[-11];
case 10: prediction += coefficients[ 9] * (ma_int64)pDecodedSamples[-10];
case 9: prediction += coefficients[ 8] * (ma_int64)pDecodedSamples[- 9];
case 8: prediction += coefficients[ 7] * (ma_int64)pDecodedSamples[- 8];
case 7: prediction += coefficients[ 6] * (ma_int64)pDecodedSamples[- 7];
case 6: prediction += coefficients[ 5] * (ma_int64)pDecodedSamples[- 6];
case 5: prediction += coefficients[ 4] * (ma_int64)pDecodedSamples[- 5];
case 4: prediction += coefficients[ 3] * (ma_int64)pDecodedSamples[- 4];
case 3: prediction += coefficients[ 2] * (ma_int64)pDecodedSamples[- 3];
case 2: prediction += coefficients[ 1] * (ma_int64)pDecodedSamples[- 2];
case 1: prediction += coefficients[ 0] * (ma_int64)pDecodedSamples[- 1];
static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__reference(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
if (ma_dr_flac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[i] = decodedRice + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
static ma_bool32 ma_dr_flac__read_rice_parts__reference(ma_dr_flac_bs* bs, ma_uint8 riceParam, ma_uint32* pZeroCounterOut, ma_uint32* pRiceParamPartOut)
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
static MA_INLINE ma_bool32 ma_dr_flac__read_rice_parts(ma_dr_flac_bs* bs, ma_uint8 riceParam, ma_uint32* pZeroCounterOut, ma_uint32* pRiceParamPartOut)
drflac_cache_t riceParamMask;
drflac_uint32 zeroCounter;
drflac_uint32 setBitOffsetPlus1;
drflac_uint32 riceParamPart;
drflac_uint32 riceLength;
DRFLAC_ASSERT(riceParam > 0);
riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
ma_dr_flac_cache_t riceParamMask;
ma_uint32 zeroCounter;
ma_uint32 setBitOffsetPlus1;
ma_uint32 riceParamPart;
ma_uint32 riceLength;
MA_DR_FLAC_ASSERT(riceParam > 0);
riceParamMask = MA_DR_FLAC_CACHE_L1_SELECTION_MASK(riceParam);
zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
if (!drflac__reload_cache(bs)) {
return DRFLAC_FALSE;
zeroCounter += (ma_uint32)MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs);
if (!ma_dr_flac__reload_cache(bs)) {
return MA_FALSE;
if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
if (riceLength < MA_DR_FLAC_CACHE_L1_BITS_REMAINING(bs)) {
riceParamPart = (ma_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> MA_DR_FLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1);
bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam);
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef DR_FLAC_NO_CRC
drflac__update_crc16(bs);
bs->cache <<= setBitOffsetPlus1 & (MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs)-1);
bitCountLo = bs->consumedBits - MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs);
resultHi = MA_DR_FLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam);
if (bs->nextL2Line < MA_DR_FLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef MA_DR_FLAC_NO_CRC
ma_dr_flac__update_crc16(bs);
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
static MA_INLINE ma_bool32 ma_dr_flac__read_rice_parts_x1(ma_dr_flac_bs* bs, ma_uint8 riceParam, ma_uint32* pZeroCounterOut, ma_uint32* pRiceParamPartOut)
drflac_uint32 riceParamPlus1 = riceParam + 1;
drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
drflac_cache_t bs_cache = bs->cache;
drflac_uint32 bs_consumedBits = bs->consumedBits;
drflac_uint32 lzcount = drflac__clz(bs_cache);
ma_uint32 riceParamPlus1 = riceParam + 1;
ma_uint32 riceParamPlus1Shift = MA_DR_FLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
ma_uint32 riceParamPlus1MaxConsumedBits = MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
ma_dr_flac_cache_t bs_cache = bs->cache;
ma_uint32 bs_consumedBits = bs->consumedBits;
ma_uint32 lzcount = ma_dr_flac__clz(bs_cache);
drflac_uint32 riceParamPartHi;
drflac_uint32 riceParamPartLo;
drflac_uint32 riceParamPartLoBitCount;
riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
ma_uint32 riceParamPartHi;
ma_uint32 riceParamPartLo;
ma_uint32 riceParamPartLoBitCount;
riceParamPartHi = (ma_uint32)(bs_cache >> riceParamPlus1Shift);
DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef DR_FLAC_NO_CRC
drflac__update_crc16(bs);
MA_DR_FLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
if (bs->nextL2Line < MA_DR_FLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef MA_DR_FLAC_NO_CRC
ma_dr_flac__update_crc16(bs);
drflac_uint32 riceParamPlus1 = riceParam + 1;
drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
drflac_cache_t bs_cache = bs->cache;
drflac_uint32 bs_consumedBits = bs->consumedBits;
drflac_uint32 lzcount = drflac__clz(bs_cache);
ma_uint32 riceParamPlus1 = riceParam + 1;
ma_uint32 riceParamPlus1MaxConsumedBits = MA_DR_FLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
ma_dr_flac_cache_t bs_cache = bs->cache;
ma_uint32 bs_consumedBits = bs->consumedBits;
ma_uint32 lzcount = ma_dr_flac__clz(bs_cache);
drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef DR_FLAC_NO_CRC
drflac__update_crc16(bs);
ma_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
MA_DR_FLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
if (bs->nextL2Line < MA_DR_FLAC_CACHE_L2_LINE_COUNT(bs)) {
#ifndef MA_DR_FLAC_NO_CRC
ma_dr_flac__update_crc16(bs);
static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar_zeroorder(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__scalar_zeroorder(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
drflac_uint32 zeroCountPart0;
drflac_uint32 riceParamPart0;
drflac_uint32 riceParamMask;
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pSamplesOut != NULL);
ma_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
ma_uint32 zeroCountPart0;
ma_uint32 riceParamPart0;
ma_uint32 riceParamMask;
ma_uint32 i;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pSamplesOut != NULL);
static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__scalar(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
drflac_uint32 zeroCountPart0 = 0;
drflac_uint32 zeroCountPart1 = 0;
drflac_uint32 zeroCountPart2 = 0;
drflac_uint32 zeroCountPart3 = 0;
drflac_uint32 riceParamPart0 = 0;
drflac_uint32 riceParamPart1 = 0;
drflac_uint32 riceParamPart2 = 0;
drflac_uint32 riceParamPart3 = 0;
drflac_uint32 riceParamMask;
const drflac_int32* pSamplesOutEnd;
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pSamplesOut != NULL);
ma_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
ma_uint32 zeroCountPart0 = 0;
ma_uint32 zeroCountPart1 = 0;
ma_uint32 zeroCountPart2 = 0;
ma_uint32 zeroCountPart3 = 0;
ma_uint32 riceParamPart0 = 0;
ma_uint32 riceParamPart1 = 0;
ma_uint32 riceParamPart2 = 0;
ma_uint32 riceParamPart3 = 0;
ma_uint32 riceParamMask;
const ma_int32* pSamplesOutEnd;
ma_uint32 i;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(pSamplesOut != NULL);
return drflac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
return MA_FALSE;
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
pSamplesOut[0] = riceParamPart0 + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[1] = riceParamPart1 + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
pSamplesOut[2] = riceParamPart2 + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
pSamplesOut[3] = riceParamPart3 + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) {
return MA_FALSE;
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
pSamplesOut[0] = riceParamPart0 + ma_dr_flac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[1] = riceParamPart1 + ma_dr_flac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 1);
pSamplesOut[2] = riceParamPart2 + ma_dr_flac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 2);
pSamplesOut[3] = riceParamPart3 + ma_dr_flac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 3);
if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
if (ma_dr_flac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[0] = riceParamPart0 + ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
pSamplesOut[0] = riceParamPart0 + ma_dr_flac__calculate_prediction_32(lpcOrder, lpcShift, coefficients, pSamplesOut + 0);
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE __m128i drflac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE __m128i ma_dr_flac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__sse41_32(ma_dr_flac_bs* bs, ma_uint32 count, ma_uint8 riceParam, ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 riceParamMask;
drflac_int32* pDecodedSamples = pSamplesOut;
drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
drflac_uint32 zeroCountParts0 = 0;
drflac_uint32 zeroCountParts1 = 0;
drflac_uint32 zeroCountParts2 = 0;
drflac_uint32 zeroCountParts3 = 0;
drflac_uint32 riceParamParts0 = 0;
drflac_uint32 riceParamParts1 = 0;
drflac_uint32 riceParamParts2 = 0;
drflac_uint32 riceParamParts3 = 0;
ma_uint32 riceParamMask;
ma_int32* pDecodedSamples = pSamplesOut;
ma_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
ma_uint32 zeroCountParts0 = 0;
ma_uint32 zeroCountParts1 = 0;
ma_uint32 zeroCountParts2 = 0;
ma_uint32 zeroCountParts3 = 0;
ma_uint32 riceParamParts0 = 0;
ma_uint32 riceParamParts1 = 0;
ma_uint32 riceParamParts2 = 0;
ma_uint32 riceParamParts3 = 0;
case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
case 12: ((ma_int32*)&coefficients128_8)[0] = coefficients[11]; ((ma_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((ma_int32*)&coefficients128_8)[1] = coefficients[10]; ((ma_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((ma_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((ma_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((ma_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((ma_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((ma_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((ma_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((ma_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((ma_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((ma_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((ma_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((ma_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((ma_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((ma_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((ma_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((ma_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((ma_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((ma_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((ma_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((ma_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((ma_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return MA_FALSE;
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01))), _mm_set1_epi32(0x01)));
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(ma_dr_flac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01))), _mm_set1_epi32(0x01)));
pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
pDecodedSamples[0] = riceParamParts0 + ma_dr_flac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__sse41_64(ma_dr_flac_bs* bs, ma_uint32 count, ma_uint8 riceParam, ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 riceParamMask;
drflac_int32* pDecodedSamples = pSamplesOut;
drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
drflac_uint32 zeroCountParts0 = 0;
drflac_uint32 zeroCountParts1 = 0;
drflac_uint32 zeroCountParts2 = 0;
drflac_uint32 zeroCountParts3 = 0;
drflac_uint32 riceParamParts0 = 0;
drflac_uint32 riceParamParts1 = 0;
drflac_uint32 riceParamParts2 = 0;
drflac_uint32 riceParamParts3 = 0;
ma_uint32 riceParamMask;
ma_int32* pDecodedSamples = pSamplesOut;
ma_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
ma_uint32 zeroCountParts0 = 0;
ma_uint32 zeroCountParts1 = 0;
ma_uint32 zeroCountParts2 = 0;
ma_uint32 zeroCountParts3 = 0;
ma_uint32 riceParamParts0 = 0;
ma_uint32 riceParamParts1 = 0;
ma_uint32 riceParamParts2 = 0;
ma_uint32 riceParamParts3 = 0;
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
DRFLAC_ASSERT(order <= 12);
riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
const ma_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
MA_DR_FLAC_ASSERT(order <= 12);
riceParamMask = (ma_uint32)~((~0UL) << riceParam);
case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
case 12: ((ma_int32*)&coefficients128_8)[0] = coefficients[11]; ((ma_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((ma_int32*)&coefficients128_8)[1] = coefficients[10]; ((ma_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((ma_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((ma_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((ma_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((ma_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((ma_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((ma_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((ma_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((ma_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((ma_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((ma_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((ma_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((ma_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((ma_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((ma_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((ma_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((ma_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((ma_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((ma_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((ma_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((ma_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return MA_FALSE;
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(1))), _mm_set1_epi32(1)));
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(ma_dr_flac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(1))), _mm_set1_epi32(1)));
prediction128 = drflac__mm_hadd_epi64(prediction128);
prediction128 = drflac__mm_srai_epi64(prediction128, shift);
prediction128 = ma_dr_flac__mm_hadd_epi64(prediction128);
prediction128 = ma_dr_flac__mm_srai_epi64(prediction128, shift);
pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
pDecodedSamples[0] = riceParamParts0 + ma_dr_flac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__sse41(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
return drflac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
if (ma_dr_flac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
return ma_dr_flac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_32(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__neon_32(ma_dr_flac_bs* bs, ma_uint32 count, ma_uint8 riceParam, ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 riceParamMask;
drflac_int32* pDecodedSamples = pSamplesOut;
drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
drflac_uint32 zeroCountParts[4];
drflac_uint32 riceParamParts[4];
ma_uint32 riceParamMask;
ma_int32* pDecodedSamples = pSamplesOut;
ma_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
ma_uint32 zeroCountParts[4];
ma_uint32 riceParamParts[4];
coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
coefficients128_0 = ma_dr_flac__vrevq_s32(coefficients128_0);
coefficients128_4 = ma_dr_flac__vrevq_s32(coefficients128_4);
coefficients128_8 = ma_dr_flac__vrevq_s32(coefficients128_8);
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return MA_FALSE;
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(ma_dr_flac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_0 = ma_dr_flac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = ma_dr_flac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_4 = ma_dr_flac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = ma_dr_flac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = ma_dr_flac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_8 = ma_dr_flac__valignrq_s32_1(samples128_4, samples128_8);
samples128_4 = ma_dr_flac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = ma_dr_flac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = ma_dr_flac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
pDecodedSamples[0] = riceParamParts[0] + ma_dr_flac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__neon_64(ma_dr_flac_bs* bs, ma_uint32 count, ma_uint8 riceParam, ma_uint32 order, ma_int32 shift, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 riceParamMask;
drflac_int32* pDecodedSamples = pSamplesOut;
drflac_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
drflac_uint32 zeroCountParts[4];
drflac_uint32 riceParamParts[4];
ma_uint32 riceParamMask;
ma_int32* pDecodedSamples = pSamplesOut;
ma_int32* pDecodedSamplesEnd = pSamplesOut + (count & ~3);
ma_uint32 zeroCountParts[4];
ma_uint32 riceParamParts[4];
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
riceParamMask = ~((~0UL) << riceParam);
int64x2_t prediction128 = { 0 };
uint32x4_t zeroCountPart128;
uint32x4_t riceParamPart128;
const ma_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
riceParamMask = (ma_uint32)~((~0UL) << riceParam);
coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
coefficients128_0 = ma_dr_flac__vrevq_s32(coefficients128_0);
coefficients128_4 = ma_dr_flac__vrevq_s32(coefficients128_4);
coefficients128_8 = ma_dr_flac__vrevq_s32(coefficients128_8);
int64x2_t prediction128;
uint32x4_t zeroCountPart128;
uint32x4_t riceParamPart128;
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!ma_dr_flac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return MA_FALSE;
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(ma_dr_flac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
samples128_8 = ma_dr_flac__valignrq_s32_1(samples128_4, samples128_8);
samples128_4 = ma_dr_flac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = ma_dr_flac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
riceParamPart128 = ma_dr_flac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
pDecodedSamples[0] = riceParamParts[0] + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
pDecodedSamples[0] = riceParamParts[0] + ma_dr_flac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice__neon(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
return drflac__decode_samples_with_residual__rice__neon_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
if (ma_dr_flac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
return ma_dr_flac__decode_samples_with_residual__rice__neon_64(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__neon_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__neon_32(bs, count, riceParam, lpcOrder, lpcShift, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__rice(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 riceParam, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
#if defined(DRFLAC_SUPPORT_SSE41)
if (drflac__gIsSSE41Supported) {
return drflac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
#if defined(MA_DR_FLAC_SUPPORT_SSE41)
if (ma_dr_flac__gIsSSE41Supported) {
return ma_dr_flac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported) {
return drflac__decode_samples_with_residual__rice__neon(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported) {
return ma_dr_flac__decode_samples_with_residual__rice__neon(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
return ma_dr_flac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pSamplesOut);
static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
static ma_bool32 ma_dr_flac__decode_samples_with_residual__unencoded(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 count, ma_uint8 unencodedBitsPerSample, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pSamplesOut)
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(unencodedBitsPerSample <= 31);
DRFLAC_ASSERT(pSamplesOut != NULL);
ma_uint32 i;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(unencodedBitsPerSample <= 31);
MA_DR_FLAC_ASSERT(pSamplesOut != NULL);
if (drflac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[i] += drflac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
if (ma_dr_flac__use_64_bit_prediction(bitsPerSample, lpcOrder, lpcPrecision)) {
pSamplesOut[i] += ma_dr_flac__calculate_prediction_64(lpcOrder, lpcShift, coefficients, pSamplesOut + i);
static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 lpcOrder, drflac_int32 lpcShift, drflac_uint32 lpcPrecision, const drflac_int32* coefficients, drflac_int32* pDecodedSamples)
static ma_bool32 ma_dr_flac__decode_samples_with_residual(ma_dr_flac_bs* bs, ma_uint32 bitsPerSample, ma_uint32 blockSize, ma_uint32 lpcOrder, ma_int32 lpcShift, ma_uint32 lpcPrecision, const ma_int32* coefficients, ma_int32* pDecodedSamples)
drflac_uint8 residualMethod;
drflac_uint8 partitionOrder;
drflac_uint32 samplesInPartition;
drflac_uint32 partitionsRemaining;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(blockSize != 0);
DRFLAC_ASSERT(pDecodedSamples != NULL);
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
return DRFLAC_FALSE;
ma_uint8 residualMethod;
ma_uint8 partitionOrder;
ma_uint32 samplesInPartition;
ma_uint32 partitionsRemaining;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(blockSize != 0);
MA_DR_FLAC_ASSERT(pDecodedSamples != NULL);
if (!ma_dr_flac__read_uint8(bs, 2, &residualMethod)) {
return MA_FALSE;
if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
return DRFLAC_FALSE;
if (residualMethod != MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
return MA_FALSE;
drflac_uint8 riceParam = 0;
if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!drflac__read_uint8(bs, 4, &riceParam)) {
return DRFLAC_FALSE;
ma_uint8 riceParam = 0;
if (residualMethod == MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!ma_dr_flac__read_uint8(bs, 4, &riceParam)) {
return MA_FALSE;
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!drflac__read_uint8(bs, 5, &riceParam)) {
return DRFLAC_FALSE;
} else if (residualMethod == MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!ma_dr_flac__read_uint8(bs, 5, &riceParam)) {
return MA_FALSE;
if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return MA_FALSE;
drflac_uint8 unencodedBitsPerSample = 0;
if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
return DRFLAC_FALSE;
ma_uint8 unencodedBitsPerSample = 0;
if (!ma_dr_flac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
return MA_FALSE;
if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return MA_FALSE;
drflac_uint8 residualMethod;
drflac_uint8 partitionOrder;
drflac_uint32 samplesInPartition;
drflac_uint32 partitionsRemaining;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(blockSize != 0);
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
return DRFLAC_FALSE;
ma_uint8 residualMethod;
ma_uint8 partitionOrder;
ma_uint32 samplesInPartition;
ma_uint32 partitionsRemaining;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(blockSize != 0);
if (!ma_dr_flac__read_uint8(bs, 2, &residualMethod)) {
return MA_FALSE;
if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
return DRFLAC_FALSE;
if (residualMethod != MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
return MA_FALSE;
drflac_uint8 riceParam = 0;
if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!drflac__read_uint8(bs, 4, &riceParam)) {
return DRFLAC_FALSE;
ma_uint8 riceParam = 0;
if (residualMethod == MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) {
if (!ma_dr_flac__read_uint8(bs, 4, &riceParam)) {
return MA_FALSE;
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!drflac__read_uint8(bs, 5, &riceParam)) {
return DRFLAC_FALSE;
} else if (residualMethod == MA_DR_FLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
if (!ma_dr_flac__read_uint8(bs, 5, &riceParam)) {
return MA_FALSE;
drflac_uint8 unencodedBitsPerSample = 0;
if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
return DRFLAC_FALSE;
ma_uint8 unencodedBitsPerSample = 0;
if (!ma_dr_flac__read_uint8(bs, 5, &unencodedBitsPerSample)) {
return MA_FALSE;
static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
static ma_bool32 ma_dr_flac__decode_samples__constant(ma_dr_flac_bs* bs, ma_uint32 blockSize, ma_uint32 subframeBitsPerSample, ma_int32* pDecodedSamples)
drflac_uint32 i;
drflac_int32 sample;
if (!drflac__read_int32(bs, subframeBitsPerSample, &sample)) {
return DRFLAC_FALSE;
ma_uint32 i;
ma_int32 sample;
if (!ma_dr_flac__read_int32(bs, subframeBitsPerSample, &sample)) {
return MA_FALSE;
static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_int32* pDecodedSamples)
static ma_bool32 ma_dr_flac__decode_samples__verbatim(ma_dr_flac_bs* bs, ma_uint32 blockSize, ma_uint32 subframeBitsPerSample, ma_int32* pDecodedSamples)
static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 subframeBitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
static ma_bool32 ma_dr_flac__decode_samples__fixed(ma_dr_flac_bs* bs, ma_uint32 blockSize, ma_uint32 subframeBitsPerSample, ma_uint8 lpcOrder, ma_int32* pDecodedSamples)
if (!drflac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__decode_samples_with_residual(bs, subframeBitsPerSample, blockSize, lpcOrder, 0, 4, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) {
return MA_FALSE;
static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples)
static ma_bool32 ma_dr_flac__decode_samples__lpc(ma_dr_flac_bs* bs, ma_uint32 blockSize, ma_uint32 bitsPerSample, ma_uint8 lpcOrder, ma_int32* pDecodedSamples)
if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, lpcPrecision, coefficients, pDecodedSamples)) {
return MA_FALSE;
static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header)
static ma_bool32 ma_dr_flac__read_next_flac_frame_header(ma_dr_flac_bs* bs, ma_uint8 streaminfoBitsPerSample, ma_dr_flac_frame_header* header)
const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1};
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(header != NULL);
const ma_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
const ma_uint8 bitsPerSampleTable[8] = {0, 8, 12, (ma_uint8)-1, 16, 20, 24, (ma_uint8)-1};
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(header != NULL);
drflac_uint8 crc8 = 0xCE;
drflac_uint8 reserved = 0;
drflac_uint8 blockingStrategy = 0;
drflac_uint8 blockSize = 0;
drflac_uint8 sampleRate = 0;
drflac_uint8 channelAssignment = 0;
drflac_uint8 bitsPerSample = 0;
drflac_bool32 isVariableBlockSize;
if (!drflac__find_and_seek_to_next_sync_code(bs)) {
return DRFLAC_FALSE;
ma_uint8 crc8 = 0xCE;
ma_uint8 reserved = 0;
ma_uint8 blockingStrategy = 0;
ma_uint8 blockSize = 0;
ma_uint8 sampleRate = 0;
ma_uint8 channelAssignment = 0;
ma_uint8 bitsPerSample = 0;
ma_bool32 isVariableBlockSize;
if (!ma_dr_flac__find_and_seek_to_next_sync_code(bs)) {
return MA_FALSE;
crc8 = drflac_crc8(crc8, sampleRate, 4);
if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
return DRFLAC_FALSE;
crc8 = ma_dr_flac_crc8(crc8, sampleRate, 4);
if (!ma_dr_flac__read_uint8(bs, 4, &channelAssignment)) {
return MA_FALSE;
crc8 = drflac_crc8(crc8, channelAssignment, 4);
if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
return DRFLAC_FALSE;
crc8 = ma_dr_flac_crc8(crc8, channelAssignment, 4);
if (!ma_dr_flac__read_uint8(bs, 3, &bitsPerSample)) {
return MA_FALSE;
drflac_uint64 pcmFrameNumber;
drflac_result result = drflac__read_utf8_coded_number(bs, &pcmFrameNumber, &crc8);
if (result != DRFLAC_SUCCESS) {
if (result == DRFLAC_AT_END) {
return DRFLAC_FALSE;
ma_uint64 pcmFrameNumber;
ma_result result = ma_dr_flac__read_utf8_coded_number(bs, &pcmFrameNumber, &crc8);
if (result != MA_SUCCESS) {
if (result == MA_AT_END) {
return MA_FALSE;
drflac_uint64 flacFrameNumber = 0;
drflac_result result = drflac__read_utf8_coded_number(bs, &flacFrameNumber, &crc8);
if (result != DRFLAC_SUCCESS) {
if (result == DRFLAC_AT_END) {
return DRFLAC_FALSE;
ma_uint64 flacFrameNumber = 0;
ma_result result = ma_dr_flac__read_utf8_coded_number(bs, &flacFrameNumber, &crc8);
if (result != MA_SUCCESS) {
if (result == MA_AT_END) {
return MA_FALSE;
static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut)
static ma_bool32 ma_dr_flac__decode_subframe(ma_dr_flac_bs* bs, ma_dr_flac_frame* frame, int subframeIndex, ma_int32* pDecodedSamplesOut)
drflac_subframe* pSubframe;
drflac_uint32 subframeBitsPerSample;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(frame != NULL);
ma_dr_flac_subframe* pSubframe;
ma_uint32 subframeBitsPerSample;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(frame != NULL);
if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
if ((frame->header.channelAssignment == MA_DR_FLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == MA_DR_FLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
drflac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
ma_dr_flac__decode_samples__constant(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
drflac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
ma_dr_flac__decode_samples__verbatim(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->pSamplesS32);
drflac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
ma_dr_flac__decode_samples__fixed(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
drflac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
ma_dr_flac__decode_samples__lpc(bs, frame->header.blockSizeInPCMFrames, subframeBitsPerSample, pSubframe->lpcOrder, pSubframe->pSamplesS32);
drflac_subframe* pSubframe;
drflac_uint32 subframeBitsPerSample;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(frame != NULL);
ma_dr_flac_subframe* pSubframe;
ma_uint32 subframeBitsPerSample;
MA_DR_FLAC_ASSERT(bs != NULL);
MA_DR_FLAC_ASSERT(frame != NULL);
if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
if ((frame->header.channelAssignment == MA_DR_FLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == MA_DR_FLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) {
if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
return MA_FALSE;
if (!drflac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_and_seek_residual(bs, frame->header.blockSizeInPCMFrames, pSubframe->lpcOrder)) {
return MA_FALSE;
channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
channelCount = ma_dr_flac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
return DRFLAC_ERROR;
if (!ma_dr_flac__decode_subframe(&pFlac->bs, &pFlac->currentFLACFrame, i, pFlac->pDecodedSamples + (pFlac->currentFLACFrame.header.blockSizeInPCMFrames * i))) {
return MA_ERROR;
channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
channelCount = ma_dr_flac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
drflac_result result;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
ma_result result;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame)
static void ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(ma_dr_flac* pFlac, ma_uint64* pFirstPCMFrame, ma_uint64* pLastPCMFrame)
drflac_bool32 result;
DRFLAC_ASSERT(pFlac != NULL);
result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
ma_bool32 result;
MA_DR_FLAC_ASSERT(pFlac != NULL);
result = ma_dr_flac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
MA_DR_FLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
drflac_uint64 pcmFrameCountInThisFLACFrame;
drflac_uint64 firstPCMFrameInFLACFrame = 0;
drflac_uint64 lastPCMFrameInFLACFrame = 0;
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
ma_uint64 pcmFrameCountInThisFLACFrame;
ma_uint64 firstPCMFrameInFLACFrame = 0;
ma_uint64 lastPCMFrameInFLACFrame = 0;
ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
drflac_result result = drflac__decode_flac_frame(pFlac);
if (result == DRFLAC_SUCCESS) {
return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
ma_result result = ma_dr_flac__decode_flac_frame(pFlac);
if (result == MA_SUCCESS) {
return ma_dr_flac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
#if !defined(DR_FLAC_NO_CRC)
#define DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
#if !defined(MA_DR_FLAC_NO_CRC)
#define MA_DR_FLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO 0.6f
static ma_bool32 ma_dr_flac__seek_to_approximate_flac_frame_to_byte(ma_dr_flac* pFlac, ma_uint64 targetByte, ma_uint64 rangeLo, ma_uint64 rangeHi, ma_uint64* pLastSuccessfulSeekOffset)
DRFLAC_ASSERT(pFlac != NULL);
DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
DRFLAC_ASSERT(targetByte >= rangeLo);
DRFLAC_ASSERT(targetByte <= rangeHi);
MA_DR_FLAC_ASSERT(pFlac != NULL);
MA_DR_FLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
MA_DR_FLAC_ASSERT(targetByte >= rangeLo);
MA_DR_FLAC_ASSERT(targetByte <= rangeHi);
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
DRFLAC_ASSERT(targetByte <= rangeHi);
ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
MA_DR_FLAC_ASSERT(targetByte <= rangeHi);
if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
return DRFLAC_FALSE;
if (ma_dr_flac__decode_flac_frame(pFlac) != MA_SUCCESS) {
if (ma_dr_flac__read_and_decode_next_flac_frame(pFlac) == MA_FALSE) {
return MA_FALSE;
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
static ma_bool32 ma_dr_flac__seek_to_pcm_frame__binary_search_internal(ma_dr_flac* pFlac, ma_uint64 pcmFrameIndex, ma_uint64 byteRangeLo, ma_uint64 byteRangeHi)
drflac_uint64 targetByte;
drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
drflac_uint64 pcmRangeHi = 0;
drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
ma_uint64 targetByte;
ma_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
ma_uint64 pcmRangeHi = 0;
ma_uint64 lastSuccessfulSeekOffset = (ma_uint64)-1;
ma_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
ma_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
targetByte = byteRangeLo + (ma_uint64)(((ma_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * MA_DR_FLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
drflac_uint64 newPCMRangeLo;
drflac_uint64 newPCMRangeHi;
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
if (ma_dr_flac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
ma_uint64 newPCMRangeLo;
ma_uint64 newPCMRangeHi;
ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
if (!ma_dr_flac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
return DRFLAC_TRUE;
if (ma_dr_flac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
return MA_TRUE;
if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
return DRFLAC_TRUE;
if (ma_dr_flac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame) ) {
return MA_TRUE;
const float approxCompressionRatio = (drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
const float approxCompressionRatio = (ma_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / ((ma_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
return DRFLAC_TRUE;
if (ma_dr_flac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
return MA_TRUE;
targetByte = lastSuccessfulSeekOffset + (drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
targetByte = lastSuccessfulSeekOffset + (ma_uint64)(((ma_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
drflac_uint64 byteRangeLo;
drflac_uint64 byteRangeHi;
drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
if (drflac__seek_to_first_frame(pFlac) == DRFLAC_FALSE) {
return DRFLAC_FALSE;
ma_uint64 byteRangeLo;
ma_uint64 byteRangeHi;
ma_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
if (ma_dr_flac__seek_to_first_frame(pFlac) == MA_FALSE) {
return MA_FALSE;
byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
return drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
byteRangeHi = pFlac->firstFLACFramePosInBytes + (ma_uint64)((ma_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
return ma_dr_flac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi);
drflac_uint32 iClosestSeekpoint = 0;
drflac_bool32 isMidFrame = DRFLAC_FALSE;
drflac_uint64 runningPCMFrameCount;
drflac_uint32 iSeekpoint;
DRFLAC_ASSERT(pFlac != NULL);
ma_uint32 iClosestSeekpoint = 0;
ma_bool32 isMidFrame = MA_FALSE;
ma_uint64 runningPCMFrameCount;
ma_uint32 iSeekpoint;
MA_DR_FLAC_ASSERT(pFlac != NULL);
drflac_uint64 byteRangeLo;
drflac_uint64 byteRangeHi;
byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
ma_uint64 byteRangeLo;
ma_uint64 byteRangeHi;
byteRangeHi = pFlac->firstFLACFramePosInBytes + (ma_uint64)((ma_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f);
if (drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
if (drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
if (drflac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
return DRFLAC_TRUE;
if (ma_dr_flac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
if (ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
if (ma_dr_flac__seek_to_pcm_frame__binary_search_internal(pFlac, pcmFrameIndex, byteRangeLo, byteRangeHi)) {
return MA_TRUE;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset)) {
return MA_FALSE;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
drflac_uint64 pcmFrameCountInThisFLACFrame;
drflac_uint64 firstPCMFrameInFLACFrame = 0;
drflac_uint64 lastPCMFrameInFLACFrame = 0;
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
ma_uint64 pcmFrameCountInThisFLACFrame;
ma_uint64 firstPCMFrameInFLACFrame = 0;
ma_uint64 lastPCMFrameInFLACFrame = 0;
ma_dr_flac__get_pcm_frame_range_of_current_flac_frame(pFlac, &firstPCMFrameInFLACFrame, &lastPCMFrameInFLACFrame);
drflac_result result = drflac__decode_flac_frame(pFlac);
if (result == DRFLAC_SUCCESS) {
return drflac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
ma_result result = ma_dr_flac__decode_flac_frame(pFlac);
if (result == MA_SUCCESS) {
return ma_dr_flac__seek_forward_by_pcm_frames(pFlac, pcmFramesToDecode) == pcmFramesToDecode;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
drflac_uint8 capturePattern[4];
drflac_uint8 structureVersion;
drflac_uint8 headerType;
drflac_uint64 granulePosition;
drflac_uint32 serialNumber;
drflac_uint32 sequenceNumber;
drflac_uint32 checksum;
drflac_uint8 segmentCount;
drflac_uint8 segmentTable[255];
} drflac_ogg_page_header;
ma_uint8 capturePattern[4];
ma_uint8 structureVersion;
ma_uint8 headerType;
ma_uint64 granulePosition;
ma_uint32 serialNumber;
ma_uint32 sequenceNumber;
ma_uint32 checksum;
ma_uint8 segmentCount;
ma_uint8 segmentTable[255];
} ma_dr_flac_ogg_page_header;
drflac_uint32 sampleRate;
drflac_uint8 channels;
drflac_uint8 bitsPerSample;
drflac_uint64 totalPCMFrameCount;
drflac_uint16 maxBlockSizeInPCMFrames;
drflac_uint64 runningFilePos;
drflac_bool32 hasStreamInfoBlock;
drflac_bool32 hasMetadataBlocks;
drflac_bs bs;
drflac_frame_header firstFrameHeader;
#ifndef DR_FLAC_NO_OGG
drflac_uint32 oggSerial;
drflac_uint64 oggFirstBytePos;
drflac_ogg_page_header oggBosHeader;
ma_uint32 sampleRate;
ma_uint8 channels;
ma_uint8 bitsPerSample;
ma_uint64 totalPCMFrameCount;
ma_uint16 maxBlockSizeInPCMFrames;
ma_uint64 runningFilePos;
ma_bool32 hasStreamInfoBlock;
ma_bool32 hasMetadataBlocks;
ma_dr_flac_bs bs;
ma_dr_flac_frame_header firstFrameHeader;
#ifndef MA_DR_FLAC_NO_OGG
ma_uint32 oggSerial;
ma_uint64 oggFirstBytePos;
ma_dr_flac_ogg_page_header oggBosHeader;
} drflac_init_info;
static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
} ma_dr_flac_init_info;
static MA_INLINE void ma_dr_flac__decode_block_header(ma_uint32 blockHeader, ma_uint8* isLastBlock, ma_uint8* blockType, ma_uint32* blockSize)
blockHeader = drflac__be2host_32(blockHeader);
*isLastBlock = (drflac_uint8)((blockHeader & 0x80000000UL) >> 31);
*blockType = (drflac_uint8)((blockHeader & 0x7F000000UL) >> 24);
blockHeader = ma_dr_flac__be2host_32(blockHeader);
*isLastBlock = (ma_uint8)((blockHeader & 0x80000000UL) >> 31);
*blockType = (ma_uint8)((blockHeader & 0x7F000000UL) >> 24);
static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize)
static MA_INLINE ma_bool32 ma_dr_flac__read_and_decode_block_header(ma_dr_flac_read_proc onRead, void* pUserData, ma_uint8* isLastBlock, ma_uint8* blockType, ma_uint32* blockSize)
static drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo)
static ma_bool32 ma_dr_flac__read_streaminfo(ma_dr_flac_read_proc onRead, void* pUserData, ma_dr_flac_streaminfo* pStreamInfo)
blockSizes = drflac__be2host_32(blockSizes);
frameSizes = drflac__be2host_64(frameSizes);
importantProps = drflac__be2host_64(importantProps);
pStreamInfo->minBlockSizeInPCMFrames = (drflac_uint16)((blockSizes & 0xFFFF0000) >> 16);
pStreamInfo->maxBlockSizeInPCMFrames = (drflac_uint16) (blockSizes & 0x0000FFFF);
pStreamInfo->minFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40);
pStreamInfo->maxFrameSizeInPCMFrames = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 0)) >> 16);
pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44);
pStreamInfo->channels = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
pStreamInfo->totalPCMFrameCount = ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
return DRFLAC_TRUE;
blockSizes = ma_dr_flac__be2host_32(blockSizes);
frameSizes = ma_dr_flac__be2host_64(frameSizes);
importantProps = ma_dr_flac__be2host_64(importantProps);
pStreamInfo->minBlockSizeInPCMFrames = (ma_uint16)((blockSizes & 0xFFFF0000) >> 16);
pStreamInfo->maxBlockSizeInPCMFrames = (ma_uint16) (blockSizes & 0x0000FFFF);
pStreamInfo->minFrameSizeInPCMFrames = (ma_uint32)((frameSizes & (((ma_uint64)0x00FFFFFF << 16) << 24)) >> 40);
pStreamInfo->maxFrameSizeInPCMFrames = (ma_uint32)((frameSizes & (((ma_uint64)0x00FFFFFF << 16) << 0)) >> 16);
pStreamInfo->sampleRate = (ma_uint32)((importantProps & (((ma_uint64)0x000FFFFF << 16) << 28)) >> 44);
pStreamInfo->channels = (ma_uint8 )((importantProps & (((ma_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
pStreamInfo->bitsPerSample = (ma_uint8 )((importantProps & (((ma_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
pStreamInfo->totalPCMFrameCount = ((importantProps & ((((ma_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
MA_DR_FLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
return MA_TRUE;
static void* drflac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drflac_allocation_callbacks* pAllocationCallbacks)
static void* ma_dr_flac__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const ma_allocation_callbacks* pAllocationCallbacks)
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* pSeektableSize, drflac_allocation_callbacks* pAllocationCallbacks)
static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, void* pUserDataMD, ma_uint64* pFirstFramePos, ma_uint64* pSeektablePos, ma_uint32* pSeekpointCount, ma_allocation_callbacks* pAllocationCallbacks)
drflac_metadata metadata;
drflac_uint8 isLastBlock = 0;
drflac_uint8 blockType;
drflac_uint32 blockSize;
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
return DRFLAC_FALSE;
ma_dr_flac_metadata metadata;
ma_uint8 isLastBlock = 0;
ma_uint8 blockType;
ma_uint32 blockSize;
if (ma_dr_flac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == MA_FALSE) {
return MA_FALSE;
metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData);
metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32));
metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32);
metadata.data.application.id = ma_dr_flac__be2host_32(*(ma_uint32*)pRawData);
metadata.data.application.pData = (const void*)((ma_uint8*)pRawData + sizeof(ma_uint32));
metadata.data.application.dataSize = blockSize - sizeof(ma_uint32);
pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
seekpointCount = blockSize/MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES;
pRawData = ma_dr_flac__malloc_from_callbacks(seekpointCount * sizeof(ma_dr_flac_seekpoint), pAllocationCallbacks);
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
for (iSeekpoint = 0; iSeekpoint < seekpointCount; ++iSeekpoint) {
ma_dr_flac_seekpoint* pSeekpoint = (ma_dr_flac_seekpoint*)pRawData + iSeekpoint;
if (onRead(pUserData, pSeekpoint, MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) != MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
}
pSeekpoint->firstPCMFrame = ma_dr_flac__be2host_64(pSeekpoint->firstPCMFrame);
pSeekpoint->flacFrameOffset = ma_dr_flac__be2host_64(pSeekpoint->flacFrameOffset);
pSeekpoint->pcmFrameCount = ma_dr_flac__be2host_16(pSeekpoint->pcmFrameCount);
metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint);
metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
pSeekpoint->firstPCMFrame = drflac__be2host_64(pSeekpoint->firstPCMFrame);
pSeekpoint->flacFrameOffset = drflac__be2host_64(pSeekpoint->flacFrameOffset);
pSeekpoint->pcmFrameCount = drflac__be2host_16(pSeekpoint->pcmFrameCount);
}
metadata.data.seektable.seekpointCount = seekpointCount;
metadata.data.seektable.pSeekpoints = (const ma_dr_flac_seekpoint*)pRawData;
metadata.data.vorbis_comment.vendorLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.vorbis_comment.vendorLength = ma_dr_flac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 4 < (ma_int64)metadata.data.vorbis_comment.vendorLength) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
metadata.data.vorbis_comment.commentCount = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.vorbis_comment.commentCount = ma_dr_flac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) / sizeof(ma_uint32) < metadata.data.vorbis_comment.commentCount) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
commentLength = drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
commentLength = ma_dr_flac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if (pRunningDataEnd - pRunningData < (ma_int64)commentLength) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
drflac_uint8 iTrack;
drflac_uint8 iIndex;
pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
size_t bufferSize;
ma_uint8 iTrack;
ma_uint8 iIndex;
void* pTrackData;
pRawData = ma_dr_flac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
DRFLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
MA_DR_FLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
metadata.data.cuesheet.leadInSampleCount = ma_dr_flac__be2host_64(*(const ma_uint64*)pRunningData); pRunningData += 8;
metadata.data.cuesheet.pTrackData = pRunningData;
for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
drflac_uint8 indexCount;
drflac_uint32 indexPointSize;
if (pRunningDataEnd - pRunningData < 36) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.cuesheet.pTrackData = NULL;
{
const char* pRunningDataSaved = pRunningData;
bufferSize = metadata.data.cuesheet.trackCount * MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES;
for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
ma_uint8 indexCount;
ma_uint32 indexPointSize;
if (pRunningDataEnd - pRunningData < MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
}
pRunningData += 35;
indexCount = pRunningData[0];
pRunningData += 1;
bufferSize += indexCount * sizeof(ma_dr_flac_cuesheet_track_index);
indexPointSize = indexCount * MA_DR_FLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
if (pRunningDataEnd - pRunningData < (ma_int64)indexPointSize) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
}
pRunningData += indexPointSize;
pRunningData += 35;
indexCount = pRunningData[0]; pRunningData += 1;
indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index);
if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
pRunningData = pRunningDataSaved;
}
{
char* pRunningTrackData;
pTrackData = ma_dr_flac__malloc_from_callbacks(bufferSize, pAllocationCallbacks);
if (pTrackData == NULL) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
for (iIndex = 0; iIndex < indexCount; ++iIndex) {
drflac_cuesheet_track_index* pTrack = (drflac_cuesheet_track_index*)pRunningData;
pRunningData += sizeof(drflac_cuesheet_track_index);
pTrack->offset = drflac__be2host_64(pTrack->offset);
pRunningTrackData = (char*)pTrackData;
for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
ma_uint8 indexCount;
MA_DR_FLAC_COPY_MEMORY(pRunningTrackData, pRunningData, MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES);
pRunningData += MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1;
pRunningTrackData += MA_DR_FLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1;
indexCount = pRunningData[0];
pRunningData += 1;
pRunningTrackData += 1;
for (iIndex = 0; iIndex < indexCount; ++iIndex) {
ma_dr_flac_cuesheet_track_index* pTrackIndex = (ma_dr_flac_cuesheet_track_index*)pRunningTrackData;
MA_DR_FLAC_COPY_MEMORY(pRunningTrackData, pRunningData, MA_DR_FLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES);
pRunningData += MA_DR_FLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
pRunningTrackData += sizeof(ma_dr_flac_cuesheet_track_index);
pTrackIndex->offset = ma_dr_flac__be2host_64(pTrackIndex->offset);
}
metadata.data.picture.type = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.mimeLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.picture.type = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.mimeLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 24 < (ma_int64)metadata.data.picture.mimeLength) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
metadata.data.picture.descriptionLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
metadata.data.picture.descriptionLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
if ((pRunningDataEnd - pRunningData) - 20 < (ma_int64)metadata.data.picture.descriptionLength) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
metadata.data.picture.width = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.height = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.colorDepth = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.indexColorCount = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.pictureDataSize = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
metadata.data.picture.width = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.height = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.colorDepth = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.indexColorCount = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.pictureDataSize = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.pPictureData = (const ma_uint8*)pRunningData;
if (pRunningDataEnd - pRunningData < (ma_int64)metadata.data.picture.pictureDataSize) {
ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks);
return MA_FALSE;
*pSeektablePos = seektablePos;
*pSeektableSize = seektableSize;
*pFirstFramePos = runningFilePos;
return DRFLAC_TRUE;
*pSeektablePos = seektablePos;
*pSeekpointCount = seektableSize / MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES;
*pFirstFramePos = runningFilePos;
return MA_TRUE;
static drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
static ma_bool32 ma_dr_flac__init_private__native(ma_dr_flac_init_info* pInit, ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, void* pUserDataMD, ma_bool32 relaxed)
pInit->container = drflac_container_native;
if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
return DRFLAC_FALSE;
pInit->container = ma_dr_flac_container_native;
if (!ma_dr_flac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
return MA_FALSE;
pInit->hasStreamInfoBlock = DRFLAC_FALSE;
pInit->hasMetadataBlocks = DRFLAC_FALSE;
if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
return DRFLAC_FALSE;
pInit->hasStreamInfoBlock = MA_FALSE;
pInit->hasMetadataBlocks = MA_FALSE;
if (!ma_dr_flac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) {
return MA_FALSE;
drflac_ogg_recover_on_crc_mismatch,
drflac_ogg_fail_on_crc_mismatch
} drflac_ogg_crc_mismatch_recovery;
#ifndef DR_FLAC_NO_CRC
static drflac_uint32 drflac__crc32_table[] = {
ma_dr_flac_ogg_recover_on_crc_mismatch,
ma_dr_flac_ogg_fail_on_crc_mismatch
} ma_dr_flac_ogg_crc_mismatch_recovery;
#ifndef MA_DR_FLAC_NO_CRC
static ma_uint32 ma_dr_flac__crc32_table[] = {
crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF));
crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF));
crc32 = ma_dr_flac_crc32_byte(crc32, (ma_uint8)((data >> 24) & 0xFF));
crc32 = ma_dr_flac_crc32_byte(crc32, (ma_uint8)((data >> 16) & 0xFF));
crc32 = ma_dr_flac_crc32_byte(crc32, (ma_uint8)((data >> 8) & 0xFF));
crc32 = ma_dr_flac_crc32_byte(crc32, (ma_uint8)((data >> 0) & 0xFF));
crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF));
crc32 = ma_dr_flac_crc32_uint32(crc32, (ma_uint32)((data >> 32) & 0xFFFFFFFF));
crc32 = ma_dr_flac_crc32_uint32(crc32, (ma_uint32)((data >> 0) & 0xFFFFFFFF));
static drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
static ma_result ma_dr_flac_ogg__read_page_header_after_capture_pattern(ma_dr_flac_read_proc onRead, void* pUserData, ma_dr_flac_ogg_page_header* pHeader, ma_uint32* pBytesRead, ma_uint32* pCRC32)
DRFLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
DRFLAC_COPY_MEMORY(&pHeader->serialNumber, &data[10], 4);
DRFLAC_COPY_MEMORY(&pHeader->sequenceNumber, &data[14], 4);
DRFLAC_COPY_MEMORY(&pHeader->checksum, &data[18], 4);
MA_DR_FLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
MA_DR_FLAC_COPY_MEMORY(&pHeader->serialNumber, &data[10], 4);
MA_DR_FLAC_COPY_MEMORY(&pHeader->sequenceNumber, &data[14], 4);
MA_DR_FLAC_COPY_MEMORY(&pHeader->checksum, &data[18], 4);
static drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32)
static ma_result ma_dr_flac_ogg__read_page_header(ma_dr_flac_read_proc onRead, void* pUserData, ma_dr_flac_ogg_page_header* pHeader, ma_uint32* pBytesRead, ma_uint32* pCRC32)
if (drflac_ogg__is_capture_pattern(id)) {
drflac_result result;
*pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32;
result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
if (result == DRFLAC_SUCCESS) {
return DRFLAC_SUCCESS;
if (ma_dr_flac_ogg__is_capture_pattern(id)) {
ma_result result;
*pCRC32 = MA_DR_FLAC_OGG_CAPTURE_PATTERN_CRC32;
result = ma_dr_flac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32);
if (result == MA_SUCCESS) {
return MA_SUCCESS;
drflac_uint64 currentBytePos;
drflac_uint64 firstBytePos;
drflac_uint32 serialNumber;
drflac_ogg_page_header bosPageHeader;
drflac_ogg_page_header currentPageHeader;
drflac_uint32 bytesRemainingInPage;
drflac_uint32 pageDataSize;
drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE];
} drflac_oggbs;
static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
ma_uint64 currentBytePos;
ma_uint64 firstBytePos;
ma_uint32 serialNumber;
ma_dr_flac_ogg_page_header bosPageHeader;
ma_dr_flac_ogg_page_header currentPageHeader;
ma_uint32 bytesRemainingInPage;
ma_uint32 pageDataSize;
ma_uint8 pageData[MA_DR_FLAC_OGG_MAX_PAGE_SIZE];
} ma_dr_flac_oggbs;
static size_t ma_dr_flac_oggbs__read_physical(ma_dr_flac_oggbs* oggbs, void* bufferOut, size_t bytesToRead)
static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin)
static ma_bool32 ma_dr_flac_oggbs__seek_physical(ma_dr_flac_oggbs* oggbs, ma_uint64 offset, ma_dr_flac_seek_origin origin)
static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod)
static ma_bool32 ma_dr_flac_oggbs__goto_next_page(ma_dr_flac_oggbs* oggbs, ma_dr_flac_ogg_crc_mismatch_recovery recoveryMethod)
drflac_uint32 crc32 = 0;
drflac_uint32 bytesRead;
drflac_uint32 pageBodySize;
#ifndef DR_FLAC_NO_CRC
drflac_uint32 actualCRC32;
ma_uint32 crc32 = 0;
ma_uint32 bytesRead;
ma_uint32 pageBodySize;
#ifndef MA_DR_FLAC_NO_CRC
ma_uint32 actualCRC32;
if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
return DRFLAC_FALSE;
if (ma_dr_flac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != MA_SUCCESS) {
return MA_FALSE;
if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) {
return DRFLAC_FALSE;
if (pageBodySize > 0 && !ma_dr_flac_oggbs__seek_physical(oggbs, pageBodySize, ma_dr_flac_seek_origin_current)) {
return MA_FALSE;
drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
drflac_uint8 iSeg = 0;
drflac_uint32 iByte = 0;
ma_uint32 bytesConsumedInPage = ma_dr_flac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
ma_uint8 iSeg = 0;
ma_uint32 iByte = 0;
drflac_bool32 atEndOfPage = DRFLAC_FALSE;
drflac_uint8 bytesRemainingInSeg;
drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
ma_bool32 atEndOfPage = MA_FALSE;
ma_uint8 bytesRemainingInSeg;
ma_uint8 iFirstSeg = ma_dr_flac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
ma_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
for (ma_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
ma_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
MA_DR_FLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
MA_DR_FLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
DRFLAC_ASSERT(bytesRemainingToRead > 0);
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
MA_DR_FLAC_ASSERT(bytesRemainingToRead > 0);
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_recover_on_crc_mismatch)) {
DRFLAC_ASSERT(oggbs != NULL);
DRFLAC_ASSERT(offset >= 0);
if (origin == drflac_seek_origin_start) {
if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) {
return DRFLAC_FALSE;
MA_DR_FLAC_ASSERT(oggbs != NULL);
MA_DR_FLAC_ASSERT(offset >= 0);
if (origin == ma_dr_flac_seek_origin_start) {
if (!ma_dr_flac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, ma_dr_flac_seek_origin_start)) {
return MA_FALSE;
DRFLAC_ASSERT(bytesRemainingToSeek > 0);
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
return DRFLAC_FALSE;
MA_DR_FLAC_ASSERT(bytesRemainingToSeek > 0);
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_fail_on_crc_mismatch)) {
return MA_FALSE;
drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
drflac_uint64 originalBytePos;
drflac_uint64 runningGranulePosition;
drflac_uint64 runningFrameBytePos;
drflac_uint64 runningPCMFrameCount;
DRFLAC_ASSERT(oggbs != NULL);
ma_dr_flac_oggbs* oggbs = (ma_dr_flac_oggbs*)pFlac->_oggbs;
ma_uint64 originalBytePos;
ma_uint64 runningGranulePosition;
ma_uint64 runningFrameBytePos;
ma_uint64 runningPCMFrameCount;
MA_DR_FLAC_ASSERT(oggbs != NULL);
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start);
return DRFLAC_FALSE;
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_recover_on_crc_mismatch)) {
ma_dr_flac_oggbs__seek_physical(oggbs, originalBytePos, ma_dr_flac_seek_origin_start);
return MA_FALSE;
runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
runningFrameBytePos = oggbs->currentBytePos - ma_dr_flac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
drflac_uint64 firstPCMFrameInFLACFrame = 0;
drflac_uint64 lastPCMFrameInFLACFrame = 0;
drflac_uint64 pcmFrameCountInThisFrame;
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return DRFLAC_FALSE;
ma_uint64 firstPCMFrameInFLACFrame = 0;
ma_uint64 lastPCMFrameInFLACFrame = 0;
ma_uint64 pcmFrameCountInThisFrame;
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
return MA_FALSE;
drflac_result result = drflac__decode_flac_frame(pFlac);
if (result == DRFLAC_SUCCESS) {
drflac_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);
ma_result result = ma_dr_flac__decode_flac_frame(pFlac);
if (result == MA_SUCCESS) {
ma_uint64 pcmFramesToDecode = (size_t)(pcmFrameIndex - runningPCMFrameCount);
static drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed)
static ma_bool32 ma_dr_flac__init_private__ogg(ma_dr_flac_init_info* pInit, ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, void* pUserDataMD, ma_bool32 relaxed)
if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
return DRFLAC_FALSE;
if (ma_dr_flac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != MA_SUCCESS) {
return MA_FALSE;
drflac_streaminfo streaminfo;
drflac_uint8 isLastBlock;
drflac_uint8 blockType;
drflac_uint32 blockSize;
if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
return DRFLAC_FALSE;
ma_dr_flac_streaminfo streaminfo;
ma_uint8 isLastBlock;
ma_uint8 blockType;
ma_uint32 blockSize;
if (!ma_dr_flac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) {
return MA_FALSE;
if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
return DRFLAC_FALSE;
if (ma_dr_flac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != MA_SUCCESS) {
return MA_FALSE;
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 ma_bool32 ma_dr_flac__init_private(ma_dr_flac_init_info* pInit, ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD)
DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
MA_DR_FLAC_COPY_MEMORY(&headerSize, header+2, 4);
headerSize = ma_dr_flac__unsynchsafe_32(ma_dr_flac__be2host_32(headerSize));
if (container == drflac_container_native) {
return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
if (container == ma_dr_flac_container_native) {
return ma_dr_flac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
#ifndef DR_FLAC_NO_OGG
if (container == drflac_container_ogg) {
return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
#ifndef MA_DR_FLAC_NO_OGG
if (container == ma_dr_flac_container_ogg) {
return ma_dr_flac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed);
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 ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD, const ma_allocation_callbacks* pAllocationCallbacks)
drflac_init_info init;
drflac_uint32 allocationSize;
drflac_uint32 wholeSIMDVectorCountPerChannel;
drflac_uint32 decodedSamplesAllocationSize;
#ifndef DR_FLAC_NO_OGG
drflac_oggbs oggbs;
ma_dr_flac_init_info init;
ma_uint32 allocationSize;
ma_uint32 wholeSIMDVectorCountPerChannel;
ma_uint32 decodedSamplesAllocationSize;
#ifndef MA_DR_FLAC_NO_OGG
ma_dr_flac_oggbs* pOggbs = NULL;
drflac_uint64 firstFramePos;
drflac_uint64 seektablePos;
drflac_uint32 seektableSize;
drflac_allocation_callbacks allocationCallbacks;
drflac* pFlac;
drflac__init_cpu_caps();
if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
ma_uint64 firstFramePos;
ma_uint64 seektablePos;
ma_uint32 seekpointCount;
ma_allocation_callbacks allocationCallbacks;
ma_dr_flac* pFlac;
ma_dr_flac__init_cpu_caps();
if (!ma_dr_flac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
allocationCallbacks.onMalloc = drflac__malloc_default;
allocationCallbacks.onRealloc = drflac__realloc_default;
allocationCallbacks.onFree = drflac__free_default;
allocationCallbacks.onMalloc = ma_dr_flac__malloc_default;
allocationCallbacks.onRealloc = ma_dr_flac__realloc_default;
allocationCallbacks.onFree = ma_dr_flac__free_default;
allocationSize = sizeof(drflac);
if ((init.maxBlockSizeInPCMFrames % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) {
wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32)));
allocationSize = sizeof(ma_dr_flac);
if ((init.maxBlockSizeInPCMFrames % (MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE / sizeof(ma_int32))) == 0) {
wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE / sizeof(ma_int32)));
wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1;
wholeSIMDVectorCountPerChannel = (init.maxBlockSizeInPCMFrames / (MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE / sizeof(ma_int32))) + 1;
allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE;
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
allocationSize += sizeof(drflac_oggbs);
allocationSize += MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE;
#ifndef MA_DR_FLAC_NO_OGG
if (init.container == ma_dr_flac_container_ogg) {
allocationSize += sizeof(ma_dr_flac_oggbs);
pOggbs = (ma_dr_flac_oggbs*)ma_dr_flac__malloc_from_callbacks(sizeof(*pOggbs), &allocationCallbacks);
if (pOggbs == NULL) {
return NULL;
}
MA_DR_FLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
pOggbs->onRead = onRead;
pOggbs->onSeek = onSeek;
pOggbs->pUserData = pUserData;
pOggbs->currentBytePos = init.oggFirstBytePos;
pOggbs->firstBytePos = init.oggFirstBytePos;
pOggbs->serialNumber = init.oggSerial;
pOggbs->bosPageHeader = init.oggBosHeader;
pOggbs->bytesRemainingInPage = 0;
DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
if (init.container == drflac_container_ogg) {
oggbs.onRead = onRead;
oggbs.onSeek = onSeek;
oggbs.pUserData = pUserData;
oggbs.currentBytePos = init.oggFirstBytePos;
oggbs.firstBytePos = init.oggFirstBytePos;
oggbs.serialNumber = init.oggSerial;
oggbs.bosPageHeader = init.oggBosHeader;
oggbs.bytesRemainingInPage = 0;
}
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
onReadOverride = drflac__on_read_ogg;
onSeekOverride = drflac__on_seek_ogg;
pUserDataOverride = (void*)&oggbs;
#ifndef MA_DR_FLAC_NO_OGG
if (init.container == ma_dr_flac_container_ogg) {
onReadOverride = ma_dr_flac__on_read_ogg;
onSeekOverride = ma_dr_flac__on_seek_ogg;
pUserDataOverride = (void*)pOggbs;
if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize, &allocationCallbacks)) {
if (!ma_dr_flac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
#ifndef MA_DR_FLAC_NO_OGG
ma_dr_flac__free_from_callbacks(pOggbs, &allocationCallbacks);
#endif
pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE);
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
DRFLAC_COPY_MEMORY(pInternalOggbs, &oggbs, sizeof(oggbs));
pFlac->bs.onRead = drflac__on_read_ogg;
pFlac->bs.onSeek = drflac__on_seek_ogg;
pFlac->pDecodedSamples = (ma_int32*)ma_dr_flac_align((size_t)pFlac->pExtraData, MA_DR_FLAC_MAX_SIMD_VECTOR_SIZE);
#ifndef MA_DR_FLAC_NO_OGG
if (init.container == ma_dr_flac_container_ogg) {
ma_dr_flac_oggbs* pInternalOggbs = (ma_dr_flac_oggbs*)((ma_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + (seekpointCount * sizeof(ma_dr_flac_seekpoint)));
MA_DR_FLAC_COPY_MEMORY(pInternalOggbs, pOggbs, sizeof(*pOggbs));
ma_dr_flac__free_from_callbacks(pOggbs, &allocationCallbacks);
pOggbs = NULL;
pFlac->bs.onRead = ma_dr_flac__on_read_ogg;
pFlac->bs.onSeek = ma_dr_flac__on_seek_ogg;
pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints);
pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
DRFLAC_ASSERT(pFlac->bs.onRead != NULL);
if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) {
drflac_uint32 iSeekpoint;
for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
pFlac->pSeekpoints[iSeekpoint].firstPCMFrame = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
pFlac->seekpointCount = seekpointCount;
pFlac->pSeekpoints = (ma_dr_flac_seekpoint*)((ma_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
MA_DR_FLAC_ASSERT(pFlac->bs.onSeek != NULL);
MA_DR_FLAC_ASSERT(pFlac->bs.onRead != NULL);
if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, ma_dr_flac_seek_origin_start)) {
ma_uint32 iSeekpoint;
for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints + iSeekpoint, MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) == MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) {
pFlac->pSeekpoints[iSeekpoint].firstPCMFrame = ma_dr_flac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = ma_dr_flac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = ma_dr_flac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
} else {
pFlac->pSeekpoints = NULL;
pFlac->seekpointCount = 0;
break;
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
drflac__free_from_callbacks(pFlac, &allocationCallbacks);
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, ma_dr_flac_seek_origin_start)) {
ma_dr_flac__free_from_callbacks(pFlac, &allocationCallbacks);
if (result == DRFLAC_CRC_MISMATCH) {
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
drflac__free_from_callbacks(pFlac, &allocationCallbacks);
if (result == MA_CRC_MISMATCH) {
if (!ma_dr_flac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
ma_dr_flac__free_from_callbacks(pFlac, &allocationCallbacks);
#include <errno.h>
static drflac_result drflac_result_from_errno(int e)
{
switch (e)
{
case 0: return DRFLAC_SUCCESS;
#ifdef EPERM
case EPERM: return DRFLAC_INVALID_OPERATION;
#endif
#ifdef ENOENT
case ENOENT: return DRFLAC_DOES_NOT_EXIST;
#endif
#ifdef ESRCH
case ESRCH: return DRFLAC_DOES_NOT_EXIST;
#endif
#ifdef EINTR
case EINTR: return DRFLAC_INTERRUPT;
#endif
#ifdef EIO
case EIO: return DRFLAC_IO_ERROR;
#endif
#ifdef ENXIO
case ENXIO: return DRFLAC_DOES_NOT_EXIST;
#endif
#ifdef E2BIG
case E2BIG: return DRFLAC_INVALID_ARGS;
#endif
#ifdef ENOEXEC
case ENOEXEC: return DRFLAC_INVALID_FILE;
#endif
#ifdef EBADF
case EBADF: return DRFLAC_INVALID_FILE;
#endif
#ifdef ECHILD
case ECHILD: return DRFLAC_ERROR;
#endif
#ifdef EAGAIN
case EAGAIN: return DRFLAC_UNAVAILABLE;
#endif
#ifdef ENOMEM
case ENOMEM: return DRFLAC_OUT_OF_MEMORY;
#endif
#ifdef EACCES
case EACCES: return DRFLAC_ACCESS_DENIED;
#endif
#ifdef EFAULT
case EFAULT: return DRFLAC_BAD_ADDRESS;
#endif
#ifdef ENOTBLK
case ENOTBLK: return DRFLAC_ERROR;
#endif
#ifdef EBUSY
case EBUSY: return DRFLAC_BUSY;
#endif
#ifdef EEXIST
case EEXIST: return DRFLAC_ALREADY_EXISTS;
#endif
#ifdef EXDEV
case EXDEV: return DRFLAC_ERROR;
#endif
#ifdef ENODEV
case ENODEV: return DRFLAC_DOES_NOT_EXIST;
#endif
#ifdef ENOTDIR
case ENOTDIR: return DRFLAC_NOT_DIRECTORY;
#endif
#ifdef EISDIR
case EISDIR: return DRFLAC_IS_DIRECTORY;
#endif
#ifdef EINVAL
case EINVAL: return DRFLAC_INVALID_ARGS;
#endif
#ifdef ENFILE
case ENFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
#endif
#ifdef EMFILE
case EMFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
#endif
#ifdef ENOTTY
case ENOTTY: return DRFLAC_INVALID_OPERATION;
#endif
#ifdef ETXTBSY
case ETXTBSY: return DRFLAC_BUSY;
#endif
#ifdef EFBIG
case EFBIG: return DRFLAC_TOO_BIG;
#endif
#ifdef ENOSPC
case ENOSPC: return DRFLAC_NO_SPACE;
#endif
#ifdef ESPIPE
case ESPIPE: return DRFLAC_BAD_SEEK;
#endif
#ifdef EROFS
case EROFS: return DRFLAC_ACCESS_DENIED;
#endif
#ifdef EMLINK
case EMLINK: return DRFLAC_TOO_MANY_LINKS;
#endif
#ifdef EPIPE
case EPIPE: return DRFLAC_BAD_PIPE;
#endif
#ifdef EDOM
case EDOM: return DRFLAC_OUT_OF_RANGE;
#endif
#ifdef ERANGE
case ERANGE: return DRFLAC_OUT_OF_RANGE;
#endif
#ifdef EDEADLK
case EDEADLK: return DRFLAC_DEADLOCK;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG: return DRFLAC_PATH_TOO_LONG;
#endif
#ifdef ENOLCK
case ENOLCK: return DRFLAC_ERROR;
#endif
#ifdef ENOSYS
case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
#endif
#ifdef ELOOP
case ELOOP: return DRFLAC_TOO_MANY_LINKS;
#endif
#ifdef ENOMSG
case ENOMSG: return DRFLAC_NO_MESSAGE;
#endif
#ifdef EIDRM
case EIDRM: return DRFLAC_ERROR;
#endif
#ifdef ECHRNG
case ECHRNG: return DRFLAC_ERROR;
#endif
#ifdef EL2NSYNC
case EL2NSYNC: return DRFLAC_ERROR;
#endif
#ifdef EL3HLT
case EL3HLT: return DRFLAC_ERROR;
#endif
#ifdef EL3RST
case EL3RST: return DRFLAC_ERROR;
#endif
#ifdef ELNRNG
case ELNRNG: return DRFLAC_OUT_OF_RANGE;
#endif
#ifdef EUNATCH
case EUNATCH: return DRFLAC_ERROR;
#endif
#ifdef ENOCSI
case ENOCSI: return DRFLAC_ERROR;
#endif
#ifdef EL2HLT
case EL2HLT: return DRFLAC_ERROR;
#endif
#ifdef EBADE
case EBADE: return DRFLAC_ERROR;
#endif
#ifdef EBADR
case EBADR: return DRFLAC_ERROR;
#endif
#ifdef EXFULL
case EXFULL: return DRFLAC_ERROR;
#endif
#ifdef ENOANO
case ENOANO: return DRFLAC_ERROR;
#endif
#ifdef EBADRQC
case EBADRQC: return DRFLAC_ERROR;
#endif
#ifdef EBADSLT
case EBADSLT: return DRFLAC_ERROR;
#endif
#ifdef EBFONT
case EBFONT: return DRFLAC_INVALID_FILE;
#endif
#ifdef ENOSTR
case ENOSTR: return DRFLAC_ERROR;
#endif
#ifdef ENODATA
case ENODATA: return DRFLAC_NO_DATA_AVAILABLE;
#endif
#ifdef ETIME
case ETIME: return DRFLAC_TIMEOUT;
#endif
#ifdef ENOSR
case ENOSR: return DRFLAC_NO_DATA_AVAILABLE;
#endif
#ifdef ENONET
case ENONET: return DRFLAC_NO_NETWORK;
#endif
#ifdef ENOPKG
case ENOPKG: return DRFLAC_ERROR;
#endif
#ifdef EREMOTE
case EREMOTE: return DRFLAC_ERROR;
#endif
#ifdef ENOLINK
case ENOLINK: return DRFLAC_ERROR;
#endif
#ifdef EADV
case EADV: return DRFLAC_ERROR;
#endif
#ifdef ESRMNT
case ESRMNT: return DRFLAC_ERROR;
#endif
#ifdef ECOMM
case ECOMM: return DRFLAC_ERROR;
#endif
#ifdef EPROTO
case EPROTO: return DRFLAC_ERROR;
#endif
#ifdef EMULTIHOP
case EMULTIHOP: return DRFLAC_ERROR;
#endif
#ifdef EDOTDOT
case EDOTDOT: return DRFLAC_ERROR;
#endif
#ifdef EBADMSG
case EBADMSG: return DRFLAC_BAD_MESSAGE;
#endif
#ifdef EOVERFLOW
case EOVERFLOW: return DRFLAC_TOO_BIG;
#endif
#ifdef ENOTUNIQ
case ENOTUNIQ: return DRFLAC_NOT_UNIQUE;
#endif
#ifdef EBADFD
case EBADFD: return DRFLAC_ERROR;
#endif
#ifdef EREMCHG
case EREMCHG: return DRFLAC_ERROR;
#endif
#ifdef ELIBACC
case ELIBACC: return DRFLAC_ACCESS_DENIED;
#endif
#ifdef ELIBBAD
case ELIBBAD: return DRFLAC_INVALID_FILE;
#endif
#ifdef ELIBSCN
case ELIBSCN: return DRFLAC_INVALID_FILE;
#endif
#ifdef ELIBMAX
case ELIBMAX: return DRFLAC_ERROR;
#endif
#ifdef ELIBEXEC
case ELIBEXEC: return DRFLAC_ERROR;
#endif
#ifdef EILSEQ
case EILSEQ: return DRFLAC_INVALID_DATA;
#endif
#ifdef ERESTART
case ERESTART: return DRFLAC_ERROR;
#endif
#ifdef ESTRPIPE
case ESTRPIPE: return DRFLAC_ERROR;
#endif
#ifdef EUSERS
case EUSERS: return DRFLAC_ERROR;
#endif
#ifdef ENOTSOCK
case ENOTSOCK: return DRFLAC_NOT_SOCKET;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ: return DRFLAC_NO_ADDRESS;
#endif
#ifdef EMSGSIZE
case EMSGSIZE: return DRFLAC_TOO_BIG;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE: return DRFLAC_BAD_PROTOCOL;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT: return DRFLAC_PROTOCOL_UNAVAILABLE;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT: return DRFLAC_PROTOCOL_NOT_SUPPORTED;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT: return DRFLAC_SOCKET_NOT_SUPPORTED;
#endif
#ifdef EOPNOTSUPP
case EOPNOTSUPP: return DRFLAC_INVALID_OPERATION;
#endif
#ifdef EPFNOSUPPORT
case EPFNOSUPPORT: return DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT: return DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EADDRINUSE
case EADDRINUSE: return DRFLAC_ALREADY_IN_USE;
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: return DRFLAC_ERROR;
#endif
#ifdef ENETDOWN
case ENETDOWN: return DRFLAC_NO_NETWORK;
#endif
#ifdef ENETUNREACH
case ENETUNREACH: return DRFLAC_NO_NETWORK;
#endif
#ifdef ENETRESET
case ENETRESET: return DRFLAC_NO_NETWORK;
#endif
#ifdef ECONNABORTED
case ECONNABORTED: return DRFLAC_NO_NETWORK;
#endif
#ifdef ECONNRESET
case ECONNRESET: return DRFLAC_CONNECTION_RESET;
#endif
#ifdef ENOBUFS
case ENOBUFS: return DRFLAC_NO_SPACE;
#endif
#ifdef EISCONN
case EISCONN: return DRFLAC_ALREADY_CONNECTED;
#endif
#ifdef ENOTCONN
case ENOTCONN: return DRFLAC_NOT_CONNECTED;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: return DRFLAC_ERROR;
#endif
#ifdef ETOOMANYREFS
case ETOOMANYREFS: return DRFLAC_ERROR;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: return DRFLAC_TIMEOUT;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: return DRFLAC_CONNECTION_REFUSED;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: return DRFLAC_NO_HOST;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: return DRFLAC_NO_HOST;
#endif
#ifdef EALREADY
case EALREADY: return DRFLAC_IN_PROGRESS;
#endif
#ifdef EINPROGRESS
case EINPROGRESS: return DRFLAC_IN_PROGRESS;
#endif
#ifdef ESTALE
case ESTALE: return DRFLAC_INVALID_FILE;
#endif
#ifdef EUCLEAN
case EUCLEAN: return DRFLAC_ERROR;
#endif
#ifdef ENOTNAM
case ENOTNAM: return DRFLAC_ERROR;
#endif
#ifdef ENAVAIL
case ENAVAIL: return DRFLAC_ERROR;
#endif
#ifdef EISNAM
case EISNAM: return DRFLAC_ERROR;
#endif
#ifdef EREMOTEIO
case EREMOTEIO: return DRFLAC_IO_ERROR;
#endif
#ifdef EDQUOT
case EDQUOT: return DRFLAC_NO_SPACE;
#endif
#ifdef ENOMEDIUM
case ENOMEDIUM: return DRFLAC_DOES_NOT_EXIST;
#endif
#ifdef EMEDIUMTYPE
case EMEDIUMTYPE: return DRFLAC_ERROR;
#endif
#ifdef ECANCELED
case ECANCELED: return DRFLAC_CANCELLED;
#endif
#ifdef ENOKEY
case ENOKEY: return DRFLAC_ERROR;
#endif
#ifdef EKEYEXPIRED
case EKEYEXPIRED: return DRFLAC_ERROR;
#endif
#ifdef EKEYREVOKED
case EKEYREVOKED: return DRFLAC_ERROR;
#endif
#ifdef EKEYREJECTED
case EKEYREJECTED: return DRFLAC_ERROR;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD: return DRFLAC_ERROR;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE: return DRFLAC_ERROR;
#endif
#ifdef ERFKILL
case ERFKILL: return DRFLAC_ERROR;
#endif
#ifdef EHWPOISON
case EHWPOISON: return DRFLAC_ERROR;
#endif
default: return DRFLAC_ERROR;
}
}
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err;
#endif
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRFLAC_INVALID_ARGS;
}
#if defined(_MSC_VER) && _MSC_VER >= 1400
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drflac_result_from_errno(err);
}
#else
#if defined(_WIN32) || defined(__APPLE__)
*ppFile = fopen(pFilePath, pOpenMode);
#else
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
*ppFile = fopen64(pFilePath, pOpenMode);
#else
*ppFile = fopen(pFilePath, pOpenMode);
#endif
if (*ppFile == NULL) {
drflac_result result = drflac_result_from_errno(errno);
if (result == DRFLAC_SUCCESS) {
result = DRFLAC_ERROR;
}
return result;
}
#endif
return DRFLAC_SUCCESS;
}
#if defined(_WIN32)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define DRFLAC_HAS_WFOPEN
#endif
#endif
static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drflac_allocation_callbacks* pAllocationCallbacks)
{
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRFLAC_INVALID_ARGS;
}
#if defined(DRFLAC_HAS_WFOPEN)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drflac_result_from_errno(err);
}
#else
*ppFile = _wfopen(pFilePath, pOpenMode);
if (*ppFile == NULL) {
return drflac_result_from_errno(errno);
}
#endif
(void)pAllocationCallbacks;
}
#else
{
mbstate_t mbs;
size_t lenMB;
const wchar_t* pFilePathTemp = pFilePath;
char* pFilePathMB = NULL;
char pOpenModeMB[32] = {0};
DRFLAC_ZERO_OBJECT(&mbs);
lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
if (lenMB == (size_t)-1) {
return drflac_result_from_errno(errno);
}
pFilePathMB = (char*)drflac__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
if (pFilePathMB == NULL) {
return DRFLAC_OUT_OF_MEMORY;
}
pFilePathTemp = pFilePath;
DRFLAC_ZERO_OBJECT(&mbs);
wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
{
size_t i = 0;
for (;;) {
if (pOpenMode[i] == 0) {
pOpenModeMB[i] = '\0';
break;
}
pOpenModeMB[i] = (char)pOpenMode[i];
i += 1;
}
}
*ppFile = fopen(pFilePathMB, pOpenModeMB);
drflac__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
}
if (*ppFile == NULL) {
return DRFLAC_ERROR;
}
#endif
return DRFLAC_SUCCESS;
}
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
static size_t ma_dr_flac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
DRFLAC_ASSERT(offset >= 0);
return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
MA_DR_FLAC_ASSERT(offset >= 0);
return fseek((FILE*)pUserData, offset, (origin == ma_dr_flac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_FLAC_NO_WCHAR
MA_API ma_dr_flac* ma_dr_flac_open_file_w(const wchar_t* pFileName, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
#endif
MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata(const char* pFileName, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_FLAC_NO_WCHAR
MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata_w(const wchar_t* pFileName, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
DRFLAC_ASSERT(memoryStream != NULL);
DRFLAC_ASSERT(offset >= 0);
if (offset > (drflac_int64)memoryStream->dataSize) {
return DRFLAC_FALSE;
ma_dr_flac__memory_stream* memoryStream = (ma_dr_flac__memory_stream*)pUserData;
MA_DR_FLAC_ASSERT(memoryStream != NULL);
MA_DR_FLAC_ASSERT(offset >= 0);
if (offset > (ma_int64)memoryStream->dataSize) {
return MA_FALSE;
DRFLAC_API drflac* drflac_open_memory(const void* pData, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_dr_flac* ma_dr_flac_open_memory(const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API drflac* drflac_open_memory_with_metadata(const void* pData, size_t dataSize, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_dr_flac* ma_dr_flac_open_memory_with_metadata(const void* pData, size_t dataSize, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_memory, ma_dr_flac__on_seek_memory, onMeta, ma_dr_flac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
return ma_dr_flac_open_with_metadata_private(onRead, onSeek, NULL, ma_dr_flac_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)
MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
return ma_dr_flac_open_with_metadata_private(onRead, onSeek, 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)
MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onMeta, ma_dr_flac_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)
MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
#ifndef DR_FLAC_NO_OGG
if (pFlac->container == drflac_container_ogg) {
drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
if (oggbs->onRead == drflac__on_read_stdio) {
#ifndef MA_DR_FLAC_NO_OGG
if (pFlac->container == ma_dr_flac_container_ogg) {
ma_dr_flac_oggbs* oggbs = (ma_dr_flac_oggbs*)pFlac->_oggbs;
MA_DR_FLAC_ASSERT(pFlac->bs.onRead == ma_dr_flac__on_read_ogg);
if (oggbs->onRead == ma_dr_flac__on_read_stdio) {
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_left_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 left = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 side = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_left_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 right0 = left0 - side0;
drflac_uint32 right1 = left1 - side1;
drflac_uint32 right2 = left2 - side2;
drflac_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (drflac_int32)left0;
pOutputSamples[i*8+1] = (drflac_int32)right0;
pOutputSamples[i*8+2] = (drflac_int32)left1;
pOutputSamples[i*8+3] = (drflac_int32)right1;
pOutputSamples[i*8+4] = (drflac_int32)left2;
pOutputSamples[i*8+5] = (drflac_int32)right2;
pOutputSamples[i*8+6] = (drflac_int32)left3;
pOutputSamples[i*8+7] = (drflac_int32)right3;
ma_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 right0 = left0 - side0;
ma_uint32 right1 = left1 - side1;
ma_uint32 right2 = left2 - side2;
ma_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (ma_int32)left0;
pOutputSamples[i*8+1] = (ma_int32)right0;
pOutputSamples[i*8+2] = (ma_int32)left1;
pOutputSamples[i*8+3] = (ma_int32)right1;
pOutputSamples[i*8+4] = (ma_int32)left2;
pOutputSamples[i*8+5] = (ma_int32)right2;
pOutputSamples[i*8+6] = (ma_int32)left3;
pOutputSamples[i*8+7] = (ma_int32)right3;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_left_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_left_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_left_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_right_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 side = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 right = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_right_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 left0 = right0 + side0;
drflac_uint32 left1 = right1 + side1;
drflac_uint32 left2 = right2 + side2;
drflac_uint32 left3 = right3 + side3;
pOutputSamples[i*8+0] = (drflac_int32)left0;
pOutputSamples[i*8+1] = (drflac_int32)right0;
pOutputSamples[i*8+2] = (drflac_int32)left1;
pOutputSamples[i*8+3] = (drflac_int32)right1;
pOutputSamples[i*8+4] = (drflac_int32)left2;
pOutputSamples[i*8+5] = (drflac_int32)right2;
pOutputSamples[i*8+6] = (drflac_int32)left3;
pOutputSamples[i*8+7] = (drflac_int32)right3;
ma_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 left0 = right0 + side0;
ma_uint32 left1 = right1 + side1;
ma_uint32 left2 = right2 + side2;
ma_uint32 left3 = right3 + side3;
pOutputSamples[i*8+0] = (ma_int32)left0;
pOutputSamples[i*8+1] = (ma_int32)right0;
pOutputSamples[i*8+2] = (ma_int32)left1;
pOutputSamples[i*8+3] = (ma_int32)right1;
pOutputSamples[i*8+4] = (ma_int32)left2;
pOutputSamples[i*8+5] = (ma_int32)right2;
pOutputSamples[i*8+6] = (ma_int32)left3;
pOutputSamples[i*8+7] = (ma_int32)right3;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_right_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_right_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left;
pOutputSamples[i*2+1] = (drflac_int32)right;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left;
pOutputSamples[i*2+1] = (ma_int32)right;
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_right_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_mid_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
for (ma_uint64 i = 0; i < frameCount; ++i) {
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+0] = (ma_int32)((ma_uint32)((ma_int32)(mid + side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+1] = (ma_int32)((ma_uint32)((ma_int32)(mid - side) >> 1) << unusedBitsPerSample);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_mid_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_int32 shift = unusedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_int32 shift = unusedBitsPerSample;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*8+0] = (drflac_int32)temp0L;
pOutputSamples[i*8+1] = (drflac_int32)temp0R;
pOutputSamples[i*8+2] = (drflac_int32)temp1L;
pOutputSamples[i*8+3] = (drflac_int32)temp1R;
pOutputSamples[i*8+4] = (drflac_int32)temp2L;
pOutputSamples[i*8+5] = (drflac_int32)temp2R;
pOutputSamples[i*8+6] = (drflac_int32)temp3L;
pOutputSamples[i*8+7] = (drflac_int32)temp3R;
pOutputSamples[i*8+0] = (ma_int32)temp0L;
pOutputSamples[i*8+1] = (ma_int32)temp0R;
pOutputSamples[i*8+2] = (ma_int32)temp1L;
pOutputSamples[i*8+3] = (ma_int32)temp1R;
pOutputSamples[i*8+4] = (ma_int32)temp2L;
pOutputSamples[i*8+5] = (ma_int32)temp2R;
pOutputSamples[i*8+6] = (ma_int32)temp3L;
pOutputSamples[i*8+7] = (ma_int32)temp3R;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
pOutputSamples[i*8+0] = (drflac_int32)temp0L;
pOutputSamples[i*8+1] = (drflac_int32)temp0R;
pOutputSamples[i*8+2] = (drflac_int32)temp1L;
pOutputSamples[i*8+3] = (drflac_int32)temp1R;
pOutputSamples[i*8+4] = (drflac_int32)temp2L;
pOutputSamples[i*8+5] = (drflac_int32)temp2R;
pOutputSamples[i*8+6] = (drflac_int32)temp3L;
pOutputSamples[i*8+7] = (drflac_int32)temp3R;
temp0L = (ma_uint32)((ma_int32)(mid0 + side0) >> 1);
temp1L = (ma_uint32)((ma_int32)(mid1 + side1) >> 1);
temp2L = (ma_uint32)((ma_int32)(mid2 + side2) >> 1);
temp3L = (ma_uint32)((ma_int32)(mid3 + side3) >> 1);
temp0R = (ma_uint32)((ma_int32)(mid0 - side0) >> 1);
temp1R = (ma_uint32)((ma_int32)(mid1 - side1) >> 1);
temp2R = (ma_uint32)((ma_int32)(mid2 - side2) >> 1);
temp3R = (ma_uint32)((ma_int32)(mid3 - side3) >> 1);
pOutputSamples[i*8+0] = (ma_int32)temp0L;
pOutputSamples[i*8+1] = (ma_int32)temp0R;
pOutputSamples[i*8+2] = (ma_int32)temp1L;
pOutputSamples[i*8+3] = (ma_int32)temp1R;
pOutputSamples[i*8+4] = (ma_int32)temp2L;
pOutputSamples[i*8+5] = (ma_int32)temp2R;
pOutputSamples[i*8+6] = (ma_int32)temp3L;
pOutputSamples[i*8+7] = (ma_int32)temp3R;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+0] = (ma_int32)((ma_uint32)((ma_int32)(mid + side) >> 1) << unusedBitsPerSample);
pOutputSamples[i*2+1] = (ma_int32)((ma_uint32)((ma_int32)(mid - side) >> 1) << unusedBitsPerSample);
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_mid_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_int32 shift = unusedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_int32 shift = unusedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
pOutputSamples[i*2+0] = (ma_int32)((mid + side) << shift);
pOutputSamples[i*2+1] = (ma_int32)((mid - side) << shift);
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_mid_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_int32 shift = unusedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_int32 shift = unusedBitsPerSample;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift);
pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift);
pOutputSamples[i*2+0] = (ma_int32)((mid + side) << shift);
pOutputSamples[i*2+1] = (ma_int32)((mid - side) << shift);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_mid_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
for (ma_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (ma_int32)((ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
pOutputSamples[i*2+1] = (ma_int32)((ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
pOutputSamples[i*8+0] = (drflac_int32)tempL0;
pOutputSamples[i*8+1] = (drflac_int32)tempR0;
pOutputSamples[i*8+2] = (drflac_int32)tempL1;
pOutputSamples[i*8+3] = (drflac_int32)tempR1;
pOutputSamples[i*8+4] = (drflac_int32)tempL2;
pOutputSamples[i*8+5] = (drflac_int32)tempR2;
pOutputSamples[i*8+6] = (drflac_int32)tempL3;
pOutputSamples[i*8+7] = (drflac_int32)tempR3;
ma_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
pOutputSamples[i*8+0] = (ma_int32)tempL0;
pOutputSamples[i*8+1] = (ma_int32)tempR0;
pOutputSamples[i*8+2] = (ma_int32)tempL1;
pOutputSamples[i*8+3] = (ma_int32)tempR1;
pOutputSamples[i*8+4] = (ma_int32)tempL2;
pOutputSamples[i*8+5] = (ma_int32)tempR2;
pOutputSamples[i*8+6] = (ma_int32)tempL3;
pOutputSamples[i*8+7] = (ma_int32)tempR3;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1);
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1);
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1);
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0);
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1);
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int32* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
drflac_uint64 frameCountThisIteration = framesToRead;
unsigned int channelCount = ma_dr_flac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
ma_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
ma_uint64 frameCountThisIteration = framesToRead;
const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
drflac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
pBufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
pBufferOut[(i*channelCount)+j] = (ma_int32)((ma_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_left_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 right = left - side;
ma_uint32 left = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 side = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 right = left - side;
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_left_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 right0 = left0 - side0;
drflac_uint32 right1 = left1 - side1;
drflac_uint32 right2 = left2 - side2;
drflac_uint32 right3 = left3 - side3;
ma_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 right0 = left0 - side0;
ma_uint32 right1 = left1 - side1;
ma_uint32 right2 = left2 - side2;
ma_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (drflac_int16)left0;
pOutputSamples[i*8+1] = (drflac_int16)right0;
pOutputSamples[i*8+2] = (drflac_int16)left1;
pOutputSamples[i*8+3] = (drflac_int16)right1;
pOutputSamples[i*8+4] = (drflac_int16)left2;
pOutputSamples[i*8+5] = (drflac_int16)right2;
pOutputSamples[i*8+6] = (drflac_int16)left3;
pOutputSamples[i*8+7] = (drflac_int16)right3;
pOutputSamples[i*8+0] = (ma_int16)left0;
pOutputSamples[i*8+1] = (ma_int16)right0;
pOutputSamples[i*8+2] = (ma_int16)left1;
pOutputSamples[i*8+3] = (ma_int16)right1;
pOutputSamples[i*8+4] = (ma_int16)left2;
pOutputSamples[i*8+5] = (ma_int16)right2;
pOutputSamples[i*8+6] = (ma_int16)left3;
pOutputSamples[i*8+7] = (ma_int16)right3;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_left_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_left_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_left_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_right_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 left = right + side;
ma_uint32 side = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 right = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 left = right + side;
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_right_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 left0 = right0 + side0;
drflac_uint32 left1 = right1 + side1;
drflac_uint32 left2 = right2 + side2;
drflac_uint32 left3 = right3 + side3;
ma_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 left0 = right0 + side0;
ma_uint32 left1 = right1 + side1;
ma_uint32 left2 = right2 + side2;
ma_uint32 left3 = right3 + side3;
pOutputSamples[i*8+0] = (drflac_int16)left0;
pOutputSamples[i*8+1] = (drflac_int16)right0;
pOutputSamples[i*8+2] = (drflac_int16)left1;
pOutputSamples[i*8+3] = (drflac_int16)right1;
pOutputSamples[i*8+4] = (drflac_int16)left2;
pOutputSamples[i*8+5] = (drflac_int16)right2;
pOutputSamples[i*8+6] = (drflac_int16)left3;
pOutputSamples[i*8+7] = (drflac_int16)right3;
pOutputSamples[i*8+0] = (ma_int16)left0;
pOutputSamples[i*8+1] = (ma_int16)right0;
pOutputSamples[i*8+2] = (ma_int16)left1;
pOutputSamples[i*8+3] = (ma_int16)right1;
pOutputSamples[i*8+4] = (ma_int16)left2;
pOutputSamples[i*8+5] = (ma_int16)right2;
pOutputSamples[i*8+6] = (ma_int16)left3;
pOutputSamples[i*8+7] = (ma_int16)right3;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_right_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_right_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_right_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_mid_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
for (ma_uint64 i = 0; i < frameCount; ++i) {
ma_uint32 mid = (ma_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = (ma_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((ma_uint32)((ma_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((ma_uint32)((ma_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_mid_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*8+0] = (drflac_int16)temp0L;
pOutputSamples[i*8+1] = (drflac_int16)temp0R;
pOutputSamples[i*8+2] = (drflac_int16)temp1L;
pOutputSamples[i*8+3] = (drflac_int16)temp1R;
pOutputSamples[i*8+4] = (drflac_int16)temp2L;
pOutputSamples[i*8+5] = (drflac_int16)temp2R;
pOutputSamples[i*8+6] = (drflac_int16)temp3L;
pOutputSamples[i*8+7] = (drflac_int16)temp3R;
pOutputSamples[i*8+0] = (ma_int16)temp0L;
pOutputSamples[i*8+1] = (ma_int16)temp0R;
pOutputSamples[i*8+2] = (ma_int16)temp1L;
pOutputSamples[i*8+3] = (ma_int16)temp1R;
pOutputSamples[i*8+4] = (ma_int16)temp2L;
pOutputSamples[i*8+5] = (ma_int16)temp2R;
pOutputSamples[i*8+6] = (ma_int16)temp3L;
pOutputSamples[i*8+7] = (ma_int16)temp3R;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
temp0L = ((drflac_int32)(mid0 + side0) >> 1);
temp1L = ((drflac_int32)(mid1 + side1) >> 1);
temp2L = ((drflac_int32)(mid2 + side2) >> 1);
temp3L = ((drflac_int32)(mid3 + side3) >> 1);
temp0R = ((drflac_int32)(mid0 - side0) >> 1);
temp1R = ((drflac_int32)(mid1 - side1) >> 1);
temp2R = ((drflac_int32)(mid2 - side2) >> 1);
temp3R = ((drflac_int32)(mid3 - side3) >> 1);
temp0L = ((ma_int32)(mid0 + side0) >> 1);
temp1L = ((ma_int32)(mid1 + side1) >> 1);
temp2L = ((ma_int32)(mid2 + side2) >> 1);
temp3L = ((ma_int32)(mid3 + side3) >> 1);
temp0R = ((ma_int32)(mid0 - side0) >> 1);
temp1R = ((ma_int32)(mid1 - side1) >> 1);
temp2R = ((ma_int32)(mid2 - side2) >> 1);
temp3R = ((ma_int32)(mid3 - side3) >> 1);
pOutputSamples[i*8+0] = (drflac_int16)temp0L;
pOutputSamples[i*8+1] = (drflac_int16)temp0R;
pOutputSamples[i*8+2] = (drflac_int16)temp1L;
pOutputSamples[i*8+3] = (drflac_int16)temp1R;
pOutputSamples[i*8+4] = (drflac_int16)temp2L;
pOutputSamples[i*8+5] = (drflac_int16)temp2R;
pOutputSamples[i*8+6] = (drflac_int16)temp3L;
pOutputSamples[i*8+7] = (drflac_int16)temp3R;
pOutputSamples[i*8+0] = (ma_int16)temp0L;
pOutputSamples[i*8+1] = (ma_int16)temp0R;
pOutputSamples[i*8+2] = (ma_int16)temp1L;
pOutputSamples[i*8+3] = (ma_int16)temp1R;
pOutputSamples[i*8+4] = (ma_int16)temp2L;
pOutputSamples[i*8+5] = (ma_int16)temp2R;
pOutputSamples[i*8+6] = (ma_int16)temp3L;
pOutputSamples[i*8+7] = (ma_int16)temp3R;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((ma_uint32)((ma_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((ma_uint32)((ma_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_mid_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample;
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample;
MA_DR_FLAC_ASSERT(pFlac->bitsPerSample <= 24);
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((ma_int32)(mid + side) >> 1) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((ma_int32)(mid - side) >> 1) >> 16);
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((mid + side) << shift) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((mid - side) << shift) >> 16);
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_mid_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((drflac_int32)(mid + side) >> 1) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((drflac_int32)(mid - side) >> 1) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((ma_int32)(mid + side) >> 1) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((ma_int32)(mid - side) >> 1) >> 16);
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)(((mid + side) << shift) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)(((mid - side) << shift) >> 16);
pOutputSamples[i*2+0] = (ma_int16)(((mid + side) << shift) >> 16);
pOutputSamples[i*2+1] = (ma_int16)(((mid - side) << shift) >> 16);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_mid_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
for (ma_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (ma_int16)((ma_int32)((ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
pOutputSamples[i*2+1] = (ma_int16)((ma_int32)((ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
pOutputSamples[i*8+0] = (drflac_int16)tempL0;
pOutputSamples[i*8+1] = (drflac_int16)tempR0;
pOutputSamples[i*8+2] = (drflac_int16)tempL1;
pOutputSamples[i*8+3] = (drflac_int16)tempR1;
pOutputSamples[i*8+4] = (drflac_int16)tempL2;
pOutputSamples[i*8+5] = (drflac_int16)tempR2;
pOutputSamples[i*8+6] = (drflac_int16)tempL3;
pOutputSamples[i*8+7] = (drflac_int16)tempR3;
pOutputSamples[i*8+0] = (ma_int16)tempL0;
pOutputSamples[i*8+1] = (ma_int16)tempR0;
pOutputSamples[i*8+2] = (ma_int16)tempL1;
pOutputSamples[i*8+3] = (ma_int16)tempR1;
pOutputSamples[i*8+4] = (ma_int16)tempL2;
pOutputSamples[i*8+5] = (ma_int16)tempR2;
pOutputSamples[i*8+6] = (ma_int16)tempL3;
pOutputSamples[i*8+7] = (ma_int16)tempR3;
pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
pOutputSamples[i*2+0] = (ma_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (ma_int16)((pInputSamples1U32[i] << shift1) >> 16);
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
pOutputSamples[i*2+0] = (ma_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (ma_int16)((pInputSamples1U32[i] << shift1) >> 16);
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (drflac_int16)((pInputSamples1U32[i] << shift1) >> 16);
pOutputSamples[i*2+0] = (ma_int16)((pInputSamples0U32[i] << shift0) >> 16);
pOutputSamples[i*2+1] = (ma_int16)((pInputSamples1U32[i] << shift1) >> 16);
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, ma_int16* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
drflac_uint64 frameCountThisIteration = framesToRead;
unsigned int channelCount = ma_dr_flac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
ma_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
ma_uint64 frameCountThisIteration = framesToRead;
const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
drflac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s16__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s16__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s16__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_s16__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
pBufferOut[(i*channelCount)+j] = (drflac_int16)(sampleS32 >> 16);
ma_int32 sampleS32 = (ma_int32)((ma_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
pBufferOut[(i*channelCount)+j] = (ma_int16)(sampleS32 >> 16);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_left_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
ma_uint32 left = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 side = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (float)((ma_int32)left / 2147483648.0);
pOutputSamples[i*2+1] = (float)((ma_int32)right / 2147483648.0);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_left_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 right0 = left0 - side0;
drflac_uint32 right1 = left1 - side1;
drflac_uint32 right2 = left2 - side2;
drflac_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (drflac_int32)left0 * factor;
pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
pOutputSamples[i*8+2] = (drflac_int32)left1 * factor;
pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
pOutputSamples[i*8+4] = (drflac_int32)left2 * factor;
pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
pOutputSamples[i*8+6] = (drflac_int32)left3 * factor;
pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
ma_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 right0 = left0 - side0;
ma_uint32 right1 = left1 - side1;
ma_uint32 right2 = left2 - side2;
ma_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (ma_int32)left0 * factor;
pOutputSamples[i*8+1] = (ma_int32)right0 * factor;
pOutputSamples[i*8+2] = (ma_int32)left1 * factor;
pOutputSamples[i*8+3] = (ma_int32)right1 * factor;
pOutputSamples[i*8+4] = (ma_int32)left2 * factor;
pOutputSamples[i*8+5] = (ma_int32)right2 * factor;
pOutputSamples[i*8+6] = (ma_int32)left3 * factor;
pOutputSamples[i*8+7] = (ma_int32)right3 * factor;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left * factor;
pOutputSamples[i*2+1] = (drflac_int32)right * factor;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left * factor;
pOutputSamples[i*2+1] = (ma_int32)right * factor;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_left_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (ma_int32)right / 8388608.0f;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_left_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
drflac_uint32 left = pInputSamples0U32[i] << shift0;
drflac_uint32 side = pInputSamples1U32[i] << shift1;
drflac_uint32 right = left - side;
pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
ma_uint32 left = pInputSamples0U32[i] << shift0;
ma_uint32 side = pInputSamples1U32[i] << shift1;
ma_uint32 right = left - side;
pOutputSamples[i*2+0] = (ma_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (ma_int32)right / 8388608.0f;
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_left_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_left_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_right_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
ma_uint32 side = (ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
ma_uint32 right = (ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (float)((ma_int32)left / 2147483648.0);
pOutputSamples[i*2+1] = (float)((ma_int32)right / 2147483648.0);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_right_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 left0 = right0 + side0;
drflac_uint32 left1 = right1 + side1;
drflac_uint32 left2 = right2 + side2;
drflac_uint32 left3 = right3 + side3;
pOutputSamples[i*8+0] = (drflac_int32)left0 * factor;
pOutputSamples[i*8+1] = (drflac_int32)right0 * factor;
pOutputSamples[i*8+2] = (drflac_int32)left1 * factor;
pOutputSamples[i*8+3] = (drflac_int32)right1 * factor;
pOutputSamples[i*8+4] = (drflac_int32)left2 * factor;
pOutputSamples[i*8+5] = (drflac_int32)right2 * factor;
pOutputSamples[i*8+6] = (drflac_int32)left3 * factor;
pOutputSamples[i*8+7] = (drflac_int32)right3 * factor;
ma_uint32 side0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 side1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 side2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 side3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 right0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 right1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 right2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 right3 = pInputSamples1U32[i*4+3] << shift1;
ma_uint32 left0 = right0 + side0;
ma_uint32 left1 = right1 + side1;
ma_uint32 left2 = right2 + side2;
ma_uint32 left3 = right3 + side3;
pOutputSamples[i*8+0] = (ma_int32)left0 * factor;
pOutputSamples[i*8+1] = (ma_int32)right0 * factor;
pOutputSamples[i*8+2] = (ma_int32)left1 * factor;
pOutputSamples[i*8+3] = (ma_int32)right1 * factor;
pOutputSamples[i*8+4] = (ma_int32)left2 * factor;
pOutputSamples[i*8+5] = (ma_int32)right2 * factor;
pOutputSamples[i*8+6] = (ma_int32)left3 * factor;
pOutputSamples[i*8+7] = (ma_int32)right3 * factor;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left * factor;
pOutputSamples[i*2+1] = (drflac_int32)right * factor;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left * factor;
pOutputSamples[i*2+1] = (ma_int32)right * factor;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_right_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (ma_int32)right / 8388608.0f;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_right_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
drflac_uint32 side = pInputSamples0U32[i] << shift0;
drflac_uint32 right = pInputSamples1U32[i] << shift1;
drflac_uint32 left = right + side;
pOutputSamples[i*2+0] = (drflac_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (drflac_int32)right / 8388608.0f;
ma_uint32 side = pInputSamples0U32[i] << shift0;
ma_uint32 right = pInputSamples1U32[i] << shift1;
ma_uint32 left = right + side;
pOutputSamples[i*2+0] = (ma_int32)left / 8388608.0f;
pOutputSamples[i*2+1] = (ma_int32)right / 8388608.0f;
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_right_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_right_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_mid_side__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
for (ma_uint64 i = 0; i < frameCount; ++i) {
ma_uint32 mid = (ma_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = (ma_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
pOutputSamples[i*2+0] = (float)((((ma_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
pOutputSamples[i*2+1] = (float)((((ma_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_mid_side__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
pOutputSamples[i*8+0] = (ma_int32)temp0L * factor;
pOutputSamples[i*8+1] = (ma_int32)temp0R * factor;
pOutputSamples[i*8+2] = (ma_int32)temp1L * factor;
pOutputSamples[i*8+3] = (ma_int32)temp1R * factor;
pOutputSamples[i*8+4] = (ma_int32)temp2L * factor;
pOutputSamples[i*8+5] = (ma_int32)temp2R * factor;
pOutputSamples[i*8+6] = (ma_int32)temp3L * factor;
pOutputSamples[i*8+7] = (ma_int32)temp3R * factor;
drflac_uint32 temp0L;
drflac_uint32 temp1L;
drflac_uint32 temp2L;
drflac_uint32 temp3L;
drflac_uint32 temp0R;
drflac_uint32 temp1R;
drflac_uint32 temp2R;
drflac_uint32 temp3R;
drflac_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 temp0L;
ma_uint32 temp1L;
ma_uint32 temp2L;
ma_uint32 temp3L;
ma_uint32 temp0R;
ma_uint32 temp1R;
ma_uint32 temp2R;
ma_uint32 temp3R;
ma_uint32 mid0 = pInputSamples0U32[i*4+0] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid1 = pInputSamples0U32[i*4+1] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid2 = pInputSamples0U32[i*4+2] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 mid3 = pInputSamples0U32[i*4+3] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side0 = pInputSamples1U32[i*4+0] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side1 = pInputSamples1U32[i*4+1] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side2 = pInputSamples1U32[i*4+2] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 side3 = pInputSamples1U32[i*4+3] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
temp0L = (drflac_uint32)((drflac_int32)(mid0 + side0) >> 1);
temp1L = (drflac_uint32)((drflac_int32)(mid1 + side1) >> 1);
temp2L = (drflac_uint32)((drflac_int32)(mid2 + side2) >> 1);
temp3L = (drflac_uint32)((drflac_int32)(mid3 + side3) >> 1);
temp0R = (drflac_uint32)((drflac_int32)(mid0 - side0) >> 1);
temp1R = (drflac_uint32)((drflac_int32)(mid1 - side1) >> 1);
temp2R = (drflac_uint32)((drflac_int32)(mid2 - side2) >> 1);
temp3R = (drflac_uint32)((drflac_int32)(mid3 - side3) >> 1);
pOutputSamples[i*8+0] = (drflac_int32)temp0L * factor;
pOutputSamples[i*8+1] = (drflac_int32)temp0R * factor;
pOutputSamples[i*8+2] = (drflac_int32)temp1L * factor;
pOutputSamples[i*8+3] = (drflac_int32)temp1R * factor;
pOutputSamples[i*8+4] = (drflac_int32)temp2L * factor;
pOutputSamples[i*8+5] = (drflac_int32)temp2R * factor;
pOutputSamples[i*8+6] = (drflac_int32)temp3L * factor;
pOutputSamples[i*8+7] = (drflac_int32)temp3R * factor;
temp0L = (ma_uint32)((ma_int32)(mid0 + side0) >> 1);
temp1L = (ma_uint32)((ma_int32)(mid1 + side1) >> 1);
temp2L = (ma_uint32)((ma_int32)(mid2 + side2) >> 1);
temp3L = (ma_uint32)((ma_int32)(mid3 + side3) >> 1);
temp0R = (ma_uint32)((ma_int32)(mid0 - side0) >> 1);
temp1R = (ma_uint32)((ma_int32)(mid1 - side1) >> 1);
temp2R = (ma_uint32)((ma_int32)(mid2 - side2) >> 1);
temp3R = (ma_uint32)((ma_int32)(mid3 - side3) >> 1);
pOutputSamples[i*8+0] = (ma_int32)temp0L * factor;
pOutputSamples[i*8+1] = (ma_int32)temp0R * factor;
pOutputSamples[i*8+2] = (ma_int32)temp1L * factor;
pOutputSamples[i*8+3] = (ma_int32)temp1R * factor;
pOutputSamples[i*8+4] = (ma_int32)temp2L * factor;
pOutputSamples[i*8+5] = (ma_int32)temp2R * factor;
pOutputSamples[i*8+6] = (ma_int32)temp3L * factor;
pOutputSamples[i*8+7] = (ma_int32)temp3R * factor;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
pOutputSamples[i*2+0] = (ma_int32)((ma_uint32)((ma_int32)(mid + side) >> 1) << unusedBitsPerSample) * factor;
pOutputSamples[i*2+1] = (ma_int32)((ma_uint32)((ma_int32)(mid - side) >> 1) << unusedBitsPerSample) * factor;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_mid_side__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample - 8;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
pOutputSamples[i*2+0] = ((ma_int32)(mid + side) >> 1) * factor;
pOutputSamples[i*2+1] = ((ma_int32)(mid - side) >> 1) * factor;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
pOutputSamples[i*2+0] = (ma_int32)((mid + side) << shift) * factor;
pOutputSamples[i*2+1] = (ma_int32)((mid - side) << shift) * factor;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_mid_side__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift = unusedBitsPerSample - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift = unusedBitsPerSample - 8;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = ((drflac_int32)(mid + side) >> 1) * factor;
pOutputSamples[i*2+1] = ((drflac_int32)(mid - side) >> 1) * factor;
pOutputSamples[i*2+0] = ((ma_int32)(mid + side) >> 1) * factor;
pOutputSamples[i*2+1] = ((ma_int32)(mid - side) >> 1) * factor;
drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
pOutputSamples[i*2+0] = (drflac_int32)((mid + side) << shift) * factor;
pOutputSamples[i*2+1] = (drflac_int32)((mid - side) << shift) * factor;
pOutputSamples[i*2+0] = (ma_int32)((mid + side) << shift) * factor;
pOutputSamples[i*2+1] = (ma_int32)((mid - side) << shift) * factor;
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_mid_side(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_mid_side__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__reference(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
for (drflac_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
for (ma_uint64 i = 0; i < frameCount; ++i) {
pOutputSamples[i*2+0] = (float)((ma_int32)((ma_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
pOutputSamples[i*2+1] = (float)((ma_int32)((ma_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__scalar(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
ma_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
drflac_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
pOutputSamples[i*8+0] = (drflac_int32)tempL0 * factor;
pOutputSamples[i*8+1] = (drflac_int32)tempR0 * factor;
pOutputSamples[i*8+2] = (drflac_int32)tempL1 * factor;
pOutputSamples[i*8+3] = (drflac_int32)tempR1 * factor;
pOutputSamples[i*8+4] = (drflac_int32)tempL2 * factor;
pOutputSamples[i*8+5] = (drflac_int32)tempR2 * factor;
pOutputSamples[i*8+6] = (drflac_int32)tempL3 * factor;
pOutputSamples[i*8+7] = (drflac_int32)tempR3 * factor;
ma_uint32 tempL0 = pInputSamples0U32[i*4+0] << shift0;
ma_uint32 tempL1 = pInputSamples0U32[i*4+1] << shift0;
ma_uint32 tempL2 = pInputSamples0U32[i*4+2] << shift0;
ma_uint32 tempL3 = pInputSamples0U32[i*4+3] << shift0;
ma_uint32 tempR0 = pInputSamples1U32[i*4+0] << shift1;
ma_uint32 tempR1 = pInputSamples1U32[i*4+1] << shift1;
ma_uint32 tempR2 = pInputSamples1U32[i*4+2] << shift1;
ma_uint32 tempR3 = pInputSamples1U32[i*4+3] << shift1;
pOutputSamples[i*8+0] = (ma_int32)tempL0 * factor;
pOutputSamples[i*8+1] = (ma_int32)tempR0 * factor;
pOutputSamples[i*8+2] = (ma_int32)tempL1 * factor;
pOutputSamples[i*8+3] = (ma_int32)tempR1 * factor;
pOutputSamples[i*8+4] = (ma_int32)tempL2 * factor;
pOutputSamples[i*8+5] = (ma_int32)tempR2 * factor;
pOutputSamples[i*8+6] = (ma_int32)tempL3 * factor;
pOutputSamples[i*8+7] = (ma_int32)tempR3 * factor;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1) * factor;
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__sse2(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1) * factor;
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__neon(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
#if defined(MA_DR_FLAC_SUPPORT_NEON)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__neon(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
drflac_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
ma_uint64 i;
ma_uint64 frameCount4 = frameCount >> 2;
const ma_uint32* pInputSamples0U32 = (const ma_uint32*)pInputSamples0;
const ma_uint32* pInputSamples1U32 = (const ma_uint32*)pInputSamples1;
ma_uint32 shift0 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample) - 8;
ma_uint32 shift1 = (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample) - 8;
pOutputSamples[i*2+0] = (drflac_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (drflac_int32)(pInputSamples1U32[i] << shift1) * factor;
pOutputSamples[i*2+0] = (ma_int32)(pInputSamples0U32[i] << shift0) * factor;
pOutputSamples[i*2+1] = (ma_int32)(pInputSamples1U32[i] << shift1) * factor;
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
static MA_INLINE void ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo(ma_dr_flac* pFlac, ma_uint64 frameCount, ma_uint32 unusedBitsPerSample, const ma_int32* pInputSamples0, const ma_int32* pInputSamples1, float* pOutputSamples)
#if defined(DRFLAC_SUPPORT_SSE2)
if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#if defined(MA_DR_FLAC_SUPPORT_SSE2)
if (ma_dr_flac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(DRFLAC_SUPPORT_NEON)
if (drflac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
drflac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
#elif defined(MA_DR_FLAC_SUPPORT_NEON)
if (ma_dr_flac__gIsNEONSupported && pFlac->bitsPerSample <= 24) {
ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__neon(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
drflac_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
drflac_uint64 frameCountThisIteration = framesToRead;
unsigned int channelCount = ma_dr_flac__get_channel_count_from_channel_assignment(pFlac->currentFLACFrame.header.channelAssignment);
ma_uint64 iFirstPCMFrame = pFlac->currentFLACFrame.header.blockSizeInPCMFrames - pFlac->currentFLACFrame.pcmFramesRemaining;
ma_uint64 frameCountThisIteration = framesToRead;
const drflac_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const drflac_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples0 = pFlac->currentFLACFrame.subframes[0].pSamplesS32 + iFirstPCMFrame;
const ma_int32* pDecodedSamples1 = pFlac->currentFLACFrame.subframes[1].pSamplesS32 + iFirstPCMFrame;
drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
ma_dr_flac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut);
drflac_int32 sampleS32 = (drflac_int32)((drflac_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
ma_int32 sampleS32 = (ma_int32)((ma_uint32)(pFlac->currentFLACFrame.subframes[j].pSamplesS32[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[j].wastedBitsPerSample));
drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentPCMFrame - pcmFrameIndex);
drflac_uint32 currentFLACFramePCMFrameCount = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
drflac_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
ma_uint32 offsetAbs = (ma_uint32)(pFlac->currentPCMFrame - pcmFrameIndex);
ma_uint32 currentFLACFramePCMFrameCount = pFlac->currentFLACFrame.header.blockSizeInPCMFrames;
ma_uint32 currentFLACFramePCMFramesConsumed = currentFLACFramePCMFrameCount - pFlac->currentFLACFrame.pcmFramesRemaining;
#if defined(SIZE_MAX)
#define DRFLAC_SIZE_MAX SIZE_MAX
#else
#if defined(DRFLAC_64BIT)
#define DRFLAC_SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
#else
#define DRFLAC_SIZE_MAX 0xFFFFFFFF
#endif
#endif
#define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \
static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut)\
#define MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \
static type* ma_dr_flac__full_read_and_close_ ## extension (ma_dr_flac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut)\
while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
while ((pcmFramesRead = (ma_uint64)ma_dr_flac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
pNewSampleData = (type*)ma_dr_flac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
MA_DR_FLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
MA_DR_FLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) { \
ma_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
if (dataSize > (ma_uint64)MA_SIZE_MAX) { \
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32)
DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16)
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)
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(s32, ma_int32)
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(s16, ma_int16)
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
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)
MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
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)
MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
#ifndef DR_FLAC_NO_STDIO
DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_FLAC_NO_STDIO
MA_API ma_int32* ma_dr_flac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_flac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_flac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int32* ma_dr_flac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_flac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_flac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRFLAC_API void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments)
MA_API void ma_dr_flac_init_vorbis_comment_iterator(ma_dr_flac_vorbis_comment_iterator* pIter, ma_uint32 commentCount, const void* pComments)
DRFLAC_API const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
MA_API const char* ma_dr_flac_next_vorbis_comment(ma_dr_flac_vorbis_comment_iterator* pIter, ma_uint32* pCommentLengthOut)
DRFLAC_API void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData)
MA_API void ma_dr_flac_init_cuesheet_track_iterator(ma_dr_flac_cuesheet_track_iterator* pIter, ma_uint32 trackCount, const void* pTrackData)
DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack)
MA_API ma_bool32 ma_dr_flac_next_cuesheet_track(ma_dr_flac_cuesheet_track_iterator* pIter, ma_dr_flac_cuesheet_track* pCuesheetTrack)
offsetHi = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
offsetHi = ma_dr_flac__be2host_32(*(const ma_uint32*)pRunningData); pRunningData += 4;
offsetLo = ma_dr_flac__be2host_32(*(const ma_uint32*)pRunningData); pRunningData += 4;
cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index);
cuesheetTrack.pIndexPoints = (const ma_dr_flac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(ma_dr_flac_cuesheet_track_index);
#if !defined(DR_MP3_IMPLEMENTATION) && !defined(DRMP3_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#if !defined(MA_DR_MP3_IMPLEMENTATION) && !defined(MA_DR_MP3_IMPLEMENTATION) /* For backwards compatibility. Will be removed in version 0.11 for cleanliness. */
#define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset)))
#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304
#ifndef DRMP3_MAX_FRAME_SYNC_MATCHES
#define DRMP3_MAX_FRAME_SYNC_MATCHES 10
#define MA_DR_MP3_OFFSET_PTR(p, offset) ((void*)((ma_uint8*)(p) + (offset)))
#define MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE 2304
#ifndef MA_DR_MP3_MAX_FRAME_SYNC_MATCHES
#define MA_DR_MP3_MAX_FRAME_SYNC_MATCHES 10
#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE
#define DRMP3_MAX_BITRESERVOIR_BYTES 511
#define DRMP3_SHORT_BLOCK_TYPE 2
#define DRMP3_STOP_BLOCK_TYPE 3
#define DRMP3_MODE_MONO 3
#define DRMP3_MODE_JOINT_STEREO 1
#define DRMP3_HDR_SIZE 4
#define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
#define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
#define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
#define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1))
#define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2)
#define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
#define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
#define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
#define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
#define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
#define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
#define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
#define DRMP3_BITS_DEQUANTIZER_OUT -1
#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210)
#define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3)
#define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
#define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a))
#if !defined(DR_MP3_NO_SIMD)
#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
#define DR_MP3_ONLY_SIMD
#define MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE
#define MA_DR_MP3_MAX_BITRESERVOIR_BYTES 511
#define MA_DR_MP3_SHORT_BLOCK_TYPE 2
#define MA_DR_MP3_STOP_BLOCK_TYPE 3
#define MA_DR_MP3_MODE_MONO 3
#define MA_DR_MP3_MODE_JOINT_STEREO 1
#define MA_DR_MP3_HDR_SIZE 4
#define MA_DR_MP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
#define MA_DR_MP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
#define MA_DR_MP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
#define MA_DR_MP3_HDR_IS_CRC(h) (!((h[1]) & 1))
#define MA_DR_MP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2)
#define MA_DR_MP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
#define MA_DR_MP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
#define MA_DR_MP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
#define MA_DR_MP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
#define MA_DR_MP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
#define MA_DR_MP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
#define MA_DR_MP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
#define MA_DR_MP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
#define MA_DR_MP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
#define MA_DR_MP3_HDR_GET_MY_SAMPLE_RATE(h) (MA_DR_MP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
#define MA_DR_MP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
#define MA_DR_MP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
#define MA_DR_MP3_BITS_DEQUANTIZER_OUT -1
#define MA_DR_MP3_MAX_SCF (255 + MA_DR_MP3_BITS_DEQUANTIZER_OUT*4 - 210)
#define MA_DR_MP3_MAX_SCFI ((MA_DR_MP3_MAX_SCF + 3) & ~3)
#define MA_DR_MP3_MIN(a, b) ((a) > (b) ? (b) : (a))
#define MA_DR_MP3_MAX(a, b) ((a) < (b) ? (b) : (a))
#if !defined(MA_DR_MP3_NO_SIMD)
#if !defined(MA_DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
#define MA_DR_MP3_ONLY_SIMD
#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__)))
#define DRMP3_HAVE_SSE 1
#define DRMP3_HAVE_SIMD 1
#define DRMP3_VSTORE _mm_storeu_ps
#define DRMP3_VLD _mm_loadu_ps
#define DRMP3_VSET _mm_set1_ps
#define DRMP3_VADD _mm_add_ps
#define DRMP3_VSUB _mm_sub_ps
#define DRMP3_VMUL _mm_mul_ps
#define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
#define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
#define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
#define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
typedef __m128 drmp3_f4;
#if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)
#define drmp3_cpuid __cpuid
#define MA_DR_MP3_HAVE_SSE 1
#define MA_DR_MP3_HAVE_SIMD 1
#define MA_DR_MP3_VSTORE _mm_storeu_ps
#define MA_DR_MP3_VLD _mm_loadu_ps
#define MA_DR_MP3_VSET _mm_set1_ps
#define MA_DR_MP3_VADD _mm_add_ps
#define MA_DR_MP3_VSUB _mm_sub_ps
#define MA_DR_MP3_VMUL _mm_mul_ps
#define MA_DR_MP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
#define MA_DR_MP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
#define MA_DR_MP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
#define MA_DR_MP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
typedef __m128 ma_dr_mp3_f4;
#if defined(_MSC_VER) || defined(MA_DR_MP3_ONLY_SIMD)
#define ma_dr_mp3_cpuid __cpuid
#define DRMP3_HAVE_SSE 0
#define DRMP3_HAVE_SIMD 1
#define DRMP3_VSTORE vst1q_f32
#define DRMP3_VLD vld1q_f32
#define DRMP3_VSET vmovq_n_f32
#define DRMP3_VADD vaddq_f32
#define DRMP3_VSUB vsubq_f32
#define DRMP3_VMUL vmulq_f32
#define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
#define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
#define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
#define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
typedef float32x4_t drmp3_f4;
static int drmp3_have_simd(void)
#define MA_DR_MP3_HAVE_SSE 0
#define MA_DR_MP3_HAVE_SIMD 1
#define MA_DR_MP3_VSTORE vst1q_f32
#define MA_DR_MP3_VLD vld1q_f32
#define MA_DR_MP3_VSET vmovq_n_f32
#define MA_DR_MP3_VADD vaddq_f32
#define MA_DR_MP3_VSUB vsubq_f32
#define MA_DR_MP3_VMUL vmulq_f32
#define MA_DR_MP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
#define MA_DR_MP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
#define MA_DR_MP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
#define MA_DR_MP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
typedef float32x4_t ma_dr_mp3_f4;
static int ma_dr_mp3_have_simd(void)
#define DRMP3_HAVE_SSE 0
#define DRMP3_HAVE_SIMD 0
#ifdef DR_MP3_ONLY_SIMD
#error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
#define MA_DR_MP3_HAVE_SSE 0
#define MA_DR_MP3_HAVE_SIMD 0
#ifdef MA_DR_MP3_ONLY_SIMD
#error MA_DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
#define DRMP3_HAVE_ARMV6 1
static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a)
#define MA_DR_MP3_HAVE_ARMV6 1
static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_arm(ma_int32 a)
#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p)))
#ifndef DRMP3_MALLOC
#define DRMP3_MALLOC(sz) malloc((sz))
#define MA_DR_MP3_ZERO_OBJECT(p) MA_DR_MP3_ZERO_MEMORY((p), sizeof(*(p)))
#ifndef MA_DR_MP3_MALLOC
#define MA_DR_MP3_MALLOC(sz) malloc((sz))
const drmp3_uint8 *sfbtab;
drmp3_uint16 part_23_length, big_values, scalefac_compress;
drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
drmp3_uint8 table_select[3], region_count[3], subblock_gain[3];
drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi;
} drmp3_L3_gr_info;
const ma_uint8 *sfbtab;
ma_uint16 part_23_length, big_values, scalefac_compress;
ma_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
ma_uint8 table_select[3], region_count[3], subblock_gain[3];
ma_uint8 preflag, scalefac_scale, count1_table, scfsi;
} ma_dr_mp3_L3_gr_info;
drmp3_bs bs;
drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES];
drmp3_L3_gr_info gr_info[4];
ma_dr_mp3_bs bs;
ma_uint8 maindata[MA_DR_MP3_MAX_BITRESERVOIR_BYTES + MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES];
ma_dr_mp3_L3_gr_info gr_info[4];
drmp3_uint8 ist_pos[2][39];
} drmp3dec_scratch;
static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes)
ma_uint8 ist_pos[2][39];
} ma_dr_mp3dec_scratch;
static void ma_dr_mp3_bs_init(ma_dr_mp3_bs *bs, const ma_uint8 *data, int bytes)
return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
return g_hz[MA_DR_MP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!MA_DR_MP3_HDR_TEST_MPEG1(h) >> (int)!MA_DR_MP3_HDR_TEST_NOT_MPEG25(h);
int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
if (DRMP3_HDR_IS_LAYER_1(h))
int frame_bytes = ma_dr_mp3_hdr_frame_samples(h)*ma_dr_mp3_hdr_bitrate_kbps(h)*125/ma_dr_mp3_hdr_sample_rate_hz(h);
if (MA_DR_MP3_HDR_IS_LAYER_1(h))
#ifndef DR_MP3_ONLY_MP3
static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
#ifndef MA_DR_MP3_ONLY_MP3
static const ma_dr_mp3_L12_subband_alloc *ma_dr_mp3_L12_subband_alloc_table(const ma_uint8 *hdr, ma_dr_mp3_L12_scale_info *sci)
const drmp3_L12_subband_alloc *alloc;
int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);
int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
if (DRMP3_HDR_IS_LAYER_1(hdr))
const ma_dr_mp3_L12_subband_alloc *alloc;
int mode = MA_DR_MP3_HDR_GET_STEREO_MODE(hdr);
int nbands, stereo_bands = (mode == MA_DR_MP3_MODE_MONO) ? 0 : (mode == MA_DR_MP3_MODE_JOINT_STEREO) ? (MA_DR_MP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
if (MA_DR_MP3_HDR_IS_LAYER_1(hdr))
static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr);
unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO);
static const ma_dr_mp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
int sample_rate_idx = MA_DR_MP3_HDR_GET_SAMPLE_RATE(hdr);
unsigned kbps = ma_dr_mp3_hdr_bitrate_kbps(hdr) >> (int)(mode != MA_DR_MP3_MODE_MONO);
#define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9)
#define MA_DR_MP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
MA_DR_MP3_DQ(3),MA_DR_MP3_DQ(7),MA_DR_MP3_DQ(15),MA_DR_MP3_DQ(31),MA_DR_MP3_DQ(63),MA_DR_MP3_DQ(127),MA_DR_MP3_DQ(255),MA_DR_MP3_DQ(511),MA_DR_MP3_DQ(1023),MA_DR_MP3_DQ(2047),MA_DR_MP3_DQ(4095),MA_DR_MP3_DQ(8191),MA_DR_MP3_DQ(16383),MA_DR_MP3_DQ(32767),MA_DR_MP3_DQ(65535),MA_DR_MP3_DQ(3),MA_DR_MP3_DQ(5),MA_DR_MP3_DQ(9)
DRMP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
MA_DR_MP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
if (DRMP3_HDR_TEST_MPEG1(hdr))
int gr_count = MA_DR_MP3_HDR_IS_MONO(hdr) ? 1 : 2;
int sr_idx = MA_DR_MP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
if (MA_DR_MP3_HDR_TEST_MPEG1(hdr))
gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8);
gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
gr->global_gain = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 8);
gr->scalefac_compress = (ma_uint16)ma_dr_mp3_bs_get_bits(bs, MA_DR_MP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
gr->subblock_gain[0] = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 3);
gr->subblock_gain[1] = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 3);
gr->subblock_gain[2] = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 3);
tables = drmp3_bs_get_bits(bs, 15);
gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4);
gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
tables = ma_dr_mp3_bs_get_bits(bs, 15);
gr->region_count[0] = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 4);
gr->region_count[1] = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 3);
gr->table_select[0] = (drmp3_uint8)(tables >> 10);
gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31);
gr->table_select[2] = (drmp3_uint8)((tables) & 31);
gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15);
gr->table_select[0] = (ma_uint8)(tables >> 10);
gr->table_select[1] = (ma_uint8)((tables >> 5) & 31);
gr->table_select[2] = (ma_uint8)((tables) & 31);
gr->preflag = (ma_uint8)(MA_DR_MP3_HDR_TEST_MPEG1(hdr) ? ma_dr_mp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
gr->scalefac_scale = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 1);
gr->count1_table = (ma_uint8)ma_dr_mp3_bs_get_bits(bs, 1);
gr->scfsi = (ma_uint8)((scfsi >> 12) & 15);
static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi)
static void ma_dr_mp3_L3_read_scalefactors(ma_uint8 *scf, ma_uint8 *ist_pos, const ma_uint8 *scf_size, const ma_uint8 *scf_count, ma_dr_mp3_bs *bitbuf, int scfsi)
static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch)
static void ma_dr_mp3_L3_decode_scalefactors(const ma_uint8 *hdr, ma_uint8 *ist_pos, ma_dr_mp3_bs *bs, const ma_dr_mp3_L3_gr_info *gr, float *scf, int ch)
const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
drmp3_uint8 scf_size[4], iscf[40];
const ma_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
ma_uint8 scf_size[4], iscf[40];
static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch;
static const ma_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
int k, modprod, sfc, ist = MA_DR_MP3_HDR_TEST_I_STEREO(hdr) && ch;
iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
iscf[gr->n_long_sfb + i + 0] = (ma_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
iscf[gr->n_long_sfb + i + 1] = (ma_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
iscf[gr->n_long_sfb + i + 2] = (ma_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp);
gain_exp = gr->global_gain + MA_DR_MP3_BITS_DEQUANTIZER_OUT*4 - 210 - (MA_DR_MP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
gain = ma_dr_mp3_L3_ldexp_q2(1 << (MA_DR_MP3_MAX_SCFI/4), MA_DR_MP3_MAX_SCFI - gain_exp);
static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
static void ma_dr_mp3_L3_huffman(float *dst, ma_dr_mp3_bs *bs, const ma_dr_mp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const ma_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n))
#define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
#define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
#define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
static const ma_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
static const ma_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
static const ma_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
static const ma_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
#define MA_DR_MP3_PEEK_BITS(n) (bs_cache >> (32 - (n)))
#define MA_DR_MP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
#define MA_DR_MP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (ma_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
#define MA_DR_MP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
const drmp3_uint8 *sfb = gr_info->sfbtab;
const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
const ma_uint8 *sfb = gr_info->sfbtab;
const ma_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
ma_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
lsb += DRMP3_PEEK_BITS(linbits);
DRMP3_FLUSH_BITS(linbits);
DRMP3_CHECK_BITS;
*dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1);
lsb += MA_DR_MP3_PEEK_BITS(linbits);
MA_DR_MP3_FLUSH_BITS(linbits);
MA_DR_MP3_CHECK_BITS;
*dst = one*ma_dr_mp3_L3_pow_43(lsb)*((ma_int32)bs_cache < 0 ? -1: 1);
const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
int leaf = codebook_count1[DRMP3_PEEK_BITS(4)];
const ma_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
int leaf = codebook_count1[MA_DR_MP3_PEEK_BITS(4)];
#define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) }
DRMP3_RELOAD_SCALEFACTOR;
DRMP3_DEQ_COUNT1(0);
DRMP3_DEQ_COUNT1(1);
DRMP3_RELOAD_SCALEFACTOR;
DRMP3_DEQ_COUNT1(2);
DRMP3_DEQ_COUNT1(3);
DRMP3_CHECK_BITS;
#define MA_DR_MP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
#define MA_DR_MP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((ma_int32)bs_cache < 0) ? -one : one; MA_DR_MP3_FLUSH_BITS(1) }
MA_DR_MP3_RELOAD_SCALEFACTOR;
MA_DR_MP3_DEQ_COUNT1(0);
MA_DR_MP3_DEQ_COUNT1(1);
MA_DR_MP3_RELOAD_SCALEFACTOR;
MA_DR_MP3_DEQ_COUNT1(2);
MA_DR_MP3_DEQ_COUNT1(3);
MA_DR_MP3_CHECK_BITS;
drmp3_f4 vl = DRMP3_VLD(left + i);
drmp3_f4 vr = DRMP3_VLD(right + i);
DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr));
DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr));
ma_dr_mp3_f4 vl = MA_DR_MP3_VLD(left + i);
ma_dr_mp3_f4 vr = MA_DR_MP3_VLD(right + i);
MA_DR_MP3_VSTORE(left + i, MA_DR_MP3_VADD(vl, vr));
MA_DR_MP3_VSTORE(right + i, MA_DR_MP3_VSUB(vl, vr));
static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh)
static void ma_dr_mp3_L3_stereo_process(float *left, const ma_uint8 *ist_pos, const ma_uint8 *sfb, const ma_uint8 *hdr, int max_band[3], int mpeg2_sh)
static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
static void ma_dr_mp3_L3_intensity_stereo(float *left, ma_uint8 *ist_pos, const ma_dr_mp3_L3_gr_info *gr, const ma_uint8 *hdr)
drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i);
drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i);
drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i);
drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i);
vd = DRMP3_VREV(vd);
DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1)));
vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0));
DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd));
ma_dr_mp3_f4 vu = MA_DR_MP3_VLD(grbuf + 18 + i);
ma_dr_mp3_f4 vd = MA_DR_MP3_VLD(grbuf + 14 - i);
ma_dr_mp3_f4 vc0 = MA_DR_MP3_VLD(g_aa[0] + i);
ma_dr_mp3_f4 vc1 = MA_DR_MP3_VLD(g_aa[1] + i);
vd = MA_DR_MP3_VREV(vd);
MA_DR_MP3_VSTORE(grbuf + 18 + i, MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vu, vc0), MA_DR_MP3_VMUL(vd, vc1)));
vd = MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vu, vc1), MA_DR_MP3_VMUL(vd, vc0));
MA_DR_MP3_VSTORE(grbuf + 14 - i, MA_DR_MP3_VREV(vd));
drmp3_f4 vovl = DRMP3_VLD(overlap + i);
drmp3_f4 vc = DRMP3_VLD(co + i);
drmp3_f4 vs = DRMP3_VLD(si + i);
drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i);
drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i);
drmp3_f4 vw0 = DRMP3_VLD(window + i);
drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i);
drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0));
DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1)));
DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1)));
vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0));
DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum));
ma_dr_mp3_f4 vovl = MA_DR_MP3_VLD(overlap + i);
ma_dr_mp3_f4 vc = MA_DR_MP3_VLD(co + i);
ma_dr_mp3_f4 vs = MA_DR_MP3_VLD(si + i);
ma_dr_mp3_f4 vr0 = MA_DR_MP3_VLD(g_twid9 + i);
ma_dr_mp3_f4 vr1 = MA_DR_MP3_VLD(g_twid9 + 9 + i);
ma_dr_mp3_f4 vw0 = MA_DR_MP3_VLD(window + i);
ma_dr_mp3_f4 vw1 = MA_DR_MP3_VLD(window + 9 + i);
ma_dr_mp3_f4 vsum = MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vc, vr1), MA_DR_MP3_VMUL(vs, vr0));
MA_DR_MP3_VSTORE(overlap + i, MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vc, vr0), MA_DR_MP3_VMUL(vs, vr1)));
MA_DR_MP3_VSTORE(grbuf + i, MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vovl, vw0), MA_DR_MP3_VMUL(vsum, vw1)));
vsum = MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vovl, vw1), MA_DR_MP3_VMUL(vsum, vw0));
MA_DR_MP3_VSTORE(grbuf + 14 - i, MA_DR_MP3_VREV(vsum));
DRMP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp));
DRMP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float));
drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
MA_DR_MP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp));
MA_DR_MP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float));
ma_dr_mp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
ma_dr_mp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
ma_dr_mp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
int bytes_have = MA_DR_MP3_MIN(h->reserv, main_data_begin);
MA_DR_MP3_COPY_MEMORY(s->maindata, h->reserv_buf + MA_DR_MP3_MAX(0, h->reserv - main_data_begin), MA_DR_MP3_MIN(h->reserv, main_data_begin));
MA_DR_MP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
ma_dr_mp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
ma_dr_mp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
ma_dr_mp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
} else if (DRMP3_HDR_IS_MS_STEREO(h->header))
ma_dr_mp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
} else if (MA_DR_MP3_HDR_IS_MS_STEREO(h->header))
drmp3_L3_antialias(s->grbuf[ch], aa_bands);
drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
drmp3_L3_change_sign(s->grbuf[ch]);
ma_dr_mp3_L3_antialias(s->grbuf[ch], aa_bands);
ma_dr_mp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
ma_dr_mp3_L3_change_sign(s->grbuf[ch]);
drmp3_f4 x0 = DRMP3_VLD(&y[i*18]);
drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]);
drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]);
drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]);
drmp3_f4 t0 = DRMP3_VADD(x0, x3);
drmp3_f4 t1 = DRMP3_VADD(x1, x2);
drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]);
drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]);
x[0] = DRMP3_VADD(t0, t1);
x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]);
x[16] = DRMP3_VADD(t3, t2);
x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]);
ma_dr_mp3_f4 x0 = MA_DR_MP3_VLD(&y[i*18]);
ma_dr_mp3_f4 x1 = MA_DR_MP3_VLD(&y[(15 - i)*18]);
ma_dr_mp3_f4 x2 = MA_DR_MP3_VLD(&y[(16 + i)*18]);
ma_dr_mp3_f4 x3 = MA_DR_MP3_VLD(&y[(31 - i)*18]);
ma_dr_mp3_f4 t0 = MA_DR_MP3_VADD(x0, x3);
ma_dr_mp3_f4 t1 = MA_DR_MP3_VADD(x1, x2);
ma_dr_mp3_f4 t2 = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(x1, x2), g_sec[3*i + 0]);
ma_dr_mp3_f4 t3 = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(x0, x3), g_sec[3*i + 1]);
x[0] = MA_DR_MP3_VADD(t0, t1);
x[8] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(t0, t1), g_sec[3*i + 2]);
x[16] = MA_DR_MP3_VADD(t3, t2);
x[24] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(t3, t2), g_sec[3*i + 2]);
drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7);
x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6);
x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5);
x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4);
x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3);
x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2);
x[0] = DRMP3_VADD(x0, x1);
x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f);
x5 = DRMP3_VADD(x5, x6);
x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f);
x7 = DRMP3_VADD(x7, xt);
x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f);
x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f));
x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6);
x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f);
x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f);
x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f);
x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f);
x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f);
x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f);
ma_dr_mp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
xt = MA_DR_MP3_VSUB(x0, x7); x0 = MA_DR_MP3_VADD(x0, x7);
x7 = MA_DR_MP3_VSUB(x1, x6); x1 = MA_DR_MP3_VADD(x1, x6);
x6 = MA_DR_MP3_VSUB(x2, x5); x2 = MA_DR_MP3_VADD(x2, x5);
x5 = MA_DR_MP3_VSUB(x3, x4); x3 = MA_DR_MP3_VADD(x3, x4);
x4 = MA_DR_MP3_VSUB(x0, x3); x0 = MA_DR_MP3_VADD(x0, x3);
x3 = MA_DR_MP3_VSUB(x1, x2); x1 = MA_DR_MP3_VADD(x1, x2);
x[0] = MA_DR_MP3_VADD(x0, x1);
x[4] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(x0, x1), 0.70710677f);
x5 = MA_DR_MP3_VADD(x5, x6);
x6 = MA_DR_MP3_VMUL_S(MA_DR_MP3_VADD(x6, x7), 0.70710677f);
x7 = MA_DR_MP3_VADD(x7, xt);
x3 = MA_DR_MP3_VMUL_S(MA_DR_MP3_VADD(x3, x4), 0.70710677f);
x5 = MA_DR_MP3_VSUB(x5, MA_DR_MP3_VMUL_S(x7, 0.198912367f));
x7 = MA_DR_MP3_VADD(x7, MA_DR_MP3_VMUL_S(x5, 0.382683432f));
x5 = MA_DR_MP3_VSUB(x5, MA_DR_MP3_VMUL_S(x7, 0.198912367f));
x0 = MA_DR_MP3_VSUB(xt, x6); xt = MA_DR_MP3_VADD(xt, x6);
x[1] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VADD(xt, x7), 0.50979561f);
x[2] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VADD(x4, x3), 0.54119611f);
x[3] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(x0, x5), 0.60134488f);
x[5] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VADD(x0, x5), 0.89997619f);
x[6] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(x4, x3), 1.30656302f);
x[7] = MA_DR_MP3_VMUL_S(MA_DR_MP3_VSUB(xt, x7), 2.56291556f);
drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
DRMP3_VSAVE2(0, t[0][i]);
DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s));
DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s));
ma_dr_mp3_f4 s = MA_DR_MP3_VADD(t[3][i], t[3][i + 1]);
MA_DR_MP3_VSAVE2(0, t[0][i]);
MA_DR_MP3_VSAVE2(1, MA_DR_MP3_VADD(t[2][i], s));
MA_DR_MP3_VSAVE2(2, MA_DR_MP3_VADD(t[1][i], t[1][i + 1]));
MA_DR_MP3_VSAVE2(3, MA_DR_MP3_VADD(t[2][1 + i], s));
DRMP3_VSAVE2(0, t[0][7]);
DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7]));
DRMP3_VSAVE2(2, t[1][7]);
DRMP3_VSAVE2(3, t[3][7]);
MA_DR_MP3_VSAVE2(0, t[0][7]);
MA_DR_MP3_VSAVE2(1, MA_DR_MP3_VADD(t[2][7], t[3][7]));
MA_DR_MP3_VSAVE2(2, t[1][7]);
MA_DR_MP3_VSAVE2(3, t[3][7]);
drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
DRMP3_VSAVE4(0, t[0][i]);
DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s));
DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s));
ma_dr_mp3_f4 s = MA_DR_MP3_VADD(t[3][i], t[3][i + 1]);
MA_DR_MP3_VSAVE4(0, t[0][i]);
MA_DR_MP3_VSAVE4(1, MA_DR_MP3_VADD(t[2][i], s));
MA_DR_MP3_VSAVE4(2, MA_DR_MP3_VADD(t[1][i], t[1][i + 1]));
MA_DR_MP3_VSAVE4(3, MA_DR_MP3_VADD(t[2][1 + i], s));
DRMP3_VSAVE4(0, t[0][7]);
DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7]));
DRMP3_VSAVE4(2, t[1][7]);
DRMP3_VSAVE4(3, t[3][7]);
MA_DR_MP3_VSAVE4(0, t[0][7]);
MA_DR_MP3_VSAVE4(1, MA_DR_MP3_VADD(t[2][7], t[3][7]));
MA_DR_MP3_VSAVE4(2, t[1][7]);
MA_DR_MP3_VSAVE4(3, t[3][7]);
if (sample >= 32766.5) return (drmp3_int16) 32767;
if (sample <= -32767.5) return (drmp3_int16)-32768;
s = (drmp3_int16)(sample + .5f);
if (sample >= 32766.5) return (ma_int16) 32767;
if (sample <= -32767.5) return (ma_int16)-32768;
s = (ma_int16)(sample + .5f);
drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
drmp3d_synth_pair(dstl, nch, lins + 4*15);
drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
#if DRMP3_HAVE_SIMD
if (drmp3_have_simd()) for (i = 14; i >= 0; i--)
ma_dr_mp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
ma_dr_mp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
ma_dr_mp3d_synth_pair(dstl, nch, lins + 4*15);
ma_dr_mp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
#if MA_DR_MP3_HAVE_SIMD
if (ma_dr_mp3_have_simd()) for (i = 14; i >= 0; i--)
#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
#define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); }
#define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); }
#define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); }
drmp3_f4 a, b;
#define MA_DR_MP3_VLOAD(k) ma_dr_mp3_f4 w0 = MA_DR_MP3_VSET(*w++); ma_dr_mp3_f4 w1 = MA_DR_MP3_VSET(*w++); ma_dr_mp3_f4 vz = MA_DR_MP3_VLD(&zlin[4*i - 64*k]); ma_dr_mp3_f4 vy = MA_DR_MP3_VLD(&zlin[4*i - 64*(15 - k)]);
#define MA_DR_MP3_V0(k) { MA_DR_MP3_VLOAD(k) b = MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vz, w1), MA_DR_MP3_VMUL(vy, w0)) ; a = MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vz, w0), MA_DR_MP3_VMUL(vy, w1)); }
#define MA_DR_MP3_V1(k) { MA_DR_MP3_VLOAD(k) b = MA_DR_MP3_VADD(b, MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vz, w1), MA_DR_MP3_VMUL(vy, w0))); a = MA_DR_MP3_VADD(a, MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vz, w0), MA_DR_MP3_VMUL(vy, w1))); }
#define MA_DR_MP3_V2(k) { MA_DR_MP3_VLOAD(k) b = MA_DR_MP3_VADD(b, MA_DR_MP3_VADD(MA_DR_MP3_VMUL(vz, w1), MA_DR_MP3_VMUL(vy, w0))); a = MA_DR_MP3_VADD(a, MA_DR_MP3_VSUB(MA_DR_MP3_VMUL(vy, w1), MA_DR_MP3_VMUL(vz, w0))); }
ma_dr_mp3_f4 a, b;
#ifndef DR_MP3_FLOAT_OUTPUT
#if DRMP3_HAVE_SSE
static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
#ifndef MA_DR_MP3_FLOAT_OUTPUT
#if MA_DR_MP3_HAVE_SSE
static const ma_dr_mp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
static const ma_dr_mp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
dstr[(15 - i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 1);
dstr[(17 + i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 5);
dstl[(15 - i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 0);
dstl[(17 + i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 4);
dstr[(47 - i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 3);
dstr[(49 + i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 7);
dstl[(47 - i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 2);
dstl[(49 + i)*nch] = (ma_int16)_mm_extract_epi16(pcm8, 6);
a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
a = MA_DR_MP3_VADD(a, MA_DR_MP3_VSET(0.5f));
b = MA_DR_MP3_VADD(b, MA_DR_MP3_VSET(0.5f));
pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, MA_DR_MP3_VSET(0)))));
pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, MA_DR_MP3_VSET(0)))));
#if DRMP3_HAVE_SSE
static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
#if MA_DR_MP3_HAVE_SSE
static const ma_dr_mp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
#define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
#define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
#define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
#define MA_DR_MP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
#define MA_DR_MP3_S0(k) { int j; MA_DR_MP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
#define MA_DR_MP3_S1(k) { int j; MA_DR_MP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
#define MA_DR_MP3_S2(k) { int j; MA_DR_MP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7)
dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]);
dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]);
dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]);
dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]);
dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]);
dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]);
dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]);
dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]);
MA_DR_MP3_S0(0) MA_DR_MP3_S2(1) MA_DR_MP3_S1(2) MA_DR_MP3_S2(3) MA_DR_MP3_S1(4) MA_DR_MP3_S2(5) MA_DR_MP3_S1(6) MA_DR_MP3_S2(7)
dstr[(15 - i)*nch] = ma_dr_mp3d_scale_pcm(a[1]);
dstr[(17 + i)*nch] = ma_dr_mp3d_scale_pcm(b[1]);
dstl[(15 - i)*nch] = ma_dr_mp3d_scale_pcm(a[0]);
dstl[(17 + i)*nch] = ma_dr_mp3d_scale_pcm(b[0]);
dstr[(47 - i)*nch] = ma_dr_mp3d_scale_pcm(a[3]);
dstr[(49 + i)*nch] = ma_dr_mp3d_scale_pcm(b[3]);
dstl[(47 - i)*nch] = ma_dr_mp3d_scale_pcm(a[2]);
dstl[(49 + i)*nch] = ma_dr_mp3d_scale_pcm(b[2]);
static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins)
static void ma_dr_mp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, ma_dr_mp3d_sample_t *pcm, float *lins)
i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
if (i + DRMP3_HDR_SIZE > mp3_bytes)
i += ma_dr_mp3_hdr_frame_bytes(hdr + i, frame_bytes) + ma_dr_mp3_hdr_padding(hdr + i);
if (i + MA_DR_MP3_HDR_SIZE > mp3_bytes)
int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
int frame_bytes = ma_dr_mp3_hdr_frame_bytes(mp3, *free_format_bytes);
int frame_and_padding = frame_bytes + ma_dr_mp3_hdr_padding(mp3);
for (k = MA_DR_MP3_HDR_SIZE; !frame_bytes && k < MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - MA_DR_MP3_HDR_SIZE; k++)
int fb = k - drmp3_hdr_padding(mp3);
int nextfb = fb + drmp3_hdr_padding(mp3 + k);
if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
int fb = k - ma_dr_mp3_hdr_padding(mp3);
int nextfb = fb + ma_dr_mp3_hdr_padding(mp3 + k);
if (i + k + nextfb + MA_DR_MP3_HDR_SIZE > mp3_bytes || !ma_dr_mp3_hdr_compare(mp3, mp3 + k + nextfb))
DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int mp3_bytes, void *pcm, ma_dr_mp3dec_frame_info *info)
const drmp3_uint8 *hdr;
drmp3_bs bs_frame[1];
drmp3dec_scratch scratch;
if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
const ma_uint8 *hdr;
ma_dr_mp3_bs bs_frame[1];
ma_dr_mp3dec_scratch scratch;
if (mp3_bytes > 4 && dec->header[0] == 0xff && ma_dr_mp3_hdr_compare(dec->header, mp3))
frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
frame_size = ma_dr_mp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + ma_dr_mp3_hdr_padding(mp3);
if (frame_size != mp3_bytes && (frame_size + MA_DR_MP3_HDR_SIZE > mp3_bytes || !ma_dr_mp3_hdr_compare(mp3, mp3 + frame_size)))
DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec));
i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
MA_DR_MP3_ZERO_MEMORY(dec, sizeof(ma_dr_mp3dec));
i = ma_dr_mp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
info->hz = drmp3_hdr_sample_rate_hz(hdr);
info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
if (DRMP3_HDR_IS_CRC(hdr))
info->channels = MA_DR_MP3_HDR_IS_MONO(hdr) ? 1 : 2;
info->hz = ma_dr_mp3_hdr_sample_rate_hz(hdr);
info->layer = 4 - MA_DR_MP3_HDR_GET_LAYER(hdr);
info->bitrate_kbps = ma_dr_mp3_hdr_bitrate_kbps(hdr);
ma_dr_mp3_bs_init(bs_frame, hdr + MA_DR_MP3_HDR_SIZE, frame_size - MA_DR_MP3_HDR_SIZE);
if (MA_DR_MP3_HDR_IS_CRC(hdr))
for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
for (igr = 0; igr < (MA_DR_MP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*576*info->channels))
DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
ma_dr_mp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]);
drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
ma_dr_mp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]);
MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*384*info->channels);
drmp3_f4 scale = DRMP3_VSET(32768.0f);
drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale);
drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale);
#if DRMP3_HAVE_SSE
drmp3_f4 s16max = DRMP3_VSET( 32767.0f);
drmp3_f4 s16min = DRMP3_VSET(-32768.0f);
ma_dr_mp3_f4 scale = MA_DR_MP3_VSET(32768.0f);
ma_dr_mp3_f4 a = MA_DR_MP3_VMUL(MA_DR_MP3_VLD(&in[i ]), scale);
ma_dr_mp3_f4 b = MA_DR_MP3_VMUL(MA_DR_MP3_VLD(&in[i+4]), scale);
#if MA_DR_MP3_HAVE_SSE
ma_dr_mp3_f4 s16max = MA_DR_MP3_VSET( 32767.0f);
ma_dr_mp3_f4 s16min = MA_DR_MP3_VSET(-32768.0f);
out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
out[i ] = (ma_int16)_mm_extract_epi16(pcm8, 0);
out[i+1] = (ma_int16)_mm_extract_epi16(pcm8, 1);
out[i+2] = (ma_int16)_mm_extract_epi16(pcm8, 2);
out[i+3] = (ma_int16)_mm_extract_epi16(pcm8, 3);
out[i+4] = (ma_int16)_mm_extract_epi16(pcm8, 4);
out[i+5] = (ma_int16)_mm_extract_epi16(pcm8, 5);
out[i+6] = (ma_int16)_mm_extract_epi16(pcm8, 6);
out[i+7] = (ma_int16)_mm_extract_epi16(pcm8, 7);
a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
a = MA_DR_MP3_VADD(a, MA_DR_MP3_VSET(0.5f));
b = MA_DR_MP3_VADD(b, MA_DR_MP3_VSET(0.5f));
pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, MA_DR_MP3_VSET(0)))));
pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, MA_DR_MP3_VSET(0)))));
#if defined(SIZE_MAX)
#define DRMP3_SIZE_MAX SIZE_MAX
#else
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
#define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF)
#else
#define DRMP3_SIZE_MAX 0xFFFFFFFF
#endif
#ifndef MA_DR_MP3_SEEK_LEADING_MP3_FRAMES
#define MA_DR_MP3_SEEK_LEADING_MP3_FRAMES 2
#define DRMP3_MIN_DATA_CHUNK_SIZE 16384
#ifndef DRMP3_DATA_CHUNK_SIZE
#define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4
#define MA_DR_MP3_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#define MA_DR_MP3_CLAMP(x, lo, hi) (MA_DR_MP3_MAX(lo, MA_DR_MP3_MIN(x, hi)))
#ifndef MA_DR_MP3_PI_D
#define MA_DR_MP3_PI_D 3.14159265358979323846264
#define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi)))
#ifndef DRMP3_PI_D
#define DRMP3_PI_D 3.14159265358979323846264
#endif
#define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2
static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a)
#define MA_DR_MP3_DEFAULT_RESAMPLER_LPF_ORDER 2
static MA_INLINE float ma_dr_mp3_mix_f32(float x, float y, float a)
static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
static void* ma_dr_mp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const ma_allocation_callbacks* pAllocationCallbacks)
static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
static ma_allocation_callbacks ma_dr_mp3_copy_allocation_callbacks_or_defaults(const ma_allocation_callbacks* pAllocationCallbacks)
allocationCallbacks.onMalloc = drmp3__malloc_default;
allocationCallbacks.onRealloc = drmp3__realloc_default;
allocationCallbacks.onFree = drmp3__free_default;
allocationCallbacks.onMalloc = ma_dr_mp3__malloc_default;
allocationCallbacks.onRealloc = ma_dr_mp3__realloc_default;
allocationCallbacks.onFree = ma_dr_mp3__free_default;
newDataCap = DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
newDataCap = MA_DR_MP3_DATA_CHUNK_SIZE;
pNewData = (ma_uint8*)ma_dr_mp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
DRMP3_ASSERT(pMP3->pData != NULL);
DRMP3_ASSERT(pMP3->dataCapacity > 0);
pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);
MA_DR_MP3_ASSERT(pMP3->pData != NULL);
MA_DR_MP3_ASSERT(pMP3->dataCapacity > 0);
if (pMP3->pData == NULL) {
return 0;
}
pcmFramesRead = ma_dr_mp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);
newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
newDataCap = pMP3->dataCapacity + MA_DR_MP3_DATA_CHUNK_SIZE;
pNewData = (ma_uint8*)ma_dr_mp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
drmp3_uint32 pcmFramesRead = 0;
drmp3dec_frame_info info;
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->memory.pData != NULL);
ma_uint32 pcmFramesRead = 0;
ma_dr_mp3dec_frame_info info;
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(pMP3->memory.pData != NULL);
pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
pcmFramesRead = ma_dr_mp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
if (drmp3_decode_next_frame(pMP3) == 0) {
drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
return DRMP3_FALSE;
if (ma_dr_mp3_decode_next_frame(pMP3) == 0) {
ma_dr_mp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
return MA_FALSE;
DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
switch (e)
{
case 0: return DRMP3_SUCCESS;
#ifdef EPERM
case EPERM: return DRMP3_INVALID_OPERATION;
#endif
#ifdef ENOENT
case ENOENT: return DRMP3_DOES_NOT_EXIST;
#endif
#ifdef ESRCH
case ESRCH: return DRMP3_DOES_NOT_EXIST;
#endif
#ifdef EINTR
case EINTR: return DRMP3_INTERRUPT;
#endif
#ifdef EIO
case EIO: return DRMP3_IO_ERROR;
#endif
#ifdef ENXIO
case ENXIO: return DRMP3_DOES_NOT_EXIST;
#endif
#ifdef E2BIG
case E2BIG: return DRMP3_INVALID_ARGS;
#endif
#ifdef ENOEXEC
case ENOEXEC: return DRMP3_INVALID_FILE;
#endif
#ifdef EBADF
case EBADF: return DRMP3_INVALID_FILE;
#endif
#ifdef ECHILD
case ECHILD: return DRMP3_ERROR;
#endif
#ifdef EAGAIN
case EAGAIN: return DRMP3_UNAVAILABLE;
#endif
#ifdef ENOMEM
case ENOMEM: return DRMP3_OUT_OF_MEMORY;
#endif
#ifdef EACCES
case EACCES: return DRMP3_ACCESS_DENIED;
#endif
#ifdef EFAULT
case EFAULT: return DRMP3_BAD_ADDRESS;
#endif
#ifdef ENOTBLK
case ENOTBLK: return DRMP3_ERROR;
#endif
#ifdef EBUSY
case EBUSY: return DRMP3_BUSY;
#endif
#ifdef EEXIST
case EEXIST: return DRMP3_ALREADY_EXISTS;
#endif
#ifdef EXDEV
case EXDEV: return DRMP3_ERROR;
#endif
#ifdef ENODEV
case ENODEV: return DRMP3_DOES_NOT_EXIST;
#endif
#ifdef ENOTDIR
case ENOTDIR: return DRMP3_NOT_DIRECTORY;
#endif
#ifdef EISDIR
case EISDIR: return DRMP3_IS_DIRECTORY;
#endif
#ifdef EINVAL
case EINVAL: return DRMP3_INVALID_ARGS;
#endif
#ifdef ENFILE
case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
#endif
#ifdef EMFILE
case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
#endif
#ifdef ENOTTY
case ENOTTY: return DRMP3_INVALID_OPERATION;
#endif
#ifdef ETXTBSY
case ETXTBSY: return DRMP3_BUSY;
#endif
#ifdef EFBIG
case EFBIG: return DRMP3_TOO_BIG;
#endif
#ifdef ENOSPC
case ENOSPC: return DRMP3_NO_SPACE;
#endif
#ifdef ESPIPE
case ESPIPE: return DRMP3_BAD_SEEK;
#endif
#ifdef EROFS
case EROFS: return DRMP3_ACCESS_DENIED;
#endif
#ifdef EMLINK
case EMLINK: return DRMP3_TOO_MANY_LINKS;
#endif
#ifdef EPIPE
case EPIPE: return DRMP3_BAD_PIPE;
#endif
#ifdef EDOM
case EDOM: return DRMP3_OUT_OF_RANGE;
#endif
#ifdef ERANGE
case ERANGE: return DRMP3_OUT_OF_RANGE;
#endif
#ifdef EDEADLK
case EDEADLK: return DRMP3_DEADLOCK;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
#endif
#ifdef ENOLCK
case ENOLCK: return DRMP3_ERROR;
#endif
#ifdef ENOSYS
case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
#endif
#ifdef ELOOP
case ELOOP: return DRMP3_TOO_MANY_LINKS;
#endif
#ifdef ENOMSG
case ENOMSG: return DRMP3_NO_MESSAGE;
#endif
#ifdef EIDRM
case EIDRM: return DRMP3_ERROR;
#endif
#ifdef ECHRNG
case ECHRNG: return DRMP3_ERROR;
#endif
#ifdef EL2NSYNC
case EL2NSYNC: return DRMP3_ERROR;
#endif
#ifdef EL3HLT
case EL3HLT: return DRMP3_ERROR;
#endif
#ifdef EL3RST
case EL3RST: return DRMP3_ERROR;
#endif
#ifdef ELNRNG
case ELNRNG: return DRMP3_OUT_OF_RANGE;
#endif
#ifdef EUNATCH
case EUNATCH: return DRMP3_ERROR;
#endif
#ifdef ENOCSI
case ENOCSI: return DRMP3_ERROR;
#endif
#ifdef EL2HLT
case EL2HLT: return DRMP3_ERROR;
#endif
#ifdef EBADE
case EBADE: return DRMP3_ERROR;
#endif
#ifdef EBADR
case EBADR: return DRMP3_ERROR;
#endif
#ifdef EXFULL
case EXFULL: return DRMP3_ERROR;
#endif
#ifdef ENOANO
case ENOANO: return DRMP3_ERROR;
#endif
#ifdef EBADRQC
case EBADRQC: return DRMP3_ERROR;
#endif
#ifdef EBADSLT
case EBADSLT: return DRMP3_ERROR;
#endif
#ifdef EBFONT
case EBFONT: return DRMP3_INVALID_FILE;
#endif
#ifdef ENOSTR
case ENOSTR: return DRMP3_ERROR;
#endif
#ifdef ENODATA
case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
#endif
#ifdef ETIME
case ETIME: return DRMP3_TIMEOUT;
#endif
#ifdef ENOSR
case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
#endif
#ifdef ENONET
case ENONET: return DRMP3_NO_NETWORK;
#endif
#ifdef ENOPKG
case ENOPKG: return DRMP3_ERROR;
#endif
#ifdef EREMOTE
case EREMOTE: return DRMP3_ERROR;
#endif
#ifdef ENOLINK
case ENOLINK: return DRMP3_ERROR;
#endif
#ifdef EADV
case EADV: return DRMP3_ERROR;
#endif
#ifdef ESRMNT
case ESRMNT: return DRMP3_ERROR;
#endif
#ifdef ECOMM
case ECOMM: return DRMP3_ERROR;
#endif
#ifdef EPROTO
case EPROTO: return DRMP3_ERROR;
#endif
#ifdef EMULTIHOP
case EMULTIHOP: return DRMP3_ERROR;
#endif
#ifdef EDOTDOT
case EDOTDOT: return DRMP3_ERROR;
#endif
#ifdef EBADMSG
case EBADMSG: return DRMP3_BAD_MESSAGE;
#endif
#ifdef EOVERFLOW
case EOVERFLOW: return DRMP3_TOO_BIG;
#endif
#ifdef ENOTUNIQ
case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
#endif
#ifdef EBADFD
case EBADFD: return DRMP3_ERROR;
#endif
#ifdef EREMCHG
case EREMCHG: return DRMP3_ERROR;
#endif
#ifdef ELIBACC
case ELIBACC: return DRMP3_ACCESS_DENIED;
#endif
#ifdef ELIBBAD
case ELIBBAD: return DRMP3_INVALID_FILE;
#endif
#ifdef ELIBSCN
case ELIBSCN: return DRMP3_INVALID_FILE;
#endif
#ifdef ELIBMAX
case ELIBMAX: return DRMP3_ERROR;
#endif
#ifdef ELIBEXEC
case ELIBEXEC: return DRMP3_ERROR;
#endif
#ifdef EILSEQ
case EILSEQ: return DRMP3_INVALID_DATA;
#endif
#ifdef ERESTART
case ERESTART: return DRMP3_ERROR;
#endif
#ifdef ESTRPIPE
case ESTRPIPE: return DRMP3_ERROR;
#endif
#ifdef EUSERS
case EUSERS: return DRMP3_ERROR;
#endif
#ifdef ENOTSOCK
case ENOTSOCK: return DRMP3_NOT_SOCKET;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
#endif
#ifdef EMSGSIZE
case EMSGSIZE: return DRMP3_TOO_BIG;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
#endif
#ifdef EOPNOTSUPP
case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
#endif
#ifdef EPFNOSUPPORT
case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
#endif
#ifdef EADDRINUSE
case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: return DRMP3_ERROR;
#endif
#ifdef ENETDOWN
case ENETDOWN: return DRMP3_NO_NETWORK;
#endif
#ifdef ENETUNREACH
case ENETUNREACH: return DRMP3_NO_NETWORK;
#endif
#ifdef ENETRESET
case ENETRESET: return DRMP3_NO_NETWORK;
#endif
#ifdef ECONNABORTED
case ECONNABORTED: return DRMP3_NO_NETWORK;
#endif
#ifdef ECONNRESET
case ECONNRESET: return DRMP3_CONNECTION_RESET;
#endif
#ifdef ENOBUFS
case ENOBUFS: return DRMP3_NO_SPACE;
#endif
#ifdef EISCONN
case EISCONN: return DRMP3_ALREADY_CONNECTED;
#endif
#ifdef ENOTCONN
case ENOTCONN: return DRMP3_NOT_CONNECTED;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: return DRMP3_ERROR;
#endif
#ifdef ETOOMANYREFS
case ETOOMANYREFS: return DRMP3_ERROR;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: return DRMP3_TIMEOUT;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: return DRMP3_NO_HOST;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: return DRMP3_NO_HOST;
#endif
#ifdef EALREADY
case EALREADY: return DRMP3_IN_PROGRESS;
#endif
#ifdef EINPROGRESS
case EINPROGRESS: return DRMP3_IN_PROGRESS;
#endif
#ifdef ESTALE
case ESTALE: return DRMP3_INVALID_FILE;
#endif
#ifdef EUCLEAN
case EUCLEAN: return DRMP3_ERROR;
#endif
#ifdef ENOTNAM
case ENOTNAM: return DRMP3_ERROR;
#endif
#ifdef ENAVAIL
case ENAVAIL: return DRMP3_ERROR;
#endif
#ifdef EISNAM
case EISNAM: return DRMP3_ERROR;
#endif
#ifdef EREMOTEIO
case EREMOTEIO: return DRMP3_IO_ERROR;
#endif
#ifdef EDQUOT
case EDQUOT: return DRMP3_NO_SPACE;
#endif
#ifdef ENOMEDIUM
case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
#endif
#ifdef EMEDIUMTYPE
case EMEDIUMTYPE: return DRMP3_ERROR;
#endif
#ifdef ECANCELED
case ECANCELED: return DRMP3_CANCELLED;
#endif
#ifdef ENOKEY
case ENOKEY: return DRMP3_ERROR;
#endif
#ifdef EKEYEXPIRED
case EKEYEXPIRED: return DRMP3_ERROR;
#endif
#ifdef EKEYREVOKED
case EKEYREVOKED: return DRMP3_ERROR;
#endif
#ifdef EKEYREJECTED
case EKEYREJECTED: return DRMP3_ERROR;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD: return DRMP3_ERROR;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE: return DRMP3_ERROR;
#endif
#ifdef ERFKILL
case ERFKILL: return DRMP3_ERROR;
#endif
#ifdef EHWPOISON
case EHWPOISON: return DRMP3_ERROR;
#endif
default: return DRMP3_ERROR;
}
}
static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err;
#endif
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRMP3_INVALID_ARGS;
}
#if defined(_MSC_VER) && _MSC_VER >= 1400
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drmp3_result_from_errno(err);
}
#else
#if defined(_WIN32) || defined(__APPLE__)
*ppFile = fopen(pFilePath, pOpenMode);
#else
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
*ppFile = fopen64(pFilePath, pOpenMode);
#else
*ppFile = fopen(pFilePath, pOpenMode);
#endif
#endif
if (*ppFile == NULL) {
drmp3_result result = drmp3_result_from_errno(errno);
if (result == DRMP3_SUCCESS) {
result = DRMP3_ERROR;
}
return result;
}
#endif
return DRMP3_SUCCESS;
}
#if defined(_WIN32)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define DRMP3_HAS_WFOPEN
#endif
#endif
static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (ppFile != NULL) {
*ppFile = NULL;
}
if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
return DRMP3_INVALID_ARGS;
}
#if defined(DRMP3_HAS_WFOPEN)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drmp3_result_from_errno(err);
}
#else
*ppFile = _wfopen(pFilePath, pOpenMode);
if (*ppFile == NULL) {
return drmp3_result_from_errno(errno);
}
#endif
(void)pAllocationCallbacks;
}
#else
{
mbstate_t mbs;
size_t lenMB;
const wchar_t* pFilePathTemp = pFilePath;
char* pFilePathMB = NULL;
char pOpenModeMB[32] = {0};
DRMP3_ZERO_OBJECT(&mbs);
lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
if (lenMB == (size_t)-1) {
return drmp3_result_from_errno(errno);
}
pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
if (pFilePathMB == NULL) {
return DRMP3_OUT_OF_MEMORY;
}
pFilePathTemp = pFilePath;
DRMP3_ZERO_OBJECT(&mbs);
wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
{
size_t i = 0;
for (;;) {
if (pOpenMode[i] == 0) {
pOpenModeMB[i] = '\0';
break;
}
pOpenModeMB[i] = (char)pOpenMode[i];
i += 1;
}
}
*ppFile = fopen(pFilePathMB, pOpenModeMB);
drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
}
if (*ppFile == NULL) {
return DRMP3_ERROR;
}
#endif
return DRMP3_SUCCESS;
}
static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_mp3_init_file(ma_dr_mp3* pMP3, const char* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRMP3_TRUE) {
result = ma_dr_mp3_init(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != MA_TRUE) {
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_bool32 ma_dr_mp3_init_file_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRMP3_TRUE) {
result = ma_dr_mp3_init(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != MA_TRUE) {
#if defined(DR_MP3_FLOAT_OUTPUT)
static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
#if defined(MA_DR_MP3_FLOAT_OUTPUT)
static void ma_dr_mp3_f32_to_s16(ma_int16* dst, const float* src, ma_uint64 sampleCount)
#if !defined(DR_MP3_FLOAT_OUTPUT)
static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
#if !defined(MA_DR_MP3_FLOAT_OUTPUT)
static void ma_dr_mp3_s16_to_f32(float* dst, const ma_int16* src, ma_uint64 sampleCount)
#if defined(DR_MP3_FLOAT_OUTPUT)
float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
#if defined(MA_DR_MP3_FLOAT_OUTPUT)
float* pFramesOutF32 = (float*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
float* pFramesInF32 = (float*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
MA_DR_MP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels);
drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
ma_int16* pFramesOutS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(ma_int16) * totalFramesRead * pMP3->channels);
ma_int16* pFramesInS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(ma_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
MA_DR_MP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(ma_int16) * framesToConsume * pMP3->channels);
drmp3_uint64 framesJustRead;
drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
ma_uint64 framesJustRead;
ma_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
ma_uint64 framesToReadNow = MA_DR_MP3_COUNTOF(pTempS16) / pMP3->channels;
drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
ma_dr_mp3_s16_to_f32((float*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
drmp3_uint64 framesJustRead;
drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
ma_uint64 framesJustRead;
ma_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
ma_uint64 framesToReadNow = MA_DR_MP3_COUNTOF(pTempF32) / pMP3->channels;
drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
ma_dr_mp3_f32_to_s16((ma_int16*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(ma_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->onSeek != NULL);
if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
return DRMP3_FALSE;
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(pMP3->onSeek != NULL);
if (!ma_dr_mp3__on_seek(pMP3, 0, ma_dr_mp3_seek_origin_start)) {
return MA_FALSE;
drmp3_uint64 framesRead;
#if defined(DR_MP3_FLOAT_OUTPUT)
framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
ma_uint64 framesRead;
#if defined(MA_DR_MP3_FLOAT_OUTPUT)
framesRead = ma_dr_mp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
MA_DR_MP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
return ma_dr_mp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
drmp3_seek_point seekPoint;
drmp3_uint32 priorSeekPointIndex;
drmp3_uint16 iMP3Frame;
drmp3_uint64 leftoverFrames;
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
DRMP3_ASSERT(pMP3->seekPointCount > 0);
if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
ma_dr_mp3_seek_point seekPoint;
ma_uint32 priorSeekPointIndex;
ma_uint16 iMP3Frame;
ma_uint64 leftoverFrames;
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(pMP3->pSeekPoints != NULL);
MA_DR_MP3_ASSERT(pMP3->seekPointCount > 0);
if (ma_dr_mp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
MA_API ma_bool32 ma_dr_mp3_get_mp3_and_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint64* pMP3FrameCount, ma_uint64* pPCMFrameCount)
static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
static void ma_dr_mp3__accumulate_running_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint32 pcmFrameCountIn, ma_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
drmp3_uint64 bytePos;
drmp3_uint64 pcmFrameIndex;
} drmp3__seeking_mp3_frame_info;
DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
ma_uint64 bytePos;
ma_uint64 pcmFrameIndex;
} ma_dr_mp3__seeking_mp3_frame_info;
MA_API ma_bool32 ma_dr_mp3_calculate_seek_points(ma_dr_mp3* pMP3, ma_uint32* pSeekPointCount, ma_dr_mp3_seek_point* pSeekPoints)
drmp3_uint32 seekPointCount;
drmp3_uint64 currentPCMFrame;
drmp3_uint64 totalMP3FrameCount;
drmp3_uint64 totalPCMFrameCount;
ma_uint32 seekPointCount;
ma_uint64 currentPCMFrame;
ma_uint64 totalMP3FrameCount;
ma_uint64 totalPCMFrameCount;
drmp3_uint64 pcmFramesBetweenSeekPoints;
drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
drmp3_uint64 runningPCMFrameCount = 0;
ma_uint64 pcmFramesBetweenSeekPoints;
ma_dr_mp3__seeking_mp3_frame_info mp3FrameInfo[MA_DR_MP3_SEEK_LEADING_MP3_FRAMES+1];
ma_uint64 runningPCMFrameCount = 0;
for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
for (iMP3Frame = 0; iMP3Frame < MA_DR_MP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
ma_uint32 pcmFramesInCurrentMP3FrameIn;
MA_DR_MP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
ma_dr_mp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
pSeekPoints[iSeekPoint].mp3FramesToDiscard = MA_DR_MP3_SEEK_LEADING_MP3_FRAMES;
pSeekPoints[iSeekPoint].pcmFramesToDiscard = (ma_uint16)(nextTargetPCMFrame - mp3FrameInfo[MA_DR_MP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
mp3FrameInfo[MA_DR_MP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
mp3FrameInfo[MA_DR_MP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
pcmFramesInCurrentMP3FrameIn = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL);
pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
pSeekPoints[iSeekPoint].mp3FramesToDiscard = MA_DR_MP3_SEEK_LEADING_MP3_FRAMES;
pSeekPoints[iSeekPoint].pcmFramesToDiscard = (ma_uint16)(nextTargetPCMFrame - mp3FrameInfo[MA_DR_MP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
ma_dr_mp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
MA_API ma_bool32 ma_dr_mp3_bind_seek_table(ma_dr_mp3* pMP3, ma_uint32 seekPointCount, ma_dr_mp3_seek_point* pSeekPoints)
drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
ma_uint64 framesToReadRightNow = MA_DR_MP3_COUNTOF(temp) / pMP3->channels;
ma_uint64 framesJustRead = ma_dr_mp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
pNewFrames = (float*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
MA_DR_MP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
static ma_int16* ma_dr_mp3__full_read_and_close_s16(ma_dr_mp3* pMP3, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount)
drmp3_uint64 totalFramesRead = 0;
drmp3_uint64 framesCapacity = 0;
drmp3_int16* pFrames = NULL;
drmp3_int16 temp[4096];
DRMP3_ASSERT(pMP3 != NULL);
ma_uint64 totalFramesRead = 0;
ma_uint64 framesCapacity = 0;
ma_int16* pFrames = NULL;
ma_int16 temp[4096];
MA_DR_MP3_ASSERT(pMP3 != NULL);
drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
ma_uint64 framesToReadRightNow = MA_DR_MP3_COUNTOF(temp) / pMP3->channels;
ma_uint64 framesJustRead = ma_dr_mp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(ma_int16);
newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(ma_int16);
if (newFramesBufferSize > (ma_uint64)MA_SIZE_MAX) {
pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
pNewFrames = (ma_int16*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
MA_DR_MP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(ma_int16)));
DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API float* ma_dr_mp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_mp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
#ifndef DR_MP3_NO_STDIO
DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
#ifndef MA_DR_MP3_NO_STDIO
MA_API float* ma_dr_mp3_open_file_and_read_pcm_frames_f32(const char* filePath, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
MA_API ma_int16* ma_dr_mp3_open_file_and_read_pcm_frames_s16(const char* filePath, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)