The problem with differentiation is that each sample relies on that one before, when reconstructing via integration.
A sample sequence:
(0 0 1 0.75 0 0.2 0 0)
After differentiation we'll get:
(0 0 1 -0.25 -0.75 0.2 -0.2 0)
We now hard-clip at 0.5:
(0 0 0.5 -0.25 -0.5 0.2 -0.2 0)
..and integrate again:
(0 0 0.5 0.25 -0.25 -0.05 -0.25 -0.25)
That's a coarse example, a limiter would rather distribute the first peak over the look ahead time.
I only want to emphase that a slight numerical error will cause the signal to drift out of balance, i.e. you'll get a temporary DC-offset.
One could treat the positive and negative bands separately, cut off the numbers that cross the zero line and put it all together again.
You can also use the slope as a control signal too manipulate the original sound directly, where a steep slope is detected, an attenuation will be applied accordingly.
By the way, slope and integrate may not be ideal because they include the sample rate into their calculations. Slope will for instance have a value of 88200 for a jump from -1 to 1.
Here are some replacement functions and the sample from above as code (click "Debug" in the Nyquist prompt):
Code: Select all
(defun integrator (s-in)
(biquad s-in 1 0 0 1 1 0))
(defun differentiator (s-in)
(biquad s-in 1 -1 0 1 0 0))
(setf sig (snd-from-array 0 44100 #(0 0 1 0.75 0 0.2 0 0)))
(snd-display sig) (terpri)
(snd-display (differentiator sig)) (terpri)
(snd-display (clip (differentiator sig) 0.5)) (terpri)
(snd-display (integrator (clip (differentiator sig) 0.5)))
There's of course still a peak of 2 possible for the differentiator.