feat(sound): add support for caching disk sounds

This commit is contained in:
fallenoak 2025-11-25 22:26:19 -06:00
parent b2447e7197
commit d4cd3e4bc1
No known key found for this signature in database
GPG Key ID: 7628F8E61AEA070D
4 changed files with 65 additions and 15 deletions

View File

@ -9,6 +9,7 @@
#define LOG_WRITE(result, ...) \ #define LOG_WRITE(result, ...) \
SESound::Log_Write(__LINE__, __FILE__, result, __VA_ARGS__); SESound::Log_Write(__LINE__, __FILE__, result, __VA_ARGS__);
STORM_LIST(SoundCacheNode) SESound::s_CacheList;
SCritSect SESound::s_CritSect3; SCritSect SESound::s_CritSect3;
int32_t SESound::s_Initialized; int32_t SESound::s_Initialized;
SCritSect SESound::s_InternalCritSect; SCritSect SESound::s_InternalCritSect;
@ -86,7 +87,7 @@ FMOD_RESULT DoneLoadingCallback(FMOD_SOUND* fmodSound, FMOD_RESULT callbackResul
// Mark cache sound node as loaded // Mark cache sound node as loaded
if (lookup->m_internal->m_useCache) { if (lookup->m_internal->m_useCache) {
static_cast<SEDiskSound*>(lookup->m_internal)->m_cacheNode->loaded = 1; static_cast<SEDiskSound*>(lookup->m_internal)->m_cacheNode->m_loaded = 1;
} }
SESound::s_LoadingCritSect.Leave(); SESound::s_LoadingCritSect.Leave();
@ -390,13 +391,44 @@ int32_t SESound::LoadDiskSound(FMOD::System* fmodSystem, const char* filename, F
} }
} }
// Generate name
char fmodName[300]; char fmodName[300];
SStrPrintf(fmodName, sizeof(fmodName), "%-24d%s", internal->m_uniqueID, filename); SStrPrintf(fmodName, sizeof(fmodName), "%-24d%s", internal->m_uniqueID, filename);
// TODO // Generate cache key
char cacheKey[400];
auto loopStr = fmodMode & FMOD_LOOP_NORMAL ? "_LOOP_" : "_NOLOOP_";
auto positionStr = fmodMode & FMOD_2D ? "_2D_" : "_3D_";
SStrPrintf(cacheKey, sizeof(cacheKey), "%s%s%s", filename, positionStr, loopStr);
auto cacheHashval = SStrHash(cacheKey);
// Load from cache
if (useCache) { if (useCache) {
// TODO for (auto cacheNode = SESound::s_CacheList.Head(); cacheNode; cacheNode = SESound::s_CacheList.Link(cacheNode)->Next()) {
if (cacheNode->m_hashval == cacheHashval) {
// Cache hit
internal->m_fmodSound = cacheNode->m_fmodSound;
internal->m_useCache = 1;
internal->m_cacheNode = cacheNode;
// TODO
if (cacheNode->m_loaded) {
internal->m_nonblockingReady = 1;
}
// TODO
SESound::s_LoadingCritSect.Leave();
return 1;
}
}
} }
// Validate file exists // Validate file exists
@ -415,8 +447,6 @@ int32_t SESound::LoadDiskSound(FMOD::System* fmodSystem, const char* filename, F
return 0; return 0;
} }
int32_t nonblockingReady = 0;
fmodMode |= FMOD_VIRTUAL_PLAYFROMSTART | FMOD_IGNORETAGS | FMOD_NONBLOCKING; fmodMode |= FMOD_VIRTUAL_PLAYFROMSTART | FMOD_IGNORETAGS | FMOD_NONBLOCKING;
uint32_t maxCacheSize = 1048576; uint32_t maxCacheSize = 1048576;
@ -462,14 +492,25 @@ int32_t SESound::LoadDiskSound(FMOD::System* fmodSystem, const char* filename, F
return 0; return 0;
} }
// Create cache node
if (useCache) { if (useCache) {
auto cacheNode = STORM_NEW(SoundCacheNode);
cacheNode->m_fmodSound = internal->m_fmodSound;
cacheNode->m_hashval = cacheHashval;
SStrCopy(cacheNode->m_filename, filename, sizeof(cacheNode->m_filename));
// TODO // TODO
internal->m_useCache = 1;
internal->m_cacheNode = cacheNode;
} }
// TODO // TODO
// Used to permit instant playback of cached sounds // No cache hit (yet)
internal->m_nonblockingReady = nonblockingReady; internal->m_nonblockingReady = 0;
s_LoadingCritSect.Leave(); s_LoadingCritSect.Leave();

View File

@ -14,6 +14,7 @@ struct SOUND_INTERNAL_LOOKUP : TSHashObject<SOUND_INTERNAL_LOOKUP, HASHKEY_NONE>
class SESound { class SESound {
public: public:
// Public static variables // Public static variables
static STORM_LIST(SoundCacheNode) s_CacheList;
static SCritSect s_CritSect3; static SCritSect s_CritSect3;
static int32_t s_Initialized; static int32_t s_Initialized;
static SCritSect s_InternalCritSect; static SCritSect s_InternalCritSect;

View File

@ -4,6 +4,10 @@
#define LOG_WRITE(result, ...) \ #define LOG_WRITE(result, ...) \
SESound::Log_Write(__LINE__, __FILE__, result, __VA_ARGS__); SESound::Log_Write(__LINE__, __FILE__, result, __VA_ARGS__);
SoundCacheNode::SoundCacheNode() {
SESound::s_CacheList.LinkToTail(this);
}
SESoundInternal::SESoundInternal() { SESoundInternal::SESoundInternal() {
// TODO // TODO
this->m_uniqueID = SESound::s_UniqueID++; this->m_uniqueID = SESound::s_UniqueID++;

View File

@ -8,14 +8,18 @@
class SESound; class SESound;
class SFile; class SFile;
struct SoundCacheNode : TSLinkedNode<SoundCacheNode> { class SoundCacheNode : public TSLinkedNode<SoundCacheNode> {
// Member variables public:
FMOD::Sound* sound; // Member variables
int32_t loaded; FMOD::Sound* m_fmodSound = nullptr;
char filename[128]; int32_t m_loaded = 0;
uint32_t hashval; char m_filename[128];
// TODO dword94 uint32_t m_hashval = 0;
// TODO dword98 // TODO dword94
// TODO dword98
// Member functions
SoundCacheNode();
}; };
class SESoundInternal : public TSLinkedNode<SESoundInternal> { class SESoundInternal : public TSLinkedNode<SESoundInternal> {