Capturing lambda and dsp::WaveShaper

dsp_module

#1

the example code for dsp::WaveShaper shows initialization like this:

dsp::WaveShaper<float> ws({ std::tanh });

and the longer form works too:
dsp::WaveShaper<float> ws({[](float sample){ return std::tanh(sample); } })

but if i try to capture anything xcode blows up so this:
dsp::WaveShaper<float> ws({[foo](float sample){ return std::tanh(sample + foo); } })

gives me:
error: no matching constructor for initialization of 'juce::dsp::WaveShaper<float>' ../../JuceLibraryCode/modules/juce_dsp/processors/juce_WaveShaper.h:36:8: note: candidate constructor (the implicit copy constructor) not viable: cannot convert initializer list argument to 'const juce::dsp::WaveShaper<float, float (*)(float)>' struct WaveShaper ^ ../../JuceLibraryCode/modules/juce_dsp/processors/juce_WaveShaper.h:36:8: note: candidate constructor (the implicit move constructor) not viable: cannot convert initializer list argument to 'juce::dsp::WaveShaper<float, float (*)(float)>' ../../JuceLibraryCode/modules/juce_dsp/processors/juce_WaveShaper.h:36:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided 1 error generated.

what am i doing wrong? is there a way to do this?


#2

I’d be curious if you put the function on it’s own line as a std::function<FloatType(FloatType)>, would you get the results you want:

float parm;
std::function<float(float)> shaperFunc = [&](float sample) { return std::tanh(sample + parm); };
dsp::WaveShaper<float> ws(shaperFunc);

#3

thanks, i had tried that too and std::function doesn’t work with or without capturing:
No matching conversion for functional-style cast from 'std::function<float (float)>' to 'juce::dsp::WaveShaper<float>'


#4

Hi,

try dsp::WaveShaper<float, std::function<float (float)>> ws([=](float sample){ return std::tanh(sample + foo); });

explanation: The Waveshaper classes second template argument is the function type. Per default this is a plain c style function pointer - not a std::function (probably for performance reasons). C++11 is clever enough to convert a non-capturing lambda into a c function pointer, but as soon as you’re trying to capture something, you need to use a std::function (to store the captured values). So the solution is to explicitly specify the second template argument of dsp::WaveShaper as std::function<float (float)>


#5

yes! i had to put the lambda in curly braces but this works. thanks!