Fix glitches in soft saturation algorithm - dsp.h #214
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This patch fixes some identified glitches in the soft saturation algorithm (mentioned in the comments of the code itself), and removes a commented-out single return implementation. I removed this comment since it only affects the positive side of the signal, so it's not equivalent to the multi-line algorithm and fixing it would require using some mathematical functions or other tricks that would make it even harder to understand and less performant than the full implementation.
In the referred origin for the algorithm it is stated that the threshold is bound between 0 and 1. I added this info in the description of the function.
The glitches in this implementation stem from the fact that it is possible for
valto evaluate as being equal tothreshwhile not being greater than 1.Consider
val = thresh = 1.0fIn this case, none of the branches of the
if elsestatements will be evaluated. Sinceoutis being initialized to0.0f, the output will be 0. If the neighboring samples are close to 1 (for example near the peak of a sinus wave), this would produce 1 sample equal to zero near samples that are close to 1.0f, therefore creating crackling sounds. There were two options to solve this issue:val < threshtoval <= thresh(line 291)outtoininstead of0.0f(line 288)I preferred the first option since in theory none of them would increase clock cycles needed to calculate the output, and the first option makes the algorithm clearer. Also the second option might produce a discontinuity if the neighbouring samples are being modified by the saturation algorithm.
Something similar happens when val == 1.0f. This case is also not handled in the conditionals, so it will also remain zero
Note 1: I didn't commit the changes done by
util/fix_style.shsince none of them are relevant to my changesNote 2:
NaNwill be mapped to0, since according to the IEEE 754 standard, a comparison toNaNwill always evaluate tofalseTesting
I created a small Qt app to visualize the effects of this code. Project is attached. Just copy all the files to the same folder and open the project file with QtCreator , or create a subdirectory called build and from there run (there needs to be a Qt 5.15 version installed in the system):
I also added a screenshot of the issue taken with the test app
Demos / Example Code
testDaisySoftSaturationFix.zip
Original plot of the problem x = a






Fix described in 1)
Fix described in 2)
Illustrating the issue with the commented -out version
Illustrating the issue with x = 1.0f