From fd6b4beeb7c6d966b9b04dc67d78407511a52ef1 Mon Sep 17 00:00:00 2001
From: Byurrer <byurrer@mail.ru>
Date: Sun, 14 Jun 2020 21:54:22 +0300
Subject: [PATCH] Added 3D sound

---
 proj/xSound/vs2013/xSound.vcxproj | 10 ++--
 sdks/mital                        |  2 +-
 source/common                     |  2 +-
 source/xEngine/Engine.cpp         |  9 ++--
 source/xSound/SoundBase.h         |  2 +-
 source/xSound/SoundEmitter.cpp    | 44 ++++++++++++----
 source/xSound/SoundEmitter.h      |  5 +-
 source/xSound/SoundLayer.cpp      | 18 +++++--
 source/xSound/SoundLayer.h        |  4 +-
 source/xSound/SoundPlayer.cpp     | 14 ++++-
 source/xSound/SoundPlayer.h       |  5 +-
 source/xSound/SoundSystem.cpp     |  6 ++-
 source/xSound/SoundSystem.h       | 23 ++++++++-
 source/xSound/plugin_main.cpp     | 86 ++++++++++++++++++++++++++++---
 14 files changed, 188 insertions(+), 42 deletions(-)

diff --git a/proj/xSound/vs2013/xSound.vcxproj b/proj/xSound/vs2013/xSound.vcxproj
index 656c8e772..fc868bf74 100644
--- a/proj/xSound/vs2013/xSound.vcxproj
+++ b/proj/xSound/vs2013/xSound.vcxproj
@@ -71,24 +71,24 @@
     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
     <OutDir>../../../build/bin/plugins/</OutDir>
     <TargetName>$(ProjectName)_d</TargetName>
-    <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../sdks/mital/lib/;</LibraryPath>
+    <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <TargetName>$(ProjectName)_d</TargetName>
-    <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../sdks/mital/lib64/;</LibraryPath>
+    <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../libs64;../../../sdks/mital/lib64/;</LibraryPath>
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;../../../sdks/;</IncludePath>
     <OutDir>../../../build/bin64/plugins/</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>../../../build/bin/plugins/</OutDir>
     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
-    <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../sdks/mital/lib/;</LibraryPath>
+    <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
-    <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../sdks/mital/lib64/;</LibraryPath>
+    <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../libs64;../../../sdks/mital/lib64/;</LibraryPath>
     <LinkIncremental>false</LinkIncremental>
     <OutDir>../../../build/bin64/plugins/</OutDir>
   </PropertyGroup>
diff --git a/sdks/mital b/sdks/mital
index e3bf76315..480bfc6f6 160000
--- a/sdks/mital
+++ b/sdks/mital
@@ -1 +1 @@
-Subproject commit e3bf76315c38eba4fde0e1b64f7afbcadeffddb3
+Subproject commit 480bfc6f618baa95129fcff28503727b43ea5940
diff --git a/source/common b/source/common
index 0dc806046..e41e5d467 160000
--- a/source/common
+++ b/source/common
@@ -1 +1 @@
-Subproject commit 0dc80604688a34568513f10d19139692174fc0c9
+Subproject commit e41e5d467c8436fb9fed92c66eebfb3a590e3e98
diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp
index 427f0d820..3ab5605f4 100644
--- a/source/xEngine/Engine.cpp
+++ b/source/xEngine/Engine.cpp
@@ -174,10 +174,11 @@ bool XMETHODCALLTYPE CEngine::initGraphics(XWINDOW_OS_HANDLE hWindow, IXEngineCa
 	IXSoundSystem *pSound = (IXSoundSystem*)(m_pCore->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID));
 	IXSoundLayer *pMasterLayer = pSound->createMasterLayer(&oAudioDesc, "master");
 	pMasterLayer->play(true);
