HydrogenAudio

Hydrogenaudio Forum => General Audio => Topic started by: Morality124 on 2012-10-07 02:33:31

Title: SoX -1 produces clipped samples?
Post by: Morality124 on 2012-10-07 02:33:31
I was trying to invert the absolute phase of some audio files using SoX, and for one of those files SoX reports that 2 peaks have been clipped. This occurs with both the -v switch and the -vol effect. both set at exactly -1. When I set the amount to 0.9, clipping does not occur.

Why is this one file clipping at -1? Thanks.
Title: SoX -1 produces clipped samples?
Post by: Dynamic on 2012-10-07 03:18:35
I was trying to invert the absolute phase of some audio files using SoX, and for one of those files SoX reports that 2 peaks have been clipped. This occurs with both the -v switch and the -vol effect. both set at exactly -1. When I set the amount to 0.9, clipping does not occur.

Why is this one file clipping at -1? Thanks.


This would be a pure inversion of normalised values, where the normalised range -1 to 0 to +1 is inverted to +1 to 0 to -1. (If you have waves more complicated than a continuous sinusoid in mind, forget phase, think polarity inversion, that's what's actually being done)

In non-floating point, e.g. 16-bit, signed value 0 is defined as zero - no audio, no DC component, so the range of allowed signed integer values goes from -32768 to +32767. Regardless of whether you define -1 to be -32768 or -32767, it's impossible to invert the -32768 to +32768 because the latter value is not permitted in 16-bit signed representation so it must be clipped to +32767. Setting volume scaling to 0.99996948 (=32767/32768) would be enough to prevent clipping (requires dither to decorrelate quantization noise). If you want mathematical perfection, the best way is to convert to floating point output, e.g. 32-bit float. Such minor clipping is almost certainly inaudible, however, if you just do what you already did.
Title: SoX -1 produces clipped samples?
Post by: Morality124 on 2012-10-07 03:45:33
I was trying to invert the absolute phase of some audio files using SoX, and for one of those files SoX reports that 2 peaks have been clipped. This occurs with both the -v switch and the -vol effect. both set at exactly -1. When I set the amount to 0.9, clipping does not occur.

Why is this one file clipping at -1? Thanks.


This would be a pure inversion of normalised values, where the normalised range -1 to 0 to +1 is inverted to +1 to 0 to -1. (If you have waves more complicated than a continuous sinusoid in mind, forget phase, think polarity inversion, that's what's actually being done)

In non-floating point, e.g. 16-bit, signed value 0 is defined as zero - no audio, no DC component, so the range of allowed signed integer values goes from -32768 to +32767. Regardless of whether you define -1 to be -32768 or -32767, it's impossible to invert the -32768 to +32768 because the latter value is not permitted in 16-bit signed representation so it must be clipped to +32767. Setting volume scaling to 0.99996948 (=32767/32768) would be enough to prevent clipping (requires dither to decorrelate quantization noise). If you want mathematical perfection, the best way is to convert to floating point output, e.g. 32-bit float. Such minor clipping is almost certainly inaudible, however, if you just do what you already did.


Interesting. I just realized that I've never inverted an audio file that had a 100% peak until now. Thanks for clarifying!

EDIT: So, to make sure I understand you, if I set the scaling to 0.999969482421875 (or how many digits I can calculate ), that would require more work than just setting the value?
Title: SoX -1 produces clipped samples?
Post by: Dynamic on 2012-10-08 00:46:58
sox -gain h --volume -1 -gain r input.wav output.wav

The above line will provide headroom, apply the inversion, then reclaim as much of the headroom as possible without clipping. (This means it will automatically apply the appropriate scaling if it needs to, otherwise it will leave the plain inversion)

I believe that if SoX increases the bit-depth at any time (i.e. scaling by -0.999...) it will automatically dither as necessary.

For some purposes the above command line will be best, for others, allowing such minor clipping is better:
sox --volume -1 input.wav output.wav

For yet other cases, subtracting each integer 16-bit sample value from -1 would be best (which can be performed as a bitwise invert for two's complement signed integers, like 16-bit or 24-bit PCM, but neither is available in SoX, AFAIK)