audio_mixer_user.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
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 //#include "background_sound_manager.h"
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         //CHashSet<uint>::hasher    h;
00069         // transtype the pointer into int then hash it
00070         //return h.operator()(uint(uintptr_t(ptr)));
00071         return (size_t)(uintptr_t)ptr;
00072     }
00073     inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const
00074     {
00075         // delegate the work to someone else as well?
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 //  virtual void                loadEnvEffects( const char *filename );
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 //  virtual void                loadSoundBank( const std::string &path );
00189 
00190 
00191     // Load environment sounds ; treeRoot can be null if you don't want an access to the envsounds
00192 //  virtual void                loadEnvSounds( const char *filename, UEnvSound **treeRoot=NULL );
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 //  void                        giveTrack( CSimpleSource *source );
00216 //  void                        releaseTrack( CSimpleSource *source );
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 //  CEnvSoundUser               *getEnvSounds()                         { return _EnvSounds; }
00257     const NLMISC::CVector&      getListenPosVector() const              { return _ListenPosition; }
00261 //  void                        removeMySource( USource *source );
00263 //  void                        addAmbiantSound( CSound *sound )        { _AmbSounds.insert( sound ); }
00264     // Allow to load sound files (nss) when the corresponding wave file is missing (see CSound)
00265     //static void                   allowMissingWave( bool b )              { CSound::allowMissingWave( b ); }
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 //  virtual void                loadBackgroundSoundFromRegion (const NLLIGO::CPrimRegion &region);
00283 //  virtual void                loadBackgroundEffectsFromRegion (const NLLIGO::CPrimRegion &region);
00284 //  virtual void                loadBackgroundSamplesFromRegion (const NLLIGO::CPrimRegion &region);
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 //  virtual void                setBackgroundSoundDayNightRatio (float ratio) { CBackgroundSoundManager::setDayNightRatio(ratio); }
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 //  bool                        setPlaying(CSimpleSource *source);
00309 //  void                        unsetPlaying(CSimpleSource *source);
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     // music
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     // Event music
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     //\name Reverb environment functions
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             //nldebug("Destroying IMixerUpdate %p", this);
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 //          nldebug("Destroying IMixerEvent %p", this);
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     // utility function for automatic sample bank loading.
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 //  typedef std::multimap<NLMISC::TTime, IMixerEvent*>                                  TTimedEventContainer;
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     // For debug purpose only (not called)
00550     void        debugLogEvent(const char *reason);
00551 
00552     // Instance of the background music manager
00553     CMusicSoundManager          *_BackgroundMusicManager;
00554 
00555 public:
00556     struct TSampleBankHeader
00557     {
00558         enum
00559         {
00560             // Mind to increment the version number each time the format change
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 //  static const std::string    SampleBankListExt;
00609 
00611     TSourceContainer        _Sources;
00612 
00614     uint32                  _PlayingSources;
00616     uint32                  _PlayingSourcesMuted;
00617 
00618 public: // Temp (EDIT)
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 } // NLSOUND
00649 
00650 
00651 #endif // NL_AUDIO_MIXER_USER_H
00652 
00653 /* End of audio_mixer_user.h */

Generated on Thu Jan 7 08:26:37 2010 for NeL by  doxygen 1.6.1