mirror of
https://github.com/AxioDL/boo.git
synced 2025-07-03 19:55:58 +00:00
dry-main, wet-submix audio routing
This commit is contained in:
parent
175aabbb0e
commit
f1e07861ca
@ -68,6 +68,12 @@ struct IAudioVoice
|
||||
/** Set channel-gains for stereo audio source (AudioChannel enum for array index) */
|
||||
virtual void setStereoMatrixCoefficients(const float coefs[8][2], bool slew)=0;
|
||||
|
||||
/** Set submix-channel-gains for mono audio source (AudioChannel enum for array index) */
|
||||
virtual void setMonoSubmixMatrixCoefficients(const float coefs[8], bool slew)=0;
|
||||
|
||||
/** Set submix-channel-gains for stereo audio source (AudioChannel enum for array index) */
|
||||
virtual void setStereoSubmixMatrixCoefficients(const float coefs[8][2], bool slew)=0;
|
||||
|
||||
/** Called by client to dynamically adjust the pitch of voices with dynamic pitch enabled */
|
||||
virtual void setPitchRatio(double ratio, bool slew)=0;
|
||||
|
||||
|
@ -22,7 +22,7 @@ AudioSubmix::~AudioSubmix()
|
||||
unbindSubmix();
|
||||
}
|
||||
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, int16_t* dataOut, int16_t* mainOut)
|
||||
{
|
||||
const AudioVoiceEngineMixInfo& info = mixInfo();
|
||||
size_t sampleCount = frames * info.m_channelMap.m_channelCount;
|
||||
@ -35,11 +35,11 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
|
||||
/* Pump child voices */
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, m_scratch16.data());
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, mainOut, m_scratch16.data());
|
||||
|
||||
/* Pump child submixes */
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(frames, m_scratch16.data());
|
||||
smx->_pumpAndMixVoices(frames, m_scratch16.data(), mainOut);
|
||||
|
||||
/* Apply submix effect (if available) */
|
||||
if (m_cb && m_cb->canApplyEffect())
|
||||
@ -55,7 +55,7 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, int32_t* dataOut)
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, int32_t* dataOut, int32_t* mainOut)
|
||||
{
|
||||
const AudioVoiceEngineMixInfo& info = mixInfo();
|
||||
size_t sampleCount = frames * info.m_channelMap.m_channelCount;
|
||||
@ -68,11 +68,11 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, int32_t* dataOut)
|
||||
/* Pump child voices */
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, m_scratch32.data());
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, mainOut, m_scratch32.data());
|
||||
|
||||
/* Pump child submixes */
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(frames, m_scratch32.data());
|
||||
smx->_pumpAndMixVoices(frames, m_scratch32.data(), mainOut);
|
||||
|
||||
/* Apply submix effect (if available) */
|
||||
if (m_cb && m_cb->canApplyEffect())
|
||||
@ -88,7 +88,7 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, int32_t* dataOut)
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, float* dataOut)
|
||||
void AudioSubmix::_pumpAndMixVoices(size_t frames, float* dataOut, float* mainOut)
|
||||
{
|
||||
const AudioVoiceEngineMixInfo& info = mixInfo();
|
||||
size_t sampleCount = frames * info.m_channelMap.m_channelCount;
|
||||
@ -101,11 +101,11 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, float* dataOut)
|
||||
/* Pump child voices */
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, m_scratchFlt.data());
|
||||
vox->pumpAndMix(m_parent.mixInfo(), frames, mainOut, m_scratchFlt.data());
|
||||
|
||||
/* Pump child submixes */
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(frames, m_scratchFlt.data());
|
||||
smx->_pumpAndMixVoices(frames, m_scratchFlt.data(), mainOut);
|
||||
|
||||
/* Apply submix effect (if available) */
|
||||
if (m_cb && m_cb->canApplyEffect())
|
||||
|
@ -41,9 +41,9 @@ class AudioSubmix : public IAudioSubmix, public IAudioMix
|
||||
std::vector<int32_t> m_scratch32;
|
||||
std::vector<float> m_scratchFlt;
|
||||
|
||||
void _pumpAndMixVoices(size_t frames, int16_t* dataOut);
|
||||
void _pumpAndMixVoices(size_t frames, int32_t* dataOut);
|
||||
void _pumpAndMixVoices(size_t frames, float* dataOut);
|
||||
void _pumpAndMixVoices(size_t frames, int16_t* dataOut, int16_t* mainOut);
|
||||
void _pumpAndMixVoices(size_t frames, int32_t* dataOut, int32_t* mainOut);
|
||||
void _pumpAndMixVoices(size_t frames, float* dataOut, float* mainOut);
|
||||
|
||||
void _unbindFrom(std::list<AudioVoice*>::iterator it);
|
||||
void _unbindFrom(std::list<AudioSubmix*>::iterator it);
|
||||
|
@ -114,7 +114,7 @@ size_t AudioVoiceMono::SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t f
|
||||
}
|
||||
|
||||
size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, int16_t* buf)
|
||||
size_t frames, int16_t* buf, int16_t* rbuf)
|
||||
{
|
||||
std::vector<int16_t>& scratch16 = m_root.m_scratch16;
|
||||
if (scratch16.size() < frames)
|
||||
@ -124,13 +124,17 @@ size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixMonoSampleData(mixInfo, scratch16.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixMonoSampleData(mixInfo, scratch16.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
|
||||
size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, int32_t* buf)
|
||||
size_t frames, int32_t* buf, int32_t* rbuf)
|
||||
{
|
||||
std::vector<int32_t>& scratch32 = m_root.m_scratch32;
|
||||
if (scratch32.size() < frames)
|
||||
@ -140,13 +144,17 @@ size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixMonoSampleData(mixInfo, scratch32.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixMonoSampleData(mixInfo, scratch32.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
|
||||
size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, float* buf)
|
||||
size_t frames, float* buf, float* rbuf)
|
||||
{
|
||||
std::vector<float>& scratchFlt = m_root.m_scratchFlt;
|
||||
if (scratchFlt.size() < frames)
|
||||
@ -156,7 +164,11 @@ size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixMonoSampleData(mixInfo, scratchFlt.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixMonoSampleData(mixInfo, scratchFlt.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
@ -164,6 +176,8 @@ size_t AudioVoiceMono::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
void AudioVoiceMono::setDefaultMatrixCoefficients()
|
||||
{
|
||||
m_matrix.setDefaultMatrixCoefficients(m_parent.mixInfo().m_channels);
|
||||
float zero[8] = {};
|
||||
m_subMatrix.setMatrixCoefficients(zero);
|
||||
}
|
||||
|
||||
void AudioVoiceMono::setMonoMatrixCoefficients(const float coefs[8], bool slew)
|
||||
@ -187,6 +201,27 @@ void AudioVoiceMono::setStereoMatrixCoefficients(const float coefs[8][2], bool s
|
||||
m_matrix.setMatrixCoefficients(newCoefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
void AudioVoiceMono::setMonoSubmixMatrixCoefficients(const float coefs[8], bool slew)
|
||||
{
|
||||
m_subMatrix.setMatrixCoefficients(coefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
void AudioVoiceMono::setStereoSubmixMatrixCoefficients(const float coefs[8][2], bool slew)
|
||||
{
|
||||
float newCoefs[8] =
|
||||
{
|
||||
coefs[0][0],
|
||||
coefs[1][0],
|
||||
coefs[2][0],
|
||||
coefs[3][0],
|
||||
coefs[4][0],
|
||||
coefs[5][0],
|
||||
coefs[6][0],
|
||||
coefs[7][0]
|
||||
};
|
||||
m_subMatrix.setMatrixCoefficients(newCoefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
AudioVoiceStereo::AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioMix& parent, IAudioVoiceCallback* cb,
|
||||
double sampleRate, bool dynamicRate)
|
||||
: AudioVoice(root, parent, cb, dynamicRate)
|
||||
@ -231,7 +266,7 @@ size_t AudioVoiceStereo::SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size
|
||||
}
|
||||
|
||||
size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, int16_t* buf)
|
||||
size_t frames, int16_t* buf, int16_t* rbuf)
|
||||
{
|
||||
std::vector<int16_t>& scratch16 = m_root.m_scratch16;
|
||||
size_t samples = frames * 2;
|
||||
@ -242,13 +277,17 @@ size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixStereoSampleData(mixInfo, scratch16.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixStereoSampleData(mixInfo, scratch16.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
|
||||
size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, int32_t* buf)
|
||||
size_t frames, int32_t* buf, int32_t* rbuf)
|
||||
{
|
||||
std::vector<int32_t>& scratch32 = m_root.m_scratch32;
|
||||
size_t samples = frames * 2;
|
||||
@ -259,13 +298,17 @@ size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixStereoSampleData(mixInfo, scratch32.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixStereoSampleData(mixInfo, scratch32.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
|
||||
size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
size_t frames, float* buf)
|
||||
size_t frames, float* buf, float* rbuf)
|
||||
{
|
||||
std::vector<float>& scratchFlt = m_root.m_scratchFlt;
|
||||
size_t samples = frames * 2;
|
||||
@ -276,7 +319,11 @@ size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
_midUpdate();
|
||||
|
||||
if (oDone)
|
||||
{
|
||||
m_matrix.mixStereoSampleData(mixInfo, scratchFlt.data(), buf, oDone);
|
||||
if (rbuf)
|
||||
m_subMatrix.mixStereoSampleData(mixInfo, scratchFlt.data(), rbuf, oDone);
|
||||
}
|
||||
|
||||
return oDone;
|
||||
}
|
||||
@ -284,6 +331,8 @@ size_t AudioVoiceStereo::pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo,
|
||||
void AudioVoiceStereo::setDefaultMatrixCoefficients()
|
||||
{
|
||||
m_matrix.setDefaultMatrixCoefficients(m_parent.mixInfo().m_channels);
|
||||
float zero[8][2] = {{}};
|
||||
m_subMatrix.setMatrixCoefficients(zero);
|
||||
}
|
||||
|
||||
void AudioVoiceStereo::setMonoMatrixCoefficients(const float coefs[8], bool slew)
|
||||
@ -307,4 +356,25 @@ void AudioVoiceStereo::setStereoMatrixCoefficients(const float coefs[8][2], bool
|
||||
m_matrix.setMatrixCoefficients(coefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
void AudioVoiceStereo::setMonoSubmixMatrixCoefficients(const float coefs[8], bool slew)
|
||||
{
|
||||
float newCoefs[8][2] =
|
||||
{
|
||||
{coefs[0], coefs[0]},
|
||||
{coefs[1], coefs[1]},
|
||||
{coefs[2], coefs[2]},
|
||||
{coefs[3], coefs[3]},
|
||||
{coefs[4], coefs[4]},
|
||||
{coefs[5], coefs[5]},
|
||||
{coefs[6], coefs[6]},
|
||||
{coefs[7], coefs[7]}
|
||||
};
|
||||
m_subMatrix.setMatrixCoefficients(newCoefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
void AudioVoiceStereo::setStereoSubmixMatrixCoefficients(const float coefs[8][2], bool slew)
|
||||
{
|
||||
m_subMatrix.setMatrixCoefficients(coefs, slew ? m_root.m_5msFrames : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,9 +55,9 @@ protected:
|
||||
/* Mid-pump update */
|
||||
void _midUpdate();
|
||||
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf)=0;
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf)=0;
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf)=0;
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf, int16_t* rbuf)=0;
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf, int32_t* rbuf)=0;
|
||||
virtual size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf, float* rbuf)=0;
|
||||
AudioVoice(BaseAudioVoiceEngine& root, IAudioMix& parent, IAudioVoiceCallback* cb, bool dynamicRate);
|
||||
|
||||
public:
|
||||
@ -72,14 +72,15 @@ public:
|
||||
class AudioVoiceMono : public AudioVoice
|
||||
{
|
||||
AudioMatrixMono m_matrix;
|
||||
AudioMatrixMono m_subMatrix;
|
||||
void _resetSampleRate(double sampleRate);
|
||||
|
||||
static size_t SRCCallback(AudioVoiceMono* ctx,
|
||||
int16_t** data, size_t requestedLen);
|
||||
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf, int16_t* rbuf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf, int32_t* rbuf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf, float* rbuf);
|
||||
|
||||
public:
|
||||
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioMix& parent, IAudioVoiceCallback* cb,
|
||||
@ -87,19 +88,22 @@ public:
|
||||
void setDefaultMatrixCoefficients();
|
||||
void setMonoMatrixCoefficients(const float coefs[8], bool slew);
|
||||
void setStereoMatrixCoefficients(const float coefs[8][2], bool slew);
|
||||
void setMonoSubmixMatrixCoefficients(const float coefs[8], bool slew);
|
||||
void setStereoSubmixMatrixCoefficients(const float coefs[8][2], bool slew);
|
||||
};
|
||||
|
||||
class AudioVoiceStereo : public AudioVoice
|
||||
{
|
||||
AudioMatrixStereo m_matrix;
|
||||
AudioMatrixStereo m_subMatrix;
|
||||
void _resetSampleRate(double sampleRate);
|
||||
|
||||
static size_t SRCCallback(AudioVoiceStereo* ctx,
|
||||
int16_t** data, size_t requestedLen);
|
||||
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int16_t* buf, int16_t* rbuf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, int32_t* buf, int32_t* rbuf);
|
||||
size_t pumpAndMix(const AudioVoiceEngineMixInfo& mixInfo, size_t frames, float* buf, float* rbuf);
|
||||
|
||||
public:
|
||||
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioMix& parent, IAudioVoiceCallback* cb,
|
||||
@ -107,6 +111,8 @@ public:
|
||||
void setDefaultMatrixCoefficients();
|
||||
void setMonoMatrixCoefficients(const float coefs[8], bool slew);
|
||||
void setStereoMatrixCoefficients(const float coefs[8][2], bool slew);
|
||||
void setMonoSubmixMatrixCoefficients(const float coefs[8], bool slew);
|
||||
void setStereoSubmixMatrixCoefficients(const float coefs[8][2], bool slew);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int16_t* dataOut)
|
||||
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut);
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut, nullptr);
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut);
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut, dataOut);
|
||||
remFrames -= thisFrames;
|
||||
dataOut += thisFrames * m_mixInfo.m_channelMap.m_channelCount;
|
||||
}
|
||||
@ -66,9 +66,9 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, int32_t* dataOut)
|
||||
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut);
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut, nullptr);
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut);
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut, dataOut);
|
||||
remFrames -= thisFrames;
|
||||
dataOut += thisFrames * m_mixInfo.m_channelMap.m_channelCount;
|
||||
}
|
||||
@ -97,9 +97,9 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, float* dataOut)
|
||||
|
||||
for (AudioVoice* vox : m_activeVoices)
|
||||
if (vox->m_running)
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut);
|
||||
vox->pumpAndMix(m_mixInfo, thisFrames, dataOut, nullptr);
|
||||
for (AudioSubmix* smx : m_activeSubmixes)
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut);
|
||||
smx->_pumpAndMixVoices(thisFrames, dataOut, dataOut);
|
||||
remFrames -= thisFrames;
|
||||
dataOut += thisFrames * m_mixInfo.m_channelMap.m_channelCount;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user