Fix audio thread race on CVar reads during preset apply (#7265)

This commit is contained in:
Chris
2026-09-28 23:27:11 -04:00
committed by GitHub
parent aa25eb4d56
commit b9bcc5e901
4 changed files with 56 additions and 3 deletions
@@ -0,0 +1,34 @@
#include "AudioSettings.h"
#include <atomic>
#include <libultraship/bridge/consolevariablebridge.h>
#include "soh/cvar_prefixes.h"
#include "soh/ShipInit.hpp"
static std::atomic<float> sMasterVolume{ 40.0f / 100.0f };
static std::atomic<int32_t> sOctaveDrop{ 0 };
static std::atomic<int32_t> sMirroredWorld{ 0 };
float AudioSettings_GetMasterVolume(void) {
return sMasterVolume.load(std::memory_order_relaxed);
}
int32_t AudioSettings_GetOctaveDrop(void) {
return sOctaveDrop.load(std::memory_order_relaxed);
}
int32_t AudioSettings_GetMirroredWorld(void) {
return sMirroredWorld.load(std::memory_order_relaxed);
}
static void RefreshAudioSettings() {
sMasterVolume.store((float)CVarGetInteger(CVAR_SETTING("Volume.Master"), 40) / 100.0f, std::memory_order_relaxed);
sOctaveDrop.store(CVarGetInteger(CVAR_AUDIO("ExperimentalOctaveDrop"), 0), std::memory_order_relaxed);
sMirroredWorld.store(CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0), std::memory_order_relaxed);
}
static RegisterShipInitFunc initAudioSettings(RefreshAudioSettings,
{ CVAR_SETTING("Volume.Master"), CVAR_AUDIO("ExperimentalOctaveDrop"),
CVAR_ENHANCEMENT("MirroredWorld") });
@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// cvars used by the audio thread should go here
// direct use can result in a race condition with the main thread
float AudioSettings_GetMasterVolume(void);
int32_t AudioSettings_GetOctaveDrop(void);
int32_t AudioSettings_GetMirroredWorld(void);
#ifdef __cplusplus
}
#endif
+3 -2
View File
@@ -1,5 +1,6 @@
#include "global.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/audio/AudioSettings.h"
extern bool gUseLegacySD;
@@ -94,7 +95,7 @@ void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) {
vel = 0.0f > vel ? 0.0f : vel;
vel = 1.0f < vel ? 1.0f : vel;
float master_vol = (float)CVarGetInteger(CVAR_SETTING("Volume.Master"), 40) / 100.0f;
float master_vol = AudioSettings_GetMasterVolume();
sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)) * master_vol;
sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)) * master_vol;
@@ -120,7 +121,7 @@ void Audio_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput)
} else {
noteSubEu->bitField1.hasTwoParts = true;
if (3.99996f < resamplingRateInput) {
if (CVarGetInteger(CVAR_AUDIO("ExperimentalOctaveDrop"), 0) || noteSubEu->bitField1.isSyntheticWave) {
if (AudioSettings_GetOctaveDrop() || noteSubEu->bitField1.isSyntheticWave) {
resamplingRate = resamplingRateInput * 0.5f;
while (resamplingRate > 1.99998f) {
+2 -1
View File
@@ -1,6 +1,7 @@
#include <libultraship/libultra.h>
#include "global.h"
#include "soh/mixer.h"
#include "soh/Enhancements/audio/AudioSettings.h"
#define DEFAULT_LEN_1CH 0x1A0
#define DEFAULT_LEN_2CH 0x340
@@ -654,7 +655,7 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
}
updateIndex = aiBufLen * 2;
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
if (AudioSettings_GetMirroredWorld()) {
aInterleave(cmd++, DMEM_TEMP, DMEM_RIGHT_CH, DMEM_LEFT_CH, updateIndex);
} else {
aInterleave(cmd++, DMEM_TEMP, DMEM_LEFT_CH, DMEM_RIGHT_CH, updateIndex);