mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Prep work for some SIMD optimizations.
This commit is contained in:
@@ -212,6 +212,7 @@ extern "C" {
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201) // nonstandard extension used: nameless struct/union
|
||||
#pragma warning(disable:4324) // structure was padded due to alignment specifier
|
||||
#endif
|
||||
|
||||
// Platform/backend detection.
|
||||
@@ -317,15 +318,47 @@ extern "C" {
|
||||
|
||||
#include <stddef.h> // For size_t.
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
#ifndef MAL_HAS_STDINT
|
||||
#if defined(_MSC_VER)
|
||||
#if _MSC_VER >= 1600
|
||||
#define MAL_HAS_STDINT
|
||||
#endif
|
||||
#else
|
||||
#if defined(__has_include) && __has_include(<stdint.h>)
|
||||
#define MAL_HAS_STDINT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAL_HAS_STDINT
|
||||
typedef signed char mal_int8;
|
||||
typedef unsigned char mal_uint8;
|
||||
typedef signed short mal_int16;
|
||||
typedef unsigned short mal_uint16;
|
||||
typedef signed int mal_int32;
|
||||
typedef unsigned int mal_uint32;
|
||||
#if defined(_MSC_VER)
|
||||
typedef signed __int64 mal_int64;
|
||||
typedef unsigned __int64 mal_uint64;
|
||||
#elif defined(__GNUC__)
|
||||
typedef signed long long int mal_int64;
|
||||
typedef unsigned long long int mal_uint64;
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN64)
|
||||
typedef mal_uint64 mal_uintptr;
|
||||
#else
|
||||
typedef mal_uint32 mal_uintptr;
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(__LP64__)
|
||||
typedef mal_uint64 mal_uintptr;
|
||||
#else
|
||||
typedef mal_uint32 mal_uintptr;
|
||||
#endif
|
||||
#else
|
||||
typedef mal_uint64 mal_uintptr; // Fallback.
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef int8_t mal_int8;
|
||||
@@ -336,6 +369,7 @@ typedef int32_t mal_int32;
|
||||
typedef uint32_t mal_uint32;
|
||||
typedef int64_t mal_int64;
|
||||
typedef uint64_t mal_uint64;
|
||||
typedef uintptr_t mal_uintptr;
|
||||
#endif
|
||||
typedef mal_uint8 mal_bool8;
|
||||
typedef mal_uint32 mal_bool32;
|
||||
@@ -349,6 +383,40 @@ typedef void (* mal_proc)();
|
||||
typedef struct mal_context mal_context;
|
||||
typedef struct mal_device mal_device;
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
|
||||
typedef mal_uint16 wchar_t;
|
||||
#endif
|
||||
|
||||
// Define NULL for some compilers.
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAL_INLINE __forceinline
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define MAL_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
#define MAL_INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAL_ALIGN(alignment) __declspec(align(alignment))
|
||||
#else
|
||||
#define MAL_ALIGN(alignment) __attribute__((aligned(alignment)))
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAL_ALIGNED_STRUCT(alignment) MAL_ALIGN(alignment) struct
|
||||
#else
|
||||
#define MAL_ALIGNED_STRUCT(alignment) struct MAL_ALIGN(alignment)
|
||||
#endif
|
||||
|
||||
// SIMD alignment in bytes. Currently set to 64 bytes in preparation for future AVX-512 optimizations.
|
||||
#define MAL_SIMD_ALIGNMENT 64
|
||||
|
||||
// Thread priorties should be ordered such that the default priority of the worker thread is 0.
|
||||
typedef enum
|
||||
{
|
||||
@@ -433,14 +501,6 @@ typedef struct
|
||||
};
|
||||
} mal_event;
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
|
||||
typedef mal_uint16 wchar_t;
|
||||
#endif
|
||||
|
||||
// Define NULL for some compilers.
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define MAL_MAX_PERIODS_DSOUND 4
|
||||
#define MAL_MAX_PERIODS_OPENAL 4
|
||||
@@ -757,15 +817,6 @@ typedef enum
|
||||
mal_src_algorithm_default = mal_src_algorithm_linear
|
||||
} mal_src_algorithm;
|
||||
|
||||
#define MAL_SRC_CACHE_SIZE_IN_FRAMES 256
|
||||
typedef struct
|
||||
{
|
||||
mal_src* pSRC;
|
||||
float cachedFrames[MAL_MAX_CHANNELS][MAL_SRC_CACHE_SIZE_IN_FRAMES];
|
||||
mal_uint32 cachedFrameCount;
|
||||
mal_uint32 iNextFrame;
|
||||
} mal_src_cache;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mal_uint32 sampleRateIn;
|
||||
@@ -776,16 +827,15 @@ typedef struct
|
||||
void* pUserData;
|
||||
} mal_src_config;
|
||||
|
||||
struct mal_src
|
||||
MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_src
|
||||
{
|
||||
float samplesFromClient[MAL_MAX_CHANNELS][256];
|
||||
mal_src_config config;
|
||||
float bin[MAL_MAX_CHANNELS][32];
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float samplesFromClient[MAL_MAX_CHANNELS][256];
|
||||
float t;
|
||||
mal_uint32 leftoverFrames;
|
||||
} linear;
|
||||
@@ -812,7 +862,7 @@ typedef struct
|
||||
void* pUserData;
|
||||
} mal_dsp_config;
|
||||
|
||||
struct mal_dsp
|
||||
MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_dsp
|
||||
{
|
||||
mal_dsp_read_proc onRead;
|
||||
void* pUserData;
|
||||
@@ -1234,7 +1284,7 @@ struct mal_context
|
||||
};
|
||||
};
|
||||
|
||||
struct mal_device
|
||||
MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device
|
||||
{
|
||||
mal_context* pContext;
|
||||
mal_device_type type;
|
||||
@@ -1705,7 +1755,7 @@ mal_uint32 mal_device_get_buffer_size_in_bytes(mal_device* pDevice);
|
||||
// Thread Safety: SAFE
|
||||
// This is API is pure.
|
||||
mal_uint32 mal_get_bytes_per_sample(mal_format format);
|
||||
static inline mal_uint32 mal_get_bytes_per_frame(mal_format format, mal_uint32 channels) { return mal_get_bytes_per_sample(format) * channels; }
|
||||
static MAL_INLINE mal_uint32 mal_get_bytes_per_frame(mal_format format, mal_uint32 channels) { return mal_get_bytes_per_sample(format) * channels; }
|
||||
|
||||
// Helper function for initializing a mal_context_config object.
|
||||
mal_context_config mal_context_config_init(mal_log_proc onLog);
|
||||
@@ -1789,15 +1839,15 @@ mal_device_config mal_device_config_init_default_playback(mal_send_proc onSendCa
|
||||
mal_device_config mal_device_config_init_ex(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_channel channelMap[MAL_MAX_CHANNELS], mal_recv_proc onRecvCallback, mal_send_proc onSendCallback);
|
||||
|
||||
// A simplified version of mal_device_config_init_ex().
|
||||
static inline mal_device_config mal_device_config_init(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_recv_proc onRecvCallback, mal_send_proc onSendCallback) { return mal_device_config_init_ex(format, channels, sampleRate, NULL, onRecvCallback, onSendCallback); }
|
||||
static MAL_INLINE mal_device_config mal_device_config_init(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_recv_proc onRecvCallback, mal_send_proc onSendCallback) { return mal_device_config_init_ex(format, channels, sampleRate, NULL, onRecvCallback, onSendCallback); }
|
||||
|
||||
// A simplified version of mal_device_config_init() for capture devices.
|
||||
static inline mal_device_config mal_device_config_init_capture_ex(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_channel channelMap[MAL_MAX_CHANNELS], mal_recv_proc onRecvCallback) { return mal_device_config_init_ex(format, channels, sampleRate, channelMap, onRecvCallback, NULL); }
|
||||
static inline mal_device_config mal_device_config_init_capture(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_recv_proc onRecvCallback) { return mal_device_config_init_capture_ex(format, channels, sampleRate, NULL, onRecvCallback); }
|
||||
static MAL_INLINE mal_device_config mal_device_config_init_capture_ex(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_channel channelMap[MAL_MAX_CHANNELS], mal_recv_proc onRecvCallback) { return mal_device_config_init_ex(format, channels, sampleRate, channelMap, onRecvCallback, NULL); }
|
||||
static MAL_INLINE mal_device_config mal_device_config_init_capture(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_recv_proc onRecvCallback) { return mal_device_config_init_capture_ex(format, channels, sampleRate, NULL, onRecvCallback); }
|
||||
|
||||
// A simplified version of mal_device_config_init() for playback devices.
|
||||
static inline mal_device_config mal_device_config_init_playback_ex(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_channel channelMap[MAL_MAX_CHANNELS], mal_send_proc onSendCallback) { return mal_device_config_init_ex(format, channels, sampleRate, channelMap, NULL, onSendCallback); }
|
||||
static inline mal_device_config mal_device_config_init_playback(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_send_proc onSendCallback) { return mal_device_config_init_playback_ex(format, channels, sampleRate, NULL, onSendCallback); }
|
||||
static MAL_INLINE mal_device_config mal_device_config_init_playback_ex(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_channel channelMap[MAL_MAX_CHANNELS], mal_send_proc onSendCallback) { return mal_device_config_init_ex(format, channels, sampleRate, channelMap, NULL, onSendCallback); }
|
||||
static MAL_INLINE mal_device_config mal_device_config_init_playback(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_send_proc onSendCallback) { return mal_device_config_init_playback_ex(format, channels, sampleRate, NULL, onSendCallback); }
|
||||
|
||||
|
||||
// Helper for retrieving a standard channel map.
|
||||
@@ -2033,6 +2083,12 @@ void mal_mutex_unlock(mal_mutex* pMutex);
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Performs an aligned malloc, with the assumption that the alignment is a power of 2.
|
||||
void* mal_aligned_malloc(size_t sz, size_t alignment);
|
||||
|
||||
// Free's an aligned malloc'd buffer.
|
||||
void mal_aligned_free(void* p);
|
||||
|
||||
// Retrieves a friendly name for a backend.
|
||||
const char* mal_get_backend_name(mal_backend backend);
|
||||
|
||||
@@ -2680,7 +2736,7 @@ int mal_strcmp(const char* str1, const char* str2)
|
||||
|
||||
|
||||
// Thanks to good old Bit Twiddling Hacks for this one: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
static inline unsigned int mal_next_power_of_2(unsigned int x)
|
||||
static MAL_INLINE unsigned int mal_next_power_of_2(unsigned int x)
|
||||
{
|
||||
x--;
|
||||
x |= x >> 1;
|
||||
@@ -2693,12 +2749,12 @@ static inline unsigned int mal_next_power_of_2(unsigned int x)
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline unsigned int mal_prev_power_of_2(unsigned int x)
|
||||
static MAL_INLINE unsigned int mal_prev_power_of_2(unsigned int x)
|
||||
{
|
||||
return mal_next_power_of_2(x) >> 1;
|
||||
}
|
||||
|
||||
static inline unsigned int mal_round_to_power_of_2(unsigned int x)
|
||||
static MAL_INLINE unsigned int mal_round_to_power_of_2(unsigned int x)
|
||||
{
|
||||
unsigned int prev = mal_prev_power_of_2(x);
|
||||
unsigned int next = mal_next_power_of_2(x);
|
||||
@@ -2712,14 +2768,14 @@ static inline unsigned int mal_round_to_power_of_2(unsigned int x)
|
||||
|
||||
|
||||
// Clamps an f32 sample to -1..1
|
||||
static inline float mal_clip_f32(float x)
|
||||
static MAL_INLINE float mal_clip_f32(float x)
|
||||
{
|
||||
if (x < -1) return -1;
|
||||
if (x > +1) return +1;
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline float mal_mix_f32(float x, float y, float a)
|
||||
static MAL_INLINE float mal_mix_f32(float x, float y, float a)
|
||||
{
|
||||
return x*(1-a) + y*a;
|
||||
}
|
||||
@@ -3331,7 +3387,7 @@ mal_result mal_post_error(mal_device* pDevice, const char* message, mal_result r
|
||||
|
||||
|
||||
// The callback for reading from the client -> DSP -> device.
|
||||
static inline mal_uint32 mal_device__on_read_from_client(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
|
||||
mal_uint32 mal_device__on_read_from_client(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
|
||||
{
|
||||
(void)pDSP;
|
||||
|
||||
@@ -3347,7 +3403,7 @@ static inline mal_uint32 mal_device__on_read_from_client(mal_dsp* pDSP, mal_uint
|
||||
}
|
||||
|
||||
// The callback for reading from the device -> DSP -> client.
|
||||
static inline mal_uint32 mal_device__on_read_from_device(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
|
||||
mal_uint32 mal_device__on_read_from_device(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
|
||||
{
|
||||
(void)pDSP;
|
||||
|
||||
@@ -3373,7 +3429,7 @@ static inline mal_uint32 mal_device__on_read_from_device(mal_dsp* pDSP, mal_uint
|
||||
|
||||
// A helper function for reading sample data from the client. Returns the number of samples read from the client. Remaining samples
|
||||
// are filled with silence.
|
||||
static inline mal_uint32 mal_device__read_frames_from_client(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
|
||||
static MAL_INLINE mal_uint32 mal_device__read_frames_from_client(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
|
||||
{
|
||||
mal_assert(pDevice != NULL);
|
||||
mal_assert(frameCount > 0);
|
||||
@@ -3390,7 +3446,7 @@ static inline mal_uint32 mal_device__read_frames_from_client(mal_device* pDevice
|
||||
}
|
||||
|
||||
// A helper for sending sample data to the client.
|
||||
static inline void mal_device__send_frames_to_client(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples)
|
||||
static MAL_INLINE void mal_device__send_frames_to_client(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples)
|
||||
{
|
||||
mal_assert(pDevice != NULL);
|
||||
mal_assert(frameCount > 0);
|
||||
@@ -3420,13 +3476,13 @@ static inline void mal_device__send_frames_to_client(mal_device* pDevice, mal_ui
|
||||
}
|
||||
|
||||
// A helper for changing the state of the device.
|
||||
static inline void mal_device__set_state(mal_device* pDevice, mal_uint32 newState)
|
||||
static MAL_INLINE void mal_device__set_state(mal_device* pDevice, mal_uint32 newState)
|
||||
{
|
||||
mal_atomic_exchange_32(&pDevice->state, newState);
|
||||
}
|
||||
|
||||
// A helper for getting the state of the device.
|
||||
static inline mal_uint32 mal_device__get_state(mal_device* pDevice)
|
||||
static MAL_INLINE mal_uint32 mal_device__get_state(mal_device* pDevice)
|
||||
{
|
||||
return pDevice->state;
|
||||
}
|
||||
@@ -4047,7 +4103,7 @@ typedef struct
|
||||
#endif
|
||||
|
||||
// Some compilers don't define PropVariantInit(). We just do this ourselves since it's just a memset().
|
||||
static inline void mal_PropVariantInit(PROPVARIANT* pProp)
|
||||
static MAL_INLINE void mal_PropVariantInit(PROPVARIANT* pProp)
|
||||
{
|
||||
mal_zero_object(pProp);
|
||||
}
|
||||
@@ -17167,7 +17223,7 @@ typedef struct
|
||||
float z;
|
||||
} mal_vec3;
|
||||
|
||||
static inline mal_vec3 mal_vec3f(float x, float y, float z)
|
||||
static MAL_INLINE mal_vec3 mal_vec3f(float x, float y, float z)
|
||||
{
|
||||
mal_vec3 r;
|
||||
r.x = x;
|
||||
@@ -17177,7 +17233,7 @@ static inline mal_vec3 mal_vec3f(float x, float y, float z)
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline mal_vec3 mal_vec3_add(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE mal_vec3 mal_vec3_add(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return mal_vec3f(
|
||||
a.x + b.x,
|
||||
@@ -17186,7 +17242,7 @@ static inline mal_vec3 mal_vec3_add(mal_vec3 a, mal_vec3 b)
|
||||
);
|
||||
}
|
||||
|
||||
static inline mal_vec3 mal_vec3_sub(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE mal_vec3 mal_vec3_sub(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return mal_vec3f(
|
||||
a.x - b.x,
|
||||
@@ -17195,7 +17251,7 @@ static inline mal_vec3 mal_vec3_sub(mal_vec3 a, mal_vec3 b)
|
||||
);
|
||||
}
|
||||
|
||||
static inline mal_vec3 mal_vec3_mul(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE mal_vec3 mal_vec3_mul(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return mal_vec3f(
|
||||
a.x * b.x,
|
||||
@@ -17204,7 +17260,7 @@ static inline mal_vec3 mal_vec3_mul(mal_vec3 a, mal_vec3 b)
|
||||
);
|
||||
}
|
||||
|
||||
static inline mal_vec3 mal_vec3_div(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE mal_vec3 mal_vec3_div(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return mal_vec3f(
|
||||
a.x / b.x,
|
||||
@@ -17213,22 +17269,22 @@ static inline mal_vec3 mal_vec3_div(mal_vec3 a, mal_vec3 b)
|
||||
);
|
||||
}
|
||||
|
||||
static inline float mal_vec3_dot(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE float mal_vec3_dot(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
static inline float mal_vec3_length2(mal_vec3 a)
|
||||
static MAL_INLINE float mal_vec3_length2(mal_vec3 a)
|
||||
{
|
||||
return mal_vec3_dot(a, a);
|
||||
}
|
||||
|
||||
static inline float mal_vec3_length(mal_vec3 a)
|
||||
static MAL_INLINE float mal_vec3_length(mal_vec3 a)
|
||||
{
|
||||
return (float)sqrt(mal_vec3_length2(a));
|
||||
}
|
||||
|
||||
static inline mal_vec3 mal_vec3_normalize(mal_vec3 a)
|
||||
static MAL_INLINE mal_vec3 mal_vec3_normalize(mal_vec3 a)
|
||||
{
|
||||
float len = 1 / mal_vec3_length(a);
|
||||
|
||||
@@ -17240,7 +17296,7 @@ static inline mal_vec3 mal_vec3_normalize(mal_vec3 a)
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline float mal_vec3_distance(mal_vec3 a, mal_vec3 b)
|
||||
static MAL_INLINE float mal_vec3_distance(mal_vec3 a, mal_vec3 b)
|
||||
{
|
||||
return mal_vec3_length(mal_vec3_sub(a, b));
|
||||
}
|
||||
@@ -17855,7 +17911,7 @@ mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCou
|
||||
|
||||
float factor = (float)pSRC->config.sampleRateIn / pSRC->config.sampleRateOut;
|
||||
|
||||
mal_uint32 maxFrameCountPerChunkIn = mal_countof(pSRC->linear.samplesFromClient[0]);
|
||||
mal_uint32 maxFrameCountPerChunkIn = mal_countof(pSRC->samplesFromClient[0]);
|
||||
|
||||
mal_uint64 totalFramesRead = 0;
|
||||
while (totalFramesRead < frameCount) {
|
||||
@@ -17878,7 +17934,7 @@ mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCou
|
||||
|
||||
float* ppSamplesFromClient[MAL_MAX_CHANNELS];
|
||||
for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; ++iChannel) {
|
||||
ppSamplesFromClient[iChannel] = pSRC->linear.samplesFromClient[iChannel] + pSRC->linear.leftoverFrames;
|
||||
ppSamplesFromClient[iChannel] = pSRC->samplesFromClient[iChannel] + pSRC->linear.leftoverFrames;
|
||||
}
|
||||
|
||||
mal_uint32 framesReadFromClient = 0;
|
||||
@@ -17892,7 +17948,7 @@ mal_uint64 mal_src_read_deinterleaved__linear(mal_src* pSRC, mal_uint64 frameCou
|
||||
}
|
||||
|
||||
for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; ++iChannel) {
|
||||
ppSamplesFromClient[iChannel] = pSRC->linear.samplesFromClient[iChannel];
|
||||
ppSamplesFromClient[iChannel] = pSRC->samplesFromClient[iChannel];
|
||||
}
|
||||
|
||||
|
||||
@@ -18596,6 +18652,30 @@ mal_uint64 mal_convert_frames_ex(void* pOut, mal_format formatOut, mal_uint32 ch
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* mal_aligned_malloc(size_t sz, size_t alignment)
|
||||
{
|
||||
if (alignment == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t extraBytes = alignment-1 + sizeof(void*);
|
||||
|
||||
void* pUnaligned = mal_malloc(sz + extraBytes);
|
||||
if (pUnaligned == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* pAligned = (void*)(((mal_uintptr)pUnaligned + extraBytes) & ~((mal_uintptr)(alignment-1)));
|
||||
((void**)pAligned)[-1] = pUnaligned;
|
||||
|
||||
return pAligned;
|
||||
}
|
||||
|
||||
void mal_aligned_free(void* p)
|
||||
{
|
||||
mal_free(((void**)p)[-1]);
|
||||
}
|
||||
|
||||
const char* mal_get_backend_name(mal_backend backend)
|
||||
{
|
||||
switch (backend)
|
||||
|
||||
@@ -96,6 +96,158 @@ void* open_and_read_file_data(const char* filePath, size_t* pSizeOut)
|
||||
return pFileData;
|
||||
}
|
||||
|
||||
|
||||
int do_types_tests()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
int sizeof_int8 = sizeof(mal_int8);
|
||||
int sizeof_uint8 = sizeof(mal_uint8);
|
||||
int sizeof_int16 = sizeof(mal_int16);
|
||||
int sizeof_uint16 = sizeof(mal_uint16);
|
||||
int sizeof_int32 = sizeof(mal_int32);
|
||||
int sizeof_uint32 = sizeof(mal_uint32);
|
||||
int sizeof_int64 = sizeof(mal_int64);
|
||||
int sizeof_uint64 = sizeof(mal_uint64);
|
||||
int sizeof_float32 = sizeof(float);
|
||||
int sizeof_float64 = sizeof(double);
|
||||
int sizeof_uintptr = sizeof(mal_uintptr);
|
||||
|
||||
printf("sizeof(mal_int8) 1 = %d", sizeof_int8);
|
||||
if (sizeof_int8 != 1) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
printf("sizeof(mal_uint8) 1 = %d", sizeof_uint8);
|
||||
if (sizeof_uint8 != 1) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
printf("sizeof(mal_int16) 2 = %d", sizeof_int16);
|
||||
if (sizeof_int16 != 2) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
printf("sizeof(mal_uint16) 2 = %d", sizeof_uint16);
|
||||
if (sizeof_uint16 != 2) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
printf("sizeof(mal_int32) 4 = %d", sizeof_int32);
|
||||
if (sizeof_int32 != 4) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
printf("sizeof(mal_uint32) 4 = %d", sizeof_uint32);
|
||||
if (sizeof_uint32 != 4) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
printf("sizeof(mal_int64) 8 = %d", sizeof_int64);
|
||||
if (sizeof_int64 != 8) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
printf("sizeof(mal_uint64) 8 = %d", sizeof_uint64);
|
||||
if (sizeof_uint64 != 8) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
printf("sizeof(float) 4 = %d", sizeof_float32);
|
||||
if (sizeof_float32 != 4) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
printf("sizeof(double) 8 = %d", sizeof_float64);
|
||||
if (sizeof_float64 != 8) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
printf("sizeof(mal_uintptr) %d = %d", (int)sizeof(void*), sizeof_uintptr);
|
||||
if (sizeof_uintptr != sizeof(void*)) {
|
||||
printf(" - FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf(" - PASSED\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int do_aligned_malloc_tests()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
// We just do a whole bunch of malloc's and check them. This can probably be made more exhaustive.
|
||||
void* p[1024];
|
||||
for (mal_uint32 i = 0; i < mal_countof(p); ++i) {
|
||||
mal_uintptr alignment = MAL_SIMD_ALIGNMENT;
|
||||
|
||||
p[i] = mal_aligned_malloc(1024, alignment);
|
||||
if (((mal_uintptr)p[i] & (alignment-1)) != 0) {
|
||||
printf("FAILED\n");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Free.
|
||||
for (mal_uint32 i = 0; i < mal_countof(p); ++i) {
|
||||
mal_aligned_free(p[i]);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
printf("PASSED\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int do_core_tests()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
printf("Types...\n");
|
||||
if (do_types_tests() != 0) {
|
||||
printf("FAILED\n");
|
||||
result = -1;
|
||||
} else {
|
||||
printf("PASSED\n");
|
||||
}
|
||||
|
||||
printf("Aligned malloc... ");
|
||||
if (do_aligned_malloc_tests() != 0) {
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void* load_raw_audio_data(const char* filePath, mal_format format, mal_uint64* pBenchmarkFrameCount)
|
||||
{
|
||||
mal_assert(pBenchmarkFrameCount != NULL);
|
||||
@@ -2130,6 +2282,16 @@ int main(int argc, char** argv)
|
||||
mal_bool32 hasErrorOccurred = MAL_FALSE;
|
||||
int result = 0;
|
||||
|
||||
// Aligned malloc/free
|
||||
printf("=== TESTING CORE ===\n");
|
||||
result = do_core_tests();
|
||||
if (result < 0) {
|
||||
hasErrorOccurred = MAL_TRUE;
|
||||
}
|
||||
printf("=== END TESTING CORE ===\n");
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Format Conversion
|
||||
printf("=== TESTING FORMAT CONVERSION ===\n");
|
||||
result = do_format_conversion_tests();
|
||||
|
||||
Reference in New Issue
Block a user