sound layer refactor
This commit is contained in:
parent
7253e8f210
commit
35564cceef
@ -243,7 +243,7 @@ void P_AppStartup(String args_str)
|
|||||||
F_StartupReceipt font_sr = F_Startup(&asset_cache_sr, &ttf_sr);
|
F_StartupReceipt font_sr = F_Startup(&asset_cache_sr, &ttf_sr);
|
||||||
S_StartupReceipt sprite_sr = sprite_startup();
|
S_StartupReceipt sprite_sr = sprite_startup();
|
||||||
M_StartupReceipt mixer_sr = M_Startup();
|
M_StartupReceipt mixer_sr = M_Startup();
|
||||||
SND_StartupReceipt sound_sr = sound_startup(&asset_cache_sr);
|
SND_StartupReceipt sound_sr = SND_Startup(&asset_cache_sr);
|
||||||
D_StartupReceipt draw_sr = D_Startup(&font_sr);
|
D_StartupReceipt draw_sr = D_Startup(&font_sr);
|
||||||
SimStartupReceipt sim_sr = sim_startup();
|
SimStartupReceipt sim_sr = sim_startup();
|
||||||
|
|
||||||
|
|||||||
@ -40,9 +40,8 @@ Struct(F_LoadJobSigStore)
|
|||||||
P_Mutex mutex;
|
P_Mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================== *
|
////////////////////////////////
|
||||||
* Global state
|
//~ Shared state
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
#define F_LookupTableSize (256)
|
#define F_LookupTableSize (256)
|
||||||
|
|
||||||
|
|||||||
@ -295,7 +295,7 @@ M_PcmF32 M_MixAllTracks(Arena *arena, u64 frame_count)
|
|||||||
SND_Sound *source = mix->source;
|
SND_Sound *source = mix->source;
|
||||||
M_TrackDesc desc = mix->desc;
|
M_TrackDesc desc = mix->desc;
|
||||||
M_EffectData *effect_data = &mix->effect_data;
|
M_EffectData *effect_data = &mix->effect_data;
|
||||||
b32 source_is_stereo = source->flags & SOUND_FLAG_STEREO;
|
b32 source_is_stereo = source->flags & SND_SoundFlag_Stereo;
|
||||||
f32 speed = MaxF32(0, desc.speed);
|
f32 speed = MaxF32(0, desc.speed);
|
||||||
|
|
||||||
//- Determine sample range
|
//- Determine sample range
|
||||||
|
|||||||
@ -1,76 +1,56 @@
|
|||||||
#define SOUND_SAMPLE_RATE 48000
|
SND_SharedState SND_shared_state = ZI;
|
||||||
|
|
||||||
struct sound_task_params {
|
////////////////////////////////
|
||||||
struct sound_task_params *next_free;
|
//~ Startup
|
||||||
|
|
||||||
u32 flags;
|
SND_StartupReceipt SND_Startup(AC_StartupReceipt *asset_cache_sr)
|
||||||
AC_Asset *asset;
|
|
||||||
u64 path_len;
|
|
||||||
char path_cstr[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sound_task_params_store {
|
|
||||||
struct sound_task_params *head_free;
|
|
||||||
Arena *arena;
|
|
||||||
P_Mutex mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Global state
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
Global struct {
|
|
||||||
struct sound_task_params_store params;
|
|
||||||
} G = ZI, DebugAlias(G, G_sound);
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Startup
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
SND_StartupReceipt sound_startup(AC_StartupReceipt *asset_cache_sr)
|
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
SND_SharedState *g = &SND_shared_state;
|
||||||
(UNUSED)asset_cache_sr;
|
(UNUSED)asset_cache_sr;
|
||||||
G.params.arena = AllocArena(Gibi(64));
|
g->params.arena = AllocArena(Gibi(64));
|
||||||
return (SND_StartupReceipt) { 0 };
|
return (SND_StartupReceipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
////////////////////////////////
|
||||||
* Load task param store
|
//~ Job sig store
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
internal struct sound_task_params *sound_task_params_alloc(void)
|
SND_LoadAssetJobSig *SND_AllocJobSig(void)
|
||||||
{
|
{
|
||||||
struct sound_task_params *p = 0;
|
SND_SharedState *g = &SND_shared_state;
|
||||||
|
SND_LoadAssetJobSig *p = 0;
|
||||||
{
|
{
|
||||||
P_Lock lock = P_LockE(&G.params.mutex);
|
P_Lock lock = P_LockE(&g->params.mutex);
|
||||||
if (G.params.head_free) {
|
if (g->params.head_free)
|
||||||
p = G.params.head_free;
|
{
|
||||||
G.params.head_free = p->next_free;
|
p = g->params.head_free;
|
||||||
} else {
|
g->params.head_free = p->next_free;
|
||||||
p = PushStruct(G.params.arena, struct sound_task_params);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = PushStruct(g->params.arena, SND_LoadAssetJobSig);
|
||||||
}
|
}
|
||||||
P_Unlock(&lock);
|
P_Unlock(&lock);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void sound_task_params_release(struct sound_task_params *p)
|
void SND_ReleaseJobSig(SND_LoadAssetJobSig *p)
|
||||||
{
|
{
|
||||||
P_Lock lock = P_LockE(&G.params.mutex);
|
SND_SharedState *g = &SND_shared_state;
|
||||||
p->next_free = G.params.head_free;
|
P_Lock lock = P_LockE(&g->params.mutex);
|
||||||
G.params.head_free = p;
|
p->next_free = g->params.head_free;
|
||||||
|
g->params.head_free = p;
|
||||||
P_Unlock(&lock);
|
P_Unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
////////////////////////////////
|
||||||
* Load
|
//~ Load job
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
internal P_JobDef(sound_load_asset_job, job)
|
P_JobDef(SND_LoadAssetJob, job)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct sound_task_params *params = job.sig;
|
SND_LoadAssetJobSig *params = job.sig;
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
String path = STRING(params->path_len, (u8 *)params->path_cstr);
|
String path = STRING(params->path_len, (u8 *)params->path_cstr);
|
||||||
AC_Asset *asset = params->asset;
|
AC_Asset *asset = params->asset;
|
||||||
@ -87,22 +67,28 @@ internal P_JobDef(sound_load_asset_job, job)
|
|||||||
MP3_Result decoded = ZI;
|
MP3_Result decoded = ZI;
|
||||||
{
|
{
|
||||||
R_Resource sound_rs = R_OpenResource(path);
|
R_Resource sound_rs = R_OpenResource(path);
|
||||||
if (R_ResourceExists(&sound_rs)) {
|
if (R_ResourceExists(&sound_rs))
|
||||||
|
{
|
||||||
u64 decode_flags = 0;
|
u64 decode_flags = 0;
|
||||||
if (flags & SOUND_FLAG_STEREO) {
|
if (flags & SND_SoundFlag_Stereo)
|
||||||
|
{
|
||||||
decode_flags |= MP3_DecodeFlag_Stereo;
|
decode_flags |= MP3_DecodeFlag_Stereo;
|
||||||
}
|
}
|
||||||
decoded = MP3_Decode(scratch.arena, R_GetResourceData(&sound_rs), SOUND_SAMPLE_RATE, decode_flags);
|
decoded = MP3_Decode(scratch.arena, R_GetResourceData(&sound_rs), SND_SampleRate, decode_flags);
|
||||||
if (!decoded.success) {
|
if (!decoded.success)
|
||||||
|
{
|
||||||
error_msg = Lit("Failed to decode sound file");
|
error_msg = Lit("Failed to decode sound file");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
error_msg = Lit("Resource not found");
|
error_msg = Lit("Resource not found");
|
||||||
}
|
}
|
||||||
R_CloseResource(&sound_rs);
|
R_CloseResource(&sound_rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoded.success) {
|
if (decoded.success)
|
||||||
|
{
|
||||||
/* Store */
|
/* Store */
|
||||||
SND_Sound *sound = 0;
|
SND_Sound *sound = 0;
|
||||||
u64 samples_count = decoded.samples_count;
|
u64 samples_count = decoded.samples_count;
|
||||||
@ -123,7 +109,9 @@ internal P_JobDef(sound_load_asset_job, job)
|
|||||||
|
|
||||||
P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FmtString(path), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)));
|
P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FmtString(path), FmtFloat(SecondsFromNs(P_TimeNs() - start_ns)));
|
||||||
AC_MarkReady(asset, sound);
|
AC_MarkReady(asset, sound);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
P_LogErrorF("Error loading sound \"%F\": %F", FmtString(path), FmtString(error_msg));
|
P_LogErrorF("Error loading sound \"%F\": %F", FmtString(path), FmtString(error_msg));
|
||||||
|
|
||||||
/* Store */
|
/* Store */
|
||||||
@ -137,12 +125,15 @@ internal P_JobDef(sound_load_asset_job, job)
|
|||||||
AC_MarkReady(asset, sound);
|
AC_MarkReady(asset, sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
sound_task_params_release(params);
|
SND_ReleaseJobSig(params);
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
|
////////////////////////////////
|
||||||
|
//~ Load sound
|
||||||
|
|
||||||
|
AC_Asset *SND_LoadAsset(String path, u32 flags, b32 wait)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
@ -156,10 +147,12 @@ AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
|
|||||||
b32 is_first_touch;
|
b32 is_first_touch;
|
||||||
AC_Asset *asset = AC_TouchCache(key, hash, &is_first_touch);
|
AC_Asset *asset = AC_TouchCache(key, hash, &is_first_touch);
|
||||||
|
|
||||||
if (is_first_touch) {
|
if (is_first_touch)
|
||||||
|
{
|
||||||
/* Assemble task params */
|
/* Assemble task params */
|
||||||
struct sound_task_params *params = sound_task_params_alloc();
|
SND_LoadAssetJobSig *params = SND_AllocJobSig();
|
||||||
if (path.len > (sizeof(params->path_cstr) - 1)) {
|
if (path.len > (sizeof(params->path_cstr) - 1))
|
||||||
|
{
|
||||||
P_Panic(StringFormat(scratch.arena,
|
P_Panic(StringFormat(scratch.arena,
|
||||||
Lit("Sound path \"%F\" too long!"),
|
Lit("Sound path \"%F\" too long!"),
|
||||||
FmtString(path)));
|
FmtString(path)));
|
||||||
@ -171,8 +164,9 @@ AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
|
|||||||
|
|
||||||
/* PushStruct task */
|
/* PushStruct task */
|
||||||
AC_MarkLoading(asset);
|
AC_MarkLoading(asset);
|
||||||
P_Run(1, sound_load_asset_job, params, P_Pool_Background, P_Priority_Low, &asset->counter);
|
P_Run(1, SND_LoadAssetJob, params, P_Pool_Background, P_Priority_Low, &asset->counter);
|
||||||
if (wait) {
|
if (wait)
|
||||||
|
{
|
||||||
AC_WaitOnAssetReady(asset);
|
AC_WaitOnAssetReady(asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,19 +175,18 @@ AC_Asset *sound_load_asset(String path, u32 flags, b32 wait)
|
|||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SND_Sound *sound_load_async(String path, u32 flags)
|
SND_Sound *SND_LoadSoundAsync(String path, u32 flags)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
AC_Asset *asset = sound_load_asset(path, flags, 0);
|
AC_Asset *asset = SND_LoadAsset(path, flags, 0);
|
||||||
SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset);
|
SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset);
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SND_Sound *SND_LoadSoundWait(String path, u32 flags)
|
||||||
SND_Sound *sound_load(String path, u32 flags)
|
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
AC_Asset *asset = sound_load_asset(path, flags, 1);
|
AC_Asset *asset = SND_LoadAsset(path, flags, 1);
|
||||||
AC_WaitOnAssetReady(asset);
|
AC_WaitOnAssetReady(asset);
|
||||||
SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset);
|
SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset);
|
||||||
return sound;
|
return sound;
|
||||||
|
|||||||
@ -1,17 +1,67 @@
|
|||||||
#define SOUND_FLAG_NONE 0x0
|
////////////////////////////////
|
||||||
#define SOUND_FLAG_STEREO 0x1
|
//~ Sound structs
|
||||||
|
|
||||||
typedef struct SND_Sound SND_Sound;
|
#define SND_SampleRate 48000
|
||||||
struct SND_Sound {
|
|
||||||
|
typedef u32 SND_SoundFlag; enum
|
||||||
|
{
|
||||||
|
SND_SoundFlag_None = 0,
|
||||||
|
SND_SoundFlag_Stereo = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(SND_Sound)
|
||||||
|
{
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u64 samples_count;
|
u64 samples_count;
|
||||||
i16 *samples;
|
i16 *samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SND_StartupReceipt SND_StartupReceipt;
|
////////////////////////////////
|
||||||
struct SND_StartupReceipt { i32 _; };
|
//~ Sound job types
|
||||||
SND_StartupReceipt sound_startup(AC_StartupReceipt *asset_cache_sr);
|
|
||||||
|
|
||||||
AC_Asset *sound_load_asset(String path, u32 flags, b32 wait);
|
Struct(SND_LoadAssetJobSig)
|
||||||
SND_Sound *sound_load_async(String path, u32 flags);
|
{
|
||||||
SND_Sound *sound_load(String path, u32 flags);
|
SND_LoadAssetJobSig *next_free;
|
||||||
|
|
||||||
|
u32 flags;
|
||||||
|
AC_Asset *asset;
|
||||||
|
u64 path_len;
|
||||||
|
char path_cstr[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(SND_LoadAssetJobSigStore)
|
||||||
|
{
|
||||||
|
SND_LoadAssetJobSig *head_free;
|
||||||
|
Arena *arena;
|
||||||
|
P_Mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Shared state
|
||||||
|
|
||||||
|
Struct(SND_SharedState)
|
||||||
|
{
|
||||||
|
SND_LoadAssetJobSigStore params;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SND_SharedState SND_shared_state;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Startup
|
||||||
|
|
||||||
|
Struct(SND_StartupReceipt) { i32 _; };
|
||||||
|
SND_StartupReceipt SND_Startup(AC_StartupReceipt *asset_cache_sr);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Sound load job
|
||||||
|
|
||||||
|
SND_LoadAssetJobSig *SND_AllocJobSig(void);
|
||||||
|
void SND_ReleaseJobSig(SND_LoadAssetJobSig *p);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Sound load operations
|
||||||
|
|
||||||
|
P_JobDef(SND_LoadAssetJob, job);
|
||||||
|
AC_Asset *SND_LoadAsset(String path, u32 flags, b32 wait);
|
||||||
|
SND_Sound *SND_LoadSoundAsync(String path, u32 flags);
|
||||||
|
SND_Sound *SND_LoadSoundWait(String path, u32 flags);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user