From 3e4185435843d368a4f521a1f6f14362d6286e24 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 3 May 2024 16:07:08 +0200 Subject: [PATCH] faudio: Import upstream release 24.05. --- libs/faudio/include/FAudio.h | 7 +++- libs/faudio/src/FACT.c | 2 +- libs/faudio/src/FACT_internal.c | 4 +- libs/faudio/src/FAudio.c | 68 ++++++++++++++++++++++++++++++++- libs/faudio/src/FAudio_internal.c | 2 +- libs/faudio/src/FAudio_internal.h | 28 +++++++++++--- libs/faudio/src/FAudio_internal_simd.c | 22 +++++------ libs/faudio/src/FAudio_platform_win32.c | 10 ++++- 8 files changed, 118 insertions(+), 25 deletions(-) diff --git a/libs/faudio/include/FAudio.h b/libs/faudio/include/FAudio.h index f87655888fa..afe81424d12 100644 --- a/libs/faudio/include/FAudio.h +++ b/libs/faudio/include/FAudio.h @@ -494,7 +494,7 @@ extern FAudioGUID DATAFORMAT_SUBTYPE_IEEE_FLOAT; #define FAUDIO_ABI_VERSION 0 #define FAUDIO_MAJOR_VERSION 24 -#define FAUDIO_MINOR_VERSION 2 +#define FAUDIO_MINOR_VERSION 5 #define FAUDIO_PATCH_VERSION 0 #define FAUDIO_COMPILED_VERSION ( \ @@ -1064,6 +1064,11 @@ FAUDIOAPI void FAudioVoice_GetOutputMatrix( /* Removes this voice from the audio graph and frees memory. */ FAUDIOAPI void FAudioVoice_DestroyVoice(FAudioVoice *voice); +/* + * Returns S_OK on success and E_FAIL if voice could not be destroyed (e. g., because it is in use). + */ +FAUDIOAPI uint32_t FAudioVoice_DestroyVoiceSafeEXT(FAudioVoice *voice); + /* FAudioSourceVoice Interface */ /* Starts processing for a source voice. diff --git a/libs/faudio/src/FACT.c b/libs/faudio/src/FACT.c index ae0c9b8f7d0..013cea36b5b 100644 --- a/libs/faudio/src/FACT.c +++ b/libs/faudio/src/FACT.c @@ -1239,7 +1239,7 @@ uint32_t FACTSoundBank_Prepare( break; } } - if ((*ppCue)->variation->flags == 3) + if ((*ppCue)->variation && (*ppCue)->variation->flags == 3) { (*ppCue)->interactive = pSoundBank->parentEngine->variables[ (*ppCue)->variation->variable diff --git a/libs/faudio/src/FACT_internal.c b/libs/faudio/src/FACT_internal.c index 8a0babdf54e..0f0e4f968d9 100644 --- a/libs/faudio/src/FACT_internal.c +++ b/libs/faudio/src/FACT_internal.c @@ -515,7 +515,7 @@ uint8_t FACT_INTERNAL_CreateSound(FACTCue *cue, uint16_t fadeInMS) /* Sound */ baseSound = cue->sound; } - else + else if (cue->variation) { /* Variation */ if (cue->variation->flags == 3) @@ -1662,7 +1662,7 @@ void FACT_INTERNAL_UpdateCue(FACTCue *cue) FACTSoundInstance *sound; /* Interactive sound selection */ - if (!(cue->data->flags & 0x04) && cue->variation->flags == 3) + if (!(cue->data->flags & 0x04) && cue->variation && cue->variation->flags == 3) { /* Interactive */ if (cue->parentBank->parentEngine->variables[cue->variation->variable].accessibility & 0x04) diff --git a/libs/faudio/src/FAudio.c b/libs/faudio/src/FAudio.c index 171df357bf2..8a4ad9a4b03 100644 --- a/libs/faudio/src/FAudio.c +++ b/libs/faudio/src/FAudio.c @@ -2265,11 +2265,71 @@ void FAudioVoice_GetOutputMatrix( LOG_API_EXIT(voice->audio) } -void FAudioVoice_DestroyVoice(FAudioVoice *voice) +static uint32_t check_for_sends_to_voice(FAudioVoice *voice) { + FAudio *audio = voice->audio; + uint32_t ret = 0; + FAudioSourceVoice *source; + FAudioSubmixVoice *submix; + LinkedList *list; uint32_t i; + + FAudio_PlatformLockMutex(audio->sourceLock); + list = audio->sources; + while (list != NULL) + { + source = (FAudioSourceVoice*) list->entry; + for (i = 0; i < source->sends.SendCount; i += 1) + if (source->sends.pSends[i].pOutputVoice == voice) + { + ret = 0x80004005; /* E_FAIL */ + break; + } + if (ret) + break; + list = list->next; + } + FAudio_PlatformUnlockMutex(audio->sourceLock); + + if (ret) + return ret; + + FAudio_PlatformLockMutex(audio->submixLock); + list = audio->submixes; + while (list != NULL) + { + submix = (FAudioSubmixVoice*) list->entry; + for (i = 0; i < submix->sends.SendCount; i += 1) + if (submix->sends.pSends[i].pOutputVoice == voice) + { + ret = 0x80004005; /* E_FAIL */ + break; + } + if (ret) + break; + list = list->next; + } + FAudio_PlatformUnlockMutex(audio->submixLock); + + return ret; +} + +uint32_t FAudioVoice_DestroyVoiceSafeEXT(FAudioVoice *voice) +{ + uint32_t i, ret; LOG_API_ENTER(voice->audio) + if ((ret = check_for_sends_to_voice(voice))) + { + LOG_ERROR( + voice->audio, + "Voice %p is an output for other voice(s)", + voice + ) + LOG_API_EXIT(voice->audio) + return ret; + } + /* TODO: Check for dependencies and remove from audio graph first! */ FAudio_OPERATIONSET_ClearAllForVoice(voice); @@ -2443,6 +2503,12 @@ void FAudioVoice_DestroyVoice(FAudioVoice *voice) LOG_API_EXIT(voice->audio) FAudio_Release(voice->audio); voice->audio->pFree(voice); + return 0; +} + +void FAudioVoice_DestroyVoice(FAudioVoice *voice) +{ + FAudioVoice_DestroyVoiceSafeEXT(voice); } /* FAudioSourceVoice Interface */ diff --git a/libs/faudio/src/FAudio_internal.c b/libs/faudio/src/FAudio_internal.c index 7e29e85be4b..a20e003db3c 100644 --- a/libs/faudio/src/FAudio_internal.c +++ b/libs/faudio/src/FAudio_internal.c @@ -212,9 +212,9 @@ void LinkedList_RemoveEntry( FAudioFreeFunc pFree ) { LinkedList *latest, *prev; + FAudio_PlatformLockMutex(lock); latest = *start; prev = latest; - FAudio_PlatformLockMutex(lock); while (latest != NULL) { if (latest->entry == toRemove) diff --git a/libs/faudio/src/FAudio_internal.h b/libs/faudio/src/FAudio_internal.h index 35379984836..6c7623d82ca 100644 --- a/libs/faudio/src/FAudio_internal.h +++ b/libs/faudio/src/FAudio_internal.h @@ -37,8 +37,8 @@ #include #include -#include -#include +#define WIN32_LEAN_AND_MEAN +#include #define FAudio_malloc malloc #define FAudio_realloc realloc @@ -109,10 +109,17 @@ extern void FAudio_Log(char const *msg); ((x << 24) & 0x00FF000000000000) | \ ((x << 32) & 0xFF00000000000000) #else +#ifdef FAUDIO_SDL3_PLATFORM +#include +#include +#include +#include +#else #include #include #include #include +#endif #define FAudio_malloc SDL_malloc #define FAudio_realloc SDL_realloc @@ -212,6 +219,15 @@ extern void FAudio_Log(char const *msg); #define restrict #endif +/* Alignment macro for gcc/clang/msvc */ +#if defined(__clang__) || defined(__GNUC__) +#define ALIGN(type, boundary) type __attribute__((aligned(boundary))) +#elif defined(_MSC_VER) +#define ALIGN(type, boundary) __declspec(align(boundary)) type +#else +#define ALIGN(type, boundary) type +#endif + /* Threading Types */ typedef void* FAudioThread; @@ -620,10 +636,10 @@ void FAudio_INTERNAL_debug_fmt( #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) +#define LOG_MUTEX_CREATE(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Create", "%p (%s)", mutex, #mutex) +#define LOG_MUTEX_DESTROY(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Destroy", "%p (%s)", mutex, #mutex) +#define LOG_MUTEX_LOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Lock", "%p (%s)", mutex, #mutex) +#define LOG_MUTEX_UNLOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Unlock", "%p (%s)", mutex, #mutex) /* TODO: LOG_MEMORY */ /* TODO: LOG_STREAMING */ diff --git a/libs/faudio/src/FAudio_internal_simd.c b/libs/faudio/src/FAudio_internal_simd.c index b21d49ae77e..7b7997b2ad0 100644 --- a/libs/faudio/src/FAudio_internal_simd.c +++ b/libs/faudio/src/FAudio_internal_simd.c @@ -32,21 +32,21 @@ * https://hg.icculus.org/icculus/mojoAL/file/default/mojoal.c */ -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC) /* Some platforms fail to define this... */ - #ifndef __SSE2__ - #define __SSE2__ 1 + #ifndef __ARM_NEON__ + #define __ARM_NEON__ 1 #endif - /* x86_64 guarantees SSE2. */ + /* AArch64 guarantees NEON. */ #define NEED_SCALAR_CONVERTER_FALLBACKS 0 -#elif defined(__aarch64__) || defined(_M_ARM64) +#elif defined(__x86_64__) || defined(_M_X64) /* Some platforms fail to define this... */ - #ifndef __ARM_NEON__ - #define __ARM_NEON__ 1 + #ifndef __SSE2__ + #define __SSE2__ 1 #endif - /* AArch64 guarantees NEON. */ + /* x86_64 guarantees SSE2. */ #define NEED_SCALAR_CONVERTER_FALLBACKS 0 #elif __MACOSX__ && !defined(__POWERPC__) /* Some build systems may need to specify this. */ @@ -62,7 +62,7 @@ #endif /* Our NEON paths require AArch64, don't check __ARM_NEON__ here */ -#if defined(__aarch64__) || defined(_M_ARM64) +#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC) #include #define HAVE_NEON_INTRINSICS 1 #endif @@ -903,7 +903,7 @@ void FAudio_INTERNAL_ResampleMono_NEON( cur_frac = vdupq_n_s32( (uint32_t) (cur_scalar & FIXED_FRACTION_MASK) - DOUBLE_TO_FIXED(0.5) ); - int32_t __attribute__((aligned(16))) data[4] = + ALIGN(int32_t, 16) data[4] = { 0, (uint32_t) (resampleStep & FIXED_FRACTION_MASK), @@ -1077,7 +1077,7 @@ void FAudio_INTERNAL_ResampleStereo_NEON( cur_frac = vdupq_n_s32( (uint32_t) (cur_scalar & FIXED_FRACTION_MASK) - DOUBLE_TO_FIXED(0.5) ); - int32_t __attribute__((aligned(16))) data[4] = + ALIGN(int32_t, 16) data[4] = { 0, 0, diff --git a/libs/faudio/src/FAudio_platform_win32.c b/libs/faudio/src/FAudio_platform_win32.c index 01a3a84d5e0..5de6536a39b 100644 --- a/libs/faudio/src/FAudio_platform_win32.c +++ b/libs/faudio/src/FAudio_platform_win32.c @@ -210,8 +210,14 @@ void FAudio_PlatformInit( HRESULT hr; HANDLE audioEvent = NULL; BOOL has_sse2 = IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); - - FAudio_INTERNAL_InitSIMDFunctions(has_sse2, FALSE); +#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC) + BOOL has_neon = TRUE; +#elif defined(__arm__) || defined(_M_ARM) + BOOL has_neon = IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); +#else + BOOL has_neon = FALSE; +#endif + FAudio_INTERNAL_InitSIMDFunctions(has_sse2, has_neon); FAudio_resolve_SetThreadDescription(); FAudio_PlatformAddRef(); -- 2.11.4.GIT