123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- /* FAudio - XAudio Reimplementation for FNA
- *
- * Copyright (c) 2011-2021 Ethan Lee, Luigi Auriemma, and the MonoGame Team
- *
- * This software is provided 'as-is', without any express or implied warranty.
- * In no event will the authors be held liable for any damages arising from
- * the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software in a
- * product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any source distribution.
- *
- * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
- *
- */
- #include "FAudio.h"
- #include "FAPOBase.h"
- #include <stdarg.h>
- #ifdef FAUDIO_WIN32_PLATFORM
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #include <math.h>
- #include <assert.h>
- #include <inttypes.h>
- #include <windef.h>
- #include <winbase.h>
- #define FAudio_malloc malloc
- #define FAudio_realloc realloc
- #define FAudio_free free
- #define FAudio_alloca(x) alloca(x)
- #define FAudio_dealloca(x) (void)(x)
- #define FAudio_zero(ptr, size) memset(ptr, '\0', size)
- #define FAudio_memset(ptr, val, size) memset(ptr, val, size)
- #define FAudio_memcpy(dst, src, size) memcpy(dst, src, size)
- #define FAudio_memmove(dst, src, size) memmove(dst, src, size)
- #define FAudio_memcmp(ptr1, ptr2, size) memcmp(ptr1, ptr2, size)
- #define FAudio_strlen(ptr) strlen(ptr)
- #define FAudio_strcmp(str1, str2) strcmp(str1, str2)
- #define FAudio_strncmp(str1, str2, size) strncmp(str1, str2, size)
- #define FAudio_strlcpy(ptr1, ptr2, size) lstrcpynA(ptr1, ptr2, size)
- #define FAudio_pow(x, y) pow(x, y)
- #define FAudio_log(x) log(x)
- #define FAudio_log10(x) log10(x)
- #define FAudio_sin(x) sin(x)
- #define FAudio_cos(x) cos(x)
- #define FAudio_tan(x) tan(x)
- #define FAudio_acos(x) acos(x)
- #define FAudio_ceil(x) ceil(x)
- #define FAudio_floor(x) floor(x)
- #define FAudio_abs(x) abs(x)
- #define FAudio_ldexp(v, e) ldexp(v, e)
- #define FAudio_exp(x) exp(x)
- #define FAudio_cosf(x) cosf(x)
- #define FAudio_sinf(x) sinf(x)
- #define FAudio_sqrtf(x) sqrtf(x)
- #define FAudio_acosf(x) acosf(x)
- #define FAudio_atan2f(y, x) atan2f(y, x)
- #define FAudio_fabsf(x) fabsf(x)
- #define FAudio_qsort qsort
- #define FAudio_assert assert
- #define FAudio_snprintf snprintf
- #define FAudio_vsnprintf vsnprintf
- #define FAudio_getenv getenv
- #define FAudio_PRIu64 PRIu64
- #define FAudio_PRIx64 PRIx64
- extern void FAudio_Log(char const *msg);
- /* FIXME: Assuming little-endian! */
- #define FAudio_swap16LE(x) (x)
- #define FAudio_swap16BE(x) \
- ((x >> 8) & 0x00FF) | \
- ((x << 8) & 0xFF00)
- #define FAudio_swap32LE(x) (x)
- #define FAudio_swap32BE(x) \
- ((x >> 24) & 0x000000FF) | \
- ((x >> 8) & 0x0000FF00) | \
- ((x << 8) & 0x00FF0000) | \
- ((x << 24) & 0xFF000000)
- #define FAudio_swap64LE(x) (x)
- #define FAudio_swap64BE(x) \
- ((x >> 32) & 0x00000000000000FF) | \
- ((x >> 24) & 0x000000000000FF00) | \
- ((x >> 16) & 0x0000000000FF0000) | \
- ((x >> 8) & 0x00000000FF000000) | \
- ((x << 8) & 0x000000FF00000000) | \
- ((x << 16) & 0x0000FF0000000000) | \
- ((x << 24) & 0x00FF000000000000) | \
- ((x << 32) & 0xFF00000000000000)
- #else
- #include <SDL_stdinc.h>
- #include <SDL_assert.h>
- #include <SDL_endian.h>
- #include <SDL_log.h>
- #define FAudio_malloc SDL_malloc
- #define FAudio_realloc SDL_realloc
- #define FAudio_free SDL_free
- #define FAudio_alloca(x) SDL_stack_alloc(uint8_t, x)
- #define FAudio_dealloca(x) SDL_stack_free(x)
- #define FAudio_zero(ptr, size) SDL_memset(ptr, '\0', size)
- #define FAudio_memset(ptr, val, size) SDL_memset(ptr, val, size)
- #define FAudio_memcpy(dst, src, size) SDL_memcpy(dst, src, size)
- #define FAudio_memmove(dst, src, size) SDL_memmove(dst, src, size)
- #define FAudio_memcmp(ptr1, ptr2, size) SDL_memcmp(ptr1, ptr2, size)
- #define FAudio_strlen(ptr) SDL_strlen(ptr)
- #define FAudio_strcmp(str1, str2) SDL_strcmp(str1, str2)
- #define FAudio_strncmp(str1, str2, size) SDL_strncmp(str1, str1, size)
- #define FAudio_strlcpy(ptr1, ptr2, size) SDL_strlcpy(ptr1, ptr2, size)
- #define FAudio_pow(x, y) SDL_pow(x, y)
- #define FAudio_log(x) SDL_log(x)
- #define FAudio_log10(x) SDL_log10(x)
- #define FAudio_sin(x) SDL_sin(x)
- #define FAudio_cos(x) SDL_cos(x)
- #define FAudio_tan(x) SDL_tan(x)
- #define FAudio_acos(x) SDL_acos(x)
- #define FAudio_ceil(x) SDL_ceil(x)
- #define FAudio_floor(x) SDL_floor(x)
- #define FAudio_abs(x) SDL_abs(x)
- #define FAudio_ldexp(v, e) SDL_scalbn(v, e)
- #define FAudio_exp(x) SDL_exp(x)
- #define FAudio_cosf(x) SDL_cosf(x)
- #define FAudio_sinf(x) SDL_sinf(x)
- #define FAudio_sqrtf(x) SDL_sqrtf(x)
- #define FAudio_acosf(x) SDL_acosf(x)
- #define FAudio_atan2f(y, x) SDL_atan2f(y, x)
- #define FAudio_fabsf(x) SDL_fabsf(x)
- #define FAudio_qsort SDL_qsort
- #ifdef FAUDIO_LOG_ASSERTIONS
- #define FAudio_assert(condition) \
- { \
- static uint8_t logged = 0; \
- if (!(condition) && !logged) \
- { \
- SDL_Log("Assertion failed: %s", #condition); \
- logged = 1; \
- } \
- }
- #else
- #define FAudio_assert SDL_assert
- #endif
- #define FAudio_snprintf SDL_snprintf
- #define FAudio_vsnprintf SDL_vsnprintf
- #define FAudio_Log(msg) SDL_Log("%s", msg)
- #define FAudio_getenv SDL_getenv
- #define FAudio_PRIu64 SDL_PRIu64
- #define FAudio_PRIx64 SDL_PRIx64
- #define FAudio_swap16LE(x) SDL_SwapLE16(x)
- #define FAudio_swap16BE(x) SDL_SwapBE16(x)
- #define FAudio_swap32LE(x) SDL_SwapLE32(x)
- #define FAudio_swap32BE(x) SDL_SwapBE32(x)
- #define FAudio_swap64LE(x) SDL_SwapLE64(x)
- #define FAudio_swap64BE(x) SDL_SwapBE64(x)
- #endif
- /* Easy Macros */
- #define FAudio_min(val1, val2) \
- (val1 < val2 ? val1 : val2)
- #define FAudio_max(val1, val2) \
- (val1 > val2 ? val1 : val2)
- #define FAudio_clamp(val, min, max) \
- (val > max ? max : (val < min ? min : val))
- /* Windows/Visual Studio cruft */
- #ifdef _WIN32
- #ifdef __cplusplus
- /* C++ should have `inline`, but not `restrict` */
- #define restrict
- #else
- #define inline __inline
- #if defined(_MSC_VER)
- #if (_MSC_VER >= 1700) /* VS2012+ */
- #define restrict __restrict
- #else /* VS2010- */
- #define restrict
- #endif
- #else
- #define restrict
- #endif
- #endif
- #endif
- /* C++ does not have restrict (though VS2012+ does have __restrict) */
- #if defined(__cplusplus) && !defined(restrict)
- #define restrict
- #endif
- /* Threading Types */
- typedef void* FAudioThread;
- typedef void* FAudioMutex;
- typedef int32_t (FAUDIOCALL * FAudioThreadFunc)(void* data);
- typedef enum FAudioThreadPriority
- {
- FAUDIO_THREAD_PRIORITY_LOW,
- FAUDIO_THREAD_PRIORITY_NORMAL,
- FAUDIO_THREAD_PRIORITY_HIGH,
- } FAudioThreadPriority;
- /* Linked Lists */
- typedef struct LinkedList LinkedList;
- struct LinkedList
- {
- void* entry;
- LinkedList *next;
- };
- void LinkedList_AddEntry(
- LinkedList **start,
- void* toAdd,
- FAudioMutex lock,
- FAudioMallocFunc pMalloc
- );
- void LinkedList_PrependEntry(
- LinkedList **start,
- void* toAdd,
- FAudioMutex lock,
- FAudioMallocFunc pMalloc
- );
- void LinkedList_RemoveEntry(
- LinkedList **start,
- void* toRemove,
- FAudioMutex lock,
- FAudioFreeFunc pFree
- );
- /* Internal FAudio Types */
- typedef enum FAudioVoiceType
- {
- FAUDIO_VOICE_SOURCE,
- FAUDIO_VOICE_SUBMIX,
- FAUDIO_VOICE_MASTER
- } FAudioVoiceType;
- typedef struct FAudioBufferEntry FAudioBufferEntry;
- struct FAudioBufferEntry
- {
- FAudioBuffer buffer;
- FAudioBufferWMA bufferWMA;
- FAudioBufferEntry *next;
- };
- typedef void (FAUDIOCALL * FAudioDecodeCallback)(
- FAudioVoice *voice,
- FAudioBuffer *buffer, /* Buffer to decode */
- float *decodeCache, /* Decode into here */
- uint32_t samples /* Samples to decode */
- );
- typedef void (FAUDIOCALL * FAudioResampleCallback)(
- float *restrict dCache,
- float *restrict resampleCache,
- uint64_t *resampleOffset,
- uint64_t resampleStep,
- uint64_t toResample,
- uint8_t channels
- );
- typedef void (FAUDIOCALL * FAudioMixCallback)(
- uint32_t toMix,
- uint32_t srcChans,
- uint32_t dstChans,
- float *restrict srcData,
- float *restrict dstData,
- float *restrict coefficients
- );
- typedef float FAudioFilterState[4];
- /* Operation Sets, original implementation by Tyler Glaiel */
- typedef struct FAudio_OPERATIONSET_Operation FAudio_OPERATIONSET_Operation;
- void FAudio_OPERATIONSET_Commit(FAudio *audio, uint32_t OperationSet);
- void FAudio_OPERATIONSET_CommitAll(FAudio *audio);
- void FAudio_OPERATIONSET_Execute(FAudio *audio);
- void FAudio_OPERATIONSET_ClearAll(FAudio *audio);
- void FAudio_OPERATIONSET_ClearAllForVoice(FAudioVoice *voice);
- void FAudio_OPERATIONSET_QueueEnableEffect(
- FAudioVoice *voice,
- uint32_t EffectIndex,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueDisableEffect(
- FAudioVoice *voice,
- uint32_t EffectIndex,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetEffectParameters(
- FAudioVoice *voice,
- uint32_t EffectIndex,
- const void *pParameters,
- uint32_t ParametersByteSize,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetFilterParameters(
- FAudioVoice *voice,
- const FAudioFilterParameters *pParameters,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetOutputFilterParameters(
- FAudioVoice *voice,
- FAudioVoice *pDestinationVoice,
- const FAudioFilterParameters *pParameters,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetVolume(
- FAudioVoice *voice,
- float Volume,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetChannelVolumes(
- FAudioVoice *voice,
- uint32_t Channels,
- const float *pVolumes,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetOutputMatrix(
- FAudioVoice *voice,
- FAudioVoice *pDestinationVoice,
- uint32_t SourceChannels,
- uint32_t DestinationChannels,
- const float *pLevelMatrix,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueStart(
- FAudioSourceVoice *voice,
- uint32_t Flags,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueStop(
- FAudioSourceVoice *voice,
- uint32_t Flags,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueExitLoop(
- FAudioSourceVoice *voice,
- uint32_t OperationSet
- );
- void FAudio_OPERATIONSET_QueueSetFrequencyRatio(
- FAudioSourceVoice *voice,
- float Ratio,
- uint32_t OperationSet
- );
- /* Public FAudio Types */
- struct FAudio
- {
- uint8_t version;
- uint8_t active;
- uint32_t refcount;
- uint32_t initFlags;
- uint32_t updateSize;
- FAudioMasteringVoice *master;
- LinkedList *sources;
- LinkedList *submixes;
- LinkedList *callbacks;
- FAudioMutex sourceLock;
- FAudioMutex submixLock;
- FAudioMutex callbackLock;
- FAudioMutex operationLock;
- FAudioWaveFormatExtensible mixFormat;
- FAudio_OPERATIONSET_Operation *queuedOperations;
- FAudio_OPERATIONSET_Operation *committedOperations;
- /* Used to prevent destroying an active voice */
- FAudioSourceVoice *processingSource;
- /* Temp storage for processing, interleaved PCM32F */
- #define EXTRA_DECODE_PADDING 2
- uint32_t decodeSamples;
- uint32_t resampleSamples;
- uint32_t effectChainSamples;
- float *decodeCache;
- float *resampleCache;
- float *effectChainCache;
- /* Allocator callbacks */
- FAudioMallocFunc pMalloc;
- FAudioFreeFunc pFree;
- FAudioReallocFunc pRealloc;
- /* EngineProcedureEXT */
- void *clientEngineUser;
- FAudioEngineProcedureEXT pClientEngineProc;
- #ifndef FAUDIO_DISABLE_DEBUGCONFIGURATION
- /* Debug Information */
- FAudioDebugConfiguration debug;
- #endif /* FAUDIO_DISABLE_DEBUGCONFIGURATION */
- /* Platform opaque pointer */
- void *platform;
- };
- struct FAudioVoice
- {
- FAudio *audio;
- uint32_t flags;
- FAudioVoiceType type;
- FAudioVoiceSends sends;
- float **sendCoefficients;
- float **mixCoefficients;
- FAudioMixCallback *sendMix;
- FAudioFilterParameters *sendFilter;
- FAudioFilterState **sendFilterState;
- struct
- {
- FAPOBufferFlags state;
- uint32_t count;
- FAudioEffectDescriptor *desc;
- void **parameters;
- uint32_t *parameterSizes;
- uint8_t *parameterUpdates;
- uint8_t *inPlaceProcessing;
- } effects;
- FAudioFilterParameters filter;
- FAudioFilterState *filterState;
- FAudioMutex sendLock;
- FAudioMutex effectLock;
- FAudioMutex filterLock;
- float volume;
- float *channelVolume;
- uint32_t outputChannels;
- FAudioMutex volumeLock;
- FAUDIONAMELESS union
- {
- struct
- {
- /* Sample storage */
- uint32_t decodeSamples;
- uint32_t resampleSamples;
- /* Resampler */
- float resampleFreq;
- uint64_t resampleStep;
- uint64_t resampleOffset;
- uint64_t curBufferOffsetDec;
- uint32_t curBufferOffset;
- /* WMA decoding */
- #ifdef HAVE_WMADEC
- struct FAudioWMADEC *wmadec;
- #endif /* HAVE_WMADEC*/
- /* Read-only */
- float maxFreqRatio;
- FAudioWaveFormatEx *format;
- FAudioDecodeCallback decode;
- FAudioResampleCallback resample;
- FAudioVoiceCallback *callback;
- /* Dynamic */
- uint8_t active;
- float freqRatio;
- uint8_t newBuffer;
- uint64_t totalSamples;
- FAudioBufferEntry *bufferList;
- FAudioBufferEntry *flushList;
- FAudioMutex bufferLock;
- } src;
- struct
- {
- /* Sample storage */
- uint32_t inputSamples;
- uint32_t outputSamples;
- float *inputCache;
- uint64_t resampleStep;
- FAudioResampleCallback resample;
- /* Read-only */
- uint32_t inputChannels;
- uint32_t inputSampleRate;
- uint32_t processingStage;
- } mix;
- struct
- {
- /* Output stream, allocated by Platform */
- float *output;
- /* Needed when inputChannels != outputChannels */
- float *effectCache;
- /* Read-only */
- uint32_t inputChannels;
- uint32_t inputSampleRate;
- } master;
- };
- };
- /* Internal Functions */
- void FAudio_INTERNAL_InsertSubmixSorted(
- LinkedList **start,
- FAudioSubmixVoice *toAdd,
- FAudioMutex lock,
- FAudioMallocFunc pMalloc
- );
- void FAudio_INTERNAL_UpdateEngine(FAudio *audio, float *output);
- void FAudio_INTERNAL_ResizeDecodeCache(FAudio *audio, uint32_t size);
- void FAudio_INTERNAL_AllocEffectChain(
- FAudioVoice *voice,
- const FAudioEffectChain *pEffectChain
- );
- void FAudio_INTERNAL_FreeEffectChain(FAudioVoice *voice);
- uint32_t FAudio_INTERNAL_VoiceOutputFrequency(
- FAudioVoice *voice,
- const FAudioVoiceSends *pSendList
- );
- extern const float FAUDIO_INTERNAL_MATRIX_DEFAULTS[8][8][64];
- /* Debug */
- #ifdef FAUDIO_DISABLE_DEBUGCONFIGURATION
- #define LOG_ERROR(engine, fmt, ...)
- #define LOG_WARNING(engine, fmt, ...)
- #define LOG_INFO(engine, fmt, ...)
- #define LOG_DETAIL(engine, fmt, ...)
- #define LOG_API_ENTER(engine)
- #define LOG_API_EXIT(engine)
- #define LOG_FUNC_ENTER(engine)
- #define LOG_FUNC_EXIT(engine)
- /* TODO: LOG_TIMING */
- #define LOG_MUTEX_CREATE(engine, mutex)
- #define LOG_MUTEX_DESTROY(engine, mutex)
- #define LOG_MUTEX_LOCK(engine, mutex)
- #define LOG_MUTEX_UNLOCK(engine, mutex)
- /* TODO: LOG_MEMORY */
- /* TODO: LOG_STREAMING */
- #define LOG_FORMAT(engine, waveFormat)
- #else
- #if defined(_MSC_VER)
- /* VC doesn't support __attribute__ at all, and there's no replacement for format. */
- void FAudio_INTERNAL_debug(
- FAudio *audio,
- const char *file,
- uint32_t line,
- const char *func,
- const char *fmt,
- ...
- );
- #if _MSC_VER <= 1700 /* <=2012 also doesn't support __func__ */
- #define __func__ __FUNCTION__
- #endif
- #else
- void FAudio_INTERNAL_debug(
- FAudio *audio,
- const char *file,
- uint32_t line,
- const char *func,
- const char *fmt,
- ...
- ) __attribute__((format(printf,5,6)));
- #endif
- void FAudio_INTERNAL_debug_fmt(
- FAudio *audio,
- const char *file,
- uint32_t line,
- const char *func,
- const FAudioWaveFormatEx *fmt
- );
- #define PRINT_DEBUG(engine, cond, type, fmt, ...) \
- if (engine->debug.TraceMask & FAUDIO_LOG_##cond) \
- { \
- FAudio_INTERNAL_debug( \
- engine, \
- __FILE__, \
- __LINE__, \
- __func__, \
- type ": " fmt, \
- __VA_ARGS__ \
- ); \
- }
- #define LOG_ERROR(engine, fmt, ...) PRINT_DEBUG(engine, ERRORS, "ERROR", fmt, __VA_ARGS__)
- #define LOG_WARNING(engine, fmt, ...) PRINT_DEBUG(engine, WARNINGS, "WARNING", fmt, __VA_ARGS__)
- #define LOG_INFO(engine, fmt, ...) PRINT_DEBUG(engine, INFO, "INFO", fmt, __VA_ARGS__)
- #define LOG_DETAIL(engine, fmt, ...) PRINT_DEBUG(engine, DETAIL, "DETAIL", fmt, __VA_ARGS__)
- #define LOG_API_ENTER(engine) PRINT_DEBUG(engine, API_CALLS, "API Enter", "%s", __func__)
- #define LOG_API_EXIT(engine) PRINT_DEBUG(engine, API_CALLS, "API Exit", "%s", __func__)
- #define LOG_FUNC_ENTER(engine) PRINT_DEBUG(engine, FUNC_CALLS, "FUNC Enter", "%s", __func__)
- #define LOG_FUNC_EXIT(engine) PRINT_DEBUG(engine, FUNC_CALLS, "FUNC Exit", "%s", __func__)
- /* TODO: LOG_TIMING */
- #define LOG_MUTEX_CREATE(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Create", "%p", mutex)
- #define LOG_MUTEX_DESTROY(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Destroy", "%p", mutex)
- #define LOG_MUTEX_LOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Lock", "%p", mutex)
- #define LOG_MUTEX_UNLOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Unlock", "%p", mutex)
- /* TODO: LOG_MEMORY */
- /* TODO: LOG_STREAMING */
- #define LOG_FORMAT(engine, waveFormat) \
- if (engine->debug.TraceMask & FAUDIO_LOG_INFO) \
- { \
- FAudio_INTERNAL_debug_fmt( \
- engine, \
- __FILE__, \
- __LINE__, \
- __func__, \
- waveFormat \
- ); \
- }
- #endif /* FAUDIO_DISABLE_DEBUGCONFIGURATION */
- /* FAPOFX Creators */
- #define CREATE_FAPOFX_FUNC(effect) \
- extern uint32_t FAPOFXCreate##effect( \
- FAPO **pEffect, \
- const void *pInitData, \
- uint32_t InitDataByteSize, \
- FAudioMallocFunc customMalloc, \
- FAudioFreeFunc customFree, \
- FAudioReallocFunc customRealloc, \
- uint8_t legacy \
- );
- CREATE_FAPOFX_FUNC(EQ)
- CREATE_FAPOFX_FUNC(MasteringLimiter)
- CREATE_FAPOFX_FUNC(Reverb)
- CREATE_FAPOFX_FUNC(Echo)
- #undef CREATE_FAPOFX_FUNC
- /* SIMD Stuff */
- /* Callbacks declared as functions (rather than function pointers) are
- * scalar-only, for now. SIMD versions should be possible for these.
- */
- extern void (*FAudio_INTERNAL_Convert_U8_To_F32)(
- const uint8_t *restrict src,
- float *restrict dst,
- uint32_t len
- );
- extern void (*FAudio_INTERNAL_Convert_S16_To_F32)(
- const int16_t *restrict src,
- float *restrict dst,
- uint32_t len
- );
- extern void (*FAudio_INTERNAL_Convert_S32_To_F32)(
- const int32_t *restrict src,
- float *restrict dst,
- uint32_t len
- );
- extern FAudioResampleCallback FAudio_INTERNAL_ResampleMono;
- extern FAudioResampleCallback FAudio_INTERNAL_ResampleStereo;
- extern void FAudio_INTERNAL_ResampleGeneric(
- float *restrict dCache,
- float *restrict resampleCache,
- uint64_t *resampleOffset,
- uint64_t resampleStep,
- uint64_t toResample,
- uint8_t channels
- );
- extern void (*FAudio_INTERNAL_Amplify)(
- float *output,
- uint32_t totalSamples,
- float volume
- );
- extern FAudioMixCallback FAudio_INTERNAL_Mix_Generic;
- #define MIX_FUNC(type) \
- extern void FAudio_INTERNAL_Mix_##type##_Scalar( \
- uint32_t toMix, \
- uint32_t srcChans, \
- uint32_t dstChans, \
- float *restrict srcData, \
- float *restrict dstData, \
- float *restrict coefficients \
- );
- MIX_FUNC(Generic)
- MIX_FUNC(1in_1out)
- MIX_FUNC(1in_2out)
- MIX_FUNC(1in_6out)
- MIX_FUNC(1in_8out)
- MIX_FUNC(2in_1out)
- MIX_FUNC(2in_2out)
- MIX_FUNC(2in_6out)
- MIX_FUNC(2in_8out)
- #undef MIX_FUNC
- void FAudio_INTERNAL_InitSIMDFunctions(uint8_t hasSSE2, uint8_t hasNEON);
- /* Decoders */
- #define DECODE_FUNC(type) \
- extern void FAudio_INTERNAL_Decode##type( \
- FAudioVoice *voice, \
- FAudioBuffer *buffer, \
- float *decodeCache, \
- uint32_t samples \
- );
- DECODE_FUNC(PCM8)
- DECODE_FUNC(PCM16)
- DECODE_FUNC(PCM24)
- DECODE_FUNC(PCM32)
- DECODE_FUNC(PCM32F)
- DECODE_FUNC(MonoMSADPCM)
- DECODE_FUNC(StereoMSADPCM)
- DECODE_FUNC(WMAERROR)
- #undef DECODE_FUNC
- /* WMA decoding */
- #ifdef HAVE_WMADEC
- uint32_t FAudio_WMADEC_init(FAudioSourceVoice *pSourceVoice, uint32_t type);
- void FAudio_WMADEC_free(FAudioSourceVoice *voice);
- void FAudio_WMADEC_end_buffer(FAudioSourceVoice *voice);
- #endif /* HAVE_WMADEC */
- /* Platform Functions */
- void FAudio_PlatformAddRef(void);
- void FAudio_PlatformRelease(void);
- void FAudio_PlatformInit(
- FAudio *audio,
- uint32_t flags,
- uint32_t deviceIndex,
- FAudioWaveFormatExtensible *mixFormat,
- uint32_t *updateSize,
- void** platformDevice
- );
- void FAudio_PlatformQuit(void* platformDevice);
- uint32_t FAudio_PlatformGetDeviceCount(void);
- uint32_t FAudio_PlatformGetDeviceDetails(
- uint32_t index,
- FAudioDeviceDetails *details
- );
- /* Threading */
- FAudioThread FAudio_PlatformCreateThread(
- FAudioThreadFunc func,
- const char *name,
- void* data
- );
- void FAudio_PlatformWaitThread(FAudioThread thread, int32_t *retval);
- void FAudio_PlatformThreadPriority(FAudioThreadPriority priority);
- uint64_t FAudio_PlatformGetThreadID(void);
- FAudioMutex FAudio_PlatformCreateMutex(void);
- void FAudio_PlatformDestroyMutex(FAudioMutex mutex);
- void FAudio_PlatformLockMutex(FAudioMutex mutex);
- void FAudio_PlatformUnlockMutex(FAudioMutex mutex);
- void FAudio_sleep(uint32_t ms);
- /* Time */
- uint32_t FAudio_timems(void);
- /* WaveFormatExtensible Helpers */
- static inline uint32_t GetMask(uint16_t channels)
- {
- if (channels == 1) return SPEAKER_MONO;
- if (channels == 2) return SPEAKER_STEREO;
- if (channels == 3) return SPEAKER_2POINT1;
- if (channels == 4) return SPEAKER_QUAD;
- if (channels == 5) return SPEAKER_4POINT1;
- if (channels == 6) return SPEAKER_5POINT1;
- if (channels == 8) return SPEAKER_7POINT1;
- FAudio_assert(0 && "Unrecognized speaker layout!");
- return 0;
- }
- static inline void WriteWaveFormatExtensible(
- FAudioWaveFormatExtensible *fmt,
- int channels,
- int samplerate,
- const FAudioGUID *subformat
- ) {
- FAudio_assert(fmt != NULL);
- fmt->Format.wBitsPerSample = 32;
- fmt->Format.wFormatTag = FAUDIO_FORMAT_EXTENSIBLE;
- fmt->Format.nChannels = channels;
- fmt->Format.nSamplesPerSec = samplerate;
- fmt->Format.nBlockAlign = (
- fmt->Format.nChannels *
- (fmt->Format.wBitsPerSample / 8)
- );
- fmt->Format.nAvgBytesPerSec = (
- fmt->Format.nSamplesPerSec *
- fmt->Format.nBlockAlign
- );
- fmt->Format.cbSize = sizeof(FAudioWaveFormatExtensible) - sizeof(FAudioWaveFormatEx);
- fmt->Samples.wValidBitsPerSample = 32;
- fmt->dwChannelMask = GetMask(fmt->Format.nChannels);
- FAudio_memcpy(&fmt->SubFormat, subformat, sizeof(FAudioGUID));
- }
- /* Resampling */
- /* Okay, so here's what all this fixed-point goo is for:
- *
- * Inevitably you're going to run into weird sample rates,
- * both from WaveBank data and from pitch shifting changes.
- *
- * How we deal with this is by calculating a fixed "step"
- * value that steps from sample to sample at the speed needed
- * to get the correct output sample rate, and the offset
- * is stored as separate integer and fraction values.
- *
- * This allows us to do weird fractional steps between samples,
- * while at the same time not letting it drift off into death
- * thanks to floating point madness.
- *
- * Steps are stored in fixed-point with 32 bits for the fraction:
- *
- * 00000000000000000000000000000000 00000000000000000000000000000000
- * ^ Integer block (32) ^ Fraction block (32)
- *
- * For example, to get 1.5:
- * 00000000000000000000000000000001 10000000000000000000000000000000
- *
- * The Integer block works exactly like you'd expect.
- * The Fraction block is divided by the Integer's "One" value.
- * So, the above Fraction represented visually...
- * 1 << 31
- * -------
- * 1 << 32
- * ... which, simplified, is...
- * 1 << 0
- * ------
- * 1 << 1
- * ... in other words, 1 / 2, or 0.5.
- */
- #define FIXED_PRECISION 32
- #define FIXED_ONE (1LL << FIXED_PRECISION)
- /* Quick way to drop parts */
- #define FIXED_FRACTION_MASK (FIXED_ONE - 1)
- #define FIXED_INTEGER_MASK ~FIXED_FRACTION_MASK
- /* Helper macros to convert fixed to float */
- #define DOUBLE_TO_FIXED(dbl) \
- ((uint64_t) (dbl * FIXED_ONE + 0.5))
- #define FIXED_TO_DOUBLE(fxd) ( \
- (double) (fxd >> FIXED_PRECISION) + /* Integer part */ \
- ((fxd & FIXED_FRACTION_MASK) * (1.0 / FIXED_ONE)) /* Fraction part */ \
- )
- #define FIXED_TO_FLOAT(fxd) ( \
- (float) (fxd >> FIXED_PRECISION) + /* Integer part */ \
- ((fxd & FIXED_FRACTION_MASK) * (1.0f / FIXED_ONE)) /* Fraction part */ \
- )
- #ifdef FAUDIO_DUMP_VOICES
- /* File writing structure */
- typedef size_t (FAUDIOCALL * FAudio_writefunc)(
- void *data,
- const void *src,
- size_t size,
- size_t count
- );
- typedef size_t (FAUDIOCALL * FAudio_sizefunc)(
- void *data
- );
- typedef struct FAudioIOStreamOut
- {
- void *data;
- FAudio_readfunc read;
- FAudio_writefunc write;
- FAudio_seekfunc seek;
- FAudio_sizefunc size;
- FAudio_closefunc close;
- void *lock;
- } FAudioIOStreamOut;
- FAudioIOStreamOut* FAudio_fopen_out(const char *path, const char *mode);
- void FAudio_close_out(FAudioIOStreamOut *io);
- #endif /* FAUDIO_DUMP_VOICES */
- /* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|