// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // 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 <http://www.gnu.org/licenses/>. #include "std_afx.h" #include "resource.h" #include "sound_system.h" #include "nel/sound/u_audio_mixer.h" #include "nel/sound/u_listener.h" #include "nel/sound/sound_anim_manager.h" #include "nel/sound/sound_animation.h" #include "nel/misc/path.h" #include "edit_ps_sound.h" using namespace std; using namespace NLMISC; using namespace NLSOUND; UAudioMixer *CSoundSystem::_AudioMixer = NULL; //set<string> CSoundSystem::_SoundBanksFileName; set<string> CSoundSystem::_SampleBanksFileName; CSoundAnimManager *CSoundSystem::_AnimManager = NULL; //TSoundAnimId CSoundSystem::_CurrentAnimation = CSoundAnimation::NoId; //sint32 CSoundSystem::_CurrentPlayback = -1; CVector CSoundSystem::_Zero = CVector::Null; string CSoundSystem::_SamplePath; string CSoundSystem::_PackedSheetPath; //sint CSoundSystem::_AnimIndex = -1; void CSoundSystem::setListenerMatrix(const NLMISC::CMatrix &m) { if (_AudioMixer) { static CMatrix oldMatrix; if(m.getPos() != oldMatrix.getPos() || m.getJ() != oldMatrix.getJ() || m.getK() != oldMatrix.getK()) { UListener *l = _AudioMixer->getListener(); l->setPos(m.getPos()); l->setOrientation(m.getJ(), m.getK()); oldMatrix = m; } } } void CSoundSystem::initSoundSystem () { _AudioMixer = NULL; _AnimManager = NULL; _AudioMixer = NLSOUND::UAudioMixer::createAudioMixer(); try { _AudioMixer->setSamplePath(_SamplePath); _AudioMixer->setPackedSheetOption(_PackedSheetPath, true); _AudioMixer->init(32, true, false, NULL, true); } catch(NLMISC::Exception &e) { // in case of exeption during mixer init, the mixer is destroyed ! string mess = string("Unable to init sound :") + e.what(); nlwarning ("Init sound: %s", mess.c_str()); _AudioMixer = NULL; return; } // ok for the mixer, now create the sound anim manager try { // TODO : boris : Hum, as far as I know, throwing exeption in constructor is a very BAD idea... _AnimManager = new CSoundAnimManager(_AudioMixer); } catch (NLMISC::Exception &e) { string mess = string("Unable to init sound :") + e.what(); nlwarning ("Init sound: %s", mess.c_str()); if (_AnimManager) { delete _AnimManager; _AnimManager = NULL; } delete _AudioMixer; _AudioMixer = NULL; return; } setPSSoundSystem(_AudioMixer); /* for (set<string>::const_iterator it1 = _SampleBanksFileName.begin(); it1 != _SampleBanksFileName.end(); ++it1) { try { //_AudioMixer->loadSampleBank(NLMISC::CPath::lookup(*it).c_str()); _AudioMixer->loadSampleBank(false, (*it1)); } catch (NLMISC::Exception &e) { string mess = "Unable to load sound file :" + *it1 + "\n" + e.what(); nlwarning ("Init sound: %s", mess.c_str()); } } */ /* for (set<string>::const_iterator it2 = _SoundBanksFileName.begin(); it2 != _SoundBanksFileName.end(); ++it2) { try { //_AudioMixer->loadSoundBank(NLMISC::CPath::lookup(*it).c_str()); _AudioMixer->loadSoundBank((*it2).c_str()); } catch (NLMISC::Exception &e) { string mess = "Unable to load sound file :" + *it2 + "\n" + e.what(); nlwarning ("Init sound: %s", mess.c_str()); } } */ } void CSoundSystem::poll() { if (_AudioMixer) { _AudioMixer->update(); } } void CSoundSystem::releaseSoundSystem(void) { setPSSoundSystem(NULL); if (_AnimManager) { delete _AnimManager; _AnimManager = NULL; } if (_AudioMixer) { delete _AudioMixer; _AudioMixer = NULL; } } void CSoundSystem::play(const string &soundName) { if (_AudioMixer) { NLSOUND::USource *src = _AudioMixer->createSource(CStringMapper::map(soundName), true); if (src) { src->setLooping(false); const CVector &pos = _AudioMixer->getListener()->getPos(); src->setPos(pos); src->play(); } else { MessageBox(NULL, "Can't play the sound (perhaps it's contextual sound)", "warning", MB_OK|MB_ICONWARNING ); } } } USource *CSoundSystem::create(const std::string &soundName) { if (_AudioMixer) { NLSOUND::USource *src = _AudioMixer->createSource(CStringMapper::map(soundName), false); if (src) { src->setLooping(false); const CVector &pos = _AudioMixer->getListener()->getPos(); src->setPos(pos); src->play(); return src; } else { MessageBox(NULL, "Can't play the sound (perhaps it's contextual sound)", "warning", MB_OK|MB_ICONWARNING ); } return NULL; } return NULL; } void CSoundSystem::playAnimation(string& name, float lastTime, float curTime, CSoundContext &context) { if (_AnimManager == NULL) { return; } TSoundAnimId id = _AnimManager->getAnimationFromName(name); if (id != CSoundAnimationNoId) { _AnimManager->playAnimation(id, lastTime, curTime, NULL, context); } }