Skip to content

Commit

Permalink
Fix a problem with very very very low attack accuracy
Browse files Browse the repository at this point in the history
If the attack was in the first few lut buckets the inaccuracy
of the lut dominates. These are at most a few samples and are cached
anyway at constant a (which it would be over these blocks) so
just do it directly there.
  • Loading branch information
baconpaul committed Feb 20, 2025
1 parent 0813146 commit 3a1b4f8
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion include/sst/basic-blocks/modulators/AHDSRShapedSC.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ struct AHDSRShapedSC : DiscreteStagesEnvelope<BLOCK_SIZE, RangeProvider>
if (!twoToX.isInit)
twoToX.init();

// First few luts do it exactly
[[unlikely]] if (x < 2.0 / 1024.0)
{
auto timeInSeconds =
(std::exp(RangeProvider::A + x * (RangeProvider::B - RangeProvider::A)) -
RangeProvider::C) /
RangeProvider::D;

auto checkV = 1.0 / timeInSeconds;

auto dPhase = BLOCK_SIZE * srProvider->sampleRateInv * checkV;
lastDPhaseX = x;
lastDPhase = dPhase;

return dPhase;
}

#define CHECK_VS_LUT 0
#if CHECK_VS_LUT
auto timeInSeconds =
(std::exp(RangeProvider::A + x * (RangeProvider::B - RangeProvider::A)) -
Expand All @@ -146,7 +164,7 @@ struct AHDSRShapedSC : DiscreteStagesEnvelope<BLOCK_SIZE, RangeProvider>
int xpi = (int)xp;
auto xpf = xp - xpi;
auto interp = (1 - xpf) * expLut[xpi] + xpf * expLut[xpi + 1];
auto res = twoToX.twoToThe(interp);
float res = twoToX.twoToThe(interp);

#if CHECK_VS_LUT
static float lastX = -23;
Expand All @@ -156,6 +174,8 @@ struct AHDSRShapedSC : DiscreteStagesEnvelope<BLOCK_SIZE, RangeProvider>
<< "\n time=" << timeInSeconds << "\n sr=" << srProvider->sampleRate
<< " sri=" << srProvider->sampleRateInv
<< " 1/sri=" << 1.0 / srProvider->sampleRateInv << " bs=" << BLOCK_SIZE
<< "\n"
<< "xp=" << xp << " xpi=" << xpi << " xpf=" << xpf << " interp=" << interp
<< "\n dPhaseLUT=" << BLOCK_SIZE * srProvider->sampleRateInv * res
<< "\n dPhaseCAL=" << BLOCK_SIZE * srProvider->sampleRateInv * checkV
<< "\n 1/dPhaseLUT="
Expand Down

0 comments on commit 3a1b4f8

Please sign in to comment.