2016-03-24 00:01:57 +00:00
|
|
|
#include "AudioMatrix.hpp"
|
|
|
|
#include "AudioVoiceEngine.hpp"
|
2016-01-28 23:53:51 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
namespace boo
|
|
|
|
{
|
|
|
|
|
2016-03-24 00:01:57 +00:00
|
|
|
void AudioMatrixMono::setDefaultMatrixCoefficients(AudioChannelSet acSet)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
m_curSlewFrame = 0;
|
|
|
|
m_slewFrames = 0;
|
2016-05-22 08:37:16 +00:00
|
|
|
memset(&m_coefs, 0, sizeof(m_coefs));
|
2016-03-24 00:01:57 +00:00
|
|
|
switch (acSet)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
|
|
|
case AudioChannelSet::Stereo:
|
|
|
|
case AudioChannelSet::Quad:
|
2016-05-22 08:37:16 +00:00
|
|
|
m_coefs.v[int(AudioChannel::FrontLeft)] = 1.0;
|
|
|
|
m_coefs.v[int(AudioChannel::FrontRight)] = 1.0;
|
2016-01-28 23:53:51 +00:00
|
|
|
break;
|
|
|
|
case AudioChannelSet::Surround51:
|
|
|
|
case AudioChannelSet::Surround71:
|
2016-05-22 08:37:16 +00:00
|
|
|
m_coefs.v[int(AudioChannel::FrontCenter)] = 1.0;
|
2016-01-28 23:53:51 +00:00
|
|
|
break;
|
2016-03-08 07:09:58 +00:00
|
|
|
default: break;
|
2016-01-28 23:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
int16_t* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const int16_t* dataIn, int16_t* dataOut, size_t samples)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
2016-03-24 00:01:57 +00:00
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t s=0 ; s<samples ; ++s, ++dataIn)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataOut = Clamp16(*dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt));
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-01-29 01:17:19 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataOut = Clamp16(*dataOut + *dataIn * m_coefs.v[int(ch)]);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
2016-01-29 01:17:19 +00:00
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-01-28 23:53:51 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
int32_t* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const int32_t* dataIn, int32_t* dataOut, size_t samples)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t s=0 ; s<samples ; ++s, ++dataIn)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataOut = Clamp32(*dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt));
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataOut = Clamp32(*dataOut + *dataIn * m_coefs.v[int(ch)]);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const float* dataIn, float* dataOut, size_t samples)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t s=0 ; s<samples ; ++s, ++dataIn)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-06-15 03:53:37 +00:00
|
|
|
*dataOut = *dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-06-15 03:53:37 +00:00
|
|
|
*dataOut = *dataOut + *dataIn * m_coefs.v[int(ch)];
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AudioMatrixStereo::setDefaultMatrixCoefficients(AudioChannelSet acSet)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
m_curSlewFrame = 0;
|
|
|
|
m_slewFrames = 0;
|
2016-05-22 08:37:16 +00:00
|
|
|
memset(&m_coefs, 0, sizeof(m_coefs));
|
2016-03-24 00:01:57 +00:00
|
|
|
switch (acSet)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
|
|
|
case AudioChannelSet::Stereo:
|
|
|
|
case AudioChannelSet::Quad:
|
2016-05-22 08:37:16 +00:00
|
|
|
m_coefs.v[int(AudioChannel::FrontLeft)][0] = 1.0;
|
|
|
|
m_coefs.v[int(AudioChannel::FrontRight)][1] = 1.0;
|
2016-01-28 23:53:51 +00:00
|
|
|
break;
|
|
|
|
case AudioChannelSet::Surround51:
|
|
|
|
case AudioChannelSet::Surround71:
|
2016-05-22 08:37:16 +00:00
|
|
|
m_coefs.v[int(AudioChannel::FrontLeft)][0] = 1.0;
|
|
|
|
m_coefs.v[int(AudioChannel::FrontRight)][1] = 1.0;
|
2016-01-28 23:53:51 +00:00
|
|
|
break;
|
2016-03-08 07:09:58 +00:00
|
|
|
default: break;
|
2016-01-28 23:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
int16_t* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const int16_t* dataIn, int16_t* dataOut, size_t frames)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t f=0 ; f<frames ; ++f, dataIn += 2)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
|
|
|
*dataOut = Clamp16(*dataOut +
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
|
|
|
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt));
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
|
|
|
*dataOut = Clamp16(*dataOut +
|
2016-05-22 08:37:16 +00:00
|
|
|
dataIn[0] * m_coefs.v[int(ch)][0] +
|
|
|
|
dataIn[1] * m_coefs.v[int(ch)][1]);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
int32_t* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const int32_t* dataIn, int32_t* dataOut, size_t frames)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t f=0 ; f<frames ; ++f, dataIn += 2)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
|
|
|
*dataOut = Clamp32(*dataOut +
|
2016-05-22 08:37:16 +00:00
|
|
|
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
|
|
|
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt));
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
|
|
|
*dataOut = Clamp32(*dataOut +
|
2016-05-22 08:37:16 +00:00
|
|
|
dataIn[0] * m_coefs.v[int(ch)][0] +
|
|
|
|
dataIn[1] * m_coefs.v[int(ch)][1]);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 20:21:20 +00:00
|
|
|
float* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
|
2016-05-21 21:45:55 +00:00
|
|
|
const float* dataIn, float* dataOut, size_t frames)
|
2016-01-28 23:53:51 +00:00
|
|
|
{
|
2016-03-24 00:01:57 +00:00
|
|
|
const ChannelMap& chmap = info.m_channelMap;
|
|
|
|
for (size_t f=0 ; f<frames ; ++f, dataIn += 2)
|
2016-05-21 21:45:55 +00:00
|
|
|
{
|
|
|
|
if (m_slewFrames && m_curSlewFrame < m_slewFrames)
|
|
|
|
{
|
|
|
|
double t = m_curSlewFrame / double(m_slewFrames);
|
|
|
|
double omt = 1.0 - t;
|
|
|
|
|
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
|
|
|
{
|
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-06-15 03:53:37 +00:00
|
|
|
*dataOut = *dataOut +
|
|
|
|
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
|
|
|
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt);
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++m_curSlewFrame;
|
|
|
|
}
|
|
|
|
else
|
2016-01-29 01:17:19 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
for (unsigned c=0 ; c<chmap.m_channelCount ; ++c)
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
2016-05-21 21:45:55 +00:00
|
|
|
AudioChannel ch = chmap.m_channels[c];
|
|
|
|
if (ch != AudioChannel::Unknown)
|
|
|
|
{
|
2016-06-15 03:53:37 +00:00
|
|
|
*dataOut = *dataOut +
|
|
|
|
dataIn[0] * m_coefs.v[int(ch)][0] +
|
|
|
|
dataIn[1] * m_coefs.v[int(ch)][1];
|
2016-05-21 21:45:55 +00:00
|
|
|
++dataOut;
|
|
|
|
}
|
2016-03-24 00:01:57 +00:00
|
|
|
}
|
2016-01-29 01:17:19 +00:00
|
|
|
}
|
2016-05-21 21:45:55 +00:00
|
|
|
}
|
2016-05-16 20:21:20 +00:00
|
|
|
return dataOut;
|
2016-01-28 23:53:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|