@@ -32,18 +32,19 @@ impl Converter {
3232
3333 // Denormalize and dither
3434 pub fn scale ( & mut self , sample : f32 , factor : i64 ) -> f32 {
35+ let dither = match self . ditherer {
36+ Some ( ref mut d) => d. noise ( ) ,
37+ None => 0.0 ,
38+ } ;
39+
3540 // From the many float to int conversion methods available, match what
3641 // the reference Vorbis implementation uses: sample * 32768 (for 16 bit)
37- let int_value = sample * factor as f32 ;
42+ let int_value = sample * factor as f32 + dither ;
3843
39- // https://doc.rust-lang.org/nomicon/casts.html: casting float to integer
40- // rounds towards zero, then saturates. Ideally halves should round to even to
41- // prevent any bias, but since it is extremely unlikely that a float has
42- // *exactly* .5 as fraction, this should be more than precise enough.
43- match self . ditherer {
44- Some ( ref mut d) => int_value + d. noise ( int_value) ,
45- None => int_value,
46- }
44+ // Casting float to integer rounds towards zero by default, i.e. it
45+ // truncates, and that generates larger error than rounding to nearest.
46+ // Absolute lowest error is gained from rounding ties to even.
47+ math:: round:: half_to_even ( int_value. into ( ) , 0 ) as f32
4748 }
4849
4950 // Special case for samples packed in a word of greater bit depth (e.g.
0 commit comments