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.

395 lines
8.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef SOUNDINFO_H
  7. #define SOUNDINFO_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "bitbuf.h"
  12. #include "const.h"
  13. #include "soundflags.h"
  14. #include "coordsize.h"
  15. #include "mathlib/vector.h"
  16. #define WRITE_DELTA_UINT( name, length ) \
  17. if ( name == delta->name ) \
  18. buffer.WriteOneBit(0); \
  19. else \
  20. { \
  21. buffer.WriteOneBit(1); \
  22. buffer.WriteUBitLong( name, length ); \
  23. }
  24. #define READ_DELTA_UINT( name, length ) \
  25. if ( buffer.ReadOneBit() != 0 ) \
  26. { name = buffer.ReadUBitLong( length ); }\
  27. else { name = delta->name; }
  28. #define WRITE_DELTA_SINT( name, length ) \
  29. if ( name == delta->name ) \
  30. buffer.WriteOneBit(0); \
  31. else \
  32. { \
  33. buffer.WriteOneBit(1); \
  34. buffer.WriteSBitLong( name, length ); \
  35. }
  36. #define WRITE_DELTA_SINT_SCALE( name, scale, length ) \
  37. if ( name == delta->name ) \
  38. buffer.WriteOneBit(0); \
  39. else \
  40. { \
  41. buffer.WriteOneBit(1); \
  42. buffer.WriteSBitLong( name / scale, length ); \
  43. }
  44. #define READ_DELTA_SINT( name, length ) \
  45. if ( buffer.ReadOneBit() != 0 ) \
  46. { name = buffer.ReadSBitLong( length ); } \
  47. else { name = delta->name; }
  48. #define READ_DELTA_SINT_SCALE( name, scale, length ) \
  49. if ( buffer.ReadOneBit() != 0 ) \
  50. { name = scale * buffer.ReadSBitLong( length ); } \
  51. else { name = delta->name; }
  52. #define SOUND_SEQNUMBER_BITS 10
  53. #define SOUND_SEQNUMBER_MASK ( (1<<SOUND_SEQNUMBER_BITS) - 1 )
  54. // offset sound delay encoding by 60ms since we encode negative sound delays with less precision
  55. // This means any negative sound delay greater than -100ms will get encoded at full precision
  56. #define SOUND_DELAY_OFFSET (0.100f)
  57. #pragma pack(4)
  58. //-----------------------------------------------------------------------------
  59. struct SoundInfo_t
  60. {
  61. int nSequenceNumber;
  62. int nEntityIndex;
  63. int nChannel;
  64. const char *pszName; // UNDONE: Make this a FilenameHandle_t to avoid bugs with arrays of these
  65. Vector vOrigin;
  66. Vector vDirection;
  67. float fVolume;
  68. soundlevel_t Soundlevel;
  69. bool bLooping;
  70. int nPitch;
  71. int nSpecialDSP;
  72. Vector vListenerOrigin;
  73. int nFlags;
  74. int nSoundNum;
  75. float fDelay;
  76. bool bIsSentence;
  77. bool bIsAmbient;
  78. int nSpeakerEntity;
  79. //---------------------------------
  80. SoundInfo_t()
  81. {
  82. SetDefault();
  83. }
  84. void Set(int newEntity, int newChannel, const char *pszNewName, const Vector &newOrigin, const Vector& newDirection,
  85. float newVolume, soundlevel_t newSoundLevel, bool newLooping, int newPitch, const Vector &vecListenerOrigin, int speakerentity )
  86. {
  87. nEntityIndex = newEntity;
  88. nChannel = newChannel;
  89. pszName = pszNewName;
  90. vOrigin = newOrigin;
  91. vDirection = newDirection;
  92. fVolume = newVolume;
  93. Soundlevel = newSoundLevel;
  94. bLooping = newLooping;
  95. nPitch = newPitch;
  96. vListenerOrigin = vecListenerOrigin;
  97. nSpeakerEntity = speakerentity;
  98. }
  99. void SetDefault()
  100. {
  101. fDelay = DEFAULT_SOUND_PACKET_DELAY;
  102. fVolume = DEFAULT_SOUND_PACKET_VOLUME;
  103. Soundlevel = SNDLVL_NORM;
  104. nPitch = DEFAULT_SOUND_PACKET_PITCH;
  105. nSpecialDSP = 0;
  106. nEntityIndex = 0;
  107. nSpeakerEntity = -1;
  108. nChannel = CHAN_STATIC;
  109. nSoundNum = 0;
  110. nFlags = 0;
  111. nSequenceNumber = 0;
  112. pszName = NULL;
  113. bLooping = false;
  114. bIsSentence = false;
  115. bIsAmbient = false;
  116. vOrigin.Init();
  117. vDirection.Init();
  118. vListenerOrigin.Init();
  119. }
  120. void ClearStopFields()
  121. {
  122. fVolume = 0;
  123. Soundlevel = SNDLVL_NONE;
  124. nPitch = PITCH_NORM;
  125. nSpecialDSP = 0;
  126. pszName = NULL;
  127. fDelay = 0.0f;
  128. nSequenceNumber = 0;
  129. vOrigin.Init();
  130. nSpeakerEntity = -1;
  131. }
  132. // this cries for Send/RecvTables:
  133. void WriteDelta( SoundInfo_t *delta, bf_write &buffer)
  134. {
  135. if ( nEntityIndex == delta->nEntityIndex )
  136. {
  137. buffer.WriteOneBit( 0 );
  138. }
  139. else
  140. {
  141. buffer.WriteOneBit( 1 );
  142. if ( nEntityIndex <= 31)
  143. {
  144. buffer.WriteOneBit( 1 );
  145. buffer.WriteUBitLong( nEntityIndex, 5 );
  146. }
  147. else
  148. {
  149. buffer.WriteOneBit( 0 );
  150. buffer.WriteUBitLong( nEntityIndex, MAX_EDICT_BITS );
  151. }
  152. }
  153. WRITE_DELTA_UINT( nSoundNum, MAX_SOUND_INDEX_BITS );
  154. WRITE_DELTA_UINT( nFlags, SND_FLAG_BITS_ENCODE );
  155. WRITE_DELTA_UINT( nChannel, 3 );
  156. buffer.WriteOneBit( bIsAmbient?1:0 );
  157. buffer.WriteOneBit( bIsSentence?1:0 ); // NOTE: SND_STOP behavior is different depending on this flag
  158. if ( nFlags != SND_STOP )
  159. {
  160. if ( nSequenceNumber == delta->nSequenceNumber )
  161. {
  162. // didn't change, most often case
  163. buffer.WriteOneBit( 1 );
  164. }
  165. else if ( nSequenceNumber == (delta->nSequenceNumber+1) )
  166. {
  167. // increased by one
  168. buffer.WriteOneBit( 0 );
  169. buffer.WriteOneBit( 1 );
  170. }
  171. else
  172. {
  173. // send full seqnr
  174. buffer.WriteUBitLong( 0, 2 ); // 2 zero bits
  175. buffer.WriteUBitLong( nSequenceNumber, SOUND_SEQNUMBER_BITS );
  176. }
  177. if ( fVolume == delta->fVolume )
  178. {
  179. buffer.WriteOneBit( 0 );
  180. }
  181. else
  182. {
  183. buffer.WriteOneBit( 1 );
  184. buffer.WriteUBitLong( (unsigned int)(fVolume*127.0f), 7 );
  185. }
  186. WRITE_DELTA_UINT( Soundlevel, MAX_SNDLVL_BITS );
  187. WRITE_DELTA_UINT( nPitch, 8 );
  188. WRITE_DELTA_UINT( nSpecialDSP, 8 );
  189. if ( fDelay == delta->fDelay )
  190. {
  191. buffer.WriteOneBit( 0 );
  192. }
  193. else
  194. {
  195. buffer.WriteOneBit( 1 );
  196. // skipahead works in 10 ms increments
  197. // bias results so that we only incur the precision loss on relatively large skipaheads
  198. fDelay += SOUND_DELAY_OFFSET;
  199. // Convert to msecs
  200. int iDelay = fDelay * 1000.0f;
  201. iDelay = clamp( iDelay, (int)(-10 * MAX_SOUND_DELAY_MSEC), (int)(MAX_SOUND_DELAY_MSEC) );
  202. if ( iDelay < 0 )
  203. {
  204. iDelay /=10;
  205. }
  206. buffer.WriteSBitLong( iDelay , MAX_SOUND_DELAY_MSEC_ENCODE_BITS );
  207. }
  208. // don't transmit sounds with high precision
  209. WRITE_DELTA_SINT_SCALE( vOrigin.x, 8.0f, COORD_INTEGER_BITS - 2 );
  210. WRITE_DELTA_SINT_SCALE( vOrigin.y, 8.0f, COORD_INTEGER_BITS - 2 );
  211. WRITE_DELTA_SINT_SCALE( vOrigin.z, 8.0f, COORD_INTEGER_BITS - 2 );
  212. WRITE_DELTA_SINT( nSpeakerEntity, MAX_EDICT_BITS + 1 );
  213. }
  214. else
  215. {
  216. ClearStopFields();
  217. }
  218. };
  219. void ReadDelta( SoundInfo_t *delta, bf_read &buffer, int nProtoVersion )
  220. {
  221. if ( !buffer.ReadOneBit() )
  222. {
  223. nEntityIndex = delta->nEntityIndex;
  224. }
  225. else
  226. {
  227. if ( buffer.ReadOneBit() )
  228. {
  229. nEntityIndex = buffer.ReadUBitLong( 5 );
  230. }
  231. else
  232. {
  233. nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS );
  234. }
  235. }
  236. if ( nProtoVersion > 22 )
  237. {
  238. READ_DELTA_UINT( nSoundNum, MAX_SOUND_INDEX_BITS );
  239. }
  240. else
  241. {
  242. READ_DELTA_UINT( nSoundNum, 13 );
  243. }
  244. if ( nProtoVersion > 18 )
  245. {
  246. READ_DELTA_UINT( nFlags, SND_FLAG_BITS_ENCODE );
  247. }
  248. else
  249. {
  250. // There was 9 flag bits for version 18 and below (prior to Halloween 2011)
  251. READ_DELTA_UINT( nFlags, 9 );
  252. }
  253. READ_DELTA_UINT( nChannel, 3 );
  254. bIsAmbient = buffer.ReadOneBit() != 0;
  255. bIsSentence = buffer.ReadOneBit() != 0; // NOTE: SND_STOP behavior is different depending on this flag
  256. if ( nFlags != SND_STOP )
  257. {
  258. if ( buffer.ReadOneBit() != 0 )
  259. {
  260. nSequenceNumber = delta->nSequenceNumber;
  261. }
  262. else if ( buffer.ReadOneBit() != 0 )
  263. {
  264. nSequenceNumber = delta->nSequenceNumber + 1;
  265. }
  266. else
  267. {
  268. nSequenceNumber = buffer.ReadUBitLong( SOUND_SEQNUMBER_BITS );
  269. }
  270. if ( buffer.ReadOneBit() != 0 )
  271. {
  272. fVolume = (float)buffer.ReadUBitLong( 7 )/127.0f;
  273. }
  274. else
  275. {
  276. fVolume = delta->fVolume;
  277. }
  278. if ( buffer.ReadOneBit() != 0 )
  279. {
  280. Soundlevel = (soundlevel_t)buffer.ReadUBitLong( MAX_SNDLVL_BITS );
  281. }
  282. else
  283. {
  284. Soundlevel = delta->Soundlevel;
  285. }
  286. READ_DELTA_UINT( nPitch, 8 );
  287. if ( nProtoVersion > 21 )
  288. {
  289. // These bit weren't written in version 19 and below
  290. READ_DELTA_UINT( nSpecialDSP, 8 );
  291. }
  292. if ( buffer.ReadOneBit() != 0 )
  293. {
  294. // Up to 4096 msec delay
  295. fDelay = (float)buffer.ReadSBitLong( MAX_SOUND_DELAY_MSEC_ENCODE_BITS ) / 1000.0f; ;
  296. if ( fDelay < 0 )
  297. {
  298. fDelay *= 10.0f;
  299. }
  300. // bias results so that we only incur the precision loss on relatively large skipaheads
  301. fDelay -= SOUND_DELAY_OFFSET;
  302. }
  303. else
  304. {
  305. fDelay = delta->fDelay;
  306. }
  307. READ_DELTA_SINT_SCALE( vOrigin.x, 8.0f, COORD_INTEGER_BITS - 2 );
  308. READ_DELTA_SINT_SCALE( vOrigin.y, 8.0f, COORD_INTEGER_BITS - 2 );
  309. READ_DELTA_SINT_SCALE( vOrigin.z, 8.0f, COORD_INTEGER_BITS - 2 );
  310. READ_DELTA_SINT( nSpeakerEntity, MAX_EDICT_BITS + 1 );
  311. }
  312. else
  313. {
  314. ClearStopFields();
  315. }
  316. }
  317. };
  318. struct SpatializationInfo_t
  319. {
  320. typedef enum
  321. {
  322. SI_INCREATION = 0,
  323. SI_INSPATIALIZATION
  324. } SPATIALIZATIONTYPE;
  325. // Inputs
  326. SPATIALIZATIONTYPE type;
  327. // Info about the sound, channel, origin, direction, etc.
  328. SoundInfo_t info;
  329. // Requested Outputs ( NULL == not requested )
  330. Vector *pOrigin;
  331. QAngle *pAngles;
  332. float *pflRadius;
  333. };
  334. #pragma pack()
  335. #endif // SOUNDINFO_H