-	/*IXSoundPlayer *pPlayer = pMasterLayer->newSoundPlayer("sounds/guitar_10.ogg", SOUND_DTYPE_2D);
-	//pPlayer->setLoop(SOUND_LOOP_SIMPLE);
-	pPlayer->play();
-	IXSoundEmitter *pEmitter = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_2D);
+	/*IXSoundPlayer *pPlayer = pMasterLayer->newSoundPlayer("sounds/guitar_10.ogg", SOUND_DTYPE_3D);
+	pPlayer->setWorldPos(float3(-11.084, 0.435, -18.707));
+	pPlayer->setLoop(SOUND_LOOP_SIMPLE);
+	pPlayer->play();*/
+	/*IXSoundEmitter *pEmitter = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_2D);
 	//pEmitter->play();
 
 	IXSoundEmitter *pEmitter2 = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_2D);
diff --git a/source/xSound/SoundBase.h b/source/xSound/SoundBase.h
index 6721f5e86..b6de20455 100644
--- a/source/xSound/SoundBase.h
+++ b/source/xSound/SoundBase.h
@@ -54,7 +54,7 @@ protected:
 	//IAudioBuffer *m_pAB = NULL;
 
 	//! дистанция слышимости
-	float m_fDist = 0.f;
+	float m_fDist = 10.f;
 
 	//! мировая позиция звука
 	float3 m_vWorldPos;
diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp
index d127bfe00..153610790 100644
--- a/source/xSound/SoundEmitter.cpp
+++ b/source/xSound/SoundEmitter.cpp
@@ -36,22 +36,31 @@ void XMETHODCALLTYPE CSoundEmitter::play()
 	if (!m_pLayer->isPlaying())
 		return;
 
+	float3 vPos, vLook, vUp;
+	m_pLayer->getObserverParam(&vPos, &vLook, &vUp);
+
+	IAudioBuffer *pAB = NULL;
+
 	//проход по массиву инстансов звука, если есть первый попавшийся не проигрываемые тогда его проигрываем
 	for (int i = 0, il = m_aInstances.size(); i<il; ++i)
 	{
 		if (!(m_aInstances[i].pAB->isPlaying()))
 		{
-			m_aInstances[i].pAB->setVolume(m_fVolume);
-			m_aInstances[i].pAB->play(true);
-			return;
+			pAB = m_aInstances[i].pAB;
+			continue;
 		}
 	}
 
-	//если пришли сюда, значит нет свободных инстансов, создаем новый и проигрыаем
-	IAudioBuffer *pInst = m_aInstances[0].pAB->newInstance();
-	pInst->setVolume(m_fVolume);
-	pInst->play(true);
-	m_aInstances.push_back(pInst);
+	if (!pAB)
+	{
+		//если пришли сюда, значит нет свободных инстансов, создаем новый и проигрыаем
+		IAudioBuffer *pInst = m_aInstances[0].pAB->newInstance();
+		pAB = pInst;
+		m_aInstances.push_back(pInst);
+	}
+
+	Com3D(pAB, m_fDist, m_vWorldPos, vPos, vLook, vUp);
+	pAB->play(true);
 }
 
 //**************************************************************************
@@ -78,11 +87,12 @@ void CSoundEmitter::pause()
 
 //**************************************************************************
 
-bool CSoundEmitter::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget)
+bool CSoundEmitter::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype)
 {
 	if (!pCodecTarget || !pLayer)
 		return false;
 
+	m_dtype = dtype;
 	AudioRawDesc oDesc;
 	pCodecTarget->getDesc(&oDesc);
 	m_pLayer = pLayer;
@@ -105,3 +115,19 @@ bool CSoundEmitter::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget
 
 	return true;
 }
+
+//##########################################################################
+
+void CSoundEmitter::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+{
+	if (m_dtype == SOUND_DTYPE_2D)
+		return;
+
+	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
+	{
+		if (m_aInstances[i].pAB->isPlaying())
+		{
+			Com3D(m_aInstances[i].pAB, m_fDist, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
+		}
+	}
+}
\ No newline at end of file
diff --git a/source/xSound/SoundEmitter.h b/source/xSound/SoundEmitter.h
index 87a1302fb..318fe7885 100644
--- a/source/xSound/SoundEmitter.h
+++ b/source/xSound/SoundEmitter.h
@@ -12,6 +12,7 @@ See the license in LICENSE
 #include <mital.h>
 
 #include "SoundTypes.h"
+#include "SoundSystem.h"
 
 //##########################################################################
 
@@ -31,13 +32,13 @@ public:
 	//! остановка проигрывания
 	void pause();
 
-	//void update();
+	void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp);
 
 protected:
 
 	friend CSoundLayer;
 
-	bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget);
+	bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype);
 
 	struct Instance
 	{
diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp
index aa9a298a9..618aa56a9 100644
--- a/source/xSound/SoundLayer.cpp
+++ b/source/xSound/SoundLayer.cpp
@@ -209,7 +209,7 @@ IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName,
 			return NULL;
 
 		pEmitter = new CSoundEmitter();
-		pEmitter->create(this, pCodecTarget);
+		pEmitter->create(this, pCodecTarget, dtype);
 	}
 
 	addSndEmitter(pEmitter, szName);
@@ -236,7 +236,7 @@ IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, S
 			return NULL;
 
 		pPlayer = new CSoundPlayer();
-		pPlayer->create(this, pCodecTarget);
+		pPlayer->create(this, pCodecTarget, dtype);
 	}
 
 	addSndPlayer(pPlayer, szName);
@@ -280,13 +280,21 @@ bool XMETHODCALLTYPE CSoundLayer::isPlaying() const
 	return m_isPlaying;
 }
 
-void CSoundLayer::update()
+void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
 	for (maplayer::Iterator i = m_mapLayers.begin(); i; i++)
-		m_mapLayers[i.first]->update();
+		m_mapLayers[i.first]->update(vListenerPos, vListenerDir, vListenerUp);
 
 	for (mapsoundplayer::Iterator i = m_mapSndPlayers.begin(); i; i++)
-		m_mapSndPlayers[i.first]->update();
+		m_mapSndPlayers[i.first]->update(vListenerPos, vListenerDir, vListenerUp);
+
+	for (mapsoundemitter::Iterator i = m_mapSndEmitters.begin(); i; i++)
+		m_mapSndEmitters[i.first]->update(vListenerPos, vListenerDir, vListenerUp);
+}
+
+void CSoundLayer::getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+{
+	m_pSoundSystem->getObserverParam(pPos, pLook, pUp);
 }
 
 bool CSoundLayer::matchPrimaryLayer(const AudioRawDesc *pDesc)
diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h
index a95a93356..06b901608 100644
--- a/source/xSound/SoundLayer.h
+++ b/source/xSound/SoundLayer.h
@@ -37,7 +37,9 @@ public:
 	uint32_t getStreamChunkSize(AudioRawDesc *pDesc) const;
 	IAudioBuffer* createAudioBuffer(AB_TYPE type, const AudioRawDesc *pDesc);
 
-	void update();
+	void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp);
+
+	void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
 
 protected:
 
diff --git a/source/xSound/SoundPlayer.cpp b/source/xSound/SoundPlayer.cpp
index 3220693dd..648532c1f 100644
--- a/source/xSound/SoundPlayer.cpp
+++ b/source/xSound/SoundPlayer.cpp
@@ -39,11 +39,12 @@ CSoundPlayer* CSoundPlayer::newInstance()
 
 //**************************************************************************
 
-bool CSoundPlayer::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget)
+bool CSoundPlayer::create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype)
 {
 	if (!pCodecTarget || !pLayer)
 		return false;
 
+	m_dtype = dtype;
 	m_pLayer = pLayer;
 	m_pCodecTarget = pCodecTarget;
 	AudioRawDesc oDesc;
@@ -95,6 +96,10 @@ void XMETHODCALLTYPE CSoundPlayer::play()
 	if (!m_pLayer->isPlaying())
 		return;
 
+	float3 vPos, vLook, vUp;
+	m_pLayer->getObserverParam(&vPos, &vLook, &vUp);
+
+	Com3D(m_pAB, m_fDist, m_vWorldPos, vPos, vLook, vUp);
 	m_pAB->play(true);
 	m_state = SOUND_STATE_PLAY;
 }
@@ -243,11 +248,16 @@ uint32_t CSoundPlayer::getPosBytes() const
 
 //##########################################################################
 
-void CSoundPlayer::update()
+void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
 	if (!m_pLayer->isPlaying())
 		return;
 
+	if (m_dtype == SOUND_DTYPE_3D)
+	{
+		Com3D(m_pAB, m_fDist, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
+	}
+
 	if (!m_pStream)
 		return;
 
diff --git a/source/xSound/SoundPlayer.h b/source/xSound/SoundPlayer.h
index 24c157b1a..e21098dd4 100644
--- a/source/xSound/SoundPlayer.h
+++ b/source/xSound/SoundPlayer.h
@@ -12,6 +12,7 @@ See the license in LICENSE
 #include <mital.h>
 
 #include "SoundTypes.h"
+#include "SoundSystem.h"
 
 //##########################################################################
 
@@ -43,9 +44,9 @@ protected:
 
 	friend CSoundLayer;
 
-	void update();
+	void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp);
 
-	bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget);
+	bool create(CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype);
 
 	//! возвращает текущую позицию проигрывания звука в байтах
 	uint32_t getPosBytes() const;
diff --git a/source/xSound/SoundSystem.cpp b/source/xSound/SoundSystem.cpp
index 46fb577ca..7109a7ce1 100644
--- a/source/xSound/SoundSystem.cpp
+++ b/source/xSound/SoundSystem.cpp
@@ -49,8 +49,12 @@ CSoundSystem::~CSoundSystem()
 
 void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
+	std::lock_guard<std::mutex> guard(m_oMutexUpdate);
+
 	if(m_pMasterLayer)
-		m_pMasterLayer->update();
+		m_pMasterLayer->update(vListenerPos, vListenerDir, vListenerUp);
+
+	m_vObserverPos = vListenerPos; m_vObserverLook = vListenerDir; m_vObserverUp = vListenerUp;
 }
 
 //**************************************************************************
diff --git a/source/xSound/SoundSystem.h b/source/xSound/SoundSystem.h
index 4bfd0841b..62ffad2c7 100644
--- a/source/xSound/SoundSystem.h
+++ b/source/xSound/SoundSystem.h
@@ -21,7 +21,7 @@ See the license in LICENSE
 
 //##########################################################################
 
-inline float Com3DPan(float3 &vSnd, float3 &vListenerPos, float3 &vListenerDir, float3 &vListenerUp)
+inline float Com3DPan(const float3 &vSnd, const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
 	float3 side = SMVector3Cross(vListenerUp, vListenerDir);
 	SMVector3Normalize(side);
@@ -32,11 +32,21 @@ inline float Com3DPan(float3 &vSnd, float3 &vListenerPos, float3 &vListenerDir,
 	return pan;
 }
 
+inline void Com3D(IAudioBuffer *pAB, float fDist, const float3 &vSnd, const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+{
+	float fPan = Com3DPan(vSnd, vListenerPos, vListenerDir, vListenerUp);
+	float fVolume = 1.f - saturatef(SMVector3Distance(vSnd, vListenerPos) / fDist);
+	fPan = lerpf(fPan, 0.f, fVolume);
+	pAB->setPan(fPan);
+	pAB->setVolume(fVolume);
+}
+
 //##########################################################################
 
 class CSoundSystem: public IXUnknownImplementation<IXSoundSystem>
 {
 public:
+	SX_ALIGNED_OP_MEM
 
 	CSoundSystem(IXCore *pXCore);
 	~CSoundSystem();
@@ -50,6 +60,14 @@ public:
 
 	IXCore* getCore() const;
 
+	void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+	{
+		while (!m_oMutexUpdate.try_lock()){}
+		m_oMutexUpdate.unlock();
+		
+		*pPos = m_vObserverPos; *pLook = m_vObserverLook; *pUp = m_vObserverUp;
+	}
+
 protected:
 
 	friend CSoundLayer;
@@ -69,6 +87,9 @@ protected:
 
 	typedef AssotiativeArray<String, IXAudioCodec*> mapcodec;
 	mapcodec m_mapCodecs;
+
+	float3 m_vObserverPos, m_vObserverLook, m_vObserverUp;
+	std::mutex m_oMutexUpdate;
 };
 
 #endif
diff --git a/source/xSound/plugin_main.cpp b/source/xSound/plugin_main.cpp
index a23d35dcb..f21f993d4 100644
--- a/source/xSound/plugin_main.cpp
+++ b/source/xSound/plugin_main.cpp
@@ -3,6 +3,7 @@
 #include <xcommon/IXUpdatable.h>
 #include "SoundSystem.h"
 #include <Audio.h>
+#include <gcore/sxgcore.h>
 
 #if defined(_DEBUG)
 #pragma comment(lib, "mital_d.lib")
@@ -10,13 +11,55 @@
 #pragma comment(lib, "mital.lib")
 #endif
 
+//##########################################################################
 
-class CUpdatable : public IXUnknownImplementation<IXUpdatable>
+class CObserverChangedEventListener : public IEventListener<XEventObserverChanged>
 {
 public:
-	CUpdatable(CSoundSystem *pSoundSystem)
+	SX_ALIGNED_OP_MEM
+
+	CObserverChangedEventListener(IXCore *pCore)
+	{
+		m_pObserverChangedEventChannel = pCore->getEventChannel<XEventObserverChanged>(EVENT_OBSERVER_CHANGED_GUID);
+		m_pObserverChangedEventChannel->addListener(this);
+	}
+
+	~CObserverChangedEventListener()
+	{
+		m_pObserverChangedEventChannel->removeListener(this);
+	}
+
+	void onEvent(const XEventObserverChanged *pData) override
+	{
+		std::lock_guard<std::mutex> guard(m_oMutex);
+		pData->pCamera->getPosition(&m_vPos);
+		pData->pCamera->getUp(&m_vUp);
+		pData->pCamera->getLook(&m_vLook);
+	}
+
+	void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+	{
+		std::lock_guard<std::mutex> guard(m_oMutex);
+		*pPos = m_vPos; *pLook = m_vLook; *pUp = m_vUp;
+	}
+
+protected:
+	IEventChannel<XEventObserverChanged> *m_pObserverChangedEventChannel = NULL;
+	float3 m_vPos, m_vLook, m_vUp;
+	std::mutex m_oMutex;
+};
+
+//##########################################################################
+
+class CUpdatableSoundSystem : public IXUnknownImplementation<IXUpdatable>
+{
+public:
+	SX_ALIGNED_OP_MEM
+
+	CUpdatableSoundSystem(CSoundSystem *pSoundSystem, CObserverChangedEventListener *pObserverListener)
 	{
 		m_pSoundSystem = pSoundSystem;
+		m_pObserverListener = pObserverListener;
 	}
 
 	UINT startup() override
@@ -30,9 +73,33 @@ public:
 
 	ID run(float fDelta) override
 	{
-		float3 v;
+		float3 vPos, vLook, vUp;
+
+		if (m_pObserverListener)
+			m_pObserverListener->getObserverParam(&vPos, &vLook, &vUp);
+
 		if (m_pSoundSystem)
-			m_pSoundSystem->update(v, v, v);
+			m_pSoundSystem->update(vPos, vLook, vUp);
+
+		/*if (!m_pEmitter)
+		{
+			IXSoundLayer *pMasterLayer = m_pSoundSystem->findLayer("master");
+			if (pMasterLayer)
+			{
+				m_pEmitter = pMasterLayer->newSoundEmitter("sounds/ak74_shoot.ogg", SOUND_DTYPE_3D);
+				m_pEmitter->setWorldPos(float3(-11.084, 0.435, -18.707));
+				m_pEmitter->setDistance(50);
+				//pEmitter->play();
+			}
+		}
+		else
+		{
+			if (GetAsyncKeyState('I'))
+			{
+				m_pEmitter->play();
+				//Sleep(100);
+			}
+		}*/
 
 		return -1;
 	}
