Added: #1459 Load group controller from sound sheets

--HG--
branch : sound_dev
This commit is contained in:
kaetemi 2012-04-10 16:32:04 +02:00
parent 0b64102ab8
commit 11f0872a01
13 changed files with 181 additions and 32 deletions

View file

@ -34,6 +34,14 @@
#include "nel/sound/mixing_track.h" #include "nel/sound/mixing_track.h"
#include "nel/sound/sound.h" #include "nel/sound/sound.h"
#include "nel/sound/music_channel_fader.h" #include "nel/sound/music_channel_fader.h"
#include "nel/sound/group_controller_root.h"
// Current version is 2, Ryzom Live uses 1
// Provided to allow compatibility with old binary files
#define NLSOUND_SHEET_VERSION_BUILT 1
#define NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER "effects"
#define NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER "music"
#define NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER "dialog"
namespace NLLIGO { namespace NLLIGO {
class CLigoConfig; class CLigoConfig;
@ -51,26 +59,6 @@ namespace NLSOUND {
class CMusicSoundManager; class CMusicSoundManager;
class IReverbEffect; class IReverbEffect;
/// Hasher functor for hashed container with pointer key.
template <class Pointer>
struct THashPtr : public std::unary_function<const Pointer &, size_t>
{
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
size_t operator () (const Pointer &ptr) const
{
//CHashSet<uint>::hasher h;
// transtype the pointer into int then hash it
//return h.operator()(uint(uintptr_t(ptr)));
return (size_t)(uintptr_t)ptr;
}
inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const
{
// delegate the work to someone else as well?
return (uintptr_t)ptr1 < (uintptr_t)ptr2;
}
};
/** /**
* Implementation of UAudioMixer * Implementation of UAudioMixer
* *
@ -197,6 +185,9 @@ public:
/// Get a TSoundId from a name (returns NULL if not found) /// Get a TSoundId from a name (returns NULL if not found)
virtual TSoundId getSoundId( const NLMISC::TStringId &name ); virtual TSoundId getSoundId( const NLMISC::TStringId &name );
/// Gets the group controller for the given group tree path with separator '/', if it doesn't exist yet it will be created.
/// Examples: "music", "effects", "dialog", "music/background", "music/loading", "music/player", etcetera
virtual UGroupController *getGroupController(const std::string &path);
/** Add a logical sound source (returns NULL if name not found). /** Add a logical sound source (returns NULL if name not found).
* If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer * If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer
@ -431,9 +422,6 @@ 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;
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;
@ -566,6 +554,9 @@ private:
// Instance of the background music manager // Instance of the background music manager
CMusicSoundManager *_BackgroundMusicManager; CMusicSoundManager *_BackgroundMusicManager;
/// Group controller
CGroupControllerRoot _GroupController;
public: public:
struct TSampleBankHeader struct TSampleBankHeader
{ {

View file

@ -0,0 +1,67 @@
/**
* \file containers.h
* \brief CContainers
* \date 2012-04-10 13:57GMT
* \author Unknown (Unknown)
* CContainers
*/
/*
* 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_CONTAINERS_H
#define NLSOUND_CONTAINERS_H
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
// Project includes
namespace NLSOUND {
class CSourceCommon;
/// Hasher functor for hashed container with pointer key.
template <class Pointer>
struct THashPtr : public std::unary_function<const Pointer &, size_t>
{
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
size_t operator () (const Pointer &ptr) const
{
//CHashSet<uint>::hasher h;
// transtype the pointer into int then hash it
//return h.operator()(uint(uintptr_t(ptr)));
return (size_t)(uintptr_t)ptr;
}
inline bool operator() (const Pointer &ptr1, const Pointer &ptr2) const
{
// delegate the work to someone else as well?
return (uintptr_t)ptr1 < (uintptr_t)ptr2;
}
};
typedef CHashSet<CSourceCommon*, THashPtr<CSourceCommon*> > TSourceContainer;
} /* namespace NLSOUND */
#endif /* #ifndef NLSOUND_CONTAINERS_H */
/* end of file */

View file

@ -35,13 +35,12 @@
// NeL includes // NeL includes
#include <nel/misc/common.h> #include <nel/misc/common.h>
#include <nel/sound/audio_mixer_user.h>
#include <nel/sound/u_group_controller.h> #include <nel/sound/u_group_controller.h>
#include <nel/sound/containers.h>
// Project includes // Project includes
namespace NLSOUND { namespace NLSOUND {
class CSourceCommon;
class CGroupControllerRoot; class CGroupControllerRoot;
/** /**
@ -64,7 +63,7 @@ private:
float m_FinalGain; float m_FinalGain;
int m_NbSourcesInclChild; int m_NbSourcesInclChild;
CAudioMixerUser::TSourceContainer m_Sources; TSourceContainer m_Sources;
public: public:
CGroupController(CGroupController *parent); CGroupController(CGroupController *parent);
@ -83,8 +82,12 @@ public:
void addSource(CSourceCommon *source); void addSource(CSourceCommon *source);
void removeSource(CSourceCommon *source); void removeSource(CSourceCommon *source);
private: virtual std::string getPath();
protected:
virtual ~CGroupController(); // subnodes can only be deleted by the root virtual ~CGroupController(); // subnodes can only be deleted by the root
private:
inline float calculateTotalGain() { return m_DevGain * m_UserGain; } inline float calculateTotalGain() { return m_DevGain * m_UserGain; }
virtual void calculateFinalGain(); virtual void calculateFinalGain();
virtual void increaseSources(); virtual void increaseSources();

View file

@ -54,6 +54,7 @@ public:
CGroupController *getGroupController(const std::string &path); CGroupController *getGroupController(const std::string &path);
protected: protected:
virtual std::string getPath();
virtual void calculateFinalGain(); virtual void calculateFinalGain();
virtual void increaseSources(); virtual void increaseSources();
virtual void decreaseSources(); virtual void decreaseSources();

View file

@ -105,7 +105,7 @@ 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 inline CGroupController *getGroupController() const { return _GroupController; }
/// Set looping /// Set looping
void setLooping( bool looping ) { _Looping = looping; } void setLooping( bool looping ) { _Looping = looping; }
@ -145,6 +145,9 @@ protected:
/// An optional user var controler. /// An optional user var controler.
NLMISC::TStringId _UserVarControler; NLMISC::TStringId _UserVarControler;
/// The group controller, always exists, owned by the audio mixer
CGroupController *_GroupController;
}; };

View file

@ -286,6 +286,10 @@ public:
/// Get a TSoundId from a name (returns NULL if not found) /// Get a TSoundId from a name (returns NULL if not found)
virtual TSoundId getSoundId( const NLMISC::TStringId &name ) = 0; virtual TSoundId getSoundId( const NLMISC::TStringId &name ) = 0;
/// Gets the group controller for the given group tree path with separator '/', if it doesn't exist yet it will be created.
/// Examples: "music", "effects", "dialog", "music/background", "music/loading", "music/player", etcetera
virtual UGroupController *getGroupController(const std::string &path) = 0;
/** Add a logical sound source (returns NULL if name not found). /** Add a logical sound source (returns NULL if name not found).
* If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer * If spawn is true, the source will auto-delete after playing. If so, the return USource* pointer
* is valid only before the time when calling play() plus the duration of the sound. You can * is valid only before the time when calling play() plus the duration of the sound. You can

View file

@ -52,7 +52,7 @@ class UGroupController
virtual float getUserGain() = 0; virtual float getUserGain() = 0;
protected: protected:
virtual ~UGroupController(); virtual ~UGroupController() { }
}; /* class UGroupController */ }; /* class UGroupController */

View file

@ -52,6 +52,7 @@
#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" #include "nel/sound/group_controller.h"
#include "nel/sound/containers.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -1827,6 +1828,10 @@ bool CAudioMixerUser::tryToLoadSampleBank(const std::string &sampleName)
} }
} }
UGroupController *CAudioMixerUser::getGroupController(const std::string &path)
{
return static_cast<UGroupController *>(_GroupController.getGroupController(path));
}
// ****************************************************************** // ******************************************************************

