diff --git a/sdks/mital b/sdks/mital
index fd57ec3eb23d3d7c01ee792fe778827c75ce5b48..1f253914532b7f90751c958312a38625def6f994 160000
--- a/sdks/mital
+++ b/sdks/mital
@@ -1 +1 @@
-Subproject commit fd57ec3eb23d3d7c01ee792fe778827c75ce5b48
+Subproject commit 1f253914532b7f90751c958312a38625def6f994
diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp
index 6575219621d623a437b5cd602dbf64bc5b0d3b29..2797795beed5135d683874ec7bff5b079bf7c914 100644
--- a/source/game/GameData.cpp
+++ b/source/game/GameData.cpp
@@ -1463,7 +1463,7 @@ void GameData::loadFoostepsSounds()
 		m_aFootstepSound[i] = (jl ? new IXSoundEmitter*[jl] : NULL);
 		for(int j = 0; j < jl; ++j)
 		{
-			m_aFootstepSound[i][j] = pMasterLayer->newSoundEmitter(paSounds[0][j], SOUND_DTYPE_3D);
+			m_aFootstepSound[i][j] = pMasterLayer->newSoundEmitter(paSounds[0][j], SOUND_SPACE_3D);
 			//m_aFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], SX_SOUND_CHANNEL_GAME, 100);
 		}
 	}
diff --git a/source/game/SoundPlayer.cpp b/source/game/SoundPlayer.cpp
index 4be510c74696484a676f770bfb06bbdfaec572fd..2faecc56e968662f1769985780c0fb1b66267520 100644
--- a/source/game/SoundPlayer.cpp
+++ b/source/game/SoundPlayer.cpp
@@ -78,8 +78,8 @@ void CSoundPlayer::setSound(const char *szSound)
 		IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID));
 		IXSoundLayer *pMasterLayer = pSound->findLayer("master");
 
-		SOUND_DTYPE dtype = (getFlags() & SND_PLAYER_TYPE_AMBIENT ? SOUND_DTYPE_2D : SOUND_DTYPE_3D);
-		m_pPlayer = pMasterLayer->newSoundPlayer(szSound, dtype);
+		SOUND_SPACE space = (getFlags() & SND_PLAYER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D);
+		m_pPlayer = pMasterLayer->newSoundPlayer(szSound, space);
 
 		if (m_pPlayer)
 		{
@@ -149,10 +149,10 @@ void CSoundPlayer::updateFlags()
 	
 	if (getFlags() & SND_PLAYER_TYPE_AMBIENT)
 	{
-		m_pPlayer->setType(SOUND_DTYPE_2D);
+		m_pPlayer->setSpace(SOUND_SPACE_2D);
 		/*m_pPlayer->setPan(0.f);
 		m_pPlayer->setVolume(m_fVolume);*/
 	}
 	else
-		m_pPlayer->setType(SOUND_DTYPE_3D);
+		m_pPlayer->setSpace(SOUND_SPACE_3D);
 }
diff --git a/source/xSound/SoundBase.cpp b/source/xSound/SoundBase.cpp
index 6281c59a761348f6b852f50e239196fcb0bda045..455d6a233e230b8f3cc1b378d1d3f4aeac071b08 100644
--- a/source/xSound/SoundBase.cpp
+++ b/source/xSound/SoundBase.cpp
@@ -1,16 +1,30 @@
 
 #include "SoundBase.h"
 
+#include "SoundLayer.h"
+
 //##########################################################################
 
-SOUND_DTYPE XMETHODCALLTYPE CSoundBase::getType() const
+SOUND_TYPE XMETHODCALLTYPE CSoundBase::getType() const
+{
+	return m_type;
+}
+
+SOUND_SPACE XMETHODCALLTYPE CSoundBase::getSpace() const
 {
-	return m_dtype;
+	return m_space;
 }
 
-void XMETHODCALLTYPE CSoundBase::setType(SOUND_DTYPE dtype)
+void XMETHODCALLTYPE CSoundBase::setSpace(SOUND_SPACE space)
 {
-	m_dtype = dtype;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_SPACE;
+	oMsg.arg.space = space;
+	if (m_type == SOUND_TYPE_EMITTER)
+		oMsg.pEmitter = (CSoundEmitter*)this;
+	else
+		oMsg.pPlayer = (CSoundPlayer*)this;
+	m_pLayer->addMessage(oMsg);
 }
 
 const char* XMETHODCALLTYPE CSoundBase::getName() const
@@ -20,7 +34,14 @@ const char* XMETHODCALLTYPE CSoundBase::getName() const
 
 void XMETHODCALLTYPE CSoundBase::setVolume(float fVolume)
 {
-	m_fVolume = fVolume;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_VOLUME;
+	oMsg.arg.f = fVolume;
+	if (m_type == SOUND_TYPE_EMITTER)
+		oMsg.pEmitter = (CSoundEmitter*)this;
+	else
+		oMsg.pPlayer = (CSoundPlayer*)this;
+	m_pLayer->addMessage(oMsg);
 }
 
 float XMETHODCALLTYPE CSoundBase::getVolume() const
@@ -30,7 +51,14 @@ float XMETHODCALLTYPE CSoundBase::getVolume() const
 
 void XMETHODCALLTYPE CSoundBase::setPan(float fPan)
 {
-	m_fPan = fPan;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PAN;
+	oMsg.arg.f = fPan;
+	if (m_type == SOUND_TYPE_EMITTER)
+		oMsg.pEmitter = (CSoundEmitter*)this;
+	else
+		oMsg.pPlayer = (CSoundPlayer*)this;
+	m_pLayer->addMessage(oMsg);
 }
 
 float XMETHODCALLTYPE CSoundBase::getPan() const
@@ -45,7 +73,16 @@ const float3& XMETHODCALLTYPE CSoundBase::getWorldPos() const
 
 void XMETHODCALLTYPE CSoundBase::setWorldPos(const float3 &vPos)
 {
-	m_vWorldPos = vPos;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_POS;
+	oMsg.arg.vector[0] = vPos.x;
+	oMsg.arg.vector[1] = vPos.y;
+	oMsg.arg.vector[2] = vPos.z;
+	if (m_type == SOUND_TYPE_EMITTER)
+		oMsg.pEmitter = (CSoundEmitter*)this;
+	else
+		oMsg.pPlayer = (CSoundPlayer*)this;
+	m_pLayer->addMessage(oMsg);
 }
 
 float XMETHODCALLTYPE CSoundBase::getDistance() const
