sfxPlayList.cpp
Engine/source/sfx/sfxPlayList.cpp
Public Defines
define
FOR_EACH_SLOT() ( = 0; < NUM_SLOTS; ++ )
Public Variables
Public Functions
ConsoleDocClass(SFXPlayList , "@brief A datablock describing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playback pattern of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sounds.\n\n</a>" "Playlists allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> define intricate playback patterns of invidual tracks and thus allow the sound system <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be " "easily used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playing multiple sounds in single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">operations.\n\n</a>" "As playlists are % SFXTracks, they can thus be used anywhere in the engine where sound data can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assigned.\n\n</a>" "Each playlist can hold <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> maximum of 16 tracks. Longer playlists may be constructed by cascading lists, i.e. " "by creating <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist that references other <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playlists.\n\n</a>" "Processing of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single playlist slot progresses in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fixed set of steps that are invariably " "iterated through <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each slot(except the slot is assigned <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state and its state is deactivated;in " "this case, the controller will <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a6d2c3c030982c7aa276480da4522ae0f">exit</a> out of the slot directly):\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "< ol >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >delayIn:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Waits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> set amount of time before processing the slot. This is 0 by default and " "is determined by the #delayTimeIn(seconds <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> wait) and #delayTimeInVariance(bounds on randomization) " "properties.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >#transitionIn:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Decides what <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> do @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> before playing the slot. Defaults <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> @c None which makes " "this stage <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> no-operation. Alternatively, the slot can be configured <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playback of other " "slots <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish(@c Wait and @c WaitAll) or <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stop playback of other slots(@c Stop and @c StopAll). " "Note that @c Wait and @c Stop always refer <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> that was last started by the list.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >play:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >< p > Finally, the #track attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the slot is played. However, this will only @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> start " "playback of the track and then immediately move on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the next stage. It will @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> not wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the " "track <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish playing. Note also that depending on the @c replay setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the slot, this " "stage may pick up <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> that is already playing on the slot rather than starting <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> one.</p > " "< p >Several slot properties(fade times, min/max distance, and volume/pitch scale) are used in this stage.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >delayOut:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Waits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> set amount of time before transitioning out of the slot. This works the " "same as @c delayIn and is set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> 0 by default(i.e. no delay).</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >#transitionOut:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Decides what <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> do @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> after playing the slot. This works like #transitionIn.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</ol >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "This is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> key difference <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> playlists in normal music players where upon reaching <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> certain slot, the slot " "will immediately play and the player then wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish before moving on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the next <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n\n</a>" " @note Be aware that time limits set on slot delays are soft limits. The sound system updates sound sources in discrete " "(and equally system update frequency dependent) intervals which thus determines the granularity at which " "time-outs can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">handled.\n\n</a>" " @section SFXPlayList_randomization <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Randomization\n\n</a>" "For greater variety, many of the values <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> individual slots may be given <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> randomization limit that will " "trigger <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dynamic variance of the specified base <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "Any given field @c xyz that may be randomized has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> corresponding field @c xyzVariance which is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> two-dimensional " "vector. The first number specifies the greatest <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> that may be subtracted from the given base <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>(i.e. the @c xyz field) " "whereas the second number specifies the greatest <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> that may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the base value. Between these two limits, " "<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random number is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">generated.\n\n</a>" "The default variance settings of \"0 0\" will thus not allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add or subtract anything from the base <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> and " "effectively disable <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">randomization.\n\n</a>" "Randomization is re-evaluated on each cycle through <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "@section SFXPlayList_states Playlists and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">States\n\n</a>" "A unique aspect of playlists is that they allow their playback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be tied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the changing set of active sound states. " "This feature enables playlists <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> basically connect <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an extensible state machine that can be leveraged by the game " "code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> signal <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> multitude of different gameplay states with the audio system then automatically reacting <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> state " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">transitions.\n\n</a>" "Playlists react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> states in three <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ways:\n</a>" "- Before <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> controller starts processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot it checks whether the slot is assigned <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state. If this is the " " case, the controller checks whether the particular state is active. If it is not, the entire slot is skipped. " "If it is, the controller goes on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n</a>" "- If <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> controller is in one of the delay stages <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state assigned and the state is deactivated, " "the controller will stop the delay and skip any of the remaining processing stages <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n</a>" "- Once the play stage has been processed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state assigned, the slot 's #stateMode will determine " "what happens with the playing sound <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the slot 's state is deactivated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the sound is still <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "A simple example of how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> make use of states in combination with playlists would be <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set up <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> background " "music that reacts <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the mood of the current gameplay situation. For example, during combat, tenser music could play than " "during normal exploration. To set this up, different %SFXStates would represent different moods in the game and the " "background music playlist would have one slot set up <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each such mood. By making use of volume fades and the " " @c PauseWhenDeactivated # stateMode)
ImplementEnumType(SFXPlayListLoopMode , "Playlist behavior when description is set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">loop.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::isLooping\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::loopMode\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListRandomMode , "Randomization pattern <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> playlist slot playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">order.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::random\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListReplayMode , "Behavior when hitting the play stage of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that is still playing from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> previous <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cycle.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::replay\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListStateMode , "Reaction behavior when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state is changed incompatibly on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has already started <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::stateMode\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListTransitionMode , "Playlist behavior when transitioning in and out of invididual <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slots.\n\n</a>" "Transition behaviors apply when the playback controller starts processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist slot and when it ends processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot. Using transition " " behaviors, playback can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">synchronized.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::transitionIn\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::transitionOut\n\n</a>" " @ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
Detailed Description
Public Defines
FOR_EACH_SLOT() ( = 0; < NUM_SLOTS; ++ )
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(SFXPlayList , "@brief A datablock describing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playback pattern of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sounds.\n\n</a>" "Playlists allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> define intricate playback patterns of invidual tracks and thus allow the sound system <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be " "easily used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playing multiple sounds in single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">operations.\n\n</a>" "As playlists are % SFXTracks, they can thus be used anywhere in the engine where sound data can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assigned.\n\n</a>" "Each playlist can hold <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> maximum of 16 tracks. Longer playlists may be constructed by cascading lists, i.e. " "by creating <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist that references other <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playlists.\n\n</a>" "Processing of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single playlist slot progresses in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fixed set of steps that are invariably " "iterated through <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each slot(except the slot is assigned <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state and its state is deactivated;in " "this case, the controller will <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a6d2c3c030982c7aa276480da4522ae0f">exit</a> out of the slot directly):\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "< ol >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >delayIn:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Waits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> set amount of time before processing the slot. This is 0 by default and " "is determined by the #delayTimeIn(seconds <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> wait) and #delayTimeInVariance(bounds on randomization) " "properties.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >#transitionIn:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Decides what <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> do @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> before playing the slot. Defaults <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> @c None which makes " "this stage <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> no-operation. Alternatively, the slot can be configured <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playback of other " "slots <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish(@c Wait and @c WaitAll) or <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stop playback of other slots(@c Stop and @c StopAll). " "Note that @c Wait and @c Stop always refer <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> that was last started by the list.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >play:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >< p > Finally, the #track attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the slot is played. However, this will only @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> start " "playback of the track and then immediately move on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the next stage. It will @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> not wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the " "track <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish playing. Note also that depending on the @c replay setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the slot, this " "stage may pick up <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> that is already playing on the slot rather than starting <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> one.</p > " "< p >Several slot properties(fade times, min/max distance, and volume/pitch scale) are used in this stage.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >delayOut:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Waits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> set amount of time before transitioning out of the slot. This works the " "same as @c delayIn and is set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> 0 by default(i.e. no delay).</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< li >< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >#transitionOut:</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> >< p >Decides what <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> do @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> after playing the slot. This works like #transitionIn.</p ></li >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</ol >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "This is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> key difference <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> playlists in normal music players where upon reaching <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> certain slot, the slot " "will immediately play and the player then wait <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> playback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> finish before moving on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the next <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n\n</a>" " @note Be aware that time limits set on slot delays are soft limits. The sound system updates sound sources in discrete " "(and equally system update frequency dependent) intervals which thus determines the granularity at which " "time-outs can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">handled.\n\n</a>" " @section SFXPlayList_randomization <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Randomization\n\n</a>" "For greater variety, many of the values <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> individual slots may be given <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> randomization limit that will " "trigger <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dynamic variance of the specified base <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "Any given field @c xyz that may be randomized has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> corresponding field @c xyzVariance which is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> two-dimensional " "vector. The first number specifies the greatest <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> that may be subtracted from the given base <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>(i.e. the @c xyz field) " "whereas the second number specifies the greatest <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> that may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the base value. Between these two limits, " "<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random number is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">generated.\n\n</a>" "The default variance settings of \"0 0\" will thus not allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add or subtract anything from the base <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> and " "effectively disable <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">randomization.\n\n</a>" "Randomization is re-evaluated on each cycle through <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "@section SFXPlayList_states Playlists and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">States\n\n</a>" "A unique aspect of playlists is that they allow their playback <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be tied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the changing set of active sound states. " "This feature enables playlists <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> basically connect <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an extensible state machine that can be leveraged by the game " "code <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> signal <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> multitude of different gameplay states with the audio system then automatically reacting <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> state " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">transitions.\n\n</a>" "Playlists react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> states in three <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ways:\n</a>" "- Before <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> controller starts processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot it checks whether the slot is assigned <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state. If this is the " " case, the controller checks whether the particular state is active. If it is not, the entire slot is skipped. " "If it is, the controller goes on <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n</a>" "- If <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> controller is in one of the delay stages <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state assigned and the state is deactivated, " "the controller will stop the delay and skip any of the remaining processing stages <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slot.\n</a>" "- Once the play stage has been processed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> #state assigned, the slot 's #stateMode will determine " "what happens with the playing sound <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the slot 's state is deactivated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the sound is still <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "A simple example of how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> make use of states in combination with playlists would be <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set up <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> background " "music that reacts <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the mood of the current gameplay situation. For example, during combat, tenser music could play than " "during normal exploration. To set this up, different %SFXStates would represent different moods in the game and the " "background music playlist would have one slot set up <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each such mood. By making use of volume fades and the " " @c PauseWhenDeactivated # stateMode)
IMPLEMENT_CO_DATABLOCK_V1(SFXPlayList )
ImplementEnumType(SFXPlayListLoopMode , "Playlist behavior when description is set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">loop.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::isLooping\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::loopMode\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListRandomMode , "Randomization pattern <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> playlist slot playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">order.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::random\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListReplayMode , "Behavior when hitting the play stage of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that is still playing from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> previous <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cycle.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::replay\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListStateMode , "Reaction behavior when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state is changed incompatibly on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot that has already started <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::stateMode\n\n</a>" "@ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
ImplementEnumType(SFXPlayListTransitionMode , "Playlist behavior when transitioning in and out of invididual <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">slots.\n\n</a>" "Transition behaviors apply when the playback controller starts processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> playlist slot and when it ends processing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> slot. Using transition " " behaviors, playback can be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">synchronized.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::transitionIn\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXPlayList::transitionOut\n\n</a>" " @ingroup <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a>" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "sfx/sfxPlayList.h" 25#include "sfx/sfxState.h" 26#include "sfx/sfxTypes.h" 27#include "core/stream/bitStream.h" 28#include "math/mRandom.h" 29#include "math/mathTypes.h" 30 31 32IMPLEMENT_CO_DATABLOCK_V1( SFXPlayList ); 33 34 35ConsoleDocClass( SFXPlayList, 36 "@brief A datablock describing a playback pattern of sounds.\n\n" 37 38 "Playlists allow to define intricate playback patterns of invidual tracks and thus allow the sound system to be " 39 "easily used for playing multiple sounds in single operations.\n\n" 40 41 "As playlists are %SFXTracks, they can thus be used anywhere in the engine where sound data can be assigned.\n\n" 42 43 "Each playlist can hold a maximum of 16 tracks. Longer playlists may be constructed by cascading lists, i.e. " 44 "by creating a playlist that references other playlists.\n\n" 45 46 "Processing of a single playlist slot progresses in a fixed set of steps that are invariably " 47 "iterated through for each slot (except the slot is assigned a state and its state is deactivated; in " 48 "this case, the controller will exit out of the slot directly):\n\n" 49 50 "<ol>\n" 51 "<li><b>delayIn:</b><p>Waits a set amount of time before processing the slot. This is 0 by default and " 52 "is determined by the #delayTimeIn (seconds to wait) and #delayTimeInVariance (bounds on randomization) " 53 "properties.</p></li>\n" 54 "<li><b>#transitionIn:</b><p>Decides what to do @b before playing the slot. Defaults to @c None which makes " 55 "this stage a no-operation. Alternatively, the slot can be configured to wait for playback of other " 56 "slots to finish (@c Wait and @c WaitAll) or to stop playback of other slots (@c Stop and @c StopAll). " 57 "Note that @c Wait and @c Stop always refer to the source that was last started by the list.</p></li>\n" 58 "<li><b>play:</b><p><p>Finally, the #track attached to the slot is played. However, this will only @b start " 59 "playback of the track and then immediately move on to the next stage. It will @b not wait for the " 60 "track to finish playing. Note also that depending on the @c replay setting for the slot, this " 61 "stage may pick up a source that is already playing on the slot rather than starting a new one.</p> " 62 "<p>Several slot properties (fade times, min/max distance, and volume/pitch scale) are used in this stage.</p></li>\n" 63 "<li><b>delayOut:</b><p>Waits a set amount of time before transitioning out of the slot. This works the " 64 "same as @c delayIn and is set to 0 by default (i.e. no delay).</p></li>\n" 65 "<li><b>#transitionOut:</b><p>Decides what to do @b after playing the slot. This works like #transitionIn.</p></li>\n" 66 "</ol>\n\n" 67 68 "This is a key difference to playlists in normal music players where upon reaching a certain slot, the slot " 69 "will immediately play and the player then wait for playback to finish before moving on to the next slot.\n\n" 70 71 "@note Be aware that time limits set on slot delays are soft limits. The sound system updates sound sources in discrete " 72 "(and equally system update frequency dependent) intervals which thus determines the granularity at which " 73 "time-outs can be handled.\n\n" 74 75 "@section SFXPlayList_randomization Value Randomization\n\n" 76 77 "For greater variety, many of the values for individual slots may be given a randomization limit that will " 78 "trigger a dynamic variance of the specified base value.\n\n" 79 80 "Any given field @c xyz that may be randomized has a corresponding field @c xyzVariance which is a two-dimensional " 81 "vector. The first number specifies the greatest value that may be subtracted from the given base value (i.e. the @c xyz field) " 82 "whereas the second number specifies the greatest value that may be added to the base value. Between these two limits, " 83 "a random number is generated.\n\n" 84 85 "The default variance settings of \"0 0\" will thus not allow to add or subtract anything from the base value and " 86 "effectively disable randomization.\n\n" 87 88 "Randomization is re-evaluated on each cycle through a list.\n\n" 89 90 "@section SFXPlayList_states Playlists and States\n\n" 91 92 "A unique aspect of playlists is that they allow their playback to be tied to the changing set of active sound states. " 93 "This feature enables playlists to basically connect to an extensible state machine that can be leveraged by the game " 94 "code to signal a multitude of different gameplay states with the audio system then automatically reacting to state " 95 "transitions.\n\n" 96 97 "Playlists react to states in three ways:\n" 98 99 "- Before a controller starts processing a slot it checks whether the slot is assigned a #state. If this is the " 100 "case, the controller checks whether the particular state is active. If it is not, the entire slot is skipped. " 101 "If it is, the controller goes on to process the slot.\n" 102 "- If a controller is in one of the delay stages for a slot that has a #state assigned and the state is deactivated, " 103 "the controller will stop the delay and skip any of the remaining processing stages for the slot.\n" 104 "- Once the play stage has been processed for a slot that has a #state assigned, the slot's #stateMode will determine " 105 "what happens with the playing sound source if the slot's state is deactivated while the sound is still playing.\n" 106 "\n" 107 108 "A simple example of how to make use of states in combination with playlists would be to set up a playlist for background " 109 "music that reacts to the mood of the current gameplay situation. For example, during combat, tenser music could play than " 110 "during normal exploration. To set this up, different %SFXStates would represent different moods in the game and the " 111 "background music playlist would have one slot set up for each such mood. By making use of volume fades and the " 112 "@c PauseWhenDeactivated #stateMode, smooth transitions between the various audio tracks can be produced.\n\n" 113 114 "@tsexample\n" 115 "// Create a play list from two SFXProfiles.\n" 116 "%playList = new SFXPlayList()\n" 117 "{\n" 118 " // Use a looped description so the list playback will loop.\n" 119 " description = AudioMusicLoop2D;\n" 120 "\n" 121 " track[ 0 ] = Profile1;\n" 122 " track[ 1 ] = Profile2;\n" 123 "};\n" 124 "\n" 125 "// Play the list.\n" 126 "sfxPlayOnce( %playList );\n" 127 "@endtsexample\n\n" 128 129 "@ref SFX_interactive\n\n" 130 131 "@ingroup SFX" 132); 133 134 135ImplementEnumType( SFXPlayListLoopMode, 136 "Playlist behavior when description is set to loop.\n\n" 137 "@see SFXDescription::isLooping\n\n" 138 "@see SFXPlayList::loopMode\n\n" 139 "@ingroup SFX" ) 140 { SFXPlayList::LOOP_All, "All", 141 "Loop over all slots, i.e. jump from last to first slot after all slots have played." }, 142 { SFXPlayList::LOOP_Single, "Single", 143 "Loop infinitely over the current slot. Only useful in combination with either states or manual playlist control." }, 144EndImplementEnumType; 145 146ImplementEnumType( SFXPlayListRandomMode, 147 "Randomization pattern to apply to playlist slot playback order.\n\n" 148 "@see SFXPlayList::random\n\n" 149 "@ingroup SFX" ) 150 { SFXPlayList::RANDOM_NotRandom, "NotRandom", 151 "Play slots in sequential order. No randomization." }, 152 { SFXPlayList::RANDOM_StrictRandom, "StrictRandom", 153 "Play a strictly random selection of slots.\n\n" 154 "In this mode, a set of numSlotsToPlay random numbers between 0 and numSlotsToPlay-1 (inclusive), i.e. in the range of valid slot indices, is " 155 "generated and playlist slots are played back in the order of this list. This allows the same slot to occur multiple times in a list and, " 156 "consequentially, allows for other slots to not appear at all in a given slot ordering." }, 157 { SFXPlayList::RANDOM_OrderedRandom, "OrderedRandom", 158 "Play all slots in the list in a random order.\n\n" 159 "In this mode, the @c numSlotsToPlay slots from the list with valid tracks assigned are put into a random order and played. This guarantees " 160 "that each slots is played exactly once albeit at a random position in the total ordering." }, 161EndImplementEnumType; 162 163ImplementEnumType( SFXPlayListTransitionMode, 164 "Playlist behavior when transitioning in and out of invididual slots.\n\n" 165 "Transition behaviors apply when the playback controller starts processing a playlist slot and when it ends processing a slot. Using transition " 166 "behaviors, playback can be synchronized.\n\n" 167 "@see SFXPlayList::transitionIn\n\n" 168 "@see SFXPlayList::transitionOut\n\n" 169 "@ingroup SFX" ) 170 { SFXPlayList::TRANSITION_None, "None", 171 "No transition. Immediately move on to processing the slot or immediately move on to the next slot." }, 172 { SFXPlayList::TRANSITION_Wait, "Wait", 173 "Wait for the sound source spawned last by this playlist to finish playing. Then proceed." }, 174 { SFXPlayList::TRANSITION_WaitAll, "WaitAll", 175 "Wait for all sound sources currently spawned by the playlist to finish playing. Then proceed." }, 176 { SFXPlayList::TRANSITION_Stop, "Stop", 177 "Stop the sound source spawned last by this playlist. Then proceed." }, 178 { SFXPlayList::TRANSITION_StopAll, "StopAll", 179 "Stop all sound sources spawned by the playlist. Then proceed." }, 180EndImplementEnumType; 181 182ImplementEnumType( SFXPlayListReplayMode, 183 "Behavior when hitting the play stage of a slot that is still playing from a previous cycle.\n\n" 184 "@see SFXPlayList::replay\n\n" 185 "@ingroup SFX" ) 186 { SFXPlayList::REPLAY_IgnorePlaying, "IgnorePlaying", 187 "Ignore any sources that may already be playing on the slot and just create a new source." }, 188 { SFXPlayList::REPLAY_RestartPlaying, "RestartPlaying", 189 "Restart all sources that was last created for the slot." }, 190 { SFXPlayList::REPLAY_KeepPlaying, "KeepPlaying", 191 "Keep playing the current source(s) as if the source started last on the slot was created in this cycle. For this, " 192 "the sources associated with the slot are brought to the top of the play stack." }, 193 { SFXPlayList::REPLAY_StartNew, "StartNew", 194 "Stop all sources currently playing on the slot and then create a new source." }, 195 { SFXPlayList::REPLAY_SkipIfPlaying, "SkipIfPlaying", 196 "If there are sources already playing on the slot, skip the play stage." }, 197EndImplementEnumType; 198 199ImplementEnumType( SFXPlayListStateMode, 200 "Reaction behavior when a state is changed incompatibly on a slot that has already started playing.\n\n" 201 "@see SFXPlayList::stateMode\n\n" 202 "@ingroup SFX" ) 203 { SFXPlayList::STATE_StopInactive, "StopWhenDeactivated", 204 "Stop the sources playing on the slot when a state changes to a setting that is incompatible with " 205 "the slot's state setting." }, 206 { SFXPlayList::STATE_PauseInactive, "PauseWhenDeactivated", 207 "Pause all sources playing on the slot when a state changes to a setting that is incompatible with the " 208 "slot's state setting.\n\n" 209 "When the slot's state is reactivated again, the sources will resume playback." }, 210 { SFXPlayList::STATE_IgnoreInactive, "IgnoreWhenDeactivated", 211 "Ignore when a state changes to a setting incompatible with the slot's state setting and just keep " 212 "playing sources attached to the slot." }, 213EndImplementEnumType; 214 215 216//----------------------------------------------------------------------------- 217 218SFXPlayList::SFXPlayList() 219 : mRandomMode( RANDOM_NotRandom ), 220 mLoopMode( LOOP_All ), 221 mTrace( false ), 222 mNumSlotsToPlay( NUM_SLOTS ) 223{ 224} 225 226//----------------------------------------------------------------------------- 227 228void SFXPlayList::initPersistFields() 229{ 230 addGroup( "Sound" ); 231 232 addField( "random", TYPEID< ERandomMode >(), Offset( mRandomMode, SFXPlayList ), 233 "Slot playback order randomization pattern.\n" 234 "By setting this field to something other than \"NotRandom\" to order in which slots of the " 235 "playlist are processed can be changed from sequential to a random pattern. This allows to " 236 "to create more varied playback patterns.\n" 237 "Defaults to \"NotRandom\"." ); 238 addField( "loopMode", TYPEID< ELoopMode >(), Offset( mLoopMode, SFXPlayList ), 239 "Behavior when description has looping enabled.\n" 240 "The loop mode determines whether the list will loop over a single slot or loop over " 241 "all the entire list of slots being played.\n\n" 242 "@see SFXDescription::isLooping" ); 243 addField( "numSlotsToPlay", TypeS32, Offset( mNumSlotsToPlay, SFXPlayList ), 244 "Number of slots to play.\n" 245 "Up to a maximum of 16, this field determines the number of slots that are taken from the " 246 "list for playback. Only slots that have a valid #track assigned will be considered for " 247 "this." ); 248 249 addArray( "slots", NUM_SLOTS ); 250 251 addField( "track", TypeSFXTrackName, Offset( mSlots.mTrack, SFXPlayList ), NUM_SLOTS, 252 "Track to play in this slot.\n" 253 "This must be set for the slot to be considered for playback. Other settings for a slot " 254 "will not take effect except this field is set." ); 255 addField( "replay", TYPEID< EReplayMode >(), Offset( mSlots.mReplayMode, SFXPlayList ), NUM_SLOTS, 256 "Behavior when an already playing sound is encountered on this slot from a previous cycle.\n" 257 "Each slot can have an arbitrary number of sounds playing on it from previous cycles. This field determines " 258 "how SFXController will handle these sources." ); 259 addField( "transitionIn", TYPEID< ETransitionMode >(), Offset( mSlots.mTransitionIn, SFXPlayList ), NUM_SLOTS, 260 "Behavior when moving into this slot.\n" 261 "After the delayIn time has expired (if any), this slot determines what the controller " 262 "will do before actually playing the slot." ); 263 addField( "transitionOut", TYPEID< ETransitionMode >(), Offset( mSlots.mTransitionOut, SFXPlayList ), NUM_SLOTS, 264 "Behavior when moving out of this slot.\n" 265 "After the #detailTimeOut has expired (if any), this slot determines what the controller " 266 "will do before moving on to the next slot." ); 267 addField( "delayTimeIn", TypeF32, Offset( mSlots.mDelayTimeIn.mValue, SFXPlayList ), NUM_SLOTS, 268 "Seconds to wait after moving into slot before #transitionIn." ); 269 addField( "delayTimeInVariance", TypePoint2F, Offset( mSlots.mDelayTimeIn.mVariance, SFXPlayList ), NUM_SLOTS, 270 "Bounds on randomization of #delayTimeIn.\n\n" 271 "@ref SFXPlayList_randomization\n" ); 272 addField( "delayTimeOut", TypeF32, Offset( mSlots.mDelayTimeOut.mValue, SFXPlayList ), NUM_SLOTS, 273 "Seconds to wait before moving out of slot after #transitionOut." ); 274 addField( "delayTimeOutVariance", TypePoint2F, Offset( mSlots.mDelayTimeOut.mVariance, SFXPlayList ), NUM_SLOTS, 275 "Bounds on randomization of #delayTimeOut.\n\n" 276 "@ref SFXPlayList_randomization\n" ); 277 addField( "fadeTimeIn", TypeF32, Offset( mSlots.mFadeTimeIn.mValue, SFXPlayList ), NUM_SLOTS, 278 "Seconds to fade sound in (-1 to use the track's own fadeInTime.)\n" 279 "@see SFXDescription::fadeTimeIn" ); 280 addField( "fadeTimeInVariance", TypePoint2F, Offset( mSlots.mFadeTimeIn.mVariance, SFXPlayList ), NUM_SLOTS, 281 "Bounds on randomization of #fadeInTime.\n\n" 282 "@ref SFXPlayList_randomization\n" ); 283 addField( "fadeTimeOut", TypeF32, Offset( mSlots.mFadeTimeOut.mValue, SFXPlayList ), NUM_SLOTS, 284 "Seconds to fade sound out (-1 to use the track's own fadeOutTime.)\n" 285 "@see SFXDescription::fadeTimeOut" ); 286 addField( "fadeTimeOutVariance", TypePoint2F, Offset( mSlots.mFadeTimeOut.mVariance, SFXPlayList ), NUM_SLOTS, 287 "Bounds on randomization of #fadeOutTime\n\n" 288 "@ref SFXPlayList_randomization\n" ); 289 addField( "referenceDistance", TypeF32, Offset( mSlots.mMinDistance.mValue, SFXPlayList ), NUM_SLOTS, 290 "@c referenceDistance to set for 3D sounds in this slot (<1 to use @c referenceDistance of track's own description).\n" 291 "@see SFXDescription::referenceDistance" ); 292 addField( "referenceDistanceVariance", TypePoint2F, Offset( mSlots.mMinDistance.mVariance, SFXPlayList ), NUM_SLOTS, 293 "Bounds on randomization of #referenceDistance.\n\n" 294 "@ref SFXPlayList_randomization\n" ); 295 addField( "maxDistance", TypeF32, Offset( mSlots.mMaxDistance.mValue, SFXPlayList ), NUM_SLOTS, 296 "@c maxDistance to apply to 3D sounds in this slot (<1 to use @c maxDistance of track's own description).\n" 297 "@see SFXDescription::maxDistance" ); 298 addField( "maxDistanceVariance", TypePoint2F, Offset( mSlots.mMaxDistance.mVariance, SFXPlayList ), NUM_SLOTS, 299 "Bounds on randomization of #maxDistance.\n\n" 300 "@ref SFXPlayList_randomization\n" ); 301 addField( "volumeScale", TypeF32, Offset( mSlots.mVolumeScale.mValue, SFXPlayList ), NUM_SLOTS, 302 "Scale factor to apply to volume of sounds played on this list slot.\n" 303 "This value will scale the actual volume level set on the track assigned to the slot, i.e. a value of 0.5 will " 304 "cause the track to play at half-volume." ); 305 addField( "volumeScaleVariance", TypePoint2F, Offset( mSlots.mVolumeScale.mVariance, SFXPlayList ), NUM_SLOTS, 306 "Bounds on randomization of #volumeScale.\n\n" 307 "@ref SFXPlayList_randomization\n" ); 308 addField( "pitchScale", TypeF32, Offset( mSlots.mPitchScale.mValue, SFXPlayList ), NUM_SLOTS, 309 "Scale factor to apply to pitch of sounds played on this list slot.\n" 310 "This value will scale the actual pitch set on the track assigned to the slot, i.e. a value of 0.5 will " 311 "cause the track to play at half its assigned speed." ); 312 addField( "pitchScaleVariance", TypePoint2F, Offset( mSlots.mPitchScale.mVariance, SFXPlayList ), NUM_SLOTS, 313 "Bounds on randomization of #pitchScale.\n\n" 314 "@ref SFXPlayList_randomization\n" ); 315 addField( "repeatCount", TypeS32, Offset( mSlots.mRepeatCount, SFXPlayList ), NUM_SLOTS, 316 "Number of times to loop this slot." ); 317 addField( "state", TypeSFXStateName, Offset( mSlots.mState, SFXPlayList ), NUM_SLOTS, 318 "State that must be active for this slot to play.\n\n" 319 "@ref SFXPlayList_states" ); 320 addField( "stateMode", TYPEID< EStateMode >(), Offset( mSlots.mStateMode, SFXPlayList ), NUM_SLOTS, 321 "Behavior when assigned state is deactivated while slot is playing.\n\n" 322 "@ref SFXPlayList_states" ); 323 324 endArray( "slots" ); 325 326 endGroup( "Sound" ); 327 328 addGroup( "Debug" ); 329 330 addField( "trace", TypeBool, Offset( mTrace, SFXPlayList ), 331 "Enable/disable execution tracing for this playlist (local only).\n" 332 "If this is true, SFXControllers attached to the list will automatically run in trace mode." ); 333 334 endGroup( "Debug" ); 335 336 Parent::initPersistFields(); 337} 338 339//----------------------------------------------------------------------------- 340 341bool SFXPlayList::preload( bool server, String& errorStr ) 342{ 343 if( !Parent::preload( server, errorStr ) ) 344 return false; 345 346 validate(); 347 348 // Resolve SFXTracks and SFXStates on client. 349 350 if( !server ) 351 { 352 for( U32 i = 0; i < NUM_SLOTS; ++ i ) 353 { 354 if( !sfxResolve( &mSlots.mTrack[ i ], errorStr ) ) 355 return false; 356 357 if( !sfxResolve( &mSlots.mState[ i ], errorStr ) ) 358 return false; 359 } 360 } 361 362 return true; 363} 364 365//----------------------------------------------------------------------------- 366 367void SFXPlayList::packData( BitStream* stream ) 368{ 369 Parent::packData( stream ); 370 371 stream->writeInt( mRandomMode, NUM_RANDOM_MODE_BITS ); 372 stream->writeInt( mLoopMode, NUM_LOOP_MODE_BITS ); 373 stream->writeInt( mNumSlotsToPlay, NUM_SLOTS_TO_PLAY_BITS ); 374 375 #define FOR_EACH_SLOT \ 376 for( U32 i = 0; i < NUM_SLOTS; ++ i ) 377 378 FOR_EACH_SLOT stream->writeInt( mSlots.mReplayMode[ i ], NUM_REPLAY_MODE_BITS ); 379 FOR_EACH_SLOT stream->writeInt( mSlots.mTransitionIn[ i ], NUM_TRANSITION_MODE_BITS ); 380 FOR_EACH_SLOT stream->writeInt( mSlots.mTransitionOut[ i ], NUM_TRANSITION_MODE_BITS ); 381 FOR_EACH_SLOT stream->writeInt( mSlots.mStateMode[ i ], NUM_STATE_MODE_BITS ); 382 383 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeIn.mValue[ i ] != -1 )) 384 stream->write( mSlots.mFadeTimeIn.mValue[ i ] ); 385 FOR_EACH_SLOT if (stream->writeFlag( mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] > 0)) 386 stream->write(mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] ); 387 FOR_EACH_SLOT if (stream->writeFlag( mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] > 0)) 388 stream->write(mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] ); 389 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mValue[ i ] != -1 )) 390 stream->write( mSlots.mFadeTimeOut.mValue[ i ] ); 391 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][0] > 0)) 392 stream->write(mSlots.mFadeTimeOut.mVariance[i][0]); 393 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mFadeTimeOut.mVariance[i][1] > 0)) 394 stream->write(mSlots.mFadeTimeOut.mVariance[i][1]); 395 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mValue[ i ] > 0)) 396 stream->write(mSlots.mDelayTimeIn.mValue[ i ] ); 397 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] > 0)) 398 stream->write(mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] ); 399 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] > 0)) 400 stream->write(mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] ); 401 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mValue[ i ] > 0)) 402 stream->write(mSlots.mDelayTimeOut.mValue[ i ] ); 403 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] > 0)) 404 stream->write(mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] ); 405 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] > 0)) 406 stream->write(mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] ); 407 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mValue[ i ] != 1)) 408 stream->write(mSlots.mVolumeScale.mValue[ i ] ); 409 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mVariance[ i ][ 0 ] > 0)) 410 stream->write(mSlots.mVolumeScale.mVariance[ i ][ 0 ] ); 411 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mVolumeScale.mVariance[ i ][ 1 ] > 0)) 412 stream->write(mSlots.mVolumeScale.mVariance[ i ][ 1 ] ); 413 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mValue[ i ] != 1)) 414 stream->write(mSlots.mPitchScale.mValue[ i ] ); 415 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mVariance[ i ][ 0 ] > 0)) 416 stream->write(mSlots.mPitchScale.mVariance[ i ][ 0 ] ); 417 FOR_EACH_SLOT if (stream->writeFlag(mSlots.mPitchScale.mVariance[ i ][ 1 ] > 0)) 418 stream->write(mSlots.mPitchScale.mVariance[ i ][ 1 ] ); 419 FOR_EACH_SLOT if (stream->writeFlag( mSlots.mRepeatCount[ i ] > 0)) 420 stream->write( mSlots.mRepeatCount[ i ] ); 421 422 FOR_EACH_SLOT sfxWrite( stream, mSlots.mState[ i ] ); 423 FOR_EACH_SLOT sfxWrite( stream, mSlots.mTrack[ i ] ); 424} 425 426//----------------------------------------------------------------------------- 427 428void SFXPlayList::unpackData( BitStream* stream ) 429{ 430 Parent::unpackData( stream ); 431 432 mRandomMode = ( ERandomMode ) stream->readInt( NUM_RANDOM_MODE_BITS ); 433 mLoopMode = ( ELoopMode ) stream->readInt( NUM_LOOP_MODE_BITS ); 434 mNumSlotsToPlay = stream->readInt( NUM_SLOTS_TO_PLAY_BITS ); 435 436 FOR_EACH_SLOT mSlots.mReplayMode[ i ] = ( EReplayMode ) stream->readInt( NUM_REPLAY_MODE_BITS ); 437 FOR_EACH_SLOT mSlots.mTransitionIn[ i ] = ( ETransitionMode ) stream->readInt( NUM_TRANSITION_MODE_BITS ); 438 FOR_EACH_SLOT mSlots.mTransitionOut[ i ] = ( ETransitionMode ) stream->readInt( NUM_TRANSITION_MODE_BITS ); 439 FOR_EACH_SLOT mSlots.mStateMode[ i ] = ( EStateMode ) stream->readInt( NUM_STATE_MODE_BITS ); 440 441 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mValue[ i ] );} 442 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mVariance[ i ][ 0 ] );} 443 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeIn.mVariance[ i ][ 1 ] );} 444 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mValue[ i ] );} 445 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mVariance[ i ][ 0 ] );} 446 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mFadeTimeOut.mVariance[ i ][ 1 ] );} 447 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mValue[ i ] );} 448 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mVariance[ i ][ 0 ] );} 449 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeIn.mVariance[ i ][ 1 ] );} 450 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mValue[ i ] );} 451 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mVariance[ i ][ 0 ] );} 452 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mDelayTimeOut.mVariance[ i ][ 1 ] );} 453 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mValue[ i ] );} 454 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mVariance[ i ][ 0 ] );} 455 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mVolumeScale.mVariance[ i ][ 1 ] );} 456 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mValue[ i ] );} 457 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mVariance[ i ][ 0 ] );} 458 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mPitchScale.mVariance[ i ][ 1 ] );} 459 FOR_EACH_SLOT if(stream->readFlag()){ stream->read( &mSlots.mRepeatCount[ i ] );} 460 461 FOR_EACH_SLOT sfxRead( stream, &mSlots.mState[ i ] ); 462 FOR_EACH_SLOT sfxRead( stream, &mSlots.mTrack[ i ] ); 463 464 #undef FOR_EACH_SLOT 465} 466 467//----------------------------------------------------------------------------- 468 469void SFXPlayList::inspectPostApply() 470{ 471 Parent::inspectPostApply(); 472 validate(); 473} 474 475//----------------------------------------------------------------------------- 476 477void SFXPlayList::validate() 478{ 479 if( mNumSlotsToPlay > NUM_SLOTS ) 480 mNumSlotsToPlay = NUM_SLOTS; 481 482 mSlots.mFadeTimeIn.validate(); 483 mSlots.mFadeTimeOut.validate(); 484 mSlots.mDelayTimeIn.validate(); 485 mSlots.mDelayTimeOut.validate(); 486 mSlots.mVolumeScale.validate(); 487 mSlots.mPitchScale.validate(); 488} 489