#endif
#define max(x,y) ((x)>(y)?(x):(y))
-#ifdef ESTIMATE_RICE_BITS
-#undef ESTIMATE_RICE_BITS
-#endif
-#define ESTIMATE_RICE_BITS(value, parameter) (2 + (parameter) + (((unsigned)((value) < 0? -(value) : (value))) >> (parameter)))
-
typedef struct FLAC__EncoderPrivate {
unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */
int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */
real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */
real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */
int32 *residual[2]; /* where the candidate and best subframe residual signals will be stored */
+ uint32 *abs_residual; /* workspace where the abs(candidate residual) is stored */
unsigned best_residual; /* index into the above */
FLAC__BitBuffer frame; /* the current frame being worked on */
FLAC__BitBuffer frame_mid_side; /* special parallel workspace for the mid-side coded version of the current frame */
static bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame);
static bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, const FLAC__FrameHeader *frame_header, unsigned channels, const int32 *integer_signal[], const real *real_signal[], FLAC__BitBuffer *bitbuffer);
static unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_per_sample, FLAC__SubframeHeader *subframe);
-static unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
-static unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
+static unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
+static unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
static unsigned encoder_evaluate_verbatim_subframe_(unsigned blocksize, unsigned bits_per_sample, FLAC__SubframeHeader *subframe);
-static unsigned encoder_find_best_partition_order_(int32 residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[]);
+static unsigned encoder_find_best_partition_order_(const int32 residual[], uint32 abs_residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[]);
static bool encoder_generate_constant_subframe_(const FLAC__SubframeHeader *header, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
static bool encoder_generate_fixed_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
static bool encoder_generate_lpc_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
static bool encoder_generate_verbatim_subframe_(const FLAC__SubframeHeader *header, const int32 signal[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
static void encoder_promote_candidate_subframe_(FLAC__Encoder *encoder);
-static bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits);
+static bool encoder_set_partitioned_rice_(const uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits);
const char *FLAC__EncoderWriteStatusString[] = {
"FLAC__ENCODER_WRITE_OK",
int32 *previous_is, *current_is;
real *previous_rs, *current_rs;
int32 *residual;
+ uint32 *abs_residual;
assert(new_size > 0);
assert(encoder->state == FLAC__ENCODER_OK);
encoder->guts->residual[i] = residual;
}
}
+ abs_residual = (uint32*)malloc(sizeof(uint32) * new_size);
+ if(0 == residual) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ if(encoder->guts->abs_residual != 0)
+ free(encoder->guts->abs_residual);
+ encoder->guts->abs_residual = abs_residual;
+ }
}
if(ok)
encoder->guts->input_capacity = new_size;
}
encoder->guts->residual[0] = 0;
encoder->guts->residual[1] = 0;
+ encoder->guts->abs_residual = 0;
encoder->guts->best_residual = 0;
encoder->guts->current_frame_can_do_mid_side = true;
encoder->guts->current_sample_number = 0;
encoder->guts->residual[i] = 0;
}
}
+ if(encoder->guts->abs_residual != 0) {
+ free(encoder->guts->abs_residual);
+ encoder->guts->abs_residual = 0;
+ }
FLAC__bitbuffer_free(&encoder->guts->frame);
free(encoder->guts);
encoder->guts = 0;
rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+1.5) : 0;
if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
- candidate_bits = encoder_evaluate_fixed_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], frame_header->blocksize, frame_header->bits_per_sample, fixed_order, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
+ candidate_bits = encoder_evaluate_fixed_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], encoder->guts->abs_residual, frame_header->blocksize, frame_header->bits_per_sample, fixed_order, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
if(candidate_bits < best_bits) {
encoder_promote_candidate_subframe_(encoder);
best_bits = candidate_bits;
if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) {
- candidate_bits = encoder_evaluate_lpc_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], lp_coeff[lpc_order-1], frame_header->blocksize, frame_header->bits_per_sample, lpc_order, qlp_coeff_precision, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
+ candidate_bits = encoder_evaluate_lpc_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], encoder->guts->abs_residual, lp_coeff[lpc_order-1], frame_header->blocksize, frame_header->bits_per_sample, lpc_order, qlp_coeff_precision, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
if(candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
if(candidate_bits < best_bits) {
encoder_promote_candidate_subframe_(encoder);
return FLAC__SUBFRAME_HEADER_TYPE_LEN + bits_per_sample;
}
-unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
+unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
{
unsigned i, residual_bits;
const unsigned residual_samples = blocksize - order;
subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
- residual_bits = encoder_find_best_partition_order_(residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters);
+ residual_bits = encoder_find_best_partition_order_(residual, abs_residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters);
subframe->data.fixed.order = order;
for(i = 0; i < order; i++)
return FLAC__SUBFRAME_HEADER_TYPE_LEN + (order * bits_per_sample) + residual_bits;
}
-unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
+unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
{
int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
unsigned i, residual_bits;
subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
- residual_bits = encoder_find_best_partition_order_(residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.parameters);
+ residual_bits = encoder_find_best_partition_order_(residual, abs_residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.parameters);
subframe->data.lpc.order = order;
subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
return FLAC__SUBFRAME_HEADER_TYPE_LEN + (blocksize * bits_per_sample);
}
-unsigned encoder_find_best_partition_order_(int32 residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
+unsigned encoder_find_best_partition_order_(const int32 residual[], uint32 abs_residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
{
unsigned residual_bits, best_residual_bits = 0;
- unsigned partition_order;
+ unsigned i, partition_order;
unsigned best_parameters_index = 0, parameters[2][1 << FLAC__MAX_RICE_PARTITION_ORDER];
+ int32 r;
+
+ /* compute the abs(residual) for use later */
+ for(i = 0; i < residual_samples; i++) {
+ r = residual[i];
+ abs_residual[i] = (uint32)(r<0? -r : r);
+ }
for(partition_order = 0; partition_order <= max_partition_order; partition_order++) {
- if(!encoder_set_partitioned_rice_(residual, residual_samples, predictor_order, rice_parameter, partition_order, parameters[!best_parameters_index], &residual_bits)) {
+ if(!encoder_set_partitioned_rice_(abs_residual, residual_samples, predictor_order, rice_parameter, partition_order, parameters[!best_parameters_index], &residual_bits)) {
assert(best_residual_bits != 0);
break;
}
encoder->guts->best_residual = !encoder->guts->best_residual;
}
-bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits)
+#ifdef ESTIMATE_RICE_BITS
+#undef ESTIMATE_RICE_BITS
+#endif
+#define ESTIMATE_RICE_BITS(value, parameter) ((value) >> (parameter))
+
+bool encoder_set_partitioned_rice_(const uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits)
{
unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
unsigned i;
#ifdef ESTIMATE_RICE_BITS
const unsigned rice_parameter_estimate = rice_parameter-1;
+ bits_ += (1+rice_parameter) * residual_samples;
#endif
parameters[0] = rice_parameter;
bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
for(i = 0; i < residual_samples; i++)
#ifdef ESTIMATE_RICE_BITS
- bits_ += ESTIMATE_RICE_BITS(residual[i], rice_parameter_estimate);
+ bits_ += ESTIMATE_RICE_BITS(abs_residual[i], rice_parameter_estimate);
#else
bits_ += FLAC__bitbuffer_rice_bits(residual[i], rice_parameter);
#endif
}
mean = partition_samples >> 1;
for(j = 0; j < partition_samples; j++, k++)
- mean += ((residual[k] < 0)? (unsigned)(-residual[k]) : (unsigned)residual[k]);
+ mean += abs_residual[k];
mean /= partition_samples;
/* calc parameter = floor(log2(mean)) + 1 */
parameter = 0;
parameters[i] = parameter;
bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
#ifdef ESTIMATE_RICE_BITS
+ bits_ += (1+parameter) * partition_samples;
--parameter;
#endif
for(j = k_last; j < k; j++)
#ifdef ESTIMATE_RICE_BITS
- bits_ += ESTIMATE_RICE_BITS(residual[j], parameter);
+ bits_ += ESTIMATE_RICE_BITS(abs_residual[j], parameter);
#else
bits_ += FLAC__bitbuffer_rice_bits(residual[j], parameter);
#endif