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 "sample_bank.h"
00029 #include "driver/sound_driver.h"
00030 #include "driver/buffer.h"
00031 #include "nel/misc/path.h"
00032 #include "async_file_manager_sound.h"
00033 #include "sound_bank.h"
00034
00035
00036
00037 using namespace std;
00038 using namespace NLMISC;
00039
00040
00041 namespace NLSOUND {
00042
00044 uint32 ASYNC_LOADING_SPLIT = 10;
00045
00046 CSampleBank::TSampleBankContainer CSampleBank::_Banks;
00047 uint CSampleBank::_LoadedSize = 0;
00048
00049
00050
00051
00052 CSampleBank *CSampleBank::findSampleBank(const std::string &filename)
00053 {
00054 TSampleBankContainer::iterator it(_Banks.find(filename));
00055
00056 if (it != _Banks.end())
00057 return it->second;
00058
00059 return NULL;
00060 }
00061
00062
00063
00064 IBuffer* CSampleBank::get(const std::string &name)
00065 {
00066 IBuffer* buffer;
00067 TSampleBankContainer::iterator iter;
00068
00069 for (iter = _Banks.begin(); iter != _Banks.end(); ++iter)
00070 {
00071 buffer = iter->second->getSample(name);
00072 if (buffer != 0)
00073 {
00074 return buffer;
00075 }
00076 }
00077
00078
00079 return 0;
00080 }
00081
00082 void CSampleBank::reload(bool async)
00083 {
00084 TSampleBankContainer::iterator first(_Banks.begin()), last(_Banks.end());
00085
00086 for (; first != last; ++first)
00087 {
00088 first->second->unload();
00089 first->second->load(async);
00090 }
00091 }
00092
00093
00094
00095
00096
00097 CSampleBank::CSampleBank(const std::string& path, ISoundDriver *sd)
00098 : _SoundDriver(sd), _Path(path), _Loaded(false), _LoadingDone(true), _ByteSize(0)
00099 {
00100
00101 _Name = CFile::getFilenameWithoutExtension(_Path);
00102 _Banks.insert(make_pair(path, this));
00103
00104 }
00105
00106
00107
00108
00109 CSampleBank::~CSampleBank()
00110 {
00111
00112 while (!_LoadingDone)
00113 {
00114
00115 nlSleep(100);
00116 }
00117
00118
00119
00120 TSampleBankContainer::iterator iter(_Banks.begin()), end(_Banks.end());
00121
00122
00123 for (; iter != end; ++iter)
00124 {
00125 if (iter->second == this)
00126 {
00127 _Banks.erase(iter);
00128 break;
00129 }
00130 }
00131
00132
00133
00134
00135 while (!_Samples.empty())
00136 {
00137
00138 delete _Samples.begin()->second;
00139 _Samples.erase(_Samples.begin());
00140
00141 }
00142 }
00143
00144
00145
00146
00147 void CSampleBank::load(bool async)
00148 {
00149 nldebug("Loading sample bank %s %", _Name.c_str(), async?"":"Asynchronously");
00150
00151 vector<string> filenames;
00152 vector<string>::iterator iter;
00153
00154 if (_Loaded)
00155 {
00156 nlwarning("Trying to load an already loaded bank : %s", _Path);
00157 return;
00158 }
00159
00160 _LoadingDone = false;
00161
00162 CPath::getPathContent(_Path, true, false, true, filenames);
00163
00164 for (iter = filenames.begin(); iter != filenames.end(); iter++)
00165 {
00166 IBuffer* buffer = NULL;
00167 try
00168 {
00169 buffer = _SoundDriver->createBuffer();
00170 nlassert(buffer);
00171
00172 std::string sampleName(CFile::getFilenameWithoutExtension(*iter));
00173
00174 if (async)
00175 {
00176 buffer->presetName(sampleName);
00177 nldebug("Preloading sample [%s]", sampleName.c_str());
00178 }
00179 else
00180 {
00181 _SoundDriver->loadWavFile(buffer, (*iter).c_str());
00182 _ByteSize += buffer->getSize();
00183 }
00184 _Samples[sampleName] = buffer ;
00185
00186
00187 CSoundBank::instance()->bufferLoaded(sampleName, buffer);
00188 }
00189 catch (ESoundDriver &e)
00190 {
00191 if (buffer != NULL) {
00192 delete buffer;
00193 buffer = NULL;
00194 }
00195 nlwarning("Problem with file '%s': %s", (*iter).c_str(), e.what());
00196 }
00197 }
00198
00199 _Loaded = true;
00200
00201 if (!async)
00202 {
00203 _LoadingDone = true;
00204
00205 _LoadedSize += _ByteSize;
00206 }
00207 else
00208 {
00209
00210 TSampleTable::iterator first(_Samples.begin()), last(_Samples.end());
00211 for (; first != last; ++first)
00212 {
00213 _LoadList.push_back(make_pair(first->second, first->first));
00214 }
00215 _SplitLoadDone = false;
00216
00217 for (uint i=0; i<ASYNC_LOADING_SPLIT && !_LoadList.empty(); ++i)
00218 {
00219 CAsyncFileManagerSound::getInstance().loadWavFile(_LoadList.front().first, _Path+"/"+_LoadList.front().second+".wav");
00220 _LoadList.pop_front();
00221 }
00222
00223 CAsyncFileManagerSound::getInstance().signal(&_SplitLoadDone);
00224
00225 CAudioMixerUser::instance()->registerUpdate(this);
00226 }
00227
00228 }
00229
00230 void CSampleBank::onUpdate()
00231 {
00232
00233 if (_SplitLoadDone)
00234 {
00235 nldebug("Some samples have been loaded");
00236 if (_LoadList.empty())
00237 {
00238
00239 TSampleTable::iterator first(_Samples.begin()), last(_Samples.end());
00240 for (; first != last; ++first)
00241 {
00242 _ByteSize += first->second->getSize();
00243 }
00244
00245 _LoadedSize += _ByteSize;
00246
00247
00248 CAudioMixerUser::instance()->unregisterUpdate(this);
00249 _LoadingDone = true;
00250
00251
00252 CAudioMixerUser::instance()->getBackgroundSoundManager()->updateBackgroundStatus();
00253
00254 nldebug("Sample bank %s loaded.", _Name.c_str());
00255 }
00256 else
00257 {
00258 _SplitLoadDone = false;
00259 for (uint i=0; i<ASYNC_LOADING_SPLIT && !_LoadList.empty(); ++i)
00260 {
00261 CAsyncFileManagerSound::getInstance().loadWavFile(_LoadList.front().first, _Path+"/"+_LoadList.front().second+".wav");
00262 _LoadList.pop_front();
00263 }
00264
00265 CAsyncFileManagerSound::getInstance().signal(&_SplitLoadDone);
00266 }
00267 }
00268
00269 }
00270
00271
00272
00273 bool CSampleBank::unload()
00274 {
00275
00276 vector<IBuffer*> vec;
00277 TSampleTable::iterator it;
00278
00279 if (!_Loaded)
00280 {
00281 nlwarning("Trying to unload an already unloaded bank : %s", _Path);
00282 }
00283
00284
00285 if (!_LoadingDone)
00286 return false;
00287
00288 nldebug("Unloading sample bank %s", _Name.c_str());
00289
00290 for (it = _Samples.begin(); it != _Samples.end(); ++it)
00291 {
00292 IBuffer *buffer = it->second;
00293 if (buffer)
00294 {
00295 const std::string & bufferName = buffer->getName();
00296
00297
00298 CAudioMixerUser::instance()->bufferUnloaded(buffer);
00299
00300 CSoundBank::instance()->bufferUnloaded(bufferName);
00301
00302
00303 it->second = NULL;
00304 delete buffer;
00305 }
00306 }
00307
00308
00309 _Loaded = false;
00310
00311 _LoadedSize -= _ByteSize;
00312 _ByteSize = 0;
00313
00314 return true;
00315 }
00316
00317
00318
00319 bool CSampleBank::isLoaded()
00320 {
00321 return _Loaded;
00322 }
00323
00324
00325
00326 IBuffer* CSampleBank::getSample(const std::string &name)
00327 {
00328 {
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 }
00343
00344
00345 TSampleTable::iterator iter = _Samples.find(name);
00346 if ( iter == _Samples.end() )
00347 {
00348 return 0;
00349 }
00350 else
00351 {
00352 return (*iter).second;
00353 }
00354 }
00355
00356
00357
00358 uint CSampleBank::countSamples()
00359 {
00360 return _Samples.size();
00361 }
00362
00363
00364
00365 uint CSampleBank::getSize()
00366 {
00367 uint size = 0;
00368
00369 TSampleTable::const_iterator iter;
00370 for (iter = _Samples.begin(); iter != _Samples.end(); iter++)
00371 {
00372 size += (*iter).second->getSize();
00373 }
00374
00375 return size;
00376 }
00377
00378 void CSampleBank::releaseAll()
00379 {
00380 nldebug( "SampleBanks: Releasing..." );
00381
00382 while (!_Banks.empty())
00383 {
00384
00385 delete _Banks.begin()->second;
00386
00387 }
00388 nldebug( "SampleBanks: Released" );
00389 }
00390
00391
00392
00393 }
00394