View file

@ -72,6 +72,22 @@ void CGroupController::removeSource(CSourceCommon *source)
m_Sources.erase(source); m_Sources.erase(source);
} }
std::string CGroupController::getPath() // overridden by root
{
for (std::map<std::string, CGroupController *>::iterator it(m_Parent->m_Children.begin()), end(m_Parent->m_Children.end()); it != end; ++it)
{
if (it->second == this)
{
const std::string &name = it->first;
std::string returnPath = m_Parent->getPath() + "/" + name;
if (returnPath[0] == '/')
returnPath = returnPath.substr(1);
return returnPath;
}
}
}
void CGroupController::calculateFinalGain() // overridden by root void CGroupController::calculateFinalGain() // overridden by root
{ {
m_FinalGain = calculateTotalGain() * m_Parent->getFinalGain(); m_FinalGain = calculateTotalGain() * m_Parent->getFinalGain();
@ -83,7 +99,7 @@ void CGroupController::updateSourceGain()
if (m_NbSourcesInclChild) if (m_NbSourcesInclChild)
{ {
calculateFinalGain(); calculateFinalGain();
for (CAudioMixerUser::TSourceContainer::iterator it(m_Sources.begin()), end(m_Sources.end()); it != end; ++it) for (TSourceContainer::iterator it(m_Sources.begin()), end(m_Sources.end()); it != end; ++it)
(*it)->updateFinalGain(); (*it)->updateFinalGain();
for (std::map<std::string, CGroupController *>::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it) for (std::map<std::string, CGroupController *>::iterator it(m_Children.begin()), end(m_Children.end()); it != end; ++it)
(*it).second->updateSourceGain(); (*it).second->updateSourceGain();

View file

@ -51,12 +51,17 @@ CGroupControllerRoot::~CGroupControllerRoot()
} }
std::string CGroupControllerRoot::getPath()
{
return "";
}
void CGroupControllerRoot::calculateFinalGain() void CGroupControllerRoot::calculateFinalGain()
{ {
m_FinalGain = calculateTotalGain(); m_FinalGain = calculateTotalGain();
} }
void CGroupController::increaseSources() void CGroupControllerRoot::increaseSources()
{ {
++m_NbSourcesInclChild; ++m_NbSourcesInclChild;
@ -65,7 +70,7 @@ void CGroupController::increaseSources()
updateSourceGain(); updateSourceGain();
} }
void CGroupController::decreaseSources() void CGroupControllerRoot::decreaseSources()
{ {
--m_NbSourcesInclChild; --m_NbSourcesInclChild;
} }

View file

@ -20,6 +20,9 @@
#include "nel/misc/path.h" #include "nel/misc/path.h"
#include "nel/georges/u_form_elm.h" #include "nel/georges/u_form_elm.h"
#if NLSOUND_SHEET_VERSION_BUILT < 2
# include "nel/sound/audio_mixer_user.h"
#endif
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -72,6 +75,10 @@ void CMusicSound::importForm(const std::string& filename, NLGEORGES::UFormElm&
root.getValueByName(_MinimumPlayTime, ".SoundType.MinimumPlayTime"); root.getValueByName(_MinimumPlayTime, ".SoundType.MinimumPlayTime");
root.getValueByName(_TimeBeforeCanReplay, ".SoundType.TimeBeforeCanReplay"); root.getValueByName(_TimeBeforeCanReplay, ".SoundType.TimeBeforeCanReplay");
#if NLSOUND_SHEET_VERSION_BUILT < 2
_GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER));
#endif
} }
// *************************************************************************** // ***************************************************************************
@ -97,6 +104,11 @@ void CMusicSound::serial(NLMISC::IStream &s)
CStringMapper::serialString(s, _FileName); CStringMapper::serialString(s, _FileName);
s.serial(_FadeInLength, _FadeOutLength); s.serial(_FadeInLength, _FadeOutLength);
s.serial(_MinimumPlayTime, _TimeBeforeCanReplay); s.serial(_MinimumPlayTime, _TimeBeforeCanReplay);
#if NLSOUND_SHEET_VERSION_BUILT < 2
if (s.isReading()) _GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_MUSIC_GROUP_CONTROLLER));
#endif
} }
// *************************************************************************** // ***************************************************************************

