@OstinTheKr0t
okok, tehre you go:
here is a short explaination -
It combines Sample Rate Reduction (Sample & Hold) and Bit Depth Quantization in a single SNEX node.How it works:The node processes audio in two distinct stages to achieve that classic "crushed" digital sound.
1. Sample Rate Reduction (Temporal Distortion)Instead of processing every incoming sample, the node "freezes" the amplitude for a set number of samples using a counter and a buffer.The Logic:
A holdCounter tracks the "steps." When it hits zero, it grabs a new "snapshot" of the input signal and stores it in holdLeft/Right.The Result: This creates a "staircase" waveform. In the frequency domain, this introduces Aliasing, giving it that metallic, ringing Lo-Fi character.
2. Bit Depth Reduction (Amplitude Quantization)This stage reduces the dynamic resolution of the signal, simulating older AD/DA converters (like 8-bit or 12-bit systems).
The Math:
We calculate the available "steps" based on the bit depth
2. We scale the signal up, round it to the nearest integer, and scale it back down
The Result: This introduces Quantization Noise and "fuzziness," especially audible on tails and quiet signals.
template <typename T> void processFrame(T& data)
{
// --- Sample Rate Reduction (Sample & Hold) ---
int divider = jmax(1, (int)srDivider);
if (holdCounter <= 0)
{
holdLeft = data[0];
holdRight = data[1];
holdCounter = divider;
}
holdCounter--;
float outL = holdLeft;
float outR = holdRight;
// --- Bit Crusher ---
float steps = std::pow(2.0f, bitDepth) - 1.0f; // calculate steps
steps = jmax(1.0f, steps);
outL = std::round(outL * steps) / steps;
outR = std::round(outR * steps) / steps;
data[0] = outL;
data[1] = outR;
}
int handleModulation(double& ) { return 0; }
void setExternalData(const ExternalData& , int ) {}
// -------------------------------------------------------------------------
// Parameters: 0 = BitDepth | 1 = SampleRateReduction
// -------------------------------------------------------------------------
template <int P> void setParameter(double v)
{
if constexpr (P == 0) // Bit Depth (1 – 16)
bitDepth = (float)jlimit(1.0, 16.0, v);
if constexpr (P == 1) // SR Divider (1 – 32)
srDivider = (float)jlimit(1.0, 32.0, v);
}
Play around with the settings, and you will get the classic NES - Sound :)
I can gice you the .h files if you send me a dm
Cheers Ben