SoundObject.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #ifndef SE_INCL_SOUNDOBJECT_H
  13. #define SE_INCL_SOUNDOBJECT_H
  14. #ifdef PRAGMA_ONCE
  15. #pragma once
  16. #endif
  17. #include <Engine/Base/Lists.h>
  18. #include <Engine/Math/Vector.h>
  19. #include <Engine/Math/Functions.h>
  20. // sound control values
  21. #define SOF_NONE (0L)
  22. #define SOF_LOOP (1L<<0) // looping sound
  23. #define SOF_3D (1L<<1) // has 3d effects
  24. #define SOF_VOLUMETRIC (1L<<2) // no 3d effects inside hot-spot
  25. #define SOF_SURROUND (1L<<3) // surround effect
  26. #define SOF_LOCAL (1L<<4) // local to listener with same entity
  27. #define SOF_SMOOTHCHANGE (1L<<5) // for smooth transition from one sound to another on same channel
  28. #define SOF_MUSIC (1L<<6) // use music-volume master control instead of sound-volume
  29. #define SOF_NONGAME (1L<<7) // game sounds are not mixed while the game is paused
  30. #define SOF_NOFILTER (1L<<8) // used to disable listener-specific filters - i.e. underwater
  31. #define SOF_PAUSED (1L<<28) // playing, but paused (internal)
  32. #define SOF_LOADED (1L<<29) // sound just loaded (internal)
  33. #define SOF_PREPARE (1L<<30) // prepared for playing (internal)
  34. #define SOF_PLAY (1L<<31) // currently playing
  35. // sound parameters
  36. class CSoundParameters {
  37. public:
  38. FLOAT sp_fLeftVolume; // left channel volume (0.0f-1.0f)
  39. FLOAT sp_fRightVolume; // right channel volume
  40. SLONG sp_slLeftFilter; // left channel bass enhance (32767-0, 0=max)
  41. SLONG sp_slRightFilter; // right channel bass enhance
  42. FLOAT sp_fPhaseShift; // right channel(!) delay in seconds (signed! fixint 16:16)
  43. FLOAT sp_fPitchShift; // playing speed factor (>0, 1.0=normal)
  44. FLOAT sp_fDelay; // seconds to wait before actual sound play start
  45. };
  46. // 3d sound parameters
  47. class CSoundParameters3D {
  48. public:
  49. FLOAT sp3_fPitch; // sound pitch 1=normal
  50. FLOAT sp3_fFalloff; // distance when sound can't be heard any more
  51. FLOAT sp3_fHotSpot; // sound at maximum volume
  52. FLOAT sp3_fMaxVolume; // maximum sound volume
  53. };
  54. class ENGINE_API CSoundObject {
  55. public:
  56. // Sound Object Aware class (notify class when direct sound pointer is not valid)
  57. CListNode so_Node; // for linking in list
  58. class CSoundDecoder *so_psdcDecoder; // only for sounds that are mpx/ogg
  59. public: //private:
  60. CSoundData *so_pCsdLink; // linked on SoundData
  61. SLONG so_slFlags; // playing flags
  62. // internal mixer parameters
  63. FLOAT so_fDelayed; // seconds already passed from start playing sound request
  64. FLOAT so_fLastLeftVolume; // volume from previous mixing (for seamless transition)
  65. FLOAT so_fLastRightVolume;
  66. SWORD so_swLastLeftSample; // samples from previous mixing (for filtering purposes)
  67. SWORD so_swLastRightSample;
  68. FLOAT so_fLeftOffset; // current playing offset of left channel
  69. FLOAT so_fRightOffset; // current playing offset of right channel
  70. FLOAT so_fOffsetDelta; // difference between offsets in samples (for seamless transition between phases)
  71. // sound parameters
  72. CEntity *so_penEntity; // entity that owns this sound (may be null)
  73. CSoundParameters so_sp; // currently active parameters
  74. CSoundParameters so_spNew; // parameters to set on next update
  75. CSoundParameters3D so_sp3; // 3d sound parameters
  76. /* Play Buffer */
  77. void PlayBuffer(void);
  78. /* Stop Buffer */
  79. void StopBuffer(void);
  80. /* Update all 3d effects. */
  81. void Update3DEffects(void);
  82. /* Prepare sound */
  83. void PrepareSound(void);
  84. // get proper sound object for predicted events - return NULL the event is already predicted
  85. CSoundObject *GetPredictionTail(ULONG ulTypeID, ULONG ulEventID);
  86. // play sound - internal function - doesn't account for prediction
  87. void Play_internal( CSoundData *pCsdLink, SLONG slFlags);
  88. void Stop_internal(void);
  89. public:
  90. // Constructor
  91. CSoundObject();
  92. // Destructor
  93. ~CSoundObject();
  94. // copy from another object of same class
  95. void Copy(CSoundObject &soOther);
  96. // play sound
  97. void Play( CSoundData *pCsdLink, SLONG slFlags);
  98. // stop playing sound
  99. void Stop( void);
  100. // Pause -> Stop playing sound but keep it linked to data
  101. inline void Pause(void) { so_slFlags |= SOF_PAUSED; };
  102. // Resume -> Resume playing stoped sound
  103. inline void Resume(void) { so_slFlags &= ~SOF_PAUSED; };
  104. // check if sound is playing
  105. inline BOOL IsPlaying(void) {
  106. return (so_slFlags&SOF_PLAY);
  107. };
  108. // check if sound is paused
  109. inline BOOL IsPaused(void) {
  110. return (so_slFlags&SOF_PAUSED);
  111. };
  112. // Check if hooked
  113. inline BOOL IsHooked(void) const { return so_Node.IsLinked(); };
  114. // Set volume
  115. inline void SetVolume( FLOAT fLeftVolume, FLOAT fRightVolume) {
  116. ASSERT( fLeftVolume <= SL_VOLUME_MAX && fLeftVolume >= SL_VOLUME_MIN);
  117. ASSERT( fRightVolume <= SL_VOLUME_MAX && fRightVolume >= SL_VOLUME_MIN);
  118. so_spNew.sp_fLeftVolume = fLeftVolume *(1.0f/SL_VOLUME_MAX);
  119. so_spNew.sp_fRightVolume = fRightVolume*(1.0f/SL_VOLUME_MAX);
  120. };
  121. // Set filter
  122. inline void SetFilter( FLOAT fLeftFilter, FLOAT fRightFilter) { // 1=no filter (>1=more bass)
  123. ASSERT( (fLeftFilter >= 1) && (fRightFilter >= 1));
  124. so_spNew.sp_slLeftFilter = FloatToInt(32767.0/fLeftFilter);
  125. so_spNew.sp_slRightFilter = FloatToInt(32767.0/fRightFilter);
  126. };
  127. // Set pitch shifting
  128. inline void SetPitch( FLOAT fPitch) { // 1.0 for normal (<1 = slower, >1 = faster playing)
  129. ASSERT( fPitch > 0);
  130. so_spNew.sp_fPitchShift = fPitch;
  131. };
  132. // Set phase shifting
  133. inline void SetPhase( FLOAT fPhase) { // right channel delay in seconds (0 = no delay)
  134. ASSERT( (fPhase <= 1) && (fPhase >= -1));
  135. so_spNew.sp_fPhaseShift = fPhase;
  136. };
  137. // Set delay
  138. inline void SetDelay( FLOAT fDelay) { // in seconds (0 = no delay)
  139. ASSERT( fDelay >= 0);
  140. so_spNew.sp_fDelay = fDelay;
  141. };
  142. // Set Position in 3D
  143. inline void SetOwner(CEntity*pen) {
  144. so_penEntity = pen;
  145. };
  146. // Set 3D parameters
  147. void Set3DParameters(FLOAT fMaxDistance, FLOAT fMinDistance, FLOAT fMaxVolume, FLOAT fPitch);
  148. // read/write functions
  149. void Read_t(CTStream *pistr); // throw char *
  150. void Write_t(CTStream *postr); // throw char *
  151. // Obtain sound and play it for this object
  152. void Play_t(const CTFileName &fnmSound, SLONG slFlags); // throw char *
  153. // hard set sound offset in seconds
  154. void SetOffset(FLOAT fOffset);
  155. };
  156. #endif /* include-once check. */