@@ -54,6 +91,40 @@ float XMETHODCALLTYPE CSoundBase::getDistance() const
 }
 
 void XMETHODCALLTYPE CSoundBase::setDistance(float fDist)
+{
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DIST;
+	oMsg.arg.f = fDist;
+	if (m_type == SOUND_TYPE_EMITTER)
+		oMsg.pEmitter = (CSoundEmitter*)this;
+	else
+		oMsg.pPlayer = (CSoundPlayer*)this;
+	m_pLayer->addMessage(oMsg);
+}
+
+//##########################################################################
+
+void CSoundBase::_setSpace(SOUND_SPACE space)
+{
+	m_space = space;
+}
+
+void CSoundBase::_setVolume(float fVolume)
+{
+	m_fVolume = fVolume;
+}
+
+void CSoundBase::_setPan(float fPan)
+{
+	m_fPan = fPan;
+}
+
+void CSoundBase::_setWorldPos(const float3 &vPos)
+{
+	m_vWorldPos = vPos;
+}
+
+void CSoundBase::_setDistance(float fDist)
 {
 	m_fDist = fDist;
 }
diff --git a/source/xSound/SoundBase.h b/source/xSound/SoundBase.h
index ea84aeba45b218566d08b6e3e8dacc5dc3c31b55..32db84810b3b33bf4d35d457c906c7c45ea49d12 100644
--- a/source/xSound/SoundBase.h
+++ b/source/xSound/SoundBase.h
@@ -38,8 +38,10 @@ public:
 
 	//########################################################################
 
-	SOUND_DTYPE XMETHODCALLTYPE getType() const override;
-	void XMETHODCALLTYPE setType(SOUND_DTYPE dtype) override;
+	SOUND_TYPE XMETHODCALLTYPE getType() const;
+
+	SOUND_SPACE XMETHODCALLTYPE getSpace() const;
+	void XMETHODCALLTYPE setSpace(SOUND_SPACE space);
 
 	const char* XMETHODCALLTYPE getName() const override;
 
@@ -49,14 +51,24 @@ public:
 	void XMETHODCALLTYPE setPan(float fPan) override;
 	float XMETHODCALLTYPE getPan() const override;
 
-	const float3& XMETHODCALLTYPE getWorldPos() const override;
 	void XMETHODCALLTYPE setWorldPos(const float3 &vPos) override;
+	const float3& XMETHODCALLTYPE getWorldPos() const override;
 
-	float XMETHODCALLTYPE getDistance() const override;
 	void XMETHODCALLTYPE setDistance(float fDist) override;
+	float XMETHODCALLTYPE getDistance() const override;
 
 protected:
 
+	virtual void _setSpace(SOUND_SPACE space);
+	virtual void _setVolume(float fVolume);
+	virtual void _setPan(float fPan);
+	virtual void _setWorldPos(const float3 &vPos);
+	virtual void _setDistance(float fDist);
+
+	//########################################################################
+
+	SOUND_TYPE m_type;
+
 	//! громкость [0.0, 1.0]
 	float m_fVolume = 1.f;
 
@@ -70,7 +82,7 @@ protected:
 	float3 m_vWorldPos;
 
 	//! тип звука
-	SOUND_DTYPE m_dtype = SOUND_DTYPE_2D;
+	SOUND_SPACE m_space = SOUND_SPACE_2D;
 
 	//! состояние проигрывания
 	SOUND_STATE m_state = SOUND_STATE_STOP;
diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp
index 59ccf22f5b9d88b9e13bfb5376aa43652d80b9d1..576e8f972b21ef1a13572c62d29263a7614cc4ae 100644
--- a/source/xSound/SoundEmitter.cpp
+++ b/source/xSound/SoundEmitter.cpp
@@ -8,9 +8,15 @@
 
 CSoundEmitter::~CSoundEmitter()
 {
-	m_pLayer->delSndEmitter(this);
+	//m_pLayer->delSndEmitter(this);
 
-	for (int i = 0; i < m_aInstances.size(); ++i)
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DELETE;
+	oMsg.pEmitter = this;
+	oMsg.pLayer = m_pLayer;
+	m_pLayer->addMessage(oMsg);
+
+	for (auto i = 0u, il = m_aInstances.size(); i < il; ++i)
 	{
 		mem_delete(m_aInstances[i]);
 	}
@@ -30,7 +36,7 @@ CSoundBase* CSoundEmitter::newInstance()
 	CSoundEmitter *pEmitter = new CSoundEmitter();
 
 	pEmitter->m_aInstances[0]->pAB = m_aInstances[0]->pAB->newInstance();
-	pEmitter->m_dtype = this->m_dtype;
+	pEmitter->m_space = this->m_space;
 	pEmitter->m_state = SOUND_STATE_STOP;
 	pEmitter->m_sName = this->m_sName;
 	pEmitter->m_pLayer = this->m_pLayer;
@@ -42,14 +48,93 @@ CSoundBase* CSoundEmitter::newInstance()
 //##########################################################################
 
 void XMETHODCALLTYPE CSoundEmitter::play()
+{
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PLAY;
+	oMsg.arg.state = SOUND_STATE_PLAY;
+	oMsg.pEmitter = this;
+	m_pLayer->addMessage(oMsg);
+}
+
+//**************************************************************************
+
+void CSoundEmitter::resume()
+{
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_RESUME;
+	oMsg.pEmitter = this;
+	m_pLayer->addMessage(oMsg);
+}
+
+void CSoundEmitter::pause()
+{
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PLAY;
+	oMsg.arg.state = SOUND_STATE_PAUSE;
+	oMsg.pEmitter = this;
+	m_pLayer->addMessage(oMsg);
+}
+
+//**************************************************************************
+
+bool CSoundEmitter::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space)
+{
+	if (!pCodecTarget || !pLayer)
+		return false;
+
+	m_sName = szName;
+	m_space = space;
+	AudioRawDesc oDesc;
+	pCodecTarget->getDesc(&oDesc);
+	m_pLayer = pLayer;
+
+	IAudioBuffer *pAB = pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc);
+	BYTE *pData = new BYTE[oDesc.uSize];
+	pCodecTarget->decode(0, oDesc.uSize, (void**)&pData);
+
+	BYTE *pData2;
+	pAB->lock(AB_LOCK_WRITE, (void**)&pData2);
+	memcpy(pData2, pData, oDesc.uSize);
+	pAB->unlock();
+
+	mem_delete_a(pData);
+	mem_release(pCodecTarget);
+
+	pAB->setLoop(AB_LOOP_NONE);
+
+	m_aInstances.push_back(new Instance(pAB));
+
+	return true;
+}
+
+//##########################################################################
+
+void CSoundEmitter::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+{
+	m_vListenerPos = vListenerPos;
+	m_vListenerDir = vListenerDir;
+	m_vListenerUp = vListenerUp;
+
+	if (m_space == SOUND_SPACE_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_fVolume, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
+		}
+	}
+}
+
+//##########################################################################
+
+void CSoundEmitter::_play()
 {
 	//если родительский слой не проигрывается, тогда не запускаем проигрывание
 	if (!m_pLayer->isPlaying())
 		return;
 
-	float3 vPos, vLook, vUp;
-	m_pLayer->getObserverParam(&vPos, &vLook, &vUp);
-
 	IAudioBuffer *pAB = NULL;
 
 	//проход по массиву инстансов звука, если есть первый попавшийся не проигрываемые тогда его проигрываем
@@ -58,7 +143,7 @@ void XMETHODCALLTYPE CSoundEmitter::play()
 		if (!(m_aInstances[i]->pAB->isPlaying()))
 		{
 			pAB = m_aInstances[i]->pAB;
-			continue;
+			break;
 		}
 	}
 
@@ -70,13 +155,13 @@ void XMETHODCALLTYPE CSoundEmitter::play()
 		m_aInstances.push_back(new Instance(pInst));
 	}
 
-	Com3D(pAB, m_fDist, m_fVolume, m_vWorldPos, vPos, vLook, vUp);
+	Com3D(pAB, m_fDist, m_fVolume, m_vWorldPos, m_vListenerPos, m_vListenerDir, m_vListenerUp);
 	pAB->play(true);
 }
 
 //**************************************************************************
 
-void CSoundEmitter::resume()
+void CSoundEmitter::_resume()
 {
 	//если инстансы проигрывались тогда включаем проигрывание
 	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
@@ -86,7 +171,9 @@ void CSoundEmitter::resume()
 	}
 }
 
-void CSoundEmitter::pause()
+//**************************************************************************
+
+void CSoundEmitter::_pause()
 {
 	//записываем состояния инстансов и останавливаем
 	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
@@ -98,48 +185,63 @@ void CSoundEmitter::pause()
 
 //**************************************************************************
 
-bool CSoundEmitter::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype)
+void CSoundEmitter::_setSpace(SOUND_SPACE space)
 {
-	if (!pCodecTarget || !pLayer)
-		return false;
-
-	m_sName = szName;
-	m_dtype = dtype;
-	AudioRawDesc oDesc;
-	pCodecTarget->getDesc(&oDesc);
-	m_pLayer = pLayer;
+	m_space = space;
+	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
+	{
+		if (m_aInstances[i]->pAB->isPlaying())
+		{
+			m_aInstances[i]->pAB->setPan(m_fPan);
+			m_aInstances[i]->pAB->setVolume(m_fVolume);
+		}
+	}
+}
 
-	IAudioBuffer *pAB = pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc);
-	BYTE *pData = new BYTE[oDesc.uSize];
-	pCodecTarget->decode(0, oDesc.uSize, (void**)&pData);
+//**************************************************************************
 
-	BYTE *pData2;
-	pAB->lock(AB_LOCK_WRITE, (void**)&pData2);
-	memcpy(pData2, pData, oDesc.uSize);
-	pAB->unlock();
+void CSoundEmitter::_setVolume(float fVolume)
+{
+	m_fVolume = fVolume;
+	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
+	{
+		if (m_aInstances[i]->pAB->isPlaying())
+			m_aInstances[i]->pAB->setVolume(m_fVolume);
+	}
+}
 
-	mem_delete_a(pData);
-	mem_release(pCodecTarget);
+//**************************************************************************
 
-	pAB->setLoop(AB_LOOP_NONE);
+void CSoundEmitter::_setPan(float fPan)
+{
+	m_fPan = fPan;
+	for (int i = 0, il = m_aInstances.size(); i < il; ++i)
+	{
+		if (m_aInstances[i]->pAB->isPlaying())
+			m_aInstances[i]->pAB->setPan(m_fPan);
+	}
+}
 
-	m_aInstances.push_back(new Instance(pAB));
+//**************************************************************************
 
-	return true;
+void CSoundEmitter::_setWorldPos(const float3 &vPos)
+{
+	m_vWorldPos = vPos;
+	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_fVolume, m_vWorldPos, m_vListenerPos, m_vListenerDir, m_vListenerUp);
+	}
 }
 
-//##########################################################################
+//**************************************************************************
 
-void CSoundEmitter::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+void CSoundEmitter::_setDistance(float fDist)
 {
-	if (m_dtype == SOUND_DTYPE_2D)
-		return;
-
+	m_fDist = fDist;
 	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_fVolume, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
-		}
+			Com3D(m_aInstances[i]->pAB, m_fDist, m_fVolume, m_vWorldPos, m_vListenerPos, m_vListenerDir, m_vListenerUp);
 	}
-}
\ No newline at end of file
+}
diff --git a/source/xSound/SoundEmitter.h b/source/xSound/SoundEmitter.h
index cf9d36f003d50e26050f27efffcf90400833a0cf..fa99085d9f8c1a25b06ed7b6d978f67cae1d6e5b 100644
--- a/source/xSound/SoundEmitter.h
+++ b/source/xSound/SoundEmitter.h
@@ -7,6 +7,10 @@ See the license in LICENSE
 #ifndef __SOUNDEMITTER_H
 #define __SOUNDEMITTER_H
 
+#ifdef _MSC_VER
+#pragma warning(disable : 4250)
+#endif
+
 #include <xcommon/IXSoundSystem.h>
 #include "SoundBase.h"
 #include <mital.h>
@@ -19,6 +23,8 @@ See the license in LICENSE
 class CSoundEmitter : public CSoundBase, public virtual IXSoundEmitter
 {
 public:
+	SX_ALIGNED_OP_MEM
+
 	~CSoundEmitter();
 
 	//########################################################################
@@ -31,7 +37,7 @@ public:
 
 	//########################################################################
 
-	virtual void XMETHODCALLTYPE play() override;
+	void XMETHODCALLTYPE play() override;
 
 	//########################################################################
 
@@ -44,8 +50,20 @@ public:
 protected:
 
 	friend CSoundLayer;
+	friend CSoundSystem;
+
+	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space);
 
