return true;
}
+static unsigned silog21_(int v)
+{
+doit_:
+ if(v == 0) {
+ return 0;
+ }
+ else if(v > 0) {
+ unsigned l = 0;
+ while(v) {
+ l++;
+ v >>= 1;
+ }
+ return l+1;
+ }
+ else if(v == -1) {
+ return 2;
+ }
+ else {
+ v = -(++v);
+ goto doit_;
+ }
+}
+
+bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter)
+{
+ unsigned total_bits, val_bits;
+ uint32 pattern;
+unsigned x;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ assert(parameter <= 31);
+
+ val_bits = silog21_(val);
+ total_bits = 2 + parameter + 5 + val_bits;
+
+x=bb->total_bits;
+ if(total_bits <= 32) {
+ pattern = 3;
+ pattern <<= (parameter + 5);
+ pattern |= val_bits;
+ pattern <<= val_bits;
+ pattern |= (val & ((1 << val_bits) - 1));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits))
+ return false;
+ }
+ else {
+ /* write the '-0' escape code first */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, 3u << parameter, 2+parameter))
+ return false;
+ /* write the length */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, val_bits, 5))
+ return false;
+ /* write the value */
+ if(!FLAC__bitbuffer_write_raw_int32(bb, val, val_bits))
+ return false;
+ }
+fprintf(stderr,"wrote %u bits\n",bb->total_bits-x);
+ return true;
+}
+
bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter)
{
unsigned total_bits, interesting_bits, msbs, uval;
return best_residual_bits;
}
-static unsigned iilog2_(unsigned v)
+static unsigned silog21_(int v)
+{
+doit_:
+ if(v == 0) {
+ return 0;
+ }
+ else if(v > 0) {
+ unsigned l = 0;
+ while(v) {
+ l++;
+ v >>= 1;
+ }
+ return l+1;
+ }
+ else if(v == -1) {
+ return 2;
+ }
+ else {
+ v = -(++v);
+ goto doit_;
+ }
+}
+
+static unsigned uilog21_(unsigned v)
{
unsigned l = 0;
- assert(v > 0);
- while(v >>= 1)
+ while(v) {
l++;
+ v >>= 1;
+ }
return l;
}
+const double smult = 3.0;
+const unsigned rpdec = 0;
+
static uint32 get_thresh_(const int32 residual[], const unsigned residual_samples)
{
double sum, sos, r, stddev, mean;
- const double smult = 2.0;
unsigned i;
uint32 thresh;
mean = sum / residual_samples;
stddev = sqrt((sos - (sum * sum / residual_samples)) / (residual_samples-1));
thresh = mean+smult*stddev;
- thresh = iilog2_(thresh);
+ thresh = (1u << uilog21_(thresh)) - 1;
return thresh;
}
if(partition_order == 0) {
unsigned i;
+#ifdef SYMMETRIC_RICE
uint32 thresh = get_thresh_(residual, residual_samples);
- const unsigned rpdec = 1;
bool cross = false;
-#ifdef SYMMETRIC_RICE
for(i=0;i<residual_samples;i++) {
if(abs_residual[i] >= thresh) {
cross = true;
for(i = 0; i < residual_samples; i++) {
#ifdef VARIABLE_RICE_BITS
#ifdef SYMMETRIC_RICE
- if(cross && abs_residual[i] >= thresh)
- bits_ += VARIABLE_RICE_BITS(0, rice_parameter) + 5 + iilog2_(abs_residual) + 1;
- else
+ if(cross) {
+ unsigned escbits, normbits;
+ escbits = /* VARIABLE_RICE_BITS(0, rice_parameter) == 0 */ 5 + silog21_(residual[i]);
+ normbits = VARIABLE_RICE_BITS(abs_residual[i], rice_parameter);
+ bits += min(escbits, normbits);
+ }
+ else {
+ /*@@@ old way */
bits_ += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter);
+ }
#else
bits_ += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter_estimate);
#endif
#include <assert.h>
#include <stdio.h>
+#include <math.h>
#include "private/encoder_framing.h"
#include "private/crc.h"
return true;
}
+static unsigned silog21_(int v)
+{
+doit_:
+ if(v == 0) {
+ return 0;
+ }
+ else if(v > 0) {
+ unsigned l = 0;
+ while(v) {
+ l++;
+ v >>= 1;
+ }
+ return l+1;
+ }
+ else if(v == -1) {
+ return 2;
+ }
+ else {
+ v = -(++v);
+ goto doit_;
+ }
+}
+
+static unsigned uilog21_(unsigned v)
+{
+ unsigned l = 0;
+ while(v) {
+ l++;
+ v >>= 1;
+ }
+ return l;
+}
+
+extern const double smult;
+
+static uint32 get_thresh_(const int32 residual[], const unsigned residual_samples)
+{
+ double sum, sos, r, stddev, mean;
+ unsigned i;
+ uint32 thresh;
+
+ sum = sos = 0.0;
+ for(i = 0; i < residual_samples; i++) {
+ r = (double)residual[i];
+ sum += r;
+ sos += r*r;
+ }
+ mean = sum / residual_samples;
+ stddev = sqrt((sos - (sum * sum / residual_samples)) / (residual_samples-1));
+ thresh = mean+smult*stddev;
+ thresh = (1u << uilog21_(thresh)) - 1;
+ return thresh;
+}
+
bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned partition_order)
{
if(partition_order == 0) {
unsigned i;
+#ifdef SYMMETRIC_RICE
+ uint32 thresh = get_thresh_(residual, residual_samples);
+ bool cross = false;
+
+ for(i=0;i<residual_samples;i++) {
+ uint32 a = (residual[i] < 0? -residual[i] : residual[i]);
+ if(a >= thresh) {
+ cross = true;
+ break;
+ }
+ }
+#endif
+
if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
return false;
for(i = 0; i < residual_samples; i++) {
#ifdef SYMMETRIC_RICE
- if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
- return false;
+ if(cross) {
+ unsigned escbits, normbits;
+ uint32 a = (residual[i] < 0? -residual[i] : residual[i]);
+ escbits = 5 + silog21_(residual[i]);
+ normbits = a >> rice_parameters[0];
+ if(escbits < normbits) {
+fprintf(stderr,"ESCAPE, k=%u, r=%d, saved %u bits\n", rice_parameters[0], residual[i], normbits-escbits);
+ if(!FLAC__bitbuffer_write_symmetric_rice_signed_escape(bb, residual[i], rice_parameters[0]))
+ return false;
+ }
+ else {
+ if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
+ return false;
+ }
+ }
+ else {
+ if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
+ return false;
+ }
#else
if(!FLAC__bitbuffer_write_rice_signed(bb, residual[i], rice_parameters[0]))
return false;