From e6ea253eacddcb5482394e2af56e07d499473c6d Mon Sep 17 00:00:00 2001
From: D-AIRY <admin@ds-servers.com>
Date: Tue, 1 Dec 2020 12:45:36 +0300
Subject: [PATCH] Added sound_emitter; some refactor; small bugfix

---
 proj/sxgame/vs2013/sxgame.vcxproj         |   2 +
 proj/sxgame/vs2013/sxgame.vcxproj.filters |   6 ++
 source/core/TaskManager.cpp               |  18 ++--
 source/core/TaskManager.h                 |  10 +-
 source/game/SoundEmitter.cpp              | 116 ++++++++++++++++++++++
 source/game/SoundEmitter.h                |  59 +++++++++++
 source/game/SoundPlayer.cpp               |   9 +-
 source/terrax/terrax.cpp                  |   2 +-
 source/xEngine/Engine.cpp                 |   4 +-
 source/xSound/SoundEmitter.cpp            |  12 +--
 source/xSound/SoundLayer.cpp              |  19 ++--
 source/xSound/SoundLayer.h                |  16 +--
 source/xSound/SoundLoader.cpp             |   2 +-
 source/xcommon/IXSoundSystem.h            |   4 +-
 14 files changed, 233 insertions(+), 46 deletions(-)
 create mode 100644 source/game/SoundEmitter.cpp
 create mode 100644 source/game/SoundEmitter.h

diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj
index 6bf851a5f..d0f399efe 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj
+++ b/proj/sxgame/vs2013/sxgame.vcxproj
@@ -236,6 +236,7 @@
     <ClCompile Include="..\..\..\source\game\BaseTool.cpp" />
     <ClCompile Include="..\..\..\source\game\BaseWeapon.cpp" />
     <ClCompile Include="..\..\..\source\game\SettingsWriter.cpp" />
+    <ClCompile Include="..\..\..\source\game\SoundEmitter.cpp" />
     <ClCompile Include="..\..\..\source\game\SoundPlayer.cpp" />
     <ClCompile Include="..\..\..\source\game\sxgame_dll.cpp" />
     <ClCompile Include="..\..\..\source\game\Player.cpp" />
@@ -310,6 +311,7 @@
     <ClInclude Include="..\..\..\source\game\BaseTool.h" />
     <ClInclude Include="..\..\..\source\game\BaseWeapon.h" />
     <ClInclude Include="..\..\..\source\game\SettingsWriter.h" />
+    <ClInclude Include="..\..\..\source\game\SoundEmitter.h" />
     <ClInclude Include="..\..\..\source\game\SoundPlayer.h" />
     <ClInclude Include="..\..\..\source\game\sxgame.h" />
     <ClInclude Include="..\..\..\source\game\Player.h" />
diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters
index 88b980f7f..1e55d43a3 100644
--- a/proj/sxgame/vs2013/sxgame.vcxproj.filters
+++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters
@@ -306,6 +306,9 @@
     <ClCompile Include="..\..\..\source\game\EnvSkybox.cpp">
       <Filter>Source Files\ents\env</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\source\game\SoundEmitter.cpp">
+      <Filter>Source Files\ents\sound</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\source\game\sxgame.h">
@@ -530,6 +533,9 @@
     <ClInclude Include="..\..\..\source\game\EnvSkybox.h">
       <Filter>Header Files\ents\env</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\source\game\SoundEmitter.h">
+      <Filter>Header Files\ents\sound</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\..\source\game\sxgame.rc">
diff --git a/source/core/TaskManager.cpp b/source/core/TaskManager.cpp
index f91def794..de83a5665 100644
--- a/source/core/TaskManager.cpp
+++ b/source/core/TaskManager.cpp
@@ -12,12 +12,12 @@ See the license in LICENSE
 extern CPerfMon *g_pPerfMon;
 
 #if defined(_WINDOWS)
-static void SetThreadName(DWORD dwThreadID, const char *threadName)
+static void SetThreadName(HANDLE hThread, const char *threadName)
 {
 	THREADNAME_INFO info;
 	info.dwType = 0x1000;
 	info.szName = threadName;
-	info.dwThreadID = dwThreadID;
+	info.dwThreadID = GetThreadId(hThread);
 	info.dwFlags = 0;
 #pragma warning(push)
 #pragma warning(disable: 6320 6322)
@@ -171,14 +171,14 @@ void CTaskManager::start()
 		std::thread * t = new std::thread(std::bind(&CTaskManager::workerMain, this));
 #if defined(_WINDOWS)
 		sprintf(name, "Worker #%u", i);
-		SetThreadName(GetThreadId(t->native_handle()), name);
+		SetThreadName(t->native_handle(), name);
 #endif
 		m_aThreads.push_back(t);
 	}
 	m_pIOThread = new std::thread(std::bind(&CTaskManager::workerIOMain, this)); 
 #if defined(_WINDOWS)
 	sprintf(name, "Worker IO");
