- Fixed: GetMSLength didn't resolve random and player sounds.

- Moved sound aliasing code out of fmodsound.cpp into S_LoadSound.


SVN r1203 (trunk)
This commit is contained in:
Christoph Oelckers 2008-09-07 14:45:50 +00:00
parent 9e7bd3f8fa
commit 2df65c70cb
8 changed files with 189 additions and 158 deletions

View file

@ -1,3 +1,7 @@
September 7, 2008 (Changes by Graf Zahl)
- Fixed: GetMSLength didn't resolve random and player sounds.
- Moved sound aliasing code out of fmodsound.cpp into S_LoadSound.
September 6, 2008 (Changes by Graf Zahl)
- Fixed: The tagged version of TranslucentLine took the information for additive
translucency from the tagged linedef, not the control linedef.

View file

@ -208,8 +208,6 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc=NULL);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern int sfx_sawup, sfx_sawidl, sfx_sawful, sfx_sawhit;
extern int sfx_itemup, sfx_tink;
extern int sfx_empty;
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -334,6 +332,56 @@ int S_PickReplacement (int refid)
return refid;
}
//==========================================================================
//
// S_GetSoundMSLength
//
// Returns duration of sound
//
//==========================================================================
unsigned int S_GetMSLength(FSoundID sound)
{
if (sound < 0 || sound >= S_sfx.Size()) return 0;
sfxinfo_t *sfx = &S_sfx[sound];
// Resolve player sounds, random sounds, and aliases
if (sfx->link != sfxinfo_t::NO_LINK)
{
if (sfx->bPlayerReserve)
{
sfx = &S_sfx[S_FindSkinnedSound (NULL, sound)];
}
else if (sfx->bRandomHeader)
{
// Hm... What should we do here?
// Pick the longest or the shortest sound?
// I think the longest one makes more sense.
int length = 0;
const FRandomSoundList *list = &S_rnd[sfx->link];
for (int i=0; i < list->NumSounds; i++)
{
// unfortunately we must load all sounds to find the longest one... :(
int thislen = S_GetMSLength(list->Sounds[i]);
if (thislen > length) length = thislen;
}
return length;
}
else
{
sfx = &S_sfx[sfx->link];
}
}
sfx = S_LoadSound(sfx);
if (sfx != NULL) return GSnd->GetMSLength(sfx);
else return 0;
}
//==========================================================================
//
// S_CacheRandomSound
@ -777,7 +825,7 @@ static void S_ClearSoundData()
S_StopAllChannels();
for (i = 0; i < S_sfx.Size(); ++i)
{
GSnd->UnloadSound(&S_sfx[i]);
S_UnloadSound(&S_sfx[i]);
}
S_sfx.Clear();
@ -1956,7 +2004,7 @@ void AAmbientSound::Activate (AActor *activator)
Destroy ();
return;
}
amb->periodmin = Scale(GSnd->GetMSLength(&S_sfx[sndnum]), TICRATE, 1000);
amb->periodmin = Scale(S_GetMSLength(sndnum), TICRATE, 1000);
}
NextCheck = gametic;

View file

