From: molivier Date: Mon, 22 Nov 2004 14:38:33 +0000 (+0000) Subject: Several changes to the SFX lock code in the sound engine, mainly to make sure SFXs... X-Git-Tag: xonotic-v0.1.0preview~5355 X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=a2445d85eccf4d0c5766f44f02cd04a600c4bad4 Several changes to the SFX lock code in the sound engine, mainly to make sure SFXs are automatically freed only at level change Moved call to CL_InitTEnts after S_Startup so the tent sounds get properly precached Added a developer warning when trying to play a non-precached SFX Made the soundlist command more verbose Added the ssize_t type for Win32 systems Some comments and dead code removal git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4781 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cd_shared.c b/cd_shared.c index 9cedbac1..70a446ca 100644 --- a/cd_shared.c +++ b/cd_shared.c @@ -115,7 +115,6 @@ void CDAudio_Play (qbyte track, qboolean looping) // Try playing a fake track (sound file) first sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, false); - // FIXME: perhaps force it to be always %03u (but for compatibility?): if (sfx == NULL || sfx->fetcher == NULL) sfx = S_PrecacheSound (va ("cdtracks/track%03u.wav", track), false, false); if (sfx != NULL) diff --git a/cl_main.c b/cl_main.c index 6ecfefb1..41667e5f 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1298,7 +1298,6 @@ void CL_Init (void) SZ_Alloc (&cls.message, 1024, "cls.message"); CL_InitInput (); - CL_InitTEnts (); // // register our commands diff --git a/cl_parse.c b/cl_parse.c index 4e782b63..e49f1c3c 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -825,11 +825,7 @@ sfx_t *cl_sfx_ric2; sfx_t *cl_sfx_ric3; sfx_t *cl_sfx_r_exp3; -/* -================= -CL_ParseTEnt -================= -*/ + void CL_InitTEnts (void) { cl_sfx_wizhit = S_PrecacheSound ("sound/wizard/hit.wav", false, true); diff --git a/fs.c b/fs.c index b3584555..2f00c1ea 100644 --- a/fs.c +++ b/fs.c @@ -405,10 +405,10 @@ qboolean PK3_GetEndOfCentralDir (const char *packfile, FILE *packhandle, pk3_end buffer = Mem_Alloc (tempmempool, maxsize); #ifdef FS_USESYSCALLS lseek (packhandle, filesize - maxsize, SEEK_SET); - if (read (packhandle, buffer, maxsize) != (int) maxsize) + if (read (packhandle, buffer, maxsize) != (ssize_t) maxsize) #else fseek (packhandle, filesize - maxsize, SEEK_SET); - if (fread (buffer, 1, maxsize, packhandle) != (unsigned int) maxsize) + if (fread (buffer, 1, maxsize, packhandle) != (size_t) maxsize) #endif { Mem_Free (buffer); diff --git a/host.c b/host.c index 953f3943..ad337c59 100644 --- a/host.c +++ b/host.c @@ -934,6 +934,7 @@ void Host_Init (void) if (cls.state != ca_dedicated) { VID_Open(); + CL_InitTEnts (); // We must wait after sound startup to load tent sounds SCR_BeginLoadingPlaque(); MR_Init(); } diff --git a/qtypes.h b/qtypes.h index 5e1d5750..480b1e7f 100644 --- a/qtypes.h +++ b/qtypes.h @@ -9,6 +9,10 @@ typedef unsigned char qbyte; typedef enum {false, true} qboolean; +#ifdef WIN32 +# define ssize_t long +#endif + #ifndef NULL #define NULL ((void *)0) #endif @@ -18,13 +22,6 @@ typedef enum {false, true} qboolean; #define TRUE 1 #endif -//define PARANOID // speed sapping error checking -#ifdef _DEBUG -#define ASSERT(condition) if (!(condition)) Sys_Error("assertion (##condition) failed at " __FILE__ ":" __LINE__ "\n"); -#else -#define ASSERT(condition) -#endif - // up / down #define PITCH 0 diff --git a/render.h b/render.h index e0a6a816..62347212 100644 --- a/render.h +++ b/render.h @@ -141,8 +141,6 @@ void R_DrawExplosions(void); #define gl_solid_format 3 #define gl_alpha_format 4 -//#define PARANOID 1 - int R_CullBox(const vec3_t mins, const vec3_t maxs); #define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (cl.worldmodel && cl.worldmodel->brush.BoxTouchingPVS && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, r_pvsbits, (mins), (maxs)))) diff --git a/snd_main.c b/snd_main.c index 7f01b52e..af6275c6 100644 --- a/snd_main.c +++ b/snd_main.c @@ -82,9 +82,13 @@ cvar_t snd_show = {0, "snd_show", "0"}; cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.1"}; cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0"}; +// Ambient sounds +sfx_t* ambient_sfxs [2] = { NULL, NULL }; +const char* ambient_names [2] = { "sound/ambience/water1.wav", "sound/ambience/wind2.wav" }; + // ==================================================================== -// User-setable variables +// Functions // ==================================================================== void S_SoundInfo_f(void) @@ -263,7 +267,7 @@ S_FreeSfx void S_FreeSfx (sfx_t *sfx) { // Never free a locked sfx - if (sfx->locks > 0) + if (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK)) return; Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name); @@ -303,16 +307,27 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) unsigned int i; // Start the ambient sounds and make them loop - channels[AMBIENT_WATER].sfx = S_PrecacheSound ("sound/ambience/water1.wav", false, true); - channels[AMBIENT_SKY].sfx = S_PrecacheSound ("sound/ambience/wind2.wav", false, true); - for (i = 0; i < NUM_AMBIENTS; i++) - channels[i].flags |= CHANNELFLAG_FORCELOOP; + for (i = 0; i < sizeof (ambient_sfxs) / sizeof (ambient_sfxs[0]); i++) + { + // Precache it if it's not done (request a lock to make sure it will never be freed) + if (ambient_sfxs[i] == NULL) + ambient_sfxs[i] = S_PrecacheSound (ambient_names[i], false, true); + if (ambient_sfxs[i] != NULL) + { + // Add a lock to the SFX while playing. It will be + // removed by S_StopAllSounds at the end of the level + S_LockSfx (ambient_sfxs[i]); + + channels[i].sfx = ambient_sfxs[i]; + channels[i].flags |= CHANNELFLAG_FORCELOOP; + } + } // Remove 1 lock from all sfx with the SFXFLAG_SERVERSOUND flag, and remove the flag for (sfx = known_sfx; sfx != NULL; sfx = sfx->next) if (sfx->flags & SFXFLAG_SERVERSOUND) { - sfx->locks--; + S_UnlockSfx (sfx); sfx->flags &= ~SFXFLAG_SERVERSOUND; } @@ -320,9 +335,9 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) for (i = 1; i < numsounds; i++) { sfx = S_FindName (serversound[i]); - if (sfx != NULL && !(sfx->flags & SFXFLAG_SERVERSOUND)) + if (sfx != NULL) { - sfx->locks++; + S_LockSfx (sfx); sfx->flags |= SFXFLAG_SERVERSOUND; } } @@ -359,11 +374,8 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock) if (sfx == NULL) return NULL; - if (lock && !(sfx->flags & SFXFLAG_PERMANENT)) - { - sfx->flags |= SFXFLAG_PERMANENT; - sfx->locks++; - } + if (lock) + S_LockSfx (sfx); if (!nosound.integer && snd_precache.integer) S_LoadSound(sfx, complain); @@ -371,17 +383,28 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock) return sfx; } +/* +================== +S_LockSfx + +Add a lock to a SFX +================== +*/ +void S_LockSfx (sfx_t *sfx) +{ + sfx->locks++; +} + /* ================== S_UnlockSfx -Remove a lock from a SFX and freed it if possible +Remove a lock from a SFX ================== */ void S_UnlockSfx (sfx_t *sfx) { sfx->locks--; - S_FreeSfx (sfx); } @@ -520,7 +543,7 @@ void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, target_chan->dist_mult = attenuation / sound_nominal_clip_dist; // Lock the SFX during play - sfx->locks++; + S_LockSfx (sfx); } @@ -532,15 +555,17 @@ int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f if (!sound_started || !sfx || nosound.integer) return -1; + if (!sfx->fetcher) + { + Con_DPrintf ("S_StartSound: \"%s\" hasn't been precached\n", sfx->name); + return -1; + } // Pick a channel to play on target_chan = SND_PickChannel(entnum, entchannel); if (!target_chan) return -1; - if (!S_LoadSound (sfx, true)) - return -1; // couldn't load the sound's data - S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_NONE, origin, fvol, attenuation, false); target_chan->entnum = entnum; target_chan->entchannel = entchannel; @@ -701,17 +726,19 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation) { channel_t *target_chan; - if (!sfx) + if (!sound_started || !sfx || nosound.integer) return; - - if (total_channels == MAX_CHANNELS) + if (!sfx->fetcher) { - Con_Print("total_channels == MAX_CHANNELS\n"); + Con_DPrintf ("S_StaticSound: \"%s\" hasn't been precached\n", sfx->name); return; } - if (!S_LoadSound (sfx, true)) + if (total_channels == MAX_CHANNELS) + { + Con_Print("S_StaticSound: total_channels == MAX_CHANNELS\n"); return; + } target_chan = &channels[total_channels++]; S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true); @@ -937,19 +964,11 @@ static void S_Play_Common(float fvol, float attenuation) i = 1; while (iflags & SFXFLAG_SERVERSOUND)) - { - sfx->flags |= SFXFLAG_SERVERSOUND; - sfx->locks++; - } - // If we need to get the volume from the command line if (fvol == -1.0f) @@ -958,13 +977,17 @@ static void S_Play_Common(float fvol, float attenuation) i++; } - ch_ind = S_StartSound(-1, 0, sfx, listener_origin, fvol, attenuation); + sfx = S_PrecacheSound (name, true, false); + if (sfx) + { + ch_ind = S_StartSound(-1, 0, sfx, listener_origin, fvol, attenuation); - // Free the sfx if the file didn't exist - if (ch_ind < 0) - S_FreeSfx (sfx); - else - channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND; + // Free the sfx if the file didn't exist + if (ch_ind < 0) + S_FreeSfx (sfx); + else + channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND; + } } } @@ -996,14 +1019,18 @@ void S_SoundList(void) { size = sfx->mempool->totalsize; total += size; - Con_Printf ("%c%c(%2db, %6s) %8i : %s\n", + Con_Printf ("%c%c%c%c(%2db, %6s) %8i : %s\n", (sfx->loopstart >= 0) ? 'L' : ' ', (sfx->flags & SFXFLAG_STREAMED) ? 'S' : ' ', + (sfx->locks > 0) ? 'K' : ' ', + (sfx->flags & SFXFLAG_PERMANENTLOCK) ? 'P' : ' ', sfx->format.width * 8, (sfx->format.channels == 1) ? "mono" : "stereo", size, sfx->name); } + else + Con_Printf (" ( unknown ) unloaded : %s\n", sfx->name); } Con_Printf("Total resident: %i\n", total); } @@ -1017,13 +1044,16 @@ qboolean S_LocalSound (const char *sound) if (!snd_initialized.integer || nosound.integer) return true; - sfx = S_PrecacheSound (sound, true, true); + sfx = S_PrecacheSound (sound, true, false); if (!sfx) { Con_Printf("S_LocalSound: can't precache %s\n", sound); return false; } + // Local sounds must not be freed + sfx->flags |= SFXFLAG_PERMANENTLOCK; + ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 1); if (ch_ind < 0) return false; diff --git a/snd_main.h b/snd_main.h index aa36d015..d2e37f39 100644 --- a/snd_main.h +++ b/snd_main.h @@ -43,7 +43,7 @@ typedef struct #define SFXFLAG_FILEMISSING (1 << 0) // wasn't able to load the associated sound file #define SFXFLAG_SERVERSOUND (1 << 1) // the sfx is part of the server precache list #define SFXFLAG_STREAMED (1 << 2) // informative only. You shouldn't need to know that -#define SFXFLAG_PERMANENT (1 << 3) // the sfx is used by the client code and should not be purged (even if it is also in the server precache list) +#define SFXFLAG_PERMANENTLOCK (1 << 3) // can never be freed (ex: used by the client code) typedef struct snd_fetcher_s snd_fetcher_t; struct sfx_s @@ -51,9 +51,11 @@ struct sfx_s char name[MAX_QPATH]; sfx_t *next; mempool_t *mempool; - unsigned int locks; // A locked sfx_t must not be freed. - // Locks are added by S_PrecacheSound and S_ServerSounds. - // SFX can be freed by S_UnlockSfx or S_ServerSounds. + int locks; // One lock is automatically granted while the sfx is + // playing (and removed when stopped). Locks can also be + // added by S_PrecacheSound and S_ServerSounds. + // A SFX with no lock and no SFXFLAG_PERMANENTLOCK is + // freed at level change by S_ServerSounds. unsigned int flags; // cf SFXFLAG_* defines snd_format_t format; int loopstart; @@ -112,6 +114,9 @@ void SNDDMA_Shutdown(void); qboolean S_LoadSound (sfx_t *s, qboolean complain); void S_UnloadSound(sfx_t *s); +void S_LockSfx (sfx_t *sfx); +void S_UnlockSfx (sfx_t *sfx); + void *S_LockBuffer(void); void S_UnlockBuffer(void); diff --git a/snd_null.c b/snd_null.c index c276f725..0bd5157e 100755 --- a/snd_null.c +++ b/snd_null.c @@ -83,10 +83,6 @@ sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean lock) return NULL; } -void S_UnlockSfx (sfx_t *sfx) -{ -} - void S_Update(const matrix4x4_t *matrix) { } diff --git a/sound.h b/sound.h index b571be4e..b09d89dd 100644 --- a/sound.h +++ b/sound.h @@ -64,7 +64,6 @@ void S_ExtraUpdate (void); sfx_t *S_PrecacheSound (const char *sample, qboolean complain, qboolean lock); void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds); -void S_UnlockSfx (sfx_t *sfx); // S_StartSound returns the channel index, or -1 if an error occurred int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation);