sfxSource.h

Engine/source/sfx/sfxSource.h

More...

Classes:

class

Baseclass for sources and controllers.

Public Defines

define
SFX_DELETE(source)    (  )               \
   {                          \
      ->deleteObject(); \
       = ;          \
   }                          \

A simple macro to automate the deletion of a source.

Detailed Description

Public Defines

SFX_DELETE(source)    (  )               \
   {                          \
      ->deleteObject(); \
       = ;          \
   }                          \

A simple macro to automate the deletion of a source.

  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#ifndef _SFXSOURCE_H_
 25#define _SFXSOURCE_H_
 26
 27#ifndef _SIMSET_H_
 28   #include "console/simSet.h"
 29#endif
 30#ifndef _SFXCOMMON_H_
 31   #include "sfx/sfxCommon.h"
 32#endif
 33#ifndef _SFXDESCRIPTION_H_
 34   #include "sfx/sfxDescription.h"
 35#endif
 36#ifndef _SFXPARAMETER_H_
 37   #include "sfx/sfxParameter.h"
 38#endif
 39#ifndef _TVECTOR_H_
 40   #include "core/util/tVector.h"
 41#endif
 42#ifndef _TIMESOURCE_H_
 43   #include "core/util/timeSource.h"
 44#endif
 45#ifndef _BITSET_H_
 46   #include "core/bitSet.h"
 47#endif
 48#ifndef _TORQUE_LIST_
 49   #include "core/util/tList.h"
 50#endif
 51
 52
 53class SFXTrack;
 54class SFXDescription;
 55class SFXSourceGroup;
 56class SFXModifier;
 57class EaseF;
 58
 59
 60/// Baseclass for sources and controllers.
 61class SFXSource : public SimGroup
 62{
 63   public:
 64
 65      typedef SimGroup Parent;
 66         
 67      friend class SFXSystem; // _init
 68         
 69   protected:
 70
 71      typedef Torque::List< SFXModifier*> ModifierList;
 72      typedef GenericTimeSource< RealMSTimer> TimeSource;
 73      
 74      enum Flags
 75      {
 76         CustomVolumeFlag           = BIT( 0 ),
 77         CustomPitchFlag            = BIT( 1 ),
 78         CustomPriorityFlag         = BIT( 2 ),
 79         CustomRadiusFlag           = BIT( 3 ),
 80         CustomConeFlag             = BIT( 4 ),
 81         CustomFadeFlag             = BIT( 5 ),
 82         CustomGroupFlag            = BIT( 6 ),
 83      };
 84                        
 85      ///
 86      BitSet32 mFlags;
 87      
 88      /// @name Status
 89      /// @{
 90
 91      /// Current playback status.
 92      SFXStatus mStatus;
 93
 94      /// The playback status that the source actually wants to be in.
 95      SFXStatus mSavedStatus;
 96
 97      /// Console functions to call when the source status changes.
 98      /// If not set, "onStatusChange" will be called on the source object.
 99      StringTableEntry mStatusCallback;
100
101      /// Used internally for setting the sound status.
102      virtual void _setStatus( SFXStatus newStatus );
103                  
104      /// Update the playback status of the source.  Meant for subclasses
105      /// that need to poll a connected resource.
106      virtual void _updateStatus() {}
107      
108      /// @}
109
110      /// @name Datablocks
111      ///
112      /// The track datablock is optional but the description datablock is required.
113      /// If either of the two goes away, the source will auto-delete itself.
114      ///
115      /// These members are SimObjectPtr so that temporary track and description
116      /// objects that are set to auto-delete will work.
117      ///
118      /// @{
119      
120      /// The track being played by this source.
121      /// @note Will be null for sources that have been created from SFXStreams.
122      SimObjectPtr< SFXTrack> mTrack;
123
124      /// The description holding the SFX sound configuration.
125      SimObjectPtr< SFXDescription> mDescription;
126      
127      /// @}
128      
129      /// @name Volume
130      ///
131      /// Volume processing goes through a series of stages.  The last stage, distance attenuation,
132      /// happens only for 3D sounds and is done on the device (though the attenuated volume is also
133      /// computed within SFX).
134      ///
135      /// The succession of stages is:
136      ///
137      /// 1. Fade (Apply fade-in/out if currently active)
138      /// 2. Modulate (Apply scale factor set on source)
139      /// 3. Modulate (Apply attenuated volume of source group as scale factor)
140      /// 4. Attenuate (Apply 3D distance attenuation based on current listener position)
141      ///
142      /// @{
143      
144      /// The desired sound volume.
145      F32 mVolume;
146      
147      /// Volume before fade stage.  Used as input to volume computation.  Usually this
148      /// corresponds to mVolume but when fading out from an already faded start volume,
149      /// this contains the starting mFadedVolume.
150      F32 mPreFadeVolume;
151      
152      /// "mVolume" after fade stage.  Same as "mPreFadeVolume" if no fade
153      /// is active.
154      F32 mFadedVolume;
155      
156      /// Volume scale factor imposed on this source by controller.
157      F32 mModulativeVolume;
158
159      /// Effective volume after fade and modulation but before distance attenuation.
160      /// For non-3D sounds, this is the final effective volume.
161      F32 mPreAttenuatedVolume;
162      
163      /// Effective volume after distance attenuation.  Continuously updated
164      /// to match listener position.  For non-3D sounds, this is the same
165      /// as mPreAttenuatedVolume.
166      ///
167      /// @note The distance attenuation that is computed here does not take
168      ///   sound cones into account so the computed attenuated volume may be
169      ///   higher than the actual effective volume on the device (never
170      ///   lower though).
171      F32 mAttenuatedVolume;
172      
173      /// Set volume without affecting CustomVolumeFlag.
174      void _setVolume( F32 volume );
175
176      /// Update the effective volume of the source.
177      virtual void _updateVolume( const MatrixF& listener );
178
179      /// @}
180      
181      /// @name Virtualization
182      /// @{
183
184      /// The desired sound priority.
185      F32 mPriority;
186      
187      /// The priority scale factor imposed by controllers.
188      F32 mModulativePriority;
189      
190      /// The final priority level.
191      F32 mEffectivePriority;
192      
193      /// Set priority without affecting CustomPriorityFlag.
194      void _setPriority( F32 priority );
195
196      /// Update the effective priority of the source.
197      virtual void _updatePriority();
198      
199      /// @}
200      
201      /// @name Pitch
202      /// @{
203
204      /// The desired sound pitch.
205      F32 mPitch;
206      
207      /// The pitch scale factor imposed by controllers.
208      F32 mModulativePitch;
209      
210      /// The final effective pitch.
211      F32 mEffectivePitch;
212      
213      /// Set pitch without affecting CustomPitchFlag.
214      void _setPitch( F32 pitch );
215
216      /// Update the effective pitch of the source.
217      virtual void _updatePitch();
218
219      ///
220      
221      /// @}
222            
223      /// @name 3D Sound
224      /// @{
225
226      /// The transform if this is a 3d source.
227      MatrixF mTransform;
228
229      /// The last set velocity.
230      VectorF mVelocity;
231
232      /// Distance at which to begin distanced-based volume attenuation.
233      F32 mMinDistance;
234
235      /// Distance at which to stop distance-based volume attenuation.
236      F32 mMaxDistance;
237
238      /// Inside cone angle in degrees.
239      F32 mConeInsideAngle;
240
241      /// Outside cone angle in degrees.
242      F32 mConeOutsideAngle;
243
244      /// Outside cone volume.
245      F32 mConeOutsideVolume;
246      
247      /// The distance of this source to the last 
248      /// listener position.
249      F32 mDistToListener;
250
251      /// If true, the transform position has been randomized.
252      bool mTransformScattered;
253
254      /// Randomize transform based on scatter settings.
255      void _scatterTransform();
256
257      /// Set 3D min/max distance without affecting CustomRadiusFlag.
258      virtual void _setMinMaxDistance( F32 min, F32 max );
259
260      /// Set 3D cone without affecting CustomConeFlag.
261      virtual void _setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
262
263      /// @}
264      
265      /// @name Fading
266      ///
267      /// The fade system consists of "persistent" fades placed at the beginning
268      /// and end of the playback range and of "temporary" fade segments placed in the
269      /// playback range when stopping/pausing/resuming a source in midst of playback.
270      ///
271      /// @{
272      
273      /// The current "persistent" fade-in time in seconds.  Taken initially from the
274      /// SFXDescription and as long as not being manually set on the source, will
275      /// stay with the description's "fadeInTime" property.
276      F32 mFadeInTime;
277      
278      /// The current "persistent" fade-out time in seconds.  Taken initially from the
279      /// SFXDescription and as long as not being manually set on the source, will
280      /// stay with the description's "fadeOutTime" property.
281      F32 mFadeOutTime;
282      
283      /// Type for temporary fade segments.
284      enum FadeSegmentType
285      {
286         FadeSegmentNone,     ///< No temporary fade segment set.
287         FadeSegmentPlay,     ///< Temporary fade-in segment.
288         FadeSegmentStop,     ///< Temporary fade-out segment ending in stop().
289         FadeSegmentPause     ///< Temporary fade-out segment ending in pause().
290      };
291
292      /// Playtime at which persistent fade-in ends.  -1 if no fade-in.
293      F32 mFadeInPoint;
294      
295      /// Playtime at which persistent fade-out starts.  -1 if no fade-out.
296      F32 mFadeOutPoint;
297      
298      /// Type of the current temporary fade segment.  No temporary fade segment
299      /// is in place when this is FadeSegmentNone.
300      FadeSegmentType mFadeSegmentType;
301                  
302      /// Easing curve for the current fade segment.
303      EaseF* mFadeSegmentEase;
304
305      /// Playback position where the current temporary fade segment starts.
306      F32 mFadeSegmentStartPoint;
307
308      /// Playback position where the current temporary fade segment ends.
309      F32 mFadeSegmentEndPoint;
310
311      /// Fade time to apply when transitioning to mSavedStatus.
312      F32 mSavedFadeTime;
313      
314      ///
315      virtual void _setFadeTimes( F32 fadeInTime, F32 fadeOutTime );
316      
317      /// Set up a temporary fade-out segment.
318      void _setupFadeOutSegment( FadeSegmentType type, F32 fadeOutTime );
319      
320      /// @}
321      
322      /// @name Parameters
323      /// @{
324                  
325      ///
326      Vector< SFXParameter*> mParameters;
327
328      ///
329      void _addParameter( StringTableEntry name );
330
331      ///
332      virtual void _onParameterEvent( SFXParameter* parameter, SFXParameterEvent event );
333      
334      /// @}
335      
336      /// @name Playback
337      /// @{
338
339      /// The simulation tick count that playback was started at for this source.
340      U32 mPlayStartTick;
341
342      /// Time object used to keep track of playback.
343      TimeSource mPlayTimer;
344      
345      /// Start playback.  For implementation by concrete subclasses.
346      /// @note This method should not take fading into account.
347      virtual void _play();
348      
349      /// Pause playback.  For implementation by concrete subclasses.
350      /// @note This method should not take fading into account.
351      virtual void _pause();
352      
353      /// Stop playback.  For implementation by concrete subclasses.
354      /// @note This method should not take fading into account.
355      virtual void _stop();
356
357      /// @}
358      
359      /// @name Modifiers
360      /// @{
361            
362      /// List of modifiers that are active on this source.
363      ModifierList mModifiers;
364      
365      /// Delete all modifiers of the given type.
366      template< class T > void _clearModifiers();
367
368      /// @}
369      
370      /// @name Callbacks
371      /// @{
372      
373      DECLARE_CALLBACK( void, onStatusChange, ( SFXStatus newStatus ) );
374      DECLARE_CALLBACK( void, onParameterValueChange, ( SFXParameter* parameter ) );
375      
376      /// @}
377                        
378      ///
379      SFXSource( SFXTrack* track, SFXDescription* description = NULL );
380            
381      ///
382      virtual void _update();
383
384      /// We overload this to disable creation of 
385      /// a source via script 'new'.
386      virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
387      
388      // Console getters/setters.
389      static bool _setDescription( void *obj, const char *index, const char *data );
390      static const char* _getDescription( void* obj, const char* data );
391
392   public:
393      
394      ///
395      SFXSource();
396      
397      ~SFXSource();
398
399      ///
400      void update();
401      
402      /// Returns the track played by this source; NULL for sources playing directly
403      /// from streams.
404      SFXTrack* getTrack() const;
405      
406      /// Return the SFX description associated with this source.  Never NULL.
407      SFXDescription* getDescription() const { return mDescription; }
408      
409      /// Return the source group that this source has been assigned to.
410      SFXSource* getSourceGroup() const;
411            
412      /// @name Playback Status
413      /// @{
414   
415      /// Returns the last known status without doing an update.
416      SFXStatus getLastStatus() const { return mStatus; }
417
418      /// Return the status that the source wants to be in.  Used for playback
419      /// control in combination with source groups.
420      SFXStatus getSavedStatus() const { return mSavedStatus; }
421
422      /// Returns the sound status.
423      SFXStatus getStatus() const { const_cast< SFXSource* >( this )->_updateStatus(); return mStatus; }
424
425      /// Returns true if the source is playing.
426      bool isPlaying() const { return getStatus() == SFXStatusPlaying; }
427
428      /// Returns true if the source is stopped.
429      bool isStopped() const { return getStatus() == SFXStatusStopped; }
430
431      /// Returns true if the source has been paused.
432      bool isPaused() const { return getStatus() == SFXStatusPaused; }
433      
434      /// Returns true if the source is currently being virtualized.
435      virtual bool isVirtualized() const { return false; }
436      
437      /// Returns true if this is a looping source.
438      bool isLooping() const { return mDescription.isValid() && mDescription->mIsLooping; }
439
440      /// @}
441      
442      /// @name Playback Control
443      /// @{
444
445      /// Starts the sound from the current playback position.
446      ///
447      /// @param fadeInTime Seconds for sound to fade in.  If -1, fadeInTime from
448      ///   SFXDescription is used.  Note that certain SFXSource classes may not
449      ///   support values other than 0 and -1.
450      virtual void play( F32 fadeInTime = -1.f );
451
452      /// Stops playback and resets the playback position.
453      ///
454      /// @note This method is also required to release all playback-related
455      ///   resources on the device.
456      ///
457      /// @param fadeOutTime Seconds for sound to fade out.  If -1, fadeOutTime from
458      ///   SFXDescription is used.  Note that certain SFXSource classes may not support
459      ///   values other than 0 and -1.
460      virtual void stop( F32 fadeOutTime = -1.f );
461
462      /// Pauses the sound playback.
463      ///
464      /// @param fadeOutTime Seconds for sound to fade out.  If -1, fadeOutTime from
465      ///   SFXDescription is used.  Note that certain SFXSource clsases may not support
466      ///   values other than 0 and -1.
467      virtual void pause( F32 fadeOutTime = -1.f );
468      
469      /// Return the elapsed play time of the current loop cycle so far in seconds.
470      virtual F32 getElapsedPlayTimeCurrentCycle() const;
471
472      /// Return the total elapsed play time so far in seconds.
473      virtual F32 getElapsedPlayTime() const;
474      
475      /// Return the total play time of the source in seconds.  Positive infinity by default.
476      ///
477      /// @note For looping sounds, this must include only the playtime of a single cycle.
478      virtual F32 getTotalPlayTime() const;
479      
480      /// @}
481            
482      /// @name 3D Sound
483      /// @{
484
485      /// Returns true if this is a 3D source.
486      bool is3d() const { return mDescription->mIs3D; }
487
488      /// Returns the last set velocity.
489      const VectorF& getVelocity() const { return mVelocity; }
490
491      /// Returns the last set transform.
492      const MatrixF& getTransform() const { return mTransform; }
493
494      /// Sets the position and orientation for a 3d buffer.
495      virtual void setTransform( const MatrixF& transform );
496
497      /// Sets the velocity for a 3d buffer.
498      virtual void setVelocity( const VectorF& velocity );
499
500      /// Sets the minimum and maximum distances for 3d falloff.
501      void setMinMaxDistance( F32 min, F32 max ) { _setMinMaxDistance( min, max ); mFlags.set( CustomRadiusFlag ); }
502
503      /// Set sound cone of a 3D sound.
504      ///
505      /// @param innerAngle Inner cone angle in degrees.
506      /// @param outerAngle Outer cone angle in degrees.
507      /// @param outerVolume Outer volume factor.
508      void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ) { _setCone( innerAngle, outerAngle, outerVolume ); mFlags.set( CustomConeFlag ); }
509      
510      /// Returns the last distance to the listener.
511      /// @note Only works when distance attenuation calculations are being triggered by SFX and
512      ///   are not left exclusively to the SFX device.
513      F32 getDistToListener() const { return mDistToListener; }
514
515      /// @}
516      
517      /// @name Volume
518      /// @{
519
520      /// Returns the source volume at its unaltered initial setting,
521      /// i.e. prior to fading, modulation, and attenuation.
522      F32 getVolume() const { return mVolume; }
523
524      /// Sets the source volume which will still be
525      /// scaled by the master and group volumes.
526      ///
527      /// @note Note that if you set an explicit volume on a source
528      void setVolume( F32 volume ) { _setVolume( volume ); mFlags.set( CustomVolumeFlag ); }
529
530      ///
531      F32 getModulativeVolume() const { return mModulativeVolume; }
532      
533      /// Set the per-source volume scale factor.
534      void setModulativeVolume( F32 value );
535      
536      ///
537      F32 getPreAttenuatedVolume() const { return mPreAttenuatedVolume; }
538
539      /// Returns the volume with respect to the master 
540      /// and group volumes and the listener.
541      F32 getAttenuatedVolume() const { return mAttenuatedVolume; }
542      
543      ///
544      F32 getFadeInTime() const { return mFadeInTime; }
545      
546      ///
547      F32 getFadeOutTime() const { return mFadeOutTime; }
548      
549      ///
550      void setFadeTimes( F32 fadeInTime, F32 fadeOutTime );
551            
552      /// @}
553      
554      /// @name Pitch
555      /// @{
556
557      /// Returns the source pitch scale.
558      F32 getPitch() const { return mPitch; }
559
560      /// Sets the source pitch scale.
561      void setPitch( F32 pitch ) { _setPitch( pitch ); mFlags.set( CustomPitchFlag ); }
562      
563      ///
564      F32 getModulativePitch() const { return mModulativePitch; }
565      
566      ///
567      void setModulativePitch( F32 value );
568      
569      ///
570      F32 getEffectivePitch() const { return mEffectivePitch; }
571      
572      /// @}
573      
574      /// @name Dynamic Parameters
575      ///
576      /// Dynamic parameters allow to pass on values from the game system to the sound system
577      /// and thus implement interactive audio.
578      ///
579      /// It is dependent on the back-end source implementation how it will react to parameter
580      /// settings.
581      ///
582      /// @{
583      
584      ///
585      U32 getNumParameters() const { return mParameters.size(); }
586      
587      ///
588      SFXParameter* getParameter( U32 index )
589      {
590         AssertFatal( index < getNumParameters(), "SFXSource::getParameter() - index out of range" );
591         return mParameters[ index ];
592      }
593      
594      ///
595      virtual void addParameter( SFXParameter* parameter );
596      
597      ///
598      virtual void removeParameter( SFXParameter* parameter );
599      
600      /// @}
601      
602      /// @name Modifiers
603      /// @{
604      
605      ///
606      void addModifier( SFXModifier* modifier );
607      
608      ///
609      void addMarker( const String& name, F32 pos );
610      
611      /// @}
612
613      /// @name Virtualization
614      /// @{
615      
616      /// Returns the source priority.
617      F32 getPriority() const { return mPriority; }
618            
619      ///
620      void setPriority( F32 priority ) { _setPriority( priority ); mFlags.set( CustomPriorityFlag ); }
621      
622      ///
623      F32 getModulativePriority() const { return mModulativePriority; }
624      
625      ///
626      void setModulativePriority( F32 value );
627      
628      ///
629      F32 getEffectivePriority() const { return mEffectivePriority; }
630
631      /// @}
632            
633      /// @}
634      
635      /// @name Change Notifications
636      /// @{
637      
638      /// Notify the source that its attached SFXDescription has changed.
639      virtual void notifyDescriptionChanged();
640      
641      /// Notify the source that its attached SFXTrack has changed.
642      virtual void notifyTrackChanged();
643      
644      /// @}
645            
646      // SimGroup.
647      virtual bool onAdd();
648      virtual void onRemove();
649      virtual void onDeleteNotify( SimObject* object );
650      virtual bool acceptsAsChild( SimObject* object );
651      virtual void onGroupAdd();
652      
653      static void initPersistFields();
654      
655      DECLARE_CONOBJECT( SFXSource );
656      DECLARE_CATEGORY( "SFX" );
657      DECLARE_DESCRIPTION( "SFX sound playback controller." );
658};
659
660/// A simple macro to automate the deletion of a source.
661///
662/// @see SFXSource
663///
664#undef  SFX_DELETE
665#define SFX_DELETE( source )  \
666   if( source )               \
667   {                          \
668      source->deleteObject(); \
669      source = NULL;          \
670   }                          \
671
672#endif // !_SFXSOURCE_H_
673