123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _SFXSYSTEM_H_
- #define _SFXSYSTEM_H_
- #ifndef _SFXCOMMON_H_
- #include "sfx/sfxCommon.h"
- #endif
- #ifndef _TSIGNAL_H_
- #include "core/util/tSignal.h"
- #endif
- #ifndef _TVECTOR_H_
- #include "core/util/tVector.h"
- #endif
- #ifndef _THREADSAFEREFCOUNT_H_
- #include "platform/threads/threadSafeRefCount.h"
- #endif
- class SFXTrack;
- class SFXDevice;
- class SFXProfile;
- class SFXStream;
- class SFXAmbience;
- class SFXSoundscapeManager;
- class SFXSource;
- class SFXSound;
- class SFXBuffer;
- class SFXDescription;
- /// SFX system events that can be received notifications on.
- enum SFXSystemEventType
- {
- /// SFX is being updated.
- SFXSystemEvent_Update,
-
- /// New SFXDevice has been created.
- SFXSystemEvent_CreateDevice,
-
- /// SFXDevice is about to be destroyed.
- SFXSystemEvent_DestroyDevice,
- };
- /// SFXSystemPlugins are used to allow other subsystems hook into core functionality
- /// of the sound system.
- class SFXSystemPlugin
- {
- public:
-
- ///
- virtual void update() {}
-
- ///
- virtual SFXSource* createSource( SFXTrack* track ) { return NULL; }
-
- /// Filter the given reverb setup before it is set up on the device. This
- /// allows to, for example, modify the current reverb depending on listener
- /// location.
- virtual void filterReverb( SFXReverbProperties& reverb ) {}
- };
- /// This class provides access to the sound system.
- ///
- /// There are a few script preferences that are used by
- /// the sound providers.
- ///
- /// $pref::SFX::frequency - This is the playback frequency
- /// for the primary sound buffer used for mixing. Although
- /// most providers will reformat on the fly, for best quality
- /// and performance match your sound files to this setting.
- ///
- /// $pref::SFX::bitrate - This is the playback bitrate for
- /// the primary sound buffer used for mixing. Although most
- /// providers will reformat on the fly, for best quality
- /// and performance match your sound files to this setting.
- ///
- class SFXSystem
- {
- friend class SFXSound; // _assignVoices
- friend class SFXSource; // _onAddSource, _onRemoveSource.
- friend class SFXProfile; // _createBuffer.
- public:
-
- typedef Signal< void( SFXSystemEventType event ) > EventSignalType;
- typedef Vector< SFXSource* > SFXSourceVector;
- typedef Vector< SFXSound* > SFXSoundVector;
-
- protected:
- /// The one and only instance of the SFXSystem.
- static SFXSystem* smSingleton;
- /// The protected constructor.
- ///
- /// @see SFXSystem::init()
- ///
- SFXSystem();
- /// The non-virtual destructor. You shouldn't
- /// ever need to overload this class.
- ~SFXSystem();
- /// The current output sound device initialized
- /// and ready to play back.
- SFXDevice* mDevice;
-
- ///
- SFXSoundVector mSounds;
- /// This is used to keep track of play once sources
- /// that must be released when they stop playing.
- SFXSourceVector mPlayOnceSources;
-
- /// The last time the sources got an update.
- U32 mLastSourceUpdateTime;
-
- ///
- U32 mLastAmbientUpdateTime;
-
- ///
- U32 mLastParameterUpdateTime;
- /// The distance model used for rolloff curve computation on 3D sounds.
- SFXDistanceModel mDistanceModel;
-
- /// The current doppler scale factor.
- F32 mDopplerFactor;
-
- /// The current curve rolloff factor.
- F32 mRolloffFactor;
-
- /// The current position and orientation of all listeners.
- Vector< SFXListenerProperties > mListeners;
-
- /// Current global reverb properties.
- SFXReverbProperties mReverb;
-
- /// SFX system event signal.
- EventSignalType mEventSignal;
-
- /// Ambient soundscape manager.
- SFXSoundscapeManager* mSoundscapeMgr;
-
- /// List of plugins currently linked to the SFX system.
- Vector< SFXSystemPlugin* > mPlugins;
- /// @name Stats
- ///
- /// Stats reported back to the console for tracking performance.
- ///
- /// @{
- S32 mStatNumSources;
- S32 mStatNumSounds;
- S32 mStatNumPlaying;
- S32 mStatNumCulled;
- S32 mStatNumVoices;
- S32 mStatSourceUpdateTime;
- S32 mStatParameterUpdateTime;
- S32 mStatAmbientUpdateTime;
- /// @}
- /// Called to reprioritize and reassign buffers as
- /// sources change state, volumes are adjusted, and
- /// the listener moves around.
- ///
- /// @see SFXSource::_update()
- ///
- void _updateSources();
- /// This called to reprioritize and reassign
- /// voices to sources.
- void _assignVoices();
-
- ///
- void _assignVoice( SFXSound* sound );
- ///
- void _sortSounds( const SFXListenerProperties& listener );
- /// Called from SFXSource::onAdd to register the source.
- void _onAddSource( SFXSource* source );
-
- /// Called from SFXSource::onRemove to unregister the source.
- void _onRemoveSource( SFXSource* source );
- /// Called from SFXProfile to create a device specific
- /// sound buffer used in conjunction with a voice in playback.
- SFXBuffer* _createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
-
- /// Load file directly through SFXDevice. Depends on
- /// availability with selected SFXDevice.
- ///
- /// @return Return new buffer or NULL.
- SFXBuffer* _createBuffer( const String& filename, SFXDescription* description );
-
- ///
- SFXDevice* _getDevice() const { return mDevice; }
- public:
- /// Returns the one an only instance of the SFXSystem
- /// unless it hasn't been initialized or its been disabled
- /// in your build.
- ///
- /// For convienence you can use the SFX-> macro as well.
- ///
- /// @see SFXSystem::init()
- /// @see SFX
- static SFXSystem* getSingleton() { return smSingleton; }
- /// This is called from initialization to prepare the
- /// sound system singleton. This also includes registering
- /// common resource types and initializing available sound
- /// providers.
- static void init();
- /// This is called after Sim::shutdown() in shutdownLibraries()
- /// to free the sound system singlton. After this the SFX
- /// singleton is null and any call to it will crash.
- static void destroy();
- /// This is only public so that it can be called by
- /// the game update loop. It updates the current
- /// device and all sources.
- void _update();
-
- /// Register the given plugin with the system.
- void addPlugin( SFXSystemPlugin* plugin );
-
- /// Unregister the given plugin with the system.
- void removePlugin( SFXSystemPlugin* plugin );
-
- /// @name Device Management
- /// @{
- /// This initializes a new device.
- ///
- /// @param providerName The name of the provider.
- /// @param deviceName The name of the provider device.
- /// @param useHardware Toggles the use of hardware processing when available.
- /// @param maxBuffers The maximum buffers for this device to use or -1
- /// for the device to pick its own reasonable default.
- /// @param changeDevice Allows this to change the current device to a new one
- /// @return Returns true if the device was created.
- bool createDevice( const String& providerName,
- const String& deviceName,
- bool useHardware,
- S32 maxBuffers,
- bool changeDevice = false);
- /// Returns the current device information or NULL if no
- /// device is present. The information string is in the
- /// following format:
- ///
- /// Provider Name\tDevice Name\tUse Hardware\tMax Buffers
- String getDeviceInfoString();
- /// This destroys the current device. All sources loose their
- /// playback buffers, but otherwise continue to function.
- void deleteDevice();
- /// Returns true if a device is allocated.
- bool hasDevice() const { return mDevice != NULL; }
-
- /// @}
-
- /// @name Source Creation
- /// @{
- /// Used to create new sound sources from a sound profile. The
- /// returned source is in a stopped state and ready for playback.
- /// Use the SFX_DELETE macro to free the source when your done.
- ///
- /// @note The track must have at least the same lifetime as the
- /// source. If the description disappears while the source is still
- /// there, the source will go with it.
- ///
- /// @param profile The sound profile for the created source.
- /// @param transform The optional transform if creating a 3D source.
- /// @param velocity The optional doppler velocity if creating a 3D source.
- ///
- /// @return The sound source or NULL if an error occured.
- SFXSource* createSource( SFXTrack* track,
- const MatrixF* transform = NULL,
- const VectorF* velocity = NULL );
- /// Used to create a streaming sound source from a user supplied
- /// stream object.
- ///
- /// It is only intended for memory based streams. For sound file
- /// streaming use createSource() with a streaming SFXProfile.
- ///
- /// Use the SFX_DELETE macro to free the source when your done.
- ///
- /// @note The description must have at least the same lifetime as the
- /// sound. If the description disappears while the source is still
- /// there, the sound will go with it.
- ///
- /// @param stream The stream used to create the sound buffer. It
- /// must exist for the lifetime of the source and will
- /// have its reference count decremented when the source
- /// is destroyed.
- ///
- /// @param description The sound description to apply to the source.
- ///
- /// @return The sound source or NULL if an error occured.
- SFXSound* createSourceFromStream( const ThreadSafeRef< SFXStream >& stream,
- SFXDescription* description );
- /// Creates a source which when it finishes playing will auto delete
- /// itself. Be aware that the returned SFXSource pointer should only
- /// be used for error checking or immediate setting changes. It may
- /// be deleted as soon as the next system tick.
- ///
- /// @param profile The sound profile for the created source.
- /// @param transform The optional transform if creating a 3D source.
- /// @param velocity The optional doppler velocity if creating a 3D source.
- ///
- /// @return The sound source or NULL if an error occured.
- SFXSource* playOnce( SFXTrack* track,
- const MatrixF* transform = NULL,
- const VectorF* velocity = NULL,
- F32 fadeInTime = -1.f );
- SFXSource* playOnce( SFXProfile* profile,
- const MatrixF* transform = NULL,
- const VectorF* velocity = NULL,
- F32 fadeInTime = -1.f )
- { // Avoids having to require inclusion of sfxProfile.h
- return playOnce( ( SFXTrack* ) profile, transform, velocity, fadeInTime );
- }
-
- /// Stop the source and delete it. This method will take care of
- /// the fade-out time that the source may need before it will actually
- /// stop and may be deleted.
- void stopAndDeleteSource( SFXSource* source );
-
- /// Mark source for deletion when it is moving into stopped state.
- /// This method is useful to basically make a source a play-once source
- /// after the fact.
- void deleteWhenStopped( SFXSource* source );
-
- /// @}
-
- /// @}
-
- /// @name Listeners
- /// @{
- /// Return the number of listeners currently configured.
- U32 getNumListeners() const { return mListeners.size(); }
-
- /// Set the number of concurrent listeners.
- /// @note It depends on the selected device if more than one listener is actually supported.
- void setNumListeners( U32 num );
- /// Set the property of the given listener.
- const SFXListenerProperties& getListener( U32 index = 0 ) const { return mListeners[ index ]; }
-
- /// Set the 3D attributes of the given listener.
- void setListener( U32 index, const MatrixF& transform, const Point3F& velocity );
- void setListener( U32 index, const SFXListenerProperties& properties )
- {
- setListener( index, properties.getTransform(), properties.getVelocity() );
- }
-
- /// @}
-
- /// @name 3D Sound Configuration
- /// {
-
- /// Return the curve model currently used distance attenuation of positional sounds.
- SFXDistanceModel getDistanceModel() const { return mDistanceModel; }
-
- ///
- void setDistanceModel( SFXDistanceModel model );
-
- ///
- F32 getDopplerFactor() const { return mDopplerFactor; }
-
- ///
- void setDopplerFactor( F32 factor );
-
- ///
- F32 getRolloffFactor() const { return mRolloffFactor; }
-
- ///
- void setRolloffFactor( F32 factor );
-
- ///
- const SFXReverbProperties& getReverb() const { return mReverb; }
-
- ///
- void setReverb( const SFXReverbProperties& reverb );
-
- /// @}
-
- ///
- SFXSoundscapeManager* getSoundscapeManager() const { return mSoundscapeMgr; }
-
- /// Dump information about all current SFXSources to the console or
- /// to the given StringBuilder.
- void dumpSources( StringBuilder* toString = NULL, bool excludeGroups = true );
-
- /// Return the SFX system event signal.
- EventSignalType& getEventSignal() { return mEventSignal; }
-
- /// Notify the SFX system that the given description has changed.
- /// All sources currently using the description will be updated.
- void notifyDescriptionChanged( SFXDescription* description);
-
- ///
- void notifyTrackChanged( SFXTrack* track );
- };
- /// Less verbose macro for accessing the SFX singleton. This
- /// should be the prefered method for accessing the system.
- ///
- /// @see SFXSystem
- /// @see SFXSystem::getSingleton()
- ///
- #define SFX SFXSystem::getSingleton()
- #endif // _SFXSYSTEM_H_
|