cvar_t snd_spatialization_control = {CVAR_SAVE, "snd_spatialization_control", "0", "enable spatialization control (headphone friendly mode)"};
// 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"};
+cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.11", "how much sound to mix ahead of time"};
cvar_t snd_streaming = { CVAR_SAVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory)"};
cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0", "swaps left/right speakers for old ISA soundblaster cards"};
extern cvar_t v_flipped;
i++;
}
- sfx = S_PrecacheSound (name, true, false);
+ sfx = S_PrecacheSound (name, true, true);
if (sfx)
{
ch_ind = S_StartSound (-1, 0, sfx, listener_origin, fvol, attenuation);
/*
==================
-S_ServerSounds
+S_ClearUsed
==================
*/
-void S_ServerSounds (char serversound [][MAX_QPATH], unsigned int numsounds)
+void S_ClearUsed (void)
{
sfx_t *sfx;
- sfx_t *sfxnext;
+// sfx_t *sfxnext;
unsigned int i;
// Start the ambient sounds and make them loop
S_UnlockSfx (sfx);
sfx->flags &= ~SFXFLAG_SERVERSOUND;
}
+}
- // Add 1 lock and the SFXFLAG_SERVERSOUND flag to each sfx in "serversound"
- for (i = 1; i < numsounds; i++)
- {
- 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;
- }
- }
+/*
+==================
+S_PurgeUnused
+==================
+*/
+void S_PurgeUnused(void)
+{
+ sfx_t *sfx;
+ sfx_t *sfxnext;
// Free all unlocked sfx
for (sfx = known_sfx;sfx;sfx = sfxnext)
S_PrecacheSound
==================
*/
-sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean lock)
+sfx_t *S_PrecacheSound (const char *name, qboolean complain, qboolean serversound)
{
sfx_t *sfx;
// previously missing file
sfx->flags &= ~ SFXFLAG_FILEMISSING;
- if (lock)
+ if (serversound && !(sfx->flags & SFXFLAG_SERVERSOUND))
+ {
S_LockSfx (sfx);
+ sfx->flags |= SFXFLAG_SERVERSOUND;
+ }
if (!nosound.integer && snd_precache.integer)
S_LoadSound(sfx, complain);
{
// no sound on this channel
first_to_die = ch_idx;
- break;
+ goto emptychan_found;
}
// don't let monster sounds override player sounds
if (first_to_die == -1)
return NULL;
+
+ S_StopChannel (first_to_die, true);
+emptychan_found:
return &channels[first_to_die];
}
void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, vec3_t origin, float fvol, float attenuation, qboolean isstatic)
{
+ if (!sfx)
+ {
+ Con_Printf("S_PlaySfxOnChannel called with NULL??\n");
+ return;
+ }
// Initialize the channel
+ // a crash was reported on an in-use channel, so check here...
+ if (target_chan->sfx)
+ {
+ int channelindex = (int)(target_chan - channels);
+ Con_Printf("S_PlaySfxOnChannel(%s): channel %i already in use?? Clearing.\n", sfx->name, channelindex);
+ S_StopChannel (channelindex, true);
+ }
// We MUST set sfx LAST because otherwise we could crash a threaded mixer
// (otherwise we'd have to call SndSys_LockRenderBuffer here)
memset (target_chan, 0, sizeof (*target_chan));
if (channel_ind >= total_channels)
return;
+ // we have to lock an audio mutex to prevent crashes if an audio mixer
+ // thread is currently mixing this channel
+ // the SndSys_LockRenderBuffer function uses such a mutex in
+ // threaded sound backends
+ if (lockmutex && !simsound)
+ SndSys_LockRenderBuffer();
+
ch = &channels[channel_ind];
if (ch->sfx != NULL)
{
sfx_t *sfx = ch->sfx;
- // we have to lock an audio mutex to prevent crashes if an audio mixer
- // thread is currently mixing this channel
- // the SndSys_LockRenderBuffer function uses such a mutex in
- // threaded sound backends
- if (lockmutex)
- SndSys_LockRenderBuffer();
if (sfx->fetcher != NULL)
{
snd_fetcher_endsb_t fetcher_endsb = sfx->fetcher->endsb;
ch->fetcher_data = NULL;
ch->sfx = NULL;
- if (lockmutex)
- SndSys_UnlockRenderBuffer();
}
+ if (lockmutex && !simsound)
+ SndSys_UnlockRenderBuffer();
}
if (flag != CHANNELFLAG_FORCELOOP &&
flag != CHANNELFLAG_PAUSED &&
- flag != CHANNELFLAG_FULLVOLUME)
+ flag != CHANNELFLAG_FULLVOLUME &&
+ flag != CHANNELFLAG_LOCALSOUND)
return false;
if (value)
// stop CD audio because it may be using a faketrack
CDAudio_Stop();
- for (i = 0; i < total_channels; i++)
- S_StopChannel (i, true);
-
- total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
- memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
-
- // Mute the contents of the submittion buffer
if (simsound || SndSys_LockRenderBuffer ())
{
int clear;
size_t memsize;
+ for (i = 0; i < total_channels; i++)
+ S_StopChannel (i, false);
+
+ total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
+ memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
+
+ // Mute the contents of the submittion buffer
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);
channels[ch_ind].master_vol = (int)(fvol * 255.0f);
}
+float S_GetChannelPosition (unsigned int ch_ind)
+{
+ // note: this is NOT accurate yet
+ int s;
+ channel_t *ch = &channels[ch_ind];
+ sfx_t *sfx = ch->sfx;
+
+ s = ch->pos;
+ /*
+ if(!snd_usethreadedmixing)
+ s += _snd_mixahead.value * S_GetSoundRate();
+ */
+ return (s % sfx->total_length) / (float) S_GetSoundRate();
+}
+
+
/*
=================