You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
7.6 KiB
214 lines
7.6 KiB
![]()
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#ifndef SND_CHANNELS_H
|
||
|
#define SND_CHANNELS_H
|
||
|
|
||
|
#include "mathlib/vector.h"
|
||
|
|
||
|
#if defined( _WIN32 )
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
class CSfxTable;
|
||
|
class CAudioMixer;
|
||
|
typedef int SoundSource;
|
||
|
|
||
|
// DO NOT REORDER: indices to fvolume arrays in channel_t
|
||
|
|
||
|
#define IFRONT_LEFT 0 // NOTE: must correspond to order of fvolume array below!
|
||
|
#define IFRONT_RIGHT 1
|
||
|
#define IREAR_LEFT 2
|
||
|
#define IREAR_RIGHT 3
|
||
|
#define IFRONT_CENTER 4
|
||
|
#define IFRONT_CENTER0 5 // dummy slot - center channel is mono, but mixers reference volume[1] slot
|
||
|
|
||
|
#define IFRONT_LEFTD 6 // start of doppler right array
|
||
|
#define IFRONT_RIGHTD 7
|
||
|
#define IREAR_LEFTD 8
|
||
|
#define IREAR_RIGHTD 9
|
||
|
#define IFRONT_CENTERD 10
|
||
|
#define IFRONT_CENTERD0 11 // dummy slot - center channel is mono, but mixers reference volume[1] slot
|
||
|
|
||
|
#define CCHANVOLUMES 12
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Each currently playing wave is stored in a channel
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// NOTE: 128bytes. These are memset to zero at some points. Do not add virtuals without changing that pattern.
|
||
|
// UNDONE: now 300 bytes...
|
||
|
struct channel_t
|
||
|
{
|
||
|
int guid; // incremented each time a channel is allocated (to match with channel free in tools, etc.)
|
||
|
int userdata; // user specified data for syncing to tools
|
||
|
|
||
|
CSfxTable *sfx; // the actual sound
|
||
|
CAudioMixer *pMixer; // The sound's instance data for this channel
|
||
|
|
||
|
// speaker channel volumes, indexed using IFRONT_LEFT to IFRONT_CENTER.
|
||
|
// NOTE: never access these fvolume[] elements directly! Use channel helpers in snd_dma.cpp.
|
||
|
|
||
|
float fvolume[CCHANVOLUMES]; // 0.0-255.0 current output volumes
|
||
|
float fvolume_target[CCHANVOLUMES]; // 0.0-255.0 target output volumes
|
||
|
float fvolume_inc[CCHANVOLUMES]; // volume increment, per frame, moves volume[i] to vol_target[i] (per spatialization)
|
||
|
uint nFreeChannelAtSampleTime;
|
||
|
|
||
|
SoundSource soundsource; // see iclientsound.h for description.
|
||
|
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||
|
int speakerentity; // if a sound is being played through a speaker entity (e.g., on a monitor,), this is the
|
||
|
// entity upon which to show the lips moving, if the sound has sentence data
|
||
|
short master_vol; // 0-255 master volume
|
||
|
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||
|
float pitch; // real-time pitch after any modulation or shift by dynamic data
|
||
|
int mixgroups[8]; // sound belongs to these mixgroups: world, actor, player weapon, explosion etc.
|
||
|
int last_mixgroupid;// last mixgroupid selected
|
||
|
float last_vol; // last volume after spatialization
|
||
|
|
||
|
Vector origin; // origin of sound effect
|
||
|
Vector direction; // direction of the sound
|
||
|
float dist_mult; // distance multiplier (attenuation/clipK)
|
||
|
|
||
|
|
||
|
float dspmix; // 0 - 1.0 proportion of dsp to mix with original sound, based on distance
|
||
|
float dspface; // -1.0 - 1.0 (1.0 = facing listener)
|
||
|
float distmix; // 0 - 1.0 proportion based on distance from listner (1.0 - 100% wav right - far)
|
||
|
float dsp_mix_min; // for dspmix calculation - set by current preset in SND_GetDspMix
|
||
|
float dsp_mix_max; // for dspmix calculation - set by current preset in SND_GetDspMix
|
||
|
|
||
|
float radius; // Radius of this sound effect (spatialization is different within the radius)
|
||
|
|
||
|
float ob_gain; // gain drop if sound source obscured from listener
|
||
|
float ob_gain_target; // target gain while crossfading between ob_gain & ob_gain_target
|
||
|
float ob_gain_inc; // crossfade increment
|
||
|
|
||
|
short activeIndex;
|
||
|
char wavtype; // 0 default, CHAR_DOPPLER, CHAR_DIRECTIONAL, CHAR_DISTVARIANT
|
||
|
char pad;
|
||
|
|
||
|
char sample_prev[8]; // last sample(s) in previous input data buffer - space for 2, 16 bit, stereo samples
|
||
|
|
||
|
int initialStreamPosition;
|
||
|
|
||
|
int special_dsp;
|
||
|
|
||
|
union
|
||
|
{
|
||
|
unsigned int flagsword;
|
||
|
struct
|
||
|
{
|
||
|
bool bUpdatePositions : 1; // if true, assume sound source can move and update according to entity
|
||
|
bool isSentence : 1; // true if playing linked sentence
|
||
|
bool bdry : 1; // if true, bypass all dsp processing for this sound (ie: music)
|
||
|
bool bSpeaker : 1; // true if sound is playing through in-game speaker entity.
|
||
|
bool bstereowav : 1; // if true, a stereo .wav file is the sample data source
|
||
|
|
||
|
bool delayed_start : 1; // If true, sound had a delay and so same sound on same channel won't channel steal from it
|
||
|
bool fromserver : 1; // for snd_show, networked sounds get colored differently than local sounds
|
||
|
|
||
|
bool bfirstpass : 1; // true if this is first time sound is spatialized
|
||
|
bool bTraced : 1; // true if channel was already checked this frame for obscuring
|
||
|
bool bfast_pitch : 1; // true if using low quality pitch (fast, but no interpolation)
|
||
|
|
||
|
bool m_bIsFreeingChannel : 1; // true when inside S_FreeChannel - prevents reentrance
|
||
|
bool m_bCompatibilityAttenuation : 1; // True when we want to use goldsrc compatibility mode for the attenuation
|
||
|
// In that case, dist_mul is set to a relatively meaningful value in StartDynamic/StartStaticSound,
|
||
|
// but we interpret it totally differently in SND_GetGain.
|
||
|
bool m_bShouldPause : 1; // if true, sound should pause when the game is paused
|
||
|
bool m_bIgnorePhonemes : 1; // if true, we don't want to drive animation w/ phoneme data
|
||
|
} flags;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
#define MAX_CHANNELS 128
|
||
|
#define MAX_DYNAMIC_CHANNELS 64
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
extern channel_t channels[MAX_CHANNELS];
|
||
|
// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds
|
||
|
// MAX_DYNAMIC_CHANNELS to total_channels = static sounds
|
||
|
|
||
|
extern int total_channels;
|
||
|
|
||
|
class CChannelList
|
||
|
{
|
||
|
public:
|
||
|
int Count();
|
||
|
int GetChannelIndex( int listIndex );
|
||
|
channel_t *GetChannel( int listIndex );
|
||
|
void RemoveChannelFromList( int listIndex );
|
||
|
bool IsQuashed( int listIndex );
|
||
|
|
||
|
int m_count;
|
||
|
short m_list[MAX_CHANNELS];
|
||
|
bool m_quashed[MAX_CHANNELS]; // if true, the channel should be advanced, but not mixed, because it's been heuristically suppressed
|
||
|
|
||
|
CUtlVector< int > m_nSpecialDSPs;
|
||
|
|
||
|
bool m_hasSpeakerChannels : 1;
|
||
|
bool m_hasDryChannels : 1;
|
||
|
bool m_has11kChannels : 1;
|
||
|
bool m_has22kChannels : 1;
|
||
|
bool m_has44kChannels : 1;
|
||
|
};
|
||
|
|
||
|
inline int CChannelList::Count()
|
||
|
{
|
||
|
return m_count;
|
||
|
}
|
||
|
|
||
|
inline int CChannelList::GetChannelIndex( int listIndex )
|
||
|
{
|
||
|
return m_list[listIndex];
|
||
|
}
|
||
|
inline channel_t *CChannelList::GetChannel( int listIndex )
|
||
|
{
|
||
|
return &channels[GetChannelIndex(listIndex)];
|
||
|
}
|
||
|
|
||
|
inline bool CChannelList::IsQuashed( int listIndex )
|
||
|
{
|
||
|
return m_quashed[listIndex];
|
||
|
}
|
||
|
|
||
|
inline void CChannelList::RemoveChannelFromList( int listIndex )
|
||
|
{
|
||
|
// decrease the count by one, and swap the deleted channel with
|
||
|
// the last one.
|
||
|
m_count--;
|
||
|
if ( m_count > 0 && listIndex != m_count )
|
||
|
{
|
||
|
m_list[listIndex] = m_list[m_count];
|
||
|
m_quashed[listIndex] = m_quashed[m_count];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class CActiveChannels
|
||
|
{
|
||
|
public:
|
||
|
void Add( channel_t *pChannel );
|
||
|
void Remove( channel_t *pChannel );
|
||
|
|
||
|
void GetActiveChannels( CChannelList &list );
|
||
|
|
||
|
void Init();
|
||
|
int GetActiveCount() { return m_count; }
|
||
|
private:
|
||
|
int m_count;
|
||
|
short m_list[MAX_CHANNELS];
|
||
|
};
|
||
|
|
||
|
extern CActiveChannels g_ActiveChannels;
|
||
|
|
||
|
//=============================================================================
|
||
|
|
||
|
#endif // SND_CHANNELS_H
|