00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef NL_AUDIO_MIXER_USER_H
00025 #define NL_AUDIO_MIXER_USER_H
00026 #include <nel/misc/types_nl.h>
00027
00028 #include <vector>
00029 #include <list>
00030 #include <numeric>
00031
00032 #include <nel/misc/time_nl.h>
00033 #include <nel/misc/stream.h>
00034 #include <nel/misc/singleton.h>
00035 #include <nel/sound/u_audio_mixer.h>
00036 #include <nel/georges/u_form.h>
00037
00038 #include "driver/source.h"
00039 #include "listener_user.h"
00040
00041 #include "mixing_track.h"
00042 #include "sound.h"
00043 #include "music_channel_fader.h"
00044
00045 namespace NLLIGO {
00046 class CLigoConfig;
00047 }
00048
00049 namespace NLSOUND {
00050 class CSimpleSource;
00051 class CEnvSoundUser;
00052 class CEnvEffect;
00053 class CSoundBank;
00054 class CSourceCommon;
00055 class CClusteredSound;
00056 class CBackgroundSoundManager;
00057 class CMusicSoundManager;
00058 class IReverbEffect;
00059
00061 template <class Pointer>
00062 struct THashPtr : public std::unary_function<const Pointer &, size_t>
00063 {
00064 static const size_t bucket_size = 4;
00065 static const size_t min_buckets = 8;
00066 size_t operator () (const Pointer &ptr) const
00067 {
00068
00069
00070
00071 return (size_t)(uintptr_t)ptr;
00072 }
00073 inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const
00074 {
00075
00076 return (uintptr_t)ptr1 < (uintptr_t)ptr2;
00077 }
00078 };
00079
00102 class CAudioMixerUser : public UAudioMixer, public ISoundDriver::IStringMapperProvider, public NLMISC::CManualSingleton<CAudioMixerUser>
00103 {
00104 public:
00105
00107 CAudioMixerUser();
00109 static CAudioMixerUser *instance() { return getInstance(); }
00111 virtual ~CAudioMixerUser();
00112
00114
00115
00116 NLMISC::TStringId map(const std::string &str) { return NLMISC::CStringMapper::map(str);}
00118 const std::string &unmap(const NLMISC::TStringId &stringId) { return NLMISC::CStringMapper::unmap(stringId);}
00120
00121
00130 virtual void init(uint maxTrack, bool useEax, bool useADPCM, NLMISC::IProgressCallback *progressCallBack, bool autoLoadSample, TDriver driverType, bool forceSoftwareBuffer, bool manualRolloff = true);
00131
00132 virtual void initClusteredSound(NL3D::UScene *uscene, float minGain, float maxDistance, float portalInterpolate);
00133 virtual void initClusteredSound(NL3D::CScene *scene, float minGain, float maxDistance, float portalInterpolate);
00134
00147 virtual void setPriorityReserve(TSoundPriority priorityChannel, size_t reserve);
00160 virtual void setLowWaterMark(size_t value);
00161
00162 virtual void changeMaxTrack(uint maxTrack);
00163
00165 virtual void reset();
00167 virtual void enable( bool b );
00169
00170
00171 void buildSampleBankList();
00172 bool useAPDCM() { return _UseADPCM;};
00177 virtual uint32 loadSampleBank(bool async, const std::string &name, std::vector<std::string> *notfoundfiles=NULL );
00180 virtual bool unloadSampleBank( const std::string &name);
00181 virtual void reloadSampleBanks(bool async);
00182 virtual uint32 getLoadedSampleSize();
00183 virtual void getLoadedSampleBankInfo(std::vector<std::pair<std::string, uint> > &result);
00184
00185
00186
00188
00189
00190
00191
00192
00194 virtual TSoundId getSoundId( const NLMISC::TStringId &name );
00195
00196
00203 virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 );
00205 virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 );
00207 void addSource( CSourceCommon *source );
00211 virtual void removeSource( CSourceCommon *source );
00212
00214
00216
00217
00221 virtual void setListenerPos (const NLMISC::CVector &pos);
00222
00224 virtual UListener *getListener() { return &_Listener; }
00225
00226
00228 virtual void selectEnvEffects( const std::string &tag );
00230 virtual void update();
00231
00232
00234 virtual void getSoundNames( std::vector<NLMISC::TStringId> &names ) const;
00236 virtual uint getPolyphony() const { return _Tracks.size(); }
00238 virtual uint getSourcesInstanceCount() const { return _Sources.size(); }
00240 virtual uint getPlayingSourcesCount() const;
00242 virtual uint getAvailableTracksCount() const;
00244 virtual uint getUsedTracksCount() const;
00246 virtual uint getMutedPlayingSourcesCount() const { return _PlayingSourcesMuted; }
00247
00249 virtual std::string getSourcesStats() const;
00250
00251
00253 void applyListenerMove( const NLMISC::CVector& listenerpos );
00255
00257 const NLMISC::CVector& getListenPosVector() const { return _ListenPosition; }
00261
00263
00264
00265
00266
00268 virtual void setSamplePath(const std::string& path);
00269 virtual void setPackedSheetOption(const std::string &path, bool update);
00270 std::string &getPackedSheetPath() {return _PackedSheetPath; }
00271 bool getPackedSheetUpdate() {return _UpdatePackedSheet; }
00272
00273
00274 CBackgroundSoundManager *getBackgroundSoundManager() { return _BackgroundSoundManager; }
00276 virtual void writeProfile(std::string& out);
00277
00278 virtual void setBackgroundFlagName(uint flagIndex, const std::string &flagName);
00279 virtual void setBackgroundFlagShortName(uint flagIndex, const std::string &flagShortName);
00280 virtual const std::string &getBackgroundFlagName(uint flagIndex);
00281 virtual const std::string &getBackgroundFlagShortName(uint flagIndex);
00282
00283
00284
00285 virtual void loadBackgroundAudioFromPrimitives(const NLLIGO::IPrimitive &audioRoot);
00286 virtual void loadBackgroundSound (const std::string &continent, NLLIGO::CLigoConfig &config);
00287 virtual void playBackgroundSound ();
00288 virtual void stopBackgroundSound ();
00289
00290 CClusteredSound *getClusteredSound() { return _ClusteredSound; }
00291
00292
00293
00295 ISoundDriver* getSoundDriver();
00296
00297 void registerBufferAssoc(CSound *sound, IBuffer *buffer);
00298 void unregisterBufferAssoc(CSound *sound, IBuffer *buffer);
00299
00300 void bufferUnloaded(IBuffer *buffer);
00301
00302 void setBackgroundFlags(const TBackgroundFlags &backgroundFlags);
00303 void setBackgroundFilterFades(const TBackgroundFilterFades &backgroundFilterFades);
00304 const TBackgroundFlags &getBackgroundFlags();
00305 const TBackgroundFilterFades &getBackgroundFilterFades();
00306
00307
00308
00309
00310
00312 CTrack *getFreeTrack(CSimpleSource *source);
00314 void freeTrack(CTrack *track);
00315
00317 CTrack *getFreeTrackWithoutSource(bool steal);
00319 void freeTrackWithoutSource(CTrack *track);
00320
00321 void incPlayingSource() { ++_PlayingSources; };
00322 void decPlayingSource() { --_PlayingSources; };
00323 void incPlayingSourceMuted() { ++_PlayingSourcesMuted; };
00324 void decPlayingSourceMuted() { --_PlayingSourcesMuted; };
00325
00326 void setUserVar(NLMISC::TStringId varName, float value);
00327 float getUserVar(NLMISC::TStringId varName);
00328
00329
00330 virtual bool playMusic(const std::string &fileName, uint xFadeTime= 0, bool async= true, bool loop=true);
00331 virtual void stopMusic(uint xFadeTime= 0);
00332 virtual void pauseMusic();
00333 virtual void resumeMusic();
00334 virtual bool isMusicEnded();
00335 virtual void setMusicVolume(float gain);
00336 virtual float getMusicLength();
00337 virtual bool getSongTitle(const std::string &filename, std::string &result);
00338 virtual void enableBackgroundMusic(bool enable);
00339 virtual void enableBackgroundMusicTimeConstraint(bool enable);
00340 CMusicSoundManager *getBackgroundMusicManager() const {return _BackgroundMusicManager;}
00341
00342 virtual bool playEventMusic(const std::string &fileName, uint xFadeTime= 0, bool async= true, bool loop=true);
00343 virtual void stopEventMusic(uint xFadeTime= 0);
00344 virtual void setEventMusicVolume(float gain);
00345 virtual bool isEventMusicEnded();
00347 virtual void getMusicExtensions(std::vector<std::string> &extensions);
00348
00349 inline IReverbEffect *getReverbEffect() { return _ReverbEffect; }
00350 inline bool useEnvironmentEffects() const { return _UseEax; }
00351
00353
00355 void addEnvironment(const std::string &name, const IReverbEffect::CEnvironment &environment);
00357 void setEnvironment(NLMISC::TStringId environmentName, float roomSize);
00359 inline void setEnvironment(const std::string &environmentName, float roomSize) { setEnvironment(NLMISC::CStringMapper::map(environmentName), roomSize); }
00361 const IReverbEffect::CEnvironment & getEnvironment(NLMISC::TStringId environmentName);
00363 inline const IReverbEffect::CEnvironment & getEnvironment(const std::string &environmentName) { return getEnvironment(NLMISC::CStringMapper::map(environmentName)); }
00365
00366 private:
00367 enum TMusicChannel
00368 {
00369 GeneralMusicChannel= 0,
00370 EventMusicChannel= 1
00371 };
00372 bool playMusicChannel(TMusicChannel chan, const std::string &fileName, uint xFadeTime, bool async, bool loop);
00373
00374
00375 public:
00377 class IMixerUpdate : public NLMISC::CDbgRefCount<IMixerUpdate>
00378 {
00379 public:
00380 virtual void onUpdate() =0;
00381 virtual ~IMixerUpdate()
00382 {
00383
00384 }
00385 };
00386
00388 void registerUpdate(IMixerUpdate *pmixerUpdate);
00390 void unregisterUpdate(IMixerUpdate *pmixerUpdate);
00391
00393 class IMixerEvent : public NLMISC::CDbgRefCount<IMixerEvent>
00394 {
00395 public:
00396 virtual void onEvent() =0;
00397 virtual ~IMixerEvent()
00398 {
00399
00400 }
00401
00402 };
00403
00405 void addEvent(IMixerEvent *pmixerEvent, const NLMISC::TTime &date);
00407 void removeEvents(IMixerEvent *pmixerEvent);
00408
00410 void addSourceWaitingForPlay(CSimpleSource *source);
00411
00413 void initUserVar();
00414 void addUserControledSource(CSourceCommon *source, NLMISC::TStringId varName);
00415 void removeUserControledSource(CSourceCommon *source, NLMISC::TStringId varName);
00416
00417
00418 virtual void startDriverBench();
00419 virtual void endDriverBench();
00420 virtual void displayDriverBench(NLMISC::CLog *log);
00421
00422 private:
00423
00424
00425 bool tryToLoadSoundBank(const std::string &sampleName);
00426
00427
00428 typedef CHashSet<CSourceCommon*, THashPtr<CSourceCommon*> > TSourceContainer;
00429 typedef CHashSet<IMixerUpdate*, THashPtr<IMixerUpdate*> > TMixerUpdateContainer;
00430 typedef CHashMap<IBuffer*, std::vector<class CSound*>, THashPtr<IBuffer*> > TBufferToSourceContainer;
00431
00432 typedef std::multimap<NLMISC::TTime, NLMISC::CDbgPtr<IMixerEvent> > TTimedEventContainer;
00433 typedef std::multimap<IMixerEvent*, TTimedEventContainer::iterator> TEventContainer;
00434
00436 enum TControledParamId
00437 {
00438 gain_control,
00439 pitch_control,
00440 nb_control,
00441 bad_control
00442 };
00443
00444 struct CControledSources
00445 {
00447 NLMISC::TStringId Name;
00449 TControledParamId ParamId;
00451 std::vector<NLMISC::TStringId> SoundNames;
00453 float Value;
00455 std::set<CSourceCommon*> Sources;
00456
00457 void serial (NLMISC::IStream &s);
00458 };
00459
00460 friend struct CControledSources;
00461 friend class CUserVarSerializer;
00462
00463 protected:
00465 TMixerUpdateContainer _UpdateList;
00467 std::vector<std::pair<IMixerUpdate*, bool> > _UpdateEventList;
00469 TTimedEventContainer _EventList;
00471 TEventContainer _Events;
00473 std::list<std::pair<NLMISC::TTime, IMixerEvent*> > _EventListUpdate;
00475 void getFreeTracks( uint nb, CTrack **tracks );
00477 virtual void getPlayingSoundsPos(bool virtualPos, std::vector<std::pair<bool, NLMISC::CVector> > &pos);
00478
00479 typedef CHashMap<NLMISC::TStringId, CControledSources, NLMISC::CStringIdHashMapTraits> TUserVarControlsContainer;
00481 TUserVarControlsContainer _UserVarControls;
00482
00483 private:
00485 bool _AutoLoadSample;
00487 bool _UseADPCM;
00489 bool _UseEax;
00490
00492 std::vector<CTrack*> _FreeTracks;
00493
00495 std::list<CSimpleSource*> _SourceWaitingForPlay;
00496
00498 uint32 _PriorityReserve[NbSoundPriorities];
00500 uint32 _ReserveUsage[NbSoundPriorities];
00502 uint32 _LowWaterMark;
00503
00505 ISoundDriver *_SoundDriver;
00506
00508 static const uint _NbMusicChannelFaders = 2;
00509
00511 CMusicChannelFader _MusicChannelFaders[_NbMusicChannelFaders];
00512
00514 CBackgroundSoundManager *_BackgroundSoundManager;
00516 std::string _BackgroundFilterNames[TBackgroundFlags::NB_BACKGROUND_FLAGS];
00518 std::string _BackgroundFilterShortNames[TBackgroundFlags::NB_BACKGROUND_FLAGS];
00519
00521 CClusteredSound *_ClusteredSound;
00522
00524 CListenerUser _Listener;
00525
00527 IReverbEffect *_ReverbEffect;
00529 IReverbEffect::CEnvironment _DefaultEnvironment;
00531 float _DefaultRoomSize;
00533 typedef std::map<NLMISC::TStringId, IReverbEffect::CEnvironment> TEnvironments;
00534 TEnvironments _Environments;
00535
00537 NLMISC::CVector _ListenPosition;
00538
00540 std::string _SamplePath;
00542 std::string _PackedSheetPath;
00544 bool _UpdatePackedSheet;
00545
00547 TBufferToSourceContainer _BufferToSources;
00548
00549
00550 void debugLogEvent(const char *reason);
00551
00552
00553 CMusicSoundManager *_BackgroundMusicManager;
00554
00555 public:
00556 struct TSampleBankHeader
00557 {
00558 enum
00559 {
00560
00561 sample_bank_header_version = 7,
00562 };
00563 uint32 Version;
00564 std::vector<std::string> Name;
00565 std::vector<uint32> NbSample;
00566 std::vector<uint32> Freq;
00567 std::vector<uint32> OffsetMono16;
00568 std::vector<uint32> OffsetAdpcm;
00569 std::vector<uint32> SizeMono16;
00570 std::vector<uint32> SizeAdpcm;
00571
00572 TSampleBankHeader()
00573 {
00574 Version = sample_bank_header_version;
00575 }
00576
00577 void addSample(const std::string &name, uint32 frequency, uint32 nbSample, uint32 sizeMono16, uint32 sizeAdpcm)
00578 {
00579 Name.push_back(name);
00580 Freq.push_back(frequency);
00581 NbSample.push_back(nbSample);
00582 uint32 off16;
00583 uint32 offAdpcm;
00584 off16 = std::accumulate(SizeMono16.begin(), SizeMono16.end(), 0);
00585 off16 = std::accumulate(SizeAdpcm.begin(), SizeAdpcm.end(), off16);
00586 OffsetMono16.push_back(off16);
00587 SizeMono16.push_back(sizeMono16);
00588 offAdpcm = std::accumulate(SizeMono16.begin(), SizeMono16.end(), 0);
00589 offAdpcm = std::accumulate(SizeAdpcm.begin(), SizeAdpcm.end(), offAdpcm);
00590 OffsetAdpcm.push_back(offAdpcm);
00591 SizeAdpcm.push_back(sizeAdpcm);
00592 }
00593
00594 void serial(NLMISC::IStream &s)
00595 {
00596 s.serialCheck(Version);
00597 s.serialCont(Name);
00598 s.serialCont(Freq);
00599 s.serialCont(NbSample);
00600 s.serialCont(OffsetMono16);
00601 s.serialCont(OffsetAdpcm);
00602 s.serialCont(SizeMono16);
00603 s.serialCont(SizeAdpcm);
00604 }
00605 };
00606
00608
00609
00611 TSourceContainer _Sources;
00612
00614 uint32 _PlayingSources;
00616 uint32 _PlayingSourcesMuted;
00617
00618 public:
00620 std::vector<CTrack *> _Tracks;
00622 bool _Leaving;
00623
00624 NLMISC::TTicks _StartTime;
00625
00626 uint32 curTime() { return (uint32) (NLMISC::CTime::getLocalTime() - _StartTime); }
00627
00628
00629 #define NL_PROFILE_MIXER 1
00630 #if NL_PROFILE_MIXER
00631 public:
00632
00633 double _UpdateTime;
00634 double _CreateTime;
00635 uint32 _UpdateCount;
00636 uint32 _CreateCount;
00637 #endif
00638
00639 friend struct displaySoundInfoClass;
00640
00641 };
00642
00643
00645 const char *getPriorityStr( TSoundPriority p );
00646
00647
00648 }
00649
00650
00651 #endif // NL_AUDIO_MIXER_USER_H
00652
00653