mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
be more lenient with negative lpc_errors due to accuracy problems with float
This commit is contained in:
@@ -85,7 +85,7 @@ void FLAC__lpc_compute_lp_coefficients(const real autoc[], unsigned max_order, r
|
|||||||
|
|
||||||
for(i = 0; i < max_order; i++) {
|
for(i = 0; i < max_order; i++) {
|
||||||
/* Sum up this iteration's reflection coefficient. */
|
/* Sum up this iteration's reflection coefficient. */
|
||||||
r =- autoc[i+1];
|
r = -autoc[i+1];
|
||||||
for(j = 0; j < i; j++)
|
for(j = 0; j < i; j++)
|
||||||
r -= lpc[j] * autoc[i-j];
|
r -= lpc[j] * autoc[i-j];
|
||||||
ref[i] = (r/=err);
|
ref[i] = (r/=err);
|
||||||
@@ -101,6 +101,7 @@ void FLAC__lpc_compute_lp_coefficients(const real autoc[], unsigned max_order, r
|
|||||||
lpc[j] += lpc[j] * r;
|
lpc[j] += lpc[j] * r;
|
||||||
|
|
||||||
err *= (1.0 - r * r);
|
err *= (1.0 - r * r);
|
||||||
|
if(err<0.0)fprintf(stderr,"@@@ err went negative, order=%u (%f,%f)\n",i,err,r);
|
||||||
|
|
||||||
/* save this order */
|
/* save this order */
|
||||||
for(j = 0; j <= i; j++)
|
for(j = 0; j <= i; j++)
|
||||||
@@ -112,7 +113,7 @@ void FLAC__lpc_compute_lp_coefficients(const real autoc[], unsigned max_order, r
|
|||||||
int FLAC__lpc_quantize_coefficients(const real lp_coeff[], unsigned order, unsigned precision, unsigned bits_per_sample, int32 qlp_coeff[], int *shift)
|
int FLAC__lpc_quantize_coefficients(const real lp_coeff[], unsigned order, unsigned precision, unsigned bits_per_sample, int32 qlp_coeff[], int *shift)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
real d, cmax = -1e99;
|
real d, cmax = -1e10;
|
||||||
|
|
||||||
assert(bits_per_sample > 0);
|
assert(bits_per_sample > 0);
|
||||||
assert(bits_per_sample <= sizeof(int32)*8);
|
assert(bits_per_sample <= sizeof(int32)*8);
|
||||||
@@ -248,20 +249,39 @@ void FLAC__lpc_restore_signal(const int32 residual[], unsigned data_len, const i
|
|||||||
|
|
||||||
real FLAC__lpc_compute_expected_bits_per_residual_sample(real lpc_error, unsigned total_samples)
|
real FLAC__lpc_compute_expected_bits_per_residual_sample(real lpc_error, unsigned total_samples)
|
||||||
{
|
{
|
||||||
real escale;
|
real error_scale;
|
||||||
|
|
||||||
assert(lpc_error >= 0.0); /* the error can never be negative */
|
|
||||||
assert(total_samples > 0);
|
assert(total_samples > 0);
|
||||||
|
|
||||||
escale = 0.5 * M_LN2 * M_LN2 / (real)total_samples;
|
error_scale = 0.5 * M_LN2 * M_LN2 / (real)total_samples;
|
||||||
|
|
||||||
if(lpc_error > 0.0) {
|
if(lpc_error > 0.0) {
|
||||||
real bps = 0.5 * log(escale * lpc_error) / M_LN2;
|
real bps = 0.5 * log(error_scale * lpc_error) / M_LN2;
|
||||||
if(bps >= 0.0)
|
if(bps >= 0.0)
|
||||||
return bps;
|
return bps;
|
||||||
else
|
else
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate float resolution */
|
||||||
|
return 1e10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
real FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(real lpc_error, real error_scale)
|
||||||
|
{
|
||||||
|
if(lpc_error > 0.0) {
|
||||||
|
real bps = 0.5 * log(error_scale * lpc_error) / M_LN2;
|
||||||
|
if(bps >= 0.0)
|
||||||
|
return bps;
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate float resolution */
|
||||||
|
return 1e10;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
@@ -271,14 +291,18 @@ unsigned FLAC__lpc_compute_best_order(const real lpc_error[], unsigned max_order
|
|||||||
{
|
{
|
||||||
unsigned order, best_order;
|
unsigned order, best_order;
|
||||||
real best_bits, tmp_bits;
|
real best_bits, tmp_bits;
|
||||||
|
const error_scale;
|
||||||
|
|
||||||
assert(max_order > 0);
|
assert(max_order > 0);
|
||||||
|
assert(total_samples > 0);
|
||||||
|
|
||||||
|
error_scale = 0.5 * M_LN2 * M_LN2 / (real)total_samples;
|
||||||
|
|
||||||
best_order = 0;
|
best_order = 0;
|
||||||
best_bits = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[0], total_samples) * (real)total_samples;
|
best_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[0], error_scale) * (real)total_samples;
|
||||||
|
|
||||||
for(order = 1; order < max_order; order++) {
|
for(order = 1; order < max_order; order++) {
|
||||||
tmp_bits = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[order], total_samples) * (real)(total_samples - order) + (real)(order * bits_per_signal_sample);
|
tmp_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[order], error_scale) * (real)(total_samples - order) + (real)(order * bits_per_signal_sample);
|
||||||
if(tmp_bits < best_bits) {
|
if(tmp_bits < best_bits) {
|
||||||
best_order = order;
|
best_order = order;
|
||||||
best_bits = tmp_bits;
|
best_bits = tmp_bits;
|
||||||
|
|||||||
Reference in New Issue
Block a user