view release on metacpan or search on metacpan
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
ma_noise noise;
ma_result result = ma_noise_init(&config, &noise);
if (result != MA_SUCCESS) {
// Error.
}
...
ma_noise_read_pcm_frames(&noise, pOutput, frameCount);
```
The noise API uses simple LCG random number generation. It supports a custom seed which is useful for things like automated testing requiring reproducibility.
Setting the seed to zero will default to MA_DEFAULT_LCG_SEED.
By default, the noise API will use different values for different channels. So, for example, the left side in a stereo stream will be different to the right
side. To instead have each channel use the same random value, set the `duplicateChannels` member of the noise config to true, like so:
```c
config.duplicateChannels = MA_TRUE;
```
Below are the supported noise types.
+------------------------+
| Enum Name |
+------------------------+
| ma_noise_type_white |
| ma_noise_type_pink |
| ma_noise_type_brownian |
+------------------------+
9. Audio Buffers
================
miniaudio supports reading from a buffer of raw audio data via the `ma_audio_buffer` API. This can read from memory that's managed by the application, but
can also handle the memory management for you internally. Memory management is flexible and should support most use cases.
Audio buffers are initialised using the standard configuration system used everywhere in miniaudio:
```c
ma_audio_buffer_config config = ma_audio_buffer_config_init(
format,
channels,
sizeInFrames,
pExistingData,
&allocationCallbacks);
ma_audio_buffer buffer;
result = ma_audio_buffer_init(&config, &buffer);
if (result != MA_SUCCESS) {
// Error.
}
...
ma_audio_buffer_uninit(&buffer);
```
In the example above, the memory pointed to by `pExistingData` will _not_ be copied and is how an application can do self-managed memory allocation. If you
would rather make a copy of the data, use `ma_audio_buffer_init_copy()`. To uninitialize the buffer, use `ma_audio_buffer_uninit()`.
Sometimes it can be convenient to allocate the memory for the `ma_audio_buffer` structure _and_ the raw audio data in a contiguous block of memory. That is,
the raw audio data will be located immediately after the `ma_audio_buffer` structure. To do this, use `ma_audio_buffer_alloc_and_init()`:
```c
ma_audio_buffer_config config = ma_audio_buffer_config_init(
format,
channels,
sizeInFrames,
pExistingData,
&allocationCallbacks);
ma_audio_buffer* pBuffer
result = ma_audio_buffer_alloc_and_init(&config, &pBuffer);
if (result != MA_SUCCESS) {
// Error
}
...
ma_audio_buffer_uninit_and_free(&buffer);
```
If you initialize the buffer with `ma_audio_buffer_alloc_and_init()` you should uninitialize it with `ma_audio_buffer_uninit_and_free()`. In the example above,
the memory pointed to by `pExistingData` will be copied into the buffer, which is contrary to the behavior of `ma_audio_buffer_init()`.
An audio buffer has a playback cursor just like a decoder. As you read frames from the buffer, the cursor moves forward. The last parameter (`loop`) can be
used to determine if the buffer should loop. The return value is the number of frames actually read. If this is less than the number of frames requested it
means the end has been reached. This should never happen if the `loop` parameter is set to true. If you want to manually loop back to the start, you can do so
with with `ma_audio_buffer_seek_to_pcm_frame(pAudioBuffer, 0)`. Below is an example for reading data from an audio buffer.
```c
ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames(pAudioBuffer, pFramesOut, desiredFrameCount, isLooping);
if (framesRead < desiredFrameCount) {
// If not looping, this means the end has been reached. This should never happen in looping mode with valid input.
}
```
Sometimes you may want to avoid the cost of data movement between the internal buffer and the output buffer. Instead you can use memory mapping to retrieve a
pointer to a segment of data:
```c
void* pMappedFrames;
ma_uint64 frameCount = frameCountToTryMapping;
ma_result result = ma_audio_buffer_map(pAudioBuffer, &pMappedFrames, &frameCount);
if (result == MA_SUCCESS) {
// Map was successful. The value in frameCount will be how many frames were _actually_ mapped, which may be
// less due to the end of the buffer being reached.
ma_copy_pcm_frames(pFramesOut, pMappedFrames, frameCount, pAudioBuffer->format, pAudioBuffer->channels);
// You must unmap the buffer.
ma_audio_buffer_unmap(pAudioBuffer, frameCount);
}
```
When you use memory mapping, the read cursor is increment by the frame count passed in to `ma_audio_buffer_unmap()`. If you decide not to process every frame
you can pass in a value smaller than the value returned by `ma_audio_buffer_map()`. The disadvantage to using memory mapping is that it does not handle looping
for you. You can determine if the buffer is at the end for the purpose of looping with `ma_audio_buffer_at_end()` or by inspecting the return value of
`ma_audio_buffer_unmap()` and checking if it equals `MA_AT_END`. You should not treat `MA_AT_END` as an error when returned by `ma_audio_buffer_unmap()`.
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
Thread Safety
-------------
Unsafe. Do not call this function across multiple threads as some backends read and write to global state.
Remarks
-------
Results are undefined if you call this while any device created by this context is still active.
See Also
--------
ma_context_init()
*/
MA_API ma_result ma_context_uninit(ma_context* pContext);
/*
Retrieves the size of the ma_context object.
This is mainly for the purpose of bindings to know how much memory to allocate.
*/
MA_API size_t ma_context_sizeof(void);
/*
Enumerates over every device (both playback and capture).
This is a lower-level enumeration function to the easier to use `ma_context_get_devices()`. Use `ma_context_enumerate_devices()` if you would rather not incur
an internal heap allocation, or it simply suits your code better.
Note that this only retrieves the ID and name/description of the device. The reason for only retrieving basic information is that it would otherwise require
opening the backend device in order to probe it for more detailed information which can be inefficient. Consider using `ma_context_get_device_info()` for this,
but don't call it from within the enumeration callback.
Returning false from the callback will stop enumeration. Returning true will continue enumeration.
Parameters
----------
pContext (in)
A pointer to the context performing the enumeration.
callback (in)
The callback to fire for each enumerated device.
pUserData (in)
A pointer to application-defined data passed to the callback.
Return Value
------------
MA_SUCCESS if successful; any other error code otherwise.
Thread Safety
-------------
Safe. This is guarded using a simple mutex lock.
Remarks
-------
Do _not_ assume the first enumerated device of a given type is the default device.
Some backends and platforms may only support default playback and capture devices.
In general, you should not do anything complicated from within the callback. In particular, do not try initializing a device from within the callback. Also,
do not try to call `ma_context_get_device_info()` from within the callback.
Consider using `ma_context_get_devices()` for a simpler and safer API, albeit at the expense of an internal heap allocation.
Example 1 - Simple Enumeration
------------------------------
ma_bool32 ma_device_enum_callback(ma_context* pContext, ma_device_type deviceType, const ma_device_info* pInfo, void* pUserData)
{
printf("Device Name: %s\n", pInfo->name);
return MA_TRUE;
}
ma_result result = ma_context_enumerate_devices(&context, my_device_enum_callback, pMyUserData);
if (result != MA_SUCCESS) {
// Error.
}
See Also
--------
ma_context_get_devices()
*/
MA_API ma_result ma_context_enumerate_devices(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
/*
Retrieves basic information about every active playback and/or capture device.
This function will allocate memory internally for the device lists and return a pointer to them through the `ppPlaybackDeviceInfos` and `ppCaptureDeviceInfos`
parameters. If you do not want to incur the overhead of these allocations consider using `ma_context_enumerate_devices()` which will instead use a callback.
Parameters
----------
pContext (in)
A pointer to the context performing the enumeration.
ppPlaybackDeviceInfos (out)
A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for playback devices.
pPlaybackDeviceCount (out)
A pointer to an unsigned integer that will receive the number of playback devices.
ppCaptureDeviceInfos (out)
A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for capture devices.
pCaptureDeviceCount (out)
A pointer to an unsigned integer that will receive the number of capture devices.
Return Value
------------
MA_SUCCESS if successful; any other error code otherwise.
Thread Safety
-------------
Unsafe. Since each call to this function invalidates the pointers from the previous call, you should not be calling this simultaneously across multiple
threads. Instead, you need to make a copy of the returned data with your own higher level synchronization.
Remarks
-------
It is _not_ safe to assume the first device in the list is the default device.
You can pass in NULL for the playback or capture lists in which case they'll be ignored.
The returned pointers will become invalid upon the next call this this function, or when the context is uninitialized. Do not free the returned pointers.
See Also
--------
ma_context_get_devices()
*/
MA_API ma_result ma_context_get_devices(ma_context* pContext, ma_device_info** ppPlaybackDeviceInfos, ma_uint32* pPlaybackDeviceCount, ma_device_info** ppCaptureDeviceInfos, ma_uint32* pCaptureDeviceCount);
/*
Retrieves information about a device of the given type, with the specified ID and share mode.
Parameters
----------
pContext (in)
A pointer to the context performing the query.
deviceType (in)
The type of the device being queried. Must be either `ma_device_type_playback` or `ma_device_type_capture`.
pDeviceID (in)
The ID of the device being queried.
shareMode (in)
The share mode to query for device capabilities. This should be set to whatever you're intending on using when initializing the device. If you're unsure,
set this to `ma_share_mode_shared`.
pDeviceInfo (out)
A pointer to the `ma_device_info` structure that will receive the device information.
Return Value
------------
MA_SUCCESS if successful; any other error code otherwise.
Thread Safety
-------------
Safe. This is guarded using a simple mutex lock.
Remarks
-------
Do _not_ call this from within the `ma_context_enumerate_devices()` callback.
It's possible for a device to have different information and capabilities depending on whether or not it's opened in shared or exclusive mode. For example, in
shared mode, WASAPI always uses floating point samples for mixing, but in exclusive mode it can be anything. Therefore, this function allows you to specify
which share mode you want information for. Note that not all backends and devices support shared or exclusive mode, in which case this function will fail if
the requested share mode is unsupported.
This leaves pDeviceInfo unmodified in the result of an error.
*/
MA_API ma_result ma_context_get_device_info(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_share_mode shareMode, ma_device_info* pDeviceInfo);
/*
Determines if the given context supports loopback mode.
Parameters
----------
pContext (in)
A pointer to the context getting queried.
Return Value
------------
MA_TRUE if the context supports loopback mode; MA_FALSE otherwise.
*/
MA_API ma_bool32 ma_context_is_loopback_supported(ma_context* pContext);
/*
Initializes a device config with default settings.
Parameters
----------
deviceType (in)
The type of the device this config is being initialized for. This must set to one of the following:
|-------------------------|
| Device Type |
|-------------------------|
| ma_device_type_playback |
| ma_device_type_capture |
| ma_device_type_duplex |
| ma_device_type_loopback |
|-------------------------|
Return Value
------------
A new device config object with default settings. You will typically want to adjust the config after this function returns. See remarks.
Thread Safety
-------------
Safe.
Callback Safety
---------------
Safe, but don't try initializing a device in a callback.
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
#endif
#if defined(MA_SUPPORT_AVX2)
static MA_INLINE __m256 ma_mix_f32_fast__avx2(__m256 x, __m256 y, __m256 a)
{
return _mm256_add_ps(x, _mm256_mul_ps(_mm256_sub_ps(y, x), a));
}
#endif
#if defined(MA_SUPPORT_AVX512)
static MA_INLINE __m512 ma_mix_f32_fast__avx512(__m512 x, __m512 y, __m512 a)
{
return _mm512_add_ps(x, _mm512_mul_ps(_mm512_sub_ps(y, x), a));
}
#endif
#if defined(MA_SUPPORT_NEON)
static MA_INLINE float32x4_t ma_mix_f32_fast__neon(float32x4_t x, float32x4_t y, float32x4_t a)
{
return vaddq_f32(x, vmulq_f32(vsubq_f32(y, x), a));
}
#endif
static MA_INLINE double ma_mix_f64(double x, double y, double a)
{
return x*(1-a) + y*a;
}
static MA_INLINE double ma_mix_f64_fast(double x, double y, double a)
{
return x + (y - x)*a;
}
static MA_INLINE float ma_scale_to_range_f32(float x, float lo, float hi)
{
return lo + x*(hi-lo);
}
/*
Greatest common factor using Euclid's algorithm iteratively.
*/
static MA_INLINE ma_uint32 ma_gcf_u32(ma_uint32 a, ma_uint32 b)
{
for (;;) {
if (b == 0) {
break;
} else {
ma_uint32 t = a;
a = b;
b = t % a;
}
}
return a;
}
/*
Random Number Generation
miniaudio uses the LCG random number generation algorithm. This is good enough for audio.
Note that miniaudio's global LCG implementation uses global state which is _not_ thread-local. When this is called across
multiple threads, results will be unpredictable. However, it won't crash and results will still be random enough for
miniaudio's purposes.
*/
#ifndef MA_DEFAULT_LCG_SEED
#define MA_DEFAULT_LCG_SEED 4321
#endif
#define MA_LCG_M 2147483647
#define MA_LCG_A 48271
#define MA_LCG_C 0
static ma_lcg g_maLCG = {MA_DEFAULT_LCG_SEED}; /* Non-zero initial seed. Use ma_seed() to use an explicit seed. */
static MA_INLINE void ma_lcg_seed(ma_lcg* pLCG, ma_int32 seed)
{
MA_ASSERT(pLCG != NULL);
pLCG->state = seed;
}
static MA_INLINE ma_int32 ma_lcg_rand_s32(ma_lcg* pLCG)
{
pLCG->state = (MA_LCG_A * pLCG->state + MA_LCG_C) % MA_LCG_M;
return pLCG->state;
}
static MA_INLINE ma_uint32 ma_lcg_rand_u32(ma_lcg* pLCG)
{
return (ma_uint32)ma_lcg_rand_s32(pLCG);
}
static MA_INLINE ma_int16 ma_lcg_rand_s16(ma_lcg* pLCG)
{
return (ma_int16)(ma_lcg_rand_s32(pLCG) & 0xFFFF);
}
static MA_INLINE double ma_lcg_rand_f64(ma_lcg* pLCG)
{
return ma_lcg_rand_s32(pLCG) / (double)0x7FFFFFFF;
}
static MA_INLINE float ma_lcg_rand_f32(ma_lcg* pLCG)
{
return (float)ma_lcg_rand_f64(pLCG);
}
static MA_INLINE float ma_lcg_rand_range_f32(ma_lcg* pLCG, float lo, float hi)
{
return ma_scale_to_range_f32(ma_lcg_rand_f32(pLCG), lo, hi);
}
static MA_INLINE ma_int32 ma_lcg_rand_range_s32(ma_lcg* pLCG, ma_int32 lo, ma_int32 hi)
{
if (lo == hi) {
return lo;
}
return lo + ma_lcg_rand_u32(pLCG) / (0xFFFFFFFF / (hi - lo + 1) + 1);
}
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
/* ID */
ma_strncpy_s(deviceInfo.id.oss, sizeof(deviceInfo.id.oss), ai.devnode, (size_t)-1);
/*
The human readable device name should be in the "ai.handle" variable, but it can
sometimes be empty in which case we just fall back to "ai.name" which is less user
friendly, but usually has a value.
*/
if (ai.handle[0] != '\0') {
ma_strncpy_s(deviceInfo.name, sizeof(deviceInfo.name), ai.handle, (size_t)-1);
} else {
ma_strncpy_s(deviceInfo.name, sizeof(deviceInfo.name), ai.name, (size_t)-1);
}
/* The device can be both playback and capture. */
if (!isTerminating && (ai.caps & PCM_CAP_OUTPUT) != 0) {
isTerminating = !callback(pContext, ma_device_type_playback, &deviceInfo, pUserData);
}
if (!isTerminating && (ai.caps & PCM_CAP_INPUT) != 0) {
isTerminating = !callback(pContext, ma_device_type_capture, &deviceInfo, pUserData);
}
if (isTerminating) {
break;
}
}
}
}
} else {
close(fd);
return ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[OSS] Failed to retrieve system information for device enumeration.", MA_NO_BACKEND);
}
close(fd);
return MA_SUCCESS;
}
static ma_result ma_context_get_device_info__oss(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_share_mode shareMode, ma_device_info* pDeviceInfo)
{
ma_bool32 foundDevice;
int fdTemp;
oss_sysinfo si;
int result;
MA_ASSERT(pContext != NULL);
(void)shareMode;
/* Handle the default device a little differently. */
if (pDeviceID == NULL) {
if (deviceType == ma_device_type_playback) {
ma_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), MA_DEFAULT_PLAYBACK_DEVICE_NAME, (size_t)-1);
} else {
ma_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), MA_DEFAULT_CAPTURE_DEVICE_NAME, (size_t)-1);
}
return MA_SUCCESS;
}
/* If we get here it means we are _not_ using the default device. */
foundDevice = MA_FALSE;
fdTemp = ma_open_temp_device__oss();
if (fdTemp == -1) {
return ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[OSS] Failed to open a temporary device for retrieving system information used for device enumeration.", MA_NO_BACKEND);
}
result = ioctl(fdTemp, SNDCTL_SYSINFO, &si);
if (result != -1) {
int iAudioDevice;
for (iAudioDevice = 0; iAudioDevice < si.numaudios; ++iAudioDevice) {
oss_audioinfo ai;
ai.dev = iAudioDevice;
result = ioctl(fdTemp, SNDCTL_AUDIOINFO, &ai);
if (result != -1) {
if (ma_strcmp(ai.devnode, pDeviceID->oss) == 0) {
/* It has the same name, so now just confirm the type. */
if ((deviceType == ma_device_type_playback && ((ai.caps & PCM_CAP_OUTPUT) != 0)) ||
(deviceType == ma_device_type_capture && ((ai.caps & PCM_CAP_INPUT) != 0))) {
unsigned int formatMask;
/* ID */
ma_strncpy_s(pDeviceInfo->id.oss, sizeof(pDeviceInfo->id.oss), ai.devnode, (size_t)-1);
/*
The human readable device name should be in the "ai.handle" variable, but it can
sometimes be empty in which case we just fall back to "ai.name" which is less user
friendly, but usually has a value.
*/
if (ai.handle[0] != '\0') {
ma_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), ai.handle, (size_t)-1);
} else {
ma_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), ai.name, (size_t)-1);
}
pDeviceInfo->minChannels = ai.min_channels;
pDeviceInfo->maxChannels = ai.max_channels;
pDeviceInfo->minSampleRate = ai.min_rate;
pDeviceInfo->maxSampleRate = ai.max_rate;
pDeviceInfo->formatCount = 0;
if (deviceType == ma_device_type_playback) {
formatMask = ai.oformats;
} else {
formatMask = ai.iformats;
}
if ((formatMask & AFMT_U8) != 0) {
pDeviceInfo->formats[pDeviceInfo->formatCount++] = ma_format_u8;
}
if (((formatMask & AFMT_S16_LE) != 0 && ma_is_little_endian()) || (AFMT_S16_BE && ma_is_big_endian())) {
pDeviceInfo->formats[pDeviceInfo->formatCount++] = ma_format_s16;
}
if (((formatMask & AFMT_S32_LE) != 0 && ma_is_little_endian()) || (AFMT_S32_BE && ma_is_big_endian())) {
pDeviceInfo->formats[pDeviceInfo->formatCount++] = ma_format_s32;
}
foundDevice = MA_TRUE;
break;
}
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
/*
When the device is being initialized it's initial state is set to MA_STATE_UNINITIALIZED. Before returning from
ma_device_init(), the state needs to be set to something valid. In miniaudio the device's default state immediately
after initialization is stopped, so therefore we need to mark the device as such. miniaudio will wait on the worker
thread to signal an event to know when the worker thread is ready for action.
*/
ma_device__set_state(pDevice, MA_STATE_STOPPED);
ma_event_signal(&pDevice->stopEvent);
for (;;) { /* <-- This loop just keeps the thread alive. The main audio loop is inside. */
ma_stop_proc onStop;
/* We wait on an event to know when something has requested that the device be started and the main loop entered. */
ma_event_wait(&pDevice->wakeupEvent);
/* Default result code. */
pDevice->workResult = MA_SUCCESS;
/* If the reason for the wake up is that we are terminating, just break from the loop. */
if (ma_device__get_state(pDevice) == MA_STATE_UNINITIALIZED) {
break;
}
/*
Getting to this point means the device is wanting to get started. The function that has requested that the device
be started will be waiting on an event (pDevice->startEvent) which means we need to make sure we signal the event
in both the success and error case. It's important that the state of the device is set _before_ signaling the event.
*/
MA_ASSERT(ma_device__get_state(pDevice) == MA_STATE_STARTING);
/* Make sure the state is set appropriately. */
ma_device__set_state(pDevice, MA_STATE_STARTED);
ma_event_signal(&pDevice->startEvent);
if (pDevice->pContext->onDeviceMainLoop != NULL) {
pDevice->pContext->onDeviceMainLoop(pDevice);
} else {
ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "No main loop implementation.", MA_API_NOT_FOUND);
}
/*
Getting here means we have broken from the main loop which happens the application has requested that device be stopped. Note that this
may have actually already happened above if the device was lost and miniaudio has attempted to re-initialize the device. In this case we
don't want to be doing this a second time.
*/
if (ma_device__get_state(pDevice) != MA_STATE_UNINITIALIZED) {
if (pDevice->pContext->onDeviceStop) {
pDevice->pContext->onDeviceStop(pDevice);
}
}
/* After the device has stopped, make sure an event is posted. */
onStop = pDevice->onStop;
if (onStop) {
onStop(pDevice);
}
/*
A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. Note that
it's possible that the device has been uninitialized which means we need to _not_ change the status to stopped. We cannot go from an
uninitialized state to stopped state.
*/
if (ma_device__get_state(pDevice) != MA_STATE_UNINITIALIZED) {
ma_device__set_state(pDevice, MA_STATE_STOPPED);
ma_event_signal(&pDevice->stopEvent);
}
}
/* Make sure we aren't continuously waiting on a stop event. */
ma_event_signal(&pDevice->stopEvent); /* <-- Is this still needed? */
#ifdef MA_WIN32
ma_CoUninitialize(pDevice->pContext);
#endif
return (ma_thread_result)0;
}
/* Helper for determining whether or not the given device is initialized. */
static ma_bool32 ma_device__is_initialized(ma_device* pDevice)
{
if (pDevice == NULL) {
return MA_FALSE;
}
return ma_device__get_state(pDevice) != MA_STATE_UNINITIALIZED;
}
#ifdef MA_WIN32
static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
{
ma_CoUninitialize(pContext);
ma_dlclose(pContext, pContext->win32.hUser32DLL);
ma_dlclose(pContext, pContext->win32.hOle32DLL);
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
return MA_SUCCESS;
}
static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
{
#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");
/* User32.dll */
pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
ma_data_converter_uninit(&pDecoder->converter);
return MA_SUCCESS;
}
MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor)
{
if (pCursor == NULL) {
return MA_INVALID_ARGS;
}
*pCursor = 0;
if (pDecoder == NULL) {
return MA_INVALID_ARGS;
}
*pCursor = pDecoder->readPointerInPCMFrames;
return MA_SUCCESS;
}
MA_API ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder)
{
if (pDecoder == NULL) {
return 0;
}
if (pDecoder->onGetLengthInPCMFrames) {
ma_uint64 nativeLengthInPCMFrames = pDecoder->onGetLengthInPCMFrames(pDecoder);
if (pDecoder->internalSampleRate == pDecoder->outputSampleRate) {
return nativeLengthInPCMFrames;
} else {
return ma_calculate_frame_count_after_resampling(pDecoder->outputSampleRate, pDecoder->internalSampleRate, nativeLengthInPCMFrames);
}
}
return 0;
}
MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
ma_result result;
ma_uint64 totalFramesReadOut;
ma_uint64 totalFramesReadIn;
void* pRunningFramesOut;
if (pDecoder == NULL) {
return 0;
}
if (pDecoder->onReadPCMFrames == NULL) {
return 0;
}
/* Fast path. */
if (pDecoder->converter.isPassthrough) {
totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, pFramesOut, frameCount);
} else {
/*
Getting here means we need to do data conversion. If we're seeking forward and are _not_ doing resampling we can run this in a fast path. If we're doing resampling we
need to run through each sample because we need to ensure it's internal cache is updated.
*/
if (pFramesOut == NULL && pDecoder->converter.hasResampler == MA_FALSE) {
totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, NULL, frameCount); /* All decoder backends must support passing in NULL for the output buffer. */
} else {
/* Slow path. Need to run everything through the data converter. */
totalFramesReadOut = 0;
totalFramesReadIn = 0;
pRunningFramesOut = pFramesOut;
while (totalFramesReadOut < frameCount) {
ma_uint8 pIntermediaryBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* In internal format. */
ma_uint64 intermediaryBufferCap = sizeof(pIntermediaryBuffer) / ma_get_bytes_per_frame(pDecoder->internalFormat, pDecoder->internalChannels);
ma_uint64 framesToReadThisIterationIn;
ma_uint64 framesReadThisIterationIn;
ma_uint64 framesToReadThisIterationOut;
ma_uint64 framesReadThisIterationOut;
ma_uint64 requiredInputFrameCount;
framesToReadThisIterationOut = (frameCount - totalFramesReadOut);
framesToReadThisIterationIn = framesToReadThisIterationOut;
if (framesToReadThisIterationIn > intermediaryBufferCap) {
framesToReadThisIterationIn = intermediaryBufferCap;
}
requiredInputFrameCount = ma_data_converter_get_required_input_frame_count(&pDecoder->converter, framesToReadThisIterationOut);
if (framesToReadThisIterationIn > requiredInputFrameCount) {
framesToReadThisIterationIn = requiredInputFrameCount;
}
if (requiredInputFrameCount > 0) {
framesReadThisIterationIn = pDecoder->onReadPCMFrames(pDecoder, pIntermediaryBuffer, framesToReadThisIterationIn);
totalFramesReadIn += framesReadThisIterationIn;
}
/*
At this point we have our decoded data in input format and now we need to convert to output format. Note that even if we didn't read any
input frames, we still want to try processing frames because there may some output frames generated from cached input data.
*/
framesReadThisIterationOut = framesToReadThisIterationOut;
result = ma_data_converter_process_pcm_frames(&pDecoder->converter, pIntermediaryBuffer, &framesReadThisIterationIn, pRunningFramesOut, &framesReadThisIterationOut);
if (result != MA_SUCCESS) {
break;
}
totalFramesReadOut += framesReadThisIterationOut;
if (pRunningFramesOut != NULL) {
pRunningFramesOut = ma_offset_ptr(pRunningFramesOut, framesReadThisIterationOut * ma_get_bytes_per_frame(pDecoder->outputFormat, pDecoder->outputChannels));
}
if (framesReadThisIterationIn == 0 && framesReadThisIterationOut == 0) {
break; /* We're done. */
}
}
}
}
pDecoder->readPointerInPCMFrames += totalFramesReadOut;
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 3);
pSamplesOut += 4;
}
} else {
while (pSamplesOut < pSamplesOutEnd) {
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;
}
riceParamPart0 &= riceParamMask;
riceParamPart1 &= riceParamMask;
riceParamPart2 &= riceParamMask;
riceParamPart3 &= riceParamMask;
riceParamPart0 |= (zeroCountPart0 << riceParam);
riceParamPart1 |= (zeroCountPart1 << riceParam);
riceParamPart2 |= (zeroCountPart2 << riceParam);
riceParamPart3 |= (zeroCountPart3 << riceParam);
riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 1);
pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 2);
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 3);
pSamplesOut += 4;
}
}
i = (count & ~3);
while (i < count) {
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) {
return DRFLAC_FALSE;
}
riceParamPart0 &= riceParamMask;
riceParamPart0 |= (zeroCountPart0 << riceParam);
riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
if (bitsPerSample+shift > 32) {
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0);
} else {
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
}
i += 1;
pSamplesOut += 1;
}
return DRFLAC_TRUE;
}
#if defined(DRFLAC_SUPPORT_SSE2)
static DRFLAC_INLINE __m128i drflac__mm_packs_interleaved_epi32(__m128i a, __m128i b)
{
__m128i r;
r = _mm_packs_epi32(a, b);
r = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 1, 2, 0));
r = _mm_shufflehi_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
r = _mm_shufflelo_epi16(r, _MM_SHUFFLE(3, 1, 2, 0));
return r;
}
#endif
#if defined(DRFLAC_SUPPORT_SSE41)
static DRFLAC_INLINE __m128i drflac__mm_not_si128(__m128i a)
{
return _mm_xor_si128(a, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()));
}
static DRFLAC_INLINE __m128i drflac__mm_hadd_epi32(__m128i x)
{
__m128i x64 = _mm_add_epi32(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i x32 = _mm_shufflelo_epi16(x64, _MM_SHUFFLE(1, 0, 3, 2));
return _mm_add_epi32(x64, x32);
}
static DRFLAC_INLINE __m128i drflac__mm_hadd_epi64(__m128i x)
{
return _mm_add_epi64(x, _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)));
}
static DRFLAC_INLINE __m128i drflac__mm_srai_epi64(__m128i x, int count)
{
__m128i lo = _mm_srli_epi64(x, count);
__m128i hi = _mm_srai_epi32(x, count);
hi = _mm_and_si128(hi, _mm_set_epi32(0xFFFFFFFF, 0, 0xFFFFFFFF, 0));
return _mm_or_si128(lo, hi);
}
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)
{
int i;
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;
__m128i coefficients128_0;
__m128i coefficients128_4;
__m128i coefficients128_8;
__m128i samples128_0;
__m128i samples128_4;
__m128i samples128_8;
__m128i riceParamMask128;
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
riceParamMask128 = _mm_set1_epi32(riceParamMask);
coefficients128_0 = _mm_setzero_si128();
coefficients128_4 = _mm_setzero_si128();
coefficients128_8 = _mm_setzero_si128();
samples128_0 = _mm_setzero_si128();
samples128_4 = _mm_setzero_si128();
samples128_8 = _mm_setzero_si128();
#if 1
{
int runningOrder = order;
if (runningOrder >= 4) {
coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
}
if (runningOrder >= 4) {
coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
}
runningOrder = 0;
}
if (runningOrder == 4) {
coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
}
runningOrder = 0;
}
coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
}
#else
switch (order)
{
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];
}
#endif
while (pDecodedSamples < pDecodedSamplesEnd) {
__m128i prediction128;
__m128i zeroCountPart128;
__m128i riceParamPart128;
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;
}
zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
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)));
if (order <= 4) {
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_mullo_epi32(coefficients128_0, samples128_0);
prediction128 = drflac__mm_hadd_epi32(prediction128);
prediction128 = _mm_srai_epi32(prediction128, shift);
prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
}
} else if (order <= 8) {
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_mullo_epi32(coefficients128_4, samples128_4);
prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
prediction128 = drflac__mm_hadd_epi32(prediction128);
prediction128 = _mm_srai_epi32(prediction128, shift);
prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
}
} else {
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_mullo_epi32(coefficients128_8, samples128_8);
prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_4, samples128_4));
prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
prediction128 = drflac__mm_hadd_epi32(prediction128);
prediction128 = _mm_srai_epi32(prediction128, shift);
prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
}
}
_mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
pDecodedSamples += 4;
}
i = (count & ~3);
while (i < (int)count) {
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
return DRFLAC_FALSE;
}
riceParamParts0 &= riceParamMask;
riceParamParts0 |= (zeroCountParts0 << riceParam);
riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pDecodedSamples);
i += 1;
pDecodedSamples += 1;
}
return DRFLAC_TRUE;
}
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)
{
int i;
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;
share/public_html/static/music_inc/src/miniaudio.h view on Meta::CPAN
runningOrder = 0;
}
if (runningOrder >= 4) {
coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
}
runningOrder = 0;
}
if (runningOrder == 4) {
coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
}
runningOrder = 0;
}
coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
}
#else
switch (order)
{
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];
}
#endif
while (pDecodedSamples < pDecodedSamplesEnd) {
__m128i zeroCountPart128;
__m128i riceParamPart128;
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;
}
zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
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)));
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_xor_si128(prediction128, prediction128);
switch (order)
{
case 12:
case 11: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(1, 1, 0, 0))));
case 10:
case 9: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(3, 3, 2, 2))));
case 8:
case 7: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(1, 1, 0, 0))));
case 6:
case 5: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(3, 3, 2, 2))));
case 4:
case 3: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(1, 1, 0, 0))));
case 2:
case 1: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(3, 3, 2, 2))));
}
prediction128 = drflac__mm_hadd_epi64(prediction128);
prediction128 = drflac__mm_srai_epi64(prediction128, shift);
prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
samples128_8 = _mm_alignr_epi8(samples128_4, samples128_8, 4);
samples128_4 = _mm_alignr_epi8(samples128_0, samples128_4, 4);
samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
}
_mm_storeu_si128((__m128i*)pDecodedSamples, samples128_0);
pDecodedSamples += 4;
}
i = (count & ~3);
while (i < (int)count) {
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) {
return DRFLAC_FALSE;
}
riceParamParts0 &= riceParamMask;
riceParamParts0 |= (zeroCountParts0 << riceParam);
riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01];
pDecodedSamples[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pDecodedSamples);
i += 1;
pDecodedSamples += 1;
}
return DRFLAC_TRUE;
}
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* p...
{
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
if (order > 0 && order <= 12) {
if (bitsPerSample+shift > 32) {
return drflac__decode_samples_with_residual__rice__sse41_64(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
} else {
return drflac__decode_samples_with_residual__rice__sse41_32(bs, count, riceParam, order, shift, coefficients, pSamplesOut);
}
} else {
return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
}
}
#endif
#if defined(DRFLAC_SUPPORT_NEON)
static DRFLAC_INLINE void drflac__vst2q_s32(drflac_int32* p, int32x4x2_t x)