View file

@ -27,6 +27,8 @@
#include "nel/sound/music_sound.h" #include "nel/sound/music_sound.h"
#include "nel/sound/stream_sound.h" #include "nel/sound/stream_sound.h"
#include "nel/sound/group_controller.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -134,6 +136,23 @@ void CSound::serial(NLMISC::IStream &s)
std::string name = CStringMapper::unmap(_Name); std::string name = CStringMapper::unmap(_Name);
s.serial(name); s.serial(name);
} }
nlassert(CAudioMixerUser::instance()); // not sure
#if NLSOUND_SHEET_VERSION_BUILT < 2
if (s.isReading()) _GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER));
#else
if (s.isReading())
{
std::string groupControllerPath;
s.serial(groupControllerPath);
_GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(groupControllerPath));
}
else
{
std::string groupControllerPath = _GroupController->getPath();
s.serial(groupControllerPath);
}
#endif
} }
@ -225,6 +244,15 @@ void CSound::importForm(const std::string& filename, NLGEORGES::UFormElm& roo
default: default:
_Priority = MidPri; _Priority = MidPri;
} }
#if NLSOUND_SHEET_VERSION_BUILT < 2
_GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_GROUP_CONTROLLER));
#else
std::string groupControllerPath;
root.getValueByName(groupControllerPath, ".GroupControllerPath");
_GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(groupControllerPath));
#endif
} }

View file

@ -17,6 +17,10 @@
#include "stdsound.h" #include "stdsound.h"
#include "nel/sound/stream_sound.h" #include "nel/sound/stream_sound.h"
#if NLSOUND_SHEET_VERSION_BUILT < 2
# include "nel/sound/audio_mixer_user.h"
#endif
namespace NLSOUND { namespace NLSOUND {
CStreamSound::CStreamSound() CStreamSound::CStreamSound()
@ -51,6 +55,11 @@ void CStreamSound::importForm(const std::string &filename, NLGEORGES::UFormElm &
// Alpha // Alpha
root.getValueByName(m_Alpha, ".SoundType.Alpha"); root.getValueByName(m_Alpha, ".SoundType.Alpha");
#if NLSOUND_SHEET_VERSION_BUILT < 2
_GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER));
#endif
} }
void CStreamSound::serial(NLMISC::IStream &s) void CStreamSound::serial(NLMISC::IStream &s)
@ -59,6 +68,11 @@ void CStreamSound::serial(NLMISC::IStream &s)
s.serial(_MinDist); s.serial(_MinDist);
s.serial(m_Alpha); s.serial(m_Alpha);
#if NLSOUND_SHEET_VERSION_BUILT < 2
if (s.isReading()) _GroupController = static_cast<CGroupController *>(CAudioMixerUser::instance()->getGroupController(NLSOUND_SHEET_V1_DEFAULT_SOUND_STREAM_GROUP_CONTROLLER));
#endif
} }
} /* namespace NLSOUND */ } /* namespace NLSOUND */