I am amazed how difficult it is in Nyquist to get one previous output sample to feed back into a function input! Maybe this needs to be addressed in a future release?
The issue is that you are needing to create a new DSP block that incorporates a mixer and limiter into the inner loop of a a bandpass filter. Because Nyquist in an interpreted language, looping through samples is expensive, which is why Nyquist's DSP blocks are written in C.
In Faust, DSP blocks are created by defining the algorithm in an algorithmic language, and then compiling that algorithm into low level code (such as C or C++). This is the main purpose of Faust.
In Nyquist you can do the same. The algorithm can be defined as an ALG definition, then compiled into C code https://www.cs.cmu.edu/~rbd/doc/nyquist/part17.html#210
This is not the main purpose of Nyquist, and is much less convenient to do than in Faust, but it can be done.
It is perfectly possible to create low distortion hard limiting, using Nyquist's built-in DSP (no need to create new DSP blocks). https://github.com/audacity/audacity/bl ... limiter.ny
However, you don't want to do that. You specifically want to create a DSP in the way that you do in Faust, which while possible, is not easy in Nyquist.
Why do you want to use Nyquist for this, when it is so much easier in Faust?
In Nyquist, the easiest way to create new DSP blocks is as Lisp objects. See DSP in Lisp
. This is considered to be an "advanced topic" for Nyquist programming.