- Adjusted the noise debug table so that fractional volume levels do not

run into the adjacent columns.
- Added a NullSoundRenderer so that most of the checks against a NULL GSnd
  can be removed.
- Fixed: Looping sounds must always successfully allocate a channel, even if
  it's only a pre-evicted channel.


SVN r1058 (trunk)
This commit is contained in:
Randy Heit 2008-07-01 01:28:22 +00:00
parent ac32bd72bb
commit 601a6ad04c
11 changed files with 251 additions and 202 deletions

View file

@ -1,3 +1,11 @@
June 30, 2008
- Adjusted the noise debug table so that fractional volume levels do not
run into the adjacent columns.
- Added a NullSoundRenderer so that most of the checks against a NULL GSnd
can be removed.
- Fixed: Looping sounds must always successfully allocate a channel, even if
it's only a pre-evicted channel.
June 30, 2008 (Changes by Graf Zahl)
- Added A_ClearReFire code pointer for weapons. Preferably A_WeaponReady should
reset this counter but that can't be done due to unwanted side effects with

View file

@ -668,7 +668,7 @@ void D_Display ()
NoWipe = 10;
}
if (snd_drawoutput && GSnd != NULL)
if (snd_drawoutput)
{
GSnd->DrawWaveDebug(snd_drawoutput);
}

View file

