[FM] functional vibrato
This commit is contained in:
parent
abd170d77a
commit
9568198a1c
3 changed files with 66 additions and 25 deletions
|
@ -14,10 +14,10 @@ void Senior::operator()(tick t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only compute skipped_frames when the control changes
|
// Only compute skipped_frames when the control changes
|
||||||
if (inputs.rate != previous_rate)
|
if (inputs.s_rate != previous_rate)
|
||||||
{
|
{
|
||||||
step_size = (1. - inputs.rate) * RATE;
|
step_size = (1. - inputs.s_rate) * RATE;
|
||||||
previous_rate = inputs.rate;
|
previous_rate = inputs.s_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the input buffer
|
// Process the input buffer
|
||||||
|
@ -27,7 +27,7 @@ void Senior::operator()(tick t)
|
||||||
auto* out = outputs.audio[i % outputs.audio.channels];
|
auto* out = outputs.audio[i % outputs.audio.channels];
|
||||||
|
|
||||||
// Init current_frame for each channel
|
// Init current_frame for each channel
|
||||||
double current_frame{crush_frame(in[i])};
|
double current_frame{crush(in[i])};
|
||||||
|
|
||||||
for(int j{0}; j < t.frames; j++)
|
for(int j{0}; j < t.frames; j++)
|
||||||
{
|
{
|
||||||
|
@ -36,21 +36,28 @@ void Senior::operator()(tick t)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skipped_frames[i] = 0;
|
skipped_frames[i] = 0;
|
||||||
current_frame = crush_frame(in[j]);
|
current_frame = crush(in[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fms[i].delay(lfos[i].cos()*0.0025 + 0.05);
|
if (!inputs.depth)
|
||||||
|
out[j] = current_frame;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lfo.set(inputs.freq, phases[i], 0);
|
||||||
|
fms[i].delay(lfo.cos() * inputs.depth + .5);
|
||||||
|
phases[i] = lfo.phase();
|
||||||
out[j] = fms[i](current_frame);
|
out[j] = fms[i](current_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Senior::set_bit_factor()
|
void Senior::set_bit_factor()
|
||||||
{
|
{
|
||||||
bit_factor = pow(2, inputs.bits) - 1;
|
bit_factor = pow(2, inputs.bits) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Senior::crush_frame(const double& f)
|
double Senior::crush(const double& f)
|
||||||
{
|
{
|
||||||
if (inputs.bits == BITS)
|
if (inputs.bits == BITS)
|
||||||
return f;
|
return f;
|
||||||
|
@ -60,4 +67,5 @@ double Senior::crush_frame(const double& f)
|
||||||
// Close, but prefer the use of roundMagic from Lance Putnam's Gama
|
// Close, but prefer the use of roundMagic from Lance Putnam's Gama
|
||||||
return gam::scl::round<double>(f * bit_factor) / bit_factor;
|
return gam::scl::round<double>(f * bit_factor) / bit_factor;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace Ottobit
|
||||||
|
|
|
@ -30,11 +30,22 @@ public:
|
||||||
struct ins
|
struct ins
|
||||||
{
|
{
|
||||||
halp::dynamic_audio_bus<"Input", double> audio;
|
halp::dynamic_audio_bus<"Input", double> audio;
|
||||||
struct : halp::knob_f32<"Bits", halp::range{.min = 3, .max = BITS, .init = BITS}>
|
halp::knob_f32<"SAMPLE RATE", halp::range{.min = .1, .max = 1., .init = 1.}> s_rate;
|
||||||
|
|
||||||
|
using log_map = halp::log_mapper<std::ratio<95, 100>>;
|
||||||
|
struct : halp::knob_f32<"BITS", halp::range{.min = 3, .max = BITS, .init = BITS}>
|
||||||
{
|
{
|
||||||
using mapper = halp::log_mapper<std::ratio<95, 100>>;
|
using mapper = log_map;
|
||||||
} bits;
|
} bits;
|
||||||
halp::knob_f32<"Rate", halp::range{.min = .1, .max = 1., .init = 1.}> rate;
|
struct : halp::knob_f32<"FREQ", halp::range{.min = .4, .max = 200., .init = 5.}>
|
||||||
|
{
|
||||||
|
using mapper = log_map;
|
||||||
|
} freq;
|
||||||
|
struct : halp::knob_f32<"DEPTH", halp::range{.min = .0, .max = 1., .init = 0.}>
|
||||||
|
{
|
||||||
|
using mapper = log_map;
|
||||||
|
}
|
||||||
|
depth;
|
||||||
} inputs;
|
} inputs;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -47,17 +58,26 @@ public:
|
||||||
{
|
{
|
||||||
// Initialization, this method will be called with buffer size, etc.
|
// Initialization, this method will be called with buffer size, etc.
|
||||||
set_bit_factor();
|
set_bit_factor();
|
||||||
|
lfo.set_sample_rate(info.rate);
|
||||||
|
lfo.freq(5);
|
||||||
|
|
||||||
skipped_frames.resize(info.input_channels);
|
skipped_frames.resize(info.input_channels);
|
||||||
lfos.resize(info.input_channels);
|
|
||||||
fms.resize(info.input_channels);
|
fms.resize(info.input_channels);
|
||||||
|
|
||||||
for (auto [lfo, fm] : std::views::zip(lfos, fms))
|
for (auto& fm : fms)
|
||||||
{
|
{
|
||||||
lfo.set_sample_rate(info.rate);
|
|
||||||
lfo.set(5, 0, 0);
|
|
||||||
fm.set_sample_rate(info.rate);
|
fm.set_sample_rate(info.rate);
|
||||||
fm.maxDelay(0.1);
|
fm.maxDelay(0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phases.resize(info.output_channels);
|
||||||
|
|
||||||
|
float phase_frac{1.f / info.output_channels};
|
||||||
|
|
||||||
|
for (int i{0}; i < info.output_channels; i++)
|
||||||
|
{
|
||||||
|
phases[i] = i * phase_frac;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do our processing for N samples
|
// Do our processing for N samples
|
||||||
|
@ -72,18 +92,21 @@ public:
|
||||||
private:
|
private:
|
||||||
int bit_factor, step_size{0};
|
int bit_factor, step_size{0};
|
||||||
|
|
||||||
|
|
||||||
|
double previous_bits{BITS},
|
||||||
|
previous_rate{1};
|
||||||
|
|
||||||
|
std::vector<float> phases;
|
||||||
std::vector<int> skipped_frames;
|
std::vector<int> skipped_frames;
|
||||||
|
|
||||||
double previous_bits{BITS}, previous_rate{1};
|
|
||||||
|
|
||||||
std::vector<gam::LFO<gam::phsInc::Loop,
|
|
||||||
halp::compat::gamma_domain>> lfos;
|
|
||||||
std::vector<gam::Delay<double,
|
std::vector<gam::Delay<double,
|
||||||
gam::ipl::Linear,
|
gam::ipl::Linear,
|
||||||
halp::compat::gamma_domain>> fms;
|
halp::compat::gamma_domain>> fms;
|
||||||
|
|
||||||
|
gam::LFO<gam::phsInc::Loop, halp::compat::gamma_domain> lfo{5.};
|
||||||
|
|
||||||
void set_bit_factor();
|
void set_bit_factor();
|
||||||
double crush_frame(const double& f);
|
double crush(const double& f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace Ottobit
|
||||||
|
|
|
@ -10,11 +10,21 @@ struct Senior::ui
|
||||||
using enum halp::layouts;
|
using enum halp::layouts;
|
||||||
|
|
||||||
halp_meta(name, "Senior")
|
halp_meta(name, "Senior")
|
||||||
halp_meta(layout, hbox)
|
halp_meta(layout, vbox)
|
||||||
halp_meta(background, dark)
|
halp_meta(background, dark)
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
halp_meta(layout, hbox)
|
||||||
halp::item<&ins::bits> bits;
|
halp::item<&ins::bits> bits;
|
||||||
|
halp::item<&ins::s_rate> s_rate;
|
||||||
|
} res;
|
||||||
|
|
||||||
halp::item<&ins::rate> rate;
|
struct
|
||||||
|
{
|
||||||
|
halp_meta(layout, hbox)
|
||||||
|
halp::item<&ins::depth> depth;
|
||||||
|
halp::item<&ins::freq> freq;
|
||||||
|
} mod;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue