afxEA_Sound.cpp
Engine/source/afx/ea/afxEA_Sound.cpp
Classes:
class
class
Detailed Description
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27#include <typeinfo> 28#include "afx/arcaneFX.h" 29 30#include "sfx/sfxSystem.h" 31#include "sfx/sfxSource.h" 32#include "sfx/sfxProfile.h" 33 34#include "afx/afxEffectDefs.h" 35#include "afx/afxEffectWrapper.h" 36#include "afx/afxChoreographer.h" 37 38//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 39// afxEA_Sound 40 41class afxEA_Sound : public afxEffectWrapper 42{ 43 typedef afxEffectWrapper Parent; 44 45 SFXProfile* sound_prof; 46 SFXDescription* sound_desc; 47 SFXSource* sound_handle; 48 49 void do_runtime_substitutions(); 50 51public: 52 /*C*/ afxEA_Sound(); 53 /*D*/ ~afxEA_Sound(); 54 55 virtual void ea_set_datablock(SimDataBlock*); 56 virtual bool ea_start(); 57 virtual bool ea_update(F32 dt); 58 virtual void ea_finish(bool was_stopped); 59 60 virtual bool ea_is_enabled() { return true; } 61 62 virtual void onDeleteNotify(SimObject*); 63}; 64 65//~~~~~~~~~~~~~~~~~~~~// 66 67afxEA_Sound::afxEA_Sound() 68{ 69 sound_prof = 0; 70 sound_desc = 0; 71 sound_handle = 0; 72} 73 74afxEA_Sound::~afxEA_Sound() 75{ 76 if (sound_prof && sound_prof->isTempClone()) 77 delete sound_prof; 78 sound_prof = 0; 79 sound_desc = 0; 80 sound_handle = 0; 81} 82 83void afxEA_Sound::ea_set_datablock(SimDataBlock* db) 84{ 85 sound_prof = dynamic_cast<SFXProfile*>(db); 86 if (sound_prof) 87 sound_desc = sound_prof->getDescription(); 88} 89 90bool afxEA_Sound::ea_start() 91{ 92 if (!sound_prof) 93 { 94 Con::errorf("afxEA_Sound::ea_start() -- missing or incompatible AudioProfile."); 95 return false; 96 } 97 if (!sound_desc) 98 { 99 Con::errorf("afxEA_Sound::ea_start() -- missing or incompatible AudioDescriptor."); 100 return false; 101 } 102 103 do_runtime_substitutions(); 104 105 return true; 106} 107 108bool afxEA_Sound::ea_update(F32 dt) 109{ 110 if (!sound_handle) 111 { 112 sound_handle = SFX->createSource(sound_prof, &mUpdated_xfm, 0); 113 if (sound_handle) 114 sound_handle->play(); 115 } 116 117 if (sound_handle) 118 { 119 sound_handle->setTransform(mUpdated_xfm); 120 sound_handle->setVolume((mIn_scope) ? mUpdated_scale.x*mFade_value : 0.0f); 121 deleteNotify(sound_handle); 122 } 123 124 return true; 125} 126 127void afxEA_Sound::ea_finish(bool was_stopped) 128{ 129 if (sound_handle) 130 { 131 sound_handle->stop(); 132 SFX_DELETE(sound_handle); 133 } 134} 135 136void afxEA_Sound::do_runtime_substitutions() 137{ 138 sound_prof = sound_prof->cloneAndPerformSubstitutions(mChoreographer, mGroup_index); 139 sound_desc = sound_prof->getDescription(); 140} 141 142void afxEA_Sound::onDeleteNotify(SimObject* obj) 143{ 144 if (sound_handle == dynamic_cast<SFXSource*>(obj)) 145 sound_handle = 0; 146 147 Parent::onDeleteNotify(obj); 148} 149 150//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 151 152class afxEA_SoundDesc : public afxEffectAdapterDesc, public afxEffectDefs 153{ 154 static afxEA_SoundDesc mDesc; 155 156public: 157 virtual bool testEffectType(const SimDataBlock*) const; 158 virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const; 159 virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; } 160 virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; } 161 virtual void prepEffect(afxEffectWrapperData*) const; 162 163 virtual afxEffectWrapper* create() const { return new afxEA_Sound; } 164}; 165 166afxEA_SoundDesc afxEA_SoundDesc::mDesc; 167 168bool afxEA_SoundDesc::testEffectType(const SimDataBlock* db) const 169{ 170 // dynamic cast used here so that both SFXProfile and AudioProfile match 171 return (dynamic_cast<const SFXProfile*>(db) != 0); 172} 173 174bool afxEA_SoundDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const 175{ 176 SFXDescription* desc = ((SFXProfile*)ew->effect_data)->getDescription(); 177 return (desc && desc->mIsLooping) ? (timing.lifetime < 0) : false; 178} 179 180void afxEA_SoundDesc::prepEffect(afxEffectWrapperData* ew) const 181{ 182 if (ew->ewd_timing.lifetime < 0) 183 { 184 SFXProfile* snd = (SFXProfile*) ew->effect_data; 185 SFXDescription* desc = snd->getDescription(); 186 if (desc && !desc->mIsLooping) 187 { 188 static bool test_for_audio = true; 189 static bool can_get_audio_len = false; 190 191 if (test_for_audio) 192 { 193 can_get_audio_len = true; 194 test_for_audio = false; 195 } 196 197 if (can_get_audio_len) 198 { 199 SFXResource* sfx_rsrc = snd->getResource(); 200 if (sfx_rsrc) 201 { 202 ew->ewd_timing.lifetime = 0.001f*sfx_rsrc->getDuration(); 203 //Con::printf("SFX (%s) duration=%g", snd->mFilename, timing.lifetime); 204 } 205 } 206 else 207 { 208 ew->ewd_timing.lifetime = 0; 209 Con::printf("afxEA_SoundDesc::prepEffect() -- cannot get audio length from sound file."); 210 } 211 } 212 } 213} 214 215//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 216