NLSOUND::CBackgroundSoundManager Class Reference

#include <background_sound_manager.h>

Inheritance diagram for NLSOUND::CBackgroundSoundManager:

NLSOUND::CAudioMixerUser::IMixerUpdate

Detailed Description

This manager handle the background sound :

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.

Author:
Boris Boucher

Nevrax France

Date:
2002

Definition at line 79 of file background_sound_manager.h.

Public Member Functions

const UAudioMixer::TBackgroundFilterFadesgetBackgroundFilterFades ()
const UAudioMixer::TBackgroundFlagsgetBackgroundFlags ()
 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 &region)
void loadSamplesFromRegion (const NLLIGO::CPrimRegion &region)
void loadSoundsFromRegion (const NLLIGO::CPrimRegion &region)
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 & Destructor Documentation

NLSOUND::CBackgroundSoundManager::CBackgroundSoundManager  )  [private]
 

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 }

NLSOUND::CBackgroundSoundManager::~CBackgroundSoundManager  )  [private, virtual]
 

Destructor.

Definition at line 71 of file background_sound_manager.cpp.

References unload().

00072 {
00073         unload();
00074 }


Member Function Documentation

void NLSOUND::CBackgroundSoundManager::addFxZone const std::string &  fxName,
const std::vector< NLLIGO::CPrimVector > &  points
[private]
 

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 }

void NLSOUND::CBackgroundSoundManager::addSampleBank const std::vector< std::string > &  bankNames,
const std::vector< NLLIGO::CPrimVector > &  points
[private]
 

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 }

void NLSOUND::CBackgroundSoundManager::addSound const std::string &  rawSoundName,
const std::vector< NLLIGO::CPrimVector > &  points,
bool  isPath
[private]
 

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 }

void NLSOUND::CBackgroundSoundManager::addSound const std::string &  soundName,
uint  layerId,
const std::vector< NLLIGO::CPrimVector > &  points,
bool  isPath
[private]
 

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 }

const UAudioMixer::TBackgroundFilterFades & NLSOUND::CBackgroundSoundManager::getBackgroundFilterFades  ) 
 

Definition at line 87 of file background_sound_manager.cpp.

References _BackgroundFilterFades.

Referenced by NLSOUND::CAudioMixerUser::getBackgroundFilterFades().

00088 {
00089         return _BackgroundFilterFades;
00090 }

const UAudioMixer::TBackgroundFlags & NLSOUND::CBackgroundSoundManager::getBackgroundFlags  ) 
 

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 }

const float* NLSOUND::CBackgroundSoundManager::getFilterValues  )  [inline]
 

Definition at line 139 of file background_sound_manager.h.

References _FilterFadeValues.

Referenced by NLSOUND::CBackgroundSource::play().

00139 { return _FilterFadeValues;}

const std::vector<NLMISC::CVector>& NLSOUND::CBackgroundSoundManager::getZone uint32  zone,
bool *  isPath = 0
 

Return a patatoid. If isPath is not null, set it.

CVector NLSOUND::CBackgroundSoundManager::getZoneSourcePos uint32  zone  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::load const std::string &  continent,
NLLIGO::CLigoConfig config
 

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 }

void NLSOUND::CBackgroundSoundManager::loadAudioFromPrimitives const NLLIGO::IPrimitive audioRoot  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::loadEffecsFromRegion const NLLIGO::CPrimRegion region  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::loadEffectsFromPrimitives const NLLIGO::IPrimitive fxRoot  )  [private]
 

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 }

void NLSOUND::CBackgroundSoundManager::loadSamplesFromPrimitives const NLLIGO::IPrimitive sampleRoot  )  [private]
 

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 }

void NLSOUND::CBackgroundSoundManager::loadSamplesFromRegion const NLLIGO::CPrimRegion region  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::loadSoundsFromPrimitives const NLLIGO::IPrimitive soundRoot  )  [private]
 

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 }

void NLSOUND::CBackgroundSoundManager::loadSoundsFromRegion const NLLIGO::CPrimRegion region  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::onUpdate  )  [private, virtual]
 

Implements NLSOUND::CAudioMixerUser::IMixerUpdate.

Definition at line 1341 of file background_sound_manager.cpp.

References updateBackgroundStatus().

01342 {
01343         updateBackgroundStatus();
01344 }

void NLSOUND::CBackgroundSoundManager::play  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::setBackgroundFilterFades const UAudioMixer::TBackgroundFilterFades backgroundFilterFades  ) 
 

Definition at line 82 of file background_sound_manager.cpp.

References _BackgroundFilterFades.

Referenced by NLSOUND::CAudioMixerUser::setBackgroundFilterFades().

00083 {
00084         _BackgroundFilterFades = backgroundFilterFades;
00085 }

void NLSOUND::CBackgroundSoundManager::setBackgroundFlags const UAudioMixer::TBackgroundFlags backgroundFlags  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::setListenerPosition const NLMISC::CVector listenerPosition  ) 
 

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 }

template<class CharType>
std::vector<std::basic_string<CharType> > NLSOUND::CBackgroundSoundManager::split const std::basic_string< CharType > &  str,
CharType  splitTag
[inline, private]
 

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         }

void NLSOUND::CBackgroundSoundManager::stop  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::unload  ) 
 

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 }

void NLSOUND::CBackgroundSoundManager::updateBackgroundStatus  ) 
 

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 }


Friends And Related Function Documentation

friend class CAudioMixerUser [friend]
 

Definition at line 147 of file background_sound_manager.h.


Field Documentation

UAudioMixer::TBackgroundFilterFades NLSOUND::CBackgroundSoundManager::_BackgroundFilterFades [private]
 

Background filters fades.

Definition at line 200 of file background_sound_manager.h.

Referenced by getBackgroundFilterFades(), setBackgroundFilterFades(), setBackgroundFlags(), and updateBackgroundStatus().

UAudioMixer::TBackgroundFlags NLSOUND::CBackgroundSoundManager::_BackgroundFlags [private]
 

Background flags.

Definition at line 198 of file background_sound_manager.h.

Referenced by CBackgroundSoundManager(), getBackgroundFlags(), play(), setBackgroundFlags(), and updateBackgroundStatus().

std::vector<TBanksData> NLSOUND::CBackgroundSoundManager::_Banks [private]
 

Container for the banks primitive.

Definition at line 229 of file background_sound_manager.h.

bool NLSOUND::CBackgroundSoundManager::_DoFade [private]
 

Is some fade in/out running?

Definition at line 206 of file background_sound_manager.h.

Referenced by play(), setBackgroundFlags(), and updateBackgroundStatus().

NLMISC::TTime NLSOUND::CBackgroundSoundManager::_FilterFadesStart[UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS] [private]
 

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().

float NLSOUND::CBackgroundSoundManager::_FilterFadeValues[UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS] [private]
 

The filter fade values.

Definition at line 204 of file background_sound_manager.h.

Referenced by CBackgroundSoundManager(), getFilterValues(), play(), setBackgroundFlags(), and updateBackgroundStatus().

std::vector<TFxZone> NLSOUND::CBackgroundSoundManager::_FxZones [private]
 

Container for the fx primitive.

Definition at line 305 of file background_sound_manager.h.

Referenced by addFxZone(), load(), loadEffectsFromPrimitives(), and updateBackgroundStatus().

NLMISC::TStringId NLSOUND::CBackgroundSoundManager::_LastEnv [private]
 

Last setted env fx. Used when clustered sound is not active.

Definition at line 307 of file background_sound_manager.h.

Referenced by updateBackgroundStatus().

NLMISC::CVector NLSOUND::CBackgroundSoundManager::_LastPosition [private]
 

The last position of the listener.

Definition at line 209 of file background_sound_manager.h.

Referenced by setListenerPosition(), and updateBackgroundStatus().

std::vector<TSoundData> NLSOUND::CBackgroundSoundManager::_Layers[BACKGROUND_LAYER] [private]
 

Array of vector of sound data.

Definition at line 265 of file background_sound_manager.h.

Referenced by addSound(), load(), stop(), unload(), and updateBackgroundStatus().

std::set<std::string> NLSOUND::CBackgroundSoundManager::_LoadedBanks [private]
 

Container for the list of currently loaded banks.

Definition at line 231 of file background_sound_manager.h.

Referenced by updateBackgroundStatus().

bool NLSOUND::CBackgroundSoundManager::_Playing [private]
 

Flag for playing background sounds.

Definition at line 195 of file background_sound_manager.h.

Referenced by loadAudioFromPrimitives(), loadSoundsFromRegion(), play(), stop(), and updateBackgroundStatus().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 14:31:47 2004 for NeL by doxygen 1.3.6