-	SetThreadName(GetThreadId(m_pIOThread->native_handle()), name);
+	SetThreadName(m_pIOThread->native_handle(), name);
 #endif
 
 	sheduleNextBunch();
@@ -245,7 +245,7 @@ void CTaskManager::synchronize()
 
 void CTaskManager::sheduleNextBunch()
 {
-	std::unique_lock<std::mutex> lock(m_mutexSync);
+	std::unique_lock<mutex> lock(m_mutexSync);
 
 	while(m_iNumTasksToWaitFor > 0)
 	{
@@ -294,7 +294,9 @@ void CTaskManager::stop()
 
 void CTaskManager::execute(TaskPtr t)
 {
+	// save time task started
 	t->run();
+	// save time task ended
 
 	if(t->getFlags() & CORE_TASK_FLAG_REPEATING)
 	{
@@ -344,7 +346,7 @@ void CTaskManager::worker(bool bOneRun)
 			if(task->getFlags() & (CORE_TASK_FLAG_FRAME_SYNC/* | CORE_TASK_FLAG_ON_SYNC*/))
 			{
 				{
-					std::lock_guard<std::mutex> lock(m_mutexSync);
+					ScopedLock lock(m_mutexSync);
 					m_iNumTasksToWaitFor -= 1;
 				}
 
@@ -354,7 +356,7 @@ void CTaskManager::worker(bool bOneRun)
 			if(task->getFlags() & CORE_TASK_FLAG_FOR_LOOP)
 			{
 				{
-					std::lock_guard<std::mutex> lock(m_mutexFor);
+					ScopedLock lock(m_mutexFor);
 					m_aiNumWaitFor[((CTaskForLoop*)task)->getID()] -= 1;
 					//m_aiNumWaitFor[std::static_pointer_cast<CTaskForLoop, ITask>(task)->getID()] -= 1;
 				}
@@ -421,7 +423,7 @@ ID CTaskManager::forLoop(int iStart, int iEnd, const IParallelForBody *pBody, in
 
 	ID id = -1;
 	{
-		std::lock_guard<std::mutex> lock(m_mutexFor);
+		ScopedLock lock(m_mutexFor);
 		id = m_aiNumWaitFor.size();
 		m_aiNumWaitFor.push_back(iTaskCount);
 	}
diff --git a/source/core/TaskManager.h b/source/core/TaskManager.h
index 1d96eb863..a94efdda8 100644
--- a/source/core/TaskManager.h
+++ b/source/core/TaskManager.h
@@ -83,14 +83,14 @@ private:
 	unsigned int m_iWriteList;
 
 	typedef std::condition_variable Condition;
-	typedef std::lock_guard<std::mutex> ScopedLock;
+	typedef std::lock_guard<mutex> ScopedLock;
 
-	mutable std::mutex m_mutexSync;
-	mutable std::mutex m_mutexFor;
-	mutable std::mutex m_mutexIOThread;
+	mutable mutex m_mutexSync;
+	mutable mutex m_mutexFor;
+	mutable mutex m_mutexIOThread;
 	Condition m_Condition;
 	Condition m_ConditionIOThread;
-	mutable std::mutex m_mutexWorker;
+	mutable SpinLock m_mutexWorker;
 	Condition m_ConditionWorker;
 	Condition m_ConditionFor;
 	int m_iNumTasksToWaitFor;
diff --git a/source/game/SoundEmitter.cpp b/source/game/SoundEmitter.cpp
new file mode 100644
index 000000000..1ec6f3fc6
--- /dev/null
+++ b/source/game/SoundEmitter.cpp
@@ -0,0 +1,116 @@
+
+#include "SoundEmitter.h"
+
+//##########################################################################
+
+/*! \skydocent sound_emitter
+	
+*/
+
+//##########################################################################
+
+BEGIN_PROPTABLE(CSoundEmitter)
+
+	//! Звуковой файл
+	DEFINE_FIELD_STRINGFN(m_szPathSound, 0, "file", "Sound file", setSound, EDITOR_SOUND)
+
+	//! Громкость
+	DEFINE_FIELD_FLOAT(m_fVolume, 0, "volume", "Volume", EDITOR_TEXTFIELD)
+
+	//! Дистанция слышимости
+	DEFINE_FIELD_FLOAT(m_fDist, 0, "distance", "Hearing distance", EDITOR_TEXTFIELD)
+	
+	//! Включить
+	DEFINE_INPUT(play, "play", "Play", PDF_NONE)
+
+	//! При включении
+	DEFINE_OUTPUT(m_onTurnOn, "OnTurnOn", "On Turn On")
+//	//! При выключении
+//	DEFINE_OUTPUT(m_onTurnOff, "OnTurnOff", "On Turn Off")
+
+	//! Тип фонового звука
+	DEFINE_FLAG(SND_EMITTER_TYPE_AMBIENT, "Ambient")
+
+END_PROPTABLE()
+
+//**************************************************************************
+
+REGISTER_ENTITY(CSoundEmitter, sound_emitter);
+
+//##########################################################################
+
+CSoundEmitter::CSoundEmitter(CEntityManager *pMgr):
+	BaseClass(pMgr)
+{
+	
+}
+
+CSoundEmitter::~CSoundEmitter()
+{
+	mem_release(m_pEmitter);
+}
+
+//##########################################################################
+
+void CSoundEmitter::setSound(const char *szSound)
+{
+	if(!m_pEmitter || fstrcmp(m_pEmitter->getName(), szSound) != 0)
+	{
+		mem_release(m_pEmitter);
+		IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID));
+		IXSoundLayer *pGameLayer = pSound->findLayer("xGame");
+
+		SOUND_SPACE space = (getFlags() & SND_EMITTER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D);
+		m_pEmitter = pGameLayer->newSoundEmitter(szSound, space);
+
+		if(m_pEmitter)
+		{
+			_setStrVal(&m_szPathSound, szSound);
+			m_pEmitter->setVolume(m_fVolume);
+		}
+	}
+}
+
+//##########################################################################
+
+void CSoundEmitter::onSync()
+{
+	BaseClass::onSync();
+	if(!m_pEmitter)
+		return;
+
+	float3 vPos = getPos();
+	m_pEmitter->setWorldPos(vPos);
+
+	m_pEmitter->setVolume(m_fVolume);
+}
+
+//##########################################################################
+
+void CSoundEmitter::play(inputdata_t * pInputdata)
+{
+	if(m_pEmitter)
+	{
+		m_pEmitter->play();
+	}
+	FIRE_OUTPUT(m_onTurnOn, pInputdata->pInflictor);
+}
+
+//##########################################################################
+
+void CSoundEmitter::updateFlags()
+{
+	BaseClass::updateFlags();
+
+	if(!m_pEmitter)
+		return;
+
+	if (getFlags() & SND_EMITTER_TYPE_AMBIENT)
+	{
+		m_pEmitter->setSpace(SOUND_SPACE_2D);
+	}
+	else
+	{
+		m_pEmitter->setSpace(SOUND_SPACE_3D);
+	}
+}
diff --git a/source/game/SoundEmitter.h b/source/game/SoundEmitter.h
new file mode 100644
index 000000000..c96e49165
--- /dev/null
+++ b/source/game/SoundEmitter.h
@@ -0,0 +1,59 @@
+/*****************************************************
+Copyright © DogmaNet Team, 2020
+Site: dogmanet.ru
+See the license in LICENSE
+*****************************************************/
+
+/*!
+	\file
+	Класс звукового эмиттера
+*/
+#ifndef __SOUND_EMITTER_H
+#define __SOUND_EMITTER_H
+
+#include "PointEntity.h"
+#include <xcommon/IXSoundSystem.h>
+
+//##########################################################################
+
+//! Флаг установки ambient типа звуку
+#define SND_EMITTER_TYPE_AMBIENT ENT_FLAG_1
+
+//##########################################################################
+
+/*! Класс звукового плеера
+	\ingroup cpointentity
+*/
+class CSoundEmitter: public CPointEntity
+{
+	DECLARE_CLASS(CSoundEmitter, CPointEntity);
+	DECLARE_PROPTABLE();
+public:
+	CSoundEmitter(CEntityManager * pMgr);
+	~CSoundEmitter();
+
+	virtual void setSound(const char *szSound);
+
+	void onSync() override;
+
+protected:
+
+	void updateFlags() override;
+
+	void play(inputdata_t *pInputdata);
+
+	//########################################################################
+
+	output_t m_onTurnOn;
+//	output_t m_onTurnOff;
+	
+	IXSoundEmitter *m_pEmitter = NULL;
+	const char *m_szPathSound = "";
+
+	float m_fDist = 10.f;
+	float m_fVolume = 1.f;
+	
+	//int m_iType = SOUND_DTYPE_3D;
+};
+
+#endif
diff --git a/source/game/SoundPlayer.cpp b/source/game/SoundPlayer.cpp
index 241eb03fb..50c83755b 100644
--- a/source/game/SoundPlayer.cpp
+++ b/source/game/SoundPlayer.cpp
@@ -52,8 +52,7 @@ REGISTER_ENTITY(CSoundPlayer, sound_player);
 //##########################################################################
 
 CSoundPlayer::CSoundPlayer(CEntityManager *pMgr):
-	BaseClass(pMgr),
-	m_pPlayer(NULL)
+	BaseClass(pMgr)
 {
 	
 }
@@ -67,7 +66,7 @@ CSoundPlayer::~CSoundPlayer()
 
 void CSoundPlayer::setSound(const char *szSound)
 {
-	if (!m_pPlayer || fstrcmp(m_pPlayer->getName(), szSound) != 0)
+	if(!m_pPlayer || fstrcmp(m_pPlayer->getName(), szSound) != 0)
 	{
 		mem_release(m_pPlayer);
 		IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID));
@@ -76,13 +75,13 @@ void CSoundPlayer::setSound(const char *szSound)
 		SOUND_SPACE space = (getFlags() & SND_PLAYER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D);
 		m_pPlayer = pGameLayer->newSoundPlayer(szSound, space);
 
-		if (m_pPlayer)
+		if(m_pPlayer)
 		{
 			_setStrVal(&m_szPathSound, szSound);
 			m_pPlayer->setLoop((SOUND_LOOP)m_iLoop);
 			m_pPlayer->setVolume(m_fVolume);
 
-			if (getFlags() & SND_PLAYER_START_PLAYED)
+			if(getFlags() & SND_PLAYER_START_PLAYED)
 				m_pPlayer->play();
 		}
 	}
diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp
index 6d8ac6c61..309c93c7c 100644
--- a/source/terrax/terrax.cpp
+++ b/source/terrax/terrax.cpp
@@ -1669,7 +1669,7 @@ bool XSaveLevel(const char *szNewName, bool bForcePrompt)
 		return(true);
 	}
 	
-	if(!bForcePrompt && g_sLevelName[0])
+	if(!bForcePrompt && g_sLevelName.length())
 	{
 		// g_sLevelName can changed during save process, so pointer will be broken
 		String tmp = g_sLevelName;
diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp
index 4d521ed2d..1a3e9087d 100644
--- a/source/xEngine/Engine.cpp
+++ b/source/xEngine/Engine.cpp
@@ -177,8 +177,8 @@ 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);
-	IXSoundLayer *pGameLayer = pMasterLayer->newSoundLayer(&oAudioDesc, "xGame");
-	IXSoundLayer *pGuiLayer = pMasterLayer->newSoundLayer(&oAudioDesc, "xGUI");
+	IXSoundLayer *pGameLayer = pMasterLayer->newSoundLayer("xGame");
+	IXSoundLayer *pGuiLayer = pMasterLayer->newSoundLayer("xGUI");
 	pSound->update(float3(), float3(), float3());
 	pGameLayer->play(false);
 	pGuiLayer->play(false);
diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp
index 27bf9a7b2..f53200789 100644
--- a/source/xSound/SoundEmitter.cpp
+++ b/source/xSound/SoundEmitter.cpp
@@ -38,13 +38,13 @@ CSoundBase* CSoundEmitter::newInstance()
 {
 	CSoundEmitter *pEmitter = new CSoundEmitter();
 
-	pEmitter->m_aInstances[0]->pAB = m_aInstances[0]->pAB->newInstance();
-	pEmitter->m_space = this->m_space;
+	pEmitter->m_aInstances.push_back(new Instance(m_aInstances[0]->pAB->newInstance()));
+	pEmitter->m_space = m_space;
 	pEmitter->m_state = SOUND_STATE_STOP;
-	pEmitter->m_sName = this->m_sName;
-	pEmitter->m_pLayer = this->m_pLayer;
-	pEmitter->m_fDist = this->m_fDist;
-	pEmitter->m_vWorldPos = this->m_vWorldPos;
+	pEmitter->m_sName = m_sName;
+	pEmitter->m_pLayer = m_pLayer;
+	pEmitter->m_fDist = m_fDist;
+	pEmitter->m_vWorldPos = m_vWorldPos;
 	return pEmitter;
 }
 
diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp
index 377096b69..c21e89c02 100644
--- a/source/xSound/SoundLayer.cpp
+++ b/source/xSound/SoundLayer.cpp
@@ -167,7 +167,7 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::findLayer(const char *szName)
 		return this;
 
 	IXSoundLayer *pFound = NULL;
-
+	// TODO use plain array for iteration
 	for(MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
 		if(!i.second)
@@ -195,14 +195,19 @@ IAudioBuffer* CSoundLayer::createAudioBuffer(AB_TYPE type, const AudioRawDesc *p
 
 //##########################################################################
 
-IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDesc, const char *szName)
+IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const char *szName, const AudioRawDesc *pDesc)
 {
+	AudioRawDesc desc;
 	if(!pDesc)
-		return NULL;
-
-	if(!matchPrimaryLayer(pDesc))
-		return NULL;
-
+	{
+		pDesc = &desc;
+		m_pPrimaryBuffer->getDesc(&desc);
+	}
+	else if(!matchPrimaryLayer(pDesc))
+	{
+		return(NULL);
+	}
+	
 	CSoundLayer *pLayer = new CSoundLayer();
 	pLayer->init(m_pSoundSystem, this, pDesc, szName);
 
diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h
index 3c0cf7561..d5a542073 100644
--- a/source/xSound/SoundLayer.h
+++ b/source/xSound/SoundLayer.h
@@ -21,17 +21,17 @@ class CSoundLayer: public IXUnknownImplementation<IXSoundLayer>
 public:
 	~CSoundLayer();
 
-	virtual void XMETHODCALLTYPE play(bool canPlay) override;
-	virtual bool XMETHODCALLTYPE isPlaying() const override;
-	virtual const char* XMETHODCALLTYPE getName() const override;
+	void XMETHODCALLTYPE play(bool canPlay) override;
+	bool XMETHODCALLTYPE isPlaying() const override;
+	const char* XMETHODCALLTYPE getName() const override;
 
-	virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override;
+	IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override;
 
-	virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) override;
-	virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) override;
-	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) override;
+	IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const char *szName, const AudioRawDesc *pDesc = NULL) override;
+	IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) override;
+	IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) override;
 
