#include <background_sound_manager.h>
Inheritance diagram for NLSOUND::CBackgroundSoundManager:

Sounds can be put in three separate layer (named a, b and c). In each layer, sounds patatoid are concurent and the smaller in surface muffle the other sounds.
Effets are managed according to the EAX capacity of the driver.
Sample bank patatoid are used to dynamicaly load/unload the sample banks will the player walk the univers.
Nevrax France
Definition at line 79 of file background_sound_manager.h.
Public Member Functions | |
| const UAudioMixer::TBackgroundFilterFades & | getBackgroundFilterFades () |
| const UAudioMixer::TBackgroundFlags & | getBackgroundFlags () |
| Get the background flags. | |
| const float * | getFilterValues () |
| const std::vector< NLMISC::CVector > & | getZone (uint32 zone, bool *isPath=0) |
| Return a patatoid. If isPath is not null, set it. | |
| NLMISC::CVector | getZoneSourcePos (uint32 zone) |
| Return the position of the 3d source for a zone. | |
| void | load (const std::string &continent, NLLIGO::CLigoConfig &config) |
| void | loadAudioFromPrimitives (const NLLIGO::IPrimitive &audioRoot) |
| void | loadEffecsFromRegion (const NLLIGO::CPrimRegion ®ion) |
| void | loadSamplesFromRegion (const NLLIGO::CPrimRegion ®ion) |
| void | loadSoundsFromRegion (const NLLIGO::CPrimRegion ®ion) |
| void | play () |
| Start to play the background sound. | |
| void | setBackgroundFilterFades (const UAudioMixer::TBackgroundFilterFades &backgroundFilterFades) |
| void | setBackgroundFlags (const UAudioMixer::TBackgroundFlags &backgroundFlags) |
| Set the background flags. | |
| void | setListenerPosition (const NLMISC::CVector &listenerPosition) |
| Call this method when the listener position change. | |
| void | stop () |
| Stop the background sound. | |
| void | unload () |
| void | updateBackgroundStatus () |
| Call this method to update the background sound (sub method of setListenerPosition). | |
Private Member Functions | |
| void | addFxZone (const std::string &fxName, const std::vector< NLLIGO::CPrimVector > &points) |
| add a fx zone | |
| void | addSampleBank (const std::vector< std::string > &bankNames, const std::vector< NLLIGO::CPrimVector > &points) |
| add a sample bank zone | |
| void | addSound (const std::string &rawSoundName, const std::vector< NLLIGO::CPrimVector > &points, bool isPath) |
| deprecated, Internal use only for loading. | |
| void | addSound (const std::string &soundName, uint layerId, const std::vector< NLLIGO::CPrimVector > &points, bool isPath) |
| CBackgroundSoundManager () | |
| Constructor. | |
| void | loadEffectsFromPrimitives (const NLLIGO::IPrimitive &fxRoot) |
| void | loadSamplesFromPrimitives (const NLLIGO::IPrimitive &sampleRoot) |
| void | loadSoundsFromPrimitives (const NLLIGO::IPrimitive &soundRoot) |
| void | onUpdate () |
| template<class CharType> std::vector< std::basic_string< CharType > > | split (const std::basic_string< CharType > &str, CharType splitTag) |
| TODO : Utility... should be in NLMISC ? | |
| virtual | ~CBackgroundSoundManager () |
| Destructor. | |
Private Attributes | |
| UAudioMixer::TBackgroundFilterFades | _BackgroundFilterFades |
| Background filters fades. | |
| UAudioMixer::TBackgroundFlags | _BackgroundFlags |
| Background flags. | |
| bool | _DoFade |
| Is some fade in/out running? | |
| NLMISC::TTime | _FilterFadesStart [UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS] |
| The date of last fade in or out started for each filter. | |
| float | _FilterFadeValues [UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS] |
| The filter fade values. | |
| std::vector< TFxZone > | _FxZones |
| Container for the fx primitive. | |
| NLMISC::TStringId | _LastEnv |
| Last setted env fx. Used when clustered sound is not active. | |
| NLMISC::CVector | _LastPosition |
| The last position of the listener. | |
| bool | _Playing |
| Flag for playing background sounds. | |
| std::vector< TBanksData > | _Banks |
| Container for the banks primitive. | |
| std::set< std::string > | _LoadedBanks |
| Container for the list of currently loaded banks. | |
| std::vector< TSoundData > | _Layers [BACKGROUND_LAYER] |
| Array of vector of sound data. | |
Friends | |
| class | CAudioMixerUser |
|
|
Constructor.
Definition at line 60 of file background_sound_manager.cpp. References _BackgroundFlags, _FilterFadesStart, _FilterFadeValues, NLSOUND::UAudioMixer::TBackgroundFlags::Flags, and uint.
00061 : _LastPosition(0,0,0), _Playing(false), _DoFade(false) 00062 { 00063 for (uint i=0; i<UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i) 00064 { 00065 _BackgroundFlags.Flags[i] = false; 00066 _FilterFadesStart[i] = 0; 00067 _FilterFadeValues[i] = 1.0f; 00068 } 00069 } |
|
|
Destructor.
Definition at line 71 of file background_sound_manager.cpp. References unload().
00072 {
00073 unload();
00074 }
|
|
||||||||||||
|
add a fx zone
Definition at line 473 of file background_sound_manager.cpp. References _FxZones, NLSOUND::CBackgroundSoundManager::TFxZone::FxName, NLSOUND::CBackgroundSoundManager::TFxZone::MaxBox, min, NLSOUND::CBackgroundSoundManager::TFxZone::MinBox, NLSOUND::CBackgroundSoundManager::TFxZone::Points, uint, NLMISC::CVector::x, and NLMISC::CVector::y. Referenced by loadEffectsFromPrimitives().
00474 {
00475 TFxZone fxZone;
00476
00477 fxZone.FxName = CStringMapper::map(fxName);
00478 fxZone.Points.resize (points.size());
00479 for (uint j=0; j<points.size(); j++)
00480 {
00481 fxZone.Points[j] = points[j];
00482 }
00483
00484 // compute bouding box.
00485 CVector vmin(FLT_MAX, FLT_MAX, 0), vmax(-FLT_MAX, -FLT_MAX, 0);
00486
00487 vector<CVector>::iterator first(fxZone.Points.begin()), last(fxZone.Points.end());
00488 for (; first != last; ++first)
00489 {
00490 vmin.x = min(first->x, vmin.x);
00491 vmin.y = min(first->y, vmin.y);
00492 vmax.x = max(first->x, vmax.x);
00493 vmax.y = max(first->y, vmax.y);
00494 }
00495 fxZone.MaxBox = vmax;
00496 fxZone.MinBox = vmin;
00497
00498 _FxZones.push_back(fxZone);
00499 }
|
|
||||||||||||
|
add a sample bank zone
Definition at line 502 of file background_sound_manager.cpp. References NLSOUND::CBackgroundSoundManager::TBanksData::Banks, NLSOUND::CBackgroundSoundManager::TBanksData::MaxBox, min, NLSOUND::CBackgroundSoundManager::TBanksData::MinBox, NLSOUND::CBackgroundSoundManager::TBanksData::Points, uint, NLMISC::CVector::x, and NLMISC::CVector::y. Referenced by loadSamplesFromPrimitives(), and loadSamplesFromRegion().
00503 {
00504 TBanksData bd;
00505 // uint pointCount = points.size ();
00506 bd.Points.resize (points.size());
00507 for (uint j=0; j<points.size(); j++)
00508 {
00509 bd.Points[j] = points[j];
00510 }
00511
00512 // compute bouding box.
00513 CVector vmin(FLT_MAX, FLT_MAX, 0), vmax(-FLT_MAX, -FLT_MAX, 0);
00514
00515 vector<CVector>::iterator first(bd.Points.begin()), last(bd.Points.end());
00516 for (; first != last; ++first)
00517 {
00518 vmin.x = min(first->x, vmin.x);
00519 vmin.y = min(first->y, vmin.y);
00520 vmax.x = max(first->x, vmax.x);
00521 vmax.y = max(first->y, vmax.y);
00522 }
00523 bd.MaxBox = vmax;
00524 bd.MinBox = vmin;
00525
00526 for(uint i=0; i<bankNames.size(); ++i)
00527 {
00528 if (!bankNames[i].empty())
00529 bd.Banks.push_back(bankNames[i]);
00530 }
00531
00532 // ok, store it in the container.
00533 _Banks.push_back(bd);
00534 }
|
|
||||||||||||||||
|
deprecated, Internal use only for loading.
Definition at line 149 of file background_sound_manager.cpp. References addSound(), NLSOUND::BACKGROUND_LAYER, NLMISC::clamp(), count, nlwarning, uint, and uint32.
00150 {
00151 uint layerId = 0;
00152 uint n = 0;
00153 string name;
00154 // count the number of '-' in the string.
00155 n = std::count(rawSoundName.begin(), rawSoundName.end(), '-');
00156
00157 if (n == 2)
00158 {
00159 // no layer spec, default to layer A
00160 uint32 pos1 = rawSoundName.find ("-");
00161 if(pos1 == string::npos)
00162 {
00163 nlwarning ("zone have the malformated name '%s' missing -name-", rawSoundName.c_str());
00164 return;
00165 }
00166 pos1++;
00167
00168 uint32 pos2 = rawSoundName.find ("-", pos1);
00169 if(pos2 == string::npos)
00170 {
00171 nlwarning ("zone have the malformated name '%s' missing -name-", rawSoundName.c_str());
00172 return;
00173 }
00174
00175 name = rawSoundName.substr(pos1, pos2-pos1);
00176 }
00177 else if (n == 3)
00178 {
00179 // layer spec !
00180 uint32 pos1 = rawSoundName.find ("-");
00181 uint32 pos2 = rawSoundName.find ("-", pos1+1);
00182 if(pos1 == string::npos || pos2 == string::npos)
00183 {
00184 nlwarning ("zone have the malformated name '%s' missing -layerId- or -name-", rawSoundName.c_str());
00185 return;
00186 }
00187 pos1++;
00188
00189 uint32 pos3 = rawSoundName.find ("-", pos2+1);
00190 if(pos3 == string::npos)
00191 {
00192 nlwarning ("zone have the malformated name '%s' missing -name-", rawSoundName.c_str());
00193 return;
00194 }
00195
00196 char id = rawSoundName[pos1];
00197
00198 // check caps
00199 if (id < 'a')
00200 id = id + ('a' - 'A');
00201
00202 layerId = id - 'a';
00203
00204 NLMISC::clamp(layerId, 0u, BACKGROUND_LAYER-1);
00205 pos2++;
00206
00207 name = rawSoundName.substr(pos2, pos3-pos2);
00208 }
00209 else
00210 {
00211 nlwarning ("zone have the malformated name '%s", rawSoundName.c_str());
00212 return;
00213 }
00214
00215 addSound(name, layerId, points, isPath);
00216 /*
00217 TSoundData sd;
00218
00219 sd.SoundName = name;
00220 sd.Sound = mixer->getSoundId(sd.SoundName);
00221 sd.Source = 0;
00222
00223 // Copy the points
00224 sd.Points.resize (points.size ());
00225 for (uint i=0; i<points.size (); i++)
00226 sd.Points[i] = points[i];
00227
00228 sd.Selected = false;
00229 sd.IsPath = isPath;
00230
00231 if (sd.Sound != 0)
00232 {
00233 // the sound is available !
00234 // compute bouding box/
00235 CVector vmin(FLT_MAX, FLT_MAX, 0), vmax(-FLT_MAX, -FLT_MAX, 0);
00236
00237 vector<CVector>::iterator first(sd.Points.begin()), last(sd.Points.end());
00238 for (; first != last; ++first)
00239 {
00240 vmin.x = min(first->x, vmin.x);
00241 vmin.y = min(first->y, vmin.y);
00242 vmax.x = max(first->x, vmax.x);
00243 vmax.y = max(first->y, vmax.y);
00244 }
00245 sd.MaxBox = vmax;
00246 sd.MinBox = vmin;
00247
00248 // compute the surface without the sound distance
00249 sd.Surface = (vmax.x - vmin.x) * (vmax.y - vmin.y);
00250
00251 // add the eard distance of the sound.
00252 float dist = sd.Sound->getMaxDistance();
00253 sd.MaxBox.x += dist;
00254 sd.MaxBox.y += dist;
00255 sd.MinBox.x -= dist;
00256 sd.MinBox.y -= dist;
00257
00258 sd.MaxDist = dist;
00259
00260 // store the sound.
00261 // TODO : handle the three layer.
00262 _Layers[layerId].push_back(sd);
00263 }
00264 else
00265 {
00266 nlwarning ("The sound '%s' can't be loaded", sd.SoundName.c_str());
00267 }
00268 */
00269 }
|
|
||||||||||||||||||||
|
Definition at line 93 of file background_sound_manager.cpp. References _Layers, NLSOUND::CSound::getMaxDistance(), NLSOUND::CAudioMixerUser::getSoundId(), NLSOUND::CBackgroundSoundManager::TSoundData::IsPath, NLSOUND::CBackgroundSoundManager::TSoundData::MaxBox, NLSOUND::CBackgroundSoundManager::TSoundData::MaxDist, min, NLSOUND::CBackgroundSoundManager::TSoundData::MinBox, nlwarning, NLSOUND::CBackgroundSoundManager::TSoundData::Points, NLSOUND::CBackgroundSoundManager::TSoundData::Selected, NLSOUND::CBackgroundSoundManager::TSoundData::Sound, NLSOUND::CBackgroundSoundManager::TSoundData::SoundName, NLSOUND::CBackgroundSoundManager::TSoundData::Source, NLSOUND::CBackgroundSoundManager::TSoundData::Surface, uint, NLMISC::CVector::x, and NLMISC::CVector::y. Referenced by addSound(), loadSoundsFromPrimitives(), and loadSoundsFromRegion().
00094 {
00095 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00096 TSoundData sd;
00097
00098 sd.SoundName = CStringMapper::map(soundName);
00099 sd.Sound = mixer->getSoundId(sd.SoundName);
00100 sd.Source = 0;
00101
00102 // Copy the points
00103 sd.Points.resize (points.size ());
00104 for (uint i=0; i<points.size (); i++)
00105 sd.Points[i] = points[i];
00106
00107 sd.Selected = false;
00108 sd.IsPath = isPath;
00109
00110 if (sd.Sound != 0)
00111 {
00112 // the sound is available !
00113 // compute bouding box/
00114 CVector vmin(FLT_MAX, FLT_MAX, 0), vmax(-FLT_MAX, -FLT_MAX, 0);
00115
00116 vector<CVector>::iterator first(sd.Points.begin()), last(sd.Points.end());
00117 for (; first != last; ++first)
00118 {
00119 vmin.x = min(first->x, vmin.x);
00120 vmin.y = min(first->y, vmin.y);
00121 vmax.x = max(first->x, vmax.x);
00122 vmax.y = max(first->y, vmax.y);
00123 }
00124 sd.MaxBox = vmax;
00125 sd.MinBox = vmin;
00126
00127 // compute the surface without the sound distance
00128 sd.Surface = (vmax.x - vmin.x) * (vmax.y - vmin.y);
00129
00130 // add the eard distance of the sound.
00131 float dist = sd.Sound->getMaxDistance();
00132 sd.MaxBox.x += dist;
00133 sd.MaxBox.y += dist;
00134 sd.MinBox.x -= dist;
00135 sd.MinBox.y -= dist;
00136
00137 sd.MaxDist = dist;
00138
00139 // store the sound.
00140 // TODO : handle the three layer.
00141 _Layers[layerId].push_back(sd);
00142 }
00143 else
00144 {
00145 nlwarning ("The sound '%s' can't be loaded", CStringMapper::unmap(sd.SoundName).c_str());
00146 }
00147 }
|
|
|
Definition at line 87 of file background_sound_manager.cpp. References _BackgroundFilterFades. Referenced by NLSOUND::CAudioMixerUser::getBackgroundFilterFades().
00088 {
00089 return _BackgroundFilterFades;
00090 }
|
|
|
Get the background flags.
Definition at line 76 of file background_sound_manager.cpp. References _BackgroundFlags. Referenced by NLSOUND::CAudioMixerUser::getBackgroundFlags().
00077 {
00078 return _BackgroundFlags;
00079 }
|
|
|
Definition at line 139 of file background_sound_manager.h. References _FilterFadeValues. Referenced by NLSOUND::CBackgroundSource::play().
00139 { return _FilterFadeValues;}
|
|
||||||||||||
|
Return a patatoid. If isPath is not null, set it.
|
|
|
Return the position of the 3d source for a zone.
Definition at line 1369 of file background_sound_manager.cpp. References uint32.
01370 {
01371 /* nlassert (zone< BackgroundSounds.size());
01372 CVector pos;
01373 if (BackgroundSounds[zone].SourceDay != NULL)
01374 BackgroundSounds[zone].SourceDay->getPos(pos);
01375 return pos;
01376 */
01377 return CVector();
01378 }
|
|
||||||||||||
|
Load background sound for a continent. It'll automatically unload the old continent before loading the new one. This method load the 'audio' regions (specifying the sounds), the 'effect' regions and the 'sample' regions. Continent is for example "matis" or "fyros". It'll add .prim to the continent name and lookup() to find zones. So, don't forget to add sound .prim in the CPath system for the lookup With the new primitive file, this method will try to load the .primitive file before attempting to load any .prim file. If the .primitive is found, then no .prim are loaded. Definition at line 618 of file background_sound_manager.cpp. References _FxZones, _Layers, NLSOUND::BACKGROUND_LAYER, file, NLSOUND::CAudioMixerUser::getPackedSheetPath(), NLSOUND::CAudioMixerUser::getPackedSheetUpdate(), H_AUTO, loadAudioFromPrimitives(), loadEffecsFromRegion(), loadSamplesFromRegion(), loadSoundsFromRegion(), nlinfo, NLLIGO::CPrimitives::read(), NLLIGO::CPrimitives::RootNode, NLLIGO::CPrimRegion::serial(), NLMISC::IStream::serial(), NLMISC::IStream::serialCont(), uint, uint32, and NLLIGO::CPrimRegion::VZones. Referenced by NLSOUND::CAudioMixerUser::loadBackgroundSound().
00619 {
00620 NL_ALLOC_CONTEXT(NLSOUND_CBackgroundSoundManager);
00621 uint32 PACKED_VERSION = 1;
00622 // First, try to load from a .primitive file (contain everythink)
00623 {
00624 CIFile file;
00625 // CPrimRegion region;
00626 CPrimitives primitives;
00627 primitives.RootNode = new CPrimNode;
00628 string fn = continent+"_audio.primitive";
00629
00630 string path = CPath::lookup(fn, false);
00631
00632 if(!path.empty() && file.open (path))
00633 {
00634 // first, try to load the binary version (if up to date)
00635 {
00636 uint32 version;
00637 string filename = continent+".background_primitive";
00638 string binPath = CPath::lookup(filename, false, false, false);
00639 if (!binPath.empty()
00640 && (CFile::getFileModificationDate(binPath) > CFile::getFileModificationDate(path)))
00641 {
00642 CIFile binFile(binPath);
00643 binFile.serial(version);
00644
00645 if (version == PACKED_VERSION)
00646 {
00647 nlinfo ("loading '%s'", filename.c_str());
00648 _Banks.clear();
00649 binFile.serialCont(_Banks);
00650 for (uint i=0; i<BACKGROUND_LAYER; ++i)
00651 {
00652 _Layers[i].clear();
00653 binFile.serialCont(_Layers[i]);
00654 }
00655 _FxZones.clear();
00656 binFile.serialCont(_FxZones);
00657
00658 // jobs done !
00659 return;
00660 }
00661 }
00662 }
00663
00664 nlinfo ("loading '%s'", fn.c_str());
00665
00666 CIXml xml;
00667 {
00668 H_AUTO(BackgroundSoundMangerLoad_xml_init);
00669 xml.init (file);
00670 }
00671
00672 {
00673 H_AUTO(BackgroundSoundMangerLoad_primitive_read);
00674 primitives.read(xml.getRootNode(), fn.c_str(), config);
00675 }
00676 // region.serial(xml);
00677 file.close ();
00678
00679 {
00680 H_AUTO(BackgroundSoundMangerLoad_loadAudioFromPrimitive);
00681 loadAudioFromPrimitives(*primitives.RootNode);
00682 }
00683
00684 // store the binary version of the audio primitive for later use
00685 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00686 if (mixer->getPackedSheetUpdate())
00687 {
00688 // need to update packed sheet, so write the binary primitive version
00689 string filename = mixer->getPackedSheetPath()+"/"+continent+".background_primitive";
00690 COFile file(filename);
00691
00692 file.serial(PACKED_VERSION);
00693 file.serialCont(_Banks);
00694 for (uint i=0; i<BACKGROUND_LAYER; ++i)
00695 file.serialCont(_Layers[i]);
00696 file.serialCont(_FxZones);
00697 }
00698
00700 // Jobs done !
00701 return;
00702 }
00703
00704 }
00705
00706 // We reach this only if the new .primitive file format is not found
00707 // then, we try to load separate .prim file for sound, samples and fx
00708
00709 // load the sound.
00710 {
00711 CIFile file;
00712 CPrimRegion region;
00713 string fn = continent+"_audio.prim";
00714
00715 nlinfo ("loading '%s'", fn.c_str());
00716
00717 string path = CPath::lookup(fn, false);
00718
00719 if(!path.empty() && file.open (path))
00720 {
00721 CIXml xml;
00722 xml.init (file);
00723 region.serial(xml);
00724 file.close ();
00725
00726 nlinfo ("Region '%s' contains %d zones for the background sounds", continent.c_str(), region.VZones.size());
00727
00728 loadSoundsFromRegion(region);
00729 }
00730 }
00731 // load the effect.
00732 {
00733 CIFile file;
00734 CPrimRegion region;
00735 string fn = continent+"_effects.prim";
00736
00737 nlinfo ("loading '%s'", fn.c_str());
00738
00739 string path = CPath::lookup(fn, false);
00740
00741 if(!path.empty() && file.open (path))
00742 {
00743 CIXml xml;
00744 xml.init (file);
00745 region.serial(xml);
00746 file.close ();
00747
00748 nlinfo ("Region '%s' contains %d zones for the background effetcs", continent.c_str(), region.VZones.size());
00749
00750 loadEffecsFromRegion(region);
00751 }
00752 }
00753 // load the samples banks.
00754 {
00755 CIFile file;
00756 CPrimRegion region;
00757 string fn = continent+"_samples.prim";
00758
00759 nlinfo ("loading '%s'", fn.c_str());
00760
00761 string path = CPath::lookup(fn, false);
00762
00763 if(!path.empty() && file.open (path))
00764 {
00765 CIXml xml;
00766 xml.init (file);
00767 region.serial(xml);
00768 file.close ();
00769
00770 nlinfo ("Region '%s' contains %d zones for the background samples banks", continent.c_str(), region.VZones.size());
00771
00772 loadSamplesFromRegion(region);
00773 }
00774 }
00775 }
|
|
|
Load the sounds, effects and sample banks from a region class. Definition at line 272 of file background_sound_manager.cpp. References _Playing, NLLIGO::IPrimitive::getChild(), NLLIGO::IPrimitive::getNumChildren(), NLLIGO::IPrimitive::getPropertyByName(), loadEffectsFromPrimitives(), loadSamplesFromPrimitives(), loadSoundsFromPrimitives(), play(), uint, and unload(). Referenced by load(), and NLSOUND::CAudioMixerUser::loadBackgroundAudioFromPrimitives().
00273 {
00274 std::string className;
00275 if(audioRoot.getPropertyByName("class", className))
00276 {
00277 if (className == "audio")
00278 {
00279 // ok, it a root of the audio primitives
00280
00281 // remember playing state
00282 bool oldState = _Playing;
00283 unload();
00284
00285 for (uint i=0; i<audioRoot.getNumChildren(); ++i)
00286 {
00287 const NLLIGO::IPrimitive *child;
00288
00289 audioRoot.getChild(child, i);
00290
00291 if (child->getPropertyByName("class", className))
00292 {
00293 if (className == "sounds")
00294 {
00295 loadSoundsFromPrimitives(*child);
00296 }
00297 else if (className == "sample_banks")
00298 {
00299 loadSamplesFromPrimitives(*child);
00300 }
00301 else if (className == "env_fx")
00302 {
00303 loadEffectsFromPrimitives(*child);
00304 }
00305 }
00306 }
00307
00308 if (oldState)
00309 play();
00310 }
00311 }
00312 else
00313 {
00314 // try to look in the first child level
00315 for (uint i=0; i<audioRoot.getNumChildren(); ++i)
00316 {
00317 const NLLIGO::IPrimitive *child;
00318 audioRoot.getChild(child, i);
00319
00320 if (child->getPropertyByName("class", className))
00321 {
00322 if (className == "audio")
00323 {
00324 // recurse in this node
00325 loadAudioFromPrimitives(*child);
00326 // don't look any other primitives
00327 break;
00328 }
00329 }
00330 }
00331 }
00332 }
|
|
|
Load the effects from a CPrimRegion class. deprecated Definition at line 570 of file background_sound_manager.cpp. Referenced by load(), and NLSOUND::CAudioMixerUser::loadBackgroundEffectsFromRegion().
00571 {
00572 }
|
|
|
Load the sounds from primitive Definition at line 441 of file background_sound_manager.cpp. References _FxZones, addFxZone(), NLLIGO::IPrimitive::getChild(), NLLIGO::IPrimitive::getNumChildren(), NLLIGO::IPrimitive::getPropertyByName(), and uint. Referenced by loadAudioFromPrimitives().
00442 {
00443 std::string className;
00444 _FxZones.clear();
00445
00446 if (fxRoot.getPropertyByName("class", className))
00447 {
00448 if (className == "env_fx")
00449 {
00450 for (uint i=0; i<fxRoot.getNumChildren(); ++i)
00451 {
00452 const NLLIGO::IPrimitive *child;
00453 std::string primName;
00454 fxRoot.getChild(child, i);
00455
00456 if (child->getPropertyByName("class", className))
00457 {
00458 child->getPropertyByName("name", primName);
00459 if (className == "env_fx_zone")
00460 {
00461 std::string fxName;
00462 if (child->getPropertyByName("fx_name", fxName))
00463 {
00464 addFxZone(fxName, static_cast<const CPrimZone*>(child)->VPoints);
00465 }
00466 }
00467 }
00468 }
00469 }
00470 }
00471 }
|
|
|
Load the sample banks from primitive Definition at line 410 of file background_sound_manager.cpp. References addSampleBank(), NLLIGO::IPrimitive::getChild(), NLLIGO::IPrimitive::getNumChildren(), NLLIGO::IPrimitive::getPropertyByName(), and uint. Referenced by loadAudioFromPrimitives().
00411 {
00412 std::string className;
00413 _Banks.clear();
00414 if (sampleRoot.getPropertyByName("class", className))
00415 {
00416 if (className == "sample_banks")
00417 {
00418 for (uint i=0; i<sampleRoot.getNumChildren(); ++i)
00419 {
00420 const NLLIGO::IPrimitive *child;
00421 std::string primName;
00422 sampleRoot.getChild(child, i);
00423
00424 if (child->getPropertyByName("class", className))
00425 {
00426 child->getPropertyByName("name", primName);
00427 if (className == "sample_bank_zone")
00428 {
00429 const std::vector<std::string> *names;
00430 if (child->getPropertyByName("bank_names", names))
00431 {
00432 addSampleBank(*names, static_cast<const CPrimZone*>(child)->VPoints);
00433 }
00434 }
00435 }
00436 }
00437 }
00438 }
00439 }
|
|
|
Load the samples banks from a CPrimRegion class. deprecated Definition at line 537 of file background_sound_manager.cpp. References addSampleBank(), nlwarning, split(), uint, and NLLIGO::CPrimRegion::VZones. Referenced by load(), and NLSOUND::CAudioMixerUser::loadBackgroundSamplesFromRegion().
00538 {
00539 _Banks.clear();
00540
00541 for (uint i=0; i< region.VZones.size(); ++i)
00542 {
00543 if (region.VZones[i].VPoints.size() > 2)
00544 {
00545 // parse the zone name to find the samples name.
00546 std::vector<std::string> splitted = split(region.VZones[i].Name, '-');
00547 std::vector<std::string> bankNames;
00548
00549 if (splitted.size() > 2)
00550 {
00551 for (uint j=1; j<splitted.size()-1; ++j)
00552 {
00553 bankNames.push_back(splitted[j]);
00554 }
00555
00556 addSampleBank(bankNames, region.VZones[i].VPoints);
00557 }
00558 else
00559 {
00560 nlwarning ("A sample bank patatoid name did'nt contains banks name '%s'", region.VZones[i].Name.c_str());
00561 }
00562 }
00563 else
00564 {
00565 nlwarning ("A sample bank patatoid have less than 3 points '%s'", region.VZones[i].Name.c_str());
00566 }
00567 }
00568 }
|
|
|
Load the sounds from primitive Definition at line 334 of file background_sound_manager.cpp. References addSound(), NLSOUND::BACKGROUND_LAYER, NLMISC::clamp(), NLLIGO::IPrimitive::getChild(), NLLIGO::IPrimitive::getNumChildren(), NLLIGO::IPrimitive::getNumVector(), NLLIGO::IPrimitive::getPropertyByName(), nlwarning, and uint. Referenced by loadAudioFromPrimitives().
00335 {
00336 std::string className;
00337 if (soundRoot.getPropertyByName("class", className))
00338 {
00339 if (className == "sounds" || className == "sound_folder")
00340 {
00341 // ok, it sounds or a sounds foilder
00342 for (uint i=0; i<soundRoot.getNumChildren(); ++i)
00343 {
00344 const NLLIGO::IPrimitive *child;
00345 std::string primName;
00346 soundRoot.getChild(child, i);
00347
00348
00349 if (child->getPropertyByName("class", className))
00350 {
00351 uint layerId = 0;
00352 std::string layerString;
00353 std::string soundName;
00354 if (child->getPropertyByName("layer", layerString))
00355 {
00356 // extract layer number.
00357 if (!layerString.empty())
00358 {
00359 // TODO : handle special case for weather layer
00360 layerId = layerString[layerString.size()-1] - '0';
00361 }
00362 clamp(layerId, 0u, BACKGROUND_LAYER-1);
00363 }
00364
00365 child->getPropertyByName("name", primName);
00366 child->getPropertyByName("sound", soundName);
00367 // compatibility with older primitive
00368 if (soundName.empty())
00369 soundName = primName;
00370
00371 if (className == "sound_zone")
00372 {
00373 if(child->getNumVector()>2)
00374 {
00375 addSound(soundName, layerId, static_cast<const CPrimZone*>(child)->VPoints, false);
00376 }
00377 else
00378 {
00379 nlwarning ("A background sound patatoid have less than 3 points '%s'", primName.c_str());
00380 }
00381 }
00382 else if (className == "sound_path")
00383 {
00384 if(child->getNumVector() > 1)
00385 {
00386 addSound(soundName, layerId, static_cast<const CPrimPath*>(child)->VPoints, true);
00387 }
00388 else
00389 {
00390 nlwarning ("A background sound path have less than 2 points '%s'", primName.c_str());
00391 }
00392 }
00393 else if (className == "sound_point")
00394 {
00395 std::vector<NLLIGO::CPrimVector> points;
00396 points.push_back(static_cast<const CPrimPoint*>(child)->Point);
00397
00398 addSound(soundName, layerId, points, false);
00399 }
00400 else if (className == "sound_folder")
00401 {
00402 loadSoundsFromPrimitives(*child);
00403 }
00404 }
00405 }
00406 }
00407 }
00408 }
|
|
|
Load the background sounds from a CPrimRegion class. deprecated Definition at line 574 of file background_sound_manager.cpp. References _Playing, addSound(), nlwarning, play(), uint, unload(), NLLIGO::CPrimRegion::VPaths, NLLIGO::CPrimRegion::VPoints, and NLLIGO::CPrimRegion::VZones. Referenced by load(), and NLSOUND::CAudioMixerUser::loadBackgroundSoundFromRegion().
00575 {
00576 uint i;
00577 // remember playing state
00578 bool oldState = _Playing;
00579 unload();
00580
00581 for (i = 0; i < region.VZones.size(); i++)
00582 {
00583 if(region.VZones[i].VPoints.size()>2)
00584 {
00585 addSound(region.VZones[i].Name, region.VZones[i].VPoints, false);
00586 }
00587 else
00588 {
00589 nlwarning ("A background sound patatoid have less than 3 points '%s'", region.VZones[i].Name.c_str());
00590 }
00591 }
00592
00593 for (i = 0; i < region.VPaths.size(); i++)
00594 {
00595 if(region.VPaths[i].VPoints.size() > 1)
00596 {
00597 addSound(region.VPaths[i].Name, region.VPaths[i].VPoints, true);
00598 }
00599 else
00600 {
00601 nlwarning ("A background sound path have less than 2 points '%s'", region.VPaths[i].Name.c_str());
00602 }
00603 }
00604 for (i = 0; i < region.VPoints.size(); i++)
00605 {
00606 std::vector<CPrimVector> points;
00607 points.push_back(region.VPoints[i].Point);
00608
00609 addSound(region.VPoints[i].Name, points, false);
00610 }
00611
00612
00613 // restart playing ?
00614 if (oldState)
00615 play();
00616 }
|
|
|
Implements NLSOUND::CAudioMixerUser::IMixerUpdate. Definition at line 1341 of file background_sound_manager.cpp. References updateBackgroundStatus().
01342 {
01343 updateBackgroundStatus();
01344 }
|
|
|
Start to play the background sound.
Definition at line 778 of file background_sound_manager.cpp. References _BackgroundFlags, _DoFade, _FilterFadesStart, _FilterFadeValues, _Playing, NLSOUND::UAudioMixer::TBackgroundFlags::Flags, uint, and updateBackgroundStatus(). Referenced by loadAudioFromPrimitives(), loadSoundsFromRegion(), and NLSOUND::CAudioMixerUser::playBackgroundSound().
00779 {
00780 if (_Playing)
00781 return;
00782
00783 _Playing = true;
00784
00785 CAudioMixerUser::instance()->registerUpdate(this);
00786
00787 // init the filter value and filter start time
00788 for (uint i =0; i<UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i)
00789 {
00790 _FilterFadesStart[i] = 0;
00791 _FilterFadeValues[i] = 1.0f * !_BackgroundFlags.Flags[i];
00792 }
00793 // force an initial filtering
00794 _DoFade = true;
00795 updateBackgroundStatus();
00796
00797
00798 }
|
|
|
Definition at line 82 of file background_sound_manager.cpp. References _BackgroundFilterFades. Referenced by NLSOUND::CAudioMixerUser::setBackgroundFilterFades().
00083 {
00084 _BackgroundFilterFades = backgroundFilterFades;
00085 }
|
|
|
Set the background flags.
Definition at line 1312 of file background_sound_manager.cpp. References _BackgroundFilterFades, _BackgroundFlags, _DoFade, _FilterFadesStart, _FilterFadeValues, NLSOUND::UAudioMixer::TBackgroundFilterFades::FadeIns, NLSOUND::UAudioMixer::TBackgroundFilterFades::FadeOuts, NLSOUND::UAudioMixer::TBackgroundFlags::Flags, uint, and uint64. Referenced by NLSOUND::CAudioMixerUser::setBackgroundFlags().
01313 {
01314 for (uint i=0; i<UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i)
01315 {
01316 if (_BackgroundFlags.Flags[i] != backgroundFlags.Flags[i])
01317 {
01318 // the filter flags has changed !
01319 if (backgroundFlags.Flags[i])
01320 {
01321 // the filter is activated, to a fade out
01322 _FilterFadesStart[i] = uint64(NLMISC::CTime::getLocalTime() - (1-_FilterFadeValues[i]) * _BackgroundFilterFades.FadeOuts[i]);
01323 _DoFade = true;
01324 }
01325 else
01326 {
01327 // the filter is cleared, do a fade in
01328 _FilterFadesStart[i] = uint64(NLMISC::CTime::getLocalTime() - (_FilterFadeValues[i]) * _BackgroundFilterFades.FadeIns[i]);
01329 _DoFade = true;
01330 }
01331 }
01332
01333 _BackgroundFlags.Flags[i] = backgroundFlags.Flags[i];
01334 }
01335
01336 if (_DoFade)
01337 CAudioMixerUser::instance()->registerUpdate(this);
01338 }
|
|
|
Call this method when the listener position change.
Definition at line 850 of file background_sound_manager.cpp. References _LastPosition, and updateBackgroundStatus(). Referenced by NLSOUND::CAudioMixerUser::setListenerPos().
00851 {
00852 if (_LastPosition == listenerPosition)
00853 {
00854 return;
00855 }
00856 _LastPosition = listenerPosition;
00857
00858 updateBackgroundStatus();
00859 }
|
|
||||||||||||||||
|
TODO : Utility... should be in NLMISC ?
Definition at line 171 of file background_sound_manager.h. References size. Referenced by loadSamplesFromRegion().
00172 {
00173 std::vector<std::basic_string<CharType> > splitted;
00174 std::basic_string<CharType>::size_type pos = 0, nextPos = 0, size = 0;
00175
00176 while ((nextPos = str.find(splitTag, nextPos)) != std::basic_string<CharType>::npos)
00177 {
00178 size = nextPos - pos;
00179 if (size > 0)
00180 splitted.push_back(std::basic_string<CharType>(str, pos, nextPos - pos));
00181 // skip the tag
00182 nextPos += 1;
00183 pos = nextPos;
00184 }
00185 // is there a last part ?
00186 size = nextPos - pos;
00187 if (pos != str.size())
00188 splitted.push_back(std::basic_string<CharType>(str, pos, str.size() - pos));
00189
00190 return splitted;
00191 }
|
|
|
Stop the background sound.
Definition at line 801 of file background_sound_manager.cpp. References _Layers, _Playing, NLSOUND::BACKGROUND_LAYER, uint, and NLSOUND::CAudioMixerUser::unregisterUpdate(). Referenced by NLSOUND::CAudioMixerUser::stopBackgroundSound(), and unload().
00802 {
00803 if(!_Playing)
00804 return;
00805 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00806
00807 for (uint i=0; i<BACKGROUND_LAYER; ++i)
00808 {
00809 // stop all playing source
00810 std::vector<TSoundData>::iterator first(_Layers[i].begin()), last(_Layers[i].end());
00811 for (; first != last; ++first)
00812 {
00813 if (first->Source != 0 && first->Source->isPlaying())
00814 first->Source->stop();
00815 }
00816 }
00817
00818 CAudioMixerUser::instance()->unregisterUpdate(this);
00819
00820 _Playing = false;
00821 }
|
|
|
Remove all data about the current continents Definition at line 823 of file background_sound_manager.cpp. References _Layers, NLSOUND::BACKGROUND_LAYER, stop(), and uint. Referenced by loadAudioFromPrimitives(), loadSoundsFromRegion(), and ~CBackgroundSoundManager().
00824 {
00825 stop();
00826
00827 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00828
00829 for (uint i=0; i<BACKGROUND_LAYER; ++i)
00830 {
00831 // delete all created source
00832 std::vector<TSoundData>::iterator first(_Layers[i].begin()), last(_Layers[i].end());
00833 for (; first != last; ++first)
00834 {
00835 if (first->Source)
00836 // mixer->removeSource(first->Source);
00837 delete first->Source;
00838 }
00839
00840 // and free the layer.
00841 _Layers[i].clear();
00842 }
00843
00844 // erase the sample banks zone
00845 _Banks.clear();
00846
00847 // TODO : erase the fx zones
00848 }
|
|
|
Call this method to update the background sound (sub method of setListenerPosition). Status of all selected sound ordered by surface. Definition at line 861 of file background_sound_manager.cpp. References _BackgroundFilterFades, _BackgroundFlags, _DoFade, _FilterFadesStart, _FilterFadeValues, _FxZones, _LastEnv, _LastPosition, _Layers, _LoadedBanks, _Playing, NLSOUND::BACKGROUND_LAYER, NLSOUND::BACKGROUND_SOUND_ALTITUDE, NLSOUND::CSourceCommon::checkup(), NLMISC::clamp(), count, NLSOUND::CAudioMixerUser::createSource(), NLSOUND::UAudioMixer::TBackgroundFilterFades::FadeIns, NLSOUND::UAudioMixer::TBackgroundFilterFades::FadeOuts, NLSOUND::UAudioMixer::TBackgroundFlags::Flags, NLSOUND::CBackgroundSoundManager::TSoundStatus::Gain, NLSOUND::CAudioMixerUser::getClusteredSound(), NLSOUND::CClusteredSound::getClusterSoundStatus(), NLSOUND::CAudioMixerUser::getListener(), NLMISC::CTime::getLocalTime(), NLSOUND::CClusteredSound::getRootCluster(), NLSOUND::CSourceCommon::getType(), H_AFTER, H_AUTO, H_BEFORE, NLSOUND::CBackgroundSoundManager::TSoundStatus::Inside, NLSOUND::INSIDE_FALLOF, NLSOUND::CBackgroundSoundManager::TSoundData::IsPath, NLSOUND::CSourceCommon::isPlaying(), NLSOUND::CAudioMixerUser::loadSampleBank(), NLSOUND::CBackgroundSoundManager::TSoundData::MaxDist, NLSOUND::CSourceCommon::play(), NLSOUND::CBackgroundSoundManager::TSoundData::Points, NLSOUND::CBackgroundSoundManager::TSoundStatus::Position, NLSOUND::CClusteredSound::CClusterSoundStatus::Position, NLSOUND::CBackgroundSoundManager::TSoundData::Selected, NLSOUND::IListener::setEnvironment(), NL3D::CCluster::setEnvironmentFx(), NLSOUND::CSourceCommon::setPos(), NLSOUND::CSourceCommon::setRelativeGain(), NLSOUND::CBackgroundSoundManager::TSoundData::Sound, NLSOUND::CBackgroundSoundManager::TSoundStatus::SoundData, NLSOUND::CBackgroundSoundManager::TSoundData::Source, NLSOUND::CSourceCommon::stop(), NLSOUND::CBackgroundSoundManager::TSoundData::Surface, uint, NLSOUND::CAudioMixerUser::unloadSampleBank(), NLSOUND::CAudioMixerUser::unregisterUpdate(), NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. Referenced by NLSOUND::CAudioMixerUser::applyListenerMove(), onUpdate(), play(), setListenerPosition(), and NLSOUND::CAudioMixerUser::update().
00862 {
00863 H_AUTO(NLSOUND_UpdateBackgroundSound)
00864 if (!_Playing)
00865 return;
00866
00867 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00868
00869
00870 // it s on 2d so we don't have z
00871 CVector listener = _LastPosition;
00872 listener.z = 0.0f;
00873
00874 // special case for clustered sound management. If the listener is not
00875 // in the global cluster, it's background listening place could be different
00876 CClusteredSound *clusteredSound = mixer->getClusteredSound();
00877 if (clusteredSound != 0)
00878 {
00879 const CClusteredSound::CClusterSoundStatus *css = clusteredSound->getClusterSoundStatus(clusteredSound->getRootCluster());
00880 if (css != 0)
00881 {
00882 listener = css->Position;
00883 listener.z = 0.0f;
00884 }
00885 }
00886
00887 // evalutate the current env fx
00888 {
00889 H_AUTO(NLSOUND_EvaluateEnvFx)
00890 NL3D::CCluster *rootCluster = 0;
00891 if (mixer->getClusteredSound())
00892 rootCluster = mixer->getClusteredSound()->getRootCluster();
00893
00894 std::vector<TFxZone>::iterator first(_FxZones.begin()), last(_FxZones.end());
00895 for (; first != last; ++first)
00896 {
00897 if (listener.x >= first->MinBox.x && listener.x <= first->MaxBox.x
00898 && listener.y >= first->MinBox.y && listener.y <= first->MaxBox.y
00899 )
00900 {
00901 // bounding box ok,
00902 if (CPrimZone::contains(listener, first->Points))
00903 {
00904 // stop at the first zone !
00905 if (rootCluster)
00906 {
00907 // use the cluster system
00908 rootCluster->setEnvironmentFx(first->FxName);
00909 }
00910 else
00911 {
00912 // no cluster system, set the env 'manualy'
00913 IListener *drvListener = static_cast<CListenerUser*>(mixer->getListener())->getListener();
00914
00915 if (_LastEnv != first->FxName)
00916 {
00917 _LastEnv = first->FxName;
00918 uint envNum;
00919 if (first->FxName == CStringMapper::map("GENERIC"))
00920 envNum = 0;
00921 else if (first->FxName == CStringMapper::map("PADDEDCELL"))
00922 envNum = 1;
00923 else if (first->FxName == CStringMapper::map("ROOM"))
00924 envNum = 2;
00925 else if (first->FxName == CStringMapper::map("BATHROOM"))
00926 envNum = 3;
00927 else if (first->FxName == CStringMapper::map("LIVINGROOM"))
00928 envNum = 4;
00929 else if (first->FxName == CStringMapper::map("STONEROOM"))
00930 envNum = 5;
00931 else if (first->FxName == CStringMapper::map("AUDITORIUM"))
00932 envNum = 6;
00933 else if (first->FxName == CStringMapper::map("CONCERTHALL"))
00934 envNum = 7;
00935 else if (first->FxName == CStringMapper::map("CAVE"))
00936 envNum = 8;
00937 else if (first->FxName == CStringMapper::map("ARENA"))
00938 envNum = 9;
00939 else if (first->FxName == CStringMapper::map("HANGAR"))
00940 envNum = 10;
00941 else if (first->FxName == CStringMapper::map("CARPETEDHALLWAY"))
00942 envNum = 11;
00943 else if (first->FxName == CStringMapper::map("HALLWAY"))
00944 envNum = 12;
00945 else if (first->FxName == CStringMapper::map("STONECORRIDOR"))
00946 envNum = 13;
00947 else if (first->FxName == CStringMapper::map("ALLEY"))
00948 envNum = 14;
00949 else if (first->FxName == CStringMapper::map("FOREST"))
00950 envNum = 15;
00951 else if (first->FxName == CStringMapper::map("CITY"))
00952 envNum = 16;
00953 else if (first->FxName == CStringMapper::map("MOUNTAINS"))
00954 envNum = 16;
00955 else if (first->FxName == CStringMapper::map("QUARRY"))
00956 envNum = 17;
00957 else if (first->FxName == CStringMapper::map("PLAIN"))
00958 envNum = 18;
00959 else if (first->FxName == CStringMapper::map("PARKINGLOT"))
00960 envNum = 19;
00961 else if (first->FxName == CStringMapper::map("SEWERPIPE"))
00962 envNum = 20;
00963 else if (first->FxName == CStringMapper::map("UNDERWATER"))
00964 envNum = 21;
00965 else if (first->FxName == CStringMapper::map("DRUGGED"))
00966 envNum = 22;
00967 else if (first->FxName == CStringMapper::map("DIZZY"))
00968 envNum = 23;
00969 else if (first->FxName == CStringMapper::map("PSYCHOTIC"))
00970 envNum = 24;
00971 else
00972 envNum = 18;
00973
00974 drvListener->setEnvironment(envNum, 10);
00975 }
00976 }
00977 break;
00978 }
00979 }
00980 }
00981 }
00982
00983
00984 // compute the list of load/unload banks.
00985 {
00986 H_AUTO(NLSOUND_LoadUnloadSampleBank)
00987 // set of bank that must be in ram.
00988 std::set<std::string> newBanks;
00989
00990 std::vector<TBanksData>::iterator first(_Banks.begin()), last(_Banks.end());
00991 for (; first != last; ++first)
00992 {
00993 if (listener.x >= first->MinBox.x && listener.x <= first->MaxBox.x
00994 && listener.y >= first->MinBox.y && listener.y <= first->MaxBox.y
00995 )
00996 {
00997 // bounding box ok,
00998 if (CPrimZone::contains(listener, first->Points))
00999 {
01000 // add the banks of this zone in the n
01001 newBanks.insert(first->Banks.begin(), first->Banks.end());
01002 }
01003 }
01004 }
01005
01006 /* {
01007 nldebug("-----------------------------");
01008 nldebug("Loaded sample banks (%u elements):", _LoadedBanks.size());
01009 set<string>::iterator first(_LoadedBanks.begin()), last(_LoadedBanks.end());
01010 for (; first != last; ++first)
01011 {
01012 const string &str = *first;
01013 nldebug(" %s", first->c_str());
01014 }
01015 }
01016 {
01017 nldebug("New Sample bank list (%u elements):", newBanks.size());
01018 set<string>::iterator first(newBanks.begin()), last(newBanks.end());
01019 for (; first != last; ++first)
01020 {
01021 const string &str = *first;
01022 nldebug(" %s", first->c_str());
01023 }
01024 }
01025 */
01026 // ok, now compute to set : the set of bank to load, and the set of banks to unload.
01027 std::set<std::string> noChange;
01028 std::set_intersection(_LoadedBanks.begin(), _LoadedBanks.end(), newBanks.begin(), newBanks.end(), std::inserter(noChange, noChange.end()));
01029
01030 std::set<std::string> loadList;
01031 std::set_difference(newBanks.begin(), newBanks.end(), noChange.begin(), noChange.end(), std::inserter(loadList, loadList.end()));
01032
01033 std::set<std::string> unloadList;
01034 std::set_difference(_LoadedBanks.begin(), _LoadedBanks.end(), newBanks.begin(), newBanks.end(), std::inserter(unloadList, unloadList.end()));
01035
01036 // and now, load and unload....
01037 {
01038 std::set<std::string>::iterator first(loadList.begin()), last(loadList.end());
01039 for (; first != last; ++first)
01040 {
01041 // nldebug("Trying to load sample bank %s", first->c_str());
01042 mixer->loadSampleBank(true, *first);
01043 }
01044 _LoadedBanks.insert(loadList.begin(), loadList.end());
01045 }
01046 {
01047 std::set<std::string>::iterator first(unloadList.begin()), last(unloadList.end());
01048 for (; first != last; ++first)
01049 {
01050 // nldebug("Trying to unload sample bank %s", first->c_str());
01051 if (mixer->unloadSampleBank(*first))
01052 {
01053 // ok, the bank is unloaded
01054 _LoadedBanks.erase(*first);
01055 }
01056 else if (CSampleBank::findSampleBank(CStringMapper::map(*first)) == 0)
01057 {
01058 // ok, the bank is unavailable !
01059 _LoadedBanks.erase(*first);
01060 }
01061 }
01062 }
01063 }
01064
01065 H_BEFORE(NLSOUND_UpdateSoundLayer)
01066 // retreive the root cluster...
01067 NL3D::CCluster *rootCluster = 0;
01068 if (mixer->getClusteredSound() != 0)
01069 rootCluster = mixer->getClusteredSound()->getRootCluster();
01070
01071 // Apply the same algo for each sound layer.
01072 for (uint i=0; i<BACKGROUND_LAYER; ++i)
01073 {
01074 vector<TSoundData> &layer = _Layers[i];
01075 vector<uint> selectedIndex;
01076 vector<uint> leaveIndex;
01077
01078 selectedIndex.reserve(layer.size());
01079 leaveIndex.reserve(layer.size());
01080
01081 // extract the list of selected/unselected box
01082 vector<TSoundData>::iterator first(layer.begin()), last(layer.end());
01083 for (uint count = 0; first != last; ++first, ++count)
01084 {
01085 if (listener.x >= first->MinBox.x && listener.x <= first->MaxBox.x
01086 && listener.y >= first->MinBox.y && listener.y <= first->MaxBox.y
01087 // && listener.z >= first->MinBox.z && listener.z <= first->MaxBox.z
01088 )
01089 {
01090 // nldebug("patat %u is selected by box (%s)", count, first->SoundName.c_str());
01091 selectedIndex.push_back(count);
01092 }
01093 else
01094 {
01095 // nldebug("patat %u is rejected by box (%s)", count, first->SoundName.c_str());
01096 // listener out of this box.
01097 if (first->Selected && first->Source != 0)
01098 {
01099 // we leave this box.
01100 leaveIndex.push_back(count);
01101 }
01102 }
01103 }
01104
01105 // stop all the sound that are leaved.
01106 {
01107 vector<uint>::iterator first(leaveIndex.begin()), last(leaveIndex.end());
01108 for (; first != last; ++first)
01109 {
01110 TSoundData &sd = layer[*first];
01111 sd.Selected = false;
01112 if (sd.Source->isPlaying())
01113 sd.Source->stop();
01114 }
01115 }
01116 // Compute new source mixing in this layer
01117 {
01119 multimap<float, TSoundStatus> status;
01120
01121 // first loop to compute selected sound gain and position and order the result by surface..
01122 {
01123 vector<uint>::iterator first(selectedIndex.begin()), last(selectedIndex.end());
01124 for (; first != last; ++first)
01125 {
01126 TSoundData &sd = layer[*first];
01127 CVector pos;
01128 float gain = 1.0f;
01129 float distance;
01130 bool inside = false;
01131
01132 // inside the patat ?
01133
01134 if(CPrimZone::contains(listener, sd.Points, distance, pos, sd.IsPath))
01135 {
01136 inside = true;
01137 pos = _LastPosition; // use the real listener position, not the 0 z centered
01138 gain = 1.0f;
01139 // nlinfo ("inside patate %d name '%s' ", *first, sd.SoundName.c_str());
01140 }
01141 else
01142 {
01143 if (distance < sd.MaxDist)
01144 {
01145 // compute the gain.
01146 // gain = (sd.MaxDist - distance) / sd.MaxDist;
01147 }
01148 else
01149 {
01150 // too far
01151 gain = 0;
01152 }
01153 //nlinfo ("near patate %d name '%s' from %f ", *first, sd.SoundName.c_str(), distance);
01154 }
01155
01156 // store the status.
01157 status.insert(make_pair(sd.Surface, TSoundStatus(sd, pos, gain, distance, inside)));
01158 }
01159 }
01160 // second loop thrue the surface ordered selected sound.
01161 {
01162 // Sound mixing strategie :
01163 // The smallest zone sound mask bigger one
01164
01165 float maskFactor = 1.0f;
01166
01167 multimap<float, TSoundStatus>::iterator first(status.begin()), last(status.end());
01168 for (; first != last; ++first)
01169 {
01170 TSoundStatus &ss = first->second;
01171
01172 if (maskFactor > 0.0f && ss.Gain > 0)
01173 {
01174 float gain;
01175
01176 if (!ss.SoundData.IsPath && ss.SoundData.Points.size() > 1)
01177 gain = maskFactor * ss.Gain;
01178 else
01179 gain = ss.Gain;
01180
01181 // maskFactor -= ss.Gain;
01182
01183 ss.SoundData.Selected = true;
01184
01185 // if (ss.Gain == 1)
01186 // if (ss.Distance == 0)
01187 if (ss.Inside)
01188 {
01189 // inside a pattate, then decrease the mask factor will we are more inside the patate
01190 maskFactor -= first->second.Distance / INSIDE_FALLOF;
01191 clamp(maskFactor, 0.0f, 1.0f);
01192 }
01193
01194 // start the soond (if needed) and update the volume.
01195
01196 if (ss.SoundData.Source == 0)
01197 {
01198 // try to create the source.
01199 ss.SoundData.Source = static_cast<CSourceCommon*>(mixer->createSource(ss.SoundData.Sound, false, 0, 0, rootCluster));
01200 }
01201 if (ss.SoundData.Source != 0)
01202 {
01203 // set the volume
01204 ss.SoundData.Source->setRelativeGain(gain);
01205 // and the position
01206 ss.Position.z = _LastPosition.z + BACKGROUND_SOUND_ALTITUDE;
01207 ss.SoundData.Source->setPos(ss.Position);
01208
01209 // nldebug("Setting source %s at %f", ss.SoundData.SoundName.c_str(), gain);
01210 if (!ss.SoundData.Source->isPlaying())
01211 {
01212 // start the sound is needed.
01213 ss.SoundData.Source->play();
01214 }
01215 else if (ss.SoundData.Source->getType() != CSourceCommon::SOURCE_SIMPLE)
01216 ss.SoundData.Source->checkup();
01217 }
01218 }
01219 else if (ss.SoundData.Source != 0 && ss.SoundData.Source->isPlaying())
01220 {
01221 // stop this too far source.
01222 ss.SoundData.Source->stop();
01223 }
01224 }
01225 }
01226 } // compute source mixing
01227 } // for each layer
01228
01229 H_AFTER(NLSOUND_UpdateSoundLayer)
01230
01231
01232 H_BEFORE(NLSOUND_DoFadeInOut)
01233 // update the fade in / out
01234 if (_DoFade)
01235 {
01236 TTime now = NLMISC::CTime::getLocalTime();
01237 _DoFade = false;
01238 uint i;
01239
01240 //for each filter
01241 for (i=0; i< UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i)
01242 {
01243 if (_FilterFadesStart[i] != 0)
01244 {
01245 // this filter is fading
01246 if (_BackgroundFlags.Flags[i])
01247 {
01248 // fading out
01249 TTime delta = now - _FilterFadesStart[i];
01250 if (delta > _BackgroundFilterFades.FadeOuts[i])
01251 {
01252 // the fade is terminated
01253 _FilterFadeValues[i] = 0;
01254 // stop the fade for this filter
01255 _FilterFadesStart[i] = 0;
01256 }
01257 else
01258 {
01259 _FilterFadeValues[i] = 1 - (float(delta) / _BackgroundFilterFades.FadeOuts[i]);
01260 // continue to fade (at least for this filter.
01261 _DoFade |= true;
01262 }
01263 }
01264 else
01265 {
01266 // fading in
01267 TTime delta = now - _FilterFadesStart[i];
01268 if (delta > _BackgroundFilterFades.FadeIns[i])
01269 {
01270 // the fade is terminated
01271 _FilterFadeValues[i] = 1;
01272 // stop the fade for this filter
01273 _FilterFadesStart[i] = 0;
01274 }
01275 else
01276 {
01277 _FilterFadeValues[i] = float(delta) / _BackgroundFilterFades.FadeIns[i];
01278 // continue to fade (at least for this filter.
01279 _DoFade |= true;
01280 }
01281 }
01282 }
01283 }
01284
01285 // update all playing background source that filter value has changed
01286 // for each layer
01287 for (i=0; i<BACKGROUND_LAYER; ++i)
01288 {
01289 // for each patat
01290 std::vector<TSoundData>::iterator first(_Layers[i].begin()), last(_Layers[i].end());
01291 for (; first != last; ++first)
01292 {
01293 if (first->Selected)
01294 {
01295 // update this playing sound
01296 if (first->Source != 0 && first->Source->getType() == CSourceCommon::SOURCE_BACKGROUND)
01297 static_cast<CBackgroundSource*>(first->Source)->updateFilterValues(_FilterFadeValues);
01298 }
01299 }
01300
01301 }
01302
01303 if (!_DoFade)
01304 {
01305 // we can remove the update.
01306 mixer->unregisterUpdate(this);
01307 }
01308 }
01309 H_AFTER(NLSOUND_DoFadeInOut)
01310 }
|
|
|
Definition at line 147 of file background_sound_manager.h. |
|
|
Background filters fades.
Definition at line 200 of file background_sound_manager.h. Referenced by getBackgroundFilterFades(), setBackgroundFilterFades(), setBackgroundFlags(), and updateBackgroundStatus(). |
|
|
Background flags.
Definition at line 198 of file background_sound_manager.h. Referenced by CBackgroundSoundManager(), getBackgroundFlags(), play(), setBackgroundFlags(), and updateBackgroundStatus(). |
|
|
Container for the banks primitive.
Definition at line 229 of file background_sound_manager.h. |
|
|
Is some fade in/out running?
Definition at line 206 of file background_sound_manager.h. Referenced by play(), setBackgroundFlags(), and updateBackgroundStatus(). |
|
|
The date of last fade in or out started for each filter.
Definition at line 202 of file background_sound_manager.h. Referenced by CBackgroundSoundManager(), play(), setBackgroundFlags(), and updateBackgroundStatus(). |
|
|
The filter fade values.
Definition at line 204 of file background_sound_manager.h. Referenced by CBackgroundSoundManager(), getFilterValues(), play(), setBackgroundFlags(), and updateBackgroundStatus(). |
|
|
Container for the fx primitive.
Definition at line 305 of file background_sound_manager.h. Referenced by addFxZone(), load(), loadEffectsFromPrimitives(), and updateBackgroundStatus(). |
|
|
Last setted env fx. Used when clustered sound is not active.
Definition at line 307 of file background_sound_manager.h. Referenced by updateBackgroundStatus(). |
|
|
The last position of the listener.
Definition at line 209 of file background_sound_manager.h. Referenced by setListenerPosition(), and updateBackgroundStatus(). |
|
|
Array of vector of sound data.
Definition at line 265 of file background_sound_manager.h. Referenced by addSound(), load(), stop(), unload(), and updateBackgroundStatus(). |
|
|
Container for the list of currently loaded banks.
Definition at line 231 of file background_sound_manager.h. Referenced by updateBackgroundStatus(). |
|
|
Flag for playing background sounds.
Definition at line 195 of file background_sound_manager.h. Referenced by loadAudioFromPrimitives(), loadSoundsFromRegion(), play(), stop(), and updateBackgroundStatus(). |
1.3.6