mirror of https://github.com/AxioDL/amuse.git
Full Chorus implemenation
This commit is contained in:
parent
d72e193715
commit
d1cb73bd3a
|
@ -2,6 +2,7 @@
|
|||
#define __AMUSE_COMMON_HPP__
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
||||
namespace amuse
|
||||
{
|
||||
|
@ -9,6 +10,39 @@ namespace amuse
|
|||
template <typename T>
|
||||
static inline T clamp(T a, T val, T b) {return std::max<T>(a, std::min<T>(b, val));}
|
||||
|
||||
template <typename T>
|
||||
static inline T ClampFull(float in) {return in;}
|
||||
|
||||
template <>
|
||||
inline int16_t ClampFull<int16_t>(float in)
|
||||
{
|
||||
if (in < SHRT_MIN)
|
||||
return SHRT_MIN;
|
||||
else if (in > SHRT_MAX)
|
||||
return SHRT_MAX;
|
||||
return in;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int32_t ClampFull<int32_t>(float in)
|
||||
{
|
||||
if (in < INT_MIN)
|
||||
return INT_MIN;
|
||||
else if (in > INT_MAX)
|
||||
return INT_MAX;
|
||||
return in;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float ClampFull<float>(float in)
|
||||
{
|
||||
if (in < -1.f)
|
||||
return -1.f;
|
||||
else if (in > 1.f)
|
||||
return 1.f;
|
||||
return in;
|
||||
}
|
||||
|
||||
#ifndef M_PIF
|
||||
#define M_PIF 3.14159265358979323846f /* pi */
|
||||
#endif
|
||||
|
|
|
@ -8,14 +8,11 @@ namespace amuse
|
|||
{
|
||||
class ChannelMap;
|
||||
|
||||
template <typename T>
|
||||
class EffectBase
|
||||
{
|
||||
public:
|
||||
virtual void applyEffect(int16_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)=0;
|
||||
virtual void applyEffect(int32_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)=0;
|
||||
virtual void applyEffect(float* audio, size_t frameCount,
|
||||
virtual void applyEffect(T* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)=0;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,26 +10,27 @@ namespace amuse
|
|||
#define AMUSE_CHORUS_NUM_BLOCKS 3
|
||||
|
||||
/** Mixes the audio back into itself after continuously-varying delay */
|
||||
class EffectChorus : public EffectBase
|
||||
template <typename T>
|
||||
class EffectChorus : public EffectBase<T>
|
||||
{
|
||||
int32_t* x0_lastLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* xc_lastRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastRearLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastRearRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastCenter[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastLFE[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastSideLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
int32_t* x18_lastSideRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x0_lastLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* xc_lastRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastRearLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastRearRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastCenter[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastLFE[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastSideLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
T* x18_lastSideRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||
|
||||
uint8_t x24_currentLast = 1;
|
||||
int32_t x28_oldLeft[4] = {};
|
||||
int32_t x38_oldRight[4] = {};
|
||||
int32_t x48_oldRearLeft[4] = {};
|
||||
int32_t x48_oldRearRight[4] = {};
|
||||
int32_t x48_oldCenter[4] = {};
|
||||
int32_t x48_oldLFE[4] = {};
|
||||
int32_t x48_oldSideLeft[4] = {};
|
||||
int32_t x48_oldSideRight[4] = {};
|
||||
T x28_oldLeft[4] = {};
|
||||
T x38_oldRight[4] = {};
|
||||
T x48_oldRearLeft[4] = {};
|
||||
T x48_oldRearRight[4] = {};
|
||||
T x48_oldCenter[4] = {};
|
||||
T x48_oldLFE[4] = {};
|
||||
T x48_oldSideLeft[4] = {};
|
||||
T x48_oldSideRight[4] = {};
|
||||
|
||||
uint32_t x58_currentPosLo = 0;
|
||||
uint32_t x5c_currentPosHi = 0;
|
||||
|
@ -40,32 +41,34 @@ class EffectChorus : public EffectBase
|
|||
|
||||
struct SrcInfo
|
||||
{
|
||||
int32_t* x6c_dest;
|
||||
int32_t* x70_smpBase;
|
||||
int32_t* x74_old;
|
||||
T* x6c_dest;
|
||||
T* x70_smpBase;
|
||||
T* x74_old;
|
||||
uint32_t x78_posLo;
|
||||
uint32_t x7c_posHi;
|
||||
uint32_t x80_pitchLo;
|
||||
uint32_t x84_pitchHi;
|
||||
uint32_t x88_trigger;
|
||||
uint32_t x8c_target = 0;
|
||||
|
||||
void doSrc1(size_t blockSamples, size_t chanCount);
|
||||
void doSrc2(size_t blockSamples, size_t chanCount);
|
||||
} x6c_src;
|
||||
|
||||
uint32_t x90_baseDelay; /**< [5, 15] minimum value (in ms) for computed delay */
|
||||
uint32_t x94_variation; /**< [0, 5] time error (in ms) to set delay within */
|
||||
uint32_t x98_period; /**< [500, 10000] time (in ms) of one delay-shift cycle */
|
||||
|
||||
double m_sampleRate;
|
||||
double m_sampsPerMs;
|
||||
uint32_t m_blockSamples;
|
||||
bool m_dirty = true;
|
||||
|
||||
void _update();
|
||||
|
||||
public:
|
||||
~EffectChorus();
|
||||
EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t period, double sampleRate);
|
||||
void applyEffect(int16_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate);
|
||||
void applyEffect(int32_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate);
|
||||
void applyEffect(float* audio, size_t frameCount,
|
||||
void applyEffect(T* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,154 @@
|
|||
#include "amuse/EffectChorus.hpp"
|
||||
#include "amuse/Common.hpp"
|
||||
#include "amuse/IBackendVoice.hpp"
|
||||
#include <string.h>
|
||||
|
||||
namespace amuse
|
||||
{
|
||||
|
||||
EffectChorus::EffectChorus(uint32_t baseDelay, uint32_t variation,
|
||||
static float rsmpTab12khz[] =
|
||||
{
|
||||
0.097504, 0.802216, 0.101593, -0.000977,
|
||||
0.093506, 0.802032, 0.105804, -0.001038,
|
||||
0.089600, 0.801697, 0.110107, -0.001160,
|
||||
0.085785, 0.801178, 0.114471, -0.001282,
|
||||
0.082031, 0.800476, 0.118927, -0.001404,
|
||||
0.078369, 0.799622, 0.123474, -0.001526,
|
||||
0.074799, 0.798615, 0.128143, -0.001648,
|
||||
0.071350, 0.797424, 0.132874, -0.001770,
|
||||
0.067963, 0.796051, 0.137695, -0.001923,
|
||||
0.064697, 0.794525, 0.142609, -0.002045,
|
||||
0.061493, 0.792847, 0.147614, -0.002197,
|
||||
0.058350, 0.790985, 0.152710, -0.002319,
|
||||
0.055328, 0.788940, 0.157898, -0.002472,
|
||||
0.052368, 0.786743, 0.163177, -0.002655,
|
||||
0.049500, 0.784424, 0.168518, -0.002808,
|
||||
0.046722, 0.781891, 0.173981, -0.002991,
|
||||
0.044006, 0.779205, 0.179504, -0.003143,
|
||||
0.041412, 0.776367, 0.185120, -0.003326,
|
||||
0.038879, 0.773376, 0.190826, -0.003510,
|
||||
0.036407, 0.770233, 0.196594, -0.003693,
|
||||
0.034027, 0.766937, 0.202484, -0.003876,
|
||||
0.031738, 0.763489, 0.208435, -0.004059,
|
||||
0.029510, 0.759857, 0.214447, -0.004272,
|
||||
0.027374, 0.756104, 0.220551, -0.004456,
|
||||
0.025299, 0.752197, 0.226746, -0.004669,
|
||||
0.023315, 0.748169, 0.233002, -0.004852,
|
||||
0.021393, 0.743988, 0.239319, -0.005066,
|
||||
0.019562, 0.739655, 0.245728, -0.005310,
|
||||
0.017792, 0.735199, 0.252197, -0.005524,
|
||||
0.016052, 0.730591, 0.258728, -0.005707,
|
||||
0.014404, 0.725861, 0.265350, -0.005920,
|
||||
0.012817, 0.721008, 0.272034, -0.006165,
|
||||
0.011322, 0.716003, 0.278778, -0.006378,
|
||||
0.009888, 0.710907, 0.285583, -0.006561,
|
||||
0.008514, 0.705658, 0.292450, -0.006775,
|
||||
0.007202, 0.700317, 0.299347, -0.007019,
|
||||
0.005920, 0.694855, 0.306335, -0.007233,
|
||||
0.004700, 0.689270, 0.313385, -0.007416,
|
||||
0.003571, 0.683563, 0.320465, -0.007629,
|
||||
0.002472, 0.677734, 0.327606, -0.007874,
|
||||
0.001434, 0.671844, 0.334778, -0.008087,
|
||||
0.000458, 0.665833, 0.341980, -0.008270,
|
||||
-0.000488, 0.659729, 0.349243, -0.008453,
|
||||
-0.001343, 0.653534, 0.356567, -0.008636,
|
||||
-0.002167, 0.647217, 0.363892, -0.008850,
|
||||
-0.002960, 0.640839, 0.371277, -0.009033,
|
||||
-0.003693, 0.634338, 0.378693, -0.009216,
|
||||
-0.004364, 0.627777, 0.386139, -0.009338,
|
||||
-0.004974, 0.621155, 0.393616, -0.009491,
|
||||
-0.005585, 0.614441, 0.401093, -0.009644,
|
||||
-0.006134, 0.607635, 0.408600, -0.009796,
|
||||
-0.006653, 0.600769, 0.416107, -0.009918,
|
||||
-0.007141, 0.593842, 0.423645, -0.010010,
|
||||
-0.007568, 0.586853, 0.431213, -0.010132,
|
||||
-0.007965, 0.579773, 0.438751, -0.010223,
|
||||
-0.008331, 0.572662, 0.446320, -0.010284,
|
||||
-0.008667, 0.565521, 0.453888, -0.010345,
|
||||
-0.008972, 0.558319, 0.461456, -0.010406,
|
||||
-0.009216, 0.551056, 0.469025, -0.010406,
|
||||
-0.009460, 0.543732, 0.476593, -0.010406,
|
||||
-0.009674, 0.536407, 0.484131, -0.010376,
|
||||
-0.009857, 0.529022, 0.491669, -0.010376,
|
||||
-0.010010, 0.521606, 0.499176, -0.010315,
|
||||
-0.010132, 0.514160, 0.506683, -0.010254,
|
||||
-0.010254, 0.506683, 0.514160, -0.010132,
|
||||
-0.010315, 0.499176, 0.521606, -0.010010,
|
||||
-0.010376, 0.491669, 0.529022, -0.009857,
|
||||
-0.010376, 0.484131, 0.536407, -0.009674,
|
||||
-0.010406, 0.476593, 0.543732, -0.009460,
|
||||
-0.010406, 0.469025, 0.551056, -0.009216,
|
||||
-0.010406, 0.461456, 0.558319, -0.008972,
|
||||
-0.010345, 0.453888, 0.565521, -0.008667,
|
||||
-0.010284, 0.446320, 0.572662, -0.008331,
|
||||
-0.010223, 0.438751, 0.579773, -0.007965,
|
||||
-0.010132, 0.431213, 0.586853, -0.007568,
|
||||
-0.010010, 0.423645, 0.593842, -0.007141,
|
||||
-0.009918, 0.416107, 0.600769, -0.006653,
|
||||
-0.009796, 0.408600, 0.607635, -0.006134,
|
||||
-0.009644, 0.401093, 0.614441, -0.005585,
|
||||
-0.009491, 0.393616, 0.621155, -0.004974,
|
||||
-0.009338, 0.386139, 0.627777, -0.004364,
|
||||
-0.009216, 0.378693, 0.634338, -0.003693,
|
||||
-0.009033, 0.371277, 0.640839, -0.002960,
|
||||
-0.008850, 0.363892, 0.647217, -0.002167,
|
||||
-0.008636, 0.356567, 0.653534, -0.001343,
|
||||
-0.008453, 0.349243, 0.659729, -0.000488,
|
||||
-0.008270, 0.341980, 0.665833, 0.000458,
|
||||
-0.008087, 0.334778, 0.671844, 0.001434,
|
||||
-0.007874, 0.327606, 0.677734, 0.002472,
|
||||
-0.007629, 0.320465, 0.683563, 0.003571,
|
||||
-0.007416, 0.313385, 0.689270, 0.004700,
|
||||
-0.007233, 0.306335, 0.694855, 0.005920,
|
||||
-0.007019, 0.299347, 0.700317, 0.007202,
|
||||
-0.006775, 0.292450, 0.705658, 0.008514,
|
||||
-0.006561, 0.285583, 0.710907, 0.009888,
|
||||
-0.006378, 0.278778, 0.716003, 0.011322,
|
||||
-0.006165, 0.272034, 0.721008, 0.012817,
|
||||
-0.005920, 0.265350, 0.725861, 0.014404,
|
||||
-0.005707, 0.258728, 0.730591, 0.016052,
|
||||
-0.005524, 0.252197, 0.735199, 0.017792,
|
||||
-0.005310, 0.245728, 0.739655, 0.019562,
|
||||
-0.005066, 0.239319, 0.743988, 0.021393,
|
||||
-0.004852, 0.233002, 0.748169, 0.023315,
|
||||
-0.004669, 0.226746, 0.752197, 0.025299,
|
||||
-0.004456, 0.220551, 0.756104, 0.027374,
|
||||
-0.004272, 0.214447, 0.759857, 0.029510,
|
||||
-0.004059, 0.208435, 0.763489, 0.031738,
|
||||
-0.003876, 0.202484, 0.766937, 0.034027,
|
||||
-0.003693, 0.196594, 0.770233, 0.036407,
|
||||
-0.003510, 0.190826, 0.773376, 0.038879,
|
||||
-0.003326, 0.185120, 0.776367, 0.041412,
|
||||
-0.003143, 0.179504, 0.779205, 0.044006,
|
||||
-0.002991, 0.173981, 0.781891, 0.046722,
|
||||
-0.002808, 0.168518, 0.784424, 0.049500,
|
||||
-0.002655, 0.163177, 0.786743, 0.052368,
|
||||
-0.002472, 0.157898, 0.788940, 0.055328,
|
||||
-0.002319, 0.152710, 0.790985, 0.058350,
|
||||
-0.002197, 0.147614, 0.792847, 0.061493,
|
||||
-0.002045, 0.142609, 0.794525, 0.064697,
|
||||
-0.001923, 0.137695, 0.796051, 0.067963,
|
||||
-0.001770, 0.132874, 0.797424, 0.071350,
|
||||
-0.001648, 0.128143, 0.798615, 0.074799,
|
||||
-0.001526, 0.123474, 0.799622, 0.078369,
|
||||
-0.001404, 0.118927, 0.800476, 0.082031,
|
||||
-0.001282, 0.114471, 0.801178, 0.085785,
|
||||
-0.001160, 0.110107, 0.801697, 0.089600,
|
||||
-0.001038, 0.105804, 0.802032, 0.093506,
|
||||
-0.000977, 0.101593, 0.802216, 0.097504,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
EffectChorus<T>::EffectChorus(uint32_t baseDelay, uint32_t variation,
|
||||
uint32_t period, double sampleRate)
|
||||
: x90_baseDelay(clamp(5u, baseDelay, 15u)),
|
||||
x94_variation(clamp(0u, variation, 5u)),
|
||||
x98_period(clamp(500u, period, 10000u)),
|
||||
m_sampleRate(sampleRate),
|
||||
m_sampsPerMs(sampleRate / 1000.0),
|
||||
m_blockSamples(sampleRate * 160.0 / 32000.0)
|
||||
{
|
||||
int32_t* buf = new int32_t[m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8];
|
||||
memset(buf, 0, m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8 * sizeof(int32_t));
|
||||
T* buf = new T[m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8];
|
||||
memset(buf, 0, m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8 * sizeof(T));
|
||||
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||
|
||||
for (int i=0 ; i<AMUSE_CHORUS_NUM_BLOCKS ; ++i)
|
||||
|
@ -42,33 +176,264 @@ EffectChorus::EffectChorus(uint32_t baseDelay, uint32_t variation,
|
|||
x18_lastSideRight[i] = buf + chanPitch * 7 + m_blockSamples * i;
|
||||
|
||||
x6c_src.x88_trigger = chanPitch;
|
||||
|
||||
x5c_currentPosHi = m_blockSamples * 2 - ((x90_baseDelay - 5) * (m_sampleRate / 1000.0));
|
||||
uint32_t temp = (x5c_currentPosHi + (x24_currentLast - 1) * m_blockSamples);
|
||||
x5c_currentPosHi = temp - int32_t(temp * 15 / (m_sampleRate / 1000.0)) * chanPitch;
|
||||
|
||||
x68_pitchOffsetPeriod = (x98_period * 2 / 10 + 1) & ~1;
|
||||
x60_pitchOffset = x94_variation * 2048 / x68_pitchOffsetPeriod;
|
||||
}
|
||||
|
||||
EffectChorus::~EffectChorus()
|
||||
template <typename T>
|
||||
void EffectChorus<T>::_update()
|
||||
{
|
||||
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||
size_t fifteenSamps = 15 * m_sampsPerMs;
|
||||
|
||||
x5c_currentPosHi = m_blockSamples * 2 - (x90_baseDelay - 5) * m_sampsPerMs;
|
||||
x58_currentPosLo = 0;
|
||||
uint32_t temp = (x5c_currentPosHi + (x24_currentLast - 1) * m_blockSamples);
|
||||
x5c_currentPosHi = temp % (chanPitch / fifteenSamps * fifteenSamps);
|
||||
|
||||
x68_pitchOffsetPeriod = (x98_period * 2 / 10 + 1) & ~1;
|
||||
x64_pitchOffsetPeriodCount = x68_pitchOffsetPeriod / 2;
|
||||
x60_pitchOffset = x94_variation * 2048 / x68_pitchOffsetPeriod;
|
||||
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
EffectChorus<T>::~EffectChorus()
|
||||
{
|
||||
delete[] x0_lastLeft[0];
|
||||
}
|
||||
|
||||
void EffectChorus::applyEffect(int16_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)
|
||||
template <typename T>
|
||||
void EffectChorus<T>::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount)
|
||||
{
|
||||
float old1 = x74_old[0];
|
||||
float old2 = x74_old[1];
|
||||
float old3 = x74_old[2];
|
||||
float cur = x70_smpBase[x7c_posHi];
|
||||
|
||||
T* dest = x6c_dest;
|
||||
for (size_t i=0 ; i<blockSamples ; ++i)
|
||||
{
|
||||
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
||||
|
||||
uint64_t ovrTest = uint64_t(x78_posLo) + uint64_t(x80_pitchLo);
|
||||
if (ovrTest > UINT32_MAX)
|
||||
{
|
||||
/* overflow */
|
||||
x78_posLo = ovrTest & 0xffffffff;
|
||||
++x7c_posHi;
|
||||
if (x7c_posHi == x88_trigger)
|
||||
x7c_posHi = x8c_target;
|
||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
||||
dest += chanCount;
|
||||
old1 = old2;
|
||||
old2 = old3;
|
||||
old3 = cur;
|
||||
cur = x70_smpBase[x7c_posHi];
|
||||
}
|
||||
else
|
||||
{
|
||||
x78_posLo = ovrTest;
|
||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
||||
dest += chanCount;
|
||||
}
|
||||
}
|
||||
|
||||
void EffectChorus::applyEffect(int32_t* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)
|
||||
{
|
||||
x74_old[0] = old1;
|
||||
x74_old[1] = old2;
|
||||
x74_old[2] = old3;
|
||||
}
|
||||
|
||||
void EffectChorus::applyEffect(float* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)
|
||||
template <typename T>
|
||||
void EffectChorus<T>::SrcInfo::doSrc2(size_t blockSamples, size_t chanCount)
|
||||
{
|
||||
float old1 = x74_old[0];
|
||||
float old2 = x74_old[1];
|
||||
float old3 = x74_old[2];
|
||||
float cur = x70_smpBase[x7c_posHi];
|
||||
|
||||
T* dest = x6c_dest;
|
||||
for (size_t i=0 ; i<blockSamples ; ++i)
|
||||
{
|
||||
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
||||
++x7c_posHi;
|
||||
|
||||
uint64_t ovrTest = uint64_t(x78_posLo) + uint64_t(x80_pitchLo);
|
||||
if (ovrTest > UINT32_MAX)
|
||||
{
|
||||
/* overflow */
|
||||
x78_posLo = ovrTest & 0xffffffff;
|
||||
|
||||
if (x7c_posHi == x88_trigger)
|
||||
x7c_posHi = x8c_target;
|
||||
|
||||
old1 = old3;
|
||||
old2 = cur;
|
||||
old3 = x70_smpBase[x7c_posHi];
|
||||
|
||||
++x7c_posHi;
|
||||
if (x7c_posHi == x88_trigger)
|
||||
x7c_posHi = x8c_target;
|
||||
|
||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
||||
dest += chanCount;
|
||||
|
||||
cur = x70_smpBase[x7c_posHi];
|
||||
}
|
||||
else
|
||||
{
|
||||
x78_posLo = ovrTest;
|
||||
|
||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
||||
dest += chanCount;
|
||||
|
||||
old1 = old2;
|
||||
old2 = old3;
|
||||
old3 = cur;
|
||||
|
||||
if (x7c_posHi == x88_trigger)
|
||||
x7c_posHi = x8c_target;
|
||||
|
||||
cur = x70_smpBase[x7c_posHi];
|
||||
}
|
||||
}
|
||||
|
||||
x74_old[0] = old1;
|
||||
x74_old[1] = old2;
|
||||
x74_old[2] = old3;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void EffectChorus<T>::applyEffect(T* audio, size_t frameCount,
|
||||
const ChannelMap& chanMap, double sampleRate)
|
||||
{
|
||||
if (m_dirty)
|
||||
_update();
|
||||
|
||||
uint8_t next = x24_currentLast + 1;
|
||||
uint8_t buf = next % 3;
|
||||
T* leftBuf = x0_lastLeft[buf];
|
||||
T* rightBuf = xc_lastRight[buf];
|
||||
T* rearLeftBuf = x18_lastRearLeft[buf];
|
||||
T* rearRightBuf = x18_lastRearRight[buf];
|
||||
T* centerBuf = x18_lastCenter[buf];
|
||||
T* lfeBuf = x18_lastLFE[buf];
|
||||
T* sideLeftBuf = x18_lastSideLeft[buf];
|
||||
T* sideRightBuf = x18_lastSideRight[buf];
|
||||
|
||||
T* inBuf = audio;
|
||||
for (size_t f=0 ; f<frameCount && f<m_blockSamples ; ++f)
|
||||
{
|
||||
for (size_t c=0 ; c<chanMap.m_channelCount ; ++c)
|
||||
{
|
||||
switch (chanMap.m_channels[c])
|
||||
{
|
||||
case AudioChannel::FrontLeft:
|
||||
*leftBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::FrontRight:
|
||||
*rightBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::RearLeft:
|
||||
*rearLeftBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::RearRight:
|
||||
*rearRightBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::FrontCenter:
|
||||
*centerBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::LFE:
|
||||
*lfeBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::SideLeft:
|
||||
*sideLeftBuf++ = *inBuf++;
|
||||
break;
|
||||
case AudioChannel::SideRight:
|
||||
*sideRightBuf++ = *inBuf++;
|
||||
break;
|
||||
default:
|
||||
inBuf++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x6c_src.x84_pitchHi = (x60_pitchOffset >> 16) + 1;
|
||||
x6c_src.x80_pitchLo = (x60_pitchOffset << 16);
|
||||
|
||||
--x64_pitchOffsetPeriodCount;
|
||||
if (x64_pitchOffsetPeriodCount == 0)
|
||||
{
|
||||
x64_pitchOffsetPeriodCount = x68_pitchOffsetPeriod;
|
||||
x60_pitchOffset = -x60_pitchOffset;
|
||||
}
|
||||
|
||||
T* outBuf = audio;
|
||||
for (size_t c=0 ; c<chanMap.m_channelCount ; ++c)
|
||||
{
|
||||
x6c_src.x7c_posHi = x5c_currentPosHi;
|
||||
x6c_src.x78_posLo = x58_currentPosLo;
|
||||
|
||||
x6c_src.x6c_dest = outBuf++;
|
||||
switch (chanMap.m_channels[c])
|
||||
{
|
||||
case AudioChannel::FrontLeft:
|
||||
x6c_src.x70_smpBase = x0_lastLeft[0];
|
||||
x6c_src.x74_old = x28_oldLeft;
|
||||
break;
|
||||
case AudioChannel::FrontRight:
|
||||
x6c_src.x70_smpBase = xc_lastRight[0];
|
||||
x6c_src.x74_old = x38_oldRight;
|
||||
break;
|
||||
case AudioChannel::RearLeft:
|
||||
x6c_src.x70_smpBase = x18_lastRearLeft[0];
|
||||
x6c_src.x74_old = x48_oldRearLeft;
|
||||
break;
|
||||
case AudioChannel::RearRight:
|
||||
x6c_src.x70_smpBase = x18_lastRearRight[0];
|
||||
x6c_src.x74_old = x48_oldRearRight;
|
||||
break;
|
||||
case AudioChannel::FrontCenter:
|
||||
x6c_src.x70_smpBase = x18_lastCenter[0];
|
||||
x6c_src.x74_old = x48_oldCenter;
|
||||
break;
|
||||
case AudioChannel::LFE:
|
||||
x6c_src.x70_smpBase = x18_lastLFE[0];
|
||||
x6c_src.x74_old = x48_oldLFE;
|
||||
break;
|
||||
case AudioChannel::SideLeft:
|
||||
x6c_src.x70_smpBase = x18_lastSideLeft[0];
|
||||
x6c_src.x74_old = x48_oldSideLeft;
|
||||
break;
|
||||
case AudioChannel::SideRight:
|
||||
x6c_src.x70_smpBase = x18_lastSideRight[0];
|
||||
x6c_src.x74_old = x48_oldSideRight;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (x6c_src.x84_pitchHi)
|
||||
{
|
||||
case 0:
|
||||
x6c_src.doSrc1(m_blockSamples, chanMap.m_channelCount);
|
||||
break;
|
||||
case 1:
|
||||
x6c_src.doSrc2(m_blockSamples, chanMap.m_channelCount);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||
size_t fifteenSamps = 15 * m_sampsPerMs;
|
||||
|
||||
x5c_currentPosHi = x6c_src.x7c_posHi % (chanPitch / fifteenSamps * fifteenSamps);
|
||||
x58_currentPosLo = x6c_src.x78_posLo;
|
||||
x24_currentLast = buf;
|
||||
}
|
||||
|
||||
template class EffectChorus<int16_t>;
|
||||
template class EffectChorus<int32_t>;
|
||||
template class EffectChorus<float>;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue