From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/audio__mixer__user_8cpp-source.html | 1410 ++++++++++++++++++++ 1 file changed, 1410 insertions(+) create mode 100644 docs/doxygen/nel/audio__mixer__user_8cpp-source.html (limited to 'docs/doxygen/nel/audio__mixer__user_8cpp-source.html') diff --git a/docs/doxygen/nel/audio__mixer__user_8cpp-source.html b/docs/doxygen/nel/audio__mixer__user_8cpp-source.html new file mode 100644 index 00000000..49451df0 --- /dev/null +++ b/docs/doxygen/nel/audio__mixer__user_8cpp-source.html @@ -0,0 +1,1410 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

audio_mixer_user.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdsound.h"
+00027 
+00028 //#include "env_sound_user.h"
+00029 //#include "env_effect.h"
+00030 #include "simple_sound.h"
+00031 #include "complex_sound.h"
+00032 //#include "ambiant_source.h"
+00033 //#include "bounding_sphere.h"
+00034 //#include "bounding_box.h"
+00035 #include "driver/buffer.h"
+00036 #include "sample_bank.h"
+00037 #include "sound_bank.h"
+00038 #include "background_sound_manager.h"
+00039 #include "simple_source.h"
+00040 #include "complex_source.h"
+00041 #include "background_source.h"
+00042 
+00043 
+00044 #include "nel/misc/file.h"
+00045 #include "nel/misc/path.h"
+00046 #include "nel/misc/time_nl.h"
+00047 #include "nel/misc/command.h"
+00048 
+00049 #include "context_sound.h"
+00050 #include <iomanip.h>
+00051 
+00052 //#include <crtdbg.h>
+00053 
+00054 using namespace NLMISC;
+00055 
+00056 using namespace std;
+00057 
+00058 
+00059 namespace NLSOUND {
+00060 
+00061 
+00062 #ifdef _DEBUG
+00063 CAudioMixerUser::IMixerEvent    *CurrentEvent = 0;
+00064 #endif
+00065 
+00066 
+00067 #define NL_TRACE_MIXER 0
+00068 
+00069 #if NL_TRACE_MIXER
+00070 #define _profile(_a) nldebug ## _a
+00071 #else
+00072 #define _profile(_a) 
+00073 #endif
+00074 
+00075 // The audio mixer singleton instance
+00076 CAudioMixerUser         *CAudioMixerUser::_Instance = NULL;
+00077 
+00078 // Return the priority cstring (debug info)
+00079 const char *PriToCStr [NbSoundPriorities] = { "XH", "HI", "MD", "LO" };
+00080 
+00081 
+00082 // ******************************************************************
+00083 
+00084 const char *getPriorityStr( TSoundPriority p )
+00085 {
+00086         nlassert( ((uint)p) < NbSoundPriorities );
+00087         return PriToCStr[p];
+00088 }
+00089 
+00090 
+00091 // ******************************************************************
+00092 
+00093 UAudioMixer     *UAudioMixer::createAudioMixer()
+00094 {
+00095         return new CAudioMixerUser();
+00096 }
+00097 
+00098 
+00099 // ******************************************************************
+00100 
+00101 CAudioMixerUser::CAudioMixerUser() : _SoundDriver(NULL),
+00102                                                                          _ListenPosition(CVector::Null),
+00103 //                                                                       _EnvSounds(NULL),
+00104 //                                                                       _BalancePeriod(0),
+00105                                                                          _CurEnvEffect(NULL),
+00106                                                                          _NbTracks(0),
+00107                                                                          _MaxNbTracks(0),
+00108                                                                          _Leaving(false),
+00109                                                                          _BackgroundSoundManager(0),
+00110                                                                          _PlayingSources(0)
+00111 {
+00112         if ( _Instance == NULL )
+00113         {
+00114                 _Instance = this;
+00115 
+00116 #if NL_PROFILE_MIXER
+00117                 _UpdateTime = 0.0;
+00118                 _CreateTime = 0.0;
+00119                 _UpdateCount = 0;
+00120                 _CreateCount = 0;
+00121 #endif
+00122 
+00123         }
+00124         else
+00125         {
+00126                 nlerror( "Audio mixer singleton instanciated twice" );
+00127         }
+00128 }
+00129 
+00130 
+00131 // ******************************************************************
+00132 
+00133 CAudioMixerUser::~CAudioMixerUser()
+00134 {
+00135         nldebug( "AM: Releasing..." );
+00136 
+00137         if (_BackgroundSoundManager != 0)
+00138                 delete _BackgroundSoundManager;
+00139 //      CBackgroundSoundManager::release();
+00140 
+00141         reset();
+00142 
+00143         _Leaving = true;
+00144 
+00145         // Release the sound bank
+00146         CSoundBank::release();
+00147         // Release all the SampleBanks
+00148         CSampleBank::releaseAll();
+00149 
+00150         // Tracks
+00151         uint i;
+00152         for ( i=0; i!=_NbTracks; i++ )
+00153         {
+00154                 if ( _Tracks[i] )
+00155                         delete _Tracks[i];
+00156         }
+00157 
+00158         // Sound driver
+00159         if ( _SoundDriver != NULL )
+00160                 delete _SoundDriver;
+00161 
+00162         _Instance = NULL;
+00163 
+00164         nldebug( "AM: Released" );
+00165 }
+00166 
+00167 
+00168 void CAudioMixerUser::setPriorityReserve(TSoundPriority priorityChannel, uint reserve)
+00169 {
+00170         _PriorityReserve[priorityChannel] = min(_NbTracks, reserve);
+00171 }
+00172 
+00173 void CAudioMixerUser::setLowWaterMark(uint value)
+00174 {
+00175         _LowWaterMark = min(_NbTracks, value);
+00176 }
+00177 
+00178 
+00179 // ******************************************************************
+00180 
+00181 void                            CAudioMixerUser::writeProfile(std::ostream& out)
+00182 {
+00183         // compute number of muted source
+00184         uint nb = 0;    
+00185         
+00186 /*      TSourceContainer::iterator first(_Sources.begin()), last(_Sources.end());
+00187         for (; first != last; ++first)
+00188         {
+00189                 CSimpleSource *psu = *first;
+00190                 if (psu->getTrack() == NULL)
+00191                 {
+00192                         ++nb;
+00193                 }
+00194         }
+00195 */
+00196 /*      hash_set<CSimpleSource*>::const_iterator ips;
+00197         for ( ips=_Sources.begin(); ips!=_Sources.end(); ++ips )
+00198         {
+00199                 CSimpleSource *psu = *ips;
+00200                 if (psu->getTrack() == NULL)
+00201                 {
+00202                         ++nb;
+00203                 }
+00204         }
+00205 */
+00206         out << "Mixer: \n";
+00207         out << "Playing sources: " << getPlayingSourcesNumber() << " \n";
+00208         out << "Available tracks: " << getNumberAvailableTracks() << " \n";
+00209 //      out << "Muted sources: " << nb << " \n";
+00210 //      out << "Muted sources: " << max(0, sint(_PlayingSources.size())-sint(_NbTracks)) << " \n";
+00211         out << "Muted sources: " << max(0, sint(_PlayingSources)-sint(_NbTracks)) << " \n";
+00212         out << "Sources waiting for play: " << _SourceWaitingForPlay.size() << " \n";
+00213         out << "HighestPri: " << _ReserveUsage[HighestPri] << " \n";
+00214         out << "HighPri: " << _ReserveUsage[HighPri] << " \n";
+00215         out << "MidPri: " << _ReserveUsage[MidPri] << " \n";
+00216         out << "LowPri: " << _ReserveUsage[LowPri] << " \n";
+00217         out << "Average update time: " << std::setw(10) << (1000.0 * _UpdateTime / _UpdateCount) << " msec\n";
+00218         out << "Average create time: " << std::setw(10) <<(1000.0 * _CreateTime / _CreateCount) << " msec\n";
+00219         out << "Estimated CPU: " << std::setiosflags(ios::right) << std::setprecision(6) << std::setw(10) << (100.0 * 1000.0 * (_UpdateTime + _CreateTime) / curTime()) << "%\n";
+00220 
+00221         if (_SoundDriver)
+00222         {
+00223                 out << "\n";
+00224                 out << "Driver: \n";
+00225                 _SoundDriver->writeProfile(out);
+00226         }
+00227 }
+00228 
+00229 // ******************************************************************
+00230 
+00231 void    CAudioMixerUser::addSourceWaitingForPlay(CSimpleSource *source)
+00232 {
+00233         _SourceWaitingForPlay.push_back(source);
+00234 }
+00235 
+00236 
+00237 // ******************************************************************
+00238 
+00239 void                            CAudioMixerUser::reset()
+00240 {
+00241         _Leaving = true;
+00242 
+00243         _SourceWaitingForPlay.clear();
+00244 
+00245         // Stop tracks
+00246         uint i;
+00247         for ( i=0; i!=_NbTracks; i++ )
+00248         {
+00249                 if ( _Tracks[i] )
+00250                 {
+00251                         CSimpleSource* src = _Tracks[i]->getSource();
+00252 
+00253                         if (src && src->isPlaying())
+00254                         {
+00255                                 src->stop();
+00256                         }
+00257                 }
+00258         }
+00259 
+00260         // Sources
+00261         while (!_Sources.empty())
+00262         {
+00263                 //removeSource( _Sources.begin(), true ); // 3D sources, the envsounds were removed above
+00264                 CSourceCommon *source = *(_Sources.begin());
+00265                 if (source->isPlaying())
+00266                         source->stop();
+00267                 else
+00268                         delete source;
+00269         }
+00270 
+00271         _Leaving = false;
+00272 }
+00273 
+00274 // ******************************************************************
+00275 
+00276 void                            CAudioMixerUser::init( /*uint32 balance_period */)
+00277 {
+00278         nldebug( "AM: Init..." );
+00279 
+00280         _profile(( "AM: ---------------------------------------------------------------" ));
+00281         _profile(( "AM: DRIVER: %s", NLSOUND_DLL_NAME ));
+00282         
+00283         // Init sound driver
+00284         try
+00285         {
+00286                 _SoundDriver = ISoundDriver::createDriver();
+00287         }
+00288         catch(...)
+00289         {
+00290                 delete this;
+00291                 _Instance = NULL;
+00292                 throw;
+00293         }
+00294 
+00295         uint i;
+00296 
+00297 
+00298         // Init registrable classes
+00299         static bool initialized = false;
+00300         if (!initialized)
+00301         {
+00302 //              CSimpleSource::init();
+00303                 initialized = true;
+00304         }
+00305 
+00306         // Init listener
+00307         _Listener.init( _SoundDriver );
+00308 
+00309         // Init tracks (physical sources)
+00310         _NbTracks = MAX_TRACKS; // could be chosen by the user, or according to the capabilities of the sound card
+00311         for ( i=0; i<MAX_TRACKS; i++ )
+00312         {
+00313                 _Tracks[i] = NULL;
+00314         }
+00315         try
+00316         {
+00317                 for ( i=0; i!=_NbTracks; i++ )
+00318                 {
+00319                         _Tracks[i] = new CTrack();
+00320                         _Tracks[i]->init( _SoundDriver );
+00321                         _FreeTracks.push_back(_Tracks[i]);
+00322                 }
+00323         }
+00324         catch ( ESoundDriver & )
+00325         {
+00326                 // If the source generation failed, keep only the generated number of sources
+00327                 _NbTracks = i;
+00328                 //delete _Tracks[i]; // Bug: the desctructor would not work because the source's name is invalid
+00329         }
+00330 
+00331         _MaxNbTracks = _NbTracks;
+00332 
+00333         // Init the reserve stuff.
+00334         _LowWaterMark = 0;
+00335         for (i=0; i<NbSoundPriorities; ++i)
+00336         {
+00337                 _PriorityReserve[i] = _NbTracks;
+00338                 _ReserveUsage[i] = 0;
+00339         }
+00340         
+00341         _StartTime = CTime::getLocalTime();
+00342 
+00343         // Create the background sound manager.
+00344         _BackgroundSoundManager = new CBackgroundSoundManager();
+00345 
+00346         // Load the sound bank singleton
+00347         CSoundBank::instance()->load();
+00348         nlinfo( "Initialized audio mixer with %u voices", _NbTracks );
+00349 }
+00350 
+00351 
+00352 // ******************************************************************
+00353 void    CAudioMixerUser::bufferUnloaded(IBuffer *buffer)
+00354 {
+00355         // check all track to find a track playing this buffer.
+00356         uint i;
+00357         for ( i=0; i!=_NbTracks; ++i )
+00358         {
+00359                 CTrack  *track = _Tracks[i];
+00360                 if ( track && track->getSource())
+00361                 {
+00362                         if (track->getSource()->getBuffer() == buffer)
+00363                         {
+00364                                 track->getSource()->stop();
+00365                         }
+00366                 }
+00367         }
+00368 
+00369 }
+00370 
+00371 
+00372 // ******************************************************************
+00373 
+00374 void                            CAudioMixerUser::enable( bool b )
+00375 {
+00376         // TODO :  rewrite this method
+00377 
+00378         nlassert(false);
+00379 /*      if ( b )
+00380         {
+00381                 // Reenable
+00382                 _NbTracks = _MaxNbTracks;
+00383         }
+00384         else
+00385         {
+00386                 // Disable
+00387                 uint i;
+00388                 for ( i=0; i!=_NbTracks; i++ )
+00389                 {
+00390                         if ( _Tracks[i] && ! _Tracks[i]->isAvailable() )
+00391                         {
+00392                                 _Tracks[i]->getSource()->leaveTrack();
+00393 //                              nlassert(_PlayingSources.find(_Tracks[i]->getSource()) != _PlayingSources.end());
+00394 //                              _PlayingSources.erase(_Tracks[i]->getSource());
+00395                         }
+00396                 }
+00397                 _NbTracks = 0;
+00398         }
+00399 */
+00400 }
+00401 
+00402 // ******************************************************************
+00403 
+00404 ISoundDriver*           CAudioMixerUser::getSoundDriver()
+00405 {
+00406         return _SoundDriver;
+00407 }
+00408 
+00409 // ******************************************************************
+00410 
+00411 /*void                          CAudioMixerUser::computeEnvEffect( const CVector& listenerpos, bool force )
+00412 {
+00413         // Find the first matching, linear search
+00414         vector<CEnvEffect*>::iterator ipe;
+00415         for ( ipe=_EnvEffects.begin(); ipe!=_EnvEffects.end(); ++ipe )
+00416         {
+00417                 if ( (*ipe)->include( listenerpos ) )
+00418                 {
+00419                         // Set the effect only if it has changed
+00420                         if ( (_CurEnvEffect != *ipe) || force )
+00421                         {
+00422                                 _CurEnvEffect = *ipe;
+00423                                 _Listener.getListener()->setEnvironment( _CurEnvEffect->getEnvNum(), _CurEnvEffect->getEnvSize() );
+00424                                 nldebug( "AM: Listener environmental effect changed to %u", _CurEnvEffect->getEnvNum() );
+00425                         }
+00426                         return;
+00427                 }
+00428         }
+00429 
+00430         // If not found, set the default (only if it wasn't the default before)
+00431         if ( _CurEnvEffect != NULL )
+00432         {
+00433                 _Listener.getListener()->setEnvironment( ENVFX_DEFAULT_NUM );
+00434                 _CurEnvEffect = NULL;
+00435                 nldebug( "AM: Listener environmental effect reset" );
+00436         }
+00437 
+00438 }
+00439 */
+00440 
+00441 
+00442 // ******************************************************************
+00443 
+00444 void                            CAudioMixerUser::getFreeTracks( uint nb, CTrack **tracks )
+00445 {
+00446         std::vector<CTrack*>::iterator first(_FreeTracks.begin()), last(_FreeTracks.end());
+00447         for (nb =0; first != last; ++first, ++nb)
+00448         {
+00449                 tracks[nb] = *first;
+00450         }
+00451 }
+00452 
+00453  
+00454 // ******************************************************************
+00455 
+00456 void                            CAudioMixerUser::applyListenerMove( const NLMISC::CVector& listenerpos )
+00457 {
+00458         // Store position
+00459         _ListenPosition = listenerpos;
+00460 
+00461         // Environmental effect
+00462 //      computeEnvEffect( listenerpos );
+00463 
+00464 /*      // Environment sounds
+00465         if ( _EnvSounds != NULL )
+00466         {
+00467                 _EnvSounds->recompute();
+00468         }
+00469 */
+00470 }
+00471 
+00472 // ******************************************************************
+00473 
+00474 void                            CAudioMixerUser::reloadSampleBanks(bool async)
+00475 {
+00476         CSampleBank::reload(async);
+00477 }
+00478 
+00479 // ******************************************************************
+00480 
+00481 CTrack *CAudioMixerUser::getFreeTrack(CSimpleSource *source)
+00482 {
+00483         // at least some track free ?
+00484         if      (!_FreeTracks.empty())
+00485         {
+00486                 // under the low water mark or  under the reserve
+00487                 if (_FreeTracks.size() > _LowWaterMark          
+00488                                 || _ReserveUsage[source->getPriority()] < _PriorityReserve[source->getPriority()] )
+00489                 {
+00490                         // non discardable track  or not too many waiting source
+00491                         if (source->getPriority() == HighestPri         
+00492                                 || _FreeTracks.size() > _SourceWaitingForPlay.size())
+00493                         {
+00494                                 CTrack *ret = _FreeTracks.back();
+00495                                 _FreeTracks.pop_back();
+00496                                 ret->setSource(source);
+00497                                 _ReserveUsage[source->getPriority()]++;
+00498 //                              nldebug("Track %p assign to source %p", ret, ret->getSource());
+00499                                 return ret;
+00500                         }
+00501                 }
+00502         }
+00503         // try to find a track with a source cuttable
+00504         {
+00505                 float d1, d2, t1, t2;
+00506                 d1 = (source->getPos() - _ListenPosition).norm();
+00507                 t1 = max(0.0f, 1-((d1-source->getSimpleSound()->getMinDistance()) / (source->getSimpleSound()->getMaxDistance() - source->getSimpleSound()->getMinDistance())));
+00508 
+00509                 for (uint i=0; i<_NbTracks; ++i)
+00510                 {
+00511                         CSimpleSource *src2 = _Tracks[i]->getSource();
+00512                         if (src2 != 0)
+00513                         {
+00514                                 d2 = (src2->getPos() - _ListenPosition).norm();
+00515                                 t2 = max(0.0f, 1-((d2-src2->getSimpleSound()->getMinDistance()) / (src2->getSimpleSound()->getMaxDistance() - src2->getSimpleSound()->getMinDistance())));
+00516 
+00517                                 const float tfactor = 1.3f;
+00518                                 if (t1 > t2 * tfactor)
+00519 //                              if (d1 < d2)
+00520                                 {
+00521                                         nldebug("Cutting source %p with source %p (%f > %f*%f)", src2, source, t1, tfactor, t2);
+00522                                         // on peut cuter cette voie !
+00523                                         src2->stop();
+00524                                         if (_FreeTracks.empty())
+00525                                         {
+00526                                                 nlwarning("No free track after cutting a playing sound source !");
+00527                                         }
+00528                                         else
+00529                                         {
+00530                                                 CTrack *ret = _FreeTracks.back();
+00531                                                 _FreeTracks.pop_back();
+00532                                                 ret->setSource(source);
+00533                                                 nldebug("Track %p assign to source %p", ret, ret->getSource());
+00534                                                 return ret;
+00535                                         }
+00536                                 }
+00537                         }
+00538                 }
+00539         }
+00540 
+00541         return 0;
+00542 }
+00543 
+00544 void CAudioMixerUser::freeTrack(CTrack *track)
+00545 {
+00546         nlassert(track != 0);
+00547         nlassert(track->getSource() != 0);
+00548 
+00549 //      nldebug("Track %p free by source %p", track, track->getSource());
+00550 
+00551         _ReserveUsage[track->getSource()->getPriority()]--;
+00552         track->setSource(0);
+00553         _FreeTracks.push_back(track);
+00554 }
+00555 
+00556 
+00557 void CAudioMixerUser::getPlayingSoundsPos(std::vector<std::pair<bool, NLMISC::CVector> > &pos)
+00558 {
+00559         int nbplay = 0;
+00560         int     nbmute = 0;
+00561         int     nbsrc = 0;
+00562 
+00563         TSourceContainer::iterator first(_Sources.begin()), last(_Sources.end());
+00564         for (; first != last; ++first)
+00565         {
+00566                 CSourceCommon *ps = *first;
+00567                 if (ps->getType() == CSourceCommon::SOURCE_SIMPLE)
+00568                 {
+00569                         CSimpleSource *source = static_cast<CSimpleSource*>(*first);
+00570                         nbsrc++;
+00571 
+00572                         if (source->isPlaying())
+00573                         {
+00574                                 pos.push_back(make_pair(source->getTrack() == 0, source->getPos()));
+00575 
+00576                                 if (source->getTrack() == 0)
+00577                                         nbmute++;
+00578                                 else
+00579                                 {
+00580 //                                      nldebug ("Source %p playing on track %p", source, source->getTrack());
+00581                                         nbplay ++;
+00582                                 }
+00583                         }
+00584                 }
+00585         }
+00586 
+00587 //      nldebug("Total source : %d, playing : %d, muted : %d", nbsrc, nbplay, nbmute);
+00588 }
+00589 
+00590 
+00591 
+00592 void                            CAudioMixerUser::update()
+00593 {
+00594 #if NL_PROFILE_MIXER
+00595         TTicks start = CTime::getPerformanceTime();
+00596 #endif
+00597 
+00598         // update the object.
+00599         {
+00600                 // 1st, update the event list
+00601                 {
+00602                         std::vector<std::pair<IMixerUpdate*, bool> >::iterator first(_UpdateEventList.begin()), last(_UpdateEventList.end());
+00603                         for (; first != last; ++first)
+00604                         {
+00605                                 if (first->second)
+00606                                         _UpdateList.insert(first->first);
+00607                                 else
+00608                                         _UpdateList.erase(first->first);
+00609                         }
+00610                         _UpdateEventList.clear();
+00611                 }
+00612                 // 2nd, do the update
+00613                 {
+00614                         TMixerUpdateContainer::iterator first(_UpdateList.begin()), last(_UpdateList.end());
+00615                         for (; first != last; ++first)
+00616                         {
+00617                                 // call the update method.
+00618                                 const_cast<IMixerUpdate*>(*first)->onUpdate();
+00619                         }
+00620                 }
+00621         }
+00622         // send the event.
+00623         {
+00624                 // 1st, update the event list
+00625                 {
+00626                         std::vector<std::pair<NLMISC::TTime, IMixerEvent*> >::iterator first(_EventListUpdate.begin()), last(_EventListUpdate.end());
+00627                         for (; first != last; ++first)
+00628                         {
+00629                                 if (first->first != 0)
+00630                                 {
+00631                                         // add an event
+00632 //                                      nldebug ("Add event %p", first->second);
+00633                                         TTimedEventContainer::iterator it(_EventList.insert(*first));
+00634                                         _Events.insert(make_pair(first->second, it));
+00635                                 }
+00636                                 else
+00637                                 {
+00638                                         // remove the events
+00639                                         pair<TEventContainer::iterator, TEventContainer::iterator> range = _Events.equal_range(first->second);
+00640                                         TEventContainer::iterator first2(range.first), last2(range.second);
+00641                                         for (; first2 != last2; ++first2)
+00642                                         {
+00643                                                 // remove the event
+00644                                                 nldebug("Remove event %p", first2->second->second);
+00645                                                 _EventList.erase(first2->second);
+00646                                         }
+00647                                         _Events.erase(range.first, range.second);
+00648                                 }
+00649                         }
+00650 
+00651                         _EventListUpdate.clear();
+00652                 }
+00653                 // 2nd, call the events
+00654                 TTime now = NLMISC::CTime::getLocalTime();
+00655                 while (!_EventList.empty() && _EventList.begin()->first <= now)
+00656                 {
+00657 #ifdef _DEBUG
+00658                         CurrentEvent = _EventList.begin()->second;
+00659 #endif
+00660 //                      nldebug("Sending Event %p", _EventList.begin()->second);
+00661                         _EventList.begin()->second->onEvent();
+00662                         TEventContainer::iterator it(_Events.lower_bound(_EventList.begin()->second));
+00663                         while (it->first == _EventList.begin()->second)
+00664                         {
+00665                                 if (it->second == _EventList.begin())
+00666                                 {
+00667                                         _Events.erase(it);
+00668                                         break;
+00669                                 }
+00670                                 it++;
+00671                         }
+00672                         _EventList.erase(_EventList.begin());
+00673 #ifdef _DEBUG
+00674                         CurrentEvent = 0;
+00675 #endif
+00676                 }
+00677         }
+00678 
+00679         // update the background sound
+00680 //      _BackgroundSoundManager->update();
+00681 
+00682         // Check all playing track and stop any terminated buffer.
+00683         for (uint i=0; i<_NbTracks; ++i)
+00684         {
+00685                 if (!_Tracks[i]->isPlaying())
+00686                 {
+00687                         if (_Tracks[i]->getSource() != 0)
+00688                         {
+00689                                 CSimpleSource *source = _Tracks[i]->getSource();
+00690                                 source->stop();
+00691                         }
+00692         
+00693                         // try to play any waiting source.
+00694                         if (!_SourceWaitingForPlay.empty())
+00695                         {
+00696                                 // check if the source still exist before trying to play it
+00697                                 if (_Sources.find(_SourceWaitingForPlay.front()) != _Sources.end())
+00698                                         _SourceWaitingForPlay.front()->play();
+00699                                 nldebug("Before POP Sources waiting : %u", _SourceWaitingForPlay.size());
+00700                                 _SourceWaitingForPlay.pop_front();
+00701                                 nldebug("After POP Sources waiting : %u", _SourceWaitingForPlay.size());
+00702                         }
+00703                 }
+00704         }
+00705 
+00706         // Debug info
+00707         /*uint32 i;
+00708         nldebug( "List of the %u tracks", _NbTracks );
+00709         for ( i=0; i!=_NbTracks; i++ )
+00710         {
+00711                 CSimpleSource *su;
+00712                 if ( su = _Tracks[i]->getSource() )
+00713                 {
+00714                         nldebug( "%u: %p %s %s %s %s, vol %u",
+00715                                     i, &_Tracks[i]->DrvSource, _Tracks[i]->isAvailable()?"FREE":"USED",
+00716                                         _Tracks[i]->isAvailable()?"":(su->isPlaying()?"PLAYING":"STOPPED"),
+00717                                         _Tracks[i]->isAvailable()?"":PriToCStr[su->getPriority()],
+00718                                         _Tracks[i]->isAvailable()?"":(su->getSound()?su->getSound()->getFilename().c_str():""),
+00719                                         (uint)(su->getGain()*100.0f) );
+00720                 }
+00721         }*/
+00722 
+00723         _SoundDriver->commit3DChanges();
+00724 
+00725 #if NL_PROFILE_MIXER
+00726         _UpdateTime = CTime::ticksToSecond(CTime::getPerformanceTime() - start);
+00727         _UpdateCount++;
+00728 #endif
+00729 
+00730 /*      // display the track using...
+00731         {
+00732                 char tmp[2048] = "";
+00733                 string str;
+00734 
+00735                 for (uint i=0; i<_NbTracks/2; ++i)
+00736                 {
+00737                         sprintf(tmp, "[%2u]%8p ", i, _Tracks[i]->getSource());
+00738                         str += tmp;
+00739                 }
+00740                 nldebug((string("Status1: ")+str).c_str());
+00741                 str = "";
+00742                 for (i=_NbTracks/2; i<_NbTracks; ++i)
+00743                 {
+00744                         sprintf(tmp, "[%2u]%8p ", i, _Tracks[i]->getSource());
+00745                         str += tmp;
+00746                 }
+00747 //              nldebug((string("Status2: ")+str).c_str());
+00748         }
+00749 */
+00750 }
+00751 
+00752 
+00753 // ******************************************************************
+00754 
+00755 TSoundId                        CAudioMixerUser::getSoundId( const std::string &name )
+00756 {
+00757         return CSoundBank::instance()->getSound(name);
+00758 }
+00759 
+00760 // ******************************************************************
+00761 
+00762 void                            CAudioMixerUser::addSource( CSourceCommon *source )
+00763 { 
+00764         nlassert(_Sources.find(source) == _Sources.end());
+00765         _Sources.insert( source ); 
+00766 
+00767 //      _profile(( "AM: ADDSOURCE, SOUND: %d, TRACK: %p, NAME=%s", source->getSound(), source->getTrack(),
+00768 //                      source->getSound() && (source->getSound()->getName()!="") ? source->getSound()->getName().c_str() : "" ));
+00769 
+00770 }
+00771 
+00772 
+00773 // ******************************************************************
+00774 
+00775 USource                         *CAudioMixerUser::createSource( TSoundId id, bool spawn, TSpawnEndCallback cb, void *userParam, CSoundContext *context )
+00776 {
+00777 #if NL_PROFILE_MIXER
+00778         TTicks start = CTime::getPerformanceTime();
+00779 #endif
+00780 
+00781         _profile(( "AM: [%u]---------------------------------------------------------------", curTime() ));
+00782         _profile(( "AM: CREATESOURCE: SOUND=%p, NAME=%s, TIME=%d", id, id->getName().c_str(), curTime() ));
+00783         _profile(( "AM: SOURCES: %d, PLAYING: %d, TRACKS: %d", getSourcesNumber(), getPlayingSourcesNumber(), getNumberAvailableTracks() ));
+00784 
+00785         if ( id == NULL )
+00786         {
+00787                 _profile(("AM: FAILED CREATESOURCE"));
+00788                 nldebug( "AM: Sound not created: invalid sound id" );
+00789                 return NULL;
+00790         }
+00791 
+00792         USource *ret = NULL;
+00793 
+00794         if (id->getSoundType() == CSound::SOUND_SIMPLE)
+00795         {
+00796                 CSimpleSound    *simpleSound = static_cast<CSimpleSound *>(id);
+00797                 // This is a simple sound
+00798                 if (simpleSound->getBuffer() == NULL)
+00799                 {
+00800                         nlwarning ("Can't create the sound '%s'", simpleSound->getBuffername().c_str());
+00801                         return NULL;
+00802                 }
+00803 
+00804                 // Create source
+00805                 CSimpleSource *source = new CSimpleSource( simpleSound, spawn, cb, userParam);
+00806 
+00807 //              nldebug("Mixer : source %p created", source);
+00808 
+00809                 if (source->getBuffer() != 0)
+00810                 {
+00811                         // Link the position to the listener position if it'a stereo source
+00812                         if ( source->getBuffer()->isStereo() )
+00813                         {
+00814                                 source->set3DPositionVector( &_ListenPosition );
+00815                         }
+00816                 }
+00817                 else
+00818                 {
+00819                         nlassert(false); // FIXME
+00820                 }
+00821                 ret = source;
+00822         }
+00823         else if (id->getSoundType() == CSound::SOUND_COMPLEX)
+00824         {
+00825                 CComplexSound   *complexSound = static_cast<CComplexSound*>(id);
+00826                 // This is a pattern sound.
+00827                 ret =  new CComplexSource(complexSound, spawn, cb, userParam);
+00828         }
+00829         else if (id->getSoundType() == CSound::SOUND_BACKGROUND)
+00830         {
+00831                 // This is a background sound.
+00832                 CBackgroundSound        *bgSound = static_cast<CBackgroundSound *>(id);
+00833                 ret = new CBackgroundSource(bgSound, spawn, cb, userParam);
+00834         }
+00835         else if (id->getSoundType() == CSound::SOUND_CONTEXT)
+00836         {
+00837                 // This is a context sound.
+00838                 if (context != 0)
+00839                 {
+00840                         CContextSound   *ctxSound = static_cast<CContextSound   *>(id);
+00841         //              nlassert(context != 0);
+00842                         CSound                  *sound = ctxSound->getContextSound(*context);
+00843                         if (sound != 0)
+00844                         {
+00845                                 ret = createSource(sound, spawn, cb, userParam);
+00846                                 // Set the volume of the source according to the context volume
+00847                                 if (ret != 0)
+00848                                         ret->setGain(ret->getGain() * ctxSound->getGain());
+00849                         }
+00850                         else 
+00851                                 ret = 0;
+00852                 }
+00853                 else
+00854                         ret = 0;
+00855         }
+00856         else
+00857         {
+00858 //              nlassertex(false, ("Unknown sound class !"));
+00859                 nlwarning("Unknow sound class : %u", id->getSoundType());
+00860         }
+00861 
+00862 #if NL_PROFILE_MIXER
+00863         _CreateTime = CTime::ticksToSecond(CTime::getPerformanceTime() - start);
+00864         _CreateCount++;
+00865 #endif
+00866 
+00867         //nldebug( "AM: Source created" ); 
+00868         return ret;                                             
+00869 }
+00870 
+00871 
+00872 // ******************************************************************
+00873 
+00874 USource                         *CAudioMixerUser::createSource( const std::string &name, bool spawn, TSpawnEndCallback cb, void *userParam, CSoundContext *context)
+00875 {
+00876         return createSource( getSoundId( name ), spawn, cb, userParam, context );
+00877 }
+00878 
+00879 
+00880 // ******************************************************************
+00881 
+00882 void                            CAudioMixerUser::removeSource( CSourceCommon *source )
+00883 {
+00884         nlassert( source != NULL );
+00885         
+00886         size_t n = _Sources.erase(source);
+00887         nlassert(n == 1);
+00888 }
+00889 
+00890 
+00891 // ******************************************************************
+00892 
+00893 void                            CAudioMixerUser::selectEnvEffects( const std::string &tag )
+00894 {
+00895         nlassertex(false, ("Not implemented yet"));
+00896 /*      // Select Env
+00897         vector<CEnvEffect*>::iterator ipe;
+00898         for ( ipe=_EnvEffects.begin(); ipe!=_EnvEffects.end(); ++ipe )
+00899         {
+00900                 (*ipe)->selectEnv( tag );
+00901         }
+00902 
+00903         // Compute
+00904         CVector pos;
+00905         _Listener.getPos( pos );
+00906         computeEnvEffect( pos, true );
+00907 */
+00908 }
+00909 
+00910 
+00911 // ******************************************************************
+00912 
+00913 /*
+00914 void                            CAudioMixerUser::loadEnvEffects( const char *filename )
+00915 {
+00916         nlassert( filename != NULL );
+00917         nlinfo( "Loading environmental effects from %s...", filename );
+00918 
+00919         // Unload previous env effects
+00920         vector<CEnvEffect*>::iterator ipe;
+00921         for ( ipe=_EnvEffects.begin(); ipe!=_EnvEffects.end(); ++ipe )
+00922         {
+00923                 delete (*ipe);
+00924         }
+00925         _EnvEffects.clear();
+00926 
+00927         string str = CPath::lookup( filename, false );
+00928 
+00929         // Load env effects
+00930         CIFile file;
+00931         if ( !str.empty() && file.open(str) )
+00932         {
+00933                 uint32 n = CEnvEffect::load( _EnvEffects, file );
+00934                 nldebug( "AM: Loaded %u environmental effects", n );
+00935         }
+00936         else
+00937         {
+00938                 nlwarning( "AM: Environmental effects file not found" );
+00939         }
+00940 }
+00941 */
+00942 
+00943 // ******************************************************************
+00944 
+00945 uint32                  CAudioMixerUser::loadSampleBank(bool async, const std::string &filename, std::vector<std::string> *notfoundfiles )
+00946 {
+00947 //      nlassert( filename != NULL );
+00948 
+00949         string path = _SamplePath;
+00950         path.append("/").append(filename);
+00951 
+00952         nldebug( "Loading samples from %s...", path.c_str() );
+00953 
+00954         CSampleBank* bank = CSampleBank::findSampleBank(path);
+00955         if (bank == NULL)
+00956         {
+00957                 // create a new sample bank
+00958 //_CrtCheckMemory();
+00959                 bank = new CSampleBank(path, _SoundDriver);
+00960 //_CrtCheckMemory();
+00961         }
+00962 
+00963         try 
+00964         {
+00965                 bank->load(async);
+00966         }
+00967         catch (Exception& e)
+00968         {
+00969                 if (notfoundfiles) {
+00970                         notfoundfiles->push_back(path);
+00971                 }
+00972                 string reason = e.what();
+00973                 nlwarning( "AM: Failed to load the samples: %s", reason.c_str() );
+00974         }
+00975 
+00976 
+00977         return bank->countSamples();
+00978 }
+00979 
+00980 bool CAudioMixerUser::unloadSampleBank( const std::string &filename)
+00981 {
+00982         string path = _SamplePath;
+00983         path.append("/").append(filename);
+00984 
+00985         nldebug( "Unloading samples from %s...", path.c_str() );
+00986         CSampleBank *pbank = CSampleBank::findSampleBank(path);
+00987 
+00988         if (pbank != NULL)
+00989         {
+00990                 // ok, the bank exist.
+00991                 return pbank->unload();
+00992         }
+00993         else
+00994                 return false;
+00995 
+00996 }
+00997 
+00998 // ******************************************************************
+00999 
+01000 void                    CAudioMixerUser::getSoundNames( std::vector<std::string>& names ) const
+01001 {
+01002         CSoundBank::instance()->getNames(names);
+01003 }
+01004 
+01005 
+01006 // ******************************************************************
+01007 
+01008 uint                    CAudioMixerUser::getPlayingSourcesNumber() const
+01009 {
+01010         return _PlayingSources;
+01011 }
+01012 
+01013 // ******************************************************************
+01014 
+01015 uint                    CAudioMixerUser::getNumberAvailableTracks() const
+01016 {
+01017         return _FreeTracks.size();
+01018 }
+01019 
+01020 
+01021 // ******************************************************************
+01022 
+01023 string                  CAudioMixerUser::getSourcesStats() const
+01024 {
+01025         // TODO : rewrite log output
+01026 
+01027         string s;
+01028         TSourceContainer::iterator ips;
+01029         for ( ips=_Sources.begin(); ips!=_Sources.end(); ++ips )
+01030         {
+01031                 if ( (*ips)->isPlaying() )
+01032                 {
+01033 //                      char line [80];
+01034 
+01035 /*                      nlassert( (*ips)->getSound() && (*ips)->getSimpleSound()->getBuffer() );
+01036                         smprintf( line, 80, "%s: %u%% %s %s",
+01037                                           (*ips)->getSound()->getName().c_str(),
+01038                                           (uint32)((*ips)->getGain()*100.0f),
+01039                                           (*ips)->getBuffer()->isStereo()?"ST":"MO",
+01040                                           PriToCStr[(*ips)->getPriority()] );
+01041                         s += string(line) + "\n";
+01042 */              }
+01043         }
+01044         return s;
+01045 
+01046 }
+01047 
+01048 // ******************************************************************
+01049 /*
+01050 void                    CAudioMixerUser::loadEnvSounds( const char *filename, UEnvSound **treeRoot )
+01051 {
+01052         nlassert( filename != NULL );
+01053         nlinfo( "Loading environment sounds from %s...", filename );
+01054 
+01055         string str = CPath::lookup( filename, false );
+01056 
+01057         CIFile file;
+01058         if ( !str.empty() && file.open( str ) )
+01059         {
+01060                 uint32 n = 0; //CEnvSoundUser::load( _EnvSounds, file );
+01061                 nldebug( "AM: Loaded %u environment sounds", n );
+01062         }
+01063         else
+01064         {
+01065                 nlwarning( "AM: Environment sounds file not found: %s", filename );
+01066         }
+01067         if ( treeRoot != NULL )
+01068         {
+01069                 *treeRoot = _EnvSounds;
+01070         }
+01071 }
+01072 */
+01073 
+01074 // ******************************************************************
+01075 
+01076 struct CompareSources : public binary_function<const CSimpleSource*, const CSimpleSource*, bool>
+01077 {
+01078         // Constructor
+01079         CompareSources( const CVector &pos ) : _Pos(pos) {}
+01080 
+01081         // Operator()
+01082         bool operator()( const CSimpleSource *s1, const CSimpleSource *s2 )
+01083         {
+01084                 if (s1->getPriority() < s2->getPriority())
+01085                 {
+01086                         return true;
+01087                 }
+01088                 else if (s1->getPriority() == s2->getPriority())
+01089                 {
+01090                         // Equal priority, test distances to the listener
+01091                         const CVector &src1pos = s1->getPos();
+01092                         const CVector &src2pos = s2->getPos();;
+01093                         return ( (src1pos-_Pos).sqrnorm() < (src2pos-_Pos).sqrnorm() );
+01094                 }
+01095                 else
+01096                 {
+01097                         return false;
+01098                 }
+01099         }
+01100 
+01101         // Listener pos
+01102         const CVector &_Pos;
+01103 };
+01104 
+01105 
+01106 // ******************************************************************
+01107 uint32                  CAudioMixerUser::getLoadedSampleSize()
+01108 {
+01109         return CSampleBank::getTotalByteSize();
+01110 }
+01111 
+01112 
+01113 // ******************************************************************
+01114 /*
+01115 void                    CAudioMixerUser::redispatchSourcesToTrack()
+01116 {
+01117 */      // TODO : rewrite ?
+01118 /*
+01119         if ( _NbTracks == 0 )
+01120         {
+01121                 return;
+01122         }
+01123 
+01124         _profile(( "AM: [%u]---------------------------------------------------------------", curTime() ));
+01125         _profile(( "AM: Redispatching sources" ));
+01126         
+01127         const CVector &listenerpos = _Listener.getPos();
+01128 
+01129         // Get a copy of the sources set (we will modify it)
+01130         static TSourceContainer sources_copy; 
+01131         sources_copy = _PlayingSources;
+01132         // FIXME: SWAPTEST
+01133         //nlassert( sources_copy.size() >= _NbTracks );
+01134 
+01135         // Select the nbtracks "smallest" sources (the ones that have the higher priorities)
+01136         TSourceContainer::iterator ips;
+01137         static TSourceContainer selected_sources;
+01138         uint32 i;
+01139 
+01140         selected_sources.clear();
+01141 
+01142         // Select the sources
+01143 
+01144         // Select the nbtracks "smallest" sources (the ones that have the higher priorities)
+01145         // FIXME: SWAPTEST
+01146         //for ( i=0; i!=_NbTracks; i++ )
+01147         // TODO : optimize : this is a very BAD PERFORMANCE code
+01148         while (!sources_copy.empty() && (selected_sources.size() < _NbTracks))
+01149         {
+01150                 ips = min_element( sources_copy.begin(), sources_copy.end(), CompareSources( listenerpos ) );
+01151 
+01152                 if ((*ips)->isPlaying())
+01153                 {
+01154                         selected_sources.insert( *ips );
+01155                 }
+01156 
+01157                 sources_copy.erase( ips );
+01158         }
+01159 
+01160         // Clear the current tracks where the sources are not selected anymore
+01161         _profile(( "AM: Total sources: %u", _PlayingSources.size() ));
+01162         _profile(( "AM: Selected sources: %u", selected_sources.size() ));
+01163         for ( i=0; i!=_NbTracks; i++ )
+01164         {
+01165                 // FIXME: SWAPTEST
+01166                 if ( _Tracks[i] && ! _Tracks[i]->isAvailable() )
+01167                 {
+01168                         // Optimization note: instead of searching the source in selected_sources, we could have
+01169                         // set a boolean in the source object and tested it.
+01170                         if ( (ips = selected_sources.find( _Tracks[i]->getSource() )) == selected_sources.end() )
+01171                         {
+01172                                 // There will be a new source in this track
+01173                                 _profile(( "AM: TRACK: %p: REPLACED, SOURCE: %p", _Tracks[i], _Tracks[i]->getSource() ));
+01174                                 if (_Tracks[i]->getSource() != 0)
+01175                                 {
+01176                                         _Tracks[i]->getSource()->leaveTrack();
+01177 //                                      nlassert(_PlayingSources.find(_Tracks[i]->getSource()) != _PlayingSources.end());
+01178                                         _PlayingSources.erase(_Tracks[i]->getSource());
+01179                                 }
+01180                         }
+01181                         else
+01182                         {
+01183                                 // The track will remain unchanged
+01184                                 selected_sources.erase( ips );
+01185                                 _profile(( "AM: TRACK: %p: UNCHANGED, SOURCE: %p", _Tracks[i], _Tracks[i]->getSource() ));
+01186                         }
+01187                 }
+01188                 else
+01189                 {
+01190                         _profile(( "AM: TRACK: %p: FREE", _Tracks[i] ));
+01191                 }
+01192         }
+01193 
+01194         if (!selected_sources.empty())
+01195         {
+01196                 // Now, only the sources to add into the tracks remain in selected_sources
+01197                 CTrack *track [MAX_TRACKS]; // a little bit more than needed (avoiding a "new")
+01198                 getFreeTracks( selected_sources.size(), track );
+01199 
+01200                 _profile(( "AM: Remaining sources: %u", selected_sources.size() ));
+01201 
+01202                 for (i=0, ips=selected_sources.begin(); ips!=selected_sources.end(); ++ips )
+01203                 {
+01204                         // FIXME: SWAPTEST
+01205                         (*ips)->enterTrack( track[i] );
+01206 //                      nlassert(_PlayingSources.find(*ips) == _PlayingSources.end());
+01207 //                      _PlayingSources.insert(*ips);
+01208         //              _profile(( "AM: TRACK: %p: ASSIGNED, SOURCE: %p", track[i], track[i]->getSource() ));
+01209                         _profile(( "AM: TRACK: %p: ASSIGNED, SOURCE: %p", track[i], *ips ));
+01210                         i++;
+01211                 }
+01212         }
+01213 */
+01214 //}
+01215 
+01216 void CAudioMixerUser::setListenerPos (const NLMISC::CVector &pos)
+01217 {
+01218         _Listener.setPos(pos);
+01219         _BackgroundSoundManager->setListenerPosition(pos);
+01220 }
+01221 
+01222 NLMISC_COMMAND (displaySoundInfo, "Display information about the audio mixer", "")
+01223 {
+01224         if(args.size() != 0) return false;
+01225 
+01226         if (CAudioMixerUser::instance() == NULL)
+01227         {
+01228                 log.displayNL ("No audio mixer available");
+01229                 return true;
+01230         }
+01231 
+01232         log.displayNL ("%d tracks, MAX_TRACKS = %d, contains:", CAudioMixerUser::instance()->_NbTracks, MAX_TRACKS);
+01233 
+01234         for (uint i = 0; i < CAudioMixerUser::instance()->_NbTracks; i++)
+01235         {
+01236                 if (CAudioMixerUser::instance()->_Tracks[i] == NULL)
+01237                 {
+01238                         log.displayNL ("Track %d is NULL", i);
+01239                 }
+01240                 else
+01241                 {
+01242                         log.displayNL ("Track %d %s available and %s playing.", i, (CAudioMixerUser::instance()->_Tracks[i]->isAvailable()?"is":"is not"), (CAudioMixerUser::instance()->_Tracks[i]->isPlaying()?"is":"is not"));
+01243                         if (CAudioMixerUser::instance()->_Tracks[i]->getSource() == NULL)
+01244                         {
+01245                                 log.displayNL ("    CUserSource is NULL");
+01246                         }
+01247                         else
+01248                         {
+01249                                 const CVector &pos = CAudioMixerUser::instance()->_Tracks[i]->getSource()->getPos();
+01250                                 string bufname;
+01251                                 if (CAudioMixerUser::instance()->_Tracks[i]->getSource()->getBuffer())
+01252                                         bufname = CAudioMixerUser::instance()->_Tracks[i]->getSource()->getBuffer()->getName();
+01253                                 log.displayNL ("    CUserSource is id %d buffer name '%s' pos %f %f %f", CAudioMixerUser::instance()->_Tracks[i]->getSource()->getSound(), bufname.c_str(), pos.x, pos.y, pos.z);
+01254                         }
+01255                 }
+01256         }
+01257 
+01258         return true;
+01259 }
+01260 
+01261 void CAudioMixerUser::registerBufferAssoc(CSound *sound, IBuffer *buffer)
+01262 {
+01263         _BufferToSources[buffer].push_back(sound);
+01264 }
+01265 
+01266 void CAudioMixerUser::unregisterBufferAssoc(CSound *sound, IBuffer *buffer)
+01267 {
+01268         TBufferToSourceContainer::iterator it(_BufferToSources.find(buffer));
+01269         if (it != _BufferToSources.end())
+01270         {
+01271                 std::vector<CSound*>::iterator first(it->second.begin()), last(it->second.end());
+01272 
+01273                 for (; first != last; ++first)
+01274                 {
+01275                         if (*first == sound)
+01276                         {
+01277                                 it->second.erase(first);
+01278                                 break;
+01279                         }
+01280                 }
+01281         }
+01282 }
+01283 
+01284 
+01286 void CAudioMixerUser::registerUpdate(CAudioMixerUser::IMixerUpdate *pmixerUpdate)
+01287 {
+01288         _UpdateEventList.push_back(make_pair(pmixerUpdate, true));
+01289 }
+01291 void CAudioMixerUser::unregisterUpdate(CAudioMixerUser::IMixerUpdate *pmixerUpdate)
+01292 {
+01293         _UpdateEventList.push_back(make_pair(pmixerUpdate, false));
+01294 }
+01295 
+01297 void CAudioMixerUser::addEvent( CAudioMixerUser::IMixerEvent *pmixerEvent, const NLMISC::TTime &date)
+01298 {
+01299 //      nldebug("Adding event %p", pmixerEvent);
+01300         _EventListUpdate.push_back(make_pair(date, pmixerEvent));
+01301 }
+01303 void CAudioMixerUser::removeEvents( CAudioMixerUser::IMixerEvent *pmixerEvent)
+01304 {
+01305 //      nldebug("Removing event %p", pmixerEvent);
+01306         // store the pointer fot future removal.
+01307         _EventListUpdate.push_back(make_pair(0, pmixerEvent));
+01308 }
+01309 
+01310 void CAudioMixerUser::setBackgroundFlags(const TBackgroundFlags &backgroundFlags)
+01311 {
+01312         _BackgroundSoundManager->setBackgroundFlags(backgroundFlags);
+01313 }
+01314 
+01315 void CAudioMixerUser::loadBackgroundSoundFromRegion (const NLLIGO::CPrimRegion &region)
+01316 {
+01317         _BackgroundSoundManager->loadSoundsFromRegion(region);
+01318 }
+01319 
+01320 void CAudioMixerUser::loadBackgroundEffectsFromRegion (const NLLIGO::CPrimRegion &region)
+01321 {
+01322         _BackgroundSoundManager->loadEffecsFromRegion(region);
+01323 }
+01324 void CAudioMixerUser::loadBackgroundSamplesFromRegion (const NLLIGO::CPrimRegion &region)
+01325 {
+01326         _BackgroundSoundManager->loadSamplesFromRegion(region);
+01327 }
+01328 
+01329 
+01330 void CAudioMixerUser::playBackgroundSound () 
+01331 { 
+01332         _BackgroundSoundManager->play (); 
+01333 }
+01334 
+01335 void CAudioMixerUser::stopBackgroundSound () 
+01336 { 
+01337         _BackgroundSoundManager->stop (); 
+01338 }
+01339 
+01340 void CAudioMixerUser::loadBackgroundSound (const std::string &continent) 
+01341 { 
+01342         _BackgroundSoundManager->load (continent); 
+01343 }
+01344 
+01345 } // NLSOUND
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1