2016-05-09 02:36:07 +00:00
|
|
|
#include "amuse/EffectDelay.hpp"
|
2019-08-25 10:28:43 +00:00
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
2016-05-09 02:36:07 +00:00
|
|
|
#include "amuse/Common.hpp"
|
|
|
|
#include "amuse/IBackendVoice.hpp"
|
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
namespace amuse {
|
2016-05-09 02:36:07 +00:00
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
EffectDelayImp::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate) {
|
2019-09-07 10:21:07 +00:00
|
|
|
initDelay = std::clamp(initDelay, 10u, 5000u);
|
|
|
|
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
|
|
|
initOutput = std::clamp(initOutput, 0u, 100u);
|
2016-05-09 02:36:07 +00:00
|
|
|
|
2020-03-27 19:54:08 +00:00
|
|
|
x3c_delay.fill(initDelay);
|
|
|
|
x48_feedback.fill(initFeedback);
|
|
|
|
x54_output.fill(initOutput);
|
2016-05-09 02:36:07 +00:00
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
_setup(sampleRate);
|
2016-06-01 04:49:35 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
EffectDelayImp::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
2020-03-27 19:54:08 +00:00
|
|
|
for (size_t i = 0; i < NumChannels; ++i) {
|
2019-09-07 10:21:07 +00:00
|
|
|
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
|
|
|
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
|
|
|
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
2018-12-08 05:20:09 +00:00
|
|
|
}
|
2017-01-23 07:21:50 +00:00
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
_setup(sampleRate);
|
2017-01-23 07:21:50 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
void EffectDelayImp::_setup(double sampleRate) {
|
2018-12-08 05:20:09 +00:00
|
|
|
m_sampsPerMs = std::ceil(sampleRate / 1000.0);
|
|
|
|
m_blockSamples = m_sampsPerMs * 5;
|
2016-06-01 04:49:35 +00:00
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
_update();
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
void EffectDelayImp::_update() {
|
2020-03-27 19:54:08 +00:00
|
|
|
for (size_t i = 0; i < NumChannels; ++i) {
|
2018-12-08 05:20:09 +00:00
|
|
|
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;
|
2016-05-09 02:36:07 +00:00
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
x30_chanLines[i] = std::make_unique<float[]>(m_blockSamples * x0_currentSize[i]);
|
2018-12-08 05:20:09 +00:00
|
|
|
}
|
2016-05-09 02:36:07 +00:00
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
m_dirty = false;
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 20:42:51 +00:00
|
|
|
void EffectDelayImp::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) {
|
2018-12-08 05:20:09 +00:00
|
|
|
if (m_dirty)
|
|
|
|
_update();
|
2016-05-09 07:22:58 +00:00
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
for (size_t f = 0; f < frameCount;) {
|
|
|
|
for (unsigned c = 0; c < chanMap.m_channelCount; ++c) {
|
2020-09-28 20:42:51 +00:00
|
|
|
auto* chanAud = audio + c;
|
2018-12-08 05:20:09 +00:00
|
|
|
for (unsigned i = 0; i < m_blockSamples && f < frameCount; ++i, ++f) {
|
2020-09-28 20:42:51 +00:00
|
|
|
auto& liveSamp = chanAud[chanMap.m_channelCount * i];
|
|
|
|
auto& samp = x30_chanLines[c][xc_currentPos[c] * m_blockSamples + i];
|
|
|
|
samp = samp * x18_currentFeedback[c] / 128 + liveSamp;
|
2018-12-08 05:20:09 +00:00
|
|
|
liveSamp = samp * x24_currentOutput[c] / 128;
|
|
|
|
}
|
|
|
|
xc_currentPos[c] = (xc_currentPos[c] + 1) % x0_currentSize[c];
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
2018-12-08 05:20:09 +00:00
|
|
|
audio += chanMap.m_channelCount * m_blockSamples;
|
|
|
|
}
|
2016-05-09 02:36:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:20:09 +00:00
|
|
|
} // namespace amuse
|