2016-05-09 02:36:07 +00:00
|
|
|
#include "amuse/EffectDelay.hpp"
|
|
|
|
#include "amuse/Common.hpp"
|
|
|
|
#include "amuse/IBackendVoice.hpp"
|
|
|
|
#include <string.h>
|
2016-05-10 03:03:26 +00:00
|
|
|
#include <cmath>
|
2016-05-09 02:36:07 +00:00
|
|
|
|
|
|
|
namespace amuse
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename T>
|
2016-05-14 04:46:39 +00:00
|
|
|
EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback,
|
|
|
|
uint32_t initOutput, double sampleRate)
|
2016-05-09 06:24:24 +00:00
|
|
|
: m_sampsPerMs(std::ceil(sampleRate / 1000.0)),
|
|
|
|
m_blockSamples(m_sampsPerMs * 5)
|
2016-05-09 02:36:07 +00:00
|
|
|
{
|
|
|
|
initDelay = clamp(10u, initDelay, 5000u);
|
|
|
|
initFeedback = clamp(0u, initFeedback, 100u);
|
|
|
|
initOutput = clamp(0u, initOutput, 100u);
|
|
|
|
|
|
|
|
for (int i=0 ; i<8 ; ++i)
|
|
|
|
{
|
|
|
|
x3c_delay[i] = initDelay;
|
|
|
|
x48_feedback[i] = initFeedback;
|
|
|
|
x54_output[i] = initOutput;
|
|
|
|
}
|
|
|
|
|
|
|
|
_update();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2016-05-14 04:46:39 +00:00
|
|
|
void EffectDelayImp<T>::_update()
|
2016-05-09 02:36:07 +00:00
|
|
|
{
|
|
|
|
for (int i=0 ; i<8 ; ++i)
|
|
|
|
{
|
|
|
|
x0_currentSize[i] = ((x3c_delay[i] - 5) * m_sampsPerMs + 159) / 160;
|
|
|
|
xc_currentPos[i] = 0;
|
|
|
|
x18_currentFeedback[i] = x48_feedback[i] * 128 / 100;
|
|
|
|
x24_currentOutput[i] = x54_output[i] * 128 / 100;
|
|
|
|
|
|
|
|
x30_chanLines[i].reset(new T[m_blockSamples * x0_currentSize[i]]);
|
2016-05-14 04:46:39 +00:00
|
|
|
memset(x30_chanLines[i].get(), 0, m_blockSamples * x0_currentSize[i] * sizeof(T));
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m_dirty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2016-05-14 04:46:39 +00:00
|
|
|
void EffectDelayImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap)
|
2016-05-09 02:36:07 +00:00
|
|
|
{
|
2016-05-09 07:22:58 +00:00
|
|
|
if (m_dirty)
|
|
|
|
_update();
|
|
|
|
|
2016-05-09 02:36:07 +00:00
|
|
|
for (size_t f=0 ; f<frameCount ;)
|
|
|
|
{
|
|
|
|
for (int c=0 ; c<chanMap.m_channelCount ; ++c)
|
|
|
|
{
|
2016-05-09 06:24:24 +00:00
|
|
|
T* chanAud = audio + c;
|
2016-05-09 02:36:07 +00:00
|
|
|
for (int i=0 ; i<m_blockSamples && f<frameCount ; ++i, ++f)
|
|
|
|
{
|
2016-05-09 06:24:24 +00:00
|
|
|
T& liveSamp = chanAud[chanMap.m_channelCount * i];
|
2016-05-09 02:36:07 +00:00
|
|
|
T& samp = x30_chanLines[c][xc_currentPos[c] * m_blockSamples + i];
|
2016-05-09 06:24:24 +00:00
|
|
|
samp = ClampFull<T>(samp * x18_currentFeedback[c] / 128 + liveSamp);
|
|
|
|
liveSamp = samp * x24_currentOutput[c] / 128;
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
2016-05-14 04:46:39 +00:00
|
|
|
xc_currentPos[c] = (xc_currentPos[c] + 1) % x0_currentSize[c];
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
2016-05-09 06:24:24 +00:00
|
|
|
audio += chanMap.m_channelCount * m_blockSamples;
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-14 04:46:39 +00:00
|
|
|
template class EffectDelayImp<int16_t>;
|
|
|
|
template class EffectDelayImp<int32_t>;
|
|
|
|
template class EffectDelayImp<float>;
|
|
|
|
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|