#include <sample_bank.h>
Inheritance diagram for NLSOUND::CSampleBank:

Nevrax France
Definition at line 67 of file sample_bank.h.
Public Member Functions | |
| uint | countSamples () |
| Return the number of samples in this bank. | |
| CSampleBank (const std::string &name, ISoundDriver *sd) | |
| Constructor. | |
| const NLMISC::TStringId | getName () const |
| Return the name (must be unique). | |
| IBuffer * | getSample (const NLMISC::TStringId &name) |
| Return a samples corresponding to a name. | |
| uint | getSize () |
| Return the size of this bank in bytes. | |
| bool | isLoaded () |
| Returns true if the samples in this bank have been loaded. | |
| void | load (bool async) |
| bool | unload () |
| virtual | ~CSampleBank () |
| Destructor. | |
Static Public Member Functions | |
| CSampleBank * | findSampleBank (const NLMISC::TStringId &filename) |
| Return an existing bank for the given file name, NULL if no bank for this file. | |
| IBuffer * | get (const NLMISC::TStringId &name) |
| Return the name corresponding to a name. The sample is searched. | |
| void | getLoadedSampleBankInfo (std::vector< std::pair< std::string, uint > > &result) |
| Fill a vector with current loaded sample banks. | |
| uint | getTotalByteSize () |
| Return the total loaded samples size. | |
| void | init (NLGEORGES::UFormElm *mixerConfig) |
| void | releaseAll () |
| Delete all the loaded banks. | |
| void | reload (bool async) |
| Reload all the sample bank. | |
Private Types | |
| typedef std::hash_map< NLMISC::TStringId, CSampleBank * > | TSampleBankContainer |
| typedef std::hash_map< NLMISC::TStringId, std::vector< TFilteredBank > > | TVirtualBankCont |
| List of virtual sample bank. | |
Private Member Functions | |
| void | onUpdate () |
| The update method. Used when waiting for async sample loading. | |
Private Attributes | |
| uint | _ByteSize |
| bool | _Loaded |
| bool | _LoadingDone |
| std::list< std::pair< IBuffer *, NLMISC::TStringId > > | _LoadList |
| List of sample that need to be loaded asynchronously. | |
| NLMISC::TStringId | _Name |
| TSampleTable | _Samples |
| ISoundDriver * | _SoundDriver |
| bool | _SplitLoadDone |
| Flag for splitted load. | |
Static Private Attributes | |
| TSampleBankContainer | _Banks |
| uint | _LoadedSize = 0 |
| TVirtualBankCont | _VirtualBanks |
|
|
Definition at line 140 of file sample_bank.h. |
|
|
List of virtual sample bank.
Definition at line 177 of file sample_bank.h. |
|
||||||||||||
|
Constructor.
Definition at line 180 of file sample_bank.cpp. Referenced by init().
00181 : _SoundDriver(sd), _Name(CStringMapper::map(name)), _Loaded(false), _LoadingDone(true), _ByteSize(0) 00182 { 00183 // _Name = CFile::getFilenameWithoutExtension(_Path); 00184 _Banks.insert(make_pair(_Name, this)); 00185 } |
|
|
Destructor.
Definition at line 190 of file sample_bank.cpp. References _LoadingDone, _Samples, NLMISC::nlSleep(), and unload().
00191 {
00192 CAudioMixerUser::instance()->unregisterUpdate(this);
00193 while (!_LoadingDone)
00194 {
00195 // need to wait for loading end.
00196 nlSleep(100);
00197 }
00198
00199 if (_Loaded)
00200 unload();
00201
00202 // remove the bank from the list of known banks
00203 TSampleBankContainer::iterator iter(_Banks.begin()), end(_Banks.end());
00204
00205 for (; iter != end; ++iter)
00206 {
00207 if (iter->second == this)
00208 {
00209 _Banks.erase(iter);
00210 break;
00211 }
00212 }
00213
00214
00215 // delete all the samples.
00216 while (!_Samples.empty())
00217 {
00218 delete _Samples.begin()->second;
00219 _Samples.erase(_Samples.begin());
00220 }
00221
00222 _Samples.clear();
00223 }
|
|
|
Return the number of samples in this bank.
Definition at line 587 of file sample_bank.cpp. References _Samples, and uint. Referenced by NLSOUND::CAudioMixerUser::loadSampleBank().
00588 {
00589 return _Samples.size();
00590 }
|
|
|
Return an existing bank for the given file name, NULL if no bank for this file.
Definition at line 115 of file sample_bank.cpp. Referenced by load().
|
|
|
Return the name corresponding to a name. The sample is searched.
Definition at line 127 of file sample_bank.cpp. References buffer.
00128 {
00129 IBuffer* buffer;
00130 TSampleBankContainer::iterator iter;
00131
00132 for (iter = _Banks.begin(); iter != _Banks.end(); ++iter)
00133 {
00134 buffer = iter->second->getSample(name);
00135 if (buffer != 0)
00136 {
00137 return buffer;
00138 }
00139 }
00140
00141 //nlwarning ("Try to get an unknown sample '%s'", name);
00142 return 0;
00143 }
|
|
|
Fill a vector with current loaded sample banks.
Definition at line 157 of file sample_bank.cpp. References NLMISC::CStringMapper::unmap().
00158 {
00159 result.clear();
00160
00161 TSampleBankContainer::iterator first(_Banks.begin()), last(_Banks.end());
00162 for (; first != last; ++first)
00163 {
00164 std::pair<std::string, uint> p;
00165 if (first->second->isLoaded())
00166 {
00167 p.first = NLMISC::CStringMapper::unmap(first->first);
00168 p.second = first->second->getSize();
00169 result.push_back(p);
00170 }
00171 }
00172 }
|
|
|
Return the name (must be unique).
Definition at line 129 of file sample_bank.h.
00129 { return _Name; }
|
|
|
Return a samples corresponding to a name.
Definition at line 555 of file sample_bank.cpp. References _Samples.
00556 {
00557 {
00558 /* // dump the sample list.
00559 TSampleTable::iterator it (_Samples.begin()), last(_Samples.end());
00560 std::string s;
00561
00562 // while (first != last)
00563 for (it = _Samples.begin(); it != _Samples.end(); ++it)
00564 {
00565 s += std::string(" [")+it->first+"] ";
00566 //first++;
00567 }
00568
00569 nldebug("getSample(%s) : sample list = [%s]", name, s.c_str());
00570 */
00571 }
00572
00573 // Find sound
00574 TSampleTable::iterator iter = _Samples.find(name);
00575 if ( iter == _Samples.end() )
00576 {
00577 return 0;
00578 }
00579 else
00580 {
00581 return (*iter).second;
00582 }
00583 }
|
|
|
Return the size of this bank in bytes.
Definition at line 594 of file sample_bank.cpp. References _Samples, size, and uint.
|
|
|
Return the total loaded samples size.
Definition at line 86 of file sample_bank.h. References _LoadedSize, and uint.
00086 { return _LoadedSize; };
|
|
|
Initialise the sample bank with the mixer config file. Definition at line 55 of file sample_bank.cpp. References _VirtualBanks, NLSOUND::CSampleBank::TFilteredBank::BankName, CSampleBank(), NLSOUND::CSampleBank::TFilteredBank::Filter, NLGEORGES::UFormElm::getArrayNode(), NLGEORGES::UFormElm::getArraySize(), NLGEORGES::UFormElm::getNodeByName(), NLGEORGES::UFormElm::getValueByName(), size, and uint.
00056 {
00057 NL_ALLOC_CONTEXT(NLSOUND_CSampleBank);
00058 if (mixerConfig == 0)
00059 return;
00060
00061 NLGEORGES::UFormElm *virtualBanks;
00062 mixerConfig->getNodeByName(&virtualBanks, ".VirtualBanks");
00063 if (virtualBanks == 0)
00064 return;
00065
00066 uint size;
00067 virtualBanks->getArraySize(size);
00068
00069 for (uint i=0; i<size; ++i)
00070 {
00071 NLGEORGES::UFormElm *virtualBank;
00072 virtualBanks->getArrayNode(&virtualBank, i);
00073
00074 if (virtualBank != 0)
00075 {
00076 std::vector<TFilteredBank> vfb;
00077 std::string virtualName;
00078 virtualBank->getValueByName(virtualName, ".VirtualName");
00079 NLGEORGES::UFormElm *realBanks;
00080 virtualBank->getNodeByName(&realBanks, ".FilteredBank");
00081 if (realBanks != 0)
00082 {
00083 uint size2;
00084 realBanks->getArraySize(size2);
00085
00086 for (uint j=0; j<size2; ++j)
00087 {
00088 TFilteredBank fb;
00089 std::string bankName;
00090 NLGEORGES::UFormElm *realBank;
00091 realBank->getArrayNode(&realBank, j);
00092
00093 realBank->getValueByName(bankName, ".SampleBank");
00094 fb.BankName = CStringMapper::map(bankName);
00095 realBank->getValueByName(fb.Filter, ".Filter");
00096
00097 vfb.push_back(fb);
00098 }
00099 }
00100
00101 if (!vfb.empty())
00102 {
00103 _VirtualBanks.insert(std::make_pair(NLMISC::CStringMapper::map(virtualName), vfb));
00104 // create the sample bank
00105 new CSampleBank(virtualName, NULL);
00106 }
00107 }
00108 }
00109 }
|
|
|
Returns true if the samples in this bank have been loaded.
Definition at line 548 of file sample_bank.cpp.
00549 {
00550 return _Loaded;
00551 }
|
|
|
Load all the samples. Can throw EPathNotFound or ESoundFileNotFound (check Exception)
Definition at line 228 of file sample_bank.cpp. References _ByteSize, _LoadedSize, _LoadingDone, _Samples, _VirtualBanks, NLSOUND::ISoundDriver::createBuffer(), data, findSampleBank(), NLSOUND::CAudioMixerUser::TSampleBankHeader::Freq, NLSOUND::CAudioMixerUser::getBackgroundFlags(), NLSOUND::CAudioMixerUser::getPackedSheetUpdate(), NLMISC::CIFile::getPos(), NLSOUND::IBuffer::getSize(), NLSOUND::Mono16, NLSOUND::Mono16ADPCM, NLSOUND::CAudioMixerUser::TSampleBankHeader::Name, nlassert, nlinfo, nlwarning, NLSOUND::CAudioMixerUser::TSampleBankHeader::OffsetAdpcm, NLSOUND::CAudioMixerUser::TSampleBankHeader::OffsetMono16, NLSOUND::IBuffer::presetName(), NLSOUND::ISoundDriver::readRawBuffer(), NLMISC::CIFile::seek(), NLMISC::IStream::serial(), NLMISC::CIFile::serialBuffer(), sint32, NLSOUND::CAudioMixerUser::TSampleBankHeader::SizeAdpcm, NLSOUND::CAudioMixerUser::TSampleBankHeader::SizeMono16, uint, and uint8. Referenced by NLSOUND::CAudioMixerUser::loadSampleBank().
00229 {
00230 // TODO : add async loading support !
00231
00232 TVirtualBankCont::iterator it(_VirtualBanks.find(_Name));
00233 if (it != _VirtualBanks.end())
00234 {
00235 // this is a virtual sample bank !
00236 nlinfo("Loading virtual sample bank %s", CStringMapper::unmap(_Name).c_str());
00237
00238 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00239 const CAudioMixerUser::TBackgroundFlags &flags = mixer->getBackgroundFlags();
00240
00241 for (uint i=0; i<it->second.size(); ++i)
00242 {
00243 if (flags.Flags[it->second[i].Filter])
00244 {
00245 CSampleBank *bank = findSampleBank(it->second[i].BankName);
00246 if (bank)
00247 bank->load(async);
00248 }
00249 }
00250 }
00251
00252 nlinfo("Loading sample bank %s %", CStringMapper::unmap(_Name).c_str(), async?"":"Asynchronously");
00253
00254 vector<string> filenames;
00255 // vector<string>::iterator iter;
00256
00257 if (_Loaded)
00258 {
00259 nlwarning("Trying to load an already loaded bank : %s", CStringMapper::unmap(_Name).c_str ());
00260 return;
00261 }
00262
00263
00264 // Load the sample bank from the builded sample_bank file.
00265 string bankName(CStringMapper::unmap(_Name)+".sample_bank");
00266 string filename = CPath::lookup(bankName);
00267 if (filename.empty())
00268 {
00269 nlwarning("Trying to load an unknown sample bank [%s]", bankName.c_str());
00270 return;
00271 }
00272
00273 try
00274 {
00275
00276 CIFile sampleBank(filename);
00277
00278 CAudioMixerUser::TSampleBankHeader sbh;
00279 sampleBank.serial(sbh);
00280 _LoadingDone = false;
00281
00282 sint32 seekStart = sampleBank.getPos();
00283
00284
00285 uint8 *data = 0;
00286 uint i;
00287 for (i=0; i<sbh.Name.size(); ++i)
00288 {
00289 IBuffer *ibuffer = _SoundDriver->createBuffer();
00290 nlassert(ibuffer);
00291
00292 TStringId nameId = CStringMapper::map(CFile::getFilenameWithoutExtension(sbh.Name[i]));
00293 ibuffer->presetName(nameId);
00294
00295 /* {
00296 sint16 *data16 = new sint16[sbh.NbSample[i]];
00297 IBuffer::TADPCMState state;
00298 state.PreviousSample = 0;
00299 state.StepIndex = 0;
00300 uint count =0;
00301 for (count=0; count+1024<sbh.NbSample[i]; count+=1024)
00302 {
00303 IBuffer::decodeADPCM(data+count/2, data16+count, 1024, state);
00304 }
00305 IBuffer::decodeADPCM(data+count/2, data16+count, sbh.NbSample[i]-count, state);
00306
00307 state.PreviousSample = 0;
00308 state.StepIndex = 0;
00309 sint16 *data16_2 = new sint16[sbh.NbSample[i]];
00310 IBuffer::decodeADPCM(data, data16_2, sbh.NbSample[i], state);
00311
00312 for (uint j=0; j<sbh.NbSample[i]; ++j)
00313 {
00314 if (data16[j] != data16_2[j])
00315 {
00316 nlwarning("Sample differ at %u", j);
00317 }
00318 }
00319
00320 _SoundDriver->readRawBuffer(ibuffer, sbh.Name[i], (uint8*)data16, sbh.NbSample[i]*2, Mono16, sbh.Freq[i]);
00321 delete [] data16;
00322 delete [] data16_2;
00323 }
00324 */
00325
00326 if (CAudioMixerUser::instance()->useAPDCM())
00327 {
00328 data = (uint8*) realloc(data, sbh.SizeAdpcm[i]);
00329 sampleBank.seek(seekStart + sbh.OffsetAdpcm[i], CIFile::begin);
00330 sampleBank.serialBuffer(data, sbh.SizeAdpcm[i]);
00331 _SoundDriver->readRawBuffer(ibuffer, sbh.Name[i], data, sbh.SizeAdpcm[i], Mono16ADPCM, sbh.Freq[i]);
00332 }
00333 else
00334 {
00335 data = (uint8*) realloc(data, sbh.SizeMono16[i]);
00336 sampleBank.seek(seekStart + sbh.OffsetMono16[i], CIFile::begin);
00337 sampleBank.serialBuffer(data, sbh.SizeMono16[i]);
00338 _SoundDriver->readRawBuffer(ibuffer, sbh.Name[i], data, sbh.SizeMono16[i], Mono16, sbh.Freq[i]);
00339 }
00340
00341 _ByteSize += ibuffer->getSize();
00342
00343 _Samples[nameId] = ibuffer;
00344
00345 // Warn the sound bank that the sample are available.
00346 CSoundBank::instance()->bufferLoaded(nameId, ibuffer);
00347 }
00348 free(data);
00349
00350 _LoadedSize += _ByteSize;
00351 }
00352 catch(Exception &e)
00353 {
00354 // loading failed !
00355 nlwarning("Exception %s during loading of sample bank %s", e.what(), filename.c_str());
00356 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00357
00358 if (mixer->getPackedSheetUpdate())
00359 {
00360 nlinfo("Deleting offending sound bank, you need to restart to recreate it!");
00361 CFile::deleteFile(filename);
00362 }
00363 }
00364
00365 _Loaded = true;
00366 _LoadingDone = true;
00367
00368
00369
00371 /*
00372
00373 std::string list = CPath::lookup(CStringMapper::unmap(_Name)+CAudioMixerUser::SampleBankListExt, false);
00374 if (list.empty())
00375 {
00376 nlwarning("File %s not found to load sample bank %s", (CStringMapper::unmap(_Name)+CAudioMixerUser::SampleBankListExt).c_str(), CStringMapper::unmap(_Name).c_str());
00377 return;
00378 }
00379
00380
00381 NLMISC::CIFile sampleBankList(list);
00382 sampleBankList.serialCont(filenames);
00383
00384 for (iter = filenames.begin(); iter != filenames.end(); iter++)
00385 {
00386 IBuffer* ibuffer = NULL;
00387 try
00388 {
00389 ibuffer = _SoundDriver->createBuffer();
00390 nlassert(ibuffer);
00391
00392 // std::string sampleName(CFile::getFilenameWithoutExtension(*iter));
00393 NLMISC::TStringId sampleName(CStringMapper::map(CFile::getFilenameWithoutExtension(*iter)));
00394
00395 if (async)
00396 {
00397 ibuffer->presetName(sampleName);
00398 nldebug("Preloading sample [%s]", CStringMapper::unmap(sampleName).c_str());
00399 }
00400 else
00401 {
00402 std::string fullName = NLMISC::CPath::lookup(*iter, false);
00403 if (!fullName.empty())
00404 {
00405 NLMISC::CIFile ifile(fullName);
00406 uint size = ifile.getFileSize();
00407 uint8 *buffer = new uint8[ifile.getFileSize()];
00408 ifile.serialBuffer(buffer, size);
00409
00410 _SoundDriver->readWavBuffer(ibuffer, fullName, buffer, size);
00411 _ByteSize += ibuffer->getSize();
00412
00413 delete [] buffer;
00414 }
00415 }
00416 _Samples[sampleName] = ibuffer ;
00417
00418 // Warn the sound bank that the sample are available.
00419 CSoundBank::instance()->bufferLoaded(sampleName, ibuffer);
00420 }
00421 catch (ESoundDriver &e)
00422 {
00423 if (ibuffer != NULL) {
00424 delete ibuffer;
00425 ibuffer = NULL;
00426 }
00427 nlwarning("Problem with file '%s': %s", (*iter).c_str(), e.what());
00428 }
00429 }
00430
00431 _Loaded = true;
00432
00433 if (!async)
00434 {
00435 _LoadingDone = true;
00436 // compute the sample bank size.
00437 _LoadedSize += _ByteSize;
00438 }
00439 else
00440 {
00441 // fill the loading list.
00442 TSampleTable::iterator first(_Samples.begin()), last(_Samples.end());
00443 for (; first != last; ++first)
00444 {
00445 _LoadList.push_back(make_pair(first->second, first->first));
00446 }
00447 _SplitLoadDone = false;
00448 // send the first files
00449 for (uint i=0; i<ASYNC_LOADING_SPLIT && !_LoadList.empty(); ++i)
00450 {
00451 CAsyncFileManagerSound::getInstance().loadWavFile(_LoadList.front().first, CStringMapper::unmap(_LoadList.front().second)+".wav");
00452 _LoadList.pop_front();
00453 }
00454 // add a end loading event...
00455 CAsyncFileManagerSound::getInstance().signal(&_SplitLoadDone);
00456 // and register for update on the mixer
00457 CAudioMixerUser::instance()->registerUpdate(this);
00458 }
00459 */
00460 }
|
|
|
The update method. Used when waiting for async sample loading.
Implements NLSOUND::CAudioMixerUser::IMixerUpdate. Definition at line 462 of file sample_bank.cpp. References _ByteSize, _LoadedSize, _LoadingDone, _LoadList, _Samples, _SplitLoadDone, NLSOUND::ASYNC_LOADING_SPLIT, nldebug, nlinfo, and uint.
00463 {
00464 if (_SplitLoadDone)
00465 {
00466 nldebug("Some samples have been loaded");
00467 if (_LoadList.empty())
00468 {
00469 // all the samples are loaded, we can compute the bank size.
00470 TSampleTable::iterator first(_Samples.begin()), last(_Samples.end());
00471 for (; first != last; ++first)
00472 {
00473 _ByteSize += first->second->getSize();
00474 }
00475
00476 _LoadedSize += _ByteSize;
00477
00478 // stop the update.
00479 CAudioMixerUser::instance()->unregisterUpdate(this);
00480 _LoadingDone = true;
00481
00482 // Force an update in the background manager (can restar stoped sound).
00483 CAudioMixerUser::instance()->getBackgroundSoundManager()->updateBackgroundStatus();
00484
00485 nlinfo("Sample bank %s loaded.", CStringMapper::unmap(_Name).c_str());
00486 }
00487 else
00488 {
00489 _SplitLoadDone = false;
00490 for (uint i=0; i<ASYNC_LOADING_SPLIT && !_LoadList.empty(); ++i)
00491 {
00492 CAsyncFileManagerSound::getInstance().loadWavFile(_LoadList.front().first, CStringMapper::unmap(_LoadList.front().second)+".wav");
00493 _LoadList.pop_front();
00494 }
00495 // add a end loading event...
00496 CAsyncFileManagerSound::getInstance().signal(&_SplitLoadDone);
00497 }
00498 }
00499 }
|
|
|
Delete all the loaded banks.
Definition at line 607 of file sample_bank.cpp. References nldebug.
|
|
|
Reload all the sample bank.
Definition at line 145 of file sample_bank.cpp.
|
|
|
Unload all the samples in this bank. Return false is unload can't be done (if an async loading is not terminated. Definition at line 503 of file sample_bank.cpp. References _ByteSize, _LoadedSize, _LoadingDone, _Samples, buffer, nlinfo, and nlwarning. Referenced by NLSOUND::CAudioMixerUser::unloadSampleBank(), and ~CSampleBank().
00504 {
00505 vector<IBuffer*> vec;
00506 TSampleTable::iterator it;
00507
00508 if (!_Loaded)
00509 {
00510 nlwarning("Trying to unload an already unloaded bank : %s", CStringMapper::unmap(_Name).c_str ());
00511 return true;
00512 }
00513
00514 // need to wait end of load ?
00515 if (!_LoadingDone)
00516 return false;
00517
00518 nlinfo("Unloading sample bank %s", CStringMapper::unmap(_Name).c_str());
00519
00520 for (it = _Samples.begin(); it != _Samples.end(); ++it)
00521 {
00522 IBuffer *buffer = it->second;
00523 if (buffer)
00524 {
00525 const NLMISC::TStringId & bufferName = buffer->getName();
00526
00527 // Warn the mixer to stop any track playing this buffer.
00528 CAudioMixerUser::instance()->bufferUnloaded(buffer);
00529 // Warn the sound banks abount this buffer.
00530 CSoundBank::instance()->bufferUnloaded(bufferName);
00531
00532 // delete
00533 it->second = NULL;
00534 delete buffer;
00535 }
00536 }
00537
00538 _Loaded = false;
00539
00540 _LoadedSize -= _ByteSize;
00541 _ByteSize = 0;
00542
00543 return true;
00544 }
|
|
|
Definition at line 47 of file sample_bank.cpp. |
|
|
Definition at line 162 of file sample_bank.h. Referenced by load(), onUpdate(), and unload(). |
|
|
Definition at line 158 of file sample_bank.h. |
|
|
Definition at line 48 of file sample_bank.cpp. Referenced by getTotalByteSize(), load(), onUpdate(), and unload(). |
|
|
Definition at line 160 of file sample_bank.h. Referenced by load(), onUpdate(), unload(), and ~CSampleBank(). |
|
|
List of sample that need to be loaded asynchronously.
Definition at line 168 of file sample_bank.h. Referenced by onUpdate(). |
|
|
Definition at line 155 of file sample_bank.h. |
|
|
Definition at line 151 of file sample_bank.h. Referenced by countSamples(), getSample(), getSize(), load(), onUpdate(), unload(), and ~CSampleBank(). |
|
|
Definition at line 148 of file sample_bank.h. |
|
|
Flag for splitted load.
Definition at line 165 of file sample_bank.h. Referenced by onUpdate(). |
|
|
Definition at line 50 of file sample_bank.cpp. |
1.3.6