sfxSource.cpp

Engine/source/sfx/sfxSource.cpp

More...

Public Variables

_sSetTransform1 ("Set the position of the source's 3D sound.\n\n" "@param position The new position in world space.\n" "@note This method has no effect if the source is not a 3D source.", "SFXSource", "void setTransform( Point3F position )")
_sSetTransform2 ("Set the position and orientation of the source's 3D sound.\n\n" "@param position The new position in world space.\n" "@param direction The forward vector.", "SFXSource", "void setTransform( Point3F position, Point3F direction )")

Public Functions

ConsoleDocClass(SFXSource , "@brief Playback controller <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "All sound playback is driven by SFXSources. Each such <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> represents an independent playback controller " "that directly or indirectly affects sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">output.\n\n</a>" "While this class itself is instantiable, such an instance will not by itself emit any sound. This is the " "responsibility of its subclasses. Note, however , that none of these subclasses must be instantiated directly " "but must instead be instantiated indirectly through the <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interface.\n\n</a>" " @section SFXSource_playonce Play-Once <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Sources\n\n</a>" " Often, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> need only exist <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the duration of the sound it is playing. In this case " "so-called \"play-once\" sources simplify the bookkeeping involved by leaving the deletion of " "sources that have expired their playtime <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">system.\n\n</a>" "Play-once sources can be created in either of two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ways:\n</a>" "-  sfxPlayOnce, pause() , and stop() commands <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> them. This allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> easily group sounds " "into logical units that can then be operated on as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">whole.\n\n</a>" "An example of this is the segregation of sounds according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> their use in the game. Volume levels of background " " music, in-game sound effects, and character voices will usually be controlled independently and putting their sounds " "into different hierarchies allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> achieve that <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">easily.\n\n</a>" "The <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> properties that are scaled by parent values <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">are:\n</a>" "- volume, \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "- pitch, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">and\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">priority\n\n</a>" "This means that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> volume of 0. 5, the child will play at half the effective volume it would otherwise " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">have.\n\n</a>" " Additionally, parents affect the playback state of their <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children:\n\n</a>" "- A parent that is in stopped state will force all its direct and indirect children into stopped <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">state.\n</a>" "- A parent that is in paused state will force all its direct and indirect children that are playing into paused state. However, " "children that are in stopped state will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">affected.\n</a>" "- A parent that is in playing state will not affect the playback state of its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n\n</a>" "Each <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> maintains <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state that is wants <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be in which may differ from the state that is enforced on it by its " "parent. If <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent changes its states in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> way that allows <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move into its desired state, the child will do " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">so.\n\n</a>" "For logically grouping sources, instantiate the <a href="/coding/class/classsfxsource/">SFXSource</a> class directly and make other sources children <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> it. A " "<a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> thus instantiated will not effect any real sound output on its own but will influence the sound output of its " "direct and indirect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n\n</a>" " @note Be aware that the property values used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale child property values are the @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> effective values. For example, " "the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale the volume of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child is the @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> effective volume of the parent, i.e. the volume after fades, " "distance attenuation, etc. has been <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">applied.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::sourceGroup\n</a>" " @section SFXSource_volume Volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Attenuation\n\n</a>" "During its lifetime, the volume of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will be continually updated. This update process always progresses " "in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fixed set of steps <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> compute the final effective volume of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> based on the base volume level " "that was either assigned from the <a href="/coding/class/classsfxdescription/">SFXDescription</a> associated with the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a>(SFXDescription::volume) or manually " "set by the user. The process of finding <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's final effective volume is called \"volume attenuation\". The " "steps involved in attenuating <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a>'s volume are (in order):\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dl>\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dt>Fading</dt>\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dd>If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> currently has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-effect applied, the volume is interpolated along the currently active fade curve.</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dt >Modulation</dt >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dd >If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is part of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> hierarchy, it 's volume is scaled according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the effective volume of its parent.</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dt >Distance Attenuation</dt >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dd >If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> 3D sound source, then the volume is interpolated according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the distance model in effect and " "current listener position and orientation(see @ref SFX_3d).</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</dl >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::volume\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::is3d\n</a>" " @section SFXSource_fades Volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Fades\n\n</a>" "To ease-in and ease-out playback of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound, fade effects may be applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sources. A fade will either go from " "zero volume <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> full effective  volume, pause() , and  stop, stop() and the " "end of loop iterations will trigger fade-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">outs.\n\n</a>" "For looping sources, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> SFXDescription::fadeLoops is false, only the initial play() will trigger <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-in and no further " "fading will be applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> loop <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">iterations.\n\n</a>" "By default, the fade durations will be governed by the SFXDescription::fadeInTime and SFXDescription::fadeOutTime properties " "of the <a href="/coding/class/classsfxdescription/">SFXDescription</a> attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source. However, these may be overridden on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> per-<a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> basis by setting fade times " "explicitly with setFadeTimes(). Additionally, the set values may be overridden <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> individual  play, pause() , and stop() " "calls by supplying appropriate fadeInTime/fadeOutTime <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parameters.\n\n</a>" "By default, volume will interpolate linearly during fades. However, custom interpolation curves can be assigned through the " "SFXDescription::fadeInEase and SFXDescription::fadeOutTime <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">properties.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInEase\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutEase\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeLoops\n</a>" " @section SFXSource_cones Sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Cones\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneInsideAngle\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneOutsideAngle\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneOutsideVolume\n</a>" " @section SFXSource_doppler Doppler <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Effect\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sfxGetDopplerFactor\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sfxSetDopplerFactor\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXAmbience::dopplerFactor\n</a>" " @section SFXSource_markers Playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Markers\n\n</a>" "Playback markers allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach notification triggers <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> specific playback positions. Once the " "play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> crosses <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> position <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> which <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> marker is defined, the #onMarkerPassed callback will " "be triggered on the <a href="/coding/class/classsfxsource/">SFXSource</a> thus allowing <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> couple script logic <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Be aware that the precision with which marker callbacks are triggered are bound by global <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> " "update frequency. Thus there may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay between the play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> actually passing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> marker position " "and the callback being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggered.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFX\n</a>" )
DefineEngineMethod(SFXSource , addMarker , void , (String name, F32 pos) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> notification marker called @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> name at @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> pos seconds of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playback.\n\n</a>" "@param name Symbolic name <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the marker that will be passed <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the onMarkerPassed() <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">callback.\n</a>" "@param pos Playback position in seconds when the notification should trigger. Note that this is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> soft limit and there " "may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay between the play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> actually passing the position and the callback being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggered.\n\n</a>" "@note For looped sounds, the marker will trigger on each <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">iteration.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" " $source)
DefineEngineMethod(SFXSource , addParameter , void , (SFXParameter *parameter) , "Attach @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source, \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Once attached, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> changes of the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter. Attaching <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter " "will also trigger an initial read-out of the parameter 's current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" " @param parameter The parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source." )
DefineEngineMethod(SFXSource , getAttenuatedVolume , F32 , () , "Get the final effective volume level of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "This method returns the volume level as it is after <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group volume modulation, fades , and distance-based " "volume attenuation have been applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the base volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">level.\n\n</a>" " @return The effective volume of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" " @ref SFXSource_volume" )
DefineEngineMethod(SFXSource , getFadeInTime , F32 , () , "Get the fade-in time set on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This will initially be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime.\n\n</a>" "@return The fade-in time set on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n\n</a>" "@ref SFXSource_fades" )
DefineEngineMethod(SFXSource , getFadeOutTime , F32 , () , "Get the fade-out time set on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This will initially be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime.\n\n</a>" "@return The fade-out time set on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n\n</a>" "@ref SFXSource_fades" )
DefineEngineMethod(SFXSource , getParameter , SFXParameter * , (S32 index) )
DefineEngineMethod(SFXSource , getParameterCount , S32 , () )
DefineEngineMethod(SFXSource , getPitch , F32 , () , "Get the pitch scale of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "Pitch determines the playback speed of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> (default: 1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@return The current pitch scale factor of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setPitch\n</a>" "@see SFXDescription::pitch" )
DefineEngineMethod(SFXSource , getStatus , SFXStatus , () , "Get the current playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">status.\n</a>" "@return Te current playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">status\n</a>" )
DefineEngineMethod(SFXSource , getVolume , F32 , () , "Get the current base volume level of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This is not the final effective volume that the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is playing at but rather the starting " "volume level before <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group modulation, fades , or distance-based volume attenuation are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">applied.\n\n</a>" " @return The current base volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">level.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setVolume\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::volume\n\n</a>" " @ref SFXSource_volume" )
DefineEngineMethod(SFXSource , isPaused , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">paused.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in paused state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pause\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )
DefineEngineMethod(SFXSource , isPlaying , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in playing state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">play\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )
DefineEngineMethod(SFXSource , isStopped , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stopped.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in stopped state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stop\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )
DefineEngineMethod(SFXSource , pause , void , (F32 fadeOutTime) , (-1.0f) , "Pause playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeOutTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> fade down <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> zero volume. If - 1, the SFXDescription::fadeOutTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect that may be " "configured on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description.\n</a>" "Be aware that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect is used, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will not immediately <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> paused state but will " "rather remain in playing state until the fade-out time has expired.." )
DefineEngineMethod(SFXSource , play , void , (F32 fadeInTime) , (-1.0f) , "Start playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "If the sound data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> has not yet been fully loaded, there will be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay after calling " "play and playback will start after the data has become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">available.\n\n</a>" " @param fadeInTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> reach full volume. If - 1, the SFXDescription::fadeInTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-in effect that may " "be configured on the description." )
DefineEngineMethod(SFXSource , removeParameter , void , (SFXParameter *parameter) , "Detach @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "Once detached, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will no longer react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> changes of the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parameter.\n\n</a>" "If the parameter is not attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source, the method will do <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">nothing.\n\n</a>" " @param parameter The parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> detach from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" )
DefineEngineMethod(SFXSource , setCone , void , (F32 innerAngle, F32 outerAngle, F32 outsideVolume) , "Set up the 3D volume cone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "@param innerAngle Angle of the inner sound cone in degrees (@ref SFXDescription::coneInsideAngle). Must be 0<=innerAngle<=360.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param outerAngle Angle of the outer sound cone in degrees (@ref SFXDescription::coneOutsideAngle). Must be 0<=outerAngle<=360.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param outsideVolume Volume scale factor outside of outer cone (@ref SFXDescription::coneOutsideVolume). Must be 0<=outsideVolume<=1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@note This method has no effect on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is not 3<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">D.\n\n</a>" )
DefineEngineMethod(SFXSource , setFadeTimes , void , (F32 fadeInTime, F32 fadeOutTime) , "Set the fade time parameters of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeInTime The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> fade-in time in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n</a>" "@param fadeOutTime The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> fade-out time in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n\n</a>" "@ref SFXSource_fades" )
DefineEngineMethod(SFXSource , setPitch , void , (F32 pitch) , "Set the pitch scale of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "Pitch determines the playback speed of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> (default: 1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param pitch The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> pitch scale <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">factor.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getPitch\n</a>" "@see SFXDescription::pitch" )
DefineEngineMethod(SFXSource , setTransform , void , (const char *position, const char *direction) , ("") , "( vector position [, vector direction ] ) " "Set the position and orientation of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> 3D sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@hide" )
DefineEngineMethod(SFXSource , setVolume , void , (F32 volume) , "Set the base volume level <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This volume will be the starting point <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group volume modulation, fades , and distance-based " "volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">attenuation.\n\n</a>" " @param volume The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> base volume level <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the source. Must be 0 >=volume<=1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getVolume\n\n</a>" " @ref SFXSource_volume" )
DefineEngineMethod(SFXSource , stop , void , (F32 fadeOutTime) , (-1.0f) , "Stop playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeOutTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> fade down <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> zero volume. If - 1, the SFXDescription::fadeOutTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect that may be " "configured on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description.\n</a>" "Be aware that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect is used, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will not immediately transtion <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stopped state but " "will rather remain in playing state until the fade-out time has expired." )
IMPLEMENT_CALLBACK(SFXSource , onParameterValueChange , void , (SFXParameter *parameter) , (parameter) , "Called when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> changes <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n</a>" "This callback will be triggered before the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> change has actually been applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param parameter The parameter that has changed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n</a>" "@note This is also triggered when the parameter is first attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source." )
IMPLEMENT_CALLBACK(SFXSource , onStatusChange , void , (SFXStatus newStatus) , (newStatus) , "Called when the playback status of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changes.\n</a>" "@param newStatus The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> playback status." )

Detailed Description

Public Variables

ConsoleDocFragment _sSetTransform1 ("Set the position of the source's 3D sound.\n\n" "@param position The new position in world space.\n" "@note This method has no effect if the source is not a 3D source.", "SFXSource", "void setTransform( Point3F position )")
ConsoleDocFragment _sSetTransform2 ("Set the position and orientation of the source's 3D sound.\n\n" "@param position The new position in world space.\n" "@param direction The forward vector.", "SFXSource", "void setTransform( Point3F position, Point3F direction )")

Public Functions

ConsoleDocClass(SFXSource , "@brief Playback controller <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "All sound playback is driven by SFXSources. Each such <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> represents an independent playback controller " "that directly or indirectly affects sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">output.\n\n</a>" "While this class itself is instantiable, such an instance will not by itself emit any sound. This is the " "responsibility of its subclasses. Note, however , that none of these subclasses must be instantiated directly " "but must instead be instantiated indirectly through the <a href="/coding/file/sfxsystem_8h/#sfxsystem_8h_1a52e87f85ae30be82ffefd31b5c03e03d">SFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interface.\n\n</a>" " @section SFXSource_playonce Play-Once <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Sources\n\n</a>" " Often, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> need only exist <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the duration of the sound it is playing. In this case " "so-called \"play-once\" sources simplify the bookkeeping involved by leaving the deletion of " "sources that have expired their playtime <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">system.\n\n</a>" "Play-once sources can be created in either of two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ways:\n</a>" "-  sfxPlayOnce, pause() , and stop() commands <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> them. This allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> easily group sounds " "into logical units that can then be operated on as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">whole.\n\n</a>" "An example of this is the segregation of sounds according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> their use in the game. Volume levels of background " " music, in-game sound effects, and character voices will usually be controlled independently and putting their sounds " "into different hierarchies allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> achieve that <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">easily.\n\n</a>" "The <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> properties that are scaled by parent values <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">are:\n</a>" "- volume, \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "- pitch, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">and\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">priority\n\n</a>" "This means that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> volume of 0. 5, the child will play at half the effective volume it would otherwise " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">have.\n\n</a>" " Additionally, parents affect the playback state of their <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children:\n\n</a>" "- A parent that is in stopped state will force all its direct and indirect children into stopped <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">state.\n</a>" "- A parent that is in paused state will force all its direct and indirect children that are playing into paused state. However, " "children that are in stopped state will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">affected.\n</a>" "- A parent that is in playing state will not affect the playback state of its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n\n</a>" "Each <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> maintains <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state that is wants <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be in which may differ from the state that is enforced on it by its " "parent. If <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent changes its states in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> way that allows <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move into its desired state, the child will do " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">so.\n\n</a>" "For logically grouping sources, instantiate the <a href="/coding/class/classsfxsource/">SFXSource</a> class directly and make other sources children <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> it. A " "<a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> thus instantiated will not effect any real sound output on its own but will influence the sound output of its " "direct and indirect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n\n</a>" " @note Be aware that the property values used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale child property values are the @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> effective values. For example, " "the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scale the volume of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child is the @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a91b64995742fd30063314f12340b4b5a">b</a> effective volume of the parent, i.e. the volume after fades, " "distance attenuation, etc. has been <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">applied.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::sourceGroup\n</a>" " @section SFXSource_volume Volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Attenuation\n\n</a>" "During its lifetime, the volume of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will be continually updated. This update process always progresses " "in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fixed set of steps <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> compute the final effective volume of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> based on the base volume level " "that was either assigned from the <a href="/coding/class/classsfxdescription/">SFXDescription</a> associated with the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a>(SFXDescription::volume) or manually " "set by the user. The process of finding <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's final effective volume is called \"volume attenuation\". The " "steps involved in attenuating <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a>'s volume are (in order):\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dl>\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dt>Fading</dt>\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<dd>If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> currently has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-effect applied, the volume is interpolated along the currently active fade curve.</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dt >Modulation</dt >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dd >If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is part of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> hierarchy, it 's volume is scaled according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the effective volume of its parent.</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dt >Distance Attenuation</dt >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "< dd >If the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> 3D sound source, then the volume is interpolated according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the distance model in effect and " "current listener position and orientation(see @ref SFX_3d).</dd >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</dl >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::volume\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::is3d\n</a>" " @section SFXSource_fades Volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Fades\n\n</a>" "To ease-in and ease-out playback of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> sound, fade effects may be applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sources. A fade will either go from " "zero volume <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> full effective  volume, pause() , and  stop, stop() and the " "end of loop iterations will trigger fade-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">outs.\n\n</a>" "For looping sources, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> SFXDescription::fadeLoops is false, only the initial play() will trigger <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-in and no further " "fading will be applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> loop <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">iterations.\n\n</a>" "By default, the fade durations will be governed by the SFXDescription::fadeInTime and SFXDescription::fadeOutTime properties " "of the <a href="/coding/class/classsfxdescription/">SFXDescription</a> attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source. However, these may be overridden on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> per-<a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> basis by setting fade times " "explicitly with setFadeTimes(). Additionally, the set values may be overridden <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> individual  play, pause() , and stop() " "calls by supplying appropriate fadeInTime/fadeOutTime <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parameters.\n\n</a>" "By default, volume will interpolate linearly during fades. However, custom interpolation curves can be assigned through the " "SFXDescription::fadeInEase and SFXDescription::fadeOutTime <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">properties.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInEase\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutEase\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeLoops\n</a>" " @section SFXSource_cones Sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Cones\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneInsideAngle\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneOutsideAngle\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::coneOutsideVolume\n</a>" " @section SFXSource_doppler Doppler <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Effect\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sfxGetDopplerFactor\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">sfxSetDopplerFactor\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXAmbience::dopplerFactor\n</a>" " @section SFXSource_markers Playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Markers\n\n</a>" "Playback markers allow <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach notification triggers <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> specific playback positions. Once the " "play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> crosses <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> position <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> which <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> marker is defined, the #onMarkerPassed callback will " "be triggered on the <a href="/coding/class/classsfxsource/">SFXSource</a> thus allowing <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> couple script logic <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Be aware that the precision with which marker callbacks are triggered are bound by global <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> " "update frequency. Thus there may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay between the play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> actually passing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> marker position " "and the callback being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggered.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFX\n</a>" )

DefineEngineMethod(SFXSource , addMarker , void , (String name, F32 pos) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> notification marker called @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> name at @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> pos seconds of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playback.\n\n</a>" "@param name Symbolic name <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the marker that will be passed <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the onMarkerPassed() <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">callback.\n</a>" "@param pos Playback position in seconds when the notification should trigger. Note that this is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> soft limit and there " "may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay between the play <a href="/coding/file/sdlcursorcontroller_8cpp/#sdlcursorcontroller_8cpp_1a06e8dd1f849973ccc456f8553601e8b9">cursor</a> actually passing the position and the callback being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggered.\n\n</a>" "@note For looped sounds, the marker will trigger on each <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">iteration.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" " $source)

DefineEngineMethod(SFXSource , addParameter , void , (SFXParameter *parameter) , "Attach @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source, \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Once attached, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> changes of the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter. Attaching <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter " "will also trigger an initial read-out of the parameter 's current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" " @param parameter The parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source." )

DefineEngineMethod(SFXSource , getAttenuatedVolume , F32 , () , "Get the final effective volume level of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "This method returns the volume level as it is after <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group volume modulation, fades , and distance-based " "volume attenuation have been applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the base volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">level.\n\n</a>" " @return The effective volume of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" " @ref SFXSource_volume" )

DefineEngineMethod(SFXSource , getFadeInTime , F32 , () , "Get the fade-in time set on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This will initially be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime.\n\n</a>" "@return The fade-in time set on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n\n</a>" "@ref SFXSource_fades" )

DefineEngineMethod(SFXSource , getFadeOutTime , F32 , () , "Get the fade-out time set on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This will initially be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime.\n\n</a>" "@return The fade-out time set on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n\n</a>" "@ref SFXSource_fades" )

DefineEngineMethod(SFXSource , getParameter , SFXParameter * , (S32 index) )

DefineEngineMethod(SFXSource , getParameterCount , S32 , () )

DefineEngineMethod(SFXSource , getPitch , F32 , () , "Get the pitch scale of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "Pitch determines the playback speed of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> (default: 1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@return The current pitch scale factor of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setPitch\n</a>" "@see SFXDescription::pitch" )

DefineEngineMethod(SFXSource , getStatus , SFXStatus , () , "Get the current playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">status.\n</a>" "@return Te current playback <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">status\n</a>" )

DefineEngineMethod(SFXSource , getVolume , F32 , () , "Get the current base volume level of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This is not the final effective volume that the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is playing at but rather the starting " "volume level before <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group modulation, fades , or distance-based volume attenuation are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">applied.\n\n</a>" " @return The current base volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">level.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setVolume\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::volume\n\n</a>" " @ref SFXSource_volume" )

DefineEngineMethod(SFXSource , isPaused , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">paused.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in paused state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pause\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )

DefineEngineMethod(SFXSource , isPlaying , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">playing.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in playing state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">play\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )

DefineEngineMethod(SFXSource , isStopped , bool , () , "Test whether the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stopped.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is in stopped state, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stop\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getStatus\n</a>" " @see <a href="/coding/file/sfxcommon_8h/#sfxcommon_8h_1a20b590584be84b430435a721b331b5ac">SFXStatus</a>" )

DefineEngineMethod(SFXSource , pause , void , (F32 fadeOutTime) , (-1.0f) , "Pause playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeOutTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> fade down <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> zero volume. If - 1, the SFXDescription::fadeOutTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect that may be " "configured on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description.\n</a>" "Be aware that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect is used, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will not immediately <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> paused state but will " "rather remain in playing state until the fade-out time has expired.." )

DefineEngineMethod(SFXSource , play , void , (F32 fadeInTime) , (-1.0f) , "Start playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "If the sound data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> has not yet been fully loaded, there will be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> delay after calling " "play and playback will start after the data has become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">available.\n\n</a>" " @param fadeInTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> reach full volume. If - 1, the SFXDescription::fadeInTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-in effect that may " "be configured on the description." )

DefineEngineMethod(SFXSource , removeParameter , void , (SFXParameter *parameter) , "Detach @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "Once detached, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will no longer react <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> changes of the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parameter.\n\n</a>" "If the parameter is not attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source, the method will do <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">nothing.\n\n</a>" " @param parameter The parameter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> detach from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" )

DefineEngineMethod(SFXSource , setCone , void , (F32 innerAngle, F32 outerAngle, F32 outsideVolume) , "Set up the 3D volume cone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n\n</a>" "@param innerAngle Angle of the inner sound cone in degrees (@ref SFXDescription::coneInsideAngle). Must be 0<=innerAngle<=360.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param outerAngle Angle of the outer sound cone in degrees (@ref SFXDescription::coneOutsideAngle). Must be 0<=outerAngle<=360.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param outsideVolume Volume scale factor outside of outer cone (@ref SFXDescription::coneOutsideVolume). Must be 0<=outsideVolume<=1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@note This method has no effect on the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> is not 3<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">D.\n\n</a>" )

DefineEngineMethod(SFXSource , setFadeTimes , void , (F32 fadeInTime, F32 fadeOutTime) , "Set the fade time parameters of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeInTime The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> fade-in time in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n</a>" "@param fadeOutTime The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> fade-out time in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">seconds.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeInTime\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXDescription::fadeOutTime\n\n</a>" "@ref SFXSource_fades" )

DefineEngineMethod(SFXSource , setPitch , void , (F32 pitch) , "Set the pitch scale of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "Pitch determines the playback speed of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> (default: 1).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param pitch The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> pitch scale <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">factor.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getPitch\n</a>" "@see SFXDescription::pitch" )

DefineEngineMethod(SFXSource , setTransform , void , (const char *position, const char *direction) , ("") , "( vector position [, vector direction ] ) " "Set the position and orientation of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> 3D sound <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@hide" )

DefineEngineMethod(SFXSource , setVolume , void , (F32 volume) , "Set the base volume level <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "This volume will be the starting point <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> group volume modulation, fades , and distance-based " "volume <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">attenuation.\n\n</a>" " @param volume The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> base volume level <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the source. Must be 0 >=volume<=1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getVolume\n\n</a>" " @ref SFXSource_volume" )

DefineEngineMethod(SFXSource , stop , void , (F32 fadeOutTime) , (-1.0f) , "Stop playback of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param fadeOutTime Seconds <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the sound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> fade down <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> zero volume. If - 1, the SFXDescription::fadeOutTime " "set in the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> 's associated description is used. Pass 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect that may be " "configured on the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description.\n</a>" "Be aware that <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> fade-out effect is used, the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> will not immediately transtion <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stopped state but " "will rather remain in playing state until the fade-out time has expired." )

IMPLEMENT_CALLBACK(SFXSource , onParameterValueChange , void , (SFXParameter *parameter) , (parameter) , "Called when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parameter attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> changes <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n</a>" "This callback will be triggered before the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> change has actually been applied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">source.\n</a>" "@param parameter The parameter that has changed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n</a>" "@note This is also triggered when the parameter is first attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the source." )

IMPLEMENT_CALLBACK(SFXSource , onStatusChange , void , (SFXStatus newStatus) , (newStatus) , "Called when the playback status of the <a href="/coding/file/pointer_8h/#pointer_8h_1adb82dfe18535e9a30aa97d275f82bd55">source</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changes.\n</a>" "@param newStatus The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> playback status." )

IMPLEMENT_CONOBJECT(SFXSource )

   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/sfxSource.h"
  25#include "sfx/sfxSystem.h"
  26#include "sfx/sfxTrack.h"
  27#include "sfx/sfxTypes.h"
  28#include "sfx/sfxDescription.h"
  29#include "sfx/sfxModifier.h"
  30#include "console/engineAPI.h"
  31#include "math/mRandom.h"
  32#include "math/mEase.h"
  33
  34
  35
  36//#define DEBUG_SPEW
  37
  38
  39IMPLEMENT_CONOBJECT( SFXSource );
  40
  41ConsoleDocClass( SFXSource,
  42   "@brief Playback controller for a sound source.\n\n"
  43   
  44   "All sound playback is driven by SFXSources.  Each such source represents an independent playback controller "
  45   "that directly or indirectly affects sound output.\n\n"
  46   
  47   "While this class itself is instantiable, such an instance will not by itself emit any sound.  This is the "
  48   "responsibility of its subclasses.  Note, however, that none of these subclasses must be instantiated directly "
  49   "but must instead be instantiated indirectly through the SFX interface.\n\n"
  50   
  51   "@section SFXSource_playonce Play-Once Sources\n\n"
  52   
  53   "Often, a sound source need only exist for the duration of the sound it is playing.  In this case "
  54   "so-called \"play-once\" sources simplify the bookkeeping involved by leaving the deletion of "
  55   "sources that have expired their playtime to the sound system.\n\n"
  56   
  57   "Play-once sources can be created in either of two ways:\n"
  58   
  59   "- sfxPlayOnce(): Directly create a play-once source from a SFXTrack or file.\n"
  60   "- sfxDeleteWhenStopped(): Retroactively turn any source into a play-once source that will automatically "
  61      "be deleted when moving into stopped state.\n\n"
  62   
  63   "@see sfxPlayOnce\n"
  64   "@see sfxDeleteWhenStopped\n\n"
  65   
  66   "@section SFXSource_hierarchies Source Hierarchies\n\n"
  67   
  68   "Source are arranged into playback hierarchies where a parent source will scale some of the properties of its "
  69   "children and also hand on any play(), pause(), and stop() commands to them.  This allows to easily group sounds "
  70   "into logical units that can then be operated on as a whole.\n\n"
  71   
  72   "An example of this is the segregation of sounds according to their use in the game.  Volume levels of background "
  73   "music, in-game sound effects, and character voices will usually be controlled independently and putting their sounds "
  74   "into different hierarchies allows to achieve that easily.\n\n"
  75   
  76   "The source properties that are scaled by parent values are:\n"
  77   
  78   "- volume,\n"
  79   "- pitch, and\n"
  80   "- priority\n\n"
  81   
  82   "This means that if a parent has a volume of 0.5, the child will play at half the effective volume it would otherwise "
  83   "have.\n\n"
  84
  85   "Additionally, parents affect the playback state of their children:\n\n"
  86   
  87   "- A parent that is in stopped state will force all its direct and indirect children into stopped state.\n"
  88   "- A parent that is in paused state will force all its direct and indirect children that are playing into paused state.  However, "
  89      "children that are in stopped state will not be affected.\n"
  90   "- A parent that is in playing state will not affect the playback state of its children.\n\n"
  91
  92   "Each source maintains a state that is wants to be in which may differ from the state that is enforced on it by its "
  93   "parent.  If a parent changes its states in a way that allows a child to move into its desired state, the child will do "
  94   "so.\n\n"
  95      
  96   "For logically grouping sources, instantiate the SFXSource class directly and make other sources children to it.  A "
  97   "source thus instantiated will not effect any real sound output on its own but will influence the sound output of its "
  98   "direct and indirect children.\n\n"
  99   
 100   "@note Be aware that the property values used to scale child property values are the @b effective values.  For example, "
 101      "the value used to scale the volume of a child is the @b effective volume of the parent, i.e. the volume after fades, "
 102      "distance attenuation, etc. has been applied.\n\n"
 103   
 104   "@see SFXDescription::sourceGroup\n"
 105   
 106   "@section SFXSource_volume Volume Attenuation\n\n"
 107   
 108   "During its lifetime, the volume of a source will be continually updated.  This update process always progresses "
 109   "in a fixed set of steps to compute the final effective volume of the source based on the base volume level "
 110   "that was either assigned from the SFXDescription associated with the source (SFXDescription::volume) or manually "
 111   "set by the user.  The process of finding a source's final effective volume is called \"volume attenuation\".  The "
 112   "steps involved in attenuating a source's volume are (in order):\n"
 113   
 114   "<dl>\n"
 115      "<dt>Fading</dt>\n"
 116      "<dd>If the source currently has a fade-effect applied, the volume is interpolated along the currently active fade curve.</dd>\n"
 117      "<dt>Modulation</dt>\n"
 118      "<dd>If the source is part of a hierarchy, it's volume is scaled according to the effective volume of its parent.</dd>\n"
 119      "<dt>Distance Attenuation</dt>\n"
 120      "<dd>If the source is a 3D sound source, then the volume is interpolated according to the distance model in effect and "
 121         "current listener position and orientation (see @ref SFX_3d).</dd>\n"
 122   "</dl>\n\n"
 123   
 124   "@see SFXDescription::volume\n"
 125   "@see SFXDescription::is3d\n"
 126   
 127   "@section SFXSource_fades Volume Fades\n\n"
 128   
 129   "To ease-in and ease-out playback of a sound, fade effects may be applied to sources.  A fade will either go from "
 130   "zero volume to full effective volume (fade-in) or from full effective volume to zero volume (fade-out).\n\n"
 131   
 132   "Fading is coupled to the play(), pause(), and stop() methods as well as to loop iterations when SFXDescription::fadeLoops "
 133   "is true for the source.  play() and the start of a loop iteration will trigger a fade-in whereas pause(), stop() and the "
 134   "end of loop iterations will trigger fade-outs.\n\n"
 135   
 136   "For looping sources, if SFXDescription::fadeLoops is false, only the initial play() will trigger a fade-in and no further "
 137   "fading will be applied to loop iterations.\n\n"
 138   
 139   "By default, the fade durations will be governed by the SFXDescription::fadeInTime and SFXDescription::fadeOutTime properties "
 140   "of the SFXDescription attached to the source.  However, these may be overridden on a per-source basis by setting fade times "
 141   "explicitly with setFadeTimes().  Additionally, the set values may be overridden for individual play(), pause(), and stop() "
 142   "calls by supplying appropriate fadeInTime/fadeOutTime parameters.\n\n"
 143   
 144   "By default, volume will interpolate linearly during fades.  However, custom interpolation curves can be assigned through the "
 145   "SFXDescription::fadeInEase and SFXDescription::fadeOutTime properties.\n\n"
 146   
 147   "@see SFXDescription::fadeInTime\n"
 148   "@see SFXDescription::fadeOutTime\n"
 149   "@see SFXDescription::fadeInEase\n"
 150   "@see SFXDescription::fadeOutEase\n"
 151   "@see SFXDescription::fadeLoops\n"
 152         
 153   "@section SFXSource_cones Sound Cones\n\n"
 154   
 155   "@see SFXDescription::coneInsideAngle\n"
 156   "@see SFXDescription::coneOutsideAngle\n"
 157   "@see SFXDescription::coneOutsideVolume\n"
 158   
 159   "@section SFXSource_doppler Doppler Effect\n\n"
 160   
 161   "@see sfxGetDopplerFactor\n"
 162   "@see sfxSetDopplerFactor\n"
 163   "@see SFXAmbience::dopplerFactor\n"
 164   
 165   "@section SFXSource_markers Playback Markers\n\n"
 166   
 167   "Playback markers allow to attach notification triggers to specific playback positions.  Once the "
 168   "play cursor crosses a position for which a marker is defined, the #onMarkerPassed callback will "
 169   "be triggered on the SFXSource thus allowing to couple script logic to .\n\n"
 170   
 171   "Be aware that the precision with which marker callbacks are triggered are bound by global source "
 172   "update frequency.  Thus there may be a delay between the play cursor actually passing a marker position "
 173   "and the callback being triggered.\n\n"
 174
 175   "@ingroup SFX\n"
 176);
 177
 178
 179IMPLEMENT_CALLBACK( SFXSource, onStatusChange, void, ( SFXStatus newStatus ), ( newStatus ),
 180   "Called when the playback status of the source changes.\n"
 181   "@param newStatus The new playback status." );
 182IMPLEMENT_CALLBACK( SFXSource, onParameterValueChange, void, ( SFXParameter* parameter ), ( parameter ),
 183   "Called when a parameter attached to the source changes value.\n"
 184   "This callback will be triggered before the value change has actually been applied to the source.\n"
 185   "@param parameter The parameter that has changed value.\n"
 186   "@note This is also triggered when the parameter is first attached to the source." );
 187
 188
 189//-----------------------------------------------------------------------------
 190
 191SFXSource::SFXSource()
 192   : mStatus( SFXStatusStopped ),
 193     mSavedStatus( SFXStatusNull ),
 194     mStatusCallback( NULL ),
 195     mDescription( NULL ),
 196     mVolume( 1.f ),
 197     mPreFadeVolume( 1.f ),
 198     mFadedVolume( 1.f ),
 199     mModulativeVolume( 1.f ),
 200     mPreAttenuatedVolume( 1.f ),
 201     mAttenuatedVolume( 1.f ),
 202     mPriority( 0 ),
 203     mModulativePriority( 1.f ),
 204     mEffectivePriority( 0 ),
 205     mPitch( 1.f ),
 206     mModulativePitch( 1.f ),
 207     mEffectivePitch( 1.f ),
 208     mTransform( true ),
 209     mVelocity( 0, 0, 0 ),
 210     mMinDistance( 1 ),
 211     mMaxDistance( 100 ),
 212     mConeInsideAngle( 360 ),
 213     mConeOutsideAngle( 360 ),
 214     mConeOutsideVolume( 1 ),
 215     mDistToListener( 0.f ),
 216     mTransformScattered( false ),
 217     mFadeInTime( 0.f ),
 218     mFadeOutTime( 0.f ),
 219     mFadeInPoint( -1.f ),
 220     mFadeOutPoint( -1.f ),
 221     mFadeSegmentType( FadeSegmentNone ),
 222     mFadeSegmentEase( NULL ),
 223     mFadeSegmentStartPoint( 0.f ),
 224     mFadeSegmentEndPoint( 0.f ),
 225     mSavedFadeTime( -1.f ),
 226     mPlayStartTick( 0 )
 227{
 228   VECTOR_SET_ASSOCIATION( mParameters );
 229}
 230
 231//-----------------------------------------------------------------------------
 232
 233SFXSource::SFXSource( SFXTrack* track, SFXDescription* description )
 234   : mStatus( SFXStatusStopped ),
 235     mSavedStatus( SFXStatusNull ),
 236     mStatusCallback( NULL ),
 237     mTrack( track ),
 238     mDescription( description ),
 239     mVolume( 1.f ),
 240     mPreFadeVolume( 1.f ),
 241     mFadedVolume( 1.f ),
 242     mModulativeVolume( 1.f ),
 243     mPreAttenuatedVolume( 1.f ),
 244     mAttenuatedVolume( 1.f ),
 245     mPriority( 0 ),
 246     mModulativePriority( 1.f ),
 247     mEffectivePriority( 0 ),
 248     mPitch( 1.f ),
 249     mModulativePitch( 1.f ),
 250     mEffectivePitch( 1.f ),
 251     mTransform( true ),
 252     mVelocity( 0, 0, 0 ),
 253     mMinDistance( 1 ),
 254     mMaxDistance( 100 ),
 255     mConeInsideAngle( 360 ),
 256     mConeOutsideAngle( 360 ),
 257     mConeOutsideVolume( 1 ),
 258     mDistToListener( 0.f ),
 259     mTransformScattered( false ),
 260     mFadeInTime( 0.f ),
 261     mFadeOutTime( 0.f ),
 262     mFadeInPoint( -1.f ),
 263     mFadeOutPoint( -1.f ),
 264     mFadeSegmentType( FadeSegmentNone ),
 265     mFadeSegmentEase( NULL ),
 266     mFadeSegmentStartPoint( 0.f ),
 267     mFadeSegmentEndPoint( 0.f ),
 268     mSavedFadeTime( -1.f ),
 269     mPlayStartTick( 0 )
 270{
 271   VECTOR_SET_ASSOCIATION( mParameters );
 272   
 273   if( !description && track )
 274      mDescription = track->getDescription();
 275      
 276   // Make sure we get notified when our datablocks go away
 277   // so we can kill this source.
 278      
 279   if( mTrack != NULL )
 280      deleteNotify( mTrack );
 281   deleteNotify( mDescription );
 282}
 283
 284//-----------------------------------------------------------------------------
 285
 286SFXSource::~SFXSource()
 287{
 288   // Disconnect from any remaining parameters.
 289   
 290   while( !mParameters.empty() )
 291   {
 292      mParameters.last()->getEventSignal().remove( this, &SFXSource::_onParameterEvent );
 293      mParameters.decrement();
 294   }
 295}
 296
 297//-----------------------------------------------------------------------------
 298
 299void SFXSource::initPersistFields()
 300{
 301   addGroup( "Sound" );
 302   
 303      addProtectedField( "description", TypeSFXDescriptionName, Offset( mDescription, SFXSource ),
 304         &_setDescription, &_getDescription,
 305         "The playback configuration that determines the initial sound properties and setup.\n"
 306         "Any SFXSource must have an associated SFXDescription." );
 307         
 308      addField( "statusCallback", TypeString, Offset( mStatusCallback, SFXSource ),
 309         "Name of function to call when the status of the source changes.\n\n"
 310         "The source that had its status changed is passed as the first argument to the function and the "
 311         "new status of the source is passed as the second argument." );
 312         
 313   endGroup( "Sound" );
 314   
 315   Parent::initPersistFields();
 316}
 317
 318//-----------------------------------------------------------------------------
 319
 320bool SFXSource::processArguments( S32 argc, ConsoleValueRef *argv )
 321{
 322   // Don't allow subclasses of this to be created via script.  Force
 323   // usage of the SFXSystem functions.
 324   
 325   if( typeid( *this ) != typeid( SFXSource ) )
 326   {
 327      Con::errorf( ConsoleLogEntry::Script, "Use sfxCreateSource, sfxPlay, or sfxPlayOnce!" );
 328      return false;
 329   }
 330   else
 331      return Parent::processArguments( argc, argv );
 332}
 333
 334//-----------------------------------------------------------------------------
 335
 336bool SFXSource::onAdd()
 337{
 338   if( !Parent::onAdd() )
 339      return false;
 340      
 341   // Make sure we have a description.
 342                  
 343   if( !mDescription )
 344   {
 345      Con::errorf( "SFXSource::onAdd() - no description set on source %i (%s)", getId(), getName() );
 346      return false;
 347   }
 348         
 349   // Set our initial properties.
 350        
 351   _setVolume( mDescription->mVolume ); 
 352   _setPitch( mDescription->mPitch );
 353   _setPriority( mDescription->mPriority );
 354   _setFadeTimes( mDescription->mFadeInTime, mDescription->mFadeOutTime );
 355
 356   _setMinMaxDistance( mDescription->mMinDistance, mDescription->mMaxDistance );
 357   _setCone( F32( mDescription->mConeInsideAngle ),
 358             F32( mDescription->mConeOutsideAngle ),
 359             mDescription->mConeOutsideVolume );
 360
 361   // Add the parameters from the description.
 362   
 363   for( U32 i = 0; i < SFXDescription::MaxNumParameters; ++ i )
 364   {
 365      StringTableEntry name = mDescription->mParameters[ i ];
 366      if( name && name[ 0 ] )
 367         _addParameter( name );
 368   }
 369
 370   // Add the parameters from the track.
 371   
 372   if( mTrack != NULL )
 373      for( U32 i = 0; i < SFXTrack::MaxNumParameters; ++ i )
 374      {
 375         StringTableEntry name = mTrack->getParameter( i );
 376         if( name && name[ 0 ] )
 377            _addParameter( name );
 378      }
 379
 380   // Add us to the description's source group.
 381   
 382   if( mDescription->mSourceGroup )
 383      mDescription->mSourceGroup->addObject( this );
 384
 385   // Add to source set.
 386
 387   if( Sim::getSFXSourceSet() )
 388      Sim::getSFXSourceSet()->addObject( this );
 389      
 390   // Register with SFX system.
 391      
 392   SFX->_onAddSource( this );
 393      
 394   return true;
 395}
 396
 397//-----------------------------------------------------------------------------
 398
 399void SFXSource::onRemove()
 400{
 401   stop();
 402
 403   // Let the system know.
 404   SFX->_onRemoveSource( this );
 405   
 406   #ifdef DEBUG_SPEW
 407   Platform::outputDebugString( "[SFXSource] removed source '%i'", getId() );
 408   #endif
 409   
 410   Parent::onRemove();
 411}
 412
 413//-----------------------------------------------------------------------------
 414
 415void SFXSource::onDeleteNotify( SimObject* object )
 416{
 417   if( object == mTrack )
 418   {
 419      deleteObject();
 420      return;
 421   }
 422
 423   Parent::onDeleteNotify( object );
 424}
 425
 426//-----------------------------------------------------------------------------
 427
 428bool SFXSource::acceptsAsChild( SimObject* object )
 429{
 430   return ( dynamic_cast< SFXSource* >( object ) != NULL );
 431}
 432
 433//-----------------------------------------------------------------------------
 434
 435void SFXSource::onGroupAdd()
 436{
 437   Parent::onGroupAdd();
 438   
 439   SFXSource* source = dynamic_cast< SFXSource* >( getGroup() );
 440   if( source )
 441   {
 442      if( source != mDescription->mSourceGroup )
 443         mFlags.set( CustomGroupFlag );
 444      else
 445         mFlags.clear( CustomGroupFlag );
 446   }
 447
 448   //DRTODO: sync up playback state
 449}
 450
 451//-----------------------------------------------------------------------------
 452
 453SFXSource* SFXSource::getSourceGroup() const
 454{
 455   return dynamic_cast< SFXSource* >( getGroup() );
 456}
 457
 458//-----------------------------------------------------------------------------
 459
 460F32 SFXSource::getElapsedPlayTime() const
 461{
 462   return F32( mPlayTimer.getPosition() ) / 1000.f;
 463}
 464
 465//-----------------------------------------------------------------------------
 466
 467F32 SFXSource::getElapsedPlayTimeCurrentCycle() const
 468{
 469   // In this base class, we can't make assumptions about total playtimes
 470   // and thus cannot clamp the playtimer into range for the current cycle.
 471   // This needs to be done by subclasses.
 472   
 473   return F32( mPlayTimer.getPosition() ) / 1000.f;
 474}
 475
 476//-----------------------------------------------------------------------------
 477
 478F32 SFXSource::getTotalPlayTime() const
 479{
 480   return Float_Inf;
 481}
 482
 483//-----------------------------------------------------------------------------
 484
 485void SFXSource::play( F32 fadeInTime )
 486{
 487   SFXStatus status = getStatus();
 488   
 489   // Return if the source is already playing.
 490   
 491   if( status == SFXStatusPlaying )
 492   {
 493      // Revert fade-out if there is one.
 494      
 495      if( mFadeSegmentType != FadeSegmentNone && mFadeSegmentType != FadeSegmentPlay )
 496      {
 497         // Let easing curve remain in place.  Otherwise we would have to
 498         // search the fade-in's easing curve for the point matching the
 499         // current fade volume in order to prevent volume pops.
 500         
 501         mFadeSegmentType = FadeSegmentPlay;
 502      }
 503   
 504      return;
 505   }
 506   
 507   // First check the parent source.  If it is not playing,
 508   // only save our non-inherited state and return.
 509
 510   SFXSource* sourceGroup = getSourceGroup();
 511   if( sourceGroup != NULL && !sourceGroup->isPlaying() )
 512   {
 513      mSavedStatus = SFXStatusPlaying;
 514      mSavedFadeTime = fadeInTime;
 515
 516      return;
 517   }
 518
 519   // Add fades, if required.
 520   
 521   if( fadeInTime == -1.f )
 522      fadeInTime = mFadeInTime;
 523      
 524   if( status == SFXStatusPaused && fadeInTime > 0.f )
 525   {
 526      // Source is paused.  Set up temporary fade-in segment.
 527      
 528      mFadeSegmentEase = &mDescription->mFadeInEase;
 529      mFadeSegmentType = FadeSegmentPlay;
 530      mFadeSegmentStartPoint = getElapsedPlayTimeCurrentCycle();
 531      mFadeSegmentEndPoint = mFadeSegmentStartPoint + fadeInTime;
 532   }
 533   else if( fadeInTime > 0.f )
 534   {
 535      mFadeInPoint = fadeInTime;
 536      
 537      // Add fade-out if play-time of the source is finite and
 538      // if it is either not looping or has fading enabled on loops.
 539      
 540      F32 totalPlayTime = getTotalPlayTime();
 541      if( !mIsInf_F( totalPlayTime ) && mDescription->mFadeOutTime > 0.f && ( !mDescription->mIsLooping || mDescription->mFadeLoops ) )
 542      {
 543         mFadeOutPoint = totalPlayTime - mDescription->mFadeOutTime;
 544
 545         // If there's an intersection between fade-in and fade-out, move them
 546         // to the midpoint.
 547      
 548         if( mFadeOutPoint < mFadeInPoint )
 549         {
 550            F32 midPoint = mFadeOutPoint + ( mFadeInPoint - mFadeOutPoint / 2 );
 551            
 552            mFadeInPoint = midPoint;
 553            mFadeOutPoint = midPoint;
 554         }
 555      }
 556   }
 557   else
 558   {
 559      mFadeInPoint = -1.f;
 560      mFadeOutPoint = -1.f;
 561   }
 562   
 563   // Start playback.
 564      
 565   if( status != SFXStatusPaused )
 566   {
 567      mPlayStartTick = Platform::getVirtualMilliseconds();
 568      mPlayTimer.reset();
 569   }
 570      
 571   _setStatus( SFXStatusPlaying );
 572   _play();
 573
 574   #ifdef DEBUG_SPEW
 575   Platform::outputDebugString( "[SFXSource] Started playback of source '%i'", getId() );
 576   #endif
 577}
 578
 579//-----------------------------------------------------------------------------
 580
 581void SFXSource::pause( F32 fadeOutTime )
 582{
 583   SFXStatus status = getStatus();
 584   if( status != SFXStatusPlaying )
 585      return;
 586   
 587   // Pause playback.
 588      
 589   if( fadeOutTime == -1.f )
 590      fadeOutTime = mFadeOutTime;
 591      
 592   if( fadeOutTime > 0.f )
 593      _setupFadeOutSegment( FadeSegmentPause, fadeOutTime );
 594   else
 595   {
 596      _setStatus( SFXStatusPaused );
 597      _pause();
 598      
 599      mFadeSegmentType = FadeSegmentNone;
 600      mPreFadeVolume = mVolume;
 601
 602      #ifdef DEBUG_SPEW
 603      Platform::outputDebugString( "[SFXSource] Paused playback of source '%i'", getId() );
 604      #endif
 605   }
 606}
 607
 608//-----------------------------------------------------------------------------
 609
 610void SFXSource::stop( F32 fadeOutTime )
 611{
 612   SFXStatus status = getStatus();
 613   if( status == SFXStatusStopped )
 614      return;
 615
 616   if( status == SFXStatusPaused )
 617   {
 618      _setStatus( SFXStatusStopped );
 619      _stop();
 620      return;
 621   }
 622   
 623   if( fadeOutTime == -1.f )
 624      fadeOutTime = mFadeOutTime;
 625      
 626   if( fadeOutTime > 0.f )
 627      _setupFadeOutSegment( FadeSegmentStop, fadeOutTime );
 628   else
 629   {
 630      _setStatus( SFXStatusStopped );
 631      _stop();
 632
 633      mFadeSegmentType = FadeSegmentNone;
 634      mPreFadeVolume = mVolume;
 635
 636      #ifdef DEBUG_SPEW
 637      Platform::outputDebugString( "[SFXSource] Stopped playback of source '%i'", getId() );
 638      #endif
 639   }
 640}
 641
 642//-----------------------------------------------------------------------------
 643
 644void SFXSource::update()
 645{
 646   if( !isPlaying() )
 647      return;
 648      
 649   _update();      
 650
 651   // Update our modifiers, if any.
 652   
 653   for( ModifierList::Iterator iter = mModifiers.begin();
 654        iter != mModifiers.end(); )
 655   {
 656      ModifierList::Iterator next = iter;
 657      next ++;
 658
 659      if( !( *iter )->update() )
 660      {
 661         delete *iter;
 662         mModifiers.erase( iter );
 663      }
 664
 665      iter = next;
 666   }
 667}
 668
 669//-----------------------------------------------------------------------------
 670
 671void SFXSource::_play()
 672{
 673   mPlayTimer.start();
 674
 675   // Resume playback of children that want to be in
 676   // playing state.
 677   
 678   for( iterator iter = begin(); iter != end(); ++ iter )
 679   {
 680      SFXSource* source = dynamic_cast< SFXSource* >( *iter );
 681      if( source && source->mSavedStatus == SFXStatusPlaying )
 682         source->play( source->mSavedFadeTime );
 683   }
 684}
 685
 686//-----------------------------------------------------------------------------
 687
 688void SFXSource::_pause()
 689{
 690   // Pause playing child sources.
 691
 692   for( iterator iter = begin(); iter != end(); ++ iter )
 693   {
 694      SFXSource* source = dynamic_cast< SFXSource* >( *iter );
 695      if( source && source->isPlaying() )
 696      {
 697         source->pause( 0.f );
 698
 699         // Save info for resuming playback.
 700
 701         source->mSavedStatus = SFXStatusPlaying;
 702         source->mSavedFadeTime = 0.f;
 703      }
 704   }
 705   
 706   mPlayTimer.pause();
 707}
 708
 709//-----------------------------------------------------------------------------
 710
 711void SFXSource::_stop()
 712{  
 713   // Stop all child sources.
 714
 715   for( iterator iter = begin(); iter != end(); ++ iter )
 716   {
 717      SFXSource* source = dynamic_cast< SFXSource* >( *iter );
 718      if( source )
 719         source->stop( 0.f );
 720   }
 721
 722   mPlayTimer.stop();
 723}
 724
 725//-----------------------------------------------------------------------------
 726
 727void SFXSource::_update()
 728{      
 729   /// Update our modulated properties.
 730      
 731   _updateVolume( SFX->getListener().getTransform() );
 732   _updatePitch();
 733   _updatePriority();         
 734}
 735
 736//-----------------------------------------------------------------------------
 737
 738bool SFXSource::_setDescription( void* obj, const char* index, const char* data )
 739{
 740   SFXSource* source = reinterpret_cast< SFXSource* >( obj );
 741
 742   source->mDescription = EngineUnmarshallData< SFXDescription*>()( data );
 743   if( !source->mDescription )
 744   {
 745      Con::errorf( "SFXSource::_setDescription - No SFXDescription '%s'", data );
 746      return false;
 747   }
 748
 749   source->notifyDescriptionChanged();
 750   
 751   return false;
 752}
 753
 754//-----------------------------------------------------------------------------
 755
 756const char* SFXSource::_getDescription( void* obj, const char* data )
 757{
 758   SFXSource* source = reinterpret_cast< SFXSource* >( obj );
 759   SFXDescription* description = source->mDescription;
 760   
 761   if( !description )
 762      return "";
 763
 764   return description->getName();
 765}
 766
 767//-----------------------------------------------------------------------------
 768
 769void SFXSource::_setStatus( SFXStatus status )
 770{
 771   if( mStatus == status )
 772      return;
 773
 774   mStatus = status;
 775
 776   // Clear saved status.
 777
 778   mSavedStatus = SFXStatusNull;
 779
 780   // Do the callback if we have it.
 781
 782   if( mStatusCallback && mStatusCallback[0] )
 783   {
 784      const char* statusString = SFXStatusToString( mStatus );
 785      Con::executef( mStatusCallback, getIdString(), statusString );
 786   }
 787   else if( getNamespace() )
 788      onStatusChange_callback( status );
 789}
 790
 791//-----------------------------------------------------------------------------
 792
 793void SFXSource::_updateVolume( const MatrixF& listener )
 794{
 795   // Handle fades (compute mFadedVolume).
 796      
 797   mFadedVolume = mPreFadeVolume;
 798   if( mFadeSegmentType != FadeSegmentNone )
 799   {
 800      // We have a temporary fade segment.
 801      
 802      F32 elapsed;
 803      if( mDescription->mIsLooping && !mDescription->mFadeLoops )
 804         elapsed = getElapsedPlayTime();
 805      else
 806         elapsed = getElapsedPlayTimeCurrentCycle();
 807      
 808      if( elapsed < mFadeSegmentEndPoint )
 809      {
 810         const F32 duration = mFadeSegmentEndPoint - mFadeSegmentStartPoint;
 811         
 812         if( mFadeSegmentType == FadeSegmentPlay )
 813         {
 814            const F32 time = elapsed - mFadeSegmentStartPoint;
 815            mFadedVolume = mFadeSegmentEase->getValue
 816               ( time, 0.f, mPreFadeVolume, duration );
 817         }
 818         else
 819         {
 820            // If the end-point to the ease functions is 0,
 821            // we'll always get out the start point.  Thus do the whole
 822            // thing backwards here.
 823            
 824            const F32 time = mFadeSegmentEndPoint - elapsed;
 825            mFadedVolume = mFadeSegmentEase->getValue
 826               ( time, 0.f, mPreFadeVolume, duration );
 827         }
 828      }
 829      else
 830      {
 831         // The fade segment has played.  Remove it.
 832         
 833         switch( mFadeSegmentType )
 834         {
 835            case FadeSegmentStop:
 836               stop( 0.f );
 837               break;
 838               
 839            case FadeSegmentPause:
 840               pause( 0.f );
 841               break;
 842               
 843            case FadeSegmentPlay: // Nothing to do.               
 844            default:
 845               break;
 846         }
 847         
 848         mFadeSegmentType = FadeSegmentNone;
 849         mPreFadeVolume = mVolume;
 850      }
 851   }
 852   else if( mFadeInPoint != -1 || mFadeOutPoint != -1 )
 853   {
 854      F32 elapsed;
 855      if( mDescription->mIsLooping && !mDescription->mFadeLoops )
 856         elapsed = getElapsedPlayTime();
 857      else
 858         elapsed = getElapsedPlayTimeCurrentCycle();
 859      
 860      // Check for fade-in.
 861      
 862      if( mFadeInPoint != -1 )
 863      {
 864         if( elapsed < mFadeInPoint )
 865            mFadedVolume = mDescription->mFadeInEase.getValue( elapsed, 0.f, mPreFadeVolume, mFadeInPoint );
 866         else if( mDescription->mIsLooping && !mDescription->mFadeLoops )
 867         {
 868            // Deactivate fade-in so we don't see it on further loops.
 869            mFadeInPoint = -1;
 870         }
 871      }
 872      
 873      // Check for fade-out.
 874      
 875      if( mFadeOutPoint != -1 && elapsed > mFadeOutPoint )
 876      {
 877         const F32 totalPlayTime = getTotalPlayTime();
 878         const F32 duration = totalPlayTime - mFadeOutPoint;
 879         const F32 time = totalPlayTime - elapsed;
 880         
 881         mFadedVolume = mDescription->mFadeOutEase.getValue( time, 0.f, mPreFadeVolume, duration );
 882      }
 883   }
 884
 885   // Compute the pre-attenuated volume.
 886   
 887   mPreAttenuatedVolume =
 888        mFadedVolume
 889      * mModulativeVolume;
 890      
 891   SFXSource* group = getSourceGroup();
 892   if( group )
 893      mPreAttenuatedVolume *= group->getAttenuatedVolume();
 894
 895   if( !is3d() ) 
 896   {
 897      mDistToListener = 0.0f;
 898      mAttenuatedVolume = mPreAttenuatedVolume; 
 899   }
 900   else
 901   {
 902      // For 3D sounds, compute distance attenuation.
 903
 904      Point3F pos, lpos;
 905      mTransform.getColumn( 3, &pos );
 906      listener.getColumn( 3, &lpos );
 907
 908      mDistToListener = ( pos - lpos ).len();
 909      mAttenuatedVolume = SFXDistanceAttenuation(
 910         SFX->getDistanceModel(),
 911         mMinDistance,
 912         mMaxDistance,
 913         mDistToListener,
 914         mPreAttenuatedVolume,
 915         SFX->getRolloffFactor() );
 916   }
 917}
 918
 919//-----------------------------------------------------------------------------
 920
 921void SFXSource::_updatePitch()
 922{
 923   mEffectivePitch = mModulativePitch * mPitch;
 924}
 925
 926//-----------------------------------------------------------------------------
 927
 928void SFXSource::_updatePriority()
 929{      
 930   mEffectivePriority = mPriority * mModulativePriority;
 931
 932   SFXSource* group = getSourceGroup();
 933   if( group )
 934      mEffectivePriority *= group->getEffectivePriority();
 935}
 936
 937//-----------------------------------------------------------------------------
 938
 939void SFXSource::setTransform( const MatrixF& transform )
 940{
 941   mTransform = transform;
 942}
 943
 944//-----------------------------------------------------------------------------
 945
 946void SFXSource::setVelocity( const VectorF& velocity )
 947{
 948   mVelocity = velocity;
 949}
 950
 951//-----------------------------------------------------------------------------
 952
 953void SFXSource::setFadeTimes( F32 fadeInTime, F32 fadeOutTime )
 954{
 955   _setFadeTimes( fadeInTime, fadeOutTime );
 956   
 957   if( mFadeInTime >= 0.f || mFadeOutTime >= 0.f )
 958      mFlags.set( CustomFadeFlag );
 959}
 960
 961//-----------------------------------------------------------------------------
 962
 963void SFXSource::_setFadeTimes( F32 fadeInTime, F32 fadeOutTime )
 964{
 965   if( fadeInTime >= 0.f )
 966      mFadeInTime = getMax( 0.f, fadeInTime );
 967   else
 968      mFadeInTime = mDescription->mFadeInTime;
 969      
 970   if( fadeOutTime >= 0.f )
 971      mFadeOutTime = getMax( 0.f, fadeOutTime );
 972   else
 973      mFadeOutTime = mDescription->mFadeOutTime;
 974}
 975
 976//-----------------------------------------------------------------------------
 977
 978void SFXSource::_setupFadeOutSegment( FadeSegmentType type, F32 fadeOutTime )
 979{
 980   // Get the current faded volume as the start volume so
 981   // that we correctly fade when starting in a fade.
 982   
 983   _updateVolume( SFX->getListener().getTransform() );
 984   mPreFadeVolume = mFadedVolume;
 985
 986   mFadeSegmentEase = &mDescription->mFadeOutEase;
 987   mFadeSegmentType = type;
 988
 989   if( mDescription->mIsLooping && mDescription->mFadeLoops )
 990   {
 991      mFadeSegmentStartPoint = getElapsedPlayTimeCurrentCycle();
 992      mFadeSegmentEndPoint = getMin( mFadeSegmentStartPoint + fadeOutTime, getTotalPlayTime() );
 993   }
 994   else
 995   {
 996      mFadeSegmentStartPoint = getElapsedPlayTime();
 997      mFadeSegmentEndPoint = mFadeSegmentStartPoint + fadeOutTime;
 998   }
 999}
1000
1001//-----------------------------------------------------------------------------
1002
1003void SFXSource::_setMinMaxDistance( F32 min, F32 max )
1004{
1005   mMinDistance = getMax( 0.0f, min );
1006   mMaxDistance = getMax( mMinDistance, max );
1007}
1008
1009//-----------------------------------------------------------------------------
1010
1011void SFXSource::_setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
1012{
1013   mConeInsideAngle = mClampF( innerAngle, 0.0, 360.0 );
1014   mConeOutsideAngle = mClampF( outerAngle, mConeInsideAngle, 360.0 );
1015   mConeOutsideVolume = mClampF( outerVolume, 0.0, 1.0 );
1016}
1017
1018//-----------------------------------------------------------------------------
1019
1020void SFXSource::_setVolume( F32 volume )
1021{
1022   mVolume = mClampF( volume, 0.f, 1.f );
1023   mPreFadeVolume = mVolume;
1024   _updateVolume( SFX->getListener( 0 ).getTransform() );
1025}
1026
1027//-----------------------------------------------------------------------------
1028
1029void SFXSource::setModulativeVolume( F32 value )
1030{
1031   mModulativeVolume = mClampF( value, 0.f, 1.f );
1032   _updateVolume( SFX->getListener( 0 ).getTransform() );
1033}
1034
1035//-----------------------------------------------------------------------------
1036
1037void SFXSource::_setPitch( F32 pitch )
1038{
1039   mPitch = mClampF( pitch, 0.001f, 2.0f );
1040   _updatePitch();
1041}
1042
1043//-----------------------------------------------------------------------------
1044
1045void SFXSource::setModulativePitch( F32 value )
1046{
1047   mModulativePitch = mClampF( value, 0.001f, 2.0f );
1048   _updatePitch();
1049}
1050
1051//-----------------------------------------------------------------------------
1052
1053void SFXSource::_setPriority( F32 priority )
1054{
1055   mPriority = priority;
1056   _updatePriority();
1057}
1058
1059//-----------------------------------------------------------------------------
1060
1061void SFXSource::setModulativePriority( F32 value )
1062{
1063   mModulativePriority = value;
1064   _updatePriority();
1065}
1066
1067//-----------------------------------------------------------------------------
1068
1069SFXTrack* SFXSource::getTrack() const
1070{
1071   return mTrack;
1072}
1073
1074//-----------------------------------------------------------------------------
1075
1076void SFXSource::notifyDescriptionChanged()
1077{
1078   if( !mFlags.test( CustomVolumeFlag ) )
1079      _setVolume( mDescription->mVolume );
1080   if( !mFlags.test( CustomPitchFlag ) )
1081      _setPitch( mDescription->mPitch );
1082   if( !mFlags.test( CustomPriorityFlag ) )
1083      _setPriority( mDescription->mPriority );
1084   if( !mFlags.test( CustomRadiusFlag ) )
1085      _setMinMaxDistance( mDescription->mMinDistance, mDescription->mMaxDistance );
1086   if( !mFlags.test( CustomConeFlag ) )
1087      _setCone( mDescription->mConeInsideAngle, mDescription->mConeOutsideAngle, mDescription->mConeOutsideVolume );
1088   if( !mFlags.test( CustomFadeFlag ) )
1089      _setFadeTimes( mDescription->mFadeInTime, mDescription->mFadeOutTime );
1090   if( !mFlags.test( CustomGroupFlag ) && mDescription->mSourceGroup != NULL && getGroup() != mDescription->mSourceGroup )
1091      mDescription->mSourceGroup->addObject( this );
1092}
1093
1094//-----------------------------------------------------------------------------
1095
1096void SFXSource::notifyTrackChanged()
1097{
1098   //RDTODO
1099}
1100
1101//-----------------------------------------------------------------------------
1102
1103template< class T >
1104void SFXSource::_clearModifiers()
1105{
1106   for( ModifierList::Iterator iter = mModifiers.begin();
1107        iter != mModifiers.end(); )
1108   {
1109      ModifierList::Iterator next = iter;
1110      next ++;
1111
1112      if( dynamic_cast< T* >( *iter ) )
1113      {
1114         delete *iter;
1115         mModifiers.erase( iter );
1116      }
1117
1118      iter = next;
1119   }
1120}
1121
1122//-----------------------------------------------------------------------------
1123
1124void SFXSource::addModifier( SFXModifier* modifier )
1125{
1126   mModifiers.pushBack( modifier );
1127}
1128
1129//-----------------------------------------------------------------------------
1130
1131void SFXSource::addMarker( const String& name, F32 pos )
1132{
1133   addModifier( new SFXMarkerModifier( this, name, pos ) );
1134}
1135
1136//-----------------------------------------------------------------------------
1137
1138void SFXSource::addParameter( SFXParameter* parameter )
1139{
1140   for( U32 i = 0; i < mParameters.size(); ++ i )
1141      if( mParameters[ i ] == parameter )
1142         return;
1143         
1144   mParameters.push_back( parameter );
1145   parameter->getEventSignal().notify( this, &SFXSource::_onParameterEvent );
1146   
1147   // Trigger an initial value-changed event so the
1148   // current parameter value becomes effective.
1149   
1150   _onParameterEvent( parameter, SFXParameterEvent_ValueChanged );
1151}
1152
1153//-----------------------------------------------------------------------------
1154
1155void SFXSource::removeParameter( SFXParameter* parameter )
1156{
1157   for( U32 i = 0; i < mParameters.size(); ++ i )
1158      if( mParameters[ i ] == parameter )
1159      {
1160         mParameters[ i ]->getEventSignal().remove( this, &SFXSource::_onParameterEvent );
1161         mParameters.erase( i );
1162         break;
1163      }
1164}
1165
1166//-----------------------------------------------------------------------------
1167
1168void SFXSource::_addParameter( StringTableEntry name )
1169{
1170   SFXParameter* parameter = dynamic_cast< SFXParameter* >(
1171      Sim::getSFXParameterGroup()->findObjectByInternalName( name )
1172   );
1173   
1174   if( !parameter )
1175   {
1176      Con::errorf( "SFXSource::_addParameter - no parameter called '%s'", name );
1177      return;
1178   }
1179   
1180   addParameter( parameter );
1181}
1182
1183//-----------------------------------------------------------------------------
1184
1185void SFXSource::_onParameterEvent( SFXParameter* parameter, SFXParameterEvent event )
1186{
1187   switch( event )
1188   {
1189      case SFXParameterEvent_ValueChanged:
1190      
1191         onParameterValueChange_callback( parameter );
1192            
1193         switch( parameter->getChannel() )
1194         {
1195            case SFXChannelStatus:
1196            {
1197               F32 value = parameter->getValue();
1198               if( value >= F32( SFXStatusPlaying ) && value <= F32( SFXStatusStopped ) )
1199               {
1200                  SFXStatus status = ( SFXStatus ) U32( value );
1201                  switch( status )
1202                  {
1203                     case SFXStatusPlaying:     play(); break;
1204                     case SFXStatusPaused:      pause(); break;
1205                     case SFXStatusStopped:     stop(); break;
1206                     
1207                     default:
1208                        break;
1209                  }
1210               }
1211               break;
1212            }
1213               
1214            case SFXChannelVolume:
1215               setVolume( parameter->getValue() );
1216               break;
1217               
1218            case SFXChannelPitch:
1219               setPitch( parameter->getValue() );
1220               break;
1221               
1222            case SFXChannelPriority:
1223               setPriority( parameter->getValue() );
1224               break;
1225               
1226            case SFXChannelMinDistance:
1227               setMinMaxDistance( parameter->getValue(), mMaxDistance );
1228               break;
1229               
1230            case SFXChannelMaxDistance:
1231               setMinMaxDistance( mMinDistance, parameter->getValue() );
1232               break;
1233               
1234            case SFXChannelPositionX:
1235            {
1236               Point3F position = mTransform.getPosition();
1237               position.x = parameter->getValue();
1238               mTransform.setPosition( position );
1239               setTransform( mTransform );
1240               break;
1241            }
1242
1243            case SFXChannelPositionY:
1244            {
1245               Point3F position = mTransform.getPosition();
1246               position.y = parameter->getValue();
1247               mTransform.setPosition( position );
1248               setTransform( mTransform );
1249               break;
1250            }
1251
1252            case SFXChannelPositionZ:
1253            {
1254               Point3F position = mTransform.getPosition();
1255               position.z = parameter->getValue();
1256               mTransform.setPosition( position );
1257               setTransform( mTransform );
1258               break;
1259            }
1260            
1261            case SFXChannelRotationX:
1262            {
1263               EulerF angles = mTransform.toEuler();
1264               angles.x = parameter->getValue();
1265               MatrixF transform( angles );
1266               transform.setPosition( mTransform.getPosition() );
1267               setTransform( transform );
1268               break;
1269            }
1270            
1271            case SFXChannelRotationY:
1272            {
1273               EulerF angles = mTransform.toEuler();
1274               angles.y = parameter->getValue();
1275               MatrixF transform( angles );
1276               transform.setPosition( mTransform.getPosition() );
1277               setTransform( transform );
1278               break;
1279            }
1280
1281            case SFXChannelRotationZ:
1282            {
1283               EulerF angles = mTransform.toEuler();
1284               angles.z = parameter->getValue();
1285               MatrixF transform( angles );
1286               transform.setPosition( mTransform.getPosition() );
1287               setTransform( transform );
1288               break;
1289            }
1290
1291            case SFXChannelVelocityX:
1292            {
1293               mVelocity.x = parameter->getValue();
1294               setVelocity( mVelocity );
1295               break;
1296            }
1297
1298            case SFXChannelVelocityY:
1299            {
1300               mVelocity.y = parameter->getValue();
1301               setVelocity( mVelocity );
1302               break;
1303            }
1304
1305            case SFXChannelVelocityZ:
1306            {
1307               mVelocity.z = parameter->getValue();
1308               setVelocity( mVelocity );
1309               break;
1310            }
1311               
1312            default:
1313               break;
1314         }
1315         break;
1316         
1317      case SFXParameterEvent_Deleted:
1318         removeParameter( parameter );
1319         break;
1320   }
1321}
1322
1323//-----------------------------------------------------------------------------
1324
1325void SFXSource::_scatterTransform()
1326{
1327   if( mDescription )
1328   {
1329      Point3F position = mTransform.getPosition();
1330      for( U32 i = 0; i < 3; ++ i )
1331      {
1332         F32 scatterDist = mDescription->mScatterDistance[ i ];
1333         if( scatterDist != 0.f )
1334            position[ 0 ] += gRandGen.randF( - scatterDist, scatterDist );
1335      }
1336      mTransform.setPosition( position );
1337   }
1338   
1339   mTransformScattered = true;
1340}
1341
1342//=============================================================================
1343//    Console Methods.
1344//=============================================================================
1345// MARK: ---- Console Methods ----
1346
1347//-----------------------------------------------------------------------------
1348
1349DefineEngineMethod( SFXSource, play, void, ( F32 fadeInTime ), ( -1.0f ),
1350   "Start playback of the source.\n"
1351   "If the sound data for the source has not yet been fully loaded, there will be a delay after calling "
1352   "play and playback will start after the data has become available.\n\n"
1353   "@param fadeInTime Seconds for the sound to reach full volume.  If -1, the SFXDescription::fadeInTime "
1354      "set in the source's associated description is used.  Pass 0 to disable a fade-in effect that may "
1355      "be configured on the description." )
1356{
1357   object->play( fadeInTime );
1358}
1359
1360//-----------------------------------------------------------------------------
1361
1362DefineEngineMethod( SFXSource, stop, void, ( F32 fadeOutTime ), ( -1.0f ),
1363   "Stop playback of the source.\n"
1364   "@param fadeOutTime Seconds for the sound to fade down to zero volume.  If -1, the SFXDescription::fadeOutTime "
1365      "set in the source's associated description is used.  Pass 0 to disable a fade-out effect that may be "
1366      "configured on the description.\n"
1367      "Be aware that if a fade-out effect is used, the source will not immediately transtion to stopped state but "
1368      "will rather remain in playing state until the fade-out time has expired." )
1369{
1370   object->stop( fadeOutTime );
1371}
1372
1373//-----------------------------------------------------------------------------
1374
1375DefineEngineMethod( SFXSource, pause, void, ( F32 fadeOutTime ), ( -1.0f ),
1376   "Pause playback of the source.\n"
1377   "@param fadeOutTime Seconds for the sound to fade down to zero volume.  If -1, the SFXDescription::fadeOutTime "
1378      "set in the source's associated description is used.  Pass 0 to disable a fade-out effect that may be "
1379      "configured on the description.\n"
1380      "Be aware that if a fade-out effect is used, the source will not immediately to paused state but will "
1381      "rather remain in playing state until the fade-out time has expired.." )
1382{
1383   object->pause( fadeOutTime );
1384}
1385
1386//-----------------------------------------------------------------------------
1387
1388DefineEngineMethod( SFXSource, isPlaying, bool, (),,
1389   "Test whether the source is currently playing.\n"
1390   "@return True if the source is in playing state, false otherwise.\n\n"
1391   "@see play\n"
1392   "@see getStatus\n"
1393   "@see SFXStatus" )
1394{
1395   return object->isPlaying();
1396}
1397
1398//-----------------------------------------------------------------------------
1399
1400DefineEngineMethod( SFXSource, isPaused, bool, (),,
1401   "Test whether the source is currently paused.\n"
1402   "@return True if the source is in paused state, false otherwise.\n\n"
1403   "@see pause\n"
1404   "@see getStatus\n"
1405   "@see SFXStatus" )
1406{
1407   return object->isPaused();
1408}
1409
1410//-----------------------------------------------------------------------------
1411
1412DefineEngineMethod( SFXSource, isStopped, bool, (),,
1413   "Test whether the source is currently stopped.\n"
1414   "@return True if the source is in stopped state, false otherwise.\n\n"
1415   "@see stop\n"
1416   "@see getStatus\n"
1417   "@see SFXStatus" )
1418{
1419   return object->isStopped();
1420}
1421
1422//-----------------------------------------------------------------------------
1423
1424DefineEngineMethod( SFXSource, getStatus, SFXStatus, (),,
1425   "Get the current playback status.\n"
1426   "@return Te current playback status\n" )
1427{
1428   return object->getStatus();
1429}
1430
1431//-----------------------------------------------------------------------------
1432
1433DefineEngineMethod( SFXSource, getVolume, F32, (),,
1434   "Get the current base volume level of the source.\n"
1435   "This is not the final effective volume that the source is playing at but rather the starting "
1436   "volume level before source group modulation, fades, or distance-based volume attenuation are applied.\n\n"
1437   "@return The current base volume level.\n\n"
1438   "@see setVolume\n"
1439   "@see SFXDescription::volume\n\n"
1440   "@ref SFXSource_volume" )
1441{
1442   return object->getVolume();
1443}
1444
1445//-----------------------------------------------------------------------------
1446
1447DefineEngineMethod( SFXSource, setVolume, void, ( F32 volume ),,
1448   "Set the base volume level for the source.\n"
1449   "This volume will be the starting point for source group volume modulation, fades, and distance-based "
1450   "volume attenuation.\n\n"
1451   "@param volume The new base volume level for the source.  Must be 0>=volume<=1.\n\n"
1452   "@see getVolume\n\n"
1453   "@ref SFXSource_volume" )
1454{
1455   object->setVolume( volume );
1456}
1457
1458//-----------------------------------------------------------------------------
1459
1460DefineEngineMethod( SFXSource, getAttenuatedVolume, F32, (),,
1461   "Get the final effective volume level of the source.\n\n"
1462   "This method returns the volume level as it is after source group volume modulation, fades, and distance-based "
1463   "volume attenuation have been applied to the base volume level.\n\n"
1464   "@return The effective volume of the source.\n\n"
1465   "@ref SFXSource_volume" )
1466{
1467   return object->getAttenuatedVolume();
1468}
1469
1470//-----------------------------------------------------------------------------
1471
1472DefineEngineMethod( SFXSource, getFadeInTime, F32, (),,
1473   "Get the fade-in time set on the source.\n"
1474   "This will initially be SFXDescription::fadeInTime.\n\n"
1475   "@return The fade-in time set on the source in seconds.\n\n"
1476   "@see SFXDescription::fadeInTime\n\n"
1477   "@ref SFXSource_fades" )
1478{
1479   return object->getFadeInTime();
1480}
1481
1482//-----------------------------------------------------------------------------
1483
1484DefineEngineMethod( SFXSource, getFadeOutTime, F32, (),,
1485   "Get the fade-out time set on the source.\n"
1486   "This will initially be SFXDescription::fadeOutTime.\n\n"
1487   "@return The fade-out time set on the source in seconds.\n\n"
1488   "@see SFXDescription::fadeOutTime\n\n"
1489   "@ref SFXSource_fades" )
1490{
1491   return object->getFadeOutTime();
1492}
1493
1494//-----------------------------------------------------------------------------
1495
1496DefineEngineMethod( SFXSource, setFadeTimes, void, ( F32 fadeInTime, F32 fadeOutTime ),,
1497   "Set the fade time parameters of the source.\n"
1498   "@param fadeInTime The new fade-in time in seconds.\n"
1499   "@param fadeOutTime The new fade-out time in seconds.\n\n"
1500   "@see SFXDescription::fadeInTime\n"
1501   "@see SFXDescription::fadeOutTime\n\n"
1502   "@ref SFXSource_fades" )
1503{
1504   object->setFadeTimes( fadeInTime, fadeOutTime );
1505}
1506
1507//-----------------------------------------------------------------------------
1508
1509DefineEngineMethod( SFXSource, getPitch, F32, (),,
1510   "Get the pitch scale of the source.\n"
1511   "Pitch determines the playback speed of the source (default: 1).\n\n"
1512   "@return The current pitch scale factor of the source.\n\n"
1513   "@see setPitch\n"
1514   "@see SFXDescription::pitch" )
1515{
1516   return object->getPitch();
1517}
1518
1519//-----------------------------------------------------------------------------
1520
1521DefineEngineMethod( SFXSource, setPitch, void, ( F32 pitch ),,
1522   "Set the pitch scale of the source.\n"
1523   "Pitch determines the playback speed of the source (default: 1).\n\n"
1524   "@param pitch The new pitch scale factor.\n\n"
1525   "@see getPitch\n"
1526   "@see SFXDescription::pitch" )
1527{
1528   object->setPitch( pitch );
1529}
1530
1531//-----------------------------------------------------------------------------
1532
1533// Need an overload here as we can't use a default parameter to signal omission of the direction argument
1534// and we need to properly detect the omission to leave the currently set direction on the source as is.
1535
1536/* LukasPJ: For now, just use the setTransform with strings as parameters.
1537DEFINE_CALLIN( fnSFXSoure_setTransform1, setTransform, SFXSource, void, ( SFXSource* source, const VectorF& position ),,,
1538   "Set the position of the source's 3D sound.\n\n"
1539   "@param position The new position in world space.\n"
1540   "@note This method has no effect if the source is not a 3D source." )
1541{
1542   MatrixF mat = source->getTransform();
1543   mat.setPosition( position );
1544   source->setTransform( mat );
1545}
1546DEFINE_CALLIN( fnSFXSoure_setTransform2, setTransform, SFXSource, void, ( SFXSource* source, const VectorF& position, const VectorF& direction  ),,,
1547   "Set the position and orientation of the source's 3D sound.\n\n"
1548   "@param position The new position in world space.\n"
1549   "@param direction The forward vector." )
1550{
1551   MatrixF mat = source->getTransform();
1552   mat.setPosition( position );
1553   mat.setColumn( 1, direction );
1554   source->setTransform( mat );
1555}
1556*/
1557
1558// Console interop version.
1559
1560static ConsoleDocFragment _sSetTransform1(
1561   "Set the position of the source's 3D sound.\n\n"
1562   "@param position The new position in world space.\n"
1563   "@note This method has no effect if the source is not a 3D source.",
1564   "SFXSource",
1565   "void setTransform( Point3F position )"
1566);
1567static ConsoleDocFragment _sSetTransform2(
1568   "Set the position and orientation of the source's 3D sound.\n\n"
1569   "@param position The new position in world space.\n"
1570   "@param direction The forward vector.",
1571   "SFXSource",
1572   "void setTransform( Point3F position, Point3F direction )"
1573);
1574
1575DefineEngineMethod( SFXSource, setTransform, void, ( const char * position, const char * direction ), ( "" ),
1576   "( vector position [, vector direction ] ) "
1577   "Set the position and orientation of a 3D sound source.\n"
1578   "@hide" )
1579{
1580   MatrixF mat = object->getTransform();
1581
1582   if(String::compare( position , "")!=0 )
1583   {
1584      Point3F pos;
1585      dSscanf( position, "%g %g %g", &pos.x, &pos.y, &pos.z );
1586      mat.setPosition( pos );
1587   }
1588   
1589   if(String::compare( direction ,"")!=0 )
1590   {
1591      Point3F dir;
1592      dSscanf( direction, "%g %g %g", &dir.x, &dir.y, &dir.z );
1593      mat.setColumn( 1, dir );
1594   }
1595   
1596   object->setTransform( mat );
1597}
1598
1599//-----------------------------------------------------------------------------
1600
1601DefineEngineMethod( SFXSource, setCone, void, ( F32 innerAngle, F32 outerAngle, F32 outsideVolume ),,
1602   "Set up the 3D volume cone for the source.\n\n"
1603   "@param innerAngle Angle of the inner sound cone in degrees (@ref SFXDescription::coneInsideAngle).  Must be 0<=innerAngle<=360.\n"
1604   "@param outerAngle Angle of the outer sound cone in degrees (@ref SFXDescription::coneOutsideAngle).  Must be 0<=outerAngle<=360.\n"
1605   "@param outsideVolume Volume scale factor outside of outer cone (@ref SFXDescription::coneOutsideVolume).  Must be 0<=outsideVolume<=1.\n"
1606   "@note This method has no effect on the source if the source is not 3D.\n\n" )
1607{
1608   bool isValid = true;
1609   
1610   if( innerAngle < 0.0 || innerAngle > 360.0 )
1611   {
1612      Con::errorf( "SFXSource.setCone() - 'innerAngle' must be between 0 and 360" );
1613      isValid = false;
1614   }
1615   if( outerAngle < 0.0 || outerAngle > 360.0 )
1616   {
1617      Con::errorf( "SFXSource.setCone() - 'outerAngle' must be between 0 and 360" );
1618      isValid = false;
1619   }
1620   if( outsideVolume < 0.0 || outsideVolume > 1.0 )
1621   {
1622      Con::errorf( "SFXSource.setCone() - 'outsideVolume' must be between 0 and 1" );
1623      isValid = false;
1624   }
1625   
1626   if( !isValid )
1627      return;
1628      
1629   object->setCone( innerAngle, outerAngle, outsideVolume );
1630}
1631
1632//-----------------------------------------------------------------------------
1633
1634DefineEngineMethod( SFXSource, getParameterCount, S32, (),,
1635   "Get the number of SFXParameters that are attached to the source.\n"
1636   "@return The number of parameters attached to the source.\n\n"
1637   "@tsexample\n"
1638      "// Print the name ofo each parameter attached to %source.\n"
1639      "%numParams = %source.getParameterCount();\n"
1640      "for( %i = 0; %i < %numParams; %i ++ )\n"
1641      "   echo( %source.getParameter( %i ).getParameterName() );\n"
1642   "@endtsexample\n\n"
1643   "@see getParameter\n"
1644   "@see addParameter\n" )
1645{
1646   return object->getNumParameters();
1647}
1648
1649//-----------------------------------------------------------------------------
1650
1651DefineEngineMethod( SFXSource, addParameter, void, ( SFXParameter* parameter ),,
1652   "Attach @a parameter to the source,\n\n"
1653   "Once attached, the source will react to value changes of the given @a parameter.  Attaching a parameter "
1654   "will also trigger an initial read-out of the parameter's current value.\n\n"
1655   "@param parameter The parameter to attach to the source." )
1656{
1657   if( parameter )
1658      object->addParameter( parameter );
1659}
1660
1661//-----------------------------------------------------------------------------
1662
1663DefineEngineMethod( SFXSource, removeParameter, void, ( SFXParameter* parameter ),,
1664   "Detach @a parameter from the source.\n\n"
1665   "Once detached, the source will no longer react to value changes of the given @a parameter.\n\n"
1666   "If the parameter is not attached to the source, the method will do nothing.\n\n"
1667   "@param parameter The parameter to detach from the source.\n" )
1668{
1669   if( parameter )
1670      object->removeParameter( parameter );
1671}
1672
1673//-----------------------------------------------------------------------------
1674
1675DefineEngineMethod( SFXSource, getParameter, SFXParameter*, ( S32 index ),,
1676   "Get the parameter at the given index.\n"
1677   "@param index Index of the parameter to fetch.  Must be 0<=index<=getParameterCount().\n"
1678   "@return The parameter at the given @a index or null if @a index is out of range.\n\n"
1679   "@tsexample\n"
1680      "// Print the name ofo each parameter attached to %source.\n"
1681      "%numParams = %source.getParameterCount();\n"
1682      "for( %i = 0; %i < %numParams; %i ++ )\n"
1683      "   echo( %source.getParameter( %i ).getParameterName() );\n"
1684   "@endtsexample\n\n"
1685   "@see getParameterCount" )
1686{
1687   if( index >= object->getNumParameters() )
1688   {
1689      Con::errorf( "SFXSource::getParameter - index out of range: %i", index );
1690      return 0;
1691   }
1692   
1693   return object->getParameter( index );
1694}
1695
1696//-----------------------------------------------------------------------------
1697
1698DefineEngineMethod( SFXSource, addMarker, void, ( String name, F32 pos ),,
1699   "Add a notification marker called @a name at @a pos seconds of playback.\n\n"
1700   "@param name Symbolic name for the marker that will be passed to the onMarkerPassed() callback.\n"
1701   "@param pos Playback position in seconds when the notification should trigger.  Note that this is a soft limit and there "
1702      "may be a delay between the play cursor actually passing the position and the callback being triggered.\n\n"
1703   "@note For looped sounds, the marker will trigger on each iteration.\n\n"
1704   "@tsexample\n"
1705   "// Create a new source.\n"
1706   "$source = sfxCreateSource( AudioMusicLoop2D, \"art/sound/backgroundMusic\" );\n"
1707   "\n"
1708   "// Assign a class to the source.\n"
1709   "$source.class = \"BackgroundMusic\";\n"
1710   "\n"
1711   "// Add a playback marker at one minute into playback.\n"
1712   "$source.addMarker( \"first\", 60 );\n"
1713   "\n"
1714   "// Define the callback function.  This function will be called when the playback position passes the one minute mark.\n"
1715   "function BackgroundMusic::onMarkerPassed( %this, %markerName )\n"
1716   "{\n"
1717   "   if( %markerName $= \"first\" )\n"
1718   "      echo( \"Playback has passed the 60 seconds mark.\" );\n"
1719   "}\n"
1720   "\n"
1721   "// Play the sound.\n"
1722   "$source.play();\n"
1723   "@endtsexample" )
1724{
1725   object->addMarker( name, pos );
1726}
1727