diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fa2d6dfdc..160e3652f 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 7ed3cdec5..c26ac7bfd 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -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; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 6131dc793..dc627c4b6 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -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; } diff --git a/src/s_sound.h b/src/s_sound.h index 6444b2705..a4c859962 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -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. diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 5c9583d77..46b0dced2 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -38,7 +38,6 @@ #define WIN32_LEAN_AND_MEAN #include #include -#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 diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 5d59a1027..9922faa86 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -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(); diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index af64c77fa..5ea1ae430 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -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) { diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 5f749f4ab..0eae448bc 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -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;