Object tracker list refactor; add object tracker to audio system

This commit is contained in:
Jack Andersen
2017-12-02 20:05:16 -10:00
parent 3c4f304d5a
commit 03de8811b1
12 changed files with 328 additions and 769 deletions

View File

@@ -1,34 +1,35 @@
#include "AudioVoiceEngine.hpp"
#include <cassert>
namespace boo
{
BaseAudioVoiceEngine::~BaseAudioVoiceEngine()
{
while (m_activeVoices.size())
m_activeVoices.front()->unbindVoice();
while (m_activeSubmixes.size())
m_activeSubmixes.front()->unbindSubmix();
m_mainSubmix.reset();
assert(m_voiceHead == nullptr && "Dangling voices detected");
assert(m_submixHead == nullptr && "Dangling submixes detected");
}
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
template <typename T>
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, T* dataOut)
{
memset(dataOut, 0, sizeof(int16_t) * frames * m_mixInfo.m_channelMap.m_channelCount);
memset(dataOut, 0, sizeof(T) * frames * m_mixInfo.m_channelMap.m_channelCount);
if (m_ltRtProcessing)
{
size_t sampleCount = m_5msFrames * 5;
if (m_ltRtIn16.size() < sampleCount)
m_ltRtIn16.resize(sampleCount);
m_mainSubmix.m_redirect16 = m_ltRtIn16.data();
if (_getLtRtIn<T>().size() < sampleCount)
_getLtRtIn<T>().resize(sampleCount);
m_mainSubmix->_getRedirect<T>() = _getLtRtIn<T>().data();
}
else
{
m_mainSubmix.m_redirect16 = dataOut;
m_mainSubmix->_getRedirect<T>() = dataOut;
}
if (m_submixesDirty)
{
m_linearizedSubmixes = m_mainSubmix._linearizeC3();
m_linearizedSubmixes = m_mainSubmix->_linearizeC3();
m_submixesDirty = false;
}
@@ -50,22 +51,23 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
}
if (m_ltRtProcessing)
std::fill(m_ltRtIn16.begin(), m_ltRtIn16.end(), 0);
std::fill(_getLtRtIn<T>().begin(), _getLtRtIn<T>().end(), 0.f);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_zeroFill16();
(*it)->_zeroFill<T>();
for (AudioVoice* vox : m_activeVoices)
if (vox->m_running)
vox->pumpAndMix16(thisFrames);
if (m_voiceHead)
for (AudioVoice& vox : *m_voiceHead)
if (vox.m_running)
vox.pumpAndMix<T>(thisFrames);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_pumpAndMix16(thisFrames);
(*it)->_pumpAndMix<T>(thisFrames);
if (m_ltRtProcessing)
{
m_ltRtProcessing->Process(m_ltRtIn16.data(), dataOut, int(thisFrames));
m_mainSubmix.m_redirect16 = m_ltRtIn16.data();
m_ltRtProcessing->Process(_getLtRtIn<T>().data(), dataOut, int(thisFrames));
m_mainSubmix->_getRedirect<T>() = _getLtRtIn<T>().data();
}
size_t sampleCount = thisFrames * m_mixInfo.m_channelMap.m_channelCount;
@@ -80,165 +82,16 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
m_engineCallback->onPumpCycleComplete(*this);
}
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int32_t* dataOut)
{
memset(dataOut, 0, sizeof(int32_t) * frames * m_mixInfo.m_channelMap.m_channelCount);
if (m_ltRtProcessing)
{
size_t sampleCount = m_5msFrames * 5;
if (m_ltRtIn32.size() < sampleCount)
m_ltRtIn32.resize(sampleCount);
m_mainSubmix.m_redirect32 = m_ltRtIn32.data();
}
else
{
m_mainSubmix.m_redirect32 = dataOut;
}
if (m_submixesDirty)
{
m_linearizedSubmixes = m_mainSubmix._linearizeC3();
m_submixesDirty = false;
}
size_t remFrames = frames;
while (remFrames)
{
size_t thisFrames;
if (remFrames < m_5msFrames)
{
thisFrames = remFrames;
if (m_engineCallback)
m_engineCallback->on5MsInterval(*this, thisFrames / double(m_5msFrames) * 5.0 / 1000.0);
}
else
{
thisFrames = m_5msFrames;
if (m_engineCallback)
m_engineCallback->on5MsInterval(*this, 5.0 / 1000.0);
}
if (m_ltRtProcessing)
std::fill(m_ltRtIn32.begin(), m_ltRtIn32.end(), 0);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_zeroFill32();
for (AudioVoice* vox : m_activeVoices)
if (vox->m_running)
vox->pumpAndMix32(thisFrames);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_pumpAndMix32(thisFrames);
if (m_ltRtProcessing)
{
m_ltRtProcessing->Process(m_ltRtIn32.data(), dataOut, int(thisFrames));
m_mainSubmix.m_redirect32 = m_ltRtIn32.data();
}
size_t sampleCount = thisFrames * m_mixInfo.m_channelMap.m_channelCount;
for (size_t i=0 ; i<sampleCount ; ++i)
dataOut[i] *= m_totalVol;
remFrames -= thisFrames;
dataOut += sampleCount;
}
if (m_engineCallback)
m_engineCallback->onPumpCycleComplete(*this);
}
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, float* dataOut)
{
memset(dataOut, 0, sizeof(float) * frames * m_mixInfo.m_channelMap.m_channelCount);
if (m_ltRtProcessing)
{
size_t sampleCount = m_5msFrames * 5;
if (m_ltRtInFlt.size() < sampleCount)
m_ltRtInFlt.resize(sampleCount);
m_mainSubmix.m_redirectFlt = m_ltRtInFlt.data();
}
else
{
m_mainSubmix.m_redirectFlt = dataOut;
}
if (m_submixesDirty)
{
m_linearizedSubmixes = m_mainSubmix._linearizeC3();
m_submixesDirty = false;
}
size_t remFrames = frames;
while (remFrames)
{
size_t thisFrames;
if (remFrames < m_5msFrames)
{
thisFrames = remFrames;
if (m_engineCallback)
m_engineCallback->on5MsInterval(*this, thisFrames / double(m_5msFrames) * 5.0 / 1000.0);
}
else
{
thisFrames = m_5msFrames;
if (m_engineCallback)
m_engineCallback->on5MsInterval(*this, 5.0 / 1000.0);
}
if (m_ltRtProcessing)
std::fill(m_ltRtInFlt.begin(), m_ltRtInFlt.end(), 0.f);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_zeroFillFlt();
for (AudioVoice* vox : m_activeVoices)
if (vox->m_running)
vox->pumpAndMixFlt(thisFrames);
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
(*it)->_pumpAndMixFlt(thisFrames);
if (m_ltRtProcessing)
{
m_ltRtProcessing->Process(m_ltRtInFlt.data(), dataOut, int(thisFrames));
m_mainSubmix.m_redirectFlt = m_ltRtInFlt.data();
}
size_t sampleCount = thisFrames * m_mixInfo.m_channelMap.m_channelCount;
for (size_t i=0 ; i<sampleCount ; ++i)
dataOut[i] *= m_totalVol;
remFrames -= thisFrames;
dataOut += sampleCount;
}
if (m_engineCallback)
m_engineCallback->onPumpCycleComplete(*this);
}
void BaseAudioVoiceEngine::_unbindFrom(std::list<AudioVoice*>::iterator it)
{
m_activeVoices.erase(it);
}
void BaseAudioVoiceEngine::_unbindFrom(std::list<AudioSubmix*>::iterator it)
{
m_activeSubmixes.erase(it);
m_submixesDirty = true;
}
template void BaseAudioVoiceEngine::_pumpAndMixVoices<int16_t>(size_t frames, int16_t* dataOut);
template void BaseAudioVoiceEngine::_pumpAndMixVoices<int32_t>(size_t frames, int32_t* dataOut);
template void BaseAudioVoiceEngine::_pumpAndMixVoices<float>(size_t frames, float* dataOut);
std::unique_ptr<IAudioVoice>
BaseAudioVoiceEngine::allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch)
{
std::unique_ptr<IAudioVoice> ret =
std::make_unique<AudioVoiceMono>(*this, cb, sampleRate, dynamicPitch);
AudioVoiceMono* retMono = static_cast<AudioVoiceMono*>(ret.get());
retMono->bindVoice(m_activeVoices.insert(m_activeVoices.end(), retMono));
return ret;
return std::make_unique<AudioVoiceMono>(*this, cb, sampleRate, dynamicPitch);
}
std::unique_ptr<IAudioVoice>
@@ -246,20 +99,13 @@ BaseAudioVoiceEngine::allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch)
{
std::unique_ptr<IAudioVoice> ret =
std::make_unique<AudioVoiceStereo>(*this, cb, sampleRate, dynamicPitch);
AudioVoiceStereo* retStereo = static_cast<AudioVoiceStereo*>(ret.get());
retStereo->bindVoice(m_activeVoices.insert(m_activeVoices.end(), retStereo));
return ret;
return std::make_unique<AudioVoiceStereo>(*this, cb, sampleRate, dynamicPitch);
}
std::unique_ptr<IAudioSubmix>
BaseAudioVoiceEngine::allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId)
{
std::unique_ptr<IAudioSubmix> ret = std::make_unique<AudioSubmix>(*this, cb, busId, mainOut);
AudioSubmix* retIntern = static_cast<AudioSubmix*>(ret.get());
retIntern->bindSubmix(m_activeSubmixes.insert(m_activeSubmixes.end(), retIntern));
return ret;
return std::make_unique<AudioSubmix>(*this, cb, busId, mainOut);
}
void BaseAudioVoiceEngine::setCallbackInterface(IAudioVoiceEngineCallback* cb)