@ -774,13 +774,10 @@ static void S_ClearSoundData()
{
unsigned int i;
if (GSnd != NULL)
S_StopAllChannels();
for (i = 0; i < S_sfx.Size(); ++i)
{
S_StopAllChannels();
for (i = 0; i < S_sfx.Size(); ++i)
{
GSnd->UnloadSound(&S_sfx[i]);
}
GSnd->UnloadSound(&S_sfx[i]);
}
S_sfx.Clear();

View file

@ -150,9 +150,9 @@ void S_NoiseDebug (void)
screen->DrawText (CR_GOLD, 120, y, "y", TAG_DONE);
screen->DrawText (CR_GOLD, 170, y, "z", TAG_DONE);
screen->DrawText (CR_GOLD, 220, y, "vol", TAG_DONE);
screen->DrawText (CR_GOLD, 250, y, "dist", TAG_DONE);
screen->DrawText (CR_GOLD, 290, y, "chan", TAG_DONE);
screen->DrawText (CR_GOLD, 330, y, "flags", TAG_DONE);
screen->DrawText (CR_GOLD, 260, y, "dist", TAG_DONE);
screen->DrawText (CR_GOLD, 300, y, "chan", TAG_DONE);
screen->DrawText (CR_GOLD, 340, y, "flags", TAG_DONE);
y += 8;
if (Channels == NULL)
@ -187,7 +187,7 @@ void S_NoiseDebug (void)
screen->DrawText(color, 70, y, "---", TAG_DONE); // X
screen->DrawText(color, 120, y, "---", TAG_DONE); // Y
screen->DrawText(color, 170, y, "---", TAG_DONE); // Z
screen->DrawText(color, 250, y, "---", TAG_DONE); // Distance
screen->DrawText(color, 260, y, "---", TAG_DONE); // Distance
}
else
{
@ -209,21 +209,21 @@ void S_NoiseDebug (void)
FVector3 sound(ox, oy, oz);
sound /= FRACUNIT;
sprintf (temp, "%.0f", (sound - listener).Length());
screen->DrawText (color, 250, y, temp, TAG_DONE);
screen->DrawText (color, 260, y, temp, TAG_DONE);
}
else
{
screen->DrawText (color, 250, y, "---", TAG_DONE);
screen->DrawText (color, 260, y, "---", TAG_DONE);
}
}
// Volume
sprintf (temp, "%g", chan->Volume);
sprintf (temp, "%.2g", chan->Volume);
screen->DrawText (color, 220, y, temp, TAG_DONE);
// Channel
sprintf (temp, "%d", chan->EntChannel);
screen->DrawText (color, 290, y, temp, TAG_DONE);
screen->DrawText (color, 300, y, temp, TAG_DONE);
// Flags
sprintf (temp, "%s3%sZ%sI%sM%sN%sA%sL%sE",
@ -235,7 +235,7 @@ void S_NoiseDebug (void)
(chan->ChanFlags & CHAN_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK,
(chan->ChanFlags & CHAN_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_BLACK);
screen->DrawText (color, 330, y, temp, TAG_DONE);
screen->DrawText (color, 340, y, temp, TAG_DONE);
y += 8;
if (chan->PrevChan == &Channels)
@ -314,23 +314,11 @@ void S_Shutdown ()
{
FSoundChan *chan, *next;
if (GSnd != NULL)
while (Channels != NULL)
{
while (Channels != NULL)
{
GSnd->StopSound(Channels);
}
GSnd->UpdateSounds();
}
else
{
for (chan = Channels; chan != NULL; chan = next)
{
next = chan->NextChan;
delete chan;
}
Channels = NULL;
GSnd->StopSound(Channels);
}
GSnd->UpdateSounds();
for (chan = FreeChannels; chan != NULL; chan = next)
{
next = chan->NextChan;
@ -660,7 +648,7 @@ static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
float pos[3];
float vel[3];
if (sound_id <= 0 || volume <= 0 || GSnd == NULL)
if (sound_id <= 0 || volume <= 0)
return NULL;
org_id = sound_id;
@ -736,7 +724,9 @@ static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
// If this is a singular sound, don't play it if it's already playing.
if (sfx->bSingular && S_CheckSingular(sound_id))
return NULL;
{
chanflags |= CHAN_EVICTED;
}
// If the sound is unpositioned or comes from the listener, it is
// never limited.
@ -748,7 +738,17 @@ static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
// If this sound doesn't like playing near itself, don't play it if
// that's what would happen.
if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit))
{
chanflags |= CHAN_EVICTED;
}
// If the sound is blocked and not looped, return now. If the sound
// is blocked and looped, pretend to play it so that it can
// eventually play for real.
if ((chanflags & (CHAN_EVICTED | CHAN_LOOP)) == CHAN_EVICTED)
{
return NULL;
}
// Make sure the sound is loaded.
sfx = S_LoadSound(sfx);
@ -817,14 +817,29 @@ static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
pitch = NORM_PITCH;
}
if (attenuation > 0)
if (chanflags & CHAN_EVICTED)
{
chan = NULL;
}
else if (attenuation > 0)
{
chan = GSnd->StartSound3D (sfx, volume, attenuation, pitch, basepriority, pos, vel, sec, channel, chanflags, NULL);
chanflags |= CHAN_IS3D | CHAN_JUSTSTARTED;
}
else
{
chan = GSnd->StartSound (sfx, volume, pitch, chanflags, NULL);
}
if (chan == NULL && (chanflags & CHAN_LOOP))
{
chan = S_GetChannel(NULL);
chanflags |= CHAN_EVICTED;
}
if (attenuation > 0)
{
chanflags |= CHAN_IS3D | CHAN_JUSTSTARTED;
}
else
{
chanflags |= CHAN_LISTENERZ | CHAN_JUSTSTARTED;
}
if (chan != NULL)
@ -844,6 +859,7 @@ static FSoundChan *S_StartSound (fixed_t *pt, AActor *mover, sector_t *sec,
chan->NearLimit = near_limit;
chan->Pitch = pitch;
chan->Priority = basepriority;
chan->DistanceScale = attenuation;
if (mover != NULL)
{
mover->SoundChans |= 1 << channel;
@ -888,6 +904,11 @@ void S_RestartSound(FSoundChan *chan)
// If this sound doesn't like playing near itself, don't play it if
// that's what would happen.
if (chan->NearLimit > 0 && S_CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit))
{
return;
}
ochan = GSnd->StartSound3D(sfx, chan->Volume, chan->DistanceScale, chan->Pitch,
chan->Priority, pos, vel, chan->Sector, chan->EntChannel, chan->ChanFlags, chan);
}
@ -1079,10 +1100,6 @@ void S_StopSound (AActor *ent, int channel)
void S_StopAllChannels ()
{
if (GSnd == NULL)
{
return;
}
SN_StopAllSequences();
while (Channels != NULL)
{
@ -1101,7 +1118,7 @@ void S_StopAllChannels ()
void S_RelinkSound (AActor *from, AActor *to)
{
if (from == NULL || GSnd == NULL)
if (from == NULL)
return;
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
@ -1197,10 +1214,7 @@ void S_PauseSound (bool notmusic)
I_PauseSong (mus_playing.handle);
MusicPaused = true;
}
if (GSnd != NULL)
{
GSnd->SetSfxPaused (true);
}
GSnd->SetSfxPaused (true);
}
//==========================================================================
@ -1217,10 +1231,7 @@ void S_ResumeSound ()
I_ResumeSong (mus_playing.handle);
MusicPaused = false;
}
if (GSnd != NULL)
{
GSnd->SetSfxPaused (false);
}
GSnd->SetSfxPaused (false);
}
//==========================================================================
@ -1243,7 +1254,7 @@ void S_EvictAllChannels()
if (!(chan->ChanFlags & CHAN_EVICTED))
{
chan->ChanFlags |= CHAN_EVICTED;
if (GSnd != NULL && chan->SysChannel != NULL)
if (chan->SysChannel != NULL)
{
GSnd->StopSound(chan);
}
@ -1295,11 +1306,6 @@ void S_RestoreEvictedChannel(FSoundChan *chan)
void S_RestoreEvictedChannels()
{
if (GSnd == NULL)
{
return;
}
// Restart channels in the same order they were originally played.
S_RestoreEvictedChannel(Channels);
}
@ -1317,9 +1323,6 @@ void S_UpdateSounds (void *listener_p)
I_UpdateMusic();
if (GSnd == NULL)
return;
// [RH] Update music and/or playlist. I_QrySongPlaying() must be called
// to attempt to reconnect to broken net streams and to advance the
// playlist when the current song finishes.
@ -1441,10 +1444,7 @@ void S_SerializeSounds(FArchive &arc)
{
FSoundChan *chan;
if (GSnd != NULL)
{
GSnd->Sync(true);
}
GSnd->Sync(true);
if (arc.IsStoring())
{
@ -1490,11 +1490,8 @@ void S_SerializeSounds(FArchive &arc)
S_RestoreEvictedChannels();
}
DSeqNode::SerializeSequences(arc);
if (GSnd != NULL)
{
GSnd->Sync(false);
GSnd->UpdateSounds();
}
GSnd->Sync(false);
GSnd->UpdateSounds();
}
//==========================================================================

View file

@ -1486,7 +1486,6 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, float dis
HandleChannelDelay(chan, reuse_chan, freq);
chan->setPaused(false);
FSoundChan *schan = CommonChannelSetup(chan, reuse_chan);
schan->DistanceScale = distscale;
return schan;
}

