diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp
index 67d7b217d61e1775e25b31e9318cb72fd9575848..27bf9a7b2cb61fc5389b2d30bf3815020460a60e 100644
--- a/source/xSound/SoundEmitter.cpp
+++ b/source/xSound/SoundEmitter.cpp
@@ -189,6 +189,20 @@ void CSoundEmitter::_pause()
 
 //**************************************************************************
 
+void CSoundEmitter::_onLayerPlay(bool yesNo)
+{
+	if(yesNo)
+	{
+		_resume();
+	}
+	else
+	{
+		_pause();
+	}
+}
+
+//**************************************************************************
+
 void CSoundEmitter::_setSpace(SOUND_SPACE space)
 {
 	m_space = space;
diff --git a/source/xSound/SoundEmitter.h b/source/xSound/SoundEmitter.h
index e3ba47caac4589192ba6533e066bbff5c1f7bc69..04ba7cb242b55b824606e34555c769e34b521c52 100644
--- a/source/xSound/SoundEmitter.h
+++ b/source/xSound/SoundEmitter.h
@@ -69,6 +69,8 @@ protected:
 	void _setWorldPos(const float3 &vPos);
 	void _setDistance(float fDist);
 
+	void _onLayerPlay(bool yesNo);
+
 	//#########################################################################
 
 	//! инстанс звукового обьекта
diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp
index 7d4e7937de873a1f4543c2a7d87c1f25349bd11b..377096b69b348e94a3376562c44612c62d1a32df 100644
--- a/source/xSound/SoundLayer.cpp
+++ b/source/xSound/SoundLayer.cpp
@@ -183,7 +183,7 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::findLayer(const char *szName)
 
 //**************************************************************************
 
-uint32_t CSoundLayer::getStreamChunkSize(AudioRawDesc *pDesc) const
+size_t CSoundLayer::getStreamChunkSize(AudioRawDesc *pDesc) const
 {
 	return m_pPrimaryBuffer->getStreamChunkSize(pDesc);
 }
@@ -300,11 +300,12 @@ void XMETHODCALLTYPE CSoundLayer::play(bool canPlay)
 
 bool XMETHODCALLTYPE CSoundLayer::isPlaying() const
 {
-	return m_isPlaying;
+	return(m_isPlayingTotal);
 }
 
 //##########################################################################
 
+// FIXME никаких итераторов в апдейте!
 void CSoundLayer::update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp)
 {
 	for(MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
@@ -351,16 +352,27 @@ bool CSoundLayer::matchPrimaryLayer(const AudioRawDesc *pDesc)
 //##########################################################################
 //##########################################################################
 
-void CSoundLayer::_play(bool canPlay)
+void CSoundLayer::_play(bool canPlay, bool isFromParent)
 {
-	if(m_isPlaying == canPlay || (m_pParent && !m_pParent->isPlaying() && canPlay))
-		return;
+	//if(m_isPlaying == canPlay || (m_pParent && !m_pParent->isPlaying() && canPlay))
+	//	return;
+	//
+	//m_isPlaying = canPlay;
+	if(!isFromParent)
+	{
+		m_isPlaying = canPlay;
+	}
+	bool isPlaying = (!m_pParent || m_pParent->isPlaying()) && m_isPlaying;
 
-	m_isPlaying = canPlay;
+	if(m_isPlayingTotal == isPlaying)
+	{
+		return;
+	}
+	m_isPlayingTotal = isPlaying;
 
 	for(MapLayer::Iterator i = m_mapLayers.begin(); i; ++i)
 	{
-		(*i.second)->_play(canPlay);
+		(*i.second)->_play(isPlaying, true);
 	}
 
 	for(MapPlayer::Iterator i = m_mapSndPlayers.begin(); i; ++i)
@@ -368,10 +380,7 @@ void CSoundLayer::_play(bool canPlay)
 		ArrayPlayer &oAP = *i.second;
 		for(int k = 0, kl = oAP.size(); k < kl; ++k)
 		{
-			if(canPlay)
-				oAP[k]->_resume();
-			else
-				oAP[k]->_pause();
+			oAP[k]->_onLayerPlay(isPlaying);
 		}
 	}
 
@@ -380,12 +389,9 @@ void CSoundLayer::_play(bool canPlay)
 		ArrayEmitter &oAE = *i.second;
 		for(int k = 0, kl = oAE.size(); k < kl; ++k)
 		{
-			if(canPlay)
-				oAE[k]->_resume();
-			else
-				oAE[k]->_pause();
+			oAE[k]->_onLayerPlay(isPlaying);
 		}
 	}
 
-	m_pPrimaryBuffer->play(canPlay);
+	m_pPrimaryBuffer->play(isPlaying);
 }
diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h
index 8129e6db17409b56d338cc284577816f1df4dc9c..3c0cf7561536df59bc8500fd4bcf1286f55ec326 100644
--- a/source/xSound/SoundLayer.h
+++ b/source/xSound/SoundLayer.h
@@ -35,7 +35,7 @@ public:
 
 	//########################################################################
 
-	uint32_t getStreamChunkSize(AudioRawDesc *pDesc) const;
+	size_t getStreamChunkSize(AudioRawDesc *pDesc) const;
 	IAudioBuffer* createAudioBuffer(AB_TYPE type, const AudioRawDesc *pDesc);
 
 	void update(const float3 &vListenerPos, const float3 &vListenerDir, const float3 &vListenerUp);
@@ -66,7 +66,7 @@ protected:
 	void addSndEmitter(CSoundEmitter *pSndEmitter);
 	void delSndEmitter(const CSoundEmitter *pSndEmitter);
 
-	void _play(bool canPlay);
+	void _play(bool canPlay, bool isFromParent);
 
 	//************************************************************************
 
@@ -78,6 +78,7 @@ protected:
 	SOUND_STATE m_state = SOUND_STATE_STOP;
 
 	bool m_isPlaying = false;
+	bool m_isPlayingTotal = false;
 
 	CSoundLayer *m_pParent = NULL;
 
diff --git a/source/xSound/SoundLoader.cpp b/source/xSound/SoundLoader.cpp
index 51039cbb13ce1e7d932c2a083fe8729cc0fe2799..df11da8590bcb2143d2c46fbfb975b5331300663 100644
--- a/source/xSound/SoundLoader.cpp
+++ b/source/xSound/SoundLoader.cpp
@@ -17,11 +17,11 @@ void CSoundLoader::init(CSoundSystem *pSoundSystem)
 
 bool CSoundLoader::load(const char *szPath, AudioRawDesc *pDesc)
 {
-	if (!m_pSoundSystem)
+	if(!m_pSoundSystem)
 		return false;
 
 	m_pCodecTarget = m_pSoundSystem->getCodecTarget(szPath);
-	if (!m_pCodecTarget)
+	if(!m_pCodecTarget)
 		return false;
 
 	m_pCodecTarget->getDesc(pDesc);
@@ -29,28 +29,28 @@ bool CSoundLoader::load(const char *szPath, AudioRawDesc *pDesc)
 	return true;
 }
 
-size_t CSoundLoader::getPCM(void **ppData, uint32_t uLen, int32_t iPos)
+size_t CSoundLoader::getPCM(void **ppData, size_t uLen, int64_t iPos)
 {
-	if (!can())
+	if(!can())
 		return 0;
 
-	if (iPos < 0)
-		iPos = getPos();
+	if(iPos < 0)
+		iPos = (int64_t)getPos();
 
 	return m_pCodecTarget->decode(iPos, uLen, ppData);
 }
 
-void CSoundLoader::setPos(uint32_t uPos)
+void CSoundLoader::setPos(size_t uPos)
 {
-	if (!can())
+	if(!can())
 		return;
 
 	m_pCodecTarget->setPos(uPos);
 }
 
