X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=snd_main.c;h=1734baeac2246df6ed7e55c73ebcc865dd6efcb2;hb=087c96690cbc912a6eeca0555d5bf1ffaa6c2daf;hp=a6945527c3837fb8b9b2924cf53b4640a485eb50;hpb=a58e22c543943e280f18e58f49886a993d160310;p=xonotic%2Fdarkplaces.git diff --git a/snd_main.c b/snd_main.c index a6945527..1734baea 100644 --- a/snd_main.c +++ b/snd_main.c @@ -167,7 +167,7 @@ cvar_t bgmvolume = {CVAR_SAVE, "bgmvolume", "1", "volume of background music (su cvar_t volume = {CVAR_SAVE, "volume", "0.7", "volume of sound effects"}; cvar_t snd_initialized = { CVAR_READONLY, "snd_initialized", "0", "indicates the sound subsystem is active"}; cvar_t snd_staticvolume = {CVAR_SAVE, "snd_staticvolume", "1", "volume of ambient sound effects (such as swampy sounds at the start of e1m2)"}; -cvar_t snd_soundradius = {0, "snd_soundradius", "1000", "radius of weapon sounds and other standard sound effects (monster idle noises are half this radius and flickering light noises are one third of this radius)"}; +cvar_t snd_soundradius = {0, "snd_soundradius", "2000", "radius of weapon sounds and other standard sound effects (monster idle noises are half this radius and flickering light noises are one third of this radius)"}; // Cvars declared in snd_main.h (shared with other snd_*.c files) cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.1", "how much sound to mix ahead of time"}; @@ -268,7 +268,7 @@ static void S_SoundList_f (void) size = sfx->memsize; format = sfx->fetcher->getfmt(sfx); Con_Printf ("%c%c%c%c(%2db, %6s) %8i : %s\n", - (sfx->loopstart >= 0) ? 'L' : ' ', + (sfx->loopstart < sfx->total_length) ? 'L' : ' ', (sfx->flags & SFXFLAG_STREAMED) ? 'S' : ' ', (sfx->locks > 0) ? 'K' : ' ', (sfx->flags & SFXFLAG_PERMANENTLOCK) ? 'P' : ' ', @@ -708,7 +708,7 @@ void S_Init(void) Cvar_RegisterVariable(&snd_channels); // COMMANDLINEOPTION: Sound: -nosound disables sound (including CD audio) - if (COM_CheckParm("-nosound") || COM_CheckParm("-safe")) + if (COM_CheckParm("-nosound")) return; snd_mempool = Mem_AllocPool("sound", 0, NULL); @@ -919,6 +919,9 @@ void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds) sfx = S_FindName (serversound[i]); if (sfx != NULL) { + // clear the FILEMISSING flag so that S_LoadSound will try again on a + // previously missing file + sfx->flags &= ~ SFXFLAG_FILEMISSING; S_LockSfx (sfx); sfx->flags |= SFXFLAG_SERVERSOUND; } @@ -949,9 +952,14 @@ sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock) return NULL; sfx = S_FindName (name); + if (sfx == NULL) return NULL; + // clear the FILEMISSING flag so that S_LoadSound will try again on a + // previously missing file + sfx->flags &= ~ SFXFLAG_FILEMISSING; + if (lock) S_LockSfx (sfx); @@ -1035,41 +1043,42 @@ channel_t *SND_PickChannel(int entnum, int entchannel) // Check for replacement sound, or find the best one to replace first_to_die = -1; first_life_left = 0x7fffffff; - for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) + + // entity channels try to replace the existing sound on the channel + if (entchannel != 0) { - ch = &channels[ch_idx]; - if (entchannel != 0) + for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) { - // try to override an existing channel + ch = &channels[ch_idx]; if (ch->entnum == entnum && (ch->entchannel == entchannel || entchannel == -1) ) { // always override sound from same entity - first_to_die = ch_idx; - break; + S_StopChannel (ch_idx); + return &channels[ch_idx]; } } - else + } + + // there was no channel to override, so look for the first empty one + for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) + { + ch = &channels[ch_idx]; + if (!ch->sfx) { - if (!ch->sfx) - { - // no sound on this channel - first_to_die = ch_idx; - break; - } + // no sound on this channel + first_to_die = ch_idx; + break; } - if (ch->sfx) - { - // don't let monster sounds override player sounds - if (ch->entnum == cl.viewentity && entnum != cl.viewentity) - continue; + // don't let monster sounds override player sounds + if (ch->entnum == cl.viewentity && entnum != cl.viewentity) + continue; - // don't override looped sounds - if ((ch->flags & CHANNELFLAG_FORCELOOP) || ch->sfx->loopstart >= 0) - continue; - } + // don't override looped sounds + if ((ch->flags & CHANNELFLAG_FORCELOOP) || ch->sfx->loopstart < ch->sfx->total_length) + continue; + life_left = ch->sfx->total_length - ch->pos; - life_left = (int)(ch->end - snd_renderbuffer->endframe); if (life_left < first_life_left) { first_life_left = life_left; @@ -1080,8 +1089,6 @@ channel_t *SND_PickChannel(int entnum, int entchannel) if (first_to_die == -1) return NULL; - S_StopChannel (first_to_die); - return &channels[first_to_die]; } @@ -1156,14 +1163,13 @@ void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, VectorCopy (origin, target_chan->origin); target_chan->master_vol = (int)(fvol * 255); target_chan->sfx = sfx; - target_chan->end = snd_renderbuffer->endframe + sfx->total_length; - target_chan->lastptime = snd_renderbuffer->endframe; target_chan->flags = flags; + target_chan->pos = 0; // start of the sound // If it's a static sound if (isstatic) { - if (sfx->loopstart == -1) + if (sfx->loopstart >= sfx->total_length) Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name); target_chan->dist_mult = attenuation / (64.0f * snd_soundradius.value); } @@ -1179,7 +1185,6 @@ int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f { channel_t *target_chan, *check; int ch_idx; - int skip; if (snd_renderbuffer == NULL || sfx == NULL || nosound.integer) return -1; @@ -1210,13 +1215,8 @@ int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f continue; if (check->sfx == sfx && !check->pos) { - skip = (int)(0.1 * snd_renderbuffer->format.speed); - if (skip > (int)sfx->total_length) - skip = (int)sfx->total_length; - if (skip > 0) - skip = rand() % skip; - target_chan->pos += skip; - target_chan->end -= skip; + // use negative pos offset to delay this sound effect + target_chan->pos += (int)lhrandom(0, -0.1 * snd_renderbuffer->format.speed); break; } } @@ -1248,7 +1248,6 @@ void S_StopChannel (unsigned int channel_ind) ch->sfx = NULL; } - ch->end = 0; } @@ -1282,6 +1281,7 @@ void S_StopSound(int entnum, int entchannel) } } +extern void CDAudio_Stop(void); void S_StopAllSounds (void) { unsigned int i; @@ -1394,17 +1394,20 @@ void S_UpdateAmbientSounds (void) // Don't adjust volume too fast // FIXME: this rounds off to an int each frame, meaning there is little to no fade at extremely high framerates! - if (chan->master_vol < vol) - { - chan->master_vol += (int)(cl.realframetime * ambient_fade.value); - if (chan->master_vol > vol) - chan->master_vol = vol; - } - else if (chan->master_vol > vol) + if (cl.time > cl.oldtime) { - chan->master_vol -= (int)(cl.realframetime * ambient_fade.value); if (chan->master_vol < vol) - chan->master_vol = vol; + { + chan->master_vol += (int)((cl.time - cl.oldtime) * ambient_fade.value); + if (chan->master_vol > vol) + chan->master_vol = vol; + } + else if (chan->master_vol > vol) + { + chan->master_vol -= (int)((cl.time - cl.oldtime) * ambient_fade.value); + if (chan->master_vol < vol) + chan->master_vol = vol; + } } for (i = 0;i < SND_LISTENERS;i++) @@ -1415,20 +1418,48 @@ void S_UpdateAmbientSounds (void) static void S_PaintAndSubmit (void) { unsigned int newsoundtime, paintedtime, endtime, maxtime, usedframes; + qboolean usesoundtimehack; + static qboolean soundtimehack = true; if (snd_renderbuffer == NULL || nosound.integer) return; - if (snd_blocked > 0 && !(cls.capturevideo.soundrate && !cls.capturevideo.realtime)) - return; - // Update sound time - if (cls.capturevideo.soundrate && !cls.capturevideo.realtime) // SUPER NASTY HACK to record non-realtime sound + usesoundtimehack = true; + if (cls.timedemo) // SUPER NASTY HACK to mix non-realtime sound for more reliable benchmarking + newsoundtime = (unsigned int)((double)cl.mtime[0] * (double)snd_renderbuffer->format.speed); + else if (cls.capturevideo.soundrate && !cls.capturevideo.realtime) // SUPER NASTY HACK to record non-realtime sound newsoundtime = (unsigned int)((double)cls.capturevideo.frame * (double)snd_renderbuffer->format.speed / (double)cls.capturevideo.framerate); else if (simsound) newsoundtime = (unsigned int)((realtime - snd_starttime) * (double)snd_renderbuffer->format.speed); else + { newsoundtime = SndSys_GetSoundTime(); + usesoundtimehack = false; + } + // if the soundtimehack state changes we need to reset the soundtime + if (soundtimehack != usesoundtimehack) + { + snd_renderbuffer->startframe = snd_renderbuffer->endframe = soundtime = newsoundtime; + + // Mute the contents of the submission buffer + if (simsound || SndSys_LockRenderBuffer ()) + { + int clear; + size_t memsize; + + clear = (snd_renderbuffer->format.width == 1) ? 0x80 : 0; + memsize = snd_renderbuffer->maxframes * snd_renderbuffer->format.width * snd_renderbuffer->format.channels; + memset(snd_renderbuffer->ring, clear, memsize); + + if (!simsound) + SndSys_UnlockRenderBuffer (); + } + } + soundtimehack = usesoundtimehack; + + if (!soundtimehack && snd_blocked > 0) + return; newsoundtime += extrasoundtime; if (newsoundtime < soundtime) @@ -1450,7 +1481,7 @@ static void S_PaintAndSubmit (void) Con_DPrintf("S_PaintAndSubmit: new extra sound time = %u\n", extrasoundtime); } - else + else if (!soundtimehack) Con_Printf("S_PaintAndSubmit: WARNING: newsoundtime < soundtime (%u < %u)\n", newsoundtime, soundtime); } @@ -1492,9 +1523,6 @@ void S_Update(const matrix4x4_t *listenermatrix) if (snd_renderbuffer == NULL || nosound.integer) return; - if (snd_blocked > 0 && !(cls.capturevideo.soundrate && !cls.capturevideo.realtime)) - return; - // If snd_swapstereo or snd_channellayout has changed, recompute the channel layout if (current_swapstereo != snd_swapstereo.integer || current_channellayout != snd_channellayout.integer)