Counter Strike : Global Offensive Source Code
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.

244 lines
6.6 KiB

  1. //===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
  2. //
  3. //
  4. //
  5. //==================================================================================================
  6. #ifndef SOUNDSCHEMA_H
  7. #define SOUNDSCHEMA_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #ifndef SOURCE1
  12. #include "resourcefile/resourcefile.h"
  13. #include "resourcefile/resourcetype.h"
  14. #endif
  15. FORWARD_DECLARE_HANDLE( memhandle_t );
  16. schema struct CEmphasisSample_t
  17. {
  18. public:
  19. TYPEMETA( MNoScatter );
  20. DECLARE_SCHEMA_DATA_CLASS(CEmphasisSample_t)
  21. float32 time;
  22. float32 value;
  23. };
  24. schema struct CBasePhonemeTag_t
  25. {
  26. public:
  27. TYPEMETA( MNoScatter );
  28. DECLARE_SCHEMA_DATA_CLASS(CBasePhonemeTag_t)
  29. float GetStartTime() const { return m_flStartTime; }
  30. float GetEndTime() const { return m_flEndTime; }
  31. int GetPhonemeCode() const { return m_nPhonemeCode; }
  32. public:
  33. float32 m_flStartTime;
  34. float32 m_flEndTime;
  35. uint16 m_nPhonemeCode;
  36. };
  37. // A sentence can be closed captioned
  38. // The default case is the entire sentence shown at start time
  39. //
  40. // "<persist:2.0><clr:255,0,0,0>The <I>default<I> case"
  41. // "<sameline>is the <U>entire<U> sentence shown at <B>start time<B>"
  42. // Commands that aren't closed at end of phrase are automatically terminated
  43. //
  44. // Commands
  45. // <linger:2.0> The line should persist for 2.0 seconds beyond m_flEndTime
  46. // <sameline> Don't go to new line for next phrase on stack
  47. // <clr:r,g,b,a> Push current color onto stack and start drawing with new
  48. // color until we reach the next <clr> marker or a <clr> with no commands which
  49. // means restore the previous color
  50. // <U> Underline text (start/end)
  51. // <I> Italics text (start/end)
  52. // <B> Bold text (start/end)
  53. // <position:where> Draw caption at special location ??? needed
  54. // <cr> Go to new line
  55. // Close Captioning Support
  56. // The phonemes drive the mouth in english, but the CC text can
  57. // be one of several languages
  58. //-----------------------------------------------------------------------------
  59. // Purpose: A sentence is a box of words, and words contain phonemes
  60. //-----------------------------------------------------------------------------
  61. schema class CSentence_t
  62. {
  63. public:
  64. TYPEMETA( MNoScatter );
  65. DECLARE_SCHEMA_DATA_CLASS(CSentence_t)
  66. inline float GetIntensity( float time, float endtime );
  67. inline CEmphasisSample_t *GetBoundedSample( int number, float endtime );
  68. int GetNumSamples( void ) { return m_EmphasisSamples.Count(); }
  69. CEmphasisSample_t *GetSample( int index ) { return &m_EmphasisSamples[ index ]; }
  70. bool GetVoiceDuck() const { return m_bShouldVoiceDuck; }
  71. int GetRuntimePhonemeCount() const { return m_RunTimePhonemes.Count(); }
  72. const CBasePhonemeTag_t *GetRuntimePhoneme( int i ) const { return &m_RunTimePhonemes[ i ]; }
  73. public:
  74. bool m_bShouldVoiceDuck;
  75. CResourceArray< CBasePhonemeTag_t > m_RunTimePhonemes;
  76. // Phoneme emphasis data
  77. CResourceArray< CEmphasisSample_t > m_EmphasisSamples;
  78. };
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. // Input : number -
  82. // Output : CEmphasisSample_t
  83. //-----------------------------------------------------------------------------
  84. inline CEmphasisSample_t *CSentence_t::GetBoundedSample( int number, float endtime )
  85. {
  86. // Search for two samples which span time f
  87. static CEmphasisSample_t nullstart;
  88. nullstart.time = 0.0f;
  89. nullstart.value = 0.5f;
  90. static CEmphasisSample_t nullend;
  91. nullend.time = endtime;
  92. nullend.value = 0.5f;
  93. if ( number < 0 )
  94. {
  95. return &nullstart;
  96. }
  97. else if ( number >= GetNumSamples() )
  98. {
  99. return &nullend;
  100. }
  101. return GetSample( number );
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Purpose:
  105. // Input : time -
  106. // type -
  107. // Output : float
  108. //-----------------------------------------------------------------------------
  109. inline float CSentence_t::GetIntensity( float time, float endtime )
  110. {
  111. float zeroValue = 0.5f;
  112. int c = GetNumSamples();
  113. if ( c <= 0 )
  114. {
  115. return zeroValue;
  116. }
  117. int i;
  118. for ( i = -1 ; i < c; i++ )
  119. {
  120. CEmphasisSample_t *s = GetBoundedSample( i, endtime );
  121. CEmphasisSample_t *n = GetBoundedSample( i + 1, endtime );
  122. if ( !s || !n )
  123. continue;
  124. if ( time >= s->time && time <= n->time )
  125. {
  126. break;
  127. }
  128. }
  129. int prev = i - 1;
  130. int start = i;
  131. int end = i + 1;
  132. int next = i + 2;
  133. prev = MAX( -1, prev );
  134. start = MAX( -1, start );
  135. end = MIN( end, GetNumSamples() );
  136. next = MIN( next, GetNumSamples() );
  137. CEmphasisSample_t *esPre = GetBoundedSample( prev, endtime );
  138. CEmphasisSample_t *esStart = GetBoundedSample( start, endtime );
  139. CEmphasisSample_t *esEnd = GetBoundedSample( end, endtime );
  140. CEmphasisSample_t *esNext = GetBoundedSample( next, endtime );
  141. float dt = esEnd->time - esStart->time;
  142. dt = clamp( dt, 0.01f, 1.0f );
  143. Vector vPre( esPre->time, esPre->value, 0 );
  144. Vector vStart( esStart->time, esStart->value, 0 );
  145. Vector vEnd( esEnd->time, esEnd->value, 0 );
  146. Vector vNext( esNext->time, esNext->value, 0 );
  147. float f2 = ( time - esStart->time ) / ( dt );
  148. f2 = clamp( f2, 0.0f, 1.0f );
  149. Vector vOut;
  150. Catmull_Rom_Spline(
  151. vPre,
  152. vStart,
  153. vEnd,
  154. vNext,
  155. f2,
  156. vOut );
  157. float retval = clamp( vOut.y, 0.0f, 1.0f );
  158. return retval;
  159. }
  160. // Used for bitpacking
  161. struct soundinfoheader_t
  162. {
  163. unsigned int m_Type : 2; // 0 1 2 or 3
  164. unsigned int m_bits : 5; // 0 to 31
  165. unsigned int m_channels : 2; // 1 or 2
  166. unsigned int m_sampleSize : 3; // 1 2 or 4
  167. unsigned int m_format : 2; // 1 == PCM, 2 == ADPCM
  168. unsigned int m_rate : 17; // 0 to 64 K
  169. };
  170. schema struct VSound_t
  171. {
  172. DECLARE_SCHEMA_DATA_CLASS(VSound_t)
  173. uint32 m_bitpackedsoundinfo;
  174. const soundinfoheader_t &info() const { return *(soundinfoheader_t *)&m_bitpackedsoundinfo; };
  175. int m_Type() const { return info().m_Type; };
  176. int m_bits() const { return info().m_bits; };
  177. int m_channels() const { return info().m_channels; };
  178. int m_sampleSize() const { return info().m_sampleSize; };
  179. int m_format() const { return info().m_format; };
  180. int m_rate() const { return info().m_rate; };
  181. int32 m_loopStart; // -1 for no loop
  182. uint32 m_sampleCount;
  183. float32 m_flDuration; // Duration in seconds
  184. // Phoneme stream (optional)
  185. CResourcePointer< CSentence_t > m_Sentence;
  186. // Raw wave header (reinterpreted based on m_Type())
  187. CResourceArray< uint8 > m_pHeader;
  188. uint32 m_nStreamingDataSize;
  189. // Any data after header is the raw sample data (PCM, ADPCM, .mp3, whatever)
  190. uint32 m_nStreamingDataOffset; META( MNoSchema );
  191. memhandle_t m_hStreamDataCacheHandle; META( MNoSchema );
  192. };
  193. #ifndef SOURCE1
  194. #define RESOURCE_TYPE_SOUND RESOURCE_TYPE('s','n','d', 0)
  195. DEFINE_RESOURCE_TYPE( VSound_t, RESOURCE_TYPE_SOUND, HSound, HSoundStrong );
  196. #define SOUND_HANDLE_INVALID ( (HSound)0 )
  197. #endif
  198. #endif // SOUNDSCHEMA_H