1
$\begingroup$

I have this recording from my DAW that showed a strange form of distortion: the signal clipped at many places, but instead of simply being clipped (loss of information), somehow the integer value of the signal overflowed and has been stored in the file. It resulted in worse-sounding distortion, but the information is still there, as a mirrored image in the opposite side of the signal.

This is plainly evident when looking at the waveform. You can clearly tell when the signal clips because the rest of the wave is visible between the peaks. waveform

How should I approach fixing this file? I am very comfortable with SOX, ffmpeg, the C language, SuperCollider and various other tools.

$\endgroup$
3
  • 1
    $\begingroup$ I find it very interesting that the DAW would overflow the signal like that. If it kept some sidecar file that contained the locations where it clipped, it would be a cheap way of achieving some additional headroom $\endgroup$
    – sleblanc
    Commented Dec 17, 2020 at 12:43
  • $\begingroup$ In a natural audio file (music or speech), sample values should be sufficiently smooth; then look for sample-to-sample jumps as large as the full signal range (xmax-xmin), then values between two such jumps is a candidate for being an overflow. But be careful: don't choose the outer interval: it's the inner-interval. The clue is that, typically, the overflow should be a short segment, otherwise it's heavily clipped... This way, you may correct certain (if not all) of those simple overflows... $\endgroup$
    – Fat32
    Commented Dec 17, 2020 at 13:21
  • $\begingroup$ well, that's good up to 1/2 Nyquist @Fat32 but above that, you might be guessing whether the signal wrapped around or not. $\endgroup$ Commented Dec 17, 2020 at 19:20

1 Answer 1

3
$\begingroup$

What you have there is "wrap around" and a bad case at that.

It's easy enough to fix though. Let's call your samples $x[n]$ and your max amplitude $x_{max}$, so your signal is currently bounded to $[-x_{max},+x_{max}]$

Go through the waveform sample by sample. Whenever you see a jump that's larger than your max amplitude, add or subtract twice the max amplitude to bring it back to where it was.

Something like

for (i = 1; i<n; i++)
{
   sampleDiff = x[i]-x[i-1];
   if (sampleDiff > xmax) { x[i] = x[i] - 2*xmax; }
   if (sampleDiff < -xmax) { x[i] = x[i] + 2*xmax;}
}

Make sure you are using a data type that accommodate a data range of at least $[-2x_{max},+2x_{max}]$, which is quite likely NOT the original data type. Also make sure you don't start in a "wrapped" region, i.e. x[0] needs to be good

$\endgroup$
1
  • $\begingroup$ Thanks for the help. I'll wait to see if other answers show up, but there is a good chance I'll end up accepting yours. $\endgroup$
    – sleblanc
    Commented Dec 18, 2020 at 5:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.