The actual value of PI is:
3.141592653589793238462643383279502884197169399375105…
so the value returned by Nyquist is only accurate to 14 decimal places.
3.14159265358979
(setf *float-format* "%.1000g")
(print (- pi 3.14159265358979))
; returns 0
The binary representation of 3.141592653589790007373494518105871975421905517578125 is
01000000010010010000111111011011
The binary representation of 3.14159265 is
01000000010010010000111111011011
Note that these two binary numbers are identical. So in this particular case, digits beyond 8 decimal places are irrelevant.
I have tested the thing incorrectly (because I changed the number manually in the text file, and as you said and your article, there are many decimal values which cannot be exactly represented in 32-bit float), sorry…
If my files are equal or less than 32-bit float (= 24-bit, 16-bit), 48000 Hz, 2 channels, with
(setf *float-format* "%.1000g")
in Sample Data Export, Sample Data Import will put the values into Audacity, and all this processing is “bit-perfect”/lossless, right?
With integer formats the whole thing becomes a lot more straightforward.
Example - 24-bit (integer):
The range of sample values is +/- 1.0 (* see below)
There are 2^24 24-bit numbers (= 16777216 discrete values)
“Normal” digital audio is PCM encoded, which divides the range +/- 1 into equal parts.
That gives 16777216 “steps” of 2/16777216. 8388608 are negative values, 8388607 are positive values, and there is zero. (** see below)
The range is actually -1 to (1 - 1/8388607) because there is 1 less positive value than negative values.
** The waveform does not actually rise and fall in “steps” (https://www.xiph.org/video/vid2.shtml)
So we know that for 24-bit audio, the theoretically maximum precision is to the closest 1/8388607 = 0.000000119, so 7 decimal places is sufficient to give us the correct binary value (bit perfect).
Also worth noting that even the best studio sound cards cannot achieve 24 bit accuracy. The bottom couple of bits are just noise, so even a studio quality 24-bit sound card can achieve no better than about 22-bit accuracy. But that’s not a problem because even “only” 22-bits is enough for fantastically high quality audio.
Is it possible to use Sample Data Export to export 24-bit values (I have a file which is in 24-bit)? Or configure Audacity to not convert to 32-bit float?
Audacity and Nyquist process in 32-bit float format regardless of the bit format.
Converting from 24-bit integer to 32-bit float is lossless because 32-bit float can represent 24-bit audio exactly, which means that the round trip from “24-bit → 32-bit float → 24-bit” is lossless (bit perfect).
There’s really no up-side to using 24-bit integer (compared with 32-bit float), other than saving a bit of space in file storage.
I show you how I represent the process in my mind:
– I have a WAV file, 24-bit / 48000 Hz / 2 channels;
– I import it into Audacity (all the settings are by default, except I changed the sample rate to 48000 Hz);
– I export it as WAV file, 24-bit;
– I think it will not be the same file as the original.
That’s true, but it is not the full picture.
If you export a track to a different file format, then yes the file format has to be converted, but regardless of the track format and export format, the audio data is ‘mixed down’ in 32-bit float and then converted to the export format.
It means dithering is applied, so there is no more “bit-perfect”/lossless! Or does this happen only if the source bit-depth + sample rate are different from the export settings?
Yes it does, unless you turn off dither in preferences. Unfortunately Audacity is a bit overenthusiastic about applying dither, and could be a lot smarter.
So, I can disable dither if (non-exhaustive list, but I will probably only do these actions):
input and output file have the same bit-depth + sample rate + number of channels, only if:
→ I simply import/export with the same characteristics (= “bit-perfect”/lossless)
→ I remove and/or move and/or copy parts of this sound file, regardless of the channel (= lossless)
→ Add silence (= lossless)
output file has an equal or bigger bit-depth (but less than 32-bit float for this case) than the input file with the same sample rate + number of channels, only if:
→ I simply import/export with the same characteristics (= lossless)
→ I remove and/or move and/or copy parts of this sound file, regardless of the channel (= lossless)
→ Add silence (= lossless)
output file is 32-bit float (whatever modifications I can make) = lossless
→ but I think dither is already disabled for the last point
The ‘rule’ about when to apply dither is very simple:
“Apply dither when converting to less bits per sample”.
Audacity does this by default.
The catch:
Audacity processes in 32-bit float format, so if the track is less than 32-bit float, then processing the track in any way will involve a conversion from the track format, to 32-bit float and back to track format. By default, Audacity applies dither during the second conversion (32 → 16 or 32 → 24). “Processing” does not include simple edits such as cut / paste / delete. “Processing” means anything that changes sample values.
The second catch:
Most of the exporters (the code that turns the raw audio data into an audio file) work in 32-bit float, so exporting to less than 32-bits will have dither applied by default. There are some exceptions to this: some of the lossy compressed formats (notably MP3) don’t apply dither, but in this case it is not really relevant as losses due to encoding are more significant than whether dither has been applied or not.
Thank you. But it does not mention the silence, and I think adding silence does not require dithering. Or it depends where the silence is added, like adding silence at the beginning and/or end of the track, so dithering is not necessary. But adding silence elsewhere than at the beginning and/or end require dithering?