View file

@ -97,11 +97,8 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
self = 1.f;
else
{
if (GSnd != NULL)
{
// Set general music volume.
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
}
// Set general music volume.
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
// For music not implemented through the digital sound system,
// let them know about the change.
if (currSong != NULL)
@ -263,10 +260,6 @@ void *I_RegisterURLSong (const char *url)
{
StreamSong *song;
if (GSnd == NULL)
{
return NULL;
}
song = new StreamSong(url, 0, 0);
if (song->IsValid())
{
@ -328,73 +321,70 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
// Check for MUS format
if (id == MAKE_ID('M','U','S',0x1a))
{
if (GSnd != NULL)
/* MUS are played as:
- OPL:
- if explicitly selected by $mididevice
- when snd_mididevice is -3 and no midi device is set for the song
Timidity:
- if explicitly selected by $mididevice
- when snd_mididevice is -2 and no midi device is set for the song
FMod:
- if explicitly selected by $mididevice
- when snd_mididevice is -1 and no midi device is set for the song
- as fallback when both OPL and Timidity failed unless snd_mididevice is >= 0
MMAPI (Win32 only):
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
- when snd_mididevice is >= 0 and no midi device is set for the song
- as fallback when both OPL and Timidity failed and snd_mididevice is >= 0
*/
if ((snd_mididevice == -3 && device == MDEV_DEFAULT) || device == MDEV_OPL)
{
/* MUS are played as:
- OPL:
- if explicitly selected by $mididevice
- when snd_mididevice is -3 and no midi device is set for the song
info = new MUSSong2 (file, musiccache, len, MIDI_OPL);
}
else if (device == MDEV_TIMIDITY || (device == MDEV_DEFAULT && snd_mididevice == -2))
{
info = new TimiditySong (file, musiccache, len);
}
else if (snd_mididevice == -4 && device == MDEV_DEFAULT)
{
info = new MUSSong2(file, musiccache, len, MIDI_Timidity);
}
if (info != NULL && !info->IsValid())
{
delete info;
info = NULL;
device = MDEV_DEFAULT;
}
if (info == NULL && (snd_mididevice == -1 || device == MDEV_FMOD) && device != MDEV_MMAPI)
{
TArray<BYTE> midi;
bool midi_made = false;
Timidity:
- if explicitly selected by $mididevice
- when snd_mididevice is -2 and no midi device is set for the song
FMod:
- if explicitly selected by $mididevice
- when snd_mididevice is -1 and no midi device is set for the song
- as fallback when both OPL and Timidity failed unless snd_mididevice is >= 0
MMAPI (Win32 only):
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
- when snd_mididevice is >= 0 and no midi device is set for the song
- as fallback when both OPL and Timidity failed and snd_mididevice is >= 0
*/
if ((snd_mididevice == -3 && device == MDEV_DEFAULT) || device == MDEV_OPL)
if (file == NULL)
{
info = new MUSSong2 (file, musiccache, len, MIDI_OPL);
midi_made = ProduceMIDI((BYTE *)musiccache, midi);
}
else if (device == MDEV_TIMIDITY || (device == MDEV_DEFAULT && snd_mididevice == -2))
else
{
info = new TimiditySong (file, musiccache, len);
}
else if ((snd_mididevice == -4 && device == MDEV_DEFAULT) && GSnd != NULL)
{
info = new MUSSong2(file, musiccache, len, MIDI_Timidity);
}
if (info != NULL && !info->IsValid())
{
delete info;
info = NULL;
device = MDEV_DEFAULT;
}
if (info == NULL && (snd_mididevice == -1 || device == MDEV_FMOD) && device != MDEV_MMAPI)
{
TArray<BYTE> midi;
bool midi_made = false;
if (file == NULL)
BYTE *mus = new BYTE[len];
size_t did_read = fread(mus, 1, len, file);
if (did_read == (size_t)len)
{
midi_made = ProduceMIDI((BYTE *)musiccache, midi);
midi_made = ProduceMIDI(mus, midi);
}
else
fseek(file, -(long)did_read, SEEK_CUR);
delete[] mus;
}
if (midi_made)
{
info = new StreamSong((char *)&midi[0], -1, midi.Size());
if (!info->IsValid())
{
BYTE *mus = new BYTE[len];
size_t did_read = fread(mus, 1, len, file);
if (did_read == (size_t)len)
{
midi_made = ProduceMIDI(mus, midi);
}
fseek(file, -(long)did_read, SEEK_CUR);
delete[] mus;
}
if (midi_made)
{
info = new StreamSong((char *)&midi[0], -1, midi.Size());
if (!info->IsValid())
{
delete info;
info = NULL;
}
delete info;
info = NULL;
}
}
}
@ -408,7 +398,6 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
// Check for MIDI format
else
{
if (id == MAKE_ID('M','T','h','d'))
{
// This is a midi file
@ -432,15 +421,15 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
- when snd_mididevice is >= 0 and no midi device is set for the song
- as fallback when Timidity failed and snd_mididevice is >= 0
*/
if ((device == MDEV_OPL || (snd_mididevice == -3 && device == MDEV_DEFAULT)) && GSnd != NULL)
if (device == MDEV_OPL || (snd_mididevice == -3 && device == MDEV_DEFAULT))
{
info = new MIDISong2 (file, musiccache, len, MIDI_OPL);
}
else if ((device == MDEV_TIMIDITY || (snd_mididevice == -2 && device == MDEV_DEFAULT)) && GSnd != NULL)
else if (device == MDEV_TIMIDITY || (snd_mididevice == -2 && device == MDEV_DEFAULT))
{
info = new TimiditySong (file, musiccache, len);
}
else if ((snd_mididevice == -4 && device == MDEV_DEFAULT) && GSnd != NULL)
else if (snd_mididevice == -4 && device == MDEV_DEFAULT)
{
info = new MIDISong2(file, musiccache, len, MIDI_Timidity);
}
@ -523,7 +512,7 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
// smaller than this can't possibly be a valid music file if it hasn't
// been identified already, so don't even bother trying to load it.
// Of course MIDIs shorter than 1024 bytes should pass.
if (info == NULL && GSnd != NULL && (len >= 1024 || id == MAKE_ID('M','T','h','d')))
if (info == NULL && (len >= 1024 || id == MAKE_ID('M','T','h','d')))
{
// Let FMOD figure out what it is.
if (file != NULL)

View file

@ -107,6 +107,111 @@ CUSTOM_CVAR (Float, snd_sfxvolume, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOIN
}
}
class NullSoundRenderer : public SoundRenderer
{
public:
void SetSfxVolume (float volume)
{
}
void SetMusicVolume (float volume)
{
}
void LoadSound (sfxinfo_t *sfx)
{
}
void UnloadSound (sfxinfo_t *sfx)
{
}
unsigned int GetMSLength(sfxinfo_t *sfx)
{
// Return something that isn't 0. This is only used by some
// ambient sounds to specify a default minimum period.
return 250;
}
float GetOutputRate()
{
return 11025; // Lies!
}
// Streaming sounds.
SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
{
return NULL;
}
SoundStream *OpenStream (const char *filename, int flags, int offset, int length)
{
return NULL;
}
// Starts a sound. (No, not really.)
FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan)
{
return NULL;
}
FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, float distscale, int pitch, int priority, float pos[3], float vel[3], sector_t *sector, int channum, int chanflags, FSoundChan *reuse_chan)
{
return NULL;
}
// Stops a sound channel.
void StopSound (FSoundChan *chan)
{
if (chan != NULL)
{
S_ReturnChannel(chan);
}
}
// Returns position of sound on this channel, in samples.
unsigned int GetPosition(FSoundChan *chan)
{
return 0;
}
// Synchronizes following sound startups.
void Sync (bool sync)
{
}
// Pauses or resumes all sound effect channels.
void SetSfxPaused (bool paused)
{
}
// Pauses or resumes *every* channel, including environmental reverb.
void SetInactive(bool inactive)
{
}
// Updates the volume, separation, and pitch of a sound channel.
void UpdateSoundParams3D (FSoundChan *chan, float pos[3], float vel[3])
{
}
void UpdateListener ()
{
}
void UpdateSounds ()
{
}
bool IsValid ()
{
return true;
}
void PrintStatus ()
{
Printf("Null sound module active.\n");
}
void PrintDriversList ()
{
Printf("Null sound module uses no drivers.\n");
}
FString GatherStats ()
{
return "Null sound module has no stats.";
}
};
void I_InitSound ()
{
@ -115,6 +220,7 @@ void I_InitSound ()
if (nosound)
{
GSnd = new NullSoundRenderer;
I_InitMusic ();
return;
}
@ -124,7 +230,7 @@ void I_InitSound ()
if (!GSnd->IsValid ())
{
delete GSnd;
GSnd = NULL;
GSnd = new NullSoundRenderer;
Printf (TEXTCOLOR_RED"Sound init failed. Using nosound.\n");
}
I_InitMusic ();
@ -143,14 +249,7 @@ void I_ShutdownSound (void)
CCMD (snd_status)
{
if (GSnd == NULL)
{
Printf ("sound is not active\n");
}
else
{
GSnd->PrintStatus ();
}
GSnd->PrintStatus ();
}
CCMD (snd_reset)
@ -169,26 +268,12 @@ CCMD (snd_reset)
CCMD (snd_listdrivers)
{
if (GSnd != NULL)
{
GSnd->PrintDriversList ();
}
else
{
Printf ("Sound is inactive.\n");
}
GSnd->PrintDriversList ();
}
ADD_STAT (sound)
{
if (GSnd != NULL)
{
return GSnd->GatherStats ();
}
else
{
return "No sound";
}
return GSnd->GatherStats ();
}
SoundRenderer::SoundRenderer ()

View file

@ -1117,18 +1117,15 @@ input_mod::input_mod(DUH *myduh)
written = 0;
length = 0;
start_order = 0;
if (GSnd != NULL)
if (mod_samplerate != 0)
{
if (mod_samplerate != 0)
{
srate = mod_samplerate;
}
else
{
srate = (int)GSnd->GetOutputRate();
}
m_Stream = GSnd->CreateStream(read, 32*1024, SoundStream::Float, srate, this);
}
srate = mod_samplerate;
}
else
{
srate = (int)GSnd->GetOutputRate();
}
m_Stream = GSnd->CreateStream(read, 32*1024, SoundStream::Float, srate, this);
delta = 65536.0 / srate;
}
@ -1343,9 +1340,5 @@ FString input_mod::GetStats()
extern "C" short *DUMBCALLBACK dumb_decode_vorbis(int outlen, const void *oggstream, int sizebytes)
{
if (GSnd == NULL)
{
return NULL;
}
return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis);
}

View file

@ -269,12 +269,6 @@ void TimiditySong::PrepTimidity ()
pipeSize = (timidity_pipe * timidity_frequency / 1000)
<< (timidity_stereo + !timidity_8bit);
if (GSnd == NULL)
{ // Can't pipe if using no sound.
pipeSize = 0;
}
if (pipeSize != 0)
{
#ifdef _WIN32
// Round pipe size up to nearest power of 2 to try and avoid partial

View file

@ -50,14 +50,7 @@ StreamSong::~StreamSong ()
StreamSong::StreamSong (const char *filename_or_data, int offset, int len)
{
if (GSnd != NULL)
{
m_Stream = GSnd->OpenStream (filename_or_data, SoundStream::Loop, offset, len);
}
else
{
m_Stream = NULL;
}
m_Stream = GSnd->OpenStream (filename_or_data, SoundStream::Loop, offset, len);
}
bool StreamSong::IsPlaying ()

View file

@ -275,10 +275,7 @@ int I_PlayMovie (const char *name)
goto bomb3;
}
if (GSnd != NULL)
{
GSnd->MovieDisableSound ();
}
GSnd->MovieDisableSound ();
returnSound = true;
CheckIfVideo ();
@ -390,10 +387,7 @@ bomb2:
if (returnSound)
{
if (GSnd != NULL)
{
GSnd->MovieResumeSound ();
}
GSnd->MovieResumeSound ();
C_FlushDisplay ();
}
if (runningFull)