1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012-2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef NL_SOUND_MANAGER_H
23 #define NL_SOUND_MANAGER_H
29 #include "nel/misc/types_nl.h"
30 #include "nel/misc/vector.h"
31 #include "nel/misc/config_file.h"
32 #include "nel/misc/fast_id_map.h"
34 #include "nel/misc/entity_id.h"
36 #include "nel/sound/u_audio_mixer.h"
37 #include "nel/sound/u_listener.h"
39 extern class CSoundManager
*SoundMngr
;
45 using NLSOUND::USource
;
49 class IProgressCallback
;
53 * class managing all the sounds for the client
54 * \author David Fleury
55 * \author Nevrax France
61 typedef uint32 TSourceId
;
64 typedef CHashMultiMap
<NLMISC::CEntityId
, TSourceId
, NLMISC::CEntityIdHashMapTraits
> TMultiMapEntityToSource
;
65 typedef NLMISC::CFastIdMap
<TSourceId
, NLSOUND::USource
*> TMapIdToSource
;
67 /// Load the properties for this sound and aplly them.
68 void loadProperties(const string
&soundName
, USource
*source
);
70 /// Load the positioned sounds
71 //void loadPositionedSounds();
75 // Loading music XFade
76 enum {LoadingMusicXFade
= 1000};
82 * \param string& samplePath The path to directory containing the .wav sample files
83 * \param vector& sampleBanks The list of sample banks to load
85 CSoundManager(NLMISC::IProgressCallback
*progressCallBack
= NULL
);
91 /// Return the audio mixer instance pointer.
92 NLSOUND::UAudioMixer
*getMixer();
94 TSourceId
addSource( const NLMISC::TStringId
&soundName
, const NLMISC::CVector
&position
, bool play
= true , bool loop
= false, const NLMISC::CEntityId
&id
= NLMISC::CEntityId::Unknown
);
96 /// spawn a new source to the world but sound manager don't keep any link and the sound will be automatically deleted when finnished
97 bool spawnSource (const NLMISC::TStringId
&soundName
, NLSOUND::CSoundContext
&context
);
99 /// spawn a new source to the world but sound manager don't keep any link and the sound will be automatically deleted when finnished
100 bool spawnSource( const NLMISC::TStringId
&soundName
, const NLMISC::CVector
&position
);
104 * \param uint32 source id
106 void removeSource( TSourceId sourceId
);
110 * update the pos of all the sounds attached to that entity
111 * \param NLMISC::CEntityId& id of the entity
112 * \param CVector& new position
114 void updateEntityPos( const NLMISC::CEntityId
&id
, const NLMISC::CVector
&pos
);
117 * update the velocity of all the sounds attached to that entity
118 * \param NLMISC::CEntityId& id of the entity
119 * \param CVector& new velocity
121 void updateEntityVelocity( const NLMISC::CEntityId
&id
, const NLMISC::CVector
&velocity
);
124 * update the direction of all the sounds attached to that entity
125 * \param NLMISC::CEntityId& id of the entity
126 * \param CVector& new direction
128 void updateEntityDirection( const NLMISC::CEntityId
&id
, const NLMISC::CVector
&dir
);
131 * remove an entity from the view : delete all the sounds attached to that entity
132 * \param NLMISC::CEntityId& id of the entity to remove
134 void removeEntity( const NLMISC::CEntityId
&id
);
137 * set the listener position
138 * \param CVector & new position
140 inline void setListenerPos( const NLMISC::CVector
&pos
)
142 static NLMISC::CVector
oldPos(0.0f
, 0.0f
, 0.0f
);
145 _AudioMixer
->setListenerPos( pos
);
151 * set the listener velocity
152 * \param CVector& new velocity
154 inline void setListenerVelocity( const NLMISC::CVector
&velocity
)
156 static NLMISC::CVector
oldVelocity(1564152.0f
,1561.0f
,846.0f
);
157 if(oldVelocity
!= velocity
)
159 _AudioMixer
->getListener()->setVelocity( velocity
);
160 oldVelocity
= velocity
;
165 * set the listener orientation
166 * \param CVector& new orientation 'front'
167 * \param CVector& new orientation 'up'
169 inline void setListenerOrientation( const NLMISC::CVector
&front
, const NLMISC::CVector
&up
= NLMISC::CVector(0.0f
,0.0f
,1.0f
) )
171 static NLMISC::CVector
oldFront(1564152.0f
,1561.0f
,846.0f
), oldUp(1564152.0f
,1561.0f
,846.0f
);
172 if(oldFront
!= front
|| oldUp
!= up
)
174 _AudioMixer
->getListener()->setOrientation( front
, up
);
181 /** Get the gain value for the sound emited by the user entity
182 * This value come from the UserEntitySoundLevel var in config file.
184 float getUserEntitySoundLevel() {return _UserEntitySoundLevel
; }
188 void setFilterState(uint filter
, bool state
);
190 void playBackgroundSound ();
191 void stopBackgroundSound ();
194 * set sound position (sound must exist)
195 * \param uint32 source id
196 * \param CVector& new position
198 void setSoundPosition( TSourceId sourceId
, const NLMISC::CVector
&position
);
201 * loop a sound (or stop looping)
202 * \param uint32 source id
203 * \param bool loop (true = loop)
205 void loopSound( TSourceId sourceId
, bool loop
);
208 * play or stop a sound
209 * \param uint32 source id
210 * \param bool play (true = play, false = stop)
212 void playSound( TSourceId sourceId
, bool play
);
215 * test whether the sepcified source is playing or not
216 * \param uint32 source id
217 * \return bool true if the source is playing
219 bool isPlaying( TSourceId sourceId
);
222 * select the env effect corresponding to tag
225 inline void selectEnvEffect( const std::string
&tag
)
227 nlassert( _AudioMixer
);
228 _AudioMixer
->selectEnvEffects( tag
);
232 * select the env corresponding to tag
235 void selectEnv( const std::string
&tag
);
239 * (Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain
240 * (which is getSource()->getGain()). Does nothing if getSource() is null )
241 * \param uint32 sourceId
242 * \param float new gain (0-1)
244 void setSourceGain( TSourceId sourceId
, float gain
);
248 * \param uint32 sourceId
249 * \return float new gain (0-1) (-1 if source not found)
251 float getSourceGain( TSourceId sourceId
);
255 * (Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift of one octave. 0 is not a legal value.)
256 * \param uint32 sourceId
257 * \param float new Pitch (0-1)
259 void setSourcePitch( TSourceId sourceId
, float gain
);
263 * \param uint32 sourceId
264 * \return float new Pitch (0-1) (>0) (-1 if source not found)
266 float getSourcePitch( TSourceId sourceId
);
269 * Play all the positioned sounds which are near the given position
271 * \param pos is the position of the user
273 void playPositionedSounds( const NLMISC::CVector
& pos
);
277 // called at outgame time
278 void updateAudioMixerOnly();
280 /// Return the number of sources
281 uint
getSourcesInstanceCount() const { if (_AudioMixer
) return _AudioMixer
->getSourcesInstanceCount(); else return 0; };
282 /// Return the number of playing sources
283 uint
getPlayingSourcesCount() const { if (_AudioMixer
) return _AudioMixer
->getPlayingSourcesCount(); else return 0; };
284 /// Return the memory size for samples.
285 uint
getLoadingSamplesSize() const { if (_AudioMixer
) return _AudioMixer
->getLoadedSampleSize(); else return 0; };
287 void switchSoundState ();
289 /// Load all stuffs for a continent (must be "lesfalaises", "tryker" ... look ryzom.world for good name)
290 void loadContinent (const std::string
&name
, const NLMISC::CVector
& pos
);
292 /// Draw the sounds/cluster/audio path for debugging purpose
293 void drawSounds(float camHeight
);
295 /// Play Music (see UAudioMixer for detail). NB: the background music system is disabled until the music is stopped
296 void playMusic(const string
&fileName
, uint xFadeTime
= 2000, bool async
= true, bool loop
=true, bool forceGameMusicVolume
= false);
297 /// Stop Music. NB: the background music system is then reenabled
298 void stopMusic(uint xFadeTime
= 2000);
305 /// set game music volume (0-1) (outgame and ingame music)
306 void setGameMusicVolume(float val
);
307 /// set user music volume (0-1) (mp3 player)
308 void setUserMusicVolume(float val
);
310 /// Set the SFX global volume (don't impact on music volume)
311 void setSFXVolume(float val
);
313 /// Fade in/out game volume (game music and sfx volume)
314 void fadeInGameSound(sint32 timeFadeMs
);
315 void fadeOutGameSound(sint32 timeFadeMs
);
316 void setupFadeSound(float sfxFade
, float musicFade
);
318 /// Start an Event music (always async). Don't restart if the same music is currently playing
319 void playEventMusic(const string
&fileName
, uint xFadeTime
= 2000, bool loop
=true);
320 /// Stop the event music played. Stop the music only if it is the same music. Set empty filename to stop any music
321 void stopEventMusic(const string
&fileName
, uint xFadeTime
= 2000);
322 /// get the eventmusic played (empty if none or ended)
323 const std::string
&getEventMusicPlayed() const {return _EventMusicPlayed
;}
326 * Initialize the audio mixer, load the sound banks, called by the constructors
327 * \param string& sound buffer file (.nss)
329 void init(NLMISC::IProgressCallback
*progressCallBack
= NULL
);
332 // attributes------------------------------
335 /// Pointer on the audio mixer object
336 NLSOUND::UAudioMixer
*_AudioMixer
;
338 /// The root effects group controller for effects volume settings by the user
339 NLSOUND::UGroupController
*_GroupControllerEffects
;
341 /// The root effects group controller for effects fading by the game
342 NLSOUND::UGroupController
*_GroupControllerEffectsGame
;
344 /// Pointer on the root of the environmental sounds tree (if any)
345 NLSOUND::UEnvSound
*_EnvSoundRoot
;
347 /// The current filter state.
348 NLSOUND::UAudioMixer::TBackgroundFlags _BackgroundFlags
;
350 /// map attached sounds to the parent entity
351 TMultiMapEntityToSource _AttachedSources
;
353 /// map sound Id to sound object
354 TMapIdToSource _Sources
;
356 /// all the step sounds
357 //CStepSounds _StepSounds;
359 /// list of positioned sounds
360 std::list
<TSourceId
> _PositionedSounds
;
362 /// Gain value for user entity sound.
363 float _UserEntitySoundLevel
;
365 /// Music Player and outgame music: re-enable the background music after a while
366 NLMISC::TTime _EnableBackgroundMusicAtTime
;
368 /// release SoundAnim system
369 void releaseSoundAnim();
373 float _GameMusicVolume
;
374 float _UserMusicVolume
;
375 bool _UseGameMusicVolume
;
376 // if event music is possible
377 bool _EventMusicEnabled
;
378 // if event music is currently playing, the name of it
379 std::string _EventMusicPlayed
;
380 // if the event music currently playing is looping
381 bool _EventMusicLoop
;
382 // the fading music volume during TP
383 float _FadeGameMusicVolume
;
384 // the fading game music volume that raise when an event music is playing (replacing the background music)
385 float _FadeGameMusicVolumeDueToEvent
;
386 float _FadeSFXVolume
;
388 void setGameMusicMode(bool enableBackground
, bool useGameMusicVolume
);
389 void fadeGameSound(bool fadeIn
,sint32 timeFadeMs
);
390 void updateEventAndGameMusicVolume();
398 #endif // NL_SOUND_MANAGER_H
400 /* End of sound_manager.h */