mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-01 00:21:35 +00:00
- Revised underwater effect now uses a lowpass filter in combination with an
optional freeverb unit. - Removed ResetEnvironment hack, since with software reverb, losing the existing reverb when focus is lost isn't a problem. - Commented out the TiMidity FIXME messages. SVN r973 (trunk)
This commit is contained in:
parent
ff4446a3a0
commit
5a066788b5
8 changed files with 139 additions and 31 deletions
|
@ -1,4 +1,9 @@
|
|||
May 14, 2008
|
||||
- Revised underwater effect now uses a lowpass filter in combination with an
|
||||
optional freeverb unit.
|
||||
- Removed ResetEnvironment hack, since with software reverb, losing the
|
||||
existing reverb when focus is lost isn't a problem.
|
||||
- Commented out the TiMidity FIXME messages.
|
||||
- Fixed: FBarShader::GetColumn() passed incorrect information to the software
|
||||
renderer for horizontal bars.
|
||||
|
||||
|
|
|
@ -1142,6 +1142,7 @@ EXTERN_CVAR (Int, snd_buffercount)
|
|||
EXTERN_CVAR (Int, snd_samplerate)
|
||||
EXTERN_CVAR (Bool, snd_hrtf)
|
||||
EXTERN_CVAR (Bool, snd_waterreverb)
|
||||
EXTERN_CVAR (Float, snd_waterlp)
|
||||
EXTERN_CVAR (Int, snd_mididevice)
|
||||
|
||||
static void MakeSoundChanges ();
|
||||
|
@ -1243,6 +1244,7 @@ static menuitem_t SoundItems[] =
|
|||
{ discrete, "MIDI device", {&snd_mididevice}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ discrete, "Underwater reverb", {&snd_waterreverb}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ slider, "Underwater cutoff", {&snd_waterlp}, {0.0}, {2000.0},{50.0}, {NULL} },
|
||||
{ discrete, "Randomize pitches", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ more, "Restart sound", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} },
|
||||
|
|
|
@ -119,6 +119,20 @@ CVAR (String, snd_output_format, "PCM-16", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
CVAR (String, snd_midipatchset, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, snd_profile, false, 0)
|
||||
|
||||
// Underwater low-pass filter cutoff frequency. Set to 0 to disable the filter.
|
||||
CUSTOM_CVAR (Float, snd_waterlp, 250, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
// Clamp to the DSP unit's limits.
|
||||
if (*self < 10 && *self != 0)
|
||||
{
|
||||
self = 10;
|
||||
}
|
||||
else if (*self > 22000)
|
||||
{
|
||||
self = 22000;
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static const ReverbContainer *PrevEnvironment;
|
||||
|
@ -569,6 +583,9 @@ bool FMODSoundRenderer::Init()
|
|||
MusicGroup = NULL;
|
||||
SfxGroup = NULL;
|
||||
PausableSfx = NULL;
|
||||
SfxConnection = NULL;
|
||||
WaterLP = NULL;
|
||||
WaterReverb = NULL;
|
||||
PrevEnvironment = DefaultEnvironments[0];
|
||||
DSPClockLo = 0;
|
||||
DSPClockHi = 0;
|
||||
|
@ -830,9 +847,55 @@ bool FMODSoundRenderer::Init()
|
|||
result = SfxGroup->addGroup(PausableSfx);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
Printf(TEXTCOLOR_BLUE" Could not create attach pausable sfx to sfx channel group. (Error %d)\n", result);
|
||||
Printf(TEXTCOLOR_BLUE" Could not attach pausable sfx to sfx channel group. (Error %d)\n", result);
|
||||
}
|
||||
|
||||
// Create DSP units for underwater effect
|
||||
result = Sys->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &WaterLP);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
Printf(TEXTCOLOR_BLUE" Could not create underwater lowpass unit. (Error %d)\n", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Sys->createDSPByType(FMOD_DSP_TYPE_REVERB, &WaterReverb);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
Printf(TEXTCOLOR_BLUE" Could not create underwater reverb unit. (Error %d)\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect underwater DSP unit between PausableSFX and SFX groups, while
|
||||
// retaining the connection established by SfxGroup->addGroup().
|
||||
if (WaterLP != NULL)
|
||||
{
|
||||
FMOD::DSP *sfx_head, *pausable_head;
|
||||
|
||||
result = SfxGroup->getDSPHead(&sfx_head);
|
||||
result = sfx_head->getInput(0, &pausable_head, &SfxConnection);
|
||||
|
||||
result = WaterLP->addInput(pausable_head, NULL);
|
||||
WaterLP->setActive(false);
|
||||
WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp);
|
||||
WaterLP->setParameter(FMOD_DSP_LOWPASS_RESONANCE, 2);
|
||||
if (WaterReverb != NULL)
|
||||
{
|
||||
FMOD::DSPConnection *dry;
|
||||
result = WaterReverb->addInput(pausable_head, &dry);
|
||||
result = dry->setMix(0.1f);
|
||||
result = WaterReverb->addInput(WaterLP, NULL);
|
||||
result = sfx_head->addInput(WaterReverb, NULL);
|
||||
WaterReverb->setParameter(FMOD_DSP_REVERB_ROOMSIZE, 0.001f);
|
||||
WaterReverb->setParameter(FMOD_DSP_REVERB_DAMP, 0.2f);
|
||||
WaterReverb->setActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = sfx_head->addInput(WaterLP, NULL);
|
||||
}
|
||||
}
|
||||
LastWaterLP = snd_waterlp;
|
||||
|
||||
result = SPC_CreateCodec(Sys);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
|
@ -878,6 +941,16 @@ void FMODSoundRenderer::Shutdown()
|
|||
SfxGroup->release();
|
||||
SfxGroup = NULL;
|
||||
}
|
||||
if (WaterLP != NULL)
|
||||
{
|
||||
WaterLP->release();
|
||||
WaterLP = NULL;
|
||||
}
|
||||
if (WaterReverb != NULL)
|
||||
{
|
||||
WaterReverb->release();
|
||||
WaterReverb = NULL;
|
||||
}
|
||||
|
||||
// Free all loaded samples
|
||||
for (i = 0; i < S_sfx.Size(); i++)
|
||||
|
@ -1490,17 +1563,6 @@ void FMODSoundRenderer::UpdateSoundParams3D(FSoundChan *chan, float pos[3], floa
|
|||
fchan->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: ResetEnvironment
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::ResetEnvironment()
|
||||
{
|
||||
PrevEnvironment = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: UpdateListener
|
||||
|
@ -1549,26 +1611,72 @@ void FMODSoundRenderer::UpdateListener()
|
|||
}
|
||||
else
|
||||
{
|
||||
underwater = (listener->waterlevel == 3 && snd_waterreverb);
|
||||
underwater = (listener->waterlevel == 3 && snd_waterlp);
|
||||
assert (zones != NULL);
|
||||
env = zones[listener->Sector->ZoneNumber].Environment;
|
||||
if (env == NULL)
|
||||
{
|
||||
env = DefaultEnvironments[0];
|
||||
}
|
||||
if (env == DefaultEnvironments[0] && underwater)
|
||||
/* if (env == DefaultEnvironments[0] && underwater)
|
||||
{
|
||||
env = DefaultEnvironments[22];
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (env != PrevEnvironment || env->Modified)
|
||||
{
|
||||
DPrintf ("Reverb Environment %s\n", env->Name);
|
||||
const_cast<ReverbContainer*>(env)->Modified = false;
|
||||
Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties));
|
||||
PausableSfx->setPitch(underwater ? 0.64171f : 1);
|
||||
PrevEnvironment = env;
|
||||
}
|
||||
|
||||
if (underwater)
|
||||
{
|
||||
//PausableSfx->setPitch(0.64171f); // This appears to be what Duke 3D uses
|
||||
PausableSfx->setPitch(0.7937005f); // Approx. 4 semitones lower; what Nash suggesetd
|
||||
if (WaterLP != NULL)
|
||||
{
|
||||
if (LastWaterLP != snd_waterlp)
|
||||
{
|
||||
LastWaterLP = snd_waterlp;
|
||||
WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp);
|
||||
}
|
||||
WaterLP->setActive(true);
|
||||
if (WaterReverb != NULL && snd_waterreverb)
|
||||
{
|
||||
WaterReverb->setActive(true);
|
||||
WaterReverb->setBypass(false);
|
||||
SfxConnection->setMix(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let some of the original mix through so that high frequencies are
|
||||
// not completely lost. The reverb unit has its own connection and
|
||||
// preserves dry sounds itself if used.
|
||||
SfxConnection->setMix(0.1f);
|
||||
if (WaterReverb != NULL)
|
||||
{
|
||||
WaterReverb->setActive(true);
|
||||
WaterReverb->setBypass(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PausableSfx->setPitch(1);
|
||||
if (WaterLP != NULL)
|
||||
{
|
||||
SfxConnection->setMix(1);
|
||||
WaterLP->setActive(false);
|
||||
if (WaterReverb != NULL)
|
||||
{
|
||||
WaterReverb->setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -47,7 +47,6 @@ public:
|
|||
void PrintStatus ();
|
||||
void PrintDriversList ();
|
||||
FString GatherStats ();
|
||||
void ResetEnvironment ();
|
||||
|
||||
void DrawWaveDebug(int mode);
|
||||
|
||||
|
@ -85,6 +84,9 @@ private:
|
|||
FMOD::System *Sys;
|
||||
FMOD::ChannelGroup *SfxGroup, *PausableSfx;
|
||||
FMOD::ChannelGroup *MusicGroup;
|
||||
FMOD::DSP *WaterLP, *WaterReverb;
|
||||
FMOD::DSPConnection *SfxConnection;
|
||||
float LastWaterLP;
|
||||
|
||||
// Just for snd_status display
|
||||
int Driver_MinFrequency;
|
||||
|
|
|
@ -208,10 +208,6 @@ void SoundRenderer::DrawWaveDebug(int mode)
|
|||
{
|
||||
}
|
||||
|
||||
void SoundRenderer::ResetEnvironment ()
|
||||
{
|
||||
}
|
||||
|
||||
SoundStream::~SoundStream ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ public:
|
|||
virtual void PrintStatus () = 0;
|
||||
virtual void PrintDriversList () = 0;
|
||||
virtual FString GatherStats ();
|
||||
virtual void ResetEnvironment ();
|
||||
|
||||
virtual void DrawWaveDebug(int mode);
|
||||
};
|
||||
|
|
|
@ -138,7 +138,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* before TiMidity kills the note. This may be useful to implement
|
||||
* later, but I don't see any urgent need for it.
|
||||
*/
|
||||
Printf("FIXME: Implement \"timeout\" in TiMidity config.\n");
|
||||
//Printf("FIXME: Implement \"timeout\" in TiMidity config.\n");
|
||||
}
|
||||
else if (!strcmp(w[0], "copydrumset") /* "copydrumset" drumset */
|
||||
|| !strcmp(w[0], "copybank")) /* "copybank" bank */
|
||||
|
@ -148,7 +148,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* the current drumset or bank. May be useful later, but not a
|
||||
* high priority.
|
||||
*/
|
||||
Printf("FIXME: Implement \"%s\" in TiMidity config.\n", w[0]);
|
||||
//Printf("FIXME: Implement \"%s\" in TiMidity config.\n", w[0]);
|
||||
}
|
||||
else if (!strcmp(w[0], "undef")) /* "undef" progno */
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* Undefines the tone "progno" of the current tone bank (or
|
||||
* drum set?). Not a high priority.
|
||||
*/
|
||||
Printf("FIXME: Implement \"undef\" in TiMidity config.\n");
|
||||
//Printf("FIXME: Implement \"undef\" in TiMidity config.\n");
|
||||
}
|
||||
else if (!strcmp(w[0], "altassign")) /* "altassign" prog1 prog2 ... */
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* Sets the alternate assign for drum set. Whatever that's
|
||||
* supposed to mean.
|
||||
*/
|
||||
Printf("FIXME: Implement \"altassign\" in TiMidity config.\n");
|
||||
//Printf("FIXME: Implement \"altassign\" in TiMidity config.\n");
|
||||
}
|
||||
else if (!strcmp(w[0], "soundfont"))
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* apparently it sets some sort of base offset for tone numbers.
|
||||
* Why anyone would want to do this is beyond me.
|
||||
*/
|
||||
Printf("FIXME: Implement \"progbase\" in TiMidity config.\n");
|
||||
//Printf("FIXME: Implement \"progbase\" in TiMidity config.\n");
|
||||
}
|
||||
else if (!strcmp(w[0], "map")) /* "map" name set1 elem1 set2 elem2 */
|
||||
{
|
||||
|
@ -271,7 +271,7 @@ static int read_config_file(const char *name, bool ismain)
|
|||
* documentation whatsoever for it, but it looks like it's used
|
||||
* for remapping one instrument to another somehow.
|
||||
*/
|
||||
Printf("FIXME: Implement \"map\" in TiMidity config.\n");
|
||||
//Printf("FIXME: Implement \"map\" in TiMidity config.\n");
|
||||
}
|
||||
|
||||
/* Standard TiMidity config */
|
||||
|
|
|
@ -737,10 +737,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
if (wParam)
|
||||
{
|
||||
SetPriorityClass (GetCurrentProcess (), INGAME_PRIORITY_CLASS);
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
GSnd->ResetEnvironment();
|
||||
}
|
||||
}
|
||||
else if (!noidle && !netgame)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue