Wow so confusing, what did you do to my class @t0m
@chkn I see your argument too but it’s important to be ultra precise here, so the documentation and the names of the classes will be clear, which is not the case right now with the last commit.
When I submit the class LogSmoothedValue to the JUCE team, the point was that I wanted to smooth volume changes in a logarithmic way, in the specific context of the Convolution IR changes, with two volumes being applied in opposite direction during the transition. It solved the issue of audible artefacts with this improvement during changes. Before, the volume was increasing too quickly for our ears, and so users perceived artefacts during the beginning of the volume ramp, unless the ramp length would be stupidly high. So that class smoothes the volume between two values, in a way the ramp is linear in the log scale. It could be used also to model what happens when a user moves a volume slider, which is usually mapped in dB in the UI.
That’s because our ears perceive linearly volume changes moving linearly in a log scale, such as the dB scale.
That class takes two arguments, first one being the middle value in dB (the slope of the ramp in the dB/log scale, the speed for increase/decrease of the ramp), and a boolean which allows us to revert the whole curve if wanted (slow start vs slow end). That middle value parameter is important to fix the amount of “log smoothing” you want, meaning how much you want the curve to be far from something looking like a straight line. That curve will be the same whatever the values we have in the class for the starting point and the end point.
Here is how the smoothed value in the linear case looks like:
Log case (mid value at default value -40 dB):
Log case (mid value at value -20 dB):
Log case (mid value at default value -40 dB + slow end):
But what you proposed is indeed different. What you want is related with a change in another well know log mapping case, handling of cutoff frequencies. Like for volume, our ears perceive linearly frequency changes moving linearly in a log scale, which could be a scale called “dBHz”, so we don’t want to have a ramp going linearly from say 20 Hz to 20000 Hz, because we would have only high frequencies over the whole range and it would sound like a very quick change to our ears at first, and then slower and slower. But the code in the multiplicative case in the new JUCE class is not behaving exactly like my LogSmoothedValue. We don’t have a middle value parameter there to fix the speed of the curve. Instead, that speed is depending on the start and end values of the ramp !
Let’s see how it looks like with a change between 1 and 2 like previously with the new class:
Now if the change is between 10 and 100, here is the result:
In comparison, the change between 10 and 100 with the log class (mid at -40 dB):
So let’s look at the big picture now. We have three classes now that are meant to smooth parameters in a discrete way, meaning that at some discrete locations in time, we decide to change the value of a given parameter, and then we smooth that change using a ramp of a given length in samples. And we wait for a new change, either in this ramp duration or after to change the ramp again, by choosing a new target value, and selecting the current value as a source.
Now, that linear change might be a problem, so we want a ramp moving logarithmically, meaning linearly in a log scale, at a given speed which is not fixed just because we decided to dismiss the linear ramp in a linear scale. That speed could be either depending on a fixed parameter (LogSmoothedValue), or depending on the context and specifically the source + target values (new multiplicative SmoothedValue class).
Why don’t we do ONE new multiplicative class which allows us to specify the speed in the first way or the another one, instead of two different classes ? So we would have everything in juce_audio_basics (and @t0m you could fix the modules definition so that the cpp files with the unit tests are included only in the unit tests project, like we did for the FFT class for example, it’s weird to mix different unit tests practice in the code and having a unit test all the time compiled in the base code). And all the three classes do the same thing, so they should have a similar name, using either the word “ramp” or “smoothed”, but not mixing them differently.