sfxSource.cpp
Engine/source/sfx/sfxSource.cpp
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