@ -109,7 +109,6 @@ static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fix
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z);
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation);
static sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
static void S_SetListener(SoundListener &listener, AActor *listenactor);
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -393,7 +392,7 @@ void S_Start ()
// First delete the old sound list
for(unsigned i = 1; i < S_sfx.Size(); i++)
{
GSnd->UnloadSound(&S_sfx[i]);
S_UnloadSound(&S_sfx[i]);
}
// Parse the global SNDINFO
@ -482,7 +481,7 @@ void S_PrecacheLevel ()
{
if (!S_sfx[i].bUsed && S_sfx[i].link == sfxinfo_t::NO_LINK)
{
GSnd->UnloadSound (&S_sfx[i]);
S_UnloadSound (&S_sfx[i]);
}
}
}
@ -513,11 +512,26 @@ void S_CacheSound (sfxinfo_t *sfx)
sfx = &S_sfx[sfx->link];
}
sfx->bUsed = true;
GSnd->LoadSound (sfx);
S_LoadSound (sfx);
}
}
}
//==========================================================================
//
// S_UnloadSound
//
//==========================================================================
void S_UnloadSound (sfxinfo_t *sfx)
{
if (sfx->data != NULL)
{
GSnd->UnloadSound(sfx);
DPrintf("Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
}
}
//==========================================================================
//
// S_GetChannel
@ -1168,13 +1182,38 @@ void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, fl
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
{
if (sfx->data == NULL)
while (sfx->data == NULL)
{
GSnd->LoadSound (sfx);
if (sfx->link != sfxinfo_t::NO_LINK)
unsigned int i;
// If the sound doesn't exist, replace it with the empty sound.
if (sfx->lumpnum == -1)
{
sfx = &S_sfx[sfx->link];
sfx->lumpnum = sfx_empty;
}
// See if there is another sound already initialized with this lump. If so,
// then set this one up as a link, and don't load the sound again.
for (i = 0; i < S_sfx.Size(); i++)
{
if (S_sfx[i].data && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum)
{
DPrintf ("Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i);
sfx->link = i;
return &S_sfx[i];
}
}
DPrintf("Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
if (!GSnd->LoadSound (sfx))
{
if (sfx->lumpnum != sfx_empty)
{
sfx->lumpnum = sfx_empty;
continue;
}
}
break;
}
return sfx;
}

View file

@ -351,6 +351,9 @@ int S_AddPlayerSound (const char *playerclass, const int gender, int refid, cons
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false);
void S_ShrinkPlayerSoundLists ();
void S_UnloadSound (sfxinfo_t *sfx);
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
unsigned int S_GetMSLength(FSoundID sound);
// [RH] Prints sound debug info to the screen.
// Modelled after Hexen's noise cheat.

View file

@ -38,7 +38,6 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include "resource.h"
extern HWND Window;
#define USE_WINDOWS_DWORD
#else
@ -50,10 +49,8 @@ extern HWND Window;
#include "fmodsound.h"
#include "c_cvars.h"
#include "i_system.h"
#include "gi.h"
#include "w_wad.h"
#include "i_music.h"
#include "i_musicinterns.h"
#include "v_text.h"
#include "v_palette.h"
@ -91,6 +88,7 @@ static const char *Enum_NameForNum(const FEnumList *list, int num);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
EXTERN_CVAR (String, snd_output)
EXTERN_CVAR (Float, snd_sfxvolume)
EXTERN_CVAR (Float, snd_musicvolume)
EXTERN_CVAR (Int, snd_buffersize)
EXTERN_CVAR (Int, snd_samplerate)
@ -1896,110 +1894,41 @@ void FMODSoundRenderer::UpdateSounds()
//
//==========================================================================
void FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
{
if (sfx->data == NULL)
{
DPrintf("Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
getsfx(sfx);
}
}
void **slot = &sfx->data;
BYTE *sfxdata;
BYTE *sfxstart;
int size;
FMOD_RESULT result;
FMOD_MODE samplemode;
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
FMOD::Sound *sample;
int rolloff;
float mindist, maxdist;
//==========================================================================
//
// FMODSoundRenderer :: UnloadSound
//
//==========================================================================
samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx)
{
if (sfx->data != NULL)
{
((FMOD::Sound *)sfx->data)->release();
sfx->data = NULL;
DPrintf("Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
}
}
//==========================================================================
//
// FMODSoundRenderer :: GetMSLength
//
//==========================================================================
unsigned int FMODSoundRenderer::GetMSLength(sfxinfo_t *sfx)
{
if (sfx->data == NULL)
{
LoadSound(sfx);
}
if (sfx->data != NULL)
{
unsigned int length;
if (((FMOD::Sound *)sfx->data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK)
if (sfx->MaxDistance == 0)
{
return length;
mindist = S_MinDistance;
maxdist = S_MaxDistanceOrRolloffFactor;
rolloff = S_RolloffType;
}
else
{
mindist = sfx->MinDistance;
maxdist = sfx->MaxDistance;
rolloff = sfx->RolloffType;
}
}
return 0; // Don't know.
}
//==========================================================================
//
// FMODSoundRenderer :: DoLoad
//
//==========================================================================
void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
{
BYTE *sfxdata;
BYTE *sfxstart;
int size;
int errcount;
FMOD_RESULT result;
FMOD_MODE samplemode;
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
FMOD::Sound *sample;
int rolloff;
float mindist, maxdist;
samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
if (sfx->MaxDistance == 0)
{
mindist = S_MinDistance;
maxdist = S_MaxDistanceOrRolloffFactor;
rolloff = S_RolloffType;
}
else
{
mindist = sfx->MinDistance;
maxdist = sfx->MaxDistance;
rolloff = sfx->RolloffType;
}
sfxdata = NULL;
errcount = 0;
while (errcount < 2)
{
sfxdata = NULL;
sample = NULL;
if (sfxdata != NULL)
{
delete[] sfxdata;
sfxdata = NULL;
}
if (errcount)
sfx->lumpnum = Wads.GetNumForName("dsempty", ns_sounds);
size = Wads.LumpLength(sfx->lumpnum);
if (size == 0)
{
errcount++;
continue;
}
if (size <= 0) return false;
FWadLump wlump = Wads.OpenLumpNum(sfx->lumpnum);
sfxstart = sfxdata = new BYTE[size];
@ -2046,75 +1975,82 @@ void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
{
exinfo.length = size;
}
if (exinfo.length == 0)
{
DPrintf("Sample has a length of 0\n");
break;
}
result = Sys->createSound((char *)sfxstart, samplemode, &exinfo, &sample);
if (result != FMOD_OK)
else
{
DPrintf("Failed to allocate sample: Error %d\n", result);
errcount++;
continue;
}
*slot = sample;
break;
}
result = Sys->createSound((char *)sfxstart, samplemode, &exinfo, &sample);
if (result != FMOD_OK)
{
DPrintf("Failed to allocate sample: Error %d\n", result);
if (sample != NULL)
{
if (rolloff == ROLLOFF_Log)
if (sfxdata != NULL)
{
delete[] sfxdata;
}
return false;
}
*slot = sample;
}
if (sfxdata != NULL)
{
maxdist = 10000.f;
delete[] sfxdata;
}
sample->set3DMinMaxDistance(mindist, maxdist);
sample->setUserData(sfx);
}
if (sfxdata != NULL)
{
delete[] sfxdata;
if (sample != NULL)
{
if (rolloff == ROLLOFF_Log)
{
maxdist = 10000.f;
}
sample->set3DMinMaxDistance(mindist, maxdist);
sample->setUserData(sfx);
}
}
return sfx->data != NULL;
}
//==========================================================================
//
// FMODSoundRenderer :: getsfx
//
// Get the sound data from the WAD and register it with sound library
// FMODSoundRenderer :: UnloadSound
//
//==========================================================================
void FMODSoundRenderer::getsfx(sfxinfo_t *sfx)
void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx)
{
unsigned int i;
// If the sound doesn't exist, replace it with the empty sound.
if (sfx->lumpnum == -1)
if (sfx->data != NULL)
{
sfx->lumpnum = sfx_empty;
}
// See if there is another sound already initialized with this lump. If so,
// then set this one up as a link, and don't load the sound again.
for (i = 0; i < S_sfx.Size(); i++)
{
if (S_sfx[i].data && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum)
{
DPrintf ("Linked to %s (%d)\n", S_sfx[i].name.GetChars(), i);
sfx->link = i;
return;
}
}
DoLoad(&sfx->data, sfx);
// If the sound failed to load, make it the empty sound.
if (sfx->data == NULL)
{
sfx->lumpnum = sfx_empty;
((FMOD::Sound *)sfx->data)->release();
sfx->data = NULL;
}
}
//==========================================================================
//
// FMODSoundRenderer :: GetMSLength
//
//==========================================================================
unsigned int FMODSoundRenderer::GetMSLength(sfxinfo_t *sfx)
{
if (sfx->data != NULL)
{
unsigned int length;
if (((FMOD::Sound *)sfx->data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK)
{
return length;
}
}
return 0; // Don't know.
}
//==========================================================================
//
// FMODSoundRenderer :: ChannelEndCallback static

View file

@ -13,7 +13,7 @@ public:
void SetSfxVolume (float volume);
void SetMusicVolume (float volume);
void LoadSound (sfxinfo_t *sfx);
bool LoadSound (sfxinfo_t *sfx);
void UnloadSound (sfxinfo_t *sfx);
unsigned int GetMSLength(sfxinfo_t *sfx);
float GetOutputRate();

View file

@ -116,8 +116,9 @@ public:
void SetMusicVolume (float volume)
{
}
void LoadSound (sfxinfo_t *sfx)
bool LoadSound (sfxinfo_t *sfx)
{
return true;
}
void UnloadSound (sfxinfo_t *sfx)
{

View file

@ -91,7 +91,7 @@ public:
virtual void SetSfxVolume (float volume) = 0;
virtual void SetMusicVolume (float volume) = 0;
virtual void LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk
virtual bool LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk
virtual void UnloadSound (sfxinfo_t *sfx) = 0; // unloads a sound from memory
virtual unsigned int GetMSLength(sfxinfo_t *sfx) = 0; // Gets the length of a sound at its default frequency
virtual float GetOutputRate() = 0;