• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

32-bit noise floor with 4 sine generator software: QUESTION

FrenchFan

Active Member
Joined
Mar 12, 2024
Messages
146
Likes
57
Hello everyone.

This question is not important for the measurements, but it bothers me.

If you generate reference sinuses with software, we can see
that in 32 bits, we do not have the same noise floor depending on the generators.
Some reach ~ -155 dbFS and others can be below -192dBFS.

For 16 and 24 bits the problem does not arise, all reach respectively
~< -96dbFS and ~< -144dbFS.

As a reminder, the 32-bit noise floor must be ~< 192.6dbFS.

I use here 4 generators to show this difference, and I give
the versions of the 4, having had differences between an old "octave" version
and the one I use.

audacity : V 2.4.2
rew : 5.40 Beta 50
octave : 6.4.0
sox : v14.4.2

I work under Linux (Linux Mint 21.1 Vera, kernel 5.15.0-60-generic)

I scanned the possibilities of the generators if they existed I even
generated with audacity a sine in 64bits to validate the problem.

Octave has a BUG, if you ask it to generate 24 bits, it
generates 32 bits noise ~< -195dbFS, if you ask it to generate 32 bits
it generates 32 bits noise ~< -154 dbFS, don't ask me why.

Here are the measurements.

1234_generator.png


5678_generator.png


Files analyse using "ffmpeg"

formatGeneratorTag.png


We see that 2 generators can be close to -192 dbBFS, octave and sox,
octave can generate 32 bits with -154dBFS of noise as well as audacity and rew.

Counter example ::

I generated a noise of -170dBFS with rew and octave, I can't do it
with audacity and sox.

Rew should have a noise measurement at -154dBFS for octave
at -170 dBFS.

This is not the case, both generate noise at -170dBFS and measure -170dBFS in all 32-bit configurations.

So there is a problem with the "sine function", the -154dBFS stop is
present on 3 generators, so they must have the same type of sine function.

The question ::
Where is the problem really ????


-------------------------------------------------

If you tried the manipulation, do not use rew to measure, rew has a
low measurement stop, which does not prevent it from doing a great job.
The noise stop you will measure will be around -151dBFS for all
signals (wav files).
 
Different rounding somewhere in the calculation, slightly different algorithm, some extra step in between, quantization or not, not generating a full period but skipping last sample, ... To be sure you'd have to check the source code all the way from the core function generating the samples through whatever there might be in between, up until the saving to disk.

Btw for something like this it is actually interesting to look in the time domain: load files in Octave then subtract from each other. If they even are the same length.

they must have the same type of sine function

Not unlikely, but when looking in something like this you cannot make such assumptions based on spectrum alone. Could just well be a slightly different algorithm yielding slightly different sample values but which happen to reach the same level in the frequency domain.
 
So there is a problem with the "sine function", the -154dBFS stop is
maybe the difference between single or double floating point precision?
 
maybe the difference between single or double floating point precision?

Concerning the formats, we see that
even with audacity in 64bits float we have
a noise floor of ~ -154dbFS.

So the format has little importance, we see
in the analysis by "ffmpeg" that it is not correlated
since I generated the signals in all the possible formats of the generators.

pcm_s32le = PCM signed 32 bits Little Indian
pcm_f32le = PCM float 32 ...
pcm_f64le = PCM float 64 ...

Or of course we can generate 16bits using a "pcm_f32le" format, but in our case, how
to explain a generation of noise at -170dBFS other than
by a real generation in 32bits, so the sine is not on the same precision.

Moreover

20*log10(1/2^25.7)= -154.73 dbFS

So we would have a noise with ENOB ~ 25.7 bits

We are very close to 24 bits, we have practically
no interest in switching to 32 bits in many
sine generators.
 
Octave has a BUG, if you ask it to generate 24 bits, it
generates 32 bits noise ~< -195dbFS, if you ask it to generate 32 bits
it generates 32 bits noise ~< -154 dbFS, don't ask me why.
Probably not a bug.
With 24 it generates an integer wav, but apparently for compatibility with matlab it is actually int32 wav, so you get 32-bit noise floor.
With 32 it generates a float32 wav, so you get about 25-bit noise floor.
There's also 64, which generates a float64 (or double) wav.
octave.audiowrite.png


You can also use ffmpeg to generate float64 wav similar to the one from octave:
Code:
ffmpeg -f lavfi -i aevalsrc="0.9996*sin(999.9991*2*PI*t):s=48000:d=10" -c pcm_f64le output.wav
 
Concerning the formats, we see that
even with audacity in 64bits float we have
a noise floor of ~ -154dbFS.

So the format has little importance, we see
in the analysis by "ffmpeg" that it is not correlated
since I generated the signals in all the possible formats of the generators.

pcm_s32le = PCM signed 32 bits Little Indian
pcm_f32le = PCM float 32 ...
pcm_f64le = PCM float 64 ...

Or of course we can generate 16bits using a "pcm_f32le" format, but in our case, how
to explain a generation of noise at -170dBFS other than
by a real generation in 32bits, so the sine is not on the same precision.

Moreover

20*log10(1/2^25.7)= -154.73 dbFS

So we would have a noise with ENOB ~ 25.7 bits

We are very close to 24 bits, we have practically
no interest in switching to 32 bits in many
sine generators.
Single float is approximately 25 bits snr
 
Hello danadam

A good part of the answer is there.

I just saw the behavior.

Concerning 64 bits with octave, the doc
of audiowrite() only gives 16,24,32 bits, I tried
with 64 and it's OK I have exactly your measurement.

I know the generation with ffmpeg and I just tried
your 3 following commands, it's true that I should have started
with that.

ffmpeg -f lavfi -i aevalsrc="0.9996*sin(999.9991*2*PI*t):s=48000:d=10" -c pcm_f64le output.wav -> noise -236 dBFS
ffmpeg -f lavfi -i aevalsrc="0.9996*sin(999.9991*2*PI*t):s=48000:d=10" -c pcm_f32le output.wav -> noise -154.51 dBFS 25bits
ffmpeg -f lavfi -i aevalsrc="0.9996*sin(999.9991*2*PI*t):s=48000:d=10" -c pcm_s32le output.wav -> noise -195.21 dBFS 32bits

As you and Hayabusa message #10 I see for

pcm_f32le -> noise ~25 bits ~ -154 dBFS

Using audioread("file.wav","native") in octave the max value and +1 and -1 (FullScale) in float 32.

float32bits.png


float 32 has only 23 bits of mantissa + the sign which makes 24 bits + the fractional value of the mantissa and
we get 25 bits.

The loop is closed.

Octave makes a mistake when asked for 24 bits since it outputs 32 bits.

I have to transform it via "ffmpeg" to have 24 bits:

ffmpeg -hide_banner -loglevel error -i octave.wav -codec pcm_s24le OUToctaveZZ.wav

But in absolute terms there is no error.

I now understand audacity and Rew, they start
from a pcm_f32le file to generate the pcm_s32le file
and in this case we have 25 bits for the pcm_s32le file.

But if you want a real 32 bits(binary) signal , you need use pcm_s32le format .

Thank you for your insights.
 
Back
Top Bottom