score-avnd-senior/Senior/SeniorModel.cpp

84 lines
2 KiB
C++

#include <Gamma/scl.h>
#include "Senior.hpp"
namespace Ottobit
{
void Senior::operator()(tick t)
{
// Only compute skipped_frames when the control changes
if (inputs.s_rate != previous_rate)
{
step_size = (1. - inputs.s_rate) * RATE;
previous_rate = inputs.s_rate;
}
// Only compute bit_factor when the control changes
if (inputs.bits != previous_bits)
{
set_bit_factor();
previous_bits = inputs.bits;
}
// Process the input buffer
for(int i{0}; i < inputs.audio.channels; i++)
{
auto* in = inputs.audio[i];
auto* out = outputs.audio[i % outputs.audio.channels];
// Init current_frame for each channel
double current_frame{crush(in[i])};
for(int j{0}; j < t.frames; j++)
{
if (skipped_frames[i] <= step_size)
skipped_frames[i]++;
else
{
skipped_frames[i] = 0;
current_frame = crush(in[j]);
}
if (!inputs.depth)
out[j] = current_frame;
else
{
lfo.set(inputs.freq, phases[i], 0);
if (inputs.am_fm < 1.f)
{
double amp = (inputs.am_fm * 0.5) + (inputs.depth * 0.5);
out[j] = current_frame * ((lfo.cos() * amp) + (1 - amp));
}
else
{
double amp = lfo.cos() * inputs.depth;
fms[i].delay(amp * .0025 + 1);
double am = current_frame * (amp + (1 - inputs.depth));
double fm = fms[i](current_frame);
out[j] = (am * (2 - inputs.am_fm)) + (fm * (inputs.am_fm - 1));
}
phases[i] = lfo.phase();
}
}
}
}
void Senior::set_bit_factor()
{
bit_factor = pow(2, inputs.bits) - 1;
}
double Senior::crush(const double& f)
{
if (inputs.bits == BITS)
return f;
else
// Rounding using static_cast
// return static_cast<double>(static_cast<int>(f * bit_factor)) / bit_factor;
// Close, but prefer the use of roundMagic from Lance Putnam's Gama
return gam::scl::round<double>(f * bit_factor) / bit_factor;
}
} // namespace Ottobit