I noticed that even when converting 24-bit Signed Integer PCM audio to Float32
, clipping still occurs even after returning to the original gain level.
sox in.wav -b 32 -e floating-point out.wav
It inevitably means that SoX doesn't support operations in 32-bit floating point precision. Am I right? Is there a way to process audio with Float32 precision in SoX?
Reading the sox source code, sox_sample_t
is int32.
You are thus correct: sox cannot represent the full float32 range.
If you read its header, sox.h
, this is documented:
/* Conversions: Linear PCM <--> sox_sample_t
*
* I/O Input sox_sample_t Clips? Input sox_sample_t Clips?
* Format Minimum Minimum I O Maximum Maximum I O
* ------ --------- ------------ -- -- -------- ------------ -- --
* Float -inf -1 y n inf 1 - 5e-10 y n
* Int8 -128 -128 n n 127 127.9999999 n y
* Int16 -32768 -32768 n n 32767 32767.99998 n y
* Int24 -8388608 -8388608 n n 8388607 8388607.996 n y
* Int32 -2147483648 -2147483648 n n 2147483647 2147483647 n n
*
* Conversions are as accurate as possible (with rounding).
*
* Rounding: halves toward +inf, all others to nearest integer.
*
* Clips? shows whether on not there is the possibility of a conversion
* clipping to the minimum or maximum value when inputing from or outputing
* to a given type.
*
* Unsigned integers are converted to and from signed integers by flipping
* the upper-most bit then treating them as signed integers.
*/
Notice how "clips" is true on input when that input is a float, and false in every other case.
If you need full floating-point precision, sox is not an appropriate tool for the job. Consider writing code in Python with numpy/scipy/&c, in Julia, or in another language that provides efficient support for interacting with large floating-point vectors.