Improve compute_residual_from_qlp_coefficients datapath selection

This bases the selection of the datapath on the actual predictor
coefficients instead of on the predictor coefficient precision
This commit is contained in:
Martijn van Beurden 2022-05-27 20:38:33 +02:00
parent dd4a263406
commit 6b2fc739ed
4 changed files with 32 additions and 2 deletions

View File

@ -96,6 +96,9 @@ void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14(const FLAC__real data[
#endif
#endif /* FLAC__NO_ASM */
uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order);
uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization);
/*
* FLAC__lpc_compute_lp_coefficients()
* --------------------------------------------------------------------

View File

@ -35,6 +35,7 @@
#endif
#include <math.h>
#include <stdlib.h>
#include "FLAC/assert.h"
#include "FLAC/format.h"
@ -259,6 +260,31 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order,
return 0;
}
uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order)
{
/* This used to be subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order)
* but that treats both the samples as well as the predictor as unknown. The
* predictor is known however, so taking the log2 of the sum of the absolute values
* of all coefficients is a more accurate representation of the predictor */
FLAC__int32 abs_sum_of_qlp_coeff = 0;
for(uint32_t i = 0; i < order; i++)
abs_sum_of_qlp_coeff += abs(qlp_coeff[i]);
if(abs_sum_of_qlp_coeff == 0)
abs_sum_of_qlp_coeff = 1;
return subframe_bps + FLAC__bitmath_silog2(abs_sum_of_qlp_coeff);
}
uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization)
{
FLAC__int32 predictor_sum_bps = FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) - lp_quantization;
if((int)subframe_bps > predictor_sum_bps)
return subframe_bps + 1;
else
return predictor_sum_bps + 1;
}
#if defined(_MSC_VER)
// silence MSVC warnings about __restrict modifier
#pragma warning ( disable : 4028 )

View File

@ -2797,7 +2797,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui
/* decode the subframe */
if(do_full_decode) {
memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
if(FLAC__lpc_max_residual_bps(bps, subframe->qlp_coeff, order, subframe->quantization_level) <= 32 &&
FLAC__lpc_max_prediction_before_shift_bps(bps, subframe->qlp_coeff, order) <= 32)
FLAC__lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
else
FLAC__lpc_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);

View File

@ -3865,7 +3865,7 @@ uint32_t evaluate_lpc_subframe_(
if(ret != 0)
return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
if(FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) <= 32)
if(subframe_bps <= 16 && qlp_coeff_precision <= 16)
encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
else