// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdsound.h" #include "nel/sound/sound.h" #include "nel/misc/path.h" #include "nel/sound/sound_bank.h" #include "nel/sound/simple_sound.h" #include "nel/sound/complex_sound.h" #include "nel/sound/background_sound.h" #include "nel/sound/context_sound.h" #include "nel/sound/music_sound.h" #include "nel/sound/stream_sound.h" #include "nel/sound/stream_file_sound.h" #include "nel/sound/group_controller.h" #include "nel/sound/group_controller_root.h" using namespace std; using namespace NLMISC; namespace NLSOUND { CSound *CSound::createSound(const std::string &filename, NLGEORGES::UFormElm& formRoot) { CSound *ret = NULL; string soundType; NLGEORGES::UFormElm *psoundType; if (!formRoot.getNodeByName(&psoundType, ".SoundType")) { nlwarning("No SoundType in : %s", filename.c_str()); return 0; } if (psoundType != NULL) { std::string dfnName; psoundType->getDfnName(dfnName); if (dfnName == "simple_sound.dfn") { ret = new CSimpleSound(); ret->importForm(filename, formRoot); } else if (dfnName == "complex_sound.dfn") { ret = new CComplexSound(); ret->importForm(filename, formRoot); } else if (dfnName == "background_sound.dfn") { ret = new CBackgroundSound(); ret->importForm(filename, formRoot); } else if (dfnName == "context_sound.dfn") { ret = new CContextSound(); ret->importForm(filename, formRoot); } else if (dfnName == "music_sound.dfn") { ret = new CMusicSound(); ret->importForm(filename, formRoot); } else if (dfnName == "stream_sound.dfn") { ret = new CStreamSound(); ret->importForm(filename, formRoot); } else if (dfnName == "stream_file_sound.dfn") { ret = new CStreamFileSound(); ret->importForm(filename, formRoot); } else { nlassertex(false, ("SoundType unsuported : %s", dfnName.c_str())); } } return ret; } /* * Constructor */ CSound::CSound() : _Gain(1.0f), _Pitch(1.0f), _Priority(MidPri), _ConeInnerAngle(6.283185f), _ConeOuterAngle(6.283185f), _ConeOuterGain( 1.0f ), _Looping(false), _MinDist(1.0f), _MaxDist(1000000.0f), _UserVarControler(CStringMapper::emptyId()), _GroupController(NULL) { } CSound::~CSound() {} void CSound::serial(NLMISC::IStream &s) { s.serial(_Gain); s.serial(_Pitch); s.serialEnum(_Priority); s.serial(_ConeInnerAngle, _ConeOuterAngle, _ConeOuterGain); s.serial(_Direction); s.serial(_Looping); s.serial(_MaxDist); _Name.serialString(s, "sound"); nlassert(CGroupControllerRoot::isInitialized()); // not sure #if NLSOUND_SHEET_VERSION_BUILT < 2 if (s.isReading()) _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER); #else if (s.isReading()) { std::string groupControllerPath; s.serial(groupControllerPath); _GroupController = CGroupControllerRoot::getInstance()->getGroupController(groupControllerPath); } else { std::string groupControllerPath = _GroupController->getPath(); s.serial(groupControllerPath); } #endif } /** * Load the sound parameters from georges' form */ void CSound::importForm(const std::string& filename, NLGEORGES::UFormElm& root) { // Name nlassert(filename.find(".sound") != std::string::npos); _Name = NLMISC::CSheetId(filename); // InternalConeAngle uint32 inner; root.getValueByName(inner, ".InternalConeAngle"); if (inner > 360) { inner = 360; } _ConeInnerAngle = (float) (Pi * inner / 180.0f); // convert to radians // ExternalConeAngle uint32 outer; root.getValueByName(outer, ".ExternalConeAngle"); if (outer > 360) { outer = 360; } _ConeOuterAngle= (float) (Pi * outer / 180.0f); // convert to radians // Loop root.getValueByName(_Looping, ".Loop"); // Gain sint32 gain; root.getValueByName(gain, ".Gain"); if (gain > 0) { gain = 0; } if (gain < -100) { gain = -100; } _Gain = (float) pow(10.0, gain / 20.0); // convert dB to linear gain // External gain root.getValueByName(gain, ".ExternalGain"); if (gain > 0) { gain = 0; } if (gain < -100) { gain = -100; } _ConeOuterGain = (float) pow(10.0, gain / 20.0); // convert dB to linear gain // Direction float x, y, z; root.getValueByName(x, ".Direction.X"); root.getValueByName(y, ".Direction.Y"); root.getValueByName(z, ".Direction.Z"); _Direction = CVector(x, y, z); // Pitch sint32 trans; root.getValueByName(trans, ".Transpose"); _Pitch = (float) pow(Sqrt12_2, trans); // convert semi-tones to playback speed // Priority uint32 prio = 0; root.getValueByName(prio, ".Priority"); switch (prio) { case 0: _Priority = LowPri; break; case 1: _Priority = MidPri; break; case 2: _Priority = HighPri; break; case 3: _Priority = HighestPri; break; default: _Priority = MidPri; } nlassert(CGroupControllerRoot::isInitialized()); // not sure #if NLSOUND_SHEET_VERSION_BUILT < 2 _GroupController = CGroupControllerRoot::getInstance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER); #else std::string groupControllerPath; root.getValueByName(groupControllerPath, ".GroupControllerPath"); _GroupController = CGroupControllerRoot::getInstance()->getGroupController(groupControllerPath); #endif } } // NLSOUND