//----------------------------------------------------------------------------- // 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. //----------------------------------------------------------------------------- #include "sfx/sfxEnvironment.h" #include "sim/netConnection.h" #include "core/stream/bitStream.h" #include "core/module.h" IMPLEMENT_CO_DATABLOCK_V1( SFXEnvironment ); // Reverb flags. static const U32 sReverbFlagDecayTimeScale = 0x001; static const U32 sReverbFlagReflectionsScale = 0x002; static const U32 sReverbFlagReflectionsDelayScale = 0x004; static const U32 sReverbFlagReverbScale = 0x008; static const U32 sReverbFlagReverbDelayScale = 0x010; static const U32 sReverbFlagDecayHFLimit = 0x020; static const U32 sReverbFlagEchoTimeScale = 0x040; static const U32 sReverbFlagModulationTimeScale = 0x080; static const U32 sReverbFlagCore0 = 0x100; static const U32 sReverbFlagCore1 = 0x200; static const U32 sReverbFlagHighQualityReverb = 0x400; static const U32 sReverbFlagHighQualityDPL2Reverb = 0x800; AFTER_MODULE_INIT( SFX ) { Con::addConstant( "SFXEnvironment::REVERB_DECAYTIMESCALE", TypeS32, &sReverbFlagDecayTimeScale, "SFXEnvironment::envSize affects reverberation decay time.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_REFLECTIONSSCALE", TypeS32, &sReverbFlagReflectionsScale, "SFXEnvironment::envSize affects reflection level.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_REFLECTIONSDELAYSCALE", TypeS32, &sReverbFlagReflectionsScale, "SFXEnvironment::envSize affects initial reflection delay time.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_REVERBSCALE", TypeS32, &sReverbFlagReverbScale, "SFXEnvironment::envSize affects reflections level.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_REVERBDELAYSCALE", TypeS32, &sReverbFlagReverbDelayScale, "SFXEnvironment::envSize affects late reverberation delay time.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_DECAYHFLIMIT", TypeS32, &sReverbFlagDecayHFLimit, "SFXEnvironment::airAbsorptionHF affects SFXEnvironment::decayHFRatio.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_ECHOTIMESCALE", TypeS32, &sReverbFlagEchoTimeScale, "SFXEnvironment::envSize affects echo time.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_MODULATIONTIMESCALE", TypeS32, &sReverbFlagModulationTimeScale, "SFXEnvironment::envSize affects modulation time.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_CORE0", TypeS32, &sReverbFlagCore0, "PS2 Only - Reverb is applied to CORE0 (hw voices 0-23).\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_CORE1", TypeS32, &sReverbFlagCore1, "PS2 Only - Reverb is applied to CORE1 (hw voices 24-47).\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_HIGHQUALITYREVERB", TypeS32, &sReverbFlagHighQualityReverb, "GameCube/Wii Only - Use high-quality reverb.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); Con::addConstant( "SFXEnvironment::REVERB_HIGHQUALITYDPL2REVERB", TypeS32, &sReverbFlagHighQualityDPL2Reverb, "GameCube/Wii Only - Use high-quality DPL2 reverb.\n" "@see SFXEnvironment::flags\n\n" "@ingroup SFXEnvironment" ); } ConsoleDocClass( SFXEnvironment, "@brief Description of a reverb environment.\n\n" "A reverb environment specifies how the audio mixer should render advanced environmental audio " "effects. \n\n" "To use reverb environments in your level, set up one or more ambient audio spaces, assign " "reverb environments appropriately, and then attach the SFXAmbiences to your LevelInfo (taking effect " "globally) or Zone objects (taking effect locally).\n\n" "To define your own custom reverb environments, it is usually easiest to adapt one of the pre-existing " "reverb definitions:\n" "@tsexample_nopar\n" "singleton SFXEnvironment( AudioEnvCustomUnderwater : AudioEnvUnderwater )\n" "{\n" " // Override select properties from AudioEnvUnderwater here.\n" "};\n" "@endtsexample\n\n" "In the Datablock Editor, this can be done by selecting an existing environment to copy from when creating " "the SFXEnvironment datablock.\n\n" "For a precise description of reverb audio and the properties of this class, please consult the EAX " "documentation.\n\n" "All SFXEnvironment instances are automatically added to the global @c SFXEnvironmentSet.\n\n" "@see http://www.atc.creative.com/algorithms/eax20.pdf\n" "@see http://connect.creativelabs.com/developer/Gaming/Forms/AllItems.aspx\n" "@see SFXAmbience::environment\n\n" "@ref SFX_reverb\n" "@ingroup SFX\n" ); //----------------------------------------------------------------------------- SFXEnvironment::SFXEnvironment() { } //----------------------------------------------------------------------------- void SFXEnvironment::initPersistFields() { addGroup( "Reverb" ); addField( "envSize", TypeF32, Offset( mReverb.mEnvSize, SFXEnvironment ), "Environment size in meters." ); addField( "envDiffusion", TypeF32, Offset( mReverb.mEnvDiffusion, SFXEnvironment ), "Environment diffusion." ); addField( "room", TypeS32, Offset( mReverb.mRoom, SFXEnvironment ), "Room effect level at mid-frequencies." ); addField( "roomHF", TypeS32, Offset( mReverb.mRoomHF, SFXEnvironment ), "Relative room effect level at high frequencies." ); addField( "roomLF", TypeS32, Offset( mReverb.mRoomLF, SFXEnvironment ), "Relative room effect level at low frequencies." ); addField( "decayTime", TypeF32, Offset( mReverb.mDecayTime, SFXEnvironment ), "Reverberation decay time at mid frequencies." ); addField( "decayHFRatio", TypeF32, Offset( mReverb.mDecayHFRatio, SFXEnvironment ), "High-frequency to mid-frequency decay time ratio." ); addField( "decayLFRatio", TypeF32, Offset( mReverb.mDecayLFRatio, SFXEnvironment ), "Low-frequency to mid-frequency decay time ratio." ); addField( "reflections", TypeS32, Offset( mReverb.mReflections, SFXEnvironment ), "Early reflections level relative to room effect." ); addField( "reflectionsDelay", TypeF32, Offset( mReverb.mReflectionsDelay, SFXEnvironment ), "Initial reflection delay time." ); addField( "reflectionsPan", TypeF32, Offset( mReverb.mReflectionsPan, SFXEnvironment ), 3, "Early reflections panning vector." ); addField( "reverb", TypeS32, Offset( mReverb.mReverb, SFXEnvironment ), "Late reverberation level relative to room effect." ); addField( "reverbDelay", TypeF32, Offset( mReverb.mReverbDelay, SFXEnvironment ), "Late reverberation delay time relative to initial reflection." ); addField( "reverbPan", TypeF32, Offset( mReverb.mReverbPan, SFXEnvironment ), 3, "Late reverberation panning vector." ); addField( "echoTime", TypeF32, Offset( mReverb.mEchoTime, SFXEnvironment ), "Echo time." ); addField( "echoDepth", TypeF32, Offset( mReverb.mEchoDepth, SFXEnvironment ), "Echo depth." ); addField( "modulationTime", TypeF32, Offset( mReverb.mModulationTime, SFXEnvironment ), "Modulation time." ); addField( "modulationDepth", TypeF32, Offset( mReverb.mModulationDepth, SFXEnvironment ), "Modulation depth." ); addField( "airAbsorptionHF", TypeF32, Offset( mReverb.mAirAbsorptionHF, SFXEnvironment ), "Change in level per meter at high frequencies." ); addField( "HFReference", TypeF32, Offset( mReverb.mHFReference, SFXEnvironment ), "Reference high frequency in Hertz." ); addField( "LFReference", TypeF32, Offset( mReverb.mLFReference, SFXEnvironment ), "Reference low frequency in Hertz." ); addField( "roomRolloffFactor", TypeF32, Offset( mReverb.mRoomRolloffFactor, SFXEnvironment ), "Logarithmic distance attenuation rolloff scale factor for reverb room size effect." ); addField( "diffusion", TypeF32, Offset( mReverb.mDiffusion, SFXEnvironment ), "Value that controls the echo density in the late reverberation decay." ); addField( "density", TypeF32, Offset( mReverb.mDensity, SFXEnvironment ), "Value that controls the modal density in the late reverberation decay." ); addField( "flags", TypeS32, Offset( mReverb.mFlags, SFXEnvironment ), "A bitfield of reverb flags.\n" "@see REVERB_DECAYTIMESCALE\n" "@see REVERB_REFLECTIONSSCALE\n" "@see REVERB_REFLECTIONSDELAYSCALE\n" "@see REVERB_REVERBSCALE\n" "@see REVERB_REVERBDELAYSCALE\n" "@see REVERB_DECAYHFLIMIT\n" "@see REVERB_ECHOTIMESCALE\n" "@see REVERB_MODULATIONTIMESCALE\n" "@see REVERB_CORE0\n" "@see REVERB_CORE1\n" "@see REVERB_HIGHQUALITYREVERB\n" "@see REVERB_HIGHQUALITYDPL2REVERB\n" ); endGroup( "Reverb" ); Parent::initPersistFields(); } //----------------------------------------------------------------------------- bool SFXEnvironment::onAdd() { if( !Parent::onAdd() ) return false; Sim::getSFXEnvironmentSet()->addObject( this ); return true; } //----------------------------------------------------------------------------- bool SFXEnvironment::preload( bool server, String& errorStr ) { if( !Parent::preload( server, errorStr ) ) return false; validate(); return true; } //----------------------------------------------------------------------------- void SFXEnvironment::inspectPostApply() { Parent::inspectPostApply(); validate(); } //----------------------------------------------------------------------------- void SFXEnvironment::validate() { mReverb.validate(); } //----------------------------------------------------------------------------- void SFXEnvironment::packData( BitStream* stream ) { Parent::packData( stream ); stream->write( mReverb.mEnvSize ); stream->write( mReverb.mEnvDiffusion ); stream->write( mReverb.mRoom ); stream->write( mReverb.mRoomHF ); stream->write( mReverb.mRoomLF ); stream->write( mReverb.mDecayTime ); stream->write( mReverb.mDecayHFRatio ); stream->write( mReverb.mDecayLFRatio ); stream->write( mReverb.mReflections ); stream->write( mReverb.mReflectionsDelay ); stream->write( mReverb.mReflectionsPan[ 0 ] ); stream->write( mReverb.mReflectionsPan[ 1 ] ); stream->write( mReverb.mReflectionsPan[ 2 ] ); stream->write( mReverb.mReverb ); stream->write( mReverb.mReverbDelay ); stream->write( mReverb.mReverbPan[ 0 ] ); stream->write( mReverb.mReverbPan[ 1 ] ); stream->write( mReverb.mReverbPan[ 2 ] ); stream->write( mReverb.mEchoTime ); stream->write( mReverb.mEchoDepth ); stream->write( mReverb.mModulationTime ); stream->write( mReverb.mModulationDepth ); stream->write( mReverb.mAirAbsorptionHF ); stream->write( mReverb.mHFReference ); stream->write( mReverb.mLFReference ); stream->write( mReverb.mRoomRolloffFactor ); stream->write( mReverb.mDiffusion ); stream->write( mReverb.mDensity ); stream->write( mReverb.mFlags ); } //----------------------------------------------------------------------------- void SFXEnvironment::unpackData( BitStream* stream ) { Parent::unpackData( stream ); stream->read( &mReverb.mEnvSize ); stream->read( &mReverb.mEnvDiffusion ); stream->read( &mReverb.mRoom ); stream->read( &mReverb.mRoomHF ); stream->read( &mReverb.mRoomLF ); stream->read( &mReverb.mDecayTime ); stream->read( &mReverb.mDecayHFRatio ); stream->read( &mReverb.mDecayLFRatio ); stream->read( &mReverb.mReflections ); stream->read( &mReverb.mReflectionsDelay ); stream->read( &mReverb.mReflectionsPan[ 0 ] ); stream->read( &mReverb.mReflectionsPan[ 1 ] ); stream->read( &mReverb.mReflectionsPan[ 2 ] ); stream->read( &mReverb.mReverb ); stream->read( &mReverb.mReverbDelay ); stream->read( &mReverb.mReverbPan[ 0 ] ); stream->read( &mReverb.mReverbPan[ 1 ] ); stream->read( &mReverb.mReverbPan[ 2 ] ); stream->read( &mReverb.mEchoTime ); stream->read( &mReverb.mEchoDepth ); stream->read( &mReverb.mModulationTime ); stream->read( &mReverb.mModulationDepth ); stream->read( &mReverb.mAirAbsorptionHF ); stream->read( &mReverb.mHFReference ); stream->read( &mReverb.mLFReference ); stream->read( &mReverb.mRoomRolloffFactor ); stream->read( &mReverb.mDiffusion ); stream->read( &mReverb.mDensity ); stream->read( &mReverb.mFlags ); }