Added sound pitch scaling and env_microphone detection for sentences

This commit is contained in:
Blixibon 2021-04-27 10:59:39 -05:00
parent 54c43dd6ce
commit 3cd50a6ed4
5 changed files with 159 additions and 25 deletions

View File

@ -9523,6 +9523,7 @@ void CBaseEntity::RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter
}
}
#ifndef MAPBASE // Moved to SoundEmitterSystem.cpp
//-----------------------------------------------------------------------------
// Purpose: Wrapper to emit a sentence and also a close caption token for the sentence as appropriate.
// Input : filter -
@ -9545,6 +9546,7 @@ void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex,
enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex,
flVolume, iSoundlevel, iFlags, iPitch, 0, pOrigin, pDirection, &dummy, bUpdatePositions, soundtime );
}
#endif
void CBaseEntity::SetRefEHandle( const CBaseHandle &handle )

View File

@ -1563,7 +1563,11 @@ public:
static void EmitCloseCaption( IRecipientFilter& filter, int entindex, char const *token, CUtlVector< Vector >& soundorigins, float duration, bool warnifmissing = false );
static void EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex,
float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM,
const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f );
const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f
#ifdef MAPBASE
, int iSpecialDSP = 0, int iSpeakerIndex = 0 // Needed for env_microphone
#endif
);
static bool IsPrecacheAllowed();
static void SetAllowPrecache( bool allow );

View File

