sfxPlayList.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SFXPLAYLIST_H_
  23. #define _SFXPLAYLIST_H_
  24. #ifndef _SFXCOMMON_H_
  25. #include "sfx/sfxCommon.h"
  26. #endif
  27. #ifndef _SFXTRACK_H_
  28. #include "sfx/sfxTrack.h"
  29. #endif
  30. class SFXState;
  31. class SFXDescription;
  32. /// A playback list of SFXTracks.
  33. ///
  34. /// Note that since SFXPlayLists are SFXTracks, play lists can be cascaded.
  35. ///
  36. /// Play lists are comprised of a sequence of slots. Each slot can be assigned
  37. /// a track (SFXProfile or another SFXPlayList) as well as a number of options
  38. /// that determine how the particular slot should behave.
  39. ///
  40. /// In addition to playing a track, each slot can do an arbitrary combination
  41. /// of the following operations:
  42. ///
  43. /// - Wait: wait for the previous or all sources to stop playing
  44. /// - Stop: stop the previous or all sources from playing
  45. /// - Delay: wait some (optionally randomized) amount of time
  46. /// - Shift Pitch: scale pitch when playing by optionally randomized amount
  47. /// - Shift Volume: scale volume when playing by optionally randomized amount
  48. /// - Fade: perform volume fade-in/out
  49. /// - Distance: only start playing track when listener is within a certain range
  50. /// - Loop: loop a set number of times
  51. /// - State: play only when the given SFXState is active; transitions out of
  52. /// slot when state is deactivated
  53. ///
  54. /// The order in which slots are played is either sequential (NotRandom),
  55. /// or a random selection (StrictRandom), or a random ordering (OrderedRandom).
  56. ///
  57. /// Additionally, the list may be looped over in entirety (All) or looped
  58. /// on single slots (useful for either manual playback control or lists that
  59. /// exclusively use states).
  60. ///
  61. /// Be aware that playlists are affected by SFXDescriptions the same way that an
  62. /// SFXProfile is, i.e. fades, looping, 3D sound, etc. all take effect.
  63. ///
  64. /// @note Playlists offer a lot of control but unfortunately they also make it
  65. /// pretty easy at the moment to shoot yourself in the foot.
  66. ///
  67. class SFXPlayList : public SFXTrack
  68. {
  69. public:
  70. typedef SFXTrack Parent;
  71. enum SFXPlaylistSettings
  72. {
  73. /// Number of slots in a playlist.
  74. ///
  75. /// @note To have longer playlists, simply cascade playlists and use
  76. /// wait behaviors.
  77. NUM_SLOTS = 12, // AFX (was 16)
  78. NUM_TRANSITION_MODE_BITS = 3,
  79. NUM_LOOP_MODE_BITS = 1,
  80. NUM_RANDOM_MODE_BITS = 2,
  81. NUM_SLOTS_TO_PLAY_BITS = 5,
  82. NUM_REPLAY_MODE_BITS = 3,
  83. NUM_STATE_MODE_BITS = 2,
  84. };
  85. /// Behavior when description is set to loop.
  86. enum ELoopMode
  87. {
  88. /// Start over after completing a cycle.
  89. LOOP_All,
  90. /// Loop a single slot over and over.
  91. ///
  92. /// @note This behavior is only useful in combination with states or manual
  93. /// playback control. To just loop over a slot for some time, set its loop
  94. /// count instead.
  95. LOOP_Single,
  96. };
  97. /// Random playback mode.
  98. enum ERandomMode
  99. {
  100. /// No randomization of playback order.
  101. RANDOM_NotRandom,
  102. /// Playback order that jumps to a random slot after completing
  103. /// a given slot. The slot being jumped to, however, may be any
  104. /// slot in the list including the slot that has just played.
  105. ///
  106. /// @note In order to ensure cycles are always finite, this mode will
  107. /// also just do NUM_SLOTS number of transitions and then stop the
  108. /// current cycle whether all slots have played or not. Otherwise,
  109. /// it would be dependent on the random number sequence generated when
  110. /// and whether at all a given cycle finishes.
  111. RANDOM_StrictRandom,
  112. /// Before a cycle over the playlist starts, a random total ordering of
  113. /// the slots is established and then played. No slot will be played
  114. /// twice in a single cycle.
  115. RANDOM_OrderedRandom,
  116. };
  117. /// Transitioning behavior when moving in and out of slots.
  118. enum ETransitionMode
  119. {
  120. /// No specific behavior for transitioning between slots.
  121. TRANSITION_None,
  122. /// Wait for single slot to stop playing. If transitioning into slot,
  123. /// this is the slot being transitioned from. If transitioning out of slot,
  124. /// this is the current slot.
  125. TRANSITION_Wait,
  126. /// Wait for all slots to stop playing.
  127. TRANSITION_WaitAll,
  128. /// Stop single slot before proceeding. If transitioning into slot, this
  129. /// is the slot being transitioned from. If transitioning out of slot,
  130. /// this is the current slot.
  131. TRANSITION_Stop,
  132. /// Stop all playing slots before proceeding.
  133. TRANSITION_StopAll,
  134. };
  135. /// Behavior when hitting play() on a slot that is still playing from
  136. /// a previous cycle.
  137. enum EReplayMode
  138. {
  139. /// Do not check if a source is already playing on the slot.
  140. REPLAY_IgnorePlaying,
  141. /// Stop the currently playing source and start playing it from the
  142. /// beginning.
  143. REPLAY_RestartPlaying,
  144. /// Move the currently playing source to the top of the stack and pretend
  145. /// it was started by this cycle.
  146. ///
  147. /// When using STATE_PauseInactive, it is usally best to also use REPLAY_KeepPlaying
  148. /// as otherwise a new source will be spawned when the state becomes active again.
  149. ///
  150. /// @note When the currently playing source is paused, KeepPlaying will
  151. /// resume playback.
  152. REPLAY_KeepPlaying,
  153. /// Let the old source play and start a new one on the same slot.
  154. REPLAY_StartNew,
  155. /// If there is a source currently playing on this slot, skip the play() stage.
  156. REPLAY_SkipIfPlaying,
  157. };
  158. /// State-reaction behavior of slot once a source has started playing.
  159. enum EStateMode
  160. {
  161. /// Stop and remove source when state becomes inactive.
  162. STATE_StopInactive,
  163. /// Pause source when state becomes inactive and resume playback
  164. /// when state becomes active again.
  165. STATE_PauseInactive,
  166. /// Once a source has started to play, it will not be stopped due to
  167. /// state changes. A source will, however, still be prevented from starting
  168. /// to play when its assigned state is not active.
  169. STATE_IgnoreInactive,
  170. };
  171. // All structures here are laid out as structures of arrays instead of arrays of structures
  172. // to allow them to be used as fixed-size TorqueScript arrays.
  173. struct VariantFloat : SFXVariantFloat< NUM_SLOTS >
  174. {
  175. VariantFloat()
  176. {
  177. dMemset( mValue, 0, sizeof( mValue ) );
  178. dMemset( mVariance, 0, sizeof( mVariance ) );
  179. }
  180. };
  181. /// Settings for the playback slots.
  182. struct SlotData
  183. {
  184. /// Behavior when a sound is already playing on a slot from a previous cycle.
  185. EReplayMode mReplayMode[ NUM_SLOTS ];
  186. /// Behavior when transitioning into the slot.
  187. ETransitionMode mTransitionIn[ NUM_SLOTS ];
  188. /// Behavior when transitioning out of the slot.
  189. ETransitionMode mTransitionOut[ NUM_SLOTS ];
  190. /// Seconds to fade sound in. -1 to leave at default.
  191. VariantFloat mFadeTimeIn;
  192. /// Seconds to fade sound out. -1 to leave at default.
  193. VariantFloat mFadeTimeOut;
  194. /// Time to delay before mTransitionIn.
  195. VariantFloat mDelayTimeIn;
  196. /// Time to delay before mTransitionOut.
  197. VariantFloat mDelayTimeOut;
  198. /// Volume scale factor.
  199. VariantFloat mVolumeScale;
  200. /// Pitch scale factor.
  201. VariantFloat mPitchScale;
  202. /// Min distance for 3D sounds.
  203. VariantFloat mMinDistance;
  204. /// Max distance for 3D sounds.
  205. VariantFloat mMaxDistance;
  206. /// Number of times to loop over this slot.
  207. /// @note Each iteration will do a full transition as if proceeding
  208. /// to a different slot.
  209. U32 mRepeatCount[ NUM_SLOTS ];
  210. /// State restriction for this slot. Slot will only play when the given
  211. /// state is active and will be automatically transitioned from
  212. /// if the state becomes inactive.
  213. SFXState* mState[ NUM_SLOTS ];
  214. /// Bahavior when state of this slot is deactivated and the slot's track
  215. /// is playing.
  216. EStateMode mStateMode[ NUM_SLOTS ];
  217. /// Track to play in this slot.
  218. SFXTrack* mTrack[NUM_SLOTS];
  219. SlotData()
  220. {
  221. dMemset( mReplayMode, 0, sizeof( mReplayMode ) );
  222. dMemset( mTransitionIn, 0, sizeof( mTransitionIn ) );
  223. dMemset( mTransitionOut, 0, sizeof( mTransitionOut ) );
  224. dMemset( mRepeatCount, 0, sizeof( mRepeatCount ) );
  225. dMemset( mState, 0, sizeof( mState ) );
  226. dMemset( mTrack, 0, sizeof( mTrack ) );
  227. dMemset( mStateMode, 0, sizeof( mStateMode ) );
  228. for( U32 i = 0; i < NUM_SLOTS; ++ i )
  229. {
  230. mTransitionOut[ i ] = TRANSITION_Wait;
  231. mVolumeScale.mValue[ i ] = 1.f;
  232. mPitchScale.mValue[ i ] = 1.f;
  233. mFadeTimeIn.mValue[ i ] = -1.f; // Don't touch by default.
  234. mFadeTimeOut.mValue[ i ] = -1.f; // Don't touch by default.
  235. mMinDistance.mValue[ i ] = -1.f; // Don't touch by default.
  236. mMaxDistance.mValue[ i ] = -1.f; // Don't touch by default.
  237. }
  238. }
  239. };
  240. public:
  241. // moved to public for soundasset
  242. /// Trace interpreter execution. This field is not networked.
  243. bool mTrace;
  244. /// Select slots at random.
  245. ERandomMode mRandomMode;
  246. /// Loop over slots in this list.
  247. ELoopMode mLoopMode;
  248. /// Number of slots to play from list. This can be used, for example,
  249. /// to create a list of tracks where only a single track is selected and
  250. /// played for each cycle.
  251. U32 mNumSlotsToPlay;
  252. /// Data for each of the playlist slots.
  253. SlotData mSlots;
  254. U32 mActiveSlots;
  255. SFXPlayList();
  256. /// The destructor.
  257. virtual ~SFXPlayList();
  258. /// Make all settings conform to constraints.
  259. void validate();
  260. /// Return true if execution tracing is enabled on this list.
  261. bool trace() const { return mTrace; }
  262. /// Return the number of slots to play from this list in a single cycle.
  263. U32 getNumSlotsToPlay() const { return mNumSlotsToPlay; }
  264. /// Return the slot order randomization behavior.
  265. ERandomMode getRandomMode() const { return mRandomMode; }
  266. /// Return the loop mode (only relevant if this is a looped playlist).
  267. ELoopMode getLoopMode() const { return mLoopMode; }
  268. /// Return the total number of slots in the list.
  269. U32 getNumSlots();
  270. /// Return the slot data for this list.
  271. const SlotData& getSlots() const { return mSlots; }
  272. DECLARE_CONOBJECT( SFXPlayList );
  273. DECLARE_CATEGORY( "SFX" );
  274. DECLARE_DESCRIPTION( "A playback list of SFXProfiles or nested SFXPlayLists." );
  275. // SFXTrack.
  276. virtual bool isLooping() const;
  277. // SimDataBlock.
  278. bool onAdd();
  279. void onRemove();
  280. virtual bool preload( bool server, String& errorStr );
  281. virtual void packData( BitStream* stream );
  282. virtual void unpackData( BitStream* stream );
  283. virtual void inspectPostApply();
  284. static void initPersistFields();
  285. };
  286. typedef SFXPlayList::ELoopMode SFXPlayListLoopMode;
  287. typedef SFXPlayList::ETransitionMode SFXPlayListTransitionMode;
  288. typedef SFXPlayList::EStateMode SFXPlayListStateMode;
  289. typedef SFXPlayList::ERandomMode SFXPlayListRandomMode;
  290. typedef SFXPlayList::EReplayMode SFXPlayListReplayMode;
  291. DefineEnumType( SFXPlayListLoopMode );
  292. DefineEnumType( SFXPlayListTransitionMode );
  293. DefineEnumType( SFXPlayListStateMode );
  294. DefineEnumType( SFXPlayListRandomMode );
  295. DefineEnumType( SFXPlayListReplayMode );
  296. #endif // _SFXPLAYLIST_H_