Apply a waveshaper function
-
I have a fairly simple waveshaper function, something like this:
left = in1 right = in2 curve = in3 * some formula out1 = curve * left out2 = curve * right
There's a bit more to it than that but not much. It just takes L and R inputs and a control parameter then performs a function on each input and sends them to the outputs.
What's the easiest way to implement this?
-
@dannytaurus Scriptnode
Do you have 3 input channels? What is in3?
-
@dannytaurus If you do not have a very complex algorithm, you do not have to process separately for left and right in SNEX.
- Insert a snex_shaper node
- Create a new file and name it "MyNode"
- Add a parameter - this will be the Drive knob
- Paste the code below
template <int NumVoices> struct MyNode { SNEX_NODE(MyNode); // Parameters float Drive = 0.0f; float getSample(float input) { input = Math.tanh(10.0f * Drive * input); return input; } // These functions are the glue code that call the function above template <typename T> void process(T& data) { for(auto ch: data) { for(auto& s: data.toChannelData(ch)) { s = getSample(s); } } } template <typename T> void processFrame(T& data) { for(auto& s: data) s = getSample(s); } void reset() { } void prepare(PrepareSpecs ps) { } void setExternalData(const ExternalData& d, int index) { } template <int P> void setParameter(double v) { if (P == 0) Drive = (float)v; } };
As you can see, the waveshaper function is:
out = tanh(10 * Drive * in)
In SNEX, we can write it like this:
input = Math.tanh(10.0f * Drive * input); return input;
-
There's a bit more to it than that but not much. It just takes L and R inputs and a control parameter then performs a function on each input and sends them to the outputs.
If you're using a stateless function with a single parameter, you are exactly within the bounds of the
math.expr
node which does exactly this (not more and not less).