First thing: There are so many kinds of errors, if you would post the error message helping you would be easier and giving you hints how to learn to read and interpret error messages yourself (and I guess that is what you want to be able to in future ) would be possible too.
Second thing: When reading your code the first question that comes to my mind is: Were is Type declared and what do you assign to it? Is it a template of the outer class, is there some using or typedef directive in the surrounding code? Some bit more of surrounding information helps as well to help you.
Third thing: What is myParam? Where is it declared? In case it’s not a static variable (and I don’t guess it is) you need to capture it in one of the ways possible (by copy, by reference or you can capture your outer class ‘this’ pointer) – which type of capture you chose is dependent on what you want to do. Otherwise it is not visible to your compiler inside the lambda – is this maybe the error you get?
No, that shouldn’t be a problem. Since you don’t specify the return type, it might be possible that the deducted return type of that function is something different than a float? This could happen if e.g. myParam would be a double and Type a float (or the other way round). In this case your compiler will convert them multiplication into something like float * double = double and then chose the double overload of std::tanh which will lead to a double return type. You could try if explicit casting works, like e.g.
waveshaper.functionToUse = [this] (Type x)
auto value = std::tanh (myParam * x);
return static_cast<Type> (value);
However, as with the right kind of capture type, also the right choice for a solution for type casting thing (if this is really the problem here) depends on the use case, e.g. the desired precision you need.
I see what you are saying. The error I mentioned above (Assigning to ‘float (*)(float)’ from incompatible type) already happens at the line where this is supposed to be captured. So the code you provided wont even run unfortunately.
Mhm, I think you are mixing up run-time interpreted and compiled language concepts here. The error you are seeing is appearing at compile time, e.g. even before the code is run. It is displayed exactly at the line where something doesn’t match. And indeed, this is the case at the = sign in the line waveshaper.functionToUse = [this] (Type x). On the left side a function pointer to a function that take as float and return a float is expected. On the right side you specify a lambda that takes a float (aka Type in this case) and returns probably something else. The compiler deducts what “something else” is from the lambda body below, so even if the lambda body is a correct piece of C++ itself, the assignment expression above doesn’t match, therefore this is the line of code where the error is displayed. If you change the lambda body, the compiler will deduct a different function signature from the code it reads and the assignment above will become valid again.
And as long as there is any compiler error, no part of the code will ever be executed as the resulting executable won’t be generated at all
don t use dsp::WaveShaper and just have a single std::function to apply your waveshaper on a buffer.
Please note it’s probably not the optimal way to do it and you should probably use something like described there
Ok, with some sleep, re-reading the whole thing, the problem becomes obvious:
The waveshaper class expects a c-style function pointer as functionToUse – this is defined by the default parameter assigned to the second template argument. I had a std::function object in mind when writing the above. While you can assign all kinds of things that have a call operator () to a std::function, including function pointers and lambdas, you cannot assign all kinds of callable objects to a raw function pointer. As one special exception, the compiler will convert lambdas without any capture parameter into some in-place declared function, so in this special case, lambdas are supported as functionToUse.
As I was working with the waveshaper in combination with capture-less lambdas recently I didn’t have this clearly in mind. However, you are free to change the second template arg to what suits your case. So if you specify your waveshaper like this:
Your lambda with captures above should become assignable to the waveshaper function!
That being said, you can of course directly implement what the waveshaper does internally in your own member function, it’s not that complex. Or, as all you do with your parameter is adding up some gain before processing the tanh function, you could also consider to just move this gain stage into the preGain element right before the waveshaper in your processor chain