-	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype);
+	void _play();
+	void _resume();
+	void _pause();
+	void _setSpace(SOUND_SPACE space);
+	void _setVolume(float fVolume);
+	void _setPan(float fPan);
+	void _setWorldPos(const float3 &vPos);
+	void _setDistance(float fDist);
+
+	//#########################################################################
 
 	struct Instance
 	{
@@ -56,7 +74,11 @@ protected:
 		bool isPlaying = false;
 	};
 
+	//#########################################################################
+
 	Array<Instance*> m_aInstances;
+
+	float3 m_vListenerPos, m_vListenerDir, m_vListenerUp;
 };
 
 #endif
diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp
index a1bc9a516d61d88ec9fe0949e22db318bd1cade1..8b1d61fa68707644b7f2caa895ca10360d7d86d6 100644
--- a/source/xSound/SoundLayer.cpp
+++ b/source/xSound/SoundLayer.cpp
@@ -12,34 +12,38 @@ CSoundLayer::~CSoundLayer()
 	if (m_pParent)
 		m_pParent->delLayer(this);
 
-	for(maplayer::Iterator i = m_mapLayers.begin(); i; ++i)
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
 		mem_release(m_mapLayers[i.first]);
 		m_mapLayers.erase(i.first);
 	}
 
 
-	// массивы очищаются while циклом потому что при release объекта он сам удаляется из массива объектов слоя
-
 	for(MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
 	{
 		ArrayPlayer *oAP = i.second;
-		while (oAP->size())
+		//while (oAP->size())
+		for (auto k = 0u, kl = oAP->size(); k < kl; ++k)
 		{
-			CSoundPlayer *pPlayer = oAP->get(0);
+			CSoundPlayer *pPlayer = oAP->get(k);
 			mem_release(pPlayer);
 		}
+		oAP->clear();
 	}
+	m_mapSndPlayers.clear();
 
 	for (MapEmitter::Iterator i = m_mapSndEmitters.begin(); i; ++i)
 	{
 		ArrayEmitter *oAE = i.second;
-		while (oAE->size())
+		//while (oAE->size())
+		for (auto k = 0u, kl = oAE->size(); k < kl; ++k)
 		{
-			CSoundEmitter *pEmitter = oAE->get(0);
+			CSoundEmitter *pEmitter = oAE->get(k);
 			mem_release(pEmitter);
 		}
+		oAE->clear();
 	}
+	m_mapSndEmitters.clear();
 
 	mem_release(m_pPrimaryBuffer);
 }
@@ -80,7 +84,7 @@ void CSoundLayer::addLayer(CSoundLayer *pLayer, const char *szName)
 
 void CSoundLayer::delLayer(const CSoundLayer *pLayer)
 {
-	for(maplayer::Iterator i = m_mapLayers.begin(); i; ++i)
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
 		if(m_mapLayers[i.first] == pLayer)
 		{
@@ -92,9 +96,9 @@ void CSoundLayer::delLayer(const CSoundLayer *pLayer)
 
 //**************************************************************************
 
-void CSoundLayer::addSndPlayer(CSoundPlayer *pSndPlayer, const char *szName)
+void CSoundLayer::addSndPlayer(CSoundPlayer *pSndPlayer/*, const char *szName*/)
 {
-	m_mapSndPlayers[szName].push_back(pSndPlayer);
+	m_mapSndPlayers[pSndPlayer->getName()].push_back(pSndPlayer);
 }
 
 void CSoundLayer::delSndPlayer(const CSoundPlayer *pSndPlayer)
@@ -113,9 +117,9 @@ void CSoundLayer::delSndPlayer(const CSoundPlayer *pSndPlayer)
 
 //**************************************************************************
 
-void CSoundLayer::addSndEmitter(CSoundEmitter *pSndEmitter, const char *szName)
+void CSoundLayer::addSndEmitter(CSoundEmitter *pSndEmitter/*, const char *szName*/)
 {
-	m_mapSndEmitters[szName].push_back(pSndEmitter);
+	m_mapSndEmitters[pSndEmitter->getName()].push_back(pSndEmitter);
 }
 
 void CSoundLayer::delSndEmitter(const CSoundEmitter *pSndEmitter)
@@ -161,7 +165,7 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::findLayer(const char *szName)
 
 	IXSoundLayer *pFound = NULL;
 
-	for(maplayer::Iterator i = m_mapLayers.begin(); i; ++i)
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
 		if((pFound = m_mapLayers[i.first]->findLayer(szName)))
 			break;
@@ -200,7 +204,7 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDe
 	return pLayer;
 }
 
-IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName, SOUND_DTYPE dtype)
+IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName, SOUND_SPACE space)
 {
 	if (!szName)
 		return NULL;
@@ -223,15 +227,21 @@ IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName,
 			return NULL;
 
 		pEmitter = new CSoundEmitter();
-		pEmitter->create(szName, this, pCodecTarget, dtype);
+		pEmitter->create(szName, this, pCodecTarget, space);
 	}
 
-	addSndEmitter(pEmitter, szName);
+	//addSndEmitter(pEmitter/*, szName*/);
+
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_NEW;
+	oMsg.pEmitter = pEmitter;
+	oMsg.pLayer = this;
+	m_pSoundSystem->addMessage(oMsg);
 
 	return pEmitter;
 }
 
-IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, SOUND_DTYPE dtype)
+IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, SOUND_SPACE space)
 {
 	if (!szName)
 		return NULL;
@@ -252,10 +262,16 @@ IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, S
 			return NULL;
 
 		pPlayer = new CSoundPlayer();
-		pPlayer->create(szName, this, pCodecTarget, dtype);
+		pPlayer->create(szName, this, pCodecTarget, space);
 	}
 
-	addSndPlayer(pPlayer, szName);
+	//addSndPlayer(pPlayer/*, szName*/);
+
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_NEW;
+	oMsg.pPlayer = pPlayer;
+	oMsg.pLayer = this;
+	m_pSoundSystem->addMessage(oMsg);
 
 	return pPlayer;
 }
@@ -269,7 +285,7 @@ void XMETHODCALLTYPE CSoundLayer::play(bool canPlay)
 
 	m_isPlaying = canPlay;
 
-	for(maplayer::Iterator i = m_mapLayers.begin(); i; ++i)
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 		m_mapLayers[i.first]->play(canPlay);
 
 	for(MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
@@ -306,7 +322,7 @@ bool XMETHODCALLTYPE CSoundLayer::isPlaying() const
 
 void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
-	for(maplayer::Iterator i = m_mapLayers.begin(); i; ++i)
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
 		if(m_mapLayers[i.first])
 			m_mapLayers[i.first]->update(vListenerPos, vListenerDir, vListenerUp);
@@ -327,11 +343,16 @@ void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir,
 	}
 }
 
