123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- //-----------------------------------------------------------------------------
- // 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 _SFXCOMMON_H_
- #define _SFXCOMMON_H_
- #ifndef _PLATFORM_H_
- #include "platform/platform.h"
- #endif
- #ifndef _MMATHFN_H_
- #include "math/mMathFn.h"
- #endif
- #ifndef _MRANDOM_H_
- #include "math/mRandom.h"
- #endif
- #ifndef _MMATRIX_H_
- #include "math/mMatrix.h"
- #endif
- #ifndef _MPOINT3_H_
- #include "math/mPoint3.h"
- #endif
- #ifndef _TYPETRAITS_H_
- #include "platform/typetraits.h"
- #endif
- #ifndef _DYNAMIC_CONSOLETYPES_H_
- #include "console/dynamicTypes.h"
- #endif
- class SFXEnvironment;
- class SFXPlayList;
- //-----------------------------------------------------------------------------
- // SFXStatus.
- //-----------------------------------------------------------------------------
- /// The sound playback state.
- enum SFXStatus
- {
- /// Initial state; no operation yet performed on sound.
- SFXStatusNull,
- /// Sound is playing.
- SFXStatusPlaying,
- /// Sound has been stopped.
- SFXStatusStopped,
- /// Sound is paused.
- SFXStatusPaused,
- /// Sound stream is starved and playback blocked.
- SFXStatusBlocked,
- /// Temporary state while transitioning to another state. This is used when multiple
- /// threads concurrently maintain a status and need to perform a sequence of actions before
- /// being able to fully go from a previous to a new current state. In this case, the
- /// transition state marks the status as being under update on another thread.
- ///
- /// @note Not all places that use SFXStatus actually use this state.
- SFXStatusTransition,
- };
- DefineEnumType( SFXStatus );
- inline const char* SFXStatusToString( SFXStatus status )
- {
- switch ( status )
- {
- case SFXStatusPlaying: return "playing";
- case SFXStatusStopped: return "stopped";
- case SFXStatusPaused: return "paused";
- case SFXStatusBlocked: return "blocked";
- case SFXStatusTransition: return "transition";
-
- case SFXStatusNull:
- default: ;
- }
-
- return "null";
- }
- //-----------------------------------------------------------------------------
- // SFXChannel.
- //-----------------------------------------------------------------------------
- /// Animatable channels in the SFX system.
- enum SFXChannel
- {
- SFXChannelVolume,
- SFXChannelPitch,
- SFXChannelPriority,
- SFXChannelPositionX,
- SFXChannelPositionY,
- SFXChannelPositionZ,
- SFXChannelRotationX,
- SFXChannelRotationY,
- SFXChannelRotationZ,
- SFXChannelVelocityX,
- SFXChannelVelocityY,
- SFXChannelVelocityZ,
- SFXChannelMinDistance,
- SFXChannelMaxDistance,
- SFXChannelConeInsideAngle,
- SFXChannelConeOutsideAngle,
- SFXChannelConeOutsideVolume,
- SFXChannelCursor,
- SFXChannelStatus,
- SFXChannelUser0,
- SFXChannelUser1,
- SFXChannelUser2,
- SFXChannelUser3,
-
- /// Total number of animatable channels.
- SFX_NUM_CHANNELS
- };
- DefineEnumType( SFXChannel );
- //-----------------------------------------------------------------------------
- // SFXDistanceModel.
- //-----------------------------------------------------------------------------
- /// Rolloff curve used for distance volume attenuation of 3D sounds.
- enum SFXDistanceModel
- {
- SFXDistanceModelLinear, ///< Volume decreases linearly from min to max where it reaches zero.
- SFXDistanceModelLogarithmic, ///< Volume halves every min distance steps starting from min distance; attenuation stops at max distance.
- SFXDistanceModelExponent, /// exponential falloff for distance attenuation.
- };
- DefineEnumType( SFXDistanceModel );
- /// Compute the distance attenuation based on the given distance model.
- ///
- /// @param minDistance Reference distance; attenuation starts here.
- /// @param maxDistance
- /// @param distance Actual distance of sound from listener.
- /// @param volume Unattenuated volume.
- /// @param rolloffFactor Rolloff curve scale factor.
- ///
- /// @return The attenuated volume.
- inline F32 SFXDistanceAttenuation( SFXDistanceModel model, F32 minDistance, F32 maxDistance, F32 distance, F32 volume, F32 rolloffFactor )
- {
- F32 gain = 1.0f;
-
- switch( model )
- {
- case SFXDistanceModelLinear:
-
- distance = getMax( distance, minDistance );
- distance = getMin( distance, maxDistance );
-
- gain = ( 1 - ( distance - minDistance ) / ( maxDistance - minDistance ) );
- break;
-
- case SFXDistanceModelLogarithmic:
-
- distance = getMax( distance, minDistance );
- distance = getMin( distance, maxDistance );
-
- gain = minDistance / ( minDistance + rolloffFactor * ( distance - minDistance ) );
- break;
- ///create exponential distance model
- case SFXDistanceModelExponent:
- distance = getMax(distance, minDistance);
- distance = getMin(distance, maxDistance);
- gain = pow((distance / minDistance), (-rolloffFactor));
- break;
-
- }
-
- return ( volume * gain );
- }
- //-----------------------------------------------------------------------------
- // SFXFormat.
- //-----------------------------------------------------------------------------
- /// This class defines the various types of sound data that may be
- /// used in the sound system.
- ///
- /// Unlike with most sound APIs, we consider each sample point to comprise
- /// all channels in a sound stream rather than only one value for a single
- /// channel.
- class SFXFormat
- {
- protected:
- /// The number of sound channels in the data.
- U8 mChannels;
- /// The number of bits per sound sample.
- U8 mBitsPerSample;
- /// The frequency in samples per second.
- U32 mSamplesPerSecond;
- public:
- SFXFormat( U8 channels = 0,
- U8 bitsPerSample = 0,
- U32 samplesPerSecond = 0 )
- : mChannels( channels ),
- mBitsPerSample( bitsPerSample ),
- mSamplesPerSecond( samplesPerSecond )
- {}
- /// Copy constructor.
- SFXFormat( const SFXFormat &format )
- : mChannels( format.mChannels ),
- mBitsPerSample( format.mBitsPerSample ),
- mSamplesPerSecond( format.mSamplesPerSecond )
- {}
- public:
- /// Sets the format.
- void set( U8 channels,
- U8 bitsPerSample,
- U32 samplesPerSecond )
- {
- mChannels = channels;
- mBitsPerSample = bitsPerSample;
- mSamplesPerSecond = samplesPerSecond;
- }
- /// Comparision between formats.
- bool operator == ( const SFXFormat& format ) const
- {
- return mChannels == format.mChannels &&
- mBitsPerSample == format.mBitsPerSample &&
- mSamplesPerSecond == format.mSamplesPerSecond;
- }
- /// Returns the number of sound channels.
- U8 getChannels() const { return mChannels; }
- /// Returns true if there is a single sound channel.
- bool isMono() const { return mChannels == 1; }
- /// Is true if there are two sound channels.
- bool isStereo() const { return mChannels == 2; }
- /// Is true if there are more than two sound channels.
- bool isMultiChannel() const { return mChannels > 2; }
- ///
- U32 getSamplesPerSecond() const { return mSamplesPerSecond; }
- /// The bits of data per channel.
- U8 getBitsPerChannel() const { return mBitsPerSample / mChannels; }
- /// The number of bytes of data per channel.
- U8 getBytesPerChannel() const { return getBitsPerChannel() / 8; }
- /// The number of bits per sound sample.
- U8 getBitsPerSample() const { return mBitsPerSample; }
- /// The number of bytes of data per sample.
- /// @note Be aware that this comprises all channels.
- U8 getBytesPerSample() const { return mBitsPerSample / 8; }
- /// Returns the duration from the sample count.
- U32 getDuration( U32 samples ) const
- {
- // Use 64bit types to avoid overflow during division.
- return ( (U64)samples * (U64)1000 ) / (U64)mSamplesPerSecond;
- }
- ///
- U32 getSampleCount( U32 ms ) const
- {
- return U64( mSamplesPerSecond ) * U64( ms ) / U64( 1000 );
- }
- /// Returns the data length in bytes.
- U32 getDataLength( U32 ms ) const
- {
- U32 bytes = ( ( (U64)ms * (U64)mSamplesPerSecond ) * (U64)getBytesPerSample() ) / (U64)1000;
- return bytes;
- }
- };
- //-----------------------------------------------------------------------------
- // SFXReverb.
- //-----------------------------------------------------------------------------
- /// Reverb environment properties.
- ///
- /// @note A given device may not implement all properties.
- ///restructure our reverbproperties to match openal
- class SFXReverbProperties
- {
- public:
- struct Parent;
- float flDensity;
- float flDiffusion;
- float flGain;
- float flGainHF;
- float flGainLF;
- float flDecayTime;
- float flDecayHFRatio;
- float flDecayLFRatio;
- float flReflectionsGain;
- float flReflectionsDelay;
- float flReflectionsPan[3];
- float flLateReverbGain;
- float flLateReverbDelay;
- float flLateReverbPan[3];
- float flEchoTime;
- float flEchoDepth;
- float flModulationTime;
- float flModulationDepth;
- float flAirAbsorptionGainHF;
- float flHFReference;
- float flLFReference;
- float flRoomRolloffFactor;
- int iDecayHFLimit;
- ///set our defaults to be the same as no reverb otherwise our reverb
- ///effects menu sounds
- SFXReverbProperties()
- {
- flDensity = 0.0f;
- flDiffusion = 0.0f;
- flGain = 0.0f;
- flGainHF = 0.0f;
- flGainLF = 0.0000f;
- flDecayTime = 0.0f;
- flDecayHFRatio = 0.0f;
- flDecayLFRatio = 0.0f;
- flReflectionsGain = 0.0f;
- flReflectionsDelay = 0.0f;
- dMemset(flReflectionsPan, 0, sizeof(flReflectionsPan));
- flLateReverbGain = 0.0f;
- flLateReverbDelay = 0.0f;
- dMemset(flLateReverbPan, 0, sizeof(flLateReverbPan));
- flEchoTime = 0.0f;
- flEchoDepth = 0.0f;
- flModulationTime = 0.0f;
- flModulationDepth = 0.0f;
- flAirAbsorptionGainHF = 0.0f;
- flHFReference = 0.0f;
- flLFReference = 0.0f;
- flRoomRolloffFactor = 0.0f;
- iDecayHFLimit = 0;
- }
- void validate()
- {
- flDensity = mClampF(flDensity, 0.0f, 1.0f);
- flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
- flGain = mClampF(flGain, 0.0f, 1.0f);
- flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
- flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
- flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
- flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
- flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
- flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
- flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
- flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
- flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
- flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
- flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
- flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
- flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
- flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
- flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
- flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
- flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
- flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
- flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
- flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
- flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
- flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
- flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
- iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
- }
- };
- //-----------------------------------------------------------------------------
- // SFXSoundReverbProperties.
- //-----------------------------------------------------------------------------
- /// Sound reverb properties.
- ///
- /// @note A given SFX device may not implement all properties.
- ///not in use by openal yet if u are going to use ambient reverb zones its
- ///probably best to not have reverb on the sound effect itself.
- class SFXSoundReverbProperties
- {
- public:
- typedef void Parent;
- float flDensity;
- float flDiffusion;
- float flGain;
- float flGainHF;
- float flGainLF;
- float flDecayTime;
- float flDecayHFRatio;
- float flDecayLFRatio;
- float flReflectionsGain;
- float flReflectionsDelay;
- float flReflectionsPan[3];
- float flLateReverbGain;
- float flLateReverbDelay;
- float flLateReverbPan[3];
- float flEchoTime;
- float flEchoDepth;
- float flModulationTime;
- float flModulationDepth;
- float flAirAbsorptionGainHF;
- float flHFReference;
- float flLFReference;
- float flRoomRolloffFactor;
- int iDecayHFLimit;
- ///Set our defaults to have no reverb
- ///if you are going to use zone reverbs its
- ///probably best not to use per-voice reverb
- SFXSoundReverbProperties()
- {
- flDensity = 0.0f;
- flDiffusion = 0.0f;
- flGain = 0.0f;
- flGainHF = 0.0f;
- flGainLF = 0.0000f;
- flDecayTime = 0.0f;
- flDecayHFRatio = 0.0f;
- flDecayLFRatio = 0.0f;
- flReflectionsGain = 0.0f;
- flReflectionsDelay = 0.0f;
- dMemset(flReflectionsPan, 0, sizeof(flReflectionsPan));
- flLateReverbGain = 0.0f;
- flLateReverbDelay = 0.0f;
- dMemset(flLateReverbPan, 0, sizeof(flLateReverbPan));
- flEchoTime = 0.0f;
- flEchoDepth = 0.0f;
- flModulationTime = 0.0f;
- flModulationDepth = 0.0f;
- flAirAbsorptionGainHF = 0.0f;
- flHFReference = 0.0f;
- flLFReference = 0.0f;
- flRoomRolloffFactor = 0.0f;
- iDecayHFLimit = 0;
- }
- void validate()
- {
- flDensity = mClampF(flDensity, 0.0f, 1.0f);
- flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
- flGain = mClampF(flGain, 0.0f, 1.0f);
- flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
- flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
- flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
- flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
- flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
- flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
- flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
- flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
- flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
- flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
- flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
- flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
- flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
- flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
- flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
- flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
- flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
- flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
- flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
- flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
- flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
- flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
- flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
- iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
- }
- };
- //-----------------------------------------------------------------------------
- // SFXListenerProperties.
- //-----------------------------------------------------------------------------
- ///
- class SFXListenerProperties
- {
- public:
-
- typedef void Parent;
-
- /// Position and orientation of the listener.
- MatrixF mTransform;
-
- ///
- Point3F mVelocity;
- SFXListenerProperties()
- : mTransform( true ),
- mVelocity( 0.0f, 0.0f, 0.0f ) {}
-
- SFXListenerProperties( const MatrixF& transform, const Point3F& velocity )
- : mTransform( transform ),
- mVelocity( velocity ) {}
-
- ///
- const MatrixF& getTransform() const { return mTransform; }
- MatrixF& getTransform() { return mTransform; }
-
- ///
- const Point3F& getVelocity() const { return mVelocity; }
- Point3F& getVelocity() { return mVelocity; }
- };
- //-----------------------------------------------------------------------------
- // SFXMaterialProperties.
- //-----------------------------------------------------------------------------
- ///
- class SFXMaterialProperties
- {
- public:
-
- typedef void Parent;
-
- ///
- bool mDoubleSided;
-
- ///
- F32 mDirectOcclusion;
-
- ///
- F32 mReverbOcclusion;
-
- SFXMaterialProperties()
- : mDoubleSided( false ),
- mDirectOcclusion( 0.5f ),
- mReverbOcclusion( 0.5f ) {}
-
- void validate()
- {
- mDirectOcclusion = mClampF( mDirectOcclusion, 0.0f, 1.0f );
- mReverbOcclusion = mClampF( mReverbOcclusion, 0.0f, 1.0f );
- }
- };
- //-----------------------------------------------------------------------------
- // SFXVariantFloat.
- //-----------------------------------------------------------------------------
- /// An array of float values with optional random variances.
- template< S32 NUM_VALUES >
- struct SFXVariantFloat
- {
- /// Base value.
- F32 mValue[ NUM_VALUES ];
-
- /// Variance of value. Final value will be
- ///
- /// mClampF( randF( mValue + mVariance[ 0 ], mValue + mVariance[ 1 ] ), min, max )
- ///
- /// with min and max being dependent on the context of the value.
- F32 mVariance[ NUM_VALUES ][ 2 ];
-
- F32 getValue( U32 index = 0, F32 min = TypeTraits< F32 >::MIN, F32 max = TypeTraits< F32 >::MAX ) const
- {
- AssertFatal( index < NUM_VALUES, "SFXVariantFloat::getValue() - index out of range!" );
-
- return mClampF( gRandGen.randF( mValue[ index ] + mVariance[ index ][ 0 ],
- mValue[ index ] + mVariance[ index ][ 1 ] ),
- min, max );
- }
-
- void validate()
- {
- for( U32 i = 0; i < NUM_VALUES; ++ i )
- mVariance[ i ][ 0 ] = getMin( mVariance[ i ][ 0 ], mVariance[ i ][ 1 ] );
- }
- };
- #endif // _SFXCOMMON_H_
|