Skip to content

Commit

Permalink
Introduce Sound Scene
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed Dec 4, 2023
1 parent 3fbf7f4 commit dfa50c2
Show file tree
Hide file tree
Showing 22 changed files with 733 additions and 590 deletions.
14 changes: 8 additions & 6 deletions src/xrEngine/IGame_Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ IGame_Level::IGame_Level()
bReady = false;
pCurrentEntity = NULL;
pCurrentViewEntity = NULL;
Sound = GEnv.Sound->create_scene();
DefaultSoundScene = Sound;
#ifndef MASTER_GOLD
GEnv.Render->ResourcesDumpMemoryUsage();
#endif
Expand All @@ -44,8 +46,8 @@ IGame_Level::~IGame_Level()
Device.seqFrame.Remove(this);
CCameraManager::ResetPP();
///////////////////////////////////////////
GEnv.Sound->set_geometry_occ(nullptr);
GEnv.Sound->set_handler(nullptr);
DefaultSoundScene = g_pGamePersistent->m_pSound;
GEnv.Sound->destroy_scene(Sound);
#ifndef MASTER_GOLD
GEnv.Render->ResourcesDumpMemoryUsage();
#endif
Expand Down Expand Up @@ -115,8 +117,8 @@ bool IGame_Level::Load(u32 dwNum)
g_pGamePersistent->SpatialSpace.initialize(ObjectSpace.GetBoundingVolume());
g_pGamePersistent->SpatialSpacePhysic.initialize(ObjectSpace.GetBoundingVolume());

GEnv.Sound->set_geometry_occ(ObjectSpace.GetStaticModel());
GEnv.Sound->set_handler([](const ref_sound& S, float range)
Sound->set_geometry_occ(ObjectSpace.GetStaticModel());
Sound->set_handler([](const ref_sound& S, float range)
{
if (g_pGameLevel && S && S->feedback)
g_pGameLevel->SoundEvent_Register(S, range);
Expand Down Expand Up @@ -303,7 +305,7 @@ void IGame_Level::SoundEvent_Register(const ref_sound& S, float range)

// Energy and signal
VERIFY(_valid(it->GetSpatialData().sphere.P));
float dist = snd_position.distance_to(it->GetSpatialData().sphere.P);
const float dist = snd_position.distance_to(it->GetSpatialData().sphere.P);
if (dist > p->max_ai_distance)
continue;
VERIFY(_valid(dist));
Expand All @@ -312,7 +314,7 @@ void IGame_Level::SoundEvent_Register(const ref_sound& S, float range)
VERIFY(_valid(Power));
if (Power > EPS_S)
{
float occ = GEnv.Sound->get_occlusion_to(it->GetSpatialData().sphere.P, snd_position);
const float occ = Sound->get_occlusion_to(it->GetSpatialData().sphere.P, snd_position);
VERIFY(_valid(occ));
Power *= occ;
if (Power > EPS_S)
Expand Down
2 changes: 2 additions & 0 deletions src/xrEngine/IGame_Level.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class ENGINE_API IGame_Level : public FactoryObjectBase,
xr_vector<ISpatial*> snd_ER;

public:
ISoundScene* Sound{};

CObjectList Objects;
CObjectSpace ObjectSpace;
CCameraManager& Cameras() { return *m_pCameras; };
Expand Down
6 changes: 6 additions & 0 deletions src/xrEngine/IGame_Persistent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,16 @@ IGame_Persistent::IGame_Persistent()
pEnvironment = xr_new<CEnvironment>();

m_pGShaderConstants = xr_new<ShadersExternalData>(); //--#SM+#--

m_pSound = GEnv.Sound->create_scene();
DefaultSoundScene = m_pSound;
}

IGame_Persistent::~IGame_Persistent()
{
GEnv.Sound->destroy_scene(m_pSound);
DefaultSoundScene = nullptr;

xr_delete(PerlinNoise1D);
Device.seqFrame.Remove(this);
Device.seqAppStart.Remove(this);
Expand Down
1 change: 1 addition & 0 deletions src/xrEngine/IGame_Persistent.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class ENGINE_API IGame_Persistent :
CEnvironment& Environment() { return *pEnvironment; };
void Prefetch();
#endif
ISoundScene* m_pSound{};
IMainMenu* m_pMainMenu{};
static bool IsMainMenuActive();
static bool MainMenuActiveOrLevelNotExist();
Expand Down
2 changes: 1 addition & 1 deletion src/xrEngine/xr_object_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ void CObjectList::Update(bool bForce)
(*oit)->net_Relcase(destroy_queue[it]);

for (int it = destroy_queue.size() - 1; it >= 0; it--)
GEnv.Sound->object_relcase(destroy_queue[it]);
g_pGameLevel->Sound->object_relcase(destroy_queue[it]);

RELCASE_CALLBACK_VEC::iterator it = m_relcase_callbacks.begin();
const RELCASE_CALLBACK_VEC::iterator ite = m_relcase_callbacks.end();
Expand Down
4 changes: 2 additions & 2 deletions src/xrGame/Level_load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ bool CLevel::Load_GameSpecific_After()
if (FS.exist(fn_game, "$level$", "level.snd_env"))
{
IReader* F = FS.r_open(fn_game);
GEnv.Sound->set_geometry_env(F);
Sound->set_geometry_env(F);
FS.r_close(F);
}
// loading SOM
if (FS.exist(fn_game, "$level$", "level.som"))
{
IReader* F = FS.r_open(fn_game);
GEnv.Sound->set_geometry_som(F);
Sound->set_geometry_som(F);
FS.r_close(F);
}

Expand Down
2 changes: 1 addition & 1 deletion src/xrGame/level_sounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void SStaticSound::Update(u32 game_time, u32 global_time)
if (0 == m_Source._feedback())
{
Fvector occ[3];
const float occluder_volume = GEnv.Sound->get_occlusion(m_Position, .2f, occ);
const float occluder_volume = g_pGameLevel->Sound->get_occlusion(m_Position, .2f, occ);
const float vol = m_Volume * occluder_volume;

if ((0 == m_PauseTime.x) && (0 == m_PauseTime.y))
Expand Down
2 changes: 2 additions & 0 deletions src/xrSound/Sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

XRSOUND_API u32 snd_device_id = u32(-1);

ISoundScene* DefaultSoundScene{};

void CSoundManager::CreateDevicesList()
{
static bool noSound = strstr(Core.Params, "-nosound");
Expand Down
71 changes: 50 additions & 21 deletions src/xrSound/Sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ constexpr pcstr SNDENV_FILENAME = "sEnvironment.xr";
class IGameObject;
class CSound;
struct resptrcode_sound;
class ISoundScene;
class XRSOUND_API CSound_params;
class XRSOUND_API CSound_source;
class XRSOUND_API CSound_emitter;
Expand Down Expand Up @@ -52,6 +53,8 @@ XRSOUND_API extern int psSoundCacheSizeMB;
XRSOUND_API extern u32 psSoundPrecacheAll;
XRSOUND_API extern u32 snd_device_id;

XRSOUND_API extern ISoundScene* DefaultSoundScene;

// Flags
enum : u32
{
Expand Down Expand Up @@ -200,6 +203,40 @@ namespace CDB
class MODEL;
}

class XRSOUND_API XR_NOVTABLE ISoundScene
{
protected:
friend struct resptrcode_sound;

public:
virtual ~ISoundScene() = 0;

virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0;
virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0;
virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr,
float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0;

virtual void stop_emitters() const = 0;
virtual int pause_emitters(bool pauseState) = 0;

virtual void set_handler(sound_event* E) = 0;
virtual void set_geometry_env(IReader* I) = 0;
virtual void set_geometry_som(IReader* I) = 0;
virtual void set_geometry_occ(CDB::MODEL* M) = 0;

virtual void set_user_env(CSound_environment* E) = 0;
virtual void set_environment(u32 id, CSound_environment** dst_env) = 0;
virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) = 0;
virtual CSound_environment* get_environment(const Fvector& P) = 0;

virtual float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) = 0;
virtual float get_occlusion(Fvector& P, float R, Fvector* occ) = 0;

virtual void object_relcase(IGameObject* obj) = 0;
};

inline ISoundScene::~ISoundScene() = default;

/// definition (Sound Manager Interface)
class XRSOUND_API XR_NOVTABLE ISoundManager
{
Expand All @@ -212,43 +249,30 @@ class XRSOUND_API XR_NOVTABLE ISoundManager

virtual void attach_tail(CSound& S, pcstr fName) = 0;

virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0;
virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0;
virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr,
float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0;

public:
virtual ~ISoundManager() = default;

virtual ISoundScene* create_scene() = 0;
virtual void destroy_scene(ISoundScene*&) = 0;

virtual void _restart() = 0;
virtual bool i_locked() = 0;

virtual void prefetch() = 0;

virtual void stop_emitters() = 0;
virtual int pause_emitters(bool val) = 0;
virtual int pause_emitters(bool pauseState) = 0;

virtual void set_master_volume(float f = 1.f) = 0;
virtual void set_geometry_env(IReader* I) = 0;
virtual void set_geometry_som(IReader* I) = 0;
virtual void set_geometry_occ(CDB::MODEL* M) = 0;
virtual void set_handler(sound_event* E) = 0;

virtual void update(const Fvector& P, const Fvector& D, const Fvector& N) = 0;
virtual void statistic(CSound_stats* s0, CSound_stats_ext* s1) = 0;
virtual void DumpStatistics(class IGameFont& font, class IPerformanceAlert* alert) = 0;

virtual float get_occlusion_to(const Fvector& hear_pt, const Fvector& snd_pt, float dispersion = 0.2f) = 0;
virtual float get_occlusion(Fvector& P, float R, Fvector* occ) = 0;

virtual void object_relcase(IGameObject* obj) = 0;
virtual const Fvector& listener_position() = 0;

virtual void refresh_env_library() = 0;
virtual void set_user_env(CSound_environment* E) = 0;
virtual void refresh_sources() = 0;
virtual void set_environment(u32 id, CSound_environment** dst_env) = 0;
virtual void set_environment_size(CSound_environment* src_env, CSound_environment** dst_env) = 0;
};

class XRSOUND_API CSoundManager
Expand Down Expand Up @@ -331,7 +355,6 @@ struct resptrcode_sound : public resptr_base<CSound>
[[nodiscard]]
ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; }


bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true)
{
VerSndUnlocked();
Expand Down Expand Up @@ -369,20 +392,26 @@ struct resptrcode_sound : public resptr_base<CSound>

void play(IGameObject* O, u32 flags = 0, float delay = 0.f)
{
if (!p_ || !DefaultSoundScene)
return;
VerSndUnlocked();
GEnv.Sound->play(static_cast<ref_sound&>(*this), O, flags, delay);
DefaultSoundScene->play(static_cast<ref_sound&>(*this), O, flags, delay);
}

void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f)
{
if (!p_ || !DefaultSoundScene)
return;
VerSndUnlocked();
GEnv.Sound->play_at_pos(static_cast<ref_sound&>(*this), O, pos, flags, delay);
DefaultSoundScene->play_at_pos(static_cast<ref_sound&>(*this), O, pos, flags, delay);
}

void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr)
{
if (!p_ || !DefaultSoundScene)
return;
VerSndUnlocked();
GEnv.Sound->play_no_feedback(static_cast<ref_sound&>(*this), O, flags, delay, pos, vol, freq, range);
DefaultSoundScene->play_no_feedback(static_cast<ref_sound&>(*this), O, flags, delay, pos, vol, freq, range);
}

ICF void stop() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); }
Expand Down
Loading

0 comments on commit dfa50c2

Please sign in to comment.