Default audio mixing to main output

This commit is contained in:
Jack Andersen 2016-12-13 15:08:42 -10:00
parent d309f124b9
commit 7463426fe6
2 changed files with 87 additions and 30 deletions

View File

@ -95,19 +95,19 @@ struct IAudioVoiceCallback
/** after resampling, boo calls this for each submix that this voice targets;
* client performs volume processing and bus-routing this way */
virtual void routeAudio(size_t frames, double dt, int busId, int16_t* in, int16_t* out)
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out)
{
memmove(out, in, frames * 2);
memmove(out, in, frames * channels * 2);
}
virtual void routeAudio(size_t frames, double dt, int busId, int32_t* in, int32_t* out)
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out)
{
memmove(out, in, frames * 4);
memmove(out, in, frames * channels * 4);
}
virtual void routeAudio(size_t frames, double dt, int busId, float* in, float* out)
virtual void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out)
{
memmove(out, in, frames * 4);
memmove(out, in, frames * channels * 4);
}
};

View File

@ -6,6 +6,9 @@ namespace boo
{
static logvisor::Module Log("boo::AudioVoice");
static AudioMatrixMono DefaultMonoMtx;
static AudioMatrixStereo DefaultStereoMtx;
AudioVoice::AudioVoice(BaseAudioVoiceEngine& root,
IAudioVoiceCallback* cb, bool dynamicRate)
: m_root(root), m_cb(cb), m_dynamicRate(dynamicRate) {}
@ -136,14 +139,23 @@ size_t AudioVoiceMono::pumpAndMix16(size_t frames)
size_t oDone = soxr_output(m_src, scratch16Pre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratch16Pre.data(), scratch16Post.data());
m_cb->routeAudio(oDone, 1, dt, smx.m_busId, scratch16Pre.data(), scratch16Post.data());
mtx.second.mixMonoSampleData(m_root.m_mixInfo, scratch16Post.data(), smx._getMergeBuf16(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 1, dt, m_root.m_mainSubmix.m_busId, scratch16Pre.data(), scratch16Post.data());
DefaultMonoMtx.mixMonoSampleData(m_root.m_mixInfo, scratch16Post.data(), smx._getMergeBuf16(oDone), oDone);
}
}
return oDone;
}
@ -164,14 +176,23 @@ size_t AudioVoiceMono::pumpAndMix32(size_t frames)
size_t oDone = soxr_output(m_src, scratch32Pre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratch32Pre.data(), scratch32Post.data());
m_cb->routeAudio(oDone, 1, dt, smx.m_busId, scratch32Pre.data(), scratch32Post.data());
mtx.second.mixMonoSampleData(m_root.m_mixInfo, scratch32Post.data(), smx._getMergeBuf32(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 1, dt, m_root.m_mainSubmix.m_busId, scratch32Pre.data(), scratch32Post.data());
DefaultMonoMtx.mixMonoSampleData(m_root.m_mixInfo, scratch32Post.data(), smx._getMergeBuf32(oDone), oDone);
}
}
return oDone;
}
@ -192,14 +213,23 @@ size_t AudioVoiceMono::pumpAndMixFlt(size_t frames)
size_t oDone = soxr_output(m_src, scratchFltPre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratchFltPre.data(), scratchFltPost.data());
m_cb->routeAudio(oDone, 1, dt, smx.m_busId, scratchFltPre.data(), scratchFltPost.data());
mtx.second.mixMonoSampleData(m_root.m_mixInfo, scratchFltPost.data(), smx._getMergeBufFlt(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 1, dt, m_root.m_mainSubmix.m_busId, scratchFltPre.data(), scratchFltPost.data());
DefaultMonoMtx.mixMonoSampleData(m_root.m_mixInfo, scratchFltPost.data(), smx._getMergeBufFlt(oDone), oDone);
}
}
return oDone;
}
@ -306,14 +336,23 @@ size_t AudioVoiceStereo::pumpAndMix16(size_t frames)
size_t oDone = soxr_output(m_src, scratch16Pre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratch16Pre.data(), scratch16Post.data());
m_cb->routeAudio(oDone, 2, dt, smx.m_busId, scratch16Pre.data(), scratch16Post.data());
mtx.second.mixStereoSampleData(m_root.m_mixInfo, scratch16Post.data(), smx._getMergeBuf16(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 2, dt, m_root.m_mainSubmix.m_busId, scratch16Pre.data(), scratch16Post.data());
DefaultStereoMtx.mixStereoSampleData(m_root.m_mixInfo, scratch16Post.data(), smx._getMergeBuf16(oDone), oDone);
}
}
return oDone;
}
@ -336,14 +375,23 @@ size_t AudioVoiceStereo::pumpAndMix32(size_t frames)
size_t oDone = soxr_output(m_src, scratch32Pre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratch32Pre.data(), scratch32Post.data());
m_cb->routeAudio(oDone, 2, dt, smx.m_busId, scratch32Pre.data(), scratch32Post.data());
mtx.second.mixStereoSampleData(m_root.m_mixInfo, scratch32Post.data(), smx._getMergeBuf32(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 2, dt, m_root.m_mainSubmix.m_busId, scratch32Pre.data(), scratch32Post.data());
DefaultStereoMtx.mixStereoSampleData(m_root.m_mixInfo, scratch32Post.data(), smx._getMergeBuf32(oDone), oDone);
}
}
return oDone;
}
@ -366,14 +414,23 @@ size_t AudioVoiceStereo::pumpAndMixFlt(size_t frames)
size_t oDone = soxr_output(m_src, scratchFltPre.data(), frames);
if (oDone)
{
if (m_sendMatrices.size())
{
for (auto& mtx : m_sendMatrices)
{
AudioSubmix& smx = *reinterpret_cast<AudioSubmix*>(mtx.first);
m_cb->routeAudio(oDone, dt, smx.m_busId, scratchFltPre.data(), scratchFltPost.data());
m_cb->routeAudio(oDone, 2, dt, smx.m_busId, scratchFltPre.data(), scratchFltPost.data());
mtx.second.mixStereoSampleData(m_root.m_mixInfo, scratchFltPost.data(), smx._getMergeBufFlt(oDone), oDone);
}
}
else
{
AudioSubmix& smx = reinterpret_cast<AudioSubmix&>(m_root.m_mainSubmix);
m_cb->routeAudio(oDone, 2, dt, m_root.m_mainSubmix.m_busId, scratchFltPre.data(), scratchFltPost.data());
DefaultStereoMtx.mixStereoSampleData(m_root.m_mixInfo, scratchFltPost.data(), smx._getMergeBufFlt(oDone), oDone);
}
}
return oDone;
}