diff --git a/source/game/SoundPlayer.cpp b/source/game/SoundPlayer.cpp
index 2faecc56e968662f1769985780c0fb1b66267520..ea9dfc37c98b2e695d2444a15012d1ca559e14a9 100644
--- a/source/game/SoundPlayer.cpp
+++ b/source/game/SoundPlayer.cpp
@@ -22,16 +22,11 @@ DEFINE_FIELD_FLOAT(m_fDist, 0, "distance", "Hearing distance", EDITOR_TEXTFIELD)
 
 //! Зацикливание
 DEFINE_FIELD_INT(m_iLoop, 0, "loop", "Loop", EDITOR_COMBOBOX)
-	COMBO_OPTION("None", "0")			//!< Нет
+	COMBO_OPTION("None", "0")		//!< Нет
 	COMBO_OPTION("Simple", "1")		//!< Простое (могут быть пустоты на стыках конца с началом)
 	COMBO_OPTION("Seamless", "2")	//!< Непрерывное (пустот не будет, все будет заполнено звуком)
 EDITOR_COMBO_END()
 
-/*DEFINE_FIELD_INT(m_iType, 0, "type", "Type", EDITOR_COMBOBOX)
-	COMBO_OPTION("2D", "0")
-	COMBO_OPTION("3D", "1")
-EDITOR_COMBO_END()*/
-
 //! Включить
 DEFINE_INPUT(turnOn, "turnOn", "Turn On", PDF_NONE)
 //! Выключить
@@ -76,10 +71,10 @@ void CSoundPlayer::setSound(const char *szSound)
 	{
 		mem_release(m_pPlayer);
 		IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID));
-		IXSoundLayer *pMasterLayer = pSound->findLayer("master");
+		IXSoundLayer *pGameLayer = pSound->findLayer("xGame");
 
 		SOUND_SPACE space = (getFlags() & SND_PLAYER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D);
-		m_pPlayer = pMasterLayer->newSoundPlayer(szSound, space);
+		m_pPlayer = pGameLayer->newSoundPlayer(szSound, space);
 
 		if (m_pPlayer)
 		{
@@ -109,12 +104,6 @@ void CSoundPlayer::onSync()
 
 	if (m_pPlayer->getVolume() != m_fVolume)
 		m_pPlayer->setVolume(m_fVolume);
-
-	/*if (m_iType != m_pPlayer->getType())
-	{
-		m_pPlayer->setType((SOUND_DTYPE)m_iType);
-		m_pPlayer->setPan(0.f);
-	}*/
 }
 
 //##########################################################################
diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp
index 576e8f972b21ef1a13572c62d29263a7614cc4ae..67d7b217d61e1775e25b31e9318cb72fd9575848 100644
--- a/source/xSound/SoundEmitter.cpp
+++ b/source/xSound/SoundEmitter.cpp
@@ -8,18 +8,21 @@
 
 CSoundEmitter::~CSoundEmitter()
 {
-	//m_pLayer->delSndEmitter(this);
+	for (auto i = 0u, il = m_aInstances.size(); i < il; ++i)
+	{
+		mem_delete(m_aInstances[i]);
+	}
+
+	mem_release(m_pLayer);
+}
 
+void XMETHODCALLTYPE CSoundEmitter::FinalRelease()
+{
 	SndQueueMsg oMsg;
 	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DELETE;
 	oMsg.pEmitter = this;
-	oMsg.pLayer = m_pLayer;
+	oMsg.pOwner = m_pLayer;
 	m_pLayer->addMessage(oMsg);
-
-	for (auto i = 0u, il = m_aInstances.size(); i < il; ++i)
-	{
-		mem_delete(m_aInstances[i]);
-	}
 }
 
 //##########################################################################
@@ -103,6 +106,7 @@ bool CSoundEmitter::create(const char* szName, CSoundLayer *pLayer, IXAudioCodec
 	pAB->setLoop(AB_LOOP_NONE);
 
 	m_aInstances.push_back(new Instance(pAB));
+	pLayer->AddRef();
 
 	return true;
 }
diff --git a/source/xSound/SoundEmitter.h b/source/xSound/SoundEmitter.h
index fa99085d9f8c1a25b06ed7b6d978f67cae1d6e5b..f9aaee61c507c900bf80cf3119961a3219919cb7 100644
--- a/source/xSound/SoundEmitter.h
+++ b/source/xSound/SoundEmitter.h
@@ -47,6 +47,9 @@ public:
 	//! остановка проигрывания
 	void pause();
 
+private:
+	virtual void XMETHODCALLTYPE FinalRelease() override;
+
 protected:
 
 	friend CSoundLayer;
@@ -54,6 +57,9 @@ protected:
 
 	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space);
 
+	//**********************************************************************
+	// функции сообщений
+
 	void _play();
 	void _resume();
 	void _pause();
@@ -65,6 +71,7 @@ protected:
 
 	//#########################################################################
 
+	//! инстанс звукового обьекта
 	struct Instance
 	{
 		Instance() = default;
@@ -76,8 +83,10 @@ protected:
 
 	//#########################################################################
 
+	//! массив инстансов
 	Array<Instance*> m_aInstances;
 
+	//! параметры слушателя
 	float3 m_vListenerPos, m_vListenerDir, m_vListenerUp;
 };
 
diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp
index 8b1d61fa68707644b7f2caa895ca10360d7d86d6..5d6af0dd405e966b5283a98789cf1ee5d0661a4e 100644
--- a/source/xSound/SoundLayer.cpp
+++ b/source/xSound/SoundLayer.cpp
@@ -9,25 +9,11 @@
 
 CSoundLayer::~CSoundLayer()
 {
-	if (m_pParent)
-		m_pParent->delLayer(this);
-
-	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
-	{
-		mem_release(m_mapLayers[i.first]);
-		m_mapLayers.erase(i.first);
-	}
-
+	m_mapLayers.clear();
 
 	for(MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
 	{
 		ArrayPlayer *oAP = i.second;
-		//while (oAP->size())
-		for (auto k = 0u, kl = oAP->size(); k < kl; ++k)
-		{
-			CSoundPlayer *pPlayer = oAP->get(k);
-			mem_release(pPlayer);
-		}
 		oAP->clear();
 	}
 	m_mapSndPlayers.clear();
@@ -35,17 +21,40 @@ CSoundLayer::~CSoundLayer()
 	for (MapEmitter::Iterator i = m_mapSndEmitters.begin(); i; ++i)
 	{
 		ArrayEmitter *oAE = i.second;
-		//while (oAE->size())
-		for (auto k = 0u, kl = oAE->size(); k < kl; ++k)
-		{
-			CSoundEmitter *pEmitter = oAE->get(k);
-			mem_release(pEmitter);
-		}
 		oAE->clear();
 	}
 	m_mapSndEmitters.clear();
 
 	mem_release(m_pPrimaryBuffer);
+	mem_release(m_pParent);
+}
+
+//**************************************************************************
+
+void XMETHODCALLTYPE CSoundLayer::FinalRelease()
+{
+	if (m_pParent)
+	{
+		SndQueueMsg oMsg;
+		oMsg.type = SND_QUEUE_MSG_TYPE_LAYER_DELETE;
+		oMsg.pLayer = this;
+		oMsg.pOwner = m_pParent;
+		m_pParent->addMessage(oMsg);
+	}
+	else
+	{
+		mem_del(this);
+	}
+}
+
+//**************************************************************************
+
+void CSoundLayer::Release2()
+{
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
+		m_mapLayers[i.first]->Release2();
+	
+	Release();
 }
 
 //**************************************************************************
@@ -60,26 +69,32 @@ bool CSoundLayer::init(CSoundSystem *pSoundSystem, CSoundLayer *pParent, const A
 		return false;
 	}
 
+	m_sName = szName;
+	m_pParent = pParent;
+	m_pSoundSystem = pSoundSystem;
+
 	AudioRawDesc oDesc = *pDesc;
 	oDesc.uSize = 0;
 
 	if (pParent == NULL)
 		m_pPrimaryBuffer = pSoundSystem->createMasterBuffer(&oDesc);
 	else
-		m_pPrimaryBuffer = dynamic_cast<IAudioBufferEx*>(createAudioBuffer(AB_TYPE_PRIMARY, &oDesc));
+		m_pPrimaryBuffer = dynamic_cast<IAudioBufferEx*>(pParent->createAudioBuffer(AB_TYPE_PRIMARY, &oDesc));
 
-	m_sName = szName;
-	m_pParent = pParent;
-	m_pSoundSystem = pSoundSystem;
+	if (m_pParent)
+		m_pParent->AddRef();
 
 	return true;
 }
 
 //**************************************************************************
 
-void CSoundLayer::addLayer(CSoundLayer *pLayer, const char *szName)
+void CSoundLayer::addLayer(CSoundLayer *pLayer)
 {
-	m_mapLayers[szName] = pLayer;
+	if (m_pSoundSystem->findLayer(pLayer->getName()))
+		LibReport(REPORT_MSG_LEVEL_FATAL, "Layer name '%s' exists", pLayer->getName());
+
+	m_mapLayers[pLayer->getName()] = pLayer;
 }
 
 void CSoundLayer::delLayer(const CSoundLayer *pLayer)
@@ -92,11 +107,13 @@ void CSoundLayer::delLayer(const CSoundLayer *pLayer)
 			break;
 		}
 	}
+
+	mem_delete(pLayer);
 }
 
 //**************************************************************************
 
-void CSoundLayer::addSndPlayer(CSoundPlayer *pSndPlayer/*, const char *szName*/)
+void CSoundLayer::addSndPlayer(CSoundPlayer *pSndPlayer)
 {
 	m_mapSndPlayers[pSndPlayer->getName()].push_back(pSndPlayer);
 }
@@ -113,11 +130,13 @@ void CSoundLayer::delSndPlayer(const CSoundPlayer *pSndPlayer)
 		if (oAP->get(i) == pSndPlayer)
 			m_mapSndPlayers[szName].erase(i);
 	}
+
+	mem_delete(pSndPlayer);
 }
 
 //**************************************************************************
 
-void CSoundLayer::addSndEmitter(CSoundEmitter *pSndEmitter/*, const char *szName*/)
+void CSoundLayer::addSndEmitter(CSoundEmitter *pSndEmitter)
 {
 	m_mapSndEmitters[pSndEmitter->getName()].push_back(pSndEmitter);
 }
@@ -134,6 +153,8 @@ void CSoundLayer::delSndEmitter(const CSoundEmitter *pSndEmitter)
 		if (oAE->get(i) == pSndEmitter)
 			m_mapSndEmitters[szName].erase(i);
 	}
+
+	mem_delete(pSndEmitter);
 }
 
 //**************************************************************************
@@ -186,7 +207,7 @@ IAudioBuffer* CSoundLayer::createAudioBuffer(AB_TYPE type, const AudioRawDesc *p
 	return m_pPrimaryBuffer->createAudioBuffer(type, pDesc);
 }
 
-//**************************************************************************
+//##########################################################################
 
 IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDesc, const char *szName)
 {
@@ -199,11 +220,17 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDe
 	CSoundLayer *pLayer = new CSoundLayer();
 	pLayer->init(m_pSoundSystem, this, pDesc, szName);
 
-	addLayer(pLayer, szName);
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_LAYER_NEW;
+	oMsg.pLayer = pLayer;
+	oMsg.pOwner = this;
+	m_pSoundSystem->addMessage(oMsg);
 
 	return pLayer;
 }
 
+//**************************************************************************
+
 IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName, SOUND_SPACE space)
 {
 	if (!szName)
@@ -213,14 +240,12 @@ IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName,
 
 	if (m_mapSndEmitters.KeyExists(szName) && m_mapSndEmitters[szName].size() > 0)
 	{
-		/*CSoundEmitter *pEmitterOrigin = m_mapSndEmitters[szName];
-		pEmitter = pEmitterOrigin->newInstance();*/
-
-		pEmitter = static_cast<CSoundEmitter*>(m_mapSndEmitters[szName][0]->newInstance());
-		/*addSndEmitter(pEmitter, szName);
-		return pEmitter;*/
+		CSoundEmitter *pEmitterOrigin = m_mapSndEmitters[szName][0];
+		if (pEmitterOrigin->canInstance())
+			pEmitter = static_cast<CSoundEmitter*>(pEmitterOrigin->newInstance());
 	}
-	else
+	
+	if (!pEmitter)
 	{
 		IXAudioCodecTarget *pCodecTarget = m_pSoundSystem->getCodecTarget(szName);
 		if (!pCodecTarget)
@@ -230,17 +255,17 @@ IXSoundEmitter* XMETHODCALLTYPE CSoundLayer::newSoundEmitter(const char *szName,
 		pEmitter->create(szName, this, pCodecTarget, space);
 	}
 
-	//addSndEmitter(pEmitter/*, szName*/);
-
 	SndQueueMsg oMsg;
 	oMsg.type = SND_QUEUE_MSG_TYPE_SND_NEW;
 	oMsg.pEmitter = pEmitter;
-	oMsg.pLayer = this;
+	oMsg.pOwner = this;
 	m_pSoundSystem->addMessage(oMsg);
 
 	return pEmitter;
 }
 
+//**************************************************************************
+
 IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, SOUND_SPACE space)
 {
 	if (!szName)
@@ -265,12 +290,10 @@ IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, S
 		pPlayer->create(szName, this, pCodecTarget, space);
 	}
 
-	//addSndPlayer(pPlayer/*, szName*/);
-
 	SndQueueMsg oMsg;
 	oMsg.type = SND_QUEUE_MSG_TYPE_SND_NEW;
 	oMsg.pPlayer = pPlayer;
-	oMsg.pLayer = this;
+	oMsg.pOwner = this;
 	m_pSoundSystem->addMessage(oMsg);
 
 	return pPlayer;
@@ -280,46 +303,22 @@ IXSoundPlayer* XMETHODCALLTYPE CSoundLayer::newSoundPlayer(const char *szName, S
 
 void XMETHODCALLTYPE CSoundLayer::play(bool canPlay)
 {
-	if (m_isPlaying == canPlay || (m_pParent && !m_pParent->isPlaying() && canPlay))
-		return;
-
-	m_isPlaying = canPlay;
-
-	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
-		m_mapLayers[i.first]->play(canPlay);
-
-	for(MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
-	{
-		ArrayPlayer *oAP = i.second;
-		for(int k = 0, kl = oAP->size(); k < kl; ++k)
-		{
-			if(canPlay)
-				oAP->get(k)->resume();
-			else
-				oAP->get(k)->pause();
-		}
-	}
-
-	for (MapEmitter::Iterator i = m_mapSndEmitters.begin(); i; ++i)
-	{
-		ArrayEmitter *oAE = i.second;
-		for (int k = 0, kl = oAE->size(); k < kl; ++k)
-		{
-			if (canPlay)
-				oAE->get(k)->resume();
-			else
-				oAE->get(k)->pause();
-		}
-	}
-
-	m_pPrimaryBuffer->play(canPlay);
+	SndQueueMsg oMsg;
+	oMsg.type = SND_QUEUE_MSG_TYPE_LAYER_PLAY;
+	oMsg.pLayer = this;
+	oMsg.arg.b = canPlay;
+	addMessage(oMsg);
 }
 
+//**************************************************************************
+
 bool XMETHODCALLTYPE CSoundLayer::isPlaying() const
 {
 	return m_isPlaying;
 }
 
+//##########################################################################
+
 void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
 	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
@@ -343,15 +342,14 @@ void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir,
 	}
 }
 
+//**************************************************************************
+
 void CSoundLayer::addMessage(SndQueueMsg &oMsg) 
 {
 	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)
 {
@@ -363,3 +361,43 @@ bool CSoundLayer::matchPrimaryLayer(const AudioRawDesc *pDesc)
 
 	return (oPrimaryDesc.uSampleRate == pDesc->uSampleRate);
 }
+
+//##########################################################################
+//##########################################################################
+
+void CSoundLayer::_play(bool canPlay)
+{
+	if (m_isPlaying == canPlay || (m_pParent && !m_pParent->isPlaying() && canPlay))
+		return;
+
+	m_isPlaying = canPlay;
+
+	for (MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
+		m_mapLayers[i.first]->play(canPlay);
+
+	for (MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
+	{
+		ArrayPlayer *oAP = i.second;
+		for (int k = 0, kl = oAP->size(); k < kl; ++k)
+		{
+			if (canPlay)
+				oAP->get(k)->resume();
+			else
+				oAP->get(k)->pause();
+		}
+	}
+
+	for (MapEmitter::Iterator i = m_mapSndEmitters.begin(); i; ++i)
+	{
+		ArrayEmitter *oAE = i.second;
+		for (int k = 0, kl = oAE->size(); k < kl; ++k)
+		{
+			if (canPlay)
+				oAE->get(k)->resume();
+			else
+				oAE->get(k)->pause();
+		}
+	}
+
+	m_pPrimaryBuffer->play(canPlay);
+}
diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h
index 6cb5b18c22328328aaa159cb565d0b5087c5a27c..81cca0899ce7454af7d3cdee118d28b11a14acb6 100644
--- a/source/xSound/SoundLayer.h
+++ b/source/xSound/SoundLayer.h
@@ -43,7 +43,14 @@ public:
 
 	void addMessage(SndQueueMsg &oMsg);
 
-	//void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
+	/*! релиз слоя 
+		все внутренние слои тоже будут зарелизены, 
+		сначала релизяться дочерние слои и только потом целевой
+	*/
+	void Release2();
+
+private:
+	virtual void XMETHODCALLTYPE FinalRelease() override;
 
 protected:
 
@@ -54,16 +61,20 @@ protected:
 	bool init(CSoundSystem *pSoundSystem, CSoundLayer *pParent, const AudioRawDesc *pDesc, const char *szName);
 
 	//************************************************************************
+	// функции добавления/удаления обьектов в массивы
+	// при удалении из массива произойдет mem_delete удаляемого обьекта
 
-	void addLayer(CSoundLayer *pLayer, const char *szName);
+	void addLayer(CSoundLayer *pLayer);
 	void delLayer(const CSoundLayer *pLayer);
 
-	void addSndPlayer(CSoundPlayer *pSndPlayer/*, const char *szName*/);
+	void addSndPlayer(CSoundPlayer *pSndPlayer);
 	void delSndPlayer(const CSoundPlayer *pSndPlayer);
 
-	void addSndEmitter(CSoundEmitter *pSndEmitter/*, const char *szName*/);
+	void addSndEmitter(CSoundEmitter *pSndEmitter);
 	void delSndEmitter(const CSoundEmitter *pSndEmitter);
 
+	void _play(bool canPlay);
+
 	//************************************************************************
 
 	//! соответствует ли описание (его критические элементы) аудио буфера первичному буферу
diff --git a/source/xSound/SoundPlayer.cpp b/source/xSound/SoundPlayer.cpp
index 0dd6b5573b25857f076cfe185c9d61d8b98a1b8b..45ed876783c996ff151a3db69c173636474afe93 100644
--- a/source/xSound/SoundPlayer.cpp
+++ b/source/xSound/SoundPlayer.cpp
@@ -8,18 +8,23 @@
 
 CSoundPlayer::~CSoundPlayer()
 {
-	//m_pLayer->delSndPlayer(this);
+	mem_release(m_pAB);
+
+	mem_delete(m_pCodecTarget);
+	mem_delete(m_pStream);
+
+	mem_release(m_pLayer);
+}
 
+//**************************************************************************
+
+void XMETHODCALLTYPE CSoundPlayer::FinalRelease()
+{ 
 	SndQueueMsg oMsg;
 	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DELETE;
 	oMsg.pPlayer = this;
-	oMsg.pLayer = m_pLayer;
+	oMsg.pOwner = m_pLayer;
 	m_pLayer->addMessage(oMsg);
-
-	mem_release(m_pAB);
-
-	mem_delete(m_pCodecTarget);
-	mem_delete(m_pStream);
 }
 
 //**************************************************************************
@@ -29,6 +34,8 @@ bool CSoundPlayer::canInstance() const
 	return (!m_pStream);
 }
 
+//**************************************************************************
+
 CSoundBase* CSoundPlayer::newInstance()
 {
 	if (m_pStream)
@@ -98,23 +105,15 @@ bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecT
 		mem_delete_a(pData);
 	}
 
-	setTime(0);
+	m_pAB->play(false);
+	_setTime(0);
+	pLayer->AddRef();
 
 	return true;
 }
 
 //##########################################################################
 