-void CSoundLayer::getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+void CSoundLayer::addMessage(SndQueueMsg &oMsg) 
 {
-	m_pSoundSystem->getObserverParam(pPos, pLook, pUp);
+	m_pSoundSystem->addMessage(oMsg); 
 }
 
+/*void CSoundLayer::getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+{
+	m_pSoundSystem->getObserverParam(pPos, pLook, pUp);
+}*/
+
 bool CSoundLayer::matchPrimaryLayer(const AudioRawDesc *pDesc)
 {
 	if (!pDesc || !m_pPrimaryBuffer)
diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h
index eee317d7543935519f32468714f38891632e18ab..6cb5b18c22328328aaa159cb565d0b5087c5a27c 100644
--- a/source/xSound/SoundLayer.h
+++ b/source/xSound/SoundLayer.h
@@ -29,8 +29,8 @@ public:
 	virtual 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_DTYPE dtype) override;
-	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_DTYPE dtype) override;
+	virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) override;
+	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) override;
 
 	virtual void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override;
 
@@ -41,7 +41,9 @@ public:
 
 	void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp);
 
-	void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
+	void addMessage(SndQueueMsg &oMsg);
+
+	//void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
 
 protected:
 
@@ -56,10 +58,10 @@ protected:
 	void addLayer(CSoundLayer *pLayer, const char *szName);
 	void delLayer(const CSoundLayer *pLayer);
 
-	void addSndPlayer(CSoundPlayer *pSndPlayer, const char *szName);
+	void addSndPlayer(CSoundPlayer *pSndPlayer/*, const char *szName*/);
 	void delSndPlayer(const CSoundPlayer *pSndPlayer);
 
-	void addSndEmitter(CSoundEmitter *pSndEmitter, const char *szName);
+	void addSndEmitter(CSoundEmitter *pSndEmitter/*, const char *szName*/);
 	void delSndEmitter(const CSoundEmitter *pSndEmitter);
 
 	//************************************************************************
@@ -67,9 +69,6 @@ protected:
 	//! соответствует ли описание (его критические элементы) аудио буфера первичному буферу
 	bool matchPrimaryLayer(const AudioRawDesc *pDesc);
 
-	void setStateLayers(SOUND_STATE state);
-	void setStateSounds(SOUND_STATE state);
-
 	//########################################################################
 
 	SOUND_STATE m_state = SOUND_STATE_STOP;
@@ -83,8 +82,8 @@ protected:
 
 	String m_sName = "";
 
-	typedef AssotiativeArray<String, CSoundLayer*> maplayer;
-	maplayer m_mapLayers;
+	typedef AssotiativeArray<String, CSoundLayer*> MapLayer;
+	MapLayer m_mapLayers;
 
 	typedef Array<CSoundPlayer*> ArrayPlayer;
 	typedef AssotiativeArray<String, ArrayPlayer> MapPlayer;
diff --git a/source/xSound/SoundPlayer.cpp b/source/xSound/SoundPlayer.cpp
index da5adfe8de42b374e742ea06ffc60e25dcd7ab53..0dd6b5573b25857f076cfe185c9d61d8b98a1b8b 100644
--- a/source/xSound/SoundPlayer.cpp
+++ b/source/xSound/SoundPlayer.cpp
@@ -8,7 +8,14 @@
 
 CSoundPlayer::~CSoundPlayer()
 {
-	m_pLayer->delSndPlayer(this);
+	//m_pLayer->delSndPlayer(this);
+
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DELETE;
+	oMsg.pPlayer = this;
+	oMsg.pLayer = m_pLayer;
+	m_pLayer->addMessage(oMsg);
+
 	mem_release(m_pAB);
 
 	mem_delete(m_pCodecTarget);
@@ -33,7 +40,7 @@ CSoundBase* CSoundPlayer::newInstance()
 	pPlayer->m_uLengthBytes = this->m_uLengthBytes;
 	pPlayer->m_fLengthMls = this->m_fLengthMls;
 	pPlayer->m_loop = this->m_loop;
-	pPlayer->m_dtype = this->m_dtype;
+	pPlayer->m_space = this->m_space;
 	pPlayer->m_state = SOUND_STATE_STOP;
 	pPlayer->m_sName = this->m_sName;
 	pPlayer->m_pLayer = this->m_pLayer;
@@ -45,13 +52,13 @@ CSoundBase* CSoundPlayer::newInstance()
 
 //**************************************************************************
 
-bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype)
+bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space)
 {
 	if (!pCodecTarget || !pLayer)
 		return false;
 
 	m_sName = szName;
-	m_dtype = dtype;
+	m_space = space;
 	m_pLayer = pLayer;
 	m_pCodecTarget = pCodecTarget;
 	AudioRawDesc oDesc;
@@ -98,53 +105,55 @@ bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecT
 
 //##########################################################################
 
-void XMETHODCALLTYPE CSoundPlayer::setType(SOUND_DTYPE dtype)
+/*void XMETHODCALLTYPE CSoundPlayer::setType(SOUND_DTYPE space)
 {
-	m_pAB->setPan(m_fPan);
-	m_pAB->setVolume(m_fVolume);
-	m_dtype = dtype;
-}
+	QueueMsg oMsg;
+	oMsg.type = QUEUE_MSG_TYPE_DTYPE;
+	oMsg.arg.dtype = dtype;
+	m_oQueue.push(oMsg);
+}*/
 
 //##########################################################################
 
 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_fVolume, m_vWorldPos, vPos, vLook, vUp);
