#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. |