-/*void XMETHODCALLTYPE CSoundPlayer::setType(SOUND_DTYPE space)
-{
-	QueueMsg oMsg;
-	oMsg.type = QUEUE_MSG_TYPE_DTYPE;
-	oMsg.arg.dtype = dtype;
-	m_oQueue.push(oMsg);
-}*/
-
-//##########################################################################
-
 void XMETHODCALLTYPE CSoundPlayer::play()
 {
 	SndQueueMsg oMsg;
@@ -211,7 +210,7 @@ void XMETHODCALLTYPE CSoundPlayer::setTime(float fTime)
 
 float XMETHODCALLTYPE CSoundPlayer::getLength() const
 {
-	return double(m_fLengthMls) / 1000.f;
+	return float(m_fLengthMls) / 1000.f;
 }
 
 //##########################################################################
@@ -229,7 +228,7 @@ void CSoundPlayer::setPosStream(uint32_t uPos)
 
 	uint32_t uPosLoader = uPos - (uCurrPart * m_pStream->uPartSize);
 	m_pCodecTarget->setPos(uPosLoader);
-	for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
+	for (uint32_t i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
 	{
 		if (i >= uCurrPart)
 		{
@@ -238,7 +237,7 @@ void CSoundPlayer::setPosStream(uint32_t uPos)
 				continue;
 
 			BYTE *pData = 0;
-			uint32_t uLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart);
+			size_t sizeLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart);
 			memcpy(pData, m_pStream->oData.pData, sizeRead);
 			m_pAB->unlock();
 
@@ -259,7 +258,7 @@ void CSoundPlayer::setPosStream(uint32_t uPos)
 
 uint32_t CSoundPlayer::getPosBytes() const
 {
-	uint32_t uPos = m_pAB->getPos();
+	size_t uPos = m_pAB->getPos();
 
 	if (m_pStream)
 		uPos = (uint64_t(uPos) + uint64_t(m_pStream->uPartSize) * uint64_t(m_pStream->uCountPlayed));
@@ -275,39 +274,6 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 	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;
@@ -321,14 +287,8 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 		return;
 
 	uint32_t uGPosBytes = getPosBytes();
-	uint32_t uGPosBytes2 = m_pCodecTarget->getPos();
-
-	/*static uint32_t uMax = 0;
-	if (uMax < uGPosBytes)
-	{
-		uMax = uGPosBytes;
-		printf("uMax = %d\n", uMax);
-	}*/
+	//uint32_t uGPosBytes2 = m_pCodecTarget->getPos();
+	float fPos = getTime();
 
 	if (uGPosBytes >= m_uLengthBytes)
 	{
@@ -341,7 +301,7 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 	if (!isPlaying())
 		return;
 
-	uint32_t uPos = m_pAB->getPos();
+	size_t uPos = m_pAB->getPos();
 
 	for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
 	{
@@ -357,11 +317,11 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 				size_t sizeRead = m_pCodecTarget->decode(m_pCodecTarget->getPos(), m_pStream->oData.uSize, (void**)&(m_pStream->oData.pData));
 				++(m_pStream->uCountPlayed);
 				if (sizeRead == 0)
-					continue;
+ 					continue;
 
 				BYTE *pData = 0;
-				uint32_t uLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart);
-				memset(pData, 0, uLocked);
+				size_t sizeLocked = m_pAB->lock(AB_LOCK_WRITE, (void**)&pData, m_pStream->aParts[i].uStart, m_pStream->aParts[i].uEnd - m_pStream->aParts[i].uStart);
+				memset(pData, 0, sizeLocked);
 				memcpy(pData, m_pStream->oData.pData, sizeRead);
 				m_pAB->unlock();
 
@@ -381,16 +341,24 @@ void CSoundPlayer::_setSpace(SOUND_SPACE space)
 	m_space = space;
 }
 
+//**************************************************************************
+
 void CSoundPlayer::_play()
 {
 	if (!m_pLayer->isPlaying())
+	{
+		m_state = SOUND_STATE_PAUSE;
 		return;
+	}
 
-	Com3D(m_pAB, m_fDist, m_fVolume, m_vWorldPos, m_vListenerPos, m_vListenerDir, m_vListenerUp);
+	if (m_space == SOUND_SPACE_3D)
+		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)
@@ -399,12 +367,16 @@ void CSoundPlayer::_resume()
 	m_pAB->play(true);
 }
 
+//**************************************************************************
+
 void CSoundPlayer::_pause()
 {
 	m_pAB->play(false);
 	m_state = SOUND_STATE_PAUSE;
 }
 
+//**************************************************************************
+
 void CSoundPlayer::_stop()
 {
 	m_pAB->play(false);
@@ -412,6 +384,8 @@ void CSoundPlayer::_stop()
 	m_state = SOUND_STATE_STOP;
 }
 
+//**************************************************************************
+
 void CSoundPlayer::_setLoop(SOUND_LOOP loop)
 {
 	m_loop = loop;
@@ -419,6 +393,8 @@ void CSoundPlayer::_setLoop(SOUND_LOOP loop)
 		m_pAB->setLoop((AB_LOOP)m_loop);
 }
 
+//**************************************************************************
+
 void CSoundPlayer::_setTime(float fTime)
 {
 	AudioRawDesc oDesc;
@@ -432,4 +408,4 @@ void CSoundPlayer::_setTime(float fTime)
 		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 920b29279d222d27eebac27b433699fbac9ea779..9c40bb3f675612a4ab1f935cbcefe890713ba020 100644
--- a/source/xSound/SoundPlayer.h
+++ b/source/xSound/SoundPlayer.h
@@ -53,6 +53,9 @@ public:
 
 	float XMETHODCALLTYPE getLength() const override;
 
+private:
+	virtual void XMETHODCALLTYPE FinalRelease() override;
+
 protected:
 
 	friend CSoundLayer;
@@ -68,7 +71,8 @@ protected:
 	*/
 	void setPosStream(uint32_t uPos);
 
-	//########################################################################
+	//**********************************************************************
+	// функции сообщений
 
 	void _setSpace(SOUND_SPACE space);
 	void _play();
@@ -80,31 +84,6 @@ protected:
 
 	//########################################################################
 
-	/*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;
 
@@ -123,8 +102,7 @@ protected:
 	//! данные потоковой загрузки
 	CStreamData *m_pStream = NULL;
 
-	SpinLock m_oSpinLockPlay;
-
+	//! параметры слушателя
 	float3 m_vListenerPos, m_vListenerDir, m_vListenerUp;
 };
 
diff --git a/source/xSound/SoundSystem.cpp b/source/xSound/SoundSystem.cpp
index 5e2aae6256f635cc3a60dd63c1ec38cc39b4dd9c..cc7ab946b4347da1182fd5b7118fd47d70a60a6b 100644
--- a/source/xSound/SoundSystem.cpp
+++ b/source/xSound/SoundSystem.cpp
@@ -44,15 +44,20 @@ CSoundSystem::CSoundSystem(IXCore *pXCore)
 
 CSoundSystem::~CSoundSystem()
 {
-	mem_release(m_pMasterLayer);
+	//mem_release(m_pMasterLayer);
+	m_pMasterLayer->Release2();
+	update(float3(), float3(), float3());
 }
 
 //**************************************************************************
 
-void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+void CSoundSystem::addMessage(SndQueueMsg &oMsg)
 {
-	//ScopedSpinLock lock(m_oSpinLockUpdate);
+	m_queue.push(oMsg); 
+}
 
+void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
+{
 	if(m_pMasterLayer)
 		m_pMasterLayer->update(vListenerPos, vListenerDir, vListenerUp);
 
@@ -66,17 +71,17 @@ void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const floa
 		case SND_QUEUE_MSG_TYPE_SND_NEW:
 		{
 			if (oMsg.pEmitter)
-				oMsg.pLayer->addSndEmitter(oMsg.pEmitter);
+				oMsg.pOwner->addSndEmitter(oMsg.pEmitter);
 			else if (oMsg.pPlayer)
-				oMsg.pLayer->addSndPlayer(oMsg.pPlayer);
+				oMsg.pOwner->addSndPlayer(oMsg.pPlayer);
 			break;
 		}
 		case SND_QUEUE_MSG_TYPE_SND_DELETE:
 		{
 			if (oMsg.pEmitter)
-				oMsg.pLayer->delSndEmitter(oMsg.pEmitter);
+				oMsg.pOwner->delSndEmitter(oMsg.pEmitter);
 			else if (oMsg.pPlayer)
-				oMsg.pLayer->delSndPlayer(oMsg.pPlayer);
+				oMsg.pOwner->delSndPlayer(oMsg.pPlayer);
 			break;
 		}
 		case SND_QUEUE_MSG_TYPE_SND_PLAY:
@@ -164,6 +169,25 @@ void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const floa
 				oMsg.pPlayer->_setTime(oMsg.arg.f);
 			break;
 		}
+		case SND_QUEUE_MSG_TYPE_LAYER_NEW:
+		{
+			if (oMsg.pOwner && oMsg.pLayer)
+				oMsg.pOwner->addLayer(oMsg.pLayer);
+			break;
+		}
+		case SND_QUEUE_MSG_TYPE_LAYER_DELETE:
+		{
+			if (oMsg.pOwner && oMsg.pLayer)
+				oMsg.pOwner->delLayer(oMsg.pLayer);
+			break;
+		}
+
+		case SND_QUEUE_MSG_TYPE_LAYER_PLAY:
+		{
+			if (oMsg.pLayer)
+				oMsg.pLayer->_play(oMsg.arg.b);
+			break;
+		}
 
 		default:
 			break;
@@ -171,13 +195,6 @@ void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const floa
 	}
 }
 
-/*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)
@@ -415,4 +432,3 @@ IXAudioCodec* CSoundSystem::getCodecSave()
 
 	return NULL;
 }
-
diff --git a/source/xSound/SoundSystem.h b/source/xSound/SoundSystem.h
index c904ad409d9e6a36f090ecadac019884c53cde51..e1e10f149546a9b0ccc5c48c53f991edf7b86adf 100644
--- a/source/xSound/SoundSystem.h
+++ b/source/xSound/SoundSystem.h
@@ -64,9 +64,7 @@ public:
 
 	IXCore* getCore() const;
 
-	//void getObserverParam(float3 *pPos, float3 *pLook, float3 *pUp);
-
-	void addMessage(SndQueueMsg &oMsg) { m_queue.push(oMsg); }
+	void addMessage(SndQueueMsg &oMsg);
 
 protected:
 
@@ -93,7 +91,8 @@ protected:
 	MapCodec m_mapCodecs;
 
 	float3 m_vObserverPos, m_vObserverLook, m_vObserverUp;
-	//SpinLock m_oSpinLockUpdate;
+	
+	SpinLock m_oSpinLockUpdate;
 };
 
 #endif
diff --git a/source/xSound/SoundTypes.h b/source/xSound/SoundTypes.h
index eb68aabc16d2c7b6c009db42aaec1442012b0e02..d7ddc2c47a12bfd51b62e391b105e14dc8df1f38 100644
--- a/source/xSound/SoundTypes.h
+++ b/source/xSound/SoundTypes.h
@@ -70,6 +70,8 @@ struct SndQueueMsg
 	CSoundEmitter *pEmitter = NULL;
 	CSoundPlayer *pPlayer = NULL;
 	CSoundLayer *pLayer = NULL;
+
+	CSoundLayer *pOwner = NULL;
 };
 
 #endif
diff --git a/source/xSound/plugin_main.cpp b/source/xSound/plugin_main.cpp
index f21f993d4857a09e75dac5bd9dccbc1f9032b3f3..3f571e1b26538e7970bffeecc2a3e194e70acc89 100644
--- a/source/xSound/plugin_main.cpp
+++ b/source/xSound/plugin_main.cpp
@@ -68,6 +68,7 @@ public:
 	}
 	void shutdown() override
 	{
+		m_pSoundSystem->update(float3(), float3(), float3());
 		mem_release(m_pSoundSystem);
 	}