-	virtual void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override;
+	void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override;
 
 	//########################################################################
 
diff --git a/source/xSound/SoundLoader.cpp b/source/xSound/SoundLoader.cpp
index df11da859..1b624b545 100644
--- a/source/xSound/SoundLoader.cpp
+++ b/source/xSound/SoundLoader.cpp
@@ -7,7 +7,7 @@
 
 bool CSoundLoader::can() const
 {
-	return (bool)m_pCodecTarget;
+	return(m_pCodecTarget != NULL);
 }
 
 void CSoundLoader::init(CSoundSystem *pSoundSystem)
diff --git a/source/xcommon/IXSoundSystem.h b/source/xcommon/IXSoundSystem.h
index cab070821..2bc35b5b2 100644
--- a/source/xcommon/IXSoundSystem.h
+++ b/source/xcommon/IXSoundSystem.h
@@ -8,14 +8,12 @@ See the license in LICENSE
 #define __IXSOUNDSYSTEM_H
 
 #include <gdefines.h>
-#include <common/math.h>
 #include <common/AudioRawDesc.h>
 
 //##########################################################################
 
 // {8FF4F913-5EA1-4EE6-8C06-73D8A49EBC22}
 #define IXSOUNDSYSTEM_GUID DEFINE_XGUID(0x8ff4f913, 0x5ea1, 0x4ee6, 0x8c, 0x6, 0x73, 0xd8, 0xa4, 0x9e, 0xbc, 0x22)
-
 #define IXSOUNDSYSTEM_VERSION 2
 
 //##########################################################################
@@ -107,7 +105,7 @@ public:
 
 	virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) = 0;
 
-	virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) = 0;
+	virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const char *szName, const AudioRawDesc *pDesc = NULL) = 0;
 	virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) = 0;
 	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) = 0;
 
-- 
GitLab