@ -19,6 +19,9 @@
#include "soundflags.h"
#include "engine/IEngineSound.h"
#include "filters.h"
#ifdef MAPBASE
#include "fmtstr.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -27,6 +30,10 @@
const float MICROPHONE_SETTLE_EPSILON = 0.005;
#ifdef MAPBASE
static ConVar sv_microphones_always_pickup_sentences( "sv_microphones_always_pickup_sentences", "0", FCVAR_NONE, "Allows env_microphones to always detect and play back sentences, regardless of their keyvalues." );
#endif
// List of env_microphones who want to be told whenever a sound is started
static CUtlVector< CHandle<CEnvMicrophone> > s_Microphones;
@ -236,7 +243,11 @@ void CEnvMicrophone::InputDisable( inputdata_t &inputdata )
m_bDisabled = true;
if ( m_hSpeaker )
{
#ifdef MAPBASE
CBaseEntity::StopSound( m_hSpeaker->entindex(), m_nChannel, m_szLastSound );
#else
CBaseEntity::StopSound( m_hSpeaker->entindex(), CHAN_STATIC, m_szLastSound );
#endif
m_szLastSound[0] = 0;
// Remove ourselves from the list of active mics
@ -554,31 +565,41 @@ MicrophoneResult_t CEnvMicrophone::SoundPlayed( int entindex, const char *soundn
CPASAttenuationFilter filter( m_hSpeaker );
EmitSound_t ep;
#ifdef MAPBASE
ep.m_nChannel = m_nChannel;
if (m_flVolumeScale != 1.0f)
ep.m_flVolume = (flVolume * m_flVolumeScale);
#else
ep.m_nChannel = CHAN_STATIC;
ep.m_flVolume = flVolume;
#endif
ep.m_pSoundName = soundname;
ep.m_SoundLevel = soundlevel;
ep.m_nFlags = iFlags;
#ifdef MAPBASE
if (m_flPitchScale != 1.0f)
ep.m_nPitch = (int)((float)iPitch * m_flPitchScale);
else
ep.m_nPitch = iPitch;
ep.m_pOrigin = &vecOrigin;
#else
ep.m_nPitch = iPitch;
ep.m_pOrigin = &m_hSpeaker->GetAbsOrigin();
#endif
ep.m_flSoundTime = soundtime;
ep.m_nSpeakerEntity = entindex;
CBaseEntity::EmitSound( filter, m_hSpeaker->entindex(), ep );
#ifdef MAPBASE
if (m_bHearingSentence)
{
CBaseEntity::EmitSentenceByIndex( filter, m_hSpeaker->entindex(), m_nChannel, atoi(soundname), flVolume, soundlevel, 0, iPitch, &vecOrigin, NULL, true, soundtime,
m_iSpeakerDSPPreset, entindex );
}
else
#endif
{
#ifdef MAPBASE
ep.m_nChannel = m_nChannel;
if (m_flVolumeScale != 1.0f)
ep.m_flVolume = (flVolume * m_flVolumeScale);
else
ep.m_flVolume = flVolume;
if (m_flPitchScale != 1.0f)
ep.m_nPitch = (int)((float)iPitch * m_flPitchScale);
else
ep.m_nPitch = iPitch;
ep.m_pOrigin = &vecOrigin;
#else
ep.m_nChannel = CHAN_STATIC;
ep.m_flVolume = flVolume;
ep.m_nPitch = iPitch;
ep.m_pOrigin = &m_hSpeaker->GetAbsOrigin();
#endif
ep.m_pSoundName = soundname;
ep.m_SoundLevel = soundlevel;
ep.m_nFlags = iFlags;
ep.m_flSoundTime = soundtime;
ep.m_nSpeakerEntity = entindex;
CBaseEntity::EmitSound( filter, m_hSpeaker->entindex(), ep );
}
Q_strncpy( m_szLastSound, soundname, sizeof(m_szLastSound) );
m_OnRoutedSound.FireOutput( this, this, 0 );
@ -646,3 +667,56 @@ bool CEnvMicrophone::OnSoundPlayed( int entindex, const char *soundname, soundle
return bSwallowed;
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose: Called by the sound system whenever a sentence is played so that
// active microphones can have a chance to pick up the sound.
// Output : Returns whether or not the sentence was swallowed by the microphone.
// Swallowed sentences should not be played by the sound system.
//-----------------------------------------------------------------------------
bool CEnvMicrophone::OnSentencePlayed( int entindex, int sentenceIndex, soundlevel_t soundlevel, float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins )
{
bool bSwallowed = false;
// Loop through all registered microphones and tell them the sound was just played
int iCount = s_Microphones.Count();
if ( iCount > 0 )
{
CNumStr szSentenceStr( sentenceIndex );
// Iterate backwards because we might be deleting microphones.
for ( int i = iCount - 1; i >= 0; i-- )
{
if ( s_Microphones[i] && (s_Microphones[i]->ShouldHearSentences() || sv_microphones_always_pickup_sentences.GetBool()) )
{
// HACKHACK: Don't want to duplicate all of the code, so just use the same function with a new member variable
s_Microphones[i]->ToggleHearingSentence( true );
MicrophoneResult_t eResult = s_Microphones[i]->SoundPlayed(
entindex,
szSentenceStr,
soundlevel,
flVolume,
iFlags,
iPitch,
pOrigin,
soundtime,
soundorigins );
s_Microphones[i]->ToggleHearingSentence( false );
if ( eResult == MicrophoneResult_Swallow )
{
// Microphone told us to swallow it
bSwallowed = true;
}
else if ( eResult == MicrophoneResult_Remove )
{
s_Microphones.FastRemove( i );
}
}
}
}
return bSwallowed;
}
#endif

View File

@ -20,6 +20,9 @@ const int SF_MICROPHONE_SOUND_BULLET_IMPACT = 0x08;
const int SF_MICROPHONE_SWALLOW_ROUTED_SOUNDS = 0x10;
const int SF_MICROPHONE_SOUND_EXPLOSION = 0x20;
const int SF_MICROPHONE_IGNORE_NONATTENUATED = 0x40;
#ifdef MAPBASE
const int SF_MICROPHONE_SOUND_SENTENCE = 0x80;
#endif
// Return codes from SoundPlayed
@ -50,6 +53,10 @@ public:
void SetSensitivity( float flSensitivity );
void SetSpeakerName( string_t iszSpeakerName );
#ifdef MAPBASE
bool ShouldHearSentences() const { return HasSpawnFlags( SF_MICROPHONE_SOUND_SENTENCE ); }
inline void ToggleHearingSentence( bool bToggle ) { m_bHearingSentence = bToggle; }
#endif
void InputEnable( inputdata_t &inputdata );
void InputDisable( inputdata_t &inputdata );
@ -67,6 +74,12 @@ public:
static bool OnSoundPlayed( int entindex, const char *soundname, soundlevel_t soundlevel,
float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins );
#ifdef MAPBASE
// Same as above, except for sentences.
static bool OnSentencePlayed( int entindex, int sentenceIndex, soundlevel_t soundlevel,
float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins );
#endif
private:
// Per-microphone notification that a sound has played.
@ -91,6 +104,8 @@ private:
float m_flPitchScale = 1.0f;
float m_flVolumeScale = 1.0f;
int m_nChannel = CHAN_STATIC;
bool m_bHearingSentence; // HACKHACK: Allows SoundPlayed() to know when to play a sentence instead
#endif
COutputFloat m_SoundLevel; // Fired when the sampled volume level changes.

View File

@ -1417,6 +1417,45 @@ int SENTENCEG_Lookup(const char *sample)
}
#endif
#if defined(MAPBASE) && defined(GAME_DLL)
//-----------------------------------------------------------------------------
// Purpose: Wrapper to emit a sentence and also a close caption token for the sentence as appropriate.
// Input : filter -
// iEntIndex -
// iChannel -
// iSentenceIndex -
// flVolume -
// iSoundlevel -
// iFlags -
// iPitch -
// bUpdatePositions -
// soundtime -
//-----------------------------------------------------------------------------
void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex,
float flVolume, soundlevel_t iSoundlevel, int iFlags /*= 0*/, int iPitch /*=PITCH_NORM*/,
const Vector *pOrigin /*=NULL*/, const Vector *pDirection /*=NULL*/,
bool bUpdatePositions /*=true*/, float soundtime /*=0.0f*/, int iSpecialDSP /*= 0*/, int iSpeakerIndex /*= 0*/ )
{
CUtlVector< Vector > soundOrigins;
bool bSwallowed = CEnvMicrophone::OnSentencePlayed(
iEntIndex,
iSentenceIndex,
iSoundlevel,
flVolume,
iFlags,
iPitch,
pOrigin,
soundtime,
soundOrigins );
if ( bSwallowed )
return;
enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex,
flVolume, iSoundlevel, iFlags, iPitch * GetSoundPitchScale(), iSpecialDSP, pOrigin, pDirection, &soundOrigins, bUpdatePositions, soundtime, iSpeakerIndex );
}
#endif
void UTIL_EmitAmbientSound( int entindex, const Vector &vecOrigin, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float soundtime /*= 0.0f*/, float *duration /*=NULL*/ )
{
#ifdef STAGING_ONLY