diff options
Diffstat (limited to 'engine/audio/private/snd_channels.h')
| -rw-r--r-- | engine/audio/private/snd_channels.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/engine/audio/private/snd_channels.h b/engine/audio/private/snd_channels.h new file mode 100644 index 0000000..06fd065 --- /dev/null +++ b/engine/audio/private/snd_channels.h @@ -0,0 +1,213 @@ +//========= 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 |