boo/lib/audiodev/AudioMatrix.hpp

157 lines
4.2 KiB
C++
Raw Normal View History

#ifndef BOO_AUDIOMATRIX_HPP
#define BOO_AUDIOMATRIX_HPP
#include "boo/audiodev/IAudioVoice.hpp"
#include <vector>
#include <stdint.h>
2016-05-07 04:28:32 +00:00
#include <limits.h>
2017-11-28 03:38:02 +00:00
#include <float.h>
2016-05-22 08:37:16 +00:00
#if __SSE__
#include <xmmintrin.h>
#endif
namespace boo
{
struct AudioVoiceEngineMixInfo;
2016-05-07 04:28:32 +00:00
static inline int16_t Clamp16(float in)
{
if (in < SHRT_MIN)
return SHRT_MIN;
else if (in > SHRT_MAX)
return SHRT_MAX;
return in;
}
static inline int32_t Clamp32(float in)
{
if (in < INT_MIN)
return INT_MIN;
else if (in > INT_MAX)
return INT_MAX;
return in;
}
class AudioMatrixMono
{
2016-05-22 08:37:16 +00:00
union Coefs
{
float v[8];
#if __SSE__
__m128 q[2];
__m64 d[4];
#endif
};
Coefs m_coefs = {};
Coefs m_oldCoefs = {};
2016-05-21 21:45:55 +00:00
size_t m_slewFrames = 0;
size_t m_curSlewFrame = 0;
public:
AudioMatrixMono() {setDefaultMatrixCoefficients(AudioChannelSet::Stereo);}
void setDefaultMatrixCoefficients(AudioChannelSet acSet);
2016-05-21 21:45:55 +00:00
void setMatrixCoefficients(const float coefs[8], size_t slewFrames=0)
{
2016-05-21 21:45:55 +00:00
m_slewFrames = slewFrames;
m_curSlewFrame = 0;
2016-05-22 08:37:16 +00:00
#if __SSE__
m_oldCoefs.q[0] = m_coefs.q[0];
m_oldCoefs.q[1] = m_coefs.q[1];
m_coefs.q[0] = _mm_loadu_ps(coefs);
m_coefs.q[1] = _mm_loadu_ps(&coefs[4]);
#else
for (int i=0 ; i<8 ; ++i)
2016-05-21 21:45:55 +00:00
{
2016-05-22 08:37:16 +00:00
m_oldCoefs.v[i] = m_coefs.v[i];
m_coefs.v[i] = coefs[i];
2016-05-21 21:45:55 +00:00
}
2016-05-22 08:37:16 +00:00
#endif
}
int16_t* mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const int16_t* dataIn, int16_t* dataOut, size_t samples);
int32_t* mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const int32_t* dataIn, int32_t* dataOut, size_t samples);
float* mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const float* dataIn, float* dataOut, size_t samples);
2017-11-28 03:38:02 +00:00
bool isSilent() const
{
if (m_curSlewFrame < m_slewFrames)
for (int i=0 ; i<8 ; ++i)
if (m_oldCoefs.v[i] > FLT_EPSILON)
return false;
for (int i=0 ; i<8 ; ++i)
if (m_coefs.v[i] > FLT_EPSILON)
return false;
return true;
}
};
class AudioMatrixStereo
{
2016-05-22 08:37:16 +00:00
union Coefs
{
float v[8][2];
#if __SSE__
__m128 q[4];
__m64 d[8];
#endif
};
Coefs m_coefs = {};
Coefs m_oldCoefs = {};
2016-05-21 21:45:55 +00:00
size_t m_slewFrames = 0;
size_t m_curSlewFrame = 0;
public:
AudioMatrixStereo() {setDefaultMatrixCoefficients(AudioChannelSet::Stereo);}
void setDefaultMatrixCoefficients(AudioChannelSet acSet);
2016-05-21 21:45:55 +00:00
void setMatrixCoefficients(const float coefs[8][2], size_t slewFrames=0)
{
2016-05-21 21:45:55 +00:00
m_slewFrames = slewFrames;
m_curSlewFrame = 0;
2016-05-22 08:37:16 +00:00
#if __SSE__
m_oldCoefs.q[0] = m_coefs.q[0];
m_oldCoefs.q[1] = m_coefs.q[1];
m_oldCoefs.q[2] = m_coefs.q[2];
m_oldCoefs.q[3] = m_coefs.q[3];
m_coefs.q[0] = _mm_loadu_ps(coefs[0]);
m_coefs.q[1] = _mm_loadu_ps(coefs[2]);
m_coefs.q[2] = _mm_loadu_ps(coefs[4]);
m_coefs.q[3] = _mm_loadu_ps(coefs[6]);
#else
for (int i=0 ; i<8 ; ++i)
{
2016-05-22 08:37:16 +00:00
m_oldCoefs.v[i][0] = m_coefs.v[i][0];
m_oldCoefs.v[i][1] = m_coefs.v[i][1];
m_coefs.v[i][0] = coefs.v[i][0];
m_coefs.v[i][1] = coefs.v[i][1];
}
2016-05-22 08:37:16 +00:00
#endif
}
int16_t* mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const int16_t* dataIn, int16_t* dataOut, size_t frames);
int32_t* mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const int32_t* dataIn, int32_t* dataOut, size_t frames);
float* mixStereoSampleData(const AudioVoiceEngineMixInfo& info,
2016-05-21 21:45:55 +00:00
const float* dataIn, float* dataOut, size_t frames);
2017-11-28 03:38:02 +00:00
bool isSilent() const
{
if (m_curSlewFrame < m_slewFrames)
for (int i=0 ; i<8 ; ++i)
if (m_oldCoefs.v[i][0] > FLT_EPSILON || m_oldCoefs.v[i][1] > FLT_EPSILON)
return false;
for (int i=0 ; i<8 ; ++i)
if (m_coefs.v[i][0] > FLT_EPSILON || m_coefs.v[i][1] > FLT_EPSILON)
return false;
return true;
}
};
}
#endif // BOO_AUDIOMATRIX_HPP