-	m_pAB->play(true);
-	m_state = SOUND_STATE_PLAY;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PLAY;
+	oMsg.arg.state = SOUND_STATE_PLAY;
+	oMsg.pPlayer = this;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
 
 void XMETHODCALLTYPE CSoundPlayer::resume()
 {
-	if (!m_pLayer->isPlaying() || m_state != SOUND_STATE_PAUSE)
-		return;
-
-	m_pAB->play(true);
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_RESUME;
+	oMsg.pPlayer = this;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
 
 void XMETHODCALLTYPE CSoundPlayer::pause()
 {
-	m_pAB->play(false);
-	m_state = SOUND_STATE_PAUSE;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PLAY;
+	oMsg.arg.state = SOUND_STATE_PAUSE;
+	oMsg.pPlayer = this;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
 
 void XMETHODCALLTYPE CSoundPlayer::stop()
 {
-	m_pAB->play(false);
-	setTime(0.f);
-	m_state = SOUND_STATE_STOP;
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_PLAY;
+	oMsg.arg.state = SOUND_STATE_STOP;
+	oMsg.pPlayer = this;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
@@ -158,9 +167,11 @@ bool XMETHODCALLTYPE CSoundPlayer::isPlaying() const
 
 void XMETHODCALLTYPE CSoundPlayer::setLoop(SOUND_LOOP loop)
 {
-	m_loop = loop;
-	if (!m_pStream)
-		m_pAB->setLoop((AB_LOOP)m_loop);
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_LOOP;
+	oMsg.arg.loop = loop;
+	oMsg.pPlayer = this;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
@@ -190,17 +201,10 @@ float XMETHODCALLTYPE CSoundPlayer::getTime() const
 
 void XMETHODCALLTYPE CSoundPlayer::setTime(float fTime)
 {
-	AudioRawDesc oDesc;
-	m_pAB->getDesc(&oDesc);
-	uint32_t uPosBytes = (uint64_t(fTime * 1000.f) * uint64_t(oDesc.uBytesPerSec)) / uint64_t(1000);
-
-	if (m_uLengthBytes < uPosBytes)
-		return;
-
-	if (m_pStream)
-		setPosStream(uPosBytes);
-	else
-		m_pAB->setPos(uPosBytes);
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_SND_TIME;
+	oMsg.arg.f = fTime;
+	m_pLayer->addMessage(oMsg);
 }
 
 //**************************************************************************
@@ -267,10 +271,48 @@ uint32_t CSoundPlayer::getPosBytes() const
 
 void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
+	m_vListenerPos = vListenerPos;
+	m_vListenerDir = vListenerDir;
+	m_vListenerUp = vListenerUp;
+
+	/*QueueMsg oMsg;
+	while (m_oQueue.pop(&oMsg))
+	{
+		switch (oMsg.type)
+		{
+		case QUEUE_MSG_TYPE_PLAY:
+		{
+			if (oMsg.arg.state == SOUND_STATE_PLAY)
+				_play();
+			else if (oMsg.arg.state == SOUND_STATE_PAUSE)
+				_pause();
+			else if (oMsg.arg.state == SOUND_STATE_STOP)
+				_stop();
+
+			break;
+		}
+		case QUEUE_MSG_TYPE_RESUME:
+			_resume();
+			break;
+		case QUEUE_MSG_TYPE_LOOP:
+			_setLoop(oMsg.arg.loop);
+			break;
+		case QUEUE_MSG_TYPE_DTYPE:
+			_setType(oMsg.arg.dtype);
+			break;
+		case QUEUE_MSG_TYPE_TIME:
+			_setTime(oMsg.arg.fTime);
+			break;
+
+		default:
+			break;
+		}
+	}*/
+
 	if (!m_pLayer->isPlaying())
 		return;
 
-	if (m_dtype == SOUND_DTYPE_3D)
+	if (m_space == SOUND_SPACE_3D)
 		Com3D(m_pAB, m_fDist, m_fVolume, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
 	else
 		int qwerty = 0;
@@ -293,7 +335,7 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 		if (m_loop == AB_LOOP_NONE)
 			m_pAB->play(false);
 		else
-			setTime(0.f);
+			_setTime(0.f);
 	}
 
 	if (!isPlaying())
@@ -328,3 +370,66 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 		}
 	}
 }
+
+//##########################################################################
+//##########################################################################
+
+void CSoundPlayer::_setSpace(SOUND_SPACE space)
+{
+	m_pAB->setPan(m_fPan);
+	m_pAB->setVolume(m_fVolume);
+	m_space = space;
+}
+
+void CSoundPlayer::_play()
+{
+	if (!m_pLayer->isPlaying())
+		return;
+
+	Com3D(m_pAB, m_fDist, m_fVolume, m_vWorldPos, m_vListenerPos, m_vListenerDir, m_vListenerUp);
+	m_pAB->play(true);
+	m_state = SOUND_STATE_PLAY;
+}
+
+void CSoundPlayer::_resume()
+{
+	if (!m_pLayer->isPlaying() || m_state != SOUND_STATE_PAUSE)
+		return;
+
+	m_pAB->play(true);
+}
+
+void CSoundPlayer::_pause()
+{
+	m_pAB->play(false);
+	m_state = SOUND_STATE_PAUSE;
+}
+
+void CSoundPlayer::_stop()
+{
+	m_pAB->play(false);
+	_setTime(0.f);
+	m_state = SOUND_STATE_STOP;
+}
+
+void CSoundPlayer::_setLoop(SOUND_LOOP loop)
+{
+	m_loop = loop;
+	if (!m_pStream)
+		m_pAB->setLoop((AB_LOOP)m_loop);
+}
+
+void CSoundPlayer::_setTime(float fTime)
+{
+	AudioRawDesc oDesc;
+	m_pAB->getDesc(&oDesc);
+	uint32_t uPosBytes = (uint64_t(fTime * 1000.f) * uint64_t(oDesc.uBytesPerSec)) / uint64_t(1000);
+
+	if (m_uLengthBytes < uPosBytes)
+		return;
+
+	if (m_pStream)
+		setPosStream(uPosBytes);
+	else
+		m_pAB->setPos(uPosBytes);
+}
\ No newline at end of file
diff --git a/source/xSound/SoundPlayer.h b/source/xSound/SoundPlayer.h
index ccef007929653458718bdf408cb5c4f6219f128a..920b29279d222d27eebac27b433699fbac9ea779 100644
--- a/source/xSound/SoundPlayer.h
+++ b/source/xSound/SoundPlayer.h
@@ -7,6 +7,11 @@ See the license in LICENSE
 #ifndef __SOUNDPLAYER_H
 #define __SOUNDPLAYER_H
 
+#ifdef _MSC_VER
+#pragma warning(disable : 4250)
+#endif
+
+#include <common/queue.h>
 #include <xcommon/IXSoundSystem.h>
 #include "SoundBase.h"
 #include <mital.h>
@@ -16,7 +21,7 @@ See the license in LICENSE
 
 //##########################################################################
 
-class CSoundPlayer : public CSoundBase, public virtual IXSoundPlayer
+class CSoundPlayer: public CSoundBase, public virtual IXSoundPlayer
 {
 public:
 	SX_ALIGNED_OP_MEM
@@ -33,8 +38,6 @@ public:
 
 	//########################################################################
 
-	void XMETHODCALLTYPE setType(SOUND_DTYPE dtype);
-
 	void XMETHODCALLTYPE play() override;
 	void XMETHODCALLTYPE resume() override;
 	void XMETHODCALLTYPE pause() override;
@@ -53,9 +56,9 @@ public:
 protected:
 
 	friend CSoundLayer;
+	friend CSoundSystem;
 
-	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_DTYPE dtype);
-
+	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space);
 
 	//! возвращает текущую позицию проигрывания звука в байтах
 	uint32_t getPosBytes() const;
@@ -67,6 +70,41 @@ protected:
 
 	//########################################################################
 
+	void _setSpace(SOUND_SPACE space);
+	void _play();
+	void _resume();
+	void _pause();
+	void _stop();
+	void _setLoop(SOUND_LOOP loop);
+	void _setTime(float fTime);
+
+	//########################################################################
+
+	/*enum QUEUE_MSG_TYPE
+	{
+		QUEUE_MSG_TYPE_PLAY,
+		QUEUE_MSG_TYPE_RESUME,
+		QUEUE_MSG_TYPE_LOOP,
+		QUEUE_MSG_TYPE_DTYPE,
+		QUEUE_MSG_TYPE_TIME
+	};
+
+	struct QueueMsg
+	{
+		QUEUE_MSG_TYPE type;
+		union
+		{
+			float fTime;
+			SOUND_DTYPE dtype;
+			SOUND_LOOP loop;
+			SOUND_STATE state;
+		} arg;
+	};
+
+	//########################################################################
+
+	Queue<QueueMsg> m_oQueue;*/
+
 	//! аудио буфер
 	IAudioBuffer *m_pAB = NULL;
 
@@ -84,6 +122,10 @@ protected:
 
 	//! данные потоковой загрузки
 	CStreamData *m_pStream = NULL;
+
+	SpinLock m_oSpinLockPlay;
+
+	float3 m_vListenerPos, m_vListenerDir, m_vListenerUp;
 };
 
 #endif
diff --git a/source/xSound/SoundSystem.cpp b/source/xSound/SoundSystem.cpp
index 5b600308648b149a05cd9c269124f52fe7048f6d..5e2aae6256f635cc3a60dd63c1ec38cc39b4dd9c 100644
--- a/source/xSound/SoundSystem.cpp
+++ b/source/xSound/SoundSystem.cpp
@@ -3,6 +3,8 @@
 #include "AudioConverter.h"
 
 #include "SoundLayer.h"
+#include "SoundEmitter.h"
+#include "SoundPlayer.h"
 
 #include <ctime>
 #include <sys/stat.h>
@@ -49,14 +51,133 @@ CSoundSystem::~CSoundSystem()
 
 void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
-	std::lock_guard<std::mutex> guard(m_oMutexUpdate);
+	//ScopedSpinLock lock(m_oSpinLockUpdate);
 
 	if(m_pMasterLayer)
 		m_pMasterLayer->update(vListenerPos, vListenerDir, vListenerUp);
 
 	m_vObserverPos = vListenerPos; m_vObserverLook = vListenerDir; m_vObserverUp = vListenerUp;
+
+	SndQueueMsg oMsg;
+	while (m_queue.pop(&oMsg))
+	{
+		switch (oMsg.type)
+		{
+		case SND_QUEUE_MSG_TYPE_SND_NEW:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pLayer->addSndEmitter(oMsg.pEmitter);
+			else if (oMsg.pPlayer)
+				oMsg.pLayer->addSndPlayer(oMsg.pPlayer);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_DELETE:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pLayer->delSndEmitter(oMsg.pEmitter);
+			else if (oMsg.pPlayer)
+				oMsg.pLayer->delSndPlayer(oMsg.pPlayer);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_PLAY:
+		{
+			if (oMsg.arg.state == SOUND_STATE_PLAY)
+			{
+				if (oMsg.pEmitter) 
+					oMsg.pEmitter->_play();
+				else if (oMsg.pPlayer) 
+					oMsg.pPlayer->_play();
+			}
+			else if (oMsg.arg.state == SOUND_STATE_PAUSE)
+			{
+				if (oMsg.pEmitter)
+					oMsg.pEmitter->_pause();
+				else if (oMsg.pPlayer)
+					oMsg.pPlayer->_pause();
+			}
+			else if (oMsg.arg.state == SOUND_STATE_STOP)
+			{
+				if (oMsg.pPlayer)
+					oMsg.pPlayer->_stop();
+			}
+
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_RESUME:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_resume();
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_resume();
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_LOOP:
+		{
+			if (oMsg.pPlayer)
+				oMsg.pPlayer->_setLoop(oMsg.arg.loop);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_SPACE:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_setSpace(oMsg.arg.space);
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_setSpace(oMsg.arg.space);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_PAN:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_setPan(oMsg.arg.f);
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_setPan(oMsg.arg.f);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_VOLUME:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_setVolume(oMsg.arg.f);
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_setVolume(oMsg.arg.f);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_POS:
+		{
+			float3 vPos(oMsg.arg.vector[0], oMsg.arg.vector[1], oMsg.arg.vector[2]);
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_setWorldPos(vPos);
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_setWorldPos(vPos);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_DIST:
+		{
+			if (oMsg.pEmitter)
+				oMsg.pEmitter->_setDistance(oMsg.arg.f);
+			else if (oMsg.pPlayer)
+				oMsg.pPlayer->_setDistance(oMsg.arg.f);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_SND_TIME:
+		{
+			if (oMsg.pPlayer)
+				oMsg.pPlayer->_setTime(oMsg.arg.f);
+			break;
+		}
+
+		default:
+			break;
+		}
+	}
 }
 
+/*void CSoundSystem::getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp)
+{
+	ScopedSpinLock lock(m_oSpinLockUpdate);
+
+	*pPos = m_vObserverPos; *pLook = m_vObserverLook; *pUp = m_vObserverUp;
+}*/
+
 //**************************************************************************
 
 IXSoundLayer* XMETHODCALLTYPE CSoundSystem::createMasterLayer(const AudioRawDesc *pDesc, const char *szName)
@@ -64,12 +185,15 @@ IXSoundLayer* XMETHODCALLTYPE CSoundSystem::createMasterLayer(const AudioRawDesc
 	if(m_pMasterLayer)
 		return m_pMasterLayer;
 
-	if(!pDesc)
+	if (!pDesc)
+	{
+		LibReport(REPORT_MSG_LEVEL_ERROR, "Not found audio buffer description");
 		return NULL;
+	}
 
 	if (!supportedDesc(pDesc, AB_TYPE_PRIMARY))
 	{
-		printf("unsupported audio buffer description");
+		LibReport(REPORT_MSG_LEVEL_ERROR, "Unsupported audio buffer description");
 		return NULL;
 	}
 
@@ -129,7 +253,7 @@ IXAudioCodecTarget* CSoundSystem::getCodecTarget(const char *szName)
 	m_pMasterLayer->getDesc(&oDescMaster);
 	pTarget->getDesc(&oDescSnd);
 
-	//если звук соответствует требования мастер буфера, тогда не надо конвертировать, возвращает целевой кодек
+	//если звук соответствует требованиям мастер буфера, тогда не надо конвертировать, возвращает целевой кодек
 	if(oDescSnd.uSampleRate == oDescMaster.uSampleRate)
 		return pTarget;
 
diff --git a/source/xSound/SoundSystem.h b/source/xSound/SoundSystem.h
index f46234212a721f74c20a6e54f94bb736ca84db52..c904ad409d9e6a36f090ecadac019884c53cde51 100644
--- a/source/xSound/SoundSystem.h
+++ b/source/xSound/SoundSystem.h
@@ -11,6 +11,8 @@ See the license in LICENSE
 #include <common/string.h>
 #include <common/path_utils.h>
 #include <common/math.h>
+#include <common/spinlock.h>
+#include <common/queue.h>
 
 #include <xcommon/IXCore.h>
 #include <xcommon/IPluginManager.h>
@@ -62,13 +64,9 @@ 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;
-	}
+	//void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
+
+	void addMessage(SndQueueMsg &oMsg) { m_queue.push(oMsg); }
 
 protected:
 
@@ -81,6 +79,8 @@ protected:
 
 	//########################################################################
 
+	Queue<SndQueueMsg> m_queue;
+
 	IXCore *m_pXCore = NULL;
 
 	IAudio *m_pAudio = NULL;
@@ -93,7 +93,7 @@ protected:
 	MapCodec m_mapCodecs;
 
 	float3 m_vObserverPos, m_vObserverLook, m_vObserverUp;
-	std::mutex m_oMutexUpdate;
+	//SpinLock m_oSpinLockUpdate;
 };
 
 #endif
diff --git a/source/xSound/SoundTypes.h b/source/xSound/SoundTypes.h
index 5c4c77482db1e05e86c2ac643c665f889cb21def..eb68aabc16d2c7b6c009db42aaec1442012b0e02 100644
--- a/source/xSound/SoundTypes.h
+++ b/source/xSound/SoundTypes.h
@@ -9,12 +9,13 @@ See the license in LICENSE
 
 #include <xcommon/IXSoundSystem.h>
 #include <xcommon/IXAudioCodec.h>
+#include <common/math.h>
 
 #include <mital.h>
 
 //##########################################################################
 
-class CStreamData;
+struct CStreamData;
 
 class CSoundBase;
 class CSoundLoader;
@@ -33,5 +34,42 @@ enum SOUND_STATE
 	SOUND_STATE_PLAY,		//!< проигрывается
 };
 
+//##########################################################################
+
+enum SND_QUEUE_MSG_TYPE
+{
+	SND_QUEUE_MSG_TYPE_SND_NEW,
+	SND_QUEUE_MSG_TYPE_SND_DELETE,
+	SND_QUEUE_MSG_TYPE_SND_PLAY,
+	SND_QUEUE_MSG_TYPE_SND_RESUME,
+	SND_QUEUE_MSG_TYPE_SND_LOOP,
+	SND_QUEUE_MSG_TYPE_SND_SPACE,
+	SND_QUEUE_MSG_TYPE_SND_PAN,
+	SND_QUEUE_MSG_TYPE_SND_VOLUME,
+	SND_QUEUE_MSG_TYPE_SND_POS,
+	SND_QUEUE_MSG_TYPE_SND_DIST,
+	SND_QUEUE_MSG_TYPE_SND_TIME,
+	SND_QUEUE_MSG_TYPE_LAYER_NEW,
+	SND_QUEUE_MSG_TYPE_LAYER_DELETE,
+	SND_QUEUE_MSG_TYPE_LAYER_PLAY
+};
+
+struct SndQueueMsg
+{
+	SND_QUEUE_MSG_TYPE type;
+	union
+	{
+		bool b;
+		float f;
+		float vector[3];
+		SOUND_SPACE space;
+		SOUND_LOOP loop;
+		SOUND_STATE state;
+	} arg;
+
+	CSoundEmitter *pEmitter = NULL;
+	CSoundPlayer *pPlayer = NULL;
+	CSoundLayer *pLayer = NULL;
+};
 
-#endif
\ No newline at end of file
+#endif
diff --git a/source/xcommon/IXSoundSystem.h b/source/xcommon/IXSoundSystem.h
index 060bab35fc9095388f022120764b6ef9e600ffe7..cab07082180c4e576004696b5a465f8188aa1ed3 100644
--- a/source/xcommon/IXSoundSystem.h
+++ b/source/xcommon/IXSoundSystem.h
@@ -22,10 +22,16 @@ See the license in LICENSE
 
 #define SOUND_CACHE "cache"
 
-enum SOUND_DTYPE
+enum SOUND_TYPE
 {
-	SOUND_DTYPE_2D,
-	SOUND_DTYPE_3D
+	SOUND_TYPE_EMITTER,
+	SOUND_TYPE_PLAYER
+};
+
+enum SOUND_SPACE
+{
+	SOUND_SPACE_2D,
+	SOUND_SPACE_3D
 };
 
 //! тип зацикленности звука
@@ -41,8 +47,10 @@ enum SOUND_LOOP
 class IXSoundBase: public IXUnknown
 {
 public:
-	virtual SOUND_DTYPE XMETHODCALLTYPE getType() const = 0;
-	virtual void XMETHODCALLTYPE setType(SOUND_DTYPE dtype) = 0;
+	virtual SOUND_TYPE XMETHODCALLTYPE getType() const = 0;
+
+	virtual SOUND_SPACE XMETHODCALLTYPE getSpace() const = 0;
+	virtual void XMETHODCALLTYPE setSpace(SOUND_SPACE space) = 0;
 
 	virtual const char* XMETHODCALLTYPE getName() const = 0;
 
@@ -100,8 +108,8 @@ public:
 	virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) = 0;
 
 	virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) = 0;
-	virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_DTYPE dtype) = 0;
-	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_DTYPE dtype) = 0;
+	virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) = 0;
+	virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) = 0;
 
 	virtual void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const = 0;
 };