Commit 3e418543 authored by Alexandre Julliard's avatar Alexandre Julliard

faudio: Import upstream release 24.05.

parent 17cbc13b
...@@ -494,7 +494,7 @@ extern FAudioGUID DATAFORMAT_SUBTYPE_IEEE_FLOAT; ...@@ -494,7 +494,7 @@ extern FAudioGUID DATAFORMAT_SUBTYPE_IEEE_FLOAT;
#define FAUDIO_ABI_VERSION 0 #define FAUDIO_ABI_VERSION 0
#define FAUDIO_MAJOR_VERSION 24 #define FAUDIO_MAJOR_VERSION 24
#define FAUDIO_MINOR_VERSION 2 #define FAUDIO_MINOR_VERSION 5
#define FAUDIO_PATCH_VERSION 0 #define FAUDIO_PATCH_VERSION 0
#define FAUDIO_COMPILED_VERSION ( \ #define FAUDIO_COMPILED_VERSION ( \
...@@ -1064,6 +1064,11 @@ FAUDIOAPI void FAudioVoice_GetOutputMatrix( ...@@ -1064,6 +1064,11 @@ FAUDIOAPI void FAudioVoice_GetOutputMatrix(
/* Removes this voice from the audio graph and frees memory. */ /* Removes this voice from the audio graph and frees memory. */
FAUDIOAPI void FAudioVoice_DestroyVoice(FAudioVoice *voice); 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 */ /* FAudioSourceVoice Interface */
/* Starts processing for a source voice. /* Starts processing for a source voice.
......
...@@ -1239,7 +1239,7 @@ uint32_t FACTSoundBank_Prepare( ...@@ -1239,7 +1239,7 @@ uint32_t FACTSoundBank_Prepare(
break; break;
} }
} }
if ((*ppCue)->variation->flags == 3) if ((*ppCue)->variation && (*ppCue)->variation->flags == 3)
{ {
(*ppCue)->interactive = pSoundBank->parentEngine->variables[ (*ppCue)->interactive = pSoundBank->parentEngine->variables[
(*ppCue)->variation->variable (*ppCue)->variation->variable
......
...@@ -515,7 +515,7 @@ uint8_t FACT_INTERNAL_CreateSound(FACTCue *cue, uint16_t fadeInMS) ...@@ -515,7 +515,7 @@ uint8_t FACT_INTERNAL_CreateSound(FACTCue *cue, uint16_t fadeInMS)
/* Sound */ /* Sound */
baseSound = cue->sound; baseSound = cue->sound;
} }
else else if (cue->variation)
{ {
/* Variation */ /* Variation */
if (cue->variation->flags == 3) if (cue->variation->flags == 3)
...@@ -1662,7 +1662,7 @@ void FACT_INTERNAL_UpdateCue(FACTCue *cue) ...@@ -1662,7 +1662,7 @@ void FACT_INTERNAL_UpdateCue(FACTCue *cue)
FACTSoundInstance *sound; FACTSoundInstance *sound;
/* Interactive sound selection */ /* Interactive sound selection */
if (!(cue->data->flags & 0x04) && cue->variation->flags == 3) if (!(cue->data->flags & 0x04) && cue->variation && cue->variation->flags == 3)
{ {
/* Interactive */ /* Interactive */
if (cue->parentBank->parentEngine->variables[cue->variation->variable].accessibility & 0x04) if (cue->parentBank->parentEngine->variables[cue->variation->variable].accessibility & 0x04)
......
...@@ -2265,11 +2265,71 @@ void FAudioVoice_GetOutputMatrix( ...@@ -2265,11 +2265,71 @@ void FAudioVoice_GetOutputMatrix(
LOG_API_EXIT(voice->audio) 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; 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) 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! */ /* TODO: Check for dependencies and remove from audio graph first! */
FAudio_OPERATIONSET_ClearAllForVoice(voice); FAudio_OPERATIONSET_ClearAllForVoice(voice);
...@@ -2443,6 +2503,12 @@ void FAudioVoice_DestroyVoice(FAudioVoice *voice) ...@@ -2443,6 +2503,12 @@ void FAudioVoice_DestroyVoice(FAudioVoice *voice)
LOG_API_EXIT(voice->audio) LOG_API_EXIT(voice->audio)
FAudio_Release(voice->audio); FAudio_Release(voice->audio);
voice->audio->pFree(voice); voice->audio->pFree(voice);
return 0;
}
void FAudioVoice_DestroyVoice(FAudioVoice *voice)
{
FAudioVoice_DestroyVoiceSafeEXT(voice);
} }
/* FAudioSourceVoice Interface */ /* FAudioSourceVoice Interface */
......
...@@ -212,9 +212,9 @@ void LinkedList_RemoveEntry( ...@@ -212,9 +212,9 @@ void LinkedList_RemoveEntry(
FAudioFreeFunc pFree FAudioFreeFunc pFree
) { ) {
LinkedList *latest, *prev; LinkedList *latest, *prev;
FAudio_PlatformLockMutex(lock);
latest = *start; latest = *start;
prev = latest; prev = latest;
FAudio_PlatformLockMutex(lock);
while (latest != NULL) while (latest != NULL)
{ {
if (latest->entry == toRemove) if (latest->entry == toRemove)
......
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
#include <assert.h> #include <assert.h>
#include <inttypes.h> #include <inttypes.h>
#include <windef.h> #define WIN32_LEAN_AND_MEAN
#include <winbase.h> #include <windows.h>
#define FAudio_malloc malloc #define FAudio_malloc malloc
#define FAudio_realloc realloc #define FAudio_realloc realloc
...@@ -109,10 +109,17 @@ extern void FAudio_Log(char const *msg); ...@@ -109,10 +109,17 @@ extern void FAudio_Log(char const *msg);
((x << 24) & 0x00FF000000000000) | \ ((x << 24) & 0x00FF000000000000) | \
((x << 32) & 0xFF00000000000000) ((x << 32) & 0xFF00000000000000)
#else #else
#ifdef FAUDIO_SDL3_PLATFORM
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_assert.h>
#include <SDL3/SDL_endian.h>
#include <SDL3/SDL_log.h>
#else
#include <SDL_stdinc.h> #include <SDL_stdinc.h>
#include <SDL_assert.h> #include <SDL_assert.h>
#include <SDL_endian.h> #include <SDL_endian.h>
#include <SDL_log.h> #include <SDL_log.h>
#endif
#define FAudio_malloc SDL_malloc #define FAudio_malloc SDL_malloc
#define FAudio_realloc SDL_realloc #define FAudio_realloc SDL_realloc
...@@ -212,6 +219,15 @@ extern void FAudio_Log(char const *msg); ...@@ -212,6 +219,15 @@ extern void FAudio_Log(char const *msg);
#define restrict #define restrict
#endif #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 */ /* Threading Types */
typedef void* FAudioThread; typedef void* FAudioThread;
...@@ -620,10 +636,10 @@ void FAudio_INTERNAL_debug_fmt( ...@@ -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_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__) #define LOG_FUNC_EXIT(engine) PRINT_DEBUG(engine, FUNC_CALLS, "FUNC Exit", "%s", __func__)
/* TODO: LOG_TIMING */ /* TODO: LOG_TIMING */
#define LOG_MUTEX_CREATE(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Create", "%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", 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", 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", mutex) #define LOG_MUTEX_UNLOCK(engine, mutex) PRINT_DEBUG(engine, LOCKS, "Mutex Unlock", "%p (%s)", mutex, #mutex)
/* TODO: LOG_MEMORY */ /* TODO: LOG_MEMORY */
/* TODO: LOG_STREAMING */ /* TODO: LOG_STREAMING */
......
...@@ -32,21 +32,21 @@ ...@@ -32,21 +32,21 @@
* https://hg.icculus.org/icculus/mojoAL/file/default/mojoal.c * 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... */ /* Some platforms fail to define this... */
#ifndef __SSE2__ #ifndef __ARM_NEON__
#define __SSE2__ 1 #define __ARM_NEON__ 1
#endif #endif
/* x86_64 guarantees SSE2. */ /* AArch64 guarantees NEON. */
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 #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... */ /* Some platforms fail to define this... */
#ifndef __ARM_NEON__ #ifndef __SSE2__
#define __ARM_NEON__ 1 #define __SSE2__ 1
#endif #endif
/* AArch64 guarantees NEON. */ /* x86_64 guarantees SSE2. */
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 #define NEED_SCALAR_CONVERTER_FALLBACKS 0
#elif __MACOSX__ && !defined(__POWERPC__) #elif __MACOSX__ && !defined(__POWERPC__)
/* Some build systems may need to specify this. */ /* Some build systems may need to specify this. */
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
#endif #endif
/* Our NEON paths require AArch64, don't check __ARM_NEON__ here */ /* 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 <arm_neon.h> #include <arm_neon.h>
#define HAVE_NEON_INTRINSICS 1 #define HAVE_NEON_INTRINSICS 1
#endif #endif
...@@ -903,7 +903,7 @@ void FAudio_INTERNAL_ResampleMono_NEON( ...@@ -903,7 +903,7 @@ void FAudio_INTERNAL_ResampleMono_NEON(
cur_frac = vdupq_n_s32( cur_frac = vdupq_n_s32(
(uint32_t) (cur_scalar & FIXED_FRACTION_MASK) - DOUBLE_TO_FIXED(0.5) (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,
(uint32_t) (resampleStep & FIXED_FRACTION_MASK), (uint32_t) (resampleStep & FIXED_FRACTION_MASK),
...@@ -1077,7 +1077,7 @@ void FAudio_INTERNAL_ResampleStereo_NEON( ...@@ -1077,7 +1077,7 @@ void FAudio_INTERNAL_ResampleStereo_NEON(
cur_frac = vdupq_n_s32( cur_frac = vdupq_n_s32(
(uint32_t) (cur_scalar & FIXED_FRACTION_MASK) - DOUBLE_TO_FIXED(0.5) (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,
0, 0,
......
...@@ -210,8 +210,14 @@ void FAudio_PlatformInit( ...@@ -210,8 +210,14 @@ void FAudio_PlatformInit(
HRESULT hr; HRESULT hr;
HANDLE audioEvent = NULL; HANDLE audioEvent = NULL;
BOOL has_sse2 = IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); BOOL has_sse2 = IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC)
FAudio_INTERNAL_InitSIMDFunctions(has_sse2, FALSE); 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_resolve_SetThreadDescription();
FAudio_PlatformAddRef(); FAudio_PlatformAddRef();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment