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; }