@@ -44,8 +111,11 @@ public:
 
 protected:
 	CSoundSystem *m_pSoundSystem = NULL;
+	CObserverChangedEventListener *m_pObserverListener = NULL;
+	IXSoundEmitter *m_pEmitter = NULL;
 };
 
+//##########################################################################
 
 class CSoundSystemPlugin : public IXUnknownImplementation<IXPlugin>
 {
@@ -55,7 +125,8 @@ public:
 	{
 		m_pCore = pCore;
 		m_pSoundSystem = new CSoundSystem(m_pCore);
-		m_pUpdatable = new CUpdatable(m_pSoundSystem);
+		m_pObserverListener = new CObserverChangedEventListener(m_pCore);
+		m_pUpdatableSoundSystem = new CUpdatableSoundSystem(m_pSoundSystem, m_pObserverListener);
 	}
 
 	void XMETHODCALLTYPE shutdown() override
@@ -87,7 +158,7 @@ public:
 		if (guid == IXSOUNDSYSTEM_GUID)
 			return m_pSoundSystem;
 		else if (guid == IXUPDATABLE_GUID)
-			return m_pUpdatable;
+			return m_pUpdatableSoundSystem;
 
 		return(NULL);
 	}
@@ -95,7 +166,8 @@ public:
 protected:
 	IXCore *m_pCore;
 	CSoundSystem *m_pSoundSystem = NULL;
-	CUpdatable *m_pUpdatable = NULL;
+	CUpdatableSoundSystem *m_pUpdatableSoundSystem = NULL;
+	CObserverChangedEventListener *m_pObserverListener = NULL;
 };
 
 DECLARE_XPLUGIN(CSoundSystemPlugin);
-- 
GitLab