Team Fortress 2 Source Code as on 22/4/2020
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.

377 lines
9.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "audio_pch.h"
  8. #include <assert.h>
  9. #include "voice.h"
  10. #include "ivoicecodec.h"
  11. #if defined( _X360 )
  12. #include "xauddefs.h"
  13. #endif
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. // ------------------------------------------------------------------------- //
  17. // CAudioSourceVoice.
  18. // This feeds the data from an incoming voice channel (a guy on the server
  19. // who is speaking) into the sound engine.
  20. // ------------------------------------------------------------------------- //
  21. class CAudioSourceVoice : public CAudioSourceWave
  22. {
  23. public:
  24. CAudioSourceVoice(CSfxTable *pSfx, int iEntity);
  25. virtual ~CAudioSourceVoice();
  26. virtual int GetType( void )
  27. {
  28. return AUDIO_SOURCE_VOICE;
  29. }
  30. virtual void GetCacheData( CAudioSourceCachedInfo *info )
  31. {
  32. Assert( 0 );
  33. }
  34. virtual CAudioMixer *CreateMixer( int initialStreamPosition = 0 );
  35. virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] );
  36. virtual int SampleRate( void );
  37. // Sample size is in bytes. It will not be accurate for compressed audio. This is a best estimate.
  38. // The compressed audio mixers understand this, but in general do not assume that SampleSize() * SampleCount() = filesize
  39. // or even that SampleSize() is 100% accurate due to compression.
  40. virtual int SampleSize( void );
  41. // Total number of samples in this source. NOTE: Some sources are infinite (mic input), they should return
  42. // a count equal to one second of audio at their current rate.
  43. virtual int SampleCount( void );
  44. virtual bool IsVoiceSource() {return true;}
  45. virtual bool IsLooped() {return false;}
  46. virtual bool IsStreaming() {return true;}
  47. virtual bool IsStereoWav() {return false;}
  48. virtual int GetCacheStatus() {return AUDIO_IS_LOADED;}
  49. virtual void CacheLoad() {}
  50. virtual void CacheUnload() {}
  51. virtual CSentence *GetSentence() {return NULL;}
  52. virtual int ZeroCrossingBefore( int sample ) {return sample;}
  53. virtual int ZeroCrossingAfter( int sample ) {return sample;}
  54. // mixer's references
  55. virtual void ReferenceAdd( CAudioMixer *pMixer );
  56. virtual void ReferenceRemove( CAudioMixer *pMixer );
  57. // check reference count, return true if nothing is referencing this
  58. virtual bool CanDelete();
  59. virtual void Prefetch() {}
  60. // Nothing, not a cache object...
  61. virtual void CheckAudioSourceCache() {}
  62. private:
  63. class CWaveDataVoice : public IWaveData
  64. {
  65. public:
  66. CWaveDataVoice( CAudioSourceWave &source ) : m_source(source) {}
  67. ~CWaveDataVoice( void ) {}
  68. virtual CAudioSource &Source( void )
  69. {
  70. return m_source;
  71. }
  72. // this file is in memory, simply pass along the data request to the source
  73. virtual int ReadSourceData( void **pData, int sampleIndex, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] )
  74. {
  75. return m_source.GetOutputData( pData, sampleIndex, sampleCount, copyBuf );
  76. }
  77. virtual bool IsReadyToMix()
  78. {
  79. return true;
  80. }
  81. private:
  82. CAudioSourceWave &m_source; // pointer to source
  83. };
  84. private:
  85. CAudioSourceVoice( const CAudioSourceVoice & );
  86. // Which entity's voice this is for.
  87. int m_iChannel;
  88. // How many mixers are referencing us.
  89. int m_refCount;
  90. };
  91. // ----------------------------------------------------------------------------- //
  92. // Globals.
  93. // ----------------------------------------------------------------------------- //
  94. // The format we sample voice in.
  95. extern WAVEFORMATEX g_VoiceSampleFormat;
  96. class CVoiceSfx : public CSfxTable
  97. {
  98. public:
  99. virtual const char *getname()
  100. {
  101. return "?VoiceSfx";
  102. }
  103. };
  104. static CVoiceSfx g_CVoiceSfx[VOICE_NUM_CHANNELS];
  105. static float g_VoiceOverdriveDuration = 0;
  106. static bool g_bVoiceOverdriveOn = false;
  107. // When voice is on, all other sounds are decreased by this factor.
  108. static ConVar voice_overdrive( "voice_overdrive", "2" );
  109. static ConVar voice_overdrivefadetime( "voice_overdrivefadetime", "0.4" ); // How long it takes to fade in and out of the voice overdrive.
  110. // The sound engine uses this to lower all sound volumes.
  111. // All non-voice sounds are multiplied by this and divided by 256.
  112. int g_SND_VoiceOverdriveInt = 256;
  113. extern int Voice_SamplesPerSec();
  114. extern int Voice_AvgBytesPerSec();
  115. // ----------------------------------------------------------------------------- //
  116. // CAudioSourceVoice implementation.
  117. // ----------------------------------------------------------------------------- //
  118. CAudioSourceVoice::CAudioSourceVoice( CSfxTable *pSfx, int iChannel )
  119. : CAudioSourceWave( pSfx )
  120. {
  121. m_iChannel = iChannel;
  122. m_refCount = 0;
  123. WAVEFORMATEX tmp = g_VoiceSampleFormat;
  124. tmp.nSamplesPerSec = Voice_SamplesPerSec();
  125. tmp.nAvgBytesPerSec = Voice_AvgBytesPerSec();
  126. Init((char*)&tmp, sizeof(tmp));
  127. m_sampleCount = tmp.nSamplesPerSec;
  128. }
  129. CAudioSourceVoice::~CAudioSourceVoice()
  130. {
  131. Voice_OnAudioSourceShutdown( m_iChannel );
  132. }
  133. CAudioMixer *CAudioSourceVoice::CreateMixer( int initialStreamPosition )
  134. {
  135. CWaveDataVoice *pVoice = new CWaveDataVoice(*this);
  136. if(!pVoice)
  137. return NULL;
  138. CAudioMixer *pMixer = CreateWaveMixer( pVoice, WAVE_FORMAT_PCM, 1, BYTES_PER_SAMPLE*8, 0 );
  139. if(!pMixer)
  140. {
  141. delete pVoice;
  142. return NULL;
  143. }
  144. return pMixer;
  145. }
  146. int CAudioSourceVoice::GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] )
  147. {
  148. int nSamplesGotten = Voice_GetOutputData(
  149. m_iChannel,
  150. copyBuf,
  151. AUDIOSOURCE_COPYBUF_SIZE,
  152. samplePosition,
  153. sampleCount );
  154. // If there weren't enough bytes in the received data channel, pad it with zeros.
  155. if( nSamplesGotten < sampleCount )
  156. {
  157. memset( &copyBuf[nSamplesGotten], 0, (sampleCount - nSamplesGotten) * BYTES_PER_SAMPLE );
  158. nSamplesGotten = sampleCount;
  159. }
  160. *pData = copyBuf;
  161. return nSamplesGotten;
  162. }
  163. int CAudioSourceVoice::SampleRate()
  164. {
  165. return Voice_SamplesPerSec();
  166. }
  167. int CAudioSourceVoice::SampleSize()
  168. {
  169. return BYTES_PER_SAMPLE;
  170. }
  171. int CAudioSourceVoice::SampleCount()
  172. {
  173. return Voice_SamplesPerSec();
  174. }
  175. void CAudioSourceVoice::ReferenceAdd(CAudioMixer *pMixer)
  176. {
  177. m_refCount++;
  178. }
  179. void CAudioSourceVoice::ReferenceRemove(CAudioMixer *pMixer)
  180. {
  181. m_refCount--;
  182. if ( m_refCount <= 0 )
  183. delete this;
  184. }
  185. bool CAudioSourceVoice::CanDelete()
  186. {
  187. return m_refCount == 0;
  188. }
  189. // ----------------------------------------------------------------------------- //
  190. // Interface implementation.
  191. // ----------------------------------------------------------------------------- //
  192. bool VoiceSE_Init()
  193. {
  194. if( !snd_initialized )
  195. return false;
  196. g_SND_VoiceOverdriveInt = 256;
  197. return true;
  198. }
  199. void VoiceSE_Term()
  200. {
  201. // Disable voice ducking.
  202. g_SND_VoiceOverdriveInt = 256;
  203. }
  204. void VoiceSE_Idle(float frametime)
  205. {
  206. g_SND_VoiceOverdriveInt = 256;
  207. if( g_bVoiceOverdriveOn )
  208. {
  209. g_VoiceOverdriveDuration = min( g_VoiceOverdriveDuration+frametime, voice_overdrivefadetime.GetFloat() );
  210. }
  211. else
  212. {
  213. if(g_VoiceOverdriveDuration == 0)
  214. return;
  215. g_VoiceOverdriveDuration = max(g_VoiceOverdriveDuration-frametime, 0.f);
  216. }
  217. float percent = g_VoiceOverdriveDuration / voice_overdrivefadetime.GetFloat();
  218. percent = (float)(-cos(percent * 3.1415926535) * 0.5 + 0.5); // Smooth it out..
  219. float voiceOverdrive = 1 + (voice_overdrive.GetFloat() - 1) * percent;
  220. g_SND_VoiceOverdriveInt = (int)(256 / voiceOverdrive);
  221. }
  222. int VoiceSE_StartChannel(
  223. int iChannel, //! Which channel to start.
  224. int iEntity,
  225. bool bProximity,
  226. int nViewEntityIndex )
  227. {
  228. Assert( iChannel >= 0 && iChannel < VOICE_NUM_CHANNELS );
  229. // Start the sound.
  230. CSfxTable *sfx = &g_CVoiceSfx[iChannel];
  231. sfx->pSource = NULL;
  232. Vector vOrigin(0,0,0);
  233. StartSoundParams_t params;
  234. params.staticsound = false;
  235. params.entchannel = (CHAN_VOICE_BASE+iChannel);
  236. params.pSfx = sfx;
  237. params.origin = vOrigin;
  238. params.fvol = 1.0f;
  239. params.flags = 0;
  240. params.pitch = PITCH_NORM;
  241. if ( bProximity == true )
  242. {
  243. params.bUpdatePositions = true;
  244. params.soundlevel = SNDLVL_TALKING;
  245. params.soundsource = iEntity;
  246. }
  247. else
  248. {
  249. params.soundlevel = SNDLVL_IDLE;
  250. params.soundsource = nViewEntityIndex;
  251. }
  252. return S_StartSound( params );
  253. }
  254. void VoiceSE_EndChannel(
  255. int iChannel, //! Which channel to stop.
  256. int iEntity
  257. )
  258. {
  259. Assert( iChannel >= 0 && iChannel < VOICE_NUM_CHANNELS );
  260. S_StopSound( iEntity, CHAN_VOICE_BASE+iChannel );
  261. // Start the sound.
  262. CSfxTable *sfx = &g_CVoiceSfx[iChannel];
  263. sfx->pSource = NULL;
  264. }
  265. void VoiceSE_StartOverdrive()
  266. {
  267. g_bVoiceOverdriveOn = true;
  268. }
  269. void VoiceSE_EndOverdrive()
  270. {
  271. g_bVoiceOverdriveOn = false;
  272. }
  273. void VoiceSE_InitMouth(int entnum)
  274. {
  275. }
  276. void VoiceSE_CloseMouth(int entnum)
  277. {
  278. }
  279. void VoiceSE_MoveMouth(int entnum, short *pSamples, int nSamples)
  280. {
  281. }
  282. CAudioSource* Voice_SetupAudioSource( int soundsource, int entchannel )
  283. {
  284. int iChannel = entchannel - CHAN_VOICE_BASE;
  285. if( iChannel >= 0 && iChannel < VOICE_NUM_CHANNELS )
  286. {
  287. CSfxTable *sfx = &g_CVoiceSfx[iChannel];
  288. return new CAudioSourceVoice( sfx, iChannel );
  289. }
  290. else
  291. return NULL;
  292. }