X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=snd_main.c;h=fe18aed74a5791afaec64c7d882190b0aa5261f0;hb=69f3a5b2fdb60c908b57ff0fb14dc1493cc6e0a5;hp=af6275c643a8f8e50ac9ad9855fa59e70cf54ec1;hpb=a2445d85eccf4d0c5766f44f02cd04a600c4bad4;p=xonotic%2Fdarkplaces.git diff --git a/snd_main.c b/snd_main.c index af6275c6..fe18aed7 100644 --- a/snd_main.c +++ b/snd_main.c @@ -31,8 +31,6 @@ void S_Play2(void); void S_SoundList(void); void S_Update_(); -void S_ClearBuffer (void); - // ======================================================================= // Internal sound data & structures @@ -53,11 +51,9 @@ matrix4x4_t listener_matrix; vec_t sound_nominal_clip_dist=1000.0; mempool_t *snd_mempool; -// sample PAIRS int soundtime; int paintedtime; - // Linked list of known sfx sfx_t *known_sfx = NULL; @@ -91,9 +87,12 @@ const char* ambient_names [2] = { "sound/ambience/water1.wav", "sound/ambience/w // Functions // ==================================================================== +void S_FreeSfx (sfx_t *sfx, qboolean force); + + void S_SoundInfo_f(void) { - if (!sound_started || !shm) + if (!sound_started) { Con_Print("sound system not started\n"); return; @@ -142,8 +141,6 @@ void S_Startup(void) sound_started = true; Con_DPrintf("Sound sampling rate: %i\n", shm->format.speed); - - S_StopAllSounds (); } void S_Shutdown(void) @@ -221,6 +218,27 @@ void S_Init(void) } +/* +================ +S_Terminate + +Shutdown and free all resources +================ +*/ +void S_Terminate (void) +{ + S_Shutdown (); + OGG_CloseLibrary (); + + // Free all SFXs + while (known_sfx != NULL) + S_FreeSfx (known_sfx, true); + + Cvar_SetValueQuick (&snd_initialized, false); + Mem_FreePool (&snd_mempool); +} + + // ======================================================================= // Load a sound // ======================================================================= @@ -238,7 +256,6 @@ sfx_t *S_FindName (const char *name) if (!snd_initialized.integer) return NULL; - // Add the default sound directory to the path if (strlen (name) >= sizeof (sfx->name)) Host_Error ("S_FindName: sound name too long (%s)", name); @@ -264,10 +281,10 @@ S_FreeSfx ================== */ -void S_FreeSfx (sfx_t *sfx) +void S_FreeSfx (sfx_t *sfx, qboolean force) { - // Never free a locked sfx - if (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK)) + // Never free a locked sfx unless forced + if (!force && (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK))) return; Con_DPrintf ("S_FreeSfx: freeing %s\n", sfx->name); @@ -304,6 +321,7 @@ S_ServerSounds void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) { sfx_t *sfx; + sfx_t *sfxnext; unsigned int i; // Start the ambient sounds and make them loop @@ -320,6 +338,7 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) channels[i].sfx = ambient_sfxs[i]; channels[i].flags |= CHANNELFLAG_FORCELOOP; + channels[i].master_vol = 0; } } @@ -343,16 +362,10 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) } // Free all unlocked sfx - sfx = known_sfx; - while (sfx != NULL) + for (sfx = known_sfx;sfx;sfx = sfxnext) { - sfx_t* crtsfx; - - // We may lose the "next" pointer after S_FreeSfx - crtsfx = sfx; - sfx = sfx->next; - - S_FreeSfx (crtsfx); + sfxnext = sfx->next; + S_FreeSfx (sfx, false); } } @@ -656,6 +669,10 @@ void S_StopSound(int entnum, int entchannel) void S_StopAllSounds (void) { unsigned int i; + unsigned char *pbuf; + + if (!sound_started) + return; for (i = 0; i < total_channels; i++) S_StopChannel (i); @@ -663,7 +680,23 @@ void S_StopAllSounds (void) total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics memset(channels, 0, MAX_CHANNELS * sizeof(channel_t)); - S_ClearBuffer (); + // Clear sound buffer + pbuf = S_LockBuffer(); + if (pbuf != NULL) + { + int setsize = shm->samples * shm->format.width; + int clear = (shm->format.width == 1) ? 0x80 : 0; + + // FIXME: is it (still) true? (check with OSS and ALSA) + // on i586/i686 optimized versions of glibc, glibc *wrongly* IMO, + // reads the memory area before writing to it causing a seg fault + // since the memory is PROT_WRITE only and not PROT_READ|PROT_WRITE + //memset(shm->buffer, clear, shm->samples * shm->format.width); + while (setsize--) + *pbuf++ = clear; + + S_UnlockBuffer (); + } } void S_PauseGameSounds (qboolean toggle) @@ -686,37 +719,6 @@ void S_SetChannelVolume (unsigned int ch_ind, float fvol) } -void S_ClearBuffer(void) -{ - int clear; - unsigned char *pbuf; - - if (!sound_started || !shm) - return; - - if (shm->format.width == 1) - clear = 0x80; // 8 bit sound (unsigned) - else - clear = 0; // 16 bit sound (signed) - - pbuf = S_LockBuffer(); - if (pbuf != NULL) - { - int setsize = shm->samples * shm->format.width; - - while (setsize--) - *pbuf++ = clear; - - // on i586/i686 optimized versions of glibc, glibc *wrongly* IMO, - // reads the memory area before writing to it causing a seg fault - // since the memory is PROT_WRITE only and not PROT_READ|PROT_WRITE - //memset(shm->buffer, clear, shm->samples * shm->format.width); - - S_UnlockBuffer (); - } -} - - /* ================= S_StaticSound @@ -762,10 +764,6 @@ void S_UpdateAmbientSounds (void) channel_t *chan; qbyte ambientlevels[NUM_AMBIENTS]; - // Mute ambient sounds until proven otherwise - for (ambient_channel = 0 ; ambient_channel < NUM_AMBIENTS;ambient_channel++) - channels[ambient_channel].master_vol = 0; - if (ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brush.AmbientSoundLevelsForPoint) return; @@ -775,7 +773,7 @@ void S_UpdateAmbientSounds (void) for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) { chan = &channels[ambient_channel]; - if (chan->sfx == NULL || (chan->sfx->flags & SFXFLAG_FILEMISSING)) + if (chan->sfx == NULL || chan->sfx->fetcher == NULL) continue; vol = ambient_level.value * ambientlevels[ambient_channel]; @@ -984,7 +982,7 @@ static void S_Play_Common(float fvol, float attenuation) // Free the sfx if the file didn't exist if (ch_ind < 0) - S_FreeSfx (sfx); + S_FreeSfx (sfx, false); else channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND; }