00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdsound.h"
00027
00028 #include "sound_bank.h"
00029 #include "simple_sound.h"
00030 #include "complex_sound.h"
00031 #include "context_sound.h"
00032 #include "background_sound.h"
00033
00034 #include "nel/georges/u_form_loader.h"
00035 #include "nel/georges/u_form_elm.h"
00036 #include "nel/georges/u_form.h"
00037 #include "nel/misc/path.h"
00038 #include "driver/buffer.h"
00039
00040 #include "nel/georges/load_form.h"
00041
00042 using namespace std;
00043 using namespace NLMISC;
00044 using namespace NLGEORGES;
00045
00046
00047 namespace NLSOUND {
00048
00049 CSoundBank *CSoundBank::_Instance;
00050
00051
00052
00053 CSoundBank *CSoundBank::instance()
00054 {
00055 if (_Instance == 0)
00056 _Instance = new CSoundBank();
00057 return _Instance;
00058 }
00059
00060 void CSoundBank::release()
00061 {
00062 if (_Instance != 0)
00063 delete _Instance;
00064 _Instance = 0;
00065 }
00066
00067
00068 void CSoundBank::bufferUnloaded(const std::string bufferName)
00069 {
00070 TBufferAssocContainer::iterator it(_BufferAssoc.find(bufferName));
00071
00072 if (it != _BufferAssoc.end())
00073 {
00074
00075
00076 TSimpleSoundContainer::iterator first(it->second.begin()), last(it->second.end());
00077 for (; first != last; ++first)
00078 {
00079
00080 CSimpleSound *ss = const_cast<CSimpleSound*>(*(first));
00081 ss->setBuffer(NULL);
00082 }
00083 }
00084 }
00085
00086 void CSoundBank::bufferLoaded(const std::string bufferName, IBuffer *buffer)
00087 {
00088
00089 TBufferAssocContainer::iterator it(_BufferAssoc.find(buffer->getName()));
00090
00091 if (it != _BufferAssoc.end())
00092 {
00093
00094
00095 TSimpleSoundContainer::iterator first(it->second.begin()), last(it->second.end());
00096 for (; first != last; ++first)
00097 {
00098 CSimpleSound *ss = const_cast<CSimpleSound*>(*(it->second.begin()));
00099
00100 ss->setBuffer(buffer);
00101 }
00102 }
00103
00104 }
00105
00106 void CSoundBank::registerBufferAssoc(CSimpleSound *sound, IBuffer *buffer)
00107 {
00108 if (buffer != NULL)
00109 {
00110 const std::string &bufferName = buffer->getName();
00111 _BufferAssoc[bufferName].insert(sound);
00112 }
00113 }
00114
00115 void CSoundBank::unregisterBufferAssoc(CSimpleSound *sound, IBuffer * buffer)
00116 {
00117 if (buffer != NULL)
00118 {
00119 const std::string &bufferName = buffer->getName();
00120 TBufferAssocContainer::iterator it(_BufferAssoc.find(bufferName));
00121
00122 if (it != _BufferAssoc.end())
00123 {
00124 TSimpleSoundContainer::iterator it2(it->second.find(sound));
00125
00126 nlassert(it2 != it->second.end())
00127 it->second.erase(it2);
00128
00129 if (it->second.empty())
00130 {
00131
00132 _BufferAssoc.erase(it);
00133 }
00134
00135 }
00136 }
00137 }
00138
00139
00140
00141
00142
00143 CSoundBank::~CSoundBank()
00144 {
00145 unload();
00146 }
00147
00148 void CSoundBank::addSound(CSound *sound)
00149 {
00150 _Sounds.insert(make_pair(sound->getName(), sound));
00151 }
00152
00153 void CSoundBank::removeSound(const std::string &name)
00154 {
00155 _Sounds.erase(name);
00156 }
00157
00158
00165 class CSoundSerializer
00166 {
00167 public:
00169 CSound *_Sound;
00170
00172 CSoundSerializer()
00173 : _Sound(0)
00174 {}
00175
00176
00177 void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const std::string &name)
00178 {
00179
00180 _Sound = CSound::createSound(name, form->getRootNode());
00181
00182
00183 if (_Sound != 0)
00184 CSoundBank::instance()->addSound(_Sound);
00185 }
00186
00187
00188 void serial (NLMISC::IStream &s)
00189 {
00190 if (s.isReading())
00191 {
00192
00193 CSound::TSOUND_TYPE type;
00194 s.serialEnum(type);
00195
00196 std::string name;
00197 s.serial(name);
00198
00199
00200 switch(CSound::TSOUND_TYPE(type))
00201 {
00202 case CSound::SOUND_SIMPLE:
00203 _Sound = new CSimpleSound();
00204 break;
00205 case CSound::SOUND_COMPLEX:
00206 _Sound = new CComplexSound();
00207 break;
00208 case CSound::SOUND_CONTEXT:
00209 _Sound = new CContextSound();
00210 break;
00211 case CSound::SOUND_BACKGROUND:
00212 _Sound = new CBackgroundSound();
00213 break;
00214 default:
00215 _Sound = 0;
00216 }
00217
00218
00219 if (_Sound)
00220 {
00221
00222 _Sound->serial(s);
00223 CSoundBank::instance()->addSound(_Sound);
00224 }
00225 }
00226 else
00227 {
00228 if (_Sound == 0)
00229 {
00230
00231 uint32 i = -1;
00232 s.serialEnum(i);
00233 s.serial(std::string("bad sound"));
00234 }
00235 else
00236 {
00237
00238 CSound::TSOUND_TYPE type = _Sound->getSoundType();
00239 s.serialEnum(type);
00240
00241 s.serial(const_cast<std::string&>(_Sound->getName()));
00242
00243
00244 _Sound->serial(s);
00245 }
00246 }
00247 }
00248
00252 void removed()
00253 {
00254 if (_Sound != 0)
00255 {
00256
00257 CSoundBank::instance()->removeSound(_Sound->getName());
00258 delete _Sound;
00259 }
00260 }
00261
00262
00263 static uint getVersion () { return 1; }
00264 };
00265
00266
00267 std::map<std::string, CSoundSerializer> Container;
00268
00273 void CSoundBank::load()
00274 {
00275 nlassert(!_Loaded);
00276
00277 ::loadForm("sound", "sounds.packed_sheets", Container, true);
00278 _Loaded = true;
00279 }
00280
00281
00282
00283
00284
00285 void CSoundBank::unload()
00286 {
00287 nlassert(_Loaded);
00288 vector<CSound*> vec;
00289 TSoundTable::iterator map_iter;
00290
00291 for (map_iter = _Sounds.begin(); map_iter != _Sounds.end(); ++map_iter)
00292 {
00293
00294 vec.push_back( (*map_iter).second );
00295 }
00296
00297 _Sounds.clear();
00298
00299 vector<CSound*>::iterator vec_iter;
00300
00301 for (vec_iter = vec.begin(); vec_iter != vec.end(); ++vec_iter)
00302 {
00303 CSound *sound = *vec_iter;
00304 delete sound;
00305 }
00306
00307 _Loaded = false;
00308 }
00309
00310
00311
00312
00313 bool CSoundBank::isLoaded()
00314 {
00315 return _Loaded;
00316 }
00317
00318
00319
00320
00321 CSound* CSoundBank::getSound(const std::string &name)
00322 {
00323
00324 TSoundTable::iterator iter = _Sounds.find(name);
00325 if ( iter == _Sounds.end() )
00326 {
00327 return 0;
00328 }
00329 else
00330 {
00331 return (*iter).second;
00332 }
00333 }
00334
00338 void CSoundBank::getNames( std::vector<std::string>& names )
00339 {
00340 TSoundTable::const_iterator iter;
00341 for (iter = _Sounds.begin(); iter != _Sounds.end(); ++iter)
00342 {
00343 names.push_back((*iter).first);
00344
00345 }
00346 }
00347
00348
00349
00350
00351 uint CSoundBank::countSounds()
00352 {
00353 return _Sounds.size();
00354 }
00355
00356
00357 }
00358