Skip to content

Commit

Permalink
FX NaN protection; Activated for Spring Reverb (#951)
Browse files Browse the repository at this point in the history
Closes #830
  • Loading branch information
baconpaul committed Nov 29, 2023
1 parent c632dfe commit 833fabe
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
4 changes: 3 additions & 1 deletion docs/nightlychangelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@
you just gotta fix it!
- Modulating a frequncy-style surge parameter gets a 'set to 1oct/v' menu item
in the RMB.
- Cache the WT conversion for saving into your patch in the WT/Window VCO
- Cache the WT conversion for saving into your patch in the WT/Window VCO
- In rare cases the SpringReverb could NaN. Reset the effect automatically if
these occur as a workaround.
24 changes: 24 additions & 0 deletions src/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef SURGE_XT_RACK_SRC_FX_H
#define SURGE_XT_RACK_SRC_FX_H

#include <cmath>
#include "SurgeXT.h"
#include "dsp/Effect.h"
#include "XTModule.h"
Expand Down Expand Up @@ -75,6 +76,7 @@ template <int fxType> struct FXConfig

static constexpr float rescaleInputFactor() { return 1.0; }
static constexpr bool softclipOutput() { return false; }
static constexpr bool nanCheckOutput() { return false; }
};

template <int fxType>
Expand Down Expand Up @@ -435,6 +437,7 @@ struct FX : modules::XTModule, sst::rackhelpers::module_connector::NeighborConne
std::string getName() override { return std::string("FX<") + fx_type_names[fxType] + ">"; }

int bufferPos{0};
uint32_t lastNanCheck{0};
float bufferL alignas(16)[MAX_POLY][BLOCK_SIZE], bufferR alignas(16)[MAX_POLY][BLOCK_SIZE];
float modulatorL alignas(16)[MAX_POLY][BLOCK_SIZE], modulatorR
alignas(16)[MAX_POLY][BLOCK_SIZE];
Expand Down Expand Up @@ -567,6 +570,25 @@ struct FX : modules::XTModule, sst::rackhelpers::module_connector::NeighborConne

FXConfig<fxType>::populateExtraOutputs(this, 0, surge_effect.get());

if constexpr (FXConfig<fxType>::nanCheckOutput())
{
if (lastNanCheck == 0)
{
bool isNumber{true};
for (int ns = 0; ns < BLOCK_SIZE; ++ns)
{
isNumber = isNumber && std::isfinite(processedL[0][ns]);
isNumber = isNumber && std::isfinite(processedR[0][ns]);
}

if (!isNumber)
{
reinitialize();
}
}
lastNanCheck = (lastNanCheck + 1) % 32;
}

bufferPos = 0;
}

Expand All @@ -581,6 +603,7 @@ struct FX : modules::XTModule, sst::rackhelpers::module_connector::NeighborConne
outl = outl - 4.0 / 27.0 * outl * outl * outl;
outr = outr - 4.0 / 27.0 * outr * outr * outr;
}

outl *= SURGE_TO_RACK_OSC_MUL;
outr *= SURGE_TO_RACK_OSC_MUL;
if (outputs[OUTPUT_L].isConnected() && !outputs[OUTPUT_R].isConnected())
Expand All @@ -604,6 +627,7 @@ struct FX : modules::XTModule, sst::rackhelpers::module_connector::NeighborConne
void reinitialize()
{
surge_effect->init();
halfbandIN.reset();
for (const auto &s : surge_effect_poly)
if (s)
s->init();
Expand Down
1 change: 1 addition & 0 deletions src/fxconfig/SpringReverb.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ template <> constexpr int FXConfig<fxt_spring_reverb>::numParams() { return 8; }
template <> constexpr int FXConfig<fxt_spring_reverb>::extraInputs() { return 1; }
template <> constexpr int FXConfig<fxt_spring_reverb>::extraSchmidtTriggers() { return 2; }
template <> constexpr int FXConfig<fxt_spring_reverb>::specificParamCount() { return 1; }
template <> constexpr bool FXConfig<fxt_spring_reverb>::nanCheckOutput() { return true; }
template <> FXConfig<fxt_spring_reverb>::layout_t FXConfig<fxt_spring_reverb>::getLayout()
{
const auto col = FXLayoutHelper::standardColumns_MM();
Expand Down

0 comments on commit 833fabe

Please sign in to comment.