# How come floating point audio doesn't clip?

I'm generating a 440Hz sine wave in 32bit floating point audio format with SDL2.

I've read else where that 32bit floating point audio format is normalised between -1.0 and +1.0.

With that statement I would expect clipping to occur for values beyond -1 and +1.

As I increase the amplitude of the sine wave beyond -1.0 and +1.0, the tone becomes loader (really really loud at 3000 amplitude), and no clipping seems to occur.

So my questions are:

-What is happening with amplitudes beyond -1.0/+1.0 and why doesn't it clip?

-What is the maximum amplitude value in 32bit floating point audio format?

-Is there anywhere that defines the -1/+1 normalisation convention?

See this and scroll down to "Converting and Using Floating Point Samples".

One good reason to convert integer samples to floating point samples in [-1,1] is so that you can mix bit-depths of integer samples easily. For instance, if you have a 24-bit file with a sample that is half of positive full scale, and an 8-bit file with a sample that is half of positive full scale, they can both be converted to the same floating point number and can be mixed together as if they were from identical formats.

Since that process is convenient and effective for allowing users to mix file formats in the same session, it is commonly used, but not defined by any body (that I'm aware of). Each software developer is finding what they think is the best way to convert and process floating point audio. So that sort of answers your third question.

Your first question is related to the implementation in the SDL2 library. It sounds like it's written so that it's very hard or impossible to "clip" when converting from 32-bit float back to integer (which has to be done for output).

In other words, your amplitude setting of 3000 is going to be converted to a set of floating point numbers with magnitudes (absolute values) much smaller than 1. The 3000 is just an arbitrary number that is part of the SDL2 library's system for generating sounds. It's not directly stored as a floating point number of 3000. So your second question depends on the library.

Integer audio format background

Integer number formats are constrained by their fixed range. Consider the 8 bit format - here you have 256 possible steps for each sample (which a bit simplified means the speaker membrane ends up having 256 possible positions all in all). If the format is signed, the samples may take values in the range -128..127, with center point at zero. If the format is unsigned the range is 0..255, with center point at 128.

dB wise that means we have to scale the value by the max values and round/truncate the remaining decimals to represent the sample value in an integer format.

Now with such a limited fixed range format it is crucial that we utilize all possible bit values, so it is natural to let the maximum bit value represent the maximum reproducible output level (0dBFS). We don't want to waste bits on theoretical possible but practically unconvertable "over" values (as in it will clip/overflow/distort etc. depending on the actual hardware/driver). That applies to other fixed integer formats as well (16bit and 24bit).

Floating point audio

With floating point numbers the whole situation changes: since the format is composed of a number (the significant) and an exponent that scales that number, the range is not fixed the same way as with the integer formats - we can "move" the range and practical utilization of the bits that in the end make up the physical precision constraint.

So we dB wise don't have to scale the sample to any maximum value like with the integer formats. We simply use the direct linear translation of the amplitudes, meaning that 0dBFS = 1.

But since we are not constrained to a range like with the fixed formats, there is no problem in working with larger than 0 dbFS amplitude or or extremely small amplitudes for that sake. At some point you hit the cruel real world though and have to settle for a fixed final format (btw you can directly think of HDR photography vs. LDR as an analogy here: the white point being 0 dBFS).

-What is happening with amplitudes beyond -1.0/+1.0 and why doesn't it clip?

As long as you're working in a floating point flow they simply take a higher value (again think about the floating/moving precision). At some point you have to convert to a fixed integer format and attenuate/clip/limit as needed.

-What is the maximum amplitude value in 32bit floating point audio format?

Answer 1: irrelevant. Answer 2: 1.0 Answer 3: for single precision 2^31 - 1, but it is irrelevant and you don't need to scale the amplitude to utilize all bits since it is floating.

-Is there anywhere that defines the -1/+1 normalisation convention?

As such this is really the dB "convention" that applies - no range scaling takes place. Values above 1 will in the end get clipped etc. to 0dBFS.