resampling early-out; capaxitor note kill on end; lut improvements

master
zetaPRIME 2021-11-11 01:51:42 -05:00
parent d4aa622fa6
commit 187b51d524
3 changed files with 19 additions and 12 deletions

View File

@ -5,12 +5,12 @@ using namespace Xybrid::NodeLib;
#include <iostream>
#include <array>
#include <cmath>
#ifdef WITH_BOOST
#include <boost/math/special_functions/bessel.hpp>
using boost::math::cyl_bessel_i;
#else
#include <cmath>
using std::cyl_bessel_i;
#endif
@ -26,6 +26,12 @@ namespace {
double px = x * PI/1;
return std::sin(px) / px;
}
#if __cplusplus >= 202002L
using std::lerp;
#else
inline constexpr double lerp(double a, double b, double t) { return (1.0 - t) * a + t * b; }
#endif
}
@ -46,16 +52,12 @@ const std::array<std::array<std::array<double, LUT_TAPS>, LUT_LEVELS>, LUT_STEPS
//double kaiser = cyl_bessel_i(0, KAISER_BETA * std::sqrt(1.0 - std::pow( (2.0*x)/(LUT_TAPS-2) - 1.0, 2 ) ) ) / denom; // by-the-book kaiser window of length LUT_TAPS-1
//double idl = (2.0*PI)/(LUT_TAPS-1);
//double kaiser = 0.40243 - 0.49804 * std::cos(idl * x) + 0.09831 * std::cos(2.0 * idl * x) - 0.00122 * std::cos(3.0 * idl * x); // approximate
//double kaiser = 1.0; // omit windowing
//kaiser = std::max(kaiser, 0.0);
t[step][0][tap] = sinc(sx) * kaiser; // sinc function centered on main tap, offset by subvalue, multiplied by window
// uprate tables
for (size_t i = 1; i < LUT_LEVELS; i++) {
double m = 1.0/static_cast<double>(i);
double om = m;
if (i == 1) om *= kaiser; // add kaiser to output mult on first level to smooth things
t[step][i][tap] = sinc(sx*m) * om; // we're squishing the waveform here so we want to "expand" the sinc function
for (size_t i = 0; i < LUT_LEVELS; i++) {
double m = 1.0/std::max(static_cast<double>(i), 1.0); // sinc function "expands" the higher we pitch things
double om = m * lerp(1.0, kaiser, std::pow(m, 0.333)); // apply kaiser proportionally; we want it less the higher we go
t[step][i][tap] = sinc(sx*m) * om;
if (t[step][i][tap] != t[step][i][tap]) t[step][i][tap] = 0; // NaN guard
}

View File

@ -29,7 +29,8 @@ namespace Xybrid::NodeLib {
auto ii = static_cast<ptrdiff_t>(ip) - LUT_HTAPS;
for (size_t i = 0; i < 8; i++) {
if (loop && ii >= le) ii = ((ii - ls) % ll) + ls;
if (ii >= 0 && ii < len) out += (*smp)[static_cast<size_t>(ii)] * pt[i];
else if (ii >= len) return out; // we can early-out here
if (ii >= 0) out += (*smp)[static_cast<size_t>(ii)] * pt[i];
ii++;
}

View File

@ -83,6 +83,9 @@ void Capaxitor::init() {
double rate = static_cast<double>(smp->sampleRate) / static_cast<double>(audioEngine->curSampleRate());
double baseNote = smp->getNote();
bool loop = smp->loopStart >= 0;
auto len = static_cast<double>(smp->length());
size_t ts = p->size;
for (size_t i = 0; i < ts; i++) {
core.advanceNote(note);
@ -92,12 +95,13 @@ void Capaxitor::init() {
// actual sample pos
double sp = data.sampleTime * rate;
if (!loop && sp >= len) return core.deleteNote(note);
auto out = NodeLib::resamp(smp.get(), sp, rate*fr);
data.flt += (out - data.flt) * 0.97;
//data.flt += (out - data.flt) * 0.97;
(*p)[i] += data.flt.gainBalance(0, note.pan) * note.ampMult();
(*p)[i] += out.gainBalance(0, note.pan) * note.ampMult();
data.sampleTime += fr;
}
};