It seems that opus_pcm_soft_clip() function can yields noise on special cases, where ending of previous frame is not soft clipped but beginning of new frame requires soft clipping.I'm not a smart guy and not quite familiar with DSP, but as far as I understand:This filter uses the following transfer function:f(x) = x (ordinary case)f(x) = x + ax^2 (soft clipping case, a is chosen so that f(x) = 1 on peak value)
Usually, soft clip is only applied on surrounding points of clipping, from nearest previous zero crossing point to nearest next zero crossing point.Zero crossing point is used as boundary because two function above can be smoothly connected only at x = 0.However, on the "special case", this function has to use non zero-crossing point as boundary. This is already specially taken care of so that result is at least "continuous", but it is not "smooth" (differentiable). And it seems to result in widely spread frequency components and audible noise at the boundary point.
I think this can be avoided by processing only until the final zero crossing point, and returning minimum of number of processed samples for each channels. And only when there is no more input, all remaining input can be processed.This requires slightly more complex book keeping, but it's possible. I don't know it's worth doing, though.
The problem with returning a smaller number of samples is that it breaks the current Opus API and it can't work for real-time applications (the samples have to go to the soundcard now and not later).
So one of the design constraints of opus_pcm_soft_clip() is be completely transparent for the user of the API, while doing a better job than hard clipping. I assume that the glitches you've been talking about are less audible than hard clipping, right? Otherwise it would be a bug.
In any case, I'm definitely interested in ways that opus_pcm_soft_clip() can be improved while still returning the same number of samples. So if you have any ideas (or better, patches), please let me know.