Added: #1459 Group controllers for sound sources
This commit is contained in:
parent
933c939509
commit
8a6b6e218c
21 changed files with 510 additions and 103 deletions
|
@ -204,9 +204,9 @@ public:
|
||||||
* pass a callback function that will be called (if not NULL) just before deleting the spawned
|
* pass a callback function that will be called (if not NULL) just before deleting the spawned
|
||||||
* source.
|
* source.
|
||||||
*/
|
*/
|
||||||
virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 );
|
virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL);
|
||||||
/// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*)
|
/// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*)
|
||||||
virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0 );
|
virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *cbUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL);
|
||||||
/// Add a source which was created by an EnvSound
|
/// Add a source which was created by an EnvSound
|
||||||
void addSource( CSourceCommon *source );
|
void addSource( CSourceCommon *source );
|
||||||
/** Delete a logical sound source. If you don't call it, the source will be auto-deleted
|
/** Delete a logical sound source. If you don't call it, the source will be auto-deleted
|
||||||
|
@ -431,8 +431,9 @@ private:
|
||||||
// utility function for automatic sample bank loading.
|
// utility function for automatic sample bank loading.
|
||||||
bool tryToLoadSampleBank(const std::string &sampleName);
|
bool tryToLoadSampleBank(const std::string &sampleName);
|
||||||
|
|
||||||
|
public:
|
||||||
typedef CHashSet<CSourceCommon*, THashPtr<CSourceCommon*> > TSourceContainer;
|
typedef CHashSet<CSourceCommon*, THashPtr<CSourceCommon*> > TSourceContainer;
|
||||||
|
private:
|
||||||
typedef CHashSet<IMixerUpdate*, THashPtr<IMixerUpdate*> > TMixerUpdateContainer;
|
typedef CHashSet<IMixerUpdate*, THashPtr<IMixerUpdate*> > TMixerUpdateContainer;
|
||||||
typedef CHashMap<IBuffer*, std::vector<class CSound*>, THashPtr<IBuffer*> > TBufferToSourceContainer;
|
typedef CHashMap<IBuffer*, std::vector<class CSound*>, THashPtr<IBuffer*> > TBufferToSourceContainer;
|
||||||
// typedef std::multimap<NLMISC::TTime, IMixerEvent*> TTimedEventContainer;
|
// typedef std::multimap<NLMISC::TTime, IMixerEvent*> TTimedEventContainer;
|
||||||
|
|
|
@ -36,7 +36,7 @@ class CBackgroundSource : public CSourceCommon , public CAudioMixerUser::IMixerU
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CBackgroundSource (CBackgroundSound *backgroundSound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0);
|
CBackgroundSource (CBackgroundSound *backgroundSound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~CBackgroundSource ();
|
~CBackgroundSource ();
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class CComplexSource : public CSourceCommon, public CAudioMixerUser::IMixerEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CComplexSource (CComplexSound *soundPattern=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0);
|
CComplexSource (CComplexSound *soundPattern=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~CComplexSource ();
|
~CComplexSource ();
|
||||||
|
|
||||||
|
|
100
code/nel/include/nel/sound/group_controller.h
Normal file
100
code/nel/include/nel/sound/group_controller.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
* \file group_controller.h
|
||||||
|
* \brief CGroupController
|
||||||
|
* \date 2012-04-10 09:29GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupController
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE.
|
||||||
|
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLSOUND_GROUP_CONTROLLER_H
|
||||||
|
#define NLSOUND_GROUP_CONTROLLER_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/common.h>
|
||||||
|
#include <nel/sound/audio_mixer_user.h>
|
||||||
|
#include <nel/sound/u_group_controller.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
namespace NLSOUND {
|
||||||
|
class CSourceCommon;
|
||||||
|
class CGroupControllerRoot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief CGroupController
|
||||||
|
* \date 2012-04-10 09:29GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupController
|
||||||
|
*/
|
||||||
|
class CGroupController : public UGroupController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend CGroupControllerRoot;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CGroupController *m_Parent;
|
||||||
|
std::map<std::string, CGroupController *> m_Children;
|
||||||
|
|
||||||
|
float m_DevGain;
|
||||||
|
float m_UserGain;
|
||||||
|
float m_FinalGain;
|
||||||
|
|
||||||
|
int m_NbSourcesInclChild;
|
||||||
|
CAudioMixerUser::TSourceContainer m_Sources;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CGroupController(CGroupController *parent);
|
||||||
|
|
||||||
|
/// \name UGroupController
|
||||||
|
//@{
|
||||||
|
virtual void setDevGain(float gain) { NLMISC::clamp(gain, 0.0f, 1.0f); m_DevGain = gain; updateSourceGain(); }
|
||||||
|
virtual float getDevGain() { return m_DevGain; }
|
||||||
|
|
||||||
|
virtual void setUserGain(float gain) { NLMISC::clamp(gain, 0.0f, 1.0f); m_UserGain = gain; updateSourceGain(); }
|
||||||
|
virtual float getUserGain() { return m_UserGain; }
|
||||||
|
//@}
|
||||||
|
|
||||||
|
inline float getFinalGain() const { return m_FinalGain; }
|
||||||
|
|
||||||
|
void addSource(CSourceCommon *source);
|
||||||
|
void removeSource(CSourceCommon *source);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~CGroupController(); // subnodes can only be deleted by the root
|
||||||
|
inline float calculateTotalGain() { return m_DevGain * m_UserGain; }
|
||||||
|
virtual void calculateFinalGain();
|
||||||
|
virtual void increaseSources();
|
||||||
|
virtual void decreaseSources();
|
||||||
|
void updateSourceGain();
|
||||||
|
|
||||||
|
}; /* class CGroupController */
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
#endif /* #ifndef NLSOUND_GROUP_CONTROLLER_H */
|
||||||
|
|
||||||
|
/* end of file */
|
67
code/nel/include/nel/sound/group_controller_root.h
Normal file
67
code/nel/include/nel/sound/group_controller_root.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* \file group_controller_root.h
|
||||||
|
* \brief CGroupControllerRoot
|
||||||
|
* \date 2012-04-10 09:44GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupControllerRoot
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE.
|
||||||
|
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLSOUND_GROUP_CONTROLLER_ROOT_H
|
||||||
|
#define NLSOUND_GROUP_CONTROLLER_ROOT_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include <nel/sound/group_controller.h>
|
||||||
|
|
||||||
|
namespace NLSOUND {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief CGroupControllerRoot
|
||||||
|
* \date 2012-04-10 09:44GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupControllerRoot
|
||||||
|
*/
|
||||||
|
class CGroupControllerRoot : public CGroupController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CGroupControllerRoot();
|
||||||
|
virtual ~CGroupControllerRoot();
|
||||||
|
|
||||||
|
/// Gets the group controller in a certain path with separator '/', if it doesn't exist yet it will be created.
|
||||||
|
CGroupController *getGroupController(const std::string &path);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void calculateFinalGain();
|
||||||
|
virtual void increaseSources();
|
||||||
|
virtual void decreaseSources();
|
||||||
|
|
||||||
|
}; /* class CGroupControllerRoot */
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
#endif /* #ifndef NLSOUND_GROUP_CONTROLLER_ROOT_H */
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -35,7 +35,7 @@ class CMusicSource : public CSourceCommon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CMusicSource (class CMusicSound *sound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0);
|
CMusicSource (class CMusicSound *sound=NULL, bool spawn=false, TSpawnEndCallback cb=0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~CMusicSource ();
|
~CMusicSource ();
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class CSimpleSource : public CSourceCommon, public CAudioMixerUser::IMixerEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CSimpleSource(CSimpleSound *simpleSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0);
|
CSimpleSource(CSimpleSound *simpleSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~CSimpleSource();
|
virtual ~CSimpleSource();
|
||||||
|
|
||||||
|
@ -97,14 +97,7 @@ public:
|
||||||
* 1.0 -> no attenuation
|
* 1.0 -> no attenuation
|
||||||
* values > 1 (amplification) not supported by most drivers
|
* values > 1 (amplification) not supported by most drivers
|
||||||
*/
|
*/
|
||||||
virtual void setGain( float gain );
|
virtual void updateFinalGain();
|
||||||
/** Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain
|
|
||||||
* (which is getSource()->getGain()). Does nothing if getSource() is null.
|
|
||||||
*/
|
|
||||||
virtual void setRelativeGain( float gain );
|
|
||||||
/** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
|
|
||||||
* of one octave. 0 is not a legal value.
|
|
||||||
*/
|
|
||||||
virtual void setPitch( float pitch );
|
virtual void setPitch( float pitch );
|
||||||
/// Set the source relative mode. If true, positions are interpreted relative to the listener position (default: false)
|
/// Set the source relative mode. If true, positions are interpreted relative to the listener position (default: false)
|
||||||
virtual void setSourceRelativeMode( bool mode );
|
virtual void setSourceRelativeMode( bool mode );
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace NLSOUND {
|
||||||
class ISoundDriver;
|
class ISoundDriver;
|
||||||
class IBuffer;
|
class IBuffer;
|
||||||
class CSound;
|
class CSound;
|
||||||
|
class CGroupController;
|
||||||
|
|
||||||
|
|
||||||
/// Sound names hash map
|
/// Sound names hash map
|
||||||
|
@ -104,6 +105,8 @@ public:
|
||||||
/// Return the max distance (if detailed())
|
/// Return the max distance (if detailed())
|
||||||
virtual float getMaxDistance() const { return _MaxDist; }
|
virtual float getMaxDistance() const { return _MaxDist; }
|
||||||
|
|
||||||
|
inline CGroupController *getGroupController() const { return NULL; } // TODO, RETURN THE GROUP CONTROLLER
|
||||||
|
|
||||||
/// Set looping
|
/// Set looping
|
||||||
void setLooping( bool looping ) { _Looping = looping; }
|
void setLooping( bool looping ) { _Looping = looping; }
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "nel/sound/u_stream_source.h"
|
#include "nel/sound/u_stream_source.h"
|
||||||
#include "nel/3d/cluster.h"
|
#include "nel/3d/cluster.h"
|
||||||
#include "nel/sound/sound.h"
|
#include "nel/sound/sound.h"
|
||||||
|
#include "nel/sound/group_controller.h"
|
||||||
|
|
||||||
namespace NLSOUND {
|
namespace NLSOUND {
|
||||||
|
|
||||||
|
@ -36,11 +36,12 @@ public:
|
||||||
SOURCE_SIMPLE,
|
SOURCE_SIMPLE,
|
||||||
SOURCE_COMPLEX,
|
SOURCE_COMPLEX,
|
||||||
SOURCE_BACKGROUND,
|
SOURCE_BACKGROUND,
|
||||||
SOURCE_MUSIC,
|
SOURCE_MUSIC, // DEPRECATED
|
||||||
SOURCE_STREAM
|
SOURCE_STREAM
|
||||||
};
|
};
|
||||||
|
|
||||||
CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster);
|
/// When groupController is NULL it will use the groupcontroller specified in the TSoundId. You should manually specify the groupController if this source is a child of another source, so that the parent source controller of the user-specified .sound file is the one that will be used.
|
||||||
|
CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController);
|
||||||
|
|
||||||
~CSourceCommon();
|
~CSourceCommon();
|
||||||
|
|
||||||
|
@ -63,6 +64,8 @@ public:
|
||||||
void setGain( float gain );
|
void setGain( float gain );
|
||||||
void setRelativeGain( float gain );
|
void setRelativeGain( float gain );
|
||||||
float getRelativeGain() const;
|
float getRelativeGain() const;
|
||||||
|
/// Called whenever the gain is changed trough setGain, setRelativeGain or the group controller's gain settings change.
|
||||||
|
virtual void updateFinalGain() { }
|
||||||
void setSourceRelativeMode( bool mode );
|
void setSourceRelativeMode( bool mode );
|
||||||
/// return the user param for the user callback
|
/// return the user param for the user callback
|
||||||
void *getCallbackUserParam(void) const { return _CbUserParam; }
|
void *getCallbackUserParam(void) const { return _CbUserParam; }
|
||||||
|
@ -74,6 +77,8 @@ public:
|
||||||
virtual void getDirection( NLMISC::CVector& dir ) const { dir = _Direction; }
|
virtual void getDirection( NLMISC::CVector& dir ) const { dir = _Direction; }
|
||||||
/// Get the gain
|
/// Get the gain
|
||||||
virtual float getGain() const { return _Gain; }
|
virtual float getGain() const { return _Gain; }
|
||||||
|
/// Get the final gain, including group controller changes. Use this when setting the physical source output gain.
|
||||||
|
inline float getFinalGain() const { return _Gain * _GroupController->getFinalGain(); }
|
||||||
/// Get the pitch
|
/// Get the pitch
|
||||||
virtual float getPitch() const { return _Pitch; }
|
virtual float getPitch() const { return _Pitch; }
|
||||||
/// Get the source relative mode
|
/// Get the source relative mode
|
||||||
|
@ -145,6 +150,9 @@ protected:
|
||||||
/// An optional user var controler.
|
/// An optional user var controler.
|
||||||
NLMISC::TStringId _UserVarControler;
|
NLMISC::TStringId _UserVarControler;
|
||||||
|
|
||||||
|
/// Group controller for gain
|
||||||
|
CGroupController *_GroupController;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // NLSOUND
|
} // NLSOUND
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace NLSOUND {
|
||||||
class CStreamSource : public CSourceCommon
|
class CStreamSource : public CSourceCommon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CStreamSource(CStreamSound *streamSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0);
|
CStreamSource(CStreamSound *streamSound = NULL, bool spawn = false, TSpawnEndCallback cb = 0, void *cbUserParam = 0, NL3D::CCluster *cluster = 0, CGroupController *groupController = NULL);
|
||||||
virtual ~CStreamSource();
|
virtual ~CStreamSource();
|
||||||
|
|
||||||
/// Return the sound binded to the source (or NULL if there is no sound)
|
/// Return the sound binded to the source (or NULL if there is no sound)
|
||||||
|
@ -80,18 +80,7 @@ public:
|
||||||
virtual void setVelocity(const NLMISC::CVector& vel);
|
virtual void setVelocity(const NLMISC::CVector& vel);
|
||||||
/// Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional)
|
/// Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional)
|
||||||
virtual void setDirection(const NLMISC::CVector& dir);
|
virtual void setDirection(const NLMISC::CVector& dir);
|
||||||
/** Set the gain (volume value inside [0 , 1]). (default: 1)
|
virtual void updateFinalGain();
|
||||||
* 0.0 -> silence
|
|
||||||
* 0.5 -> -6dB
|
|
||||||
* 1.0 -> no attenuation
|
|
||||||
* values > 1 (amplification) not supported by most drivers
|
|
||||||
*/
|
|
||||||
virtual void setGain(float gain);
|
|
||||||
|
|
||||||
/** Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain
|
|
||||||
* (which is getSource()->getGain()). Does nothing if getSource() is null.
|
|
||||||
*/
|
|
||||||
virtual void setRelativeGain(float gain);
|
|
||||||
/** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
|
/** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
|
||||||
* of one octave. 0 is not a legal value.
|
* of one octave. 0 is not a legal value.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "nel/misc/types_nl.h"
|
#include "nel/misc/types_nl.h"
|
||||||
#include "nel/misc/string_mapper.h"
|
#include "nel/misc/string_mapper.h"
|
||||||
#include "nel/sound/u_source.h"
|
#include "nel/sound/u_source.h"
|
||||||
|
#include "nel/sound/u_group_controller.h"
|
||||||
#include "nel/ligo/primitive.h"
|
#include "nel/ligo/primitive.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -291,9 +292,9 @@ public:
|
||||||
* pass a callback function that will be called (if not NULL) just before deleting the spawned
|
* pass a callback function that will be called (if not NULL) just before deleting the spawned
|
||||||
* source.
|
* source.
|
||||||
*/
|
*/
|
||||||
virtual USource *createSource( const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context=0) = 0;
|
virtual USource *createSource(const NLMISC::TStringId &name, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL) = 0;
|
||||||
/// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*)
|
/// Add a logical sound source (by sound id). To remove a source, just delete it. See createSource(const char*)
|
||||||
virtual USource *createSource( TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context=0 ) = 0;
|
virtual USource *createSource(TSoundId id, bool spawn=false, TSpawnEndCallback cb=NULL, void *callbackUserParam = NULL, NL3D::CCluster *cluster = 0, CSoundContext *context = 0, UGroupController *groupController = NULL) = 0;
|
||||||
|
|
||||||
/** Use this method to set the listener position instead of using getListener->setPos();
|
/** Use this method to set the listener position instead of using getListener->setPos();
|
||||||
* It's because we have to update the background sounds in this case.
|
* It's because we have to update the background sounds in this case.
|
||||||
|
|
63
code/nel/include/nel/sound/u_group_controller.h
Normal file
63
code/nel/include/nel/sound/u_group_controller.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* \file u_group_controller.h
|
||||||
|
* \brief UGroupController
|
||||||
|
* \date 2012-04-10 12:49GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* UGroupController
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE.
|
||||||
|
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLSOUND_U_GROUP_CONTROLLER_H
|
||||||
|
#define NLSOUND_U_GROUP_CONTROLLER_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
namespace NLSOUND {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief UGroupController
|
||||||
|
* \date 2012-04-10 12:49GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* UGroupController
|
||||||
|
*/
|
||||||
|
class UGroupController
|
||||||
|
{
|
||||||
|
virtual void setDevGain(float gain) = 0;
|
||||||
|
virtual float getDevGain() = 0;
|
||||||
|
|
||||||
|
virtual void setUserGain(float gain) = 0;
|
||||||
|
virtual float getUserGain() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~UGroupController();
|
||||||
|
|
||||||
|
}; /* class UGroupController */
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
#endif /* #ifndef NLSOUND_U_GROUP_CONTROLLER_H */
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -51,6 +51,7 @@
|
||||||
#include "nel/sound/sample_bank_manager.h"
|
#include "nel/sound/sample_bank_manager.h"
|
||||||
#include "nel/sound/sample_bank.h"
|
#include "nel/sound/sample_bank.h"
|
||||||
#include "nel/sound/sound_bank.h"
|
#include "nel/sound/sound_bank.h"
|
||||||
|
#include "nel/sound/group_controller.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace NLMISC;
|
using namespace NLMISC;
|
||||||
|
@ -1689,7 +1690,7 @@ void CAudioMixerUser::update()
|
||||||
// _Tracks[i]->DrvSource->setPos(source->getPos() * (1-css->PosAlpha) + css->Position*(css->PosAlpha));
|
// _Tracks[i]->DrvSource->setPos(source->getPos() * (1-css->PosAlpha) + css->Position*(css->PosAlpha));
|
||||||
_Tracks[i]->getPhysicalSource()->setPos(source->getPos() * (1-css->PosAlpha) + vpos*(css->PosAlpha));
|
_Tracks[i]->getPhysicalSource()->setPos(source->getPos() * (1-css->PosAlpha) + vpos*(css->PosAlpha));
|
||||||
// update the relative gain
|
// update the relative gain
|
||||||
_Tracks[i]->getPhysicalSource()->setGain(source->getRelativeGain()*source->getGain()*css->Gain);
|
_Tracks[i]->getPhysicalSource()->setGain(source->getFinalGain() * css->Gain);
|
||||||
#if EAX_AVAILABLE == 1
|
#if EAX_AVAILABLE == 1
|
||||||
if (_UseEax)
|
if (_UseEax)
|
||||||
{
|
{
|
||||||
|
@ -1829,7 +1830,7 @@ bool CAudioMixerUser::tryToLoadSampleBank(const std::string &sampleName)
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
||||||
USource *CAudioMixerUser::createSource( TSoundId id, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context )
|
USource *CAudioMixerUser::createSource( TSoundId id, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context, UGroupController *groupController )
|
||||||
{
|
{
|
||||||
#if NL_PROFILE_MIXER
|
#if NL_PROFILE_MIXER
|
||||||
TTicks start = CTime::getPerformanceTime();
|
TTicks start = CTime::getPerformanceTime();
|
||||||
|
@ -1915,7 +1916,7 @@ retrySound:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create source
|
// Create source
|
||||||
CSimpleSource *source = new CSimpleSource( simpleSound, spawn, cb, userParam, cluster);
|
CSimpleSource *source = new CSimpleSource( simpleSound, spawn, cb, userParam, cluster, static_cast<CGroupController *>(groupController));
|
||||||
|
|
||||||
// nldebug("Mixer : source %p created", source);
|
// nldebug("Mixer : source %p created", source);
|
||||||
|
|
||||||
|
@ -1939,28 +1940,28 @@ retrySound:
|
||||||
{
|
{
|
||||||
CStreamSound *streamSound = static_cast<CStreamSound *>(id);
|
CStreamSound *streamSound = static_cast<CStreamSound *>(id);
|
||||||
// This is a stream thingy.
|
// This is a stream thingy.
|
||||||
ret = new CStreamSource(streamSound, spawn, cb, userParam, cluster);
|
ret = new CStreamSource(streamSound, spawn, cb, userParam, cluster, static_cast<CGroupController *>(groupController));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSound::SOUND_COMPLEX:
|
case CSound::SOUND_COMPLEX:
|
||||||
{
|
{
|
||||||
CComplexSound *complexSound = static_cast<CComplexSound *>(id);
|
CComplexSound *complexSound = static_cast<CComplexSound *>(id);
|
||||||
// This is a pattern sound.
|
// This is a pattern sound.
|
||||||
ret = new CComplexSource(complexSound, spawn, cb, userParam, cluster);
|
ret = new CComplexSource(complexSound, spawn, cb, userParam, cluster, static_cast<CGroupController *>(groupController));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSound::SOUND_BACKGROUND:
|
case CSound::SOUND_BACKGROUND:
|
||||||
{
|
{
|
||||||
// This is a background sound.
|
// This is a background sound.
|
||||||
CBackgroundSound *bgSound = static_cast<CBackgroundSound *>(id);
|
CBackgroundSound *bgSound = static_cast<CBackgroundSound *>(id);
|
||||||
ret = new CBackgroundSource(bgSound, spawn, cb, userParam, cluster);
|
ret = new CBackgroundSource(bgSound, spawn, cb, userParam, cluster, static_cast<CGroupController *>(groupController));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSound::SOUND_MUSIC:
|
case CSound::SOUND_MUSIC:
|
||||||
{
|
{
|
||||||
// This is a background music sound
|
// This is a background music sound
|
||||||
CMusicSound *music_sound= static_cast<CMusicSound *>(id);
|
CMusicSound *music_sound= static_cast<CMusicSound *>(id);
|
||||||
ret = new CMusicSource(music_sound, spawn, cb, userParam, cluster);
|
ret = new CMusicSource(music_sound, spawn, cb, userParam, cluster, static_cast<CGroupController *>(groupController));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSound::SOUND_CONTEXT:
|
case CSound::SOUND_CONTEXT:
|
||||||
|
@ -1974,7 +1975,7 @@ retrySound:
|
||||||
CSound *sound = ctxSound->getContextSound(*context);
|
CSound *sound = ctxSound->getContextSound(*context);
|
||||||
if (sound != 0)
|
if (sound != 0)
|
||||||
{
|
{
|
||||||
ret = createSource(sound, spawn, cb, userParam, cluster);
|
ret = createSource(sound, spawn, cb, userParam, cluster, NULL, static_cast<CGroupController *>(groupController));
|
||||||
// Set the volume of the source according to the context volume
|
// Set the volume of the source according to the context volume
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
|
@ -2007,9 +2008,9 @@ retrySound:
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
||||||
USource *CAudioMixerUser::createSource( const NLMISC::TStringId &name, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context)
|
USource *CAudioMixerUser::createSource( const NLMISC::TStringId &name, bool spawn, TSpawnEndCallback cb, void *userParam, NL3D::CCluster *cluster, CSoundContext *context, UGroupController *groupController)
|
||||||
{
|
{
|
||||||
return createSource( getSoundId( name ), spawn, cb, userParam, cluster, context);
|
return createSource( getSoundId( name ), spawn, cb, userParam, cluster, context, groupController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ namespace NLSOUND
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: CSourceCommon(backgroundSound, spawn, cb, cbUserParam, cluster)
|
: CSourceCommon(backgroundSound, spawn, cb, cbUserParam, cluster, groupController)
|
||||||
{
|
{
|
||||||
_BackgroundSound = backgroundSound;
|
_BackgroundSound = backgroundSound;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ void CBackgroundSource::play()
|
||||||
for (; first != last; ++first)
|
for (; first != last; ++first)
|
||||||
{
|
{
|
||||||
TSubSource subSource;
|
TSubSource subSource;
|
||||||
subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, 0);
|
subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (subSource.Source != NULL)
|
if (subSource.Source != NULL)
|
||||||
subSource.Source->setPriority(_Priority);
|
subSource.Source->setPriority(_Priority);
|
||||||
subSource.Filter = first->Filter;
|
subSource.Filter = first->Filter;
|
||||||
|
|
|
@ -25,8 +25,8 @@ using namespace NLMISC;
|
||||||
namespace NLSOUND
|
namespace NLSOUND
|
||||||
{
|
{
|
||||||
|
|
||||||
CComplexSource::CComplexSource (CComplexSound *soundPattern, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CComplexSource::CComplexSource (CComplexSound *soundPattern, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: CSourceCommon(soundPattern, spawn, cb, cbUserParam, cluster),
|
: CSourceCommon(soundPattern, spawn, cb, cbUserParam, cluster, groupController),
|
||||||
_Source1(NULL),
|
_Source1(NULL),
|
||||||
_Source2(NULL)
|
_Source2(NULL)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ void CComplexSource::playStuf()
|
||||||
else
|
else
|
||||||
_FadeLength = 0;
|
_FadeLength = 0;
|
||||||
|
|
||||||
_Source2 = mixer->createSource(sound, false, 0, 0, _Cluster);
|
_Source2 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (_Source2 == NULL)
|
if (_Source2 == NULL)
|
||||||
return;
|
return;
|
||||||
_Source2->setPriority(_Priority);
|
_Source2->setPriority(_Priority);
|
||||||
|
@ -155,7 +155,7 @@ void CComplexSource::playStuf()
|
||||||
{
|
{
|
||||||
CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++]));
|
CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++]));
|
||||||
|
|
||||||
_Source1 = mixer->createSource(sound, false, 0, 0, _Cluster);
|
_Source1 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (_Source1 == NULL)
|
if (_Source1 == NULL)
|
||||||
return;
|
return;
|
||||||
_Source1->setPriority(_Priority);
|
_Source1->setPriority(_Priority);
|
||||||
|
@ -202,7 +202,7 @@ void CComplexSource::playStuf()
|
||||||
CSound *sound = mixer->getSoundId(*first);
|
CSound *sound = mixer->getSoundId(*first);
|
||||||
if (sound != NULL)
|
if (sound != NULL)
|
||||||
{
|
{
|
||||||
USource *source = mixer->createSource(sound, false, 0, 0, _Cluster);
|
USource *source = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (source != NULL)
|
if (source != NULL)
|
||||||
{
|
{
|
||||||
source->setPriority(_Priority);
|
source->setPriority(_Priority);
|
||||||
|
@ -512,7 +512,7 @@ void CComplexSource::onUpdate()
|
||||||
|
|
||||||
// determine the XFade length (if next sound is too short.
|
// determine the XFade length (if next sound is too short.
|
||||||
_FadeLength = minof<uint32>(uint32(_PatternSound->getFadeLength()/_TickPerSecond), (sound2->getDuration()) / 2, (_Source1->getSound()->getDuration())/2);
|
_FadeLength = minof<uint32>(uint32(_PatternSound->getFadeLength()/_TickPerSecond), (sound2->getDuration()) / 2, (_Source1->getSound()->getDuration())/2);
|
||||||
_Source2 = mixer->createSource(sound2, false, 0, 0, _Cluster);
|
_Source2 = mixer->createSource(sound2, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (_Source2)
|
if (_Source2)
|
||||||
{
|
{
|
||||||
_Source2->setPriority(_Priority);
|
_Source2->setPriority(_Priority);
|
||||||
|
@ -641,7 +641,7 @@ void CComplexSource::onEvent()
|
||||||
|
|
||||||
CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++]));
|
CSound *sound = mixer->getSoundId(_PatternSound->getSound(soundSeq[_SoundSeqIndex++]));
|
||||||
|
|
||||||
_Source1 = mixer->createSource(sound, false, 0, 0, _Cluster);
|
_Source1 = mixer->createSource(sound, false, 0, 0, _Cluster, NULL, _GroupController);
|
||||||
if (_Source1 == NULL)
|
if (_Source1 == NULL)
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
|
|
112
code/nel/src/sound/group_controller.cpp
Normal file
112
code/nel/src/sound/group_controller.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/**
|
||||||
|
* \file group_controller.cpp
|
||||||
|
* \brief CGroupController
|
||||||
|
* \date 2012-04-10 09:29GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupController
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE.
|
||||||
|
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdsound.h"
|
||||||
|
#include <nel/sound/group_controller.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
// #include <nel/misc/debug.h>
|
||||||
|
#include <nel/sound/source_common.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
// using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NLSOUND {
|
||||||
|
|
||||||
|
CGroupController::CGroupController(CGroupController *parent) :
|
||||||
|
m_Parent(parent), m_DevGain(1.0f), m_UserGain(1.0f), m_NbSourcesInclChild(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CGroupController::~CGroupController()
|
||||||
|
{
|
||||||
|
// If m_Sources is not empty, a crash is very likely.
|
||||||
|
nlassert(m_Sources.empty());
|
||||||
|
|
||||||
|
for (std::map<std::string, CGroupController *>::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it)
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
it->second = NULL;
|
||||||
|
}
|
||||||
|
m_Parent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::addSource(CSourceCommon *source)
|
||||||
|
{
|
||||||
|
m_Sources.insert(source);
|
||||||
|
increaseSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::removeSource(CSourceCommon *source)
|
||||||
|
{
|
||||||
|
decreaseSources();
|
||||||
|
m_Sources.erase(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::calculateFinalGain() // overridden by root
|
||||||
|
{
|
||||||
|
m_FinalGain = calculateTotalGain() * m_Parent->getFinalGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::updateSourceGain()
|
||||||
|
{
|
||||||
|
// Dont update source gain when this controller is inactive.
|
||||||
|
if (m_NbSourcesInclChild)
|
||||||
|
{
|
||||||
|
calculateFinalGain();
|
||||||
|
for (CAudioMixerUser::TSourceContainer::iterator it(m_Sources.begin()), end(m_Sources.end()); it != end; ++it)
|
||||||
|
(*it)->updateFinalGain();
|
||||||
|
for (std::map<std::string, CGroupController *>::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it)
|
||||||
|
(*it).second->updateSourceGain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::increaseSources() // overridden by root
|
||||||
|
{
|
||||||
|
++m_NbSourcesInclChild;
|
||||||
|
m_Parent->increaseSources();
|
||||||
|
|
||||||
|
// Update source gain when this controller was inactive before but the parent was active before.
|
||||||
|
// Thus, when this controller was the root of inactive controllers.
|
||||||
|
if (m_NbSourcesInclChild == 1 && m_Parent->m_NbSourcesInclChild > 1)
|
||||||
|
updateSourceGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::decreaseSources() // overridden by root
|
||||||
|
{
|
||||||
|
--m_NbSourcesInclChild;
|
||||||
|
m_Parent->decreaseSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
/* end of file */
|
99
code/nel/src/sound/group_controller_root.cpp
Normal file
99
code/nel/src/sound/group_controller_root.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* \file group_controller_root.cpp
|
||||||
|
* \brief CGroupControllerRoot
|
||||||
|
* \date 2012-04-10 09:44GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CGroupControllerRoot
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE.
|
||||||
|
* RYZOM CORE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdsound.h"
|
||||||
|
#include <nel/sound/group_controller_root.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
// #include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/algo.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
// using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NLSOUND {
|
||||||
|
|
||||||
|
CGroupControllerRoot::CGroupControllerRoot() : CGroupController(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CGroupControllerRoot::~CGroupControllerRoot()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupControllerRoot::calculateFinalGain()
|
||||||
|
{
|
||||||
|
m_FinalGain = calculateTotalGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::increaseSources()
|
||||||
|
{
|
||||||
|
++m_NbSourcesInclChild;
|
||||||
|
|
||||||
|
// Update source gain when this controller was inactive before.
|
||||||
|
if (m_NbSourcesInclChild == 1)
|
||||||
|
updateSourceGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroupController::decreaseSources()
|
||||||
|
{
|
||||||
|
--m_NbSourcesInclChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGroupController *CGroupControllerRoot::getGroupController(const std::string &path)
|
||||||
|
{
|
||||||
|
std::vector<std::string> pathNodes;
|
||||||
|
NLMISC::splitString(NLMISC::toLower(path), "/", pathNodes);
|
||||||
|
CGroupController *active = this;
|
||||||
|
for (std::vector<std::string>::iterator it(pathNodes.begin()), end(pathNodes.end()); it != end; ++it)
|
||||||
|
{
|
||||||
|
if (!(*it).empty())
|
||||||
|
{
|
||||||
|
std::map<std::string, CGroupController *>::iterator found = active->m_Children.find(*it);
|
||||||
|
if (found == active->m_Children.end())
|
||||||
|
{
|
||||||
|
active = new CGroupController(active);
|
||||||
|
active->m_Parent->m_Children[*it] = active;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
active = (*found).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace NLSOUND */
|
||||||
|
|
||||||
|
/* end of file */
|
|
@ -26,8 +26,8 @@ namespace NLSOUND {
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
CMusicSource::CMusicSource(CMusicSound *musicSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CMusicSource::CMusicSource(CMusicSound *musicSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: CSourceCommon(musicSound, spawn, cb, cbUserParam, cluster)
|
: CSourceCommon(musicSound, spawn, cb, cbUserParam, cluster, groupController)
|
||||||
{
|
{
|
||||||
_MusicSound= musicSound;
|
_MusicSound= musicSound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ using namespace NLMISC;
|
||||||
|
|
||||||
namespace NLSOUND {
|
namespace NLSOUND {
|
||||||
|
|
||||||
CSimpleSource::CSimpleSource(CSimpleSound *simpleSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CSimpleSource::CSimpleSource(CSimpleSound *simpleSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: CSourceCommon(simpleSound, spawn, cb, cbUserParam, cluster),
|
: CSourceCommon(simpleSound, spawn, cb, cbUserParam, cluster, groupController),
|
||||||
_SimpleSound(simpleSound),
|
_SimpleSound(simpleSound),
|
||||||
_Track(NULL),
|
_Track(NULL),
|
||||||
_PlayMuted(false)
|
_PlayMuted(false)
|
||||||
|
@ -166,7 +166,7 @@ void CSimpleSource::play()
|
||||||
setDirection(_Direction); // because there is a workaround inside
|
setDirection(_Direction); // because there is a workaround inside
|
||||||
pSource->setVelocity(_Velocity);
|
pSource->setVelocity(_Velocity);
|
||||||
}
|
}
|
||||||
pSource->setGain(_Gain);
|
pSource->setGain(getFinalGain());
|
||||||
pSource->setSourceRelativeMode(_RelativeMode);
|
pSource->setSourceRelativeMode(_RelativeMode);
|
||||||
pSource->setLooping(_Looping);
|
pSource->setLooping(_Looping);
|
||||||
pSource->setPitch(_Pitch);
|
pSource->setPitch(_Pitch);
|
||||||
|
@ -312,35 +312,12 @@ void CSimpleSource::setDirection(const NLMISC::CVector& dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimpleSource::updateFinalGain()
|
||||||
/* Set the gain (volume value inside [0 , 1]). (default: 1)
|
|
||||||
* 0.0 -> silence
|
|
||||||
* 0.5 -> -6dB
|
|
||||||
* 1.0 -> no attenuation
|
|
||||||
* values > 1 (amplification) not supported by most drivers
|
|
||||||
*/
|
|
||||||
void CSimpleSource::setGain(float gain)
|
|
||||||
{
|
{
|
||||||
CSourceCommon::setGain(gain);
|
|
||||||
|
|
||||||
// Set the gain
|
// Set the gain
|
||||||
if (hasPhysicalSource())
|
if (hasPhysicalSource())
|
||||||
{
|
getPhysicalSource()->setGain(getFinalGain());
|
||||||
getPhysicalSource()->setGain(gain);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CSimpleSource::setRelativeGain(float gain)
|
|
||||||
{
|
|
||||||
CSourceCommon::setRelativeGain(gain);
|
|
||||||
|
|
||||||
// Set the gain
|
|
||||||
if (hasPhysicalSource())
|
|
||||||
{
|
|
||||||
getPhysicalSource()->setGain(_Gain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
|
/* Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
|
||||||
* of one octave. 0 is not a legal value.
|
* of one octave. 0 is not a legal value.
|
||||||
|
|
|
@ -25,7 +25,7 @@ using namespace NLMISC;
|
||||||
namespace NLSOUND
|
namespace NLSOUND
|
||||||
{
|
{
|
||||||
|
|
||||||
CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: _Priority(MidPri),
|
: _Priority(MidPri),
|
||||||
_Playing(false),
|
_Playing(false),
|
||||||
_Looping(false),
|
_Looping(false),
|
||||||
|
@ -41,9 +41,11 @@ CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void
|
||||||
_SpawnEndCb(cb),
|
_SpawnEndCb(cb),
|
||||||
_CbUserParam(cbUserParam),
|
_CbUserParam(cbUserParam),
|
||||||
_Cluster(cluster),
|
_Cluster(cluster),
|
||||||
_UserVarControler(id->getUserVarControler())
|
_UserVarControler(id->getUserVarControler()),
|
||||||
|
_GroupController(groupController ? groupController : id->getGroupController())
|
||||||
{
|
{
|
||||||
CAudioMixerUser::instance()->addSource(this);
|
CAudioMixerUser::instance()->addSource(this);
|
||||||
|
groupController->addSource(this);
|
||||||
|
|
||||||
// get a local copy of the sound parameter
|
// get a local copy of the sound parameter
|
||||||
_InitialGain = _Gain = id->getGain();
|
_InitialGain = _Gain = id->getGain();
|
||||||
|
@ -51,11 +53,11 @@ CSourceCommon::CSourceCommon(TSoundId id, bool spawn, TSpawnEndCallback cb, void
|
||||||
_Looping = id->getLooping();
|
_Looping = id->getLooping();
|
||||||
_Priority = id->getPriority();
|
_Priority = id->getPriority();
|
||||||
_Direction = id->getDirectionVector();
|
_Direction = id->getDirectionVector();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSourceCommon::~CSourceCommon()
|
CSourceCommon::~CSourceCommon()
|
||||||
{
|
{
|
||||||
|
_GroupController->removeSource(this);
|
||||||
CAudioMixerUser::instance()->removeSource(this);
|
CAudioMixerUser::instance()->removeSource(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +179,7 @@ void CSourceCommon::setGain( float gain )
|
||||||
{
|
{
|
||||||
clamp(gain, 0.0f, 1.0f);
|
clamp(gain, 0.0f, 1.0f);
|
||||||
_InitialGain = _Gain = gain;
|
_InitialGain = _Gain = gain;
|
||||||
|
updateFinalGain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain
|
/* Set the gain amount (value inside [0, 1]) to map between 0 and the nominal gain
|
||||||
|
@ -185,8 +188,8 @@ void CSourceCommon::setGain( float gain )
|
||||||
void CSourceCommon::setRelativeGain( float gain )
|
void CSourceCommon::setRelativeGain( float gain )
|
||||||
{
|
{
|
||||||
clamp(gain, 0.0f, 1.0f);
|
clamp(gain, 0.0f, 1.0f);
|
||||||
|
|
||||||
_Gain = _InitialGain * gain;
|
_Gain = _InitialGain * gain;
|
||||||
|
updateFinalGain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -28,8 +28,8 @@ using namespace NLMISC;
|
||||||
|
|
||||||
namespace NLSOUND {
|
namespace NLSOUND {
|
||||||
|
|
||||||
CStreamSource::CStreamSource(CStreamSound *streamSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster)
|
CStreamSource::CStreamSource(CStreamSound *streamSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
|
||||||
: CSourceCommon(streamSound, spawn, cb, cbUserParam, cluster),
|
: CSourceCommon(streamSound, spawn, cb, cbUserParam, cluster, groupController),
|
||||||
m_StreamSound(streamSound),
|
m_StreamSound(streamSound),
|
||||||
m_Alpha(0.0f),
|
m_Alpha(0.0f),
|
||||||
m_Track(NULL),
|
m_Track(NULL),
|
||||||
|
@ -177,7 +177,7 @@ void CStreamSource::play()
|
||||||
setDirection(_Direction); // because there is a workaround inside
|
setDirection(_Direction); // because there is a workaround inside
|
||||||
pSource->setVelocity(_Velocity);
|
pSource->setVelocity(_Velocity);
|
||||||
}
|
}
|
||||||
pSource->setGain(_Gain);
|
pSource->setGain(getFinalGain());
|
||||||
pSource->setSourceRelativeMode(_RelativeMode);
|
pSource->setSourceRelativeMode(_RelativeMode);
|
||||||
// pSource->setLooping(_Looping);
|
// pSource->setLooping(_Looping);
|
||||||
pSource->setPitch(_Pitch);
|
pSource->setPitch(_Pitch);
|
||||||
|
@ -294,22 +294,12 @@ void CStreamSource::setDirection(const NLMISC::CVector& dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStreamSource::setGain(float gain)
|
void CStreamSource::updateFinalGain()
|
||||||
{
|
{
|
||||||
CAutoMutex<CMutex> autoMutex(m_BufferMutex);
|
CAutoMutex<CMutex> autoMutex(m_BufferMutex);
|
||||||
|
|
||||||
CSourceCommon::setGain(gain);
|
|
||||||
if (hasPhysicalSource())
|
if (hasPhysicalSource())
|
||||||
getPhysicalSource()->setGain(gain);
|
getPhysicalSource()->setGain(getFinalGain());
|
||||||
}
|
|
||||||
|
|
||||||
void CStreamSource::setRelativeGain(float gain)
|
|
||||||
{
|
|
||||||
CAutoMutex<CMutex> autoMutex(m_BufferMutex);
|
|
||||||
|
|
||||||
CSourceCommon::setRelativeGain(gain);
|
|
||||||
if (hasPhysicalSource())
|
|
||||||
getPhysicalSource()->setGain(_Gain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStreamSource::setPitch(float pitch)
|
void CStreamSource::setPitch(float pitch)
|
||||||
|
|
Loading…
Reference in a new issue