Re: dither on export (bug 22)
Posted: Wed Mar 07, 2012 11:22 pm
Converting from float to int by truncating sounds wrong on many levels
I can't properly understand what truncate means in this context...
For questions, answers and opinions
https://forum.audacityteam.org/
rounding down.bgravato wrote:I can't properly understand what truncate means in this context...
It's something like:bgravato wrote:what could it mean to truncate a float and get an int without float->int conversion?
Multiplying and rounding is not truncating... it's multiplying and roundingsteve wrote:It's something like:bgravato wrote:what could it mean to truncate a float and get an int without float->int conversion?
Multiply the original 32 bit float value by 2^23 then round down to get the signed 24 bit integer.
In 32 bit float notation, 0 dB is +/- 1
In 24 bit integer notation, 0 dB is +/- 2^23
Those lines were last modified in 2002 (around the time of 1.0.0) when there was no sample format preference. 1.2.0 (2004) had the 24-bit format preference.steve wrote:It looks like that was written at a time when there was no 24 bit option. Has there ever been such a time?Gale Andrews wrote:From ImportPCM.cpp:Code: Select all
// In general, go with the user's preferences. However, if // the file is higher-quality, go with a format which preserves // the quality of the original file. if (mFormat != floatSample && sf_subtype_more_than_16_bits(mInfo.format)) mFormat = floatSample;
Is it possible to be a bit more definitive e.g. by testing this in 1.2.6 and HEAD and comparing sample values like for like?steve wrote:It looks to me like 24 bit files are converted to 32 bit float (surprising perhaps, but perhaps not a "bad" thing), but then on Export to 24 bit, the sample values are truncated to 24 bit. Export should properly convert to 24 bit (with dither if enabled) and not just truncated to 24 bit.
I think all that was about the Manual stating that Audacity "by default" processed internally at 32-bit, when in truth it always does that irrespective of the sample format of the audio - there is no option.steve wrote:@Gale - I vaguely recall some fuss a long time ago about something in the manual that said that converting from 32 bit float to 24 bit integer was done by truncating. Do you remember that? Does it relate to this issue?
Yes, certainly.Gale Andrews wrote:Is it possible to be a bit more definitive
Sadly no, because there was a different bug in early versions of Audacity that caused 24 bit sample values to be calculated incorrectly and that didn't get fixed until well into 1.3.x versions.Gale Andrews wrote: e.g. by testing this in 1.2.6 and HEAD and comparing sample values like for like?
Code: Select all
;; generate ramp with one sample at each 24 bit value
(abs-env
(control-srate-abs *sound-srate*
(pwlv -1 (/ (power 2 24) *sound-srate*) 1)))Code: Select all
;; print 24 bit value for x number of sample
(setq x 20)
(setq *float-format* "%1.1f")
(setq output "")
(dotimes (i x)
(setq output
(format nil "~a~%~a" output
(* (power 2 23)(snd-fetch s)))))
(print output)Code: Select all
2195392.0
2195393.0
2195394.0
2195395.0
2195396.0
2195397.0
2195398.0
2195399.0
2195400.0
2195401.0Code: Select all
-5742608.0
-5742607.0
-5742606.0
-5742605.0
-5742604.0
-5742603.0
-5742602.0
-5742601.0
-5742600.0
-5742599.0Code: Select all
2195392.0
2195393.0
2195394.0
2195394.0
2195396.0
2195398.0
2195398.0
2195399.0
2195400.0
2195400.0Code: Select all
2195392.0
2195393.0
2195394.0
2195395.0
2195396.0
2195397.0
2195398.0
2195399.0
2195400.0
2195401.0Code: Select all
2195392.0
2195393.0
2195394.0
2195395.0
2195396.0
2195397.0
2195398.0
2195399.0
2195400.0
2195401.0Code: Select all
;; generate ramp from -0.25 to +0.25
(abs-env
(control-srate-abs *sound-srate*
(pwlv -0.25 (/ (power 2 24) *sound-srate*) 0.25)))Code: Select all
548848.00
548848.25
548848.50
548848.75
548849.00
548849.25
548849.50
548849.75
548850.00
548850.25Code: Select all
548848.00
548848.00
548848.00
548848.00
548849.00
548849.00
548849.00
548849.00
548850.00
548850.00Code: Select all
548848.00
548848.00
548848.00
548848.00
548849.00
548849.00
548849.00
548849.00
548850.00
548850.00Thanks for the tests.steve wrote:The samples test as sequential half-integer values. Example output from 4min into the track :
7) Export the track from test 6 as 24 bit with dither = none.Code: Select all
548848.00 548848.25 548848.50 548848.75 548849.00
I would have expected integer results rounded to the nearest value but we actually get rounded down values.
Example output from 4min into the track :
Code: Select all
548848.00 548848.00 548848.00 548848.00 548849.00
Mathematically speaking "rounding" rounds to the nearest integer. Therefore ".00" through ".49" should round down to ".00" and ".50" through ".99" should round up to next ".00"Gale Andrews wrote:...what direction should the rounding go in?...