Audio processing with normalized [0.0, 1.0] domain
Prefer C++ headers

Instead of &lt;math.h&gt;, it's better to include &lt;cmath&gt; and qualify names such as std::log.

Prefer constants to macros

Re-write pi as a strongly-typed, scoped variable rather than a preprocessor macro.  Same for 2*pi if you really feel the need.

Manage line lengths

Some lines are very long.  In many cases, they just need newlines adding (e.g. bodies of inline functions can have their own lines).

In the case of the std::clamp() call, it's probably worth using variables to give a name to the candidate value before clamping. 

Easier sizeof

Instead of recomputing the size of bufferLeft and bufferRight like this:


    memset(&amp;bufferLeft, 0, blockSize * sizeof(double));
    memset(&amp;bufferRight, 0, blockSize * sizeof(double));



It's easier and clearer to just use the whole array size:

    memset(&amp;bufferLeft, 0, sizeof bufferLeft);
    memset(&amp;bufferRight, 0, sizeof bufferRight);


Personally, I'd generally prefer std::fill to match types and ensure the intention is clear:

    std::fill(std::begin(bufferLeft), std::end(bufferLeft), 0.0);
    std::fill(std::begin(bufferRight), std::end(bufferRight), 0.0);


Then I don't need to think about whether all-bits zero is the same as 0.0 or not.