[Flac-dev] FLAC 24 bit test results

Miroslav Lichvar lichvarm at phoenix.inf.upol.cz
Sun Apr 8 12:17:23 PDT 2007


On Thu, Apr 05, 2007 at 06:48:06PM +0200, Josh Green wrote:
> It seems that generally Wavpack does a little better than FLAC at
> compressing audio.  But that is generally within a rather small margin.
> 20% margin seems a little large to me though.  There may indeed be no
> problem with the FLAC reference implementation in regards to 24 bit and
> its just having trouble compressing certain types of audio that Wavpack
> does much better on.  But I think its worth having an understanding of
> what exactly is going on, in case there is something that can be
> improved in the FLAC reference implementation.

Problem is that the samples have huge amount of noise. The FLAC format
allows the maximum value of the rice parameter to be 14 and that's
preventing the encoder from storing the residual signal effectively.

Fortunately, the format also allows to skip the rice coding and store
the residual signal unencoded. The encoder can do this, but it was
disabled some time ago as it didn't have any benefit on 16bit files,
iirc.

Attached is a patch that enables the escaping when the rice parameter
was clipped. With flac -8 --no-padding I'm getting compression ratio
90.3% for the grasshopper sample.

-- 
Miroslav Lichvar
-------------- next part --------------
Index: src/libFLAC/stream_encoder.c
===================================================================
RCS file: /cvsroot/flac/flac/src/libFLAC/stream_encoder.c,v
retrieving revision 1.136
diff -u -r1.136 stream_encoder.c
--- src/libFLAC/stream_encoder.c	4 Apr 2007 01:08:24 -0000	1.136
+++ src/libFLAC/stream_encoder.c	8 Apr 2007 18:51:58 -0000
@@ -2284,8 +2284,7 @@
 	/* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */
 	/*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */
 	ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums);
-	if(encoder->protected_->do_escape_coding)
-		ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition);
+	ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition);
 
 	/* now adjust the windows if the blocksize has changed */
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
@@ -3170,6 +3169,7 @@
 	unsigned rice_parameter;
 	unsigned _candidate_bits, _best_bits;
 	unsigned _best_subframe;
+	FLAC__bool do_escape_coding = encoder->protected_->do_escape_coding;
 
 	FLAC__ASSERT(frame_header->blocksize > 0);
 
@@ -3237,6 +3237,7 @@
 						fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
 #endif
 						rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+						do_escape_coding = true;
 					}
 					_candidate_bits =
 						evaluate_fixed_subframe_(
@@ -3251,7 +3252,7 @@
 							rice_parameter,
 							min_partition_order,
 							max_partition_order,
-							encoder->protected_->do_escape_coding,
+							do_escape_coding,
 							encoder->protected_->rice_parameter_search_dist,
 							subframe[!_best_subframe],
 							partitioned_rice_contents[!_best_subframe]
@@ -3308,6 +3309,7 @@
 									fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
 #endif
 									rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
+									do_escape_coding = true;
 								}
 								if(encoder->protected_->do_qlp_coeff_prec_search) {
 									min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
@@ -3338,7 +3340,7 @@
 											rice_parameter,
 											min_partition_order,
 											max_partition_order,
-											encoder->protected_->do_escape_coding,
+											do_escape_coding,
 											encoder->protected_->rice_parameter_search_dist,
 											subframe[!_best_subframe],
 											partitioned_rice_contents[!_best_subframe]


More information about the Flac-dev mailing list