parameter smoothing gain controls
-
- KVRAF
- Topic Starter
- 7416 posts since 17 Feb, 2005
Is using a first order lowpass usually problematic? I've implemented two dB scale controls, for in and out gain, and when changing presets it can make a loud pop of the input signal. I implement the filter on the dB scale, not the linear control input, and I think that is the problem. Doing it this (wrong) way prevents having to calculate the pow() every sample. Will linear smoothing of the dB scale gain modifier prevent this problem?
-
- KVRian
- 573 posts since 1 Jan, 2013 from Denmark
.. why not store the filter scale in normalized scale (non-dB) and update it on control input?
Anyway, isn't the problem that you don't apply the smoothing on switching presets?
Anyway, isn't the problem that you don't apply the smoothing on switching presets?
-
- KVRAF
- Topic Starter
- 7416 posts since 17 Feb, 2005
The filter runs at audio rate, not control rate. This also "decouples" the parameters from the audio, so when switching presets ( at least in this one case ... ) there is very little stutter, since it only changes the parameters. Might be a question for a different thread but is suspend() called on program change? I should probably try the vst debugger but I'm learning so slowly And the problem was the first order lowpass, I fixed it with linear smoother.
-
- KVRian
- 573 posts since 1 Jan, 2013 from Denmark
Okay, I get what you're doing now. Don't see why you would worry that much about two pow calls/sample, though.camsr wrote:The filter runs at audio rate, not control rate. This also "decouples" the parameters from the audio, so when switching presets ( at least in this one case ... ) there is very little stutter, since it only changes the parameters. Might be a question for a different thread but is suspend() called on program change? I should probably try the vst debugger but I'm learning so slowly And the problem was the first order lowpass, I fixed it with linear smoother.
I also don't see why suspend() would be called on program change, seeing as program changes can be automated.
-
- KVRAF
- Topic Starter
- 7416 posts since 17 Feb, 2005
Last time I used a fancy math function from math.h it was generating a call instruction, despite being "inline". Why could that happen? The results wasn't too bad, speed wise, but I wasn't thrilled it told me it was inline and then generated a call instruction. Although I have seen weirder things happen where the compiler will insert call instructions, I think it's an x64 thing. What else could call be used for?Mayae wrote:Don't see why you would worry that much about two pow calls/sample, though.
-
- KVRian
- 573 posts since 1 Jan, 2013 from Denmark
The compiler probably judged the benefits of inlining it were too small. In general, inlining should only happen for small functions, inlining in a loop makes it bigger and it can fail to be cached properly. It's harder to predict the performance effects of assembly just by looking at it; CPUs now adays cache code and data very intelligently. Measuring is the only way to really know..
As always, 'inline' is only a hint from the compiler and is also used to avoid ODR.
Other uses of call? It can be the only way to retrieve the PIC (when calling, the return address is pushed to the stack; popping it gets the EIP/RIP register value).
As always, 'inline' is only a hint from the compiler and is also used to avoid ODR.
Other uses of call? It can be the only way to retrieve the PIC (when calling, the return address is pushed to the stack; popping it gets the EIP/RIP register value).
-
- KVRist
- 350 posts since 9 Aug, 2011
Interesting to see this posted here. I had this same question the other day. I found this code. I converted it from C to C#:
class CParamSmooth
{
public:
CParamSmooth() { a = 0.99f; b = 1.f - a; z = 0; };
~CParamSmooth();
inline float Process(float in) { z = (in * b) + (z * a); return z; }
private:
float a, b, z;
};
I found it on musicdsp.org. Here:
http://musicdsp.org/archive.php?classid=3#257
It works well. It went from crackling and popping all over the place to being pretty much smooth with some tiny artifacts.
There are plenty of algorithms out there but this one is light on CPU, and will get the job done as a place holder if nothing else.
Just a reminder though. Remember, to make a copy of your gain variable. There should be a gain for the UI, and a gain for the DSP. I accidentally smoothed my UI variable and the knob started fighting against me like it didn't want to be turned.
class CParamSmooth
{
public:
CParamSmooth() { a = 0.99f; b = 1.f - a; z = 0; };
~CParamSmooth();
inline float Process(float in) { z = (in * b) + (z * a); return z; }
private:
float a, b, z;
};
I found it on musicdsp.org. Here:
http://musicdsp.org/archive.php?classid=3#257
It works well. It went from crackling and popping all over the place to being pretty much smooth with some tiny artifacts.
There are plenty of algorithms out there but this one is light on CPU, and will get the job done as a place holder if nothing else.
Just a reminder though. Remember, to make a copy of your gain variable. There should be a gain for the UI, and a gain for the DSP. I accidentally smoothed my UI variable and the knob started fighting against me like it didn't want to be turned.
-
- KVRAF
- Topic Starter
- 7416 posts since 17 Feb, 2005
Right it does that, but is it possbile to have inlined C library functions? I don't recall ever seeing one.Mayae wrote:The compiler probably judged the benefits of inlining it were too small.
I have attempted before to make the compiler inline everything. In GCC there are many parameters controlling inline generation, and it is quite confusing.
-
- KVRian
- 1379 posts since 26 Apr, 2004 from UK
Witht he new linkers that can recompile code, it is possile. But usually, if the two functions are in different compilation units, one function can't be inlined in the other.
If the functions are in the same unit (easier with C++ templates...), then I think it's better to let the compiler decide whether to inline or not.
If the functions are in the same unit (easier with C++ templates...), then I think it's better to let the compiler decide whether to inline or not.
-
- KVRian
- 573 posts since 1 Jan, 2013 from Denmark
In my experience, it does it if its benificiable. I have tested by copying source into the project, and IIRC there really weren't a difference.camsr wrote:Right it does that, but is it possbile to have inlined C library functions? I don't recall ever seeing one.Mayae wrote:The compiler probably judged the benefits of inlining it were too small.
I have attempted before to make the compiler inline everything. In GCC there are many parameters controlling inline generation, and it is quite confusing.
Functions like abs(), ldexp() etc. that handles bitwise semantics are often inlined in my experience (this also depends on the floating point model (fast/strict etc.)), but beyond that the gains are negligible.
If its crucial to inline cmath, it sounds like it's in a loop. If it's in a loop, you should rather look into simd-vectorization.
As said by miles, link-time code generation can potentially inline stuff in different compilation units - I know msvc does it, if you enable the setting.
-
- KVRian
- 573 posts since 1 Jan, 2013 from Denmark
I guess, you can read up on it here:
GL - whole program optimization: https://msdn.microsoft.com/en-us/library/0zza0de8.aspx
-that makes use of LTGC - link-time code generation: https://msdn.microsoft.com/en-us/library/xbf3tbeh.aspx
GL - whole program optimization: https://msdn.microsoft.com/en-us/library/0zza0de8.aspx
-that makes use of LTGC - link-time code generation: https://msdn.microsoft.com/en-us/library/xbf3tbeh.aspx
-
- KVRian
- 1379 posts since 26 Apr, 2004 from UK
Yes, that's the one.camsr wrote:Is that the same thing as Link Time Optimization (-flto)?
Please note also that this is something quite recent compared to the usual compiler techniques, and it is far less stable and can be riddled with bugs as well.
-
- KVRAF
- Topic Starter
- 7416 posts since 17 Feb, 2005
I am thinking LTO may not be the best solution. I attempted to use it before and the plugin would not compile. There are known issues with LTO.
Maybe I should implement a 2^x algorithm myself? I have come up with a piecewise approximation that does not involve calculating log, but I feel the accuracy for this intended usage is more important.
Anyone have an example?
Maybe I should implement a 2^x algorithm myself? I have come up with a piecewise approximation that does not involve calculating log, but I feel the accuracy for this intended usage is more important.
Anyone have an example?