-int32_t CSoundLoader::getPos() const
+size_t CSoundLoader::getPos() const
 {
-	if (!can())
+	if(!can())
 		return 0;
 
 	return m_pCodecTarget->getPos();
diff --git a/source/xSound/SoundLoader.h b/source/xSound/SoundLoader.h
index 6372307387125f716ca48cd01a13414bd9a154cf..03b839d0eafa9bb1fabb68f516173495baed16dc 100644
--- a/source/xSound/SoundLoader.h
+++ b/source/xSound/SoundLoader.h
@@ -59,9 +59,9 @@ public:
 	/*! загружает звук через подходящий декодер
 	*/
 	bool load(const char *szPath, AudioRawDesc *pDesc);
-	size_t getPCM(void **ppData, uint32_t uLen, int32_t iPos = -1);
-	void setPos(uint32_t uPos);
-	int32_t getPos() const;
+	size_t getPCM(void **ppData, size_t uLen, int64_t iPos = -1);
+	void setPos(size_t uPos);
+	size_t getPos() const;
 
 protected:
 
diff --git a/source/xSound/SoundPlayer.cpp b/source/xSound/SoundPlayer.cpp
index 597fc568a1bbda8b99defa79f852decd398a0b0b..79d1c38e2e5077fc6a131e053ed716a52220a798 100644
--- a/source/xSound/SoundPlayer.cpp
+++ b/source/xSound/SoundPlayer.cpp
@@ -19,7 +19,7 @@ CSoundPlayer::~CSoundPlayer()
 //**************************************************************************
 
 void XMETHODCALLTYPE CSoundPlayer::FinalRelease()
-{ 
+{
 	SndQueueMsg oMsg;
 	oMsg.type = SND_QUEUE_MSG_TYPE_SND_DELETE;
 	oMsg.pPlayer = this;
@@ -38,7 +38,7 @@ bool CSoundPlayer::canInstance() const
 
 CSoundBase* CSoundPlayer::newInstance()
 {
-	if (m_pStream)
+	if(m_pStream)
 		return NULL;
 
 	CSoundPlayer *pPlayer = new CSoundPlayer();
@@ -61,7 +61,7 @@ CSoundBase* CSoundPlayer::newInstance()
 
 bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space)
 {
-	if (!pCodecTarget || !pLayer)
+	if(!pCodecTarget || !pLayer)
 		return false;
 
 	m_sName = szName;
@@ -72,19 +72,19 @@ bool CSoundPlayer::create(const char* szName, CSoundLayer *pLayer, IXAudioCodecT
 	pCodecTarget->getDesc(&oDesc);
 	m_uLengthBytes = oDesc.uSize;
 	m_fLengthMls = (uint32_t)(double(oDesc.uSize * 1000) / double(oDesc.uBytesPerSec));
-	
-	uint32_t uChunkSize = m_pLayer->getStreamChunkSize(&oDesc);
+
+	size_t uChunkSize = m_pLayer->getStreamChunkSize(&oDesc);
 
 
-	if (oDesc.uSize / uChunkSize > STREAM_COUNT_MIN_PARTS)
+	if(oDesc.uSize / uChunkSize > STREAM_COUNT_MIN_PARTS)
 	{
-		oDesc.uSize = uChunkSize * 4;
+		oDesc.uSize = (uint32_t)(uChunkSize * 4);
 		m_pAB = m_pLayer->createAudioBuffer(AB_TYPE_SECOND, &oDesc);
 		m_pStream = new CStreamData();
 		m_pStream->uPartSize = oDesc.uSize / STREAM_DATA_COUNT_PARTS;
 		m_pStream->oData.uSize = m_pStream->uPartSize;
 		m_pStream->oData.pData = new BYTE[m_pStream->oData.uSize];
-		for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
+		for(int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
 		{
 			m_pStream->aParts[i].uStart = i * m_pStream->uPartSize;
 			m_pStream->aParts[i].uEnd = m_pStream->aParts[i].uStart + m_pStream->uPartSize;
@@ -184,13 +184,13 @@ SOUND_LOOP XMETHODCALLTYPE CSoundPlayer::getLoop() const
 
 float XMETHODCALLTYPE CSoundPlayer::getTime() const
 {
-	uint32_t uPos = getPosBytes();
+	size_t uPos = getPosBytes();
 
-	if (m_pStream)
+	if(m_pStream)
 	{
 		AudioRawDesc oDesc;
 		m_pAB->getDesc(&oDesc);
-		uPos = (uint64_t(uPos) * uint64_t(1000)) / uint64_t(oDesc.uBytesPerSec);
+		uPos = (uPos * 1000) / oDesc.uBytesPerSec;
 	}
 
 	return float(uPos) / 1000.f;
@@ -215,25 +215,25 @@ float XMETHODCALLTYPE CSoundPlayer::getLength() const
 
 //##########################################################################
 
-void CSoundPlayer::setPosStream(uint32_t uPos)
+void CSoundPlayer::setPosStream(size_t uPos)
 {
 	uint32_t uCountParts = STREAM_DATA_COUNT_PARTS;
-	uint32_t uParts = uPos / (m_pStream->uPartSize * uCountParts);
-	if (uParts * m_pStream->uPartSize * uCountParts > uPos)
+	size_t uParts = uPos / (m_pStream->uPartSize * uCountParts);
+	if(uParts * m_pStream->uPartSize * uCountParts > uPos)
 		--uParts;
 
-	uint32_t uPosAB = (uPos - (uParts * m_pStream->uPartSize * uCountParts));
-	uint32_t uCurrPart = uPosAB / m_pStream->uPartSize;
-	m_pStream->uCountPlayed = uParts * uCountParts + uCurrPart;
+	size_t uPosAB = (uPos - (uParts * m_pStream->uPartSize * uCountParts));
+	size_t uCurrPart = uPosAB / m_pStream->uPartSize;
+	m_pStream->uCountPlayed = (uint32_t)(uParts * uCountParts + uCurrPart);
 
-	uint32_t uPosLoader = uPos - (uCurrPart * m_pStream->uPartSize);
+	size_t uPosLoader = uPos - (uCurrPart * m_pStream->uPartSize);
 	m_pCodecTarget->setPos(uPosLoader);
-	for (uint32_t i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
+	for(uint32_t i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
 	{
-		if (i >= uCurrPart)
+		if(i >= uCurrPart)
 		{
 			size_t sizeRead = m_pCodecTarget->decode(m_pCodecTarget->getPos(), m_pStream->oData.uSize, (void**)&(m_pStream->oData.pData));
-			if (sizeRead <= 0)
+			if(sizeRead <= 0)
 				continue;
 
 			BYTE *pData = 0;
@@ -256,14 +256,16 @@ void CSoundPlayer::setPosStream(uint32_t uPos)
 
 //**************************************************************************
 
-uint32_t CSoundPlayer::getPosBytes() const
+size_t CSoundPlayer::getPosBytes() const
 {
 	size_t uPos = m_pAB->getPos();
 
-	if (m_pStream)
-		uPos = (uint64_t(uPos) + uint64_t(m_pStream->uPartSize) * uint64_t(m_pStream->uCountPlayed));
+	if(m_pStream)
+	{
+		uPos = uPos + m_pStream->uPartSize * m_pStream->uCountPlayed;
+	}
 
-	return uPos;
+	return(uPos);
 }
 
 //##########################################################################
@@ -275,49 +277,61 @@ void CSoundPlayer::update(const float3 &vListenerPos, const float3 &vListenerDir
 	m_vListenerUp = vListenerUp;
 
 
-	if (!m_pLayer->isPlaying())
+	if(!m_pLayer->isPlaying())
 		return;
 
-	if (m_space == SOUND_SPACE_3D)
+	if(m_space == SOUND_SPACE_3D)
+	{
 		Com3D(m_pAB, m_fDist, m_fVolume, m_vWorldPos, vListenerPos, vListenerDir, vListenerUp);
-	else
-		int qwerty = 0;
+	}
 
-	if (!m_pStream)
+	if(!m_pStream)
+	{
+		if(m_state == SOUND_STATE_PLAY && !m_pAB->isPlaying())
+		{
+			_stop();
+		}
 		return;
+	}
 
-	uint32_t uGPosBytes = getPosBytes();
+	size_t uGPosBytes = getPosBytes();
 	//uint32_t uGPosBytes2 = m_pCodecTarget->getPos();
 	float fPos = getTime();
 
-	if (uGPosBytes >= m_uLengthBytes)
+	if(uGPosBytes >= m_uLengthBytes)
 	{
-		if (m_loop == AB_LOOP_NONE)
-			m_pAB->play(false);
+		if(m_loop == AB_LOOP_NONE)
+		{
+			_stop();
+		}
 		else
+		{
 			_setTime(0.f);
+		}
 	}
 
-	if (!isPlaying())
+	if(!isPlaying())
 		return;
 
 	size_t uPos = m_pAB->getPos();
 
-	for (int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
+	for(int i = 0; i < STREAM_DATA_COUNT_PARTS; ++i)
 	{
-		if (m_pStream->aParts[i].uStart <= uPos && uPos <= m_pStream->aParts[i].uEnd)
+		if(m_pStream->aParts[i].uStart <= uPos && uPos <= m_pStream->aParts[i].uEnd)
+		{
 			m_pStream->aParts[i].isPlay = true;
+		}
 		else
 		{
-			if (m_pStream->aParts[i].isPlay)
+			if(m_pStream->aParts[i].isPlay)
 			{
 				m_pStream->aParts[i].isPlay = false;
 				m_pStream->aParts[i].isLoaded = false;
 
 				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;
+				if(sizeRead == 0)
+					continue;
 
 				BYTE *pData = 0;
 				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);
@@ -345,24 +359,34 @@ void CSoundPlayer::_setSpace(SOUND_SPACE space)
 
 void CSoundPlayer::_play()
 {
-	if (!m_pLayer->isPlaying())
+	m_state = SOUND_STATE_PLAY;
+
+	if(!m_pLayer->isPlaying())
 	{
-		m_state = SOUND_STATE_PAUSE;
 		return;
 	}
 
-	if (m_space == SOUND_SPACE_3D)
+	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)
+	if(m_state != SOUND_STATE_PAUSE)
+	{
+		return;
+	}
+	m_state = SOUND_STATE_PLAY;
+
+	if(!m_pLayer->isPlaying())
+	{
 		return;
+	}
 
 	m_pAB->play(true);
 }
@@ -386,10 +410,24 @@ void CSoundPlayer::_stop()
 
 //**************************************************************************
 
+void CSoundPlayer::_onLayerPlay(bool yesNo)
+{
+	if(!yesNo)
+	{
+		m_pAB->play(false);
+	}
+	else if(m_state == SOUND_STATE_PLAY)
+	{
+		m_pAB->play(true);
+	}
+}
+
+//**************************************************************************
+
 void CSoundPlayer::_setLoop(SOUND_LOOP loop)
 {
 	m_loop = loop;
-	if (!m_pStream)
+	if(!m_pStream)
 		m_pAB->setLoop((AB_LOOP)m_loop);
 }
 
@@ -401,10 +439,10 @@ void CSoundPlayer::_setTime(float fTime)
 	m_pAB->getDesc(&oDesc);
 	uint32_t uPosBytes = (uint64_t(fTime * 1000.f) * uint64_t(oDesc.uBytesPerSec)) / uint64_t(1000);
 
-	if (m_uLengthBytes < uPosBytes)
+	if(m_uLengthBytes < uPosBytes)
 		return;
 
-	if (m_pStream)
+	if(m_pStream)
 		setPosStream(uPosBytes);
 	else
 		m_pAB->setPos(uPosBytes);
diff --git a/source/xSound/SoundPlayer.h b/source/xSound/SoundPlayer.h
index 136722adbc9ec6fc3a633d4483b55b193fd0bfe8..cca9c938f58552edcd60cf5afbd13f6562c36247 100644
--- a/source/xSound/SoundPlayer.h
+++ b/source/xSound/SoundPlayer.h
@@ -62,12 +62,12 @@ protected:
 	bool create(const char* szName, CSoundLayer *pLayer, IXAudioCodecTarget *pCodecTarget, SOUND_SPACE space);
 
 	//! возвращает текущую позицию проигрывания звука в байтах
-	uint32_t getPosBytes() const;
+	size_t getPosBytes() const;
 
 	/*! установка позиции при потоковом воспроизведении
 		@param uPos позиция в байтах
 	*/
-	void setPosStream(uint32_t uPos);
+	void setPosStream(size_t uPos);
 
 	//**********************************************************************
 	// функции сообщений
@@ -80,6 +80,8 @@ protected:
 	void _setLoop(SOUND_LOOP loop);
 	void _setTime(float fTime);
 
+	void _onLayerPlay(bool yesNo);
+
 	//########################################################################
 
 	//! аудио буфер
diff --git a/source/xSound/SoundSystem.cpp b/source/xSound/SoundSystem.cpp
index d95f9630674c21ec99e1466dcb1785981439ef04..9ddceb66f7f703ed53ecced0d0be5ff1d35b089c 100644
--- a/source/xSound/SoundSystem.cpp
+++ b/source/xSound/SoundSystem.cpp
@@ -179,7 +179,7 @@ void XMETHODCALLTYPE CSoundSystem::update(const float3 &vListenerPos, const floa
 		case SND_QUEUE_MSG_TYPE_LAYER_PLAY:
 			{
 				if(oMsg.pLayer)
-					oMsg.pLayer->_play(oMsg.arg.b);
+					oMsg.pLayer->_play(oMsg.arg.b, false);
 				break;
 			}