summaryrefslogtreecommitdiffstats
path: root/libFLAC/lpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libFLAC/lpc.c')
-rw-r--r--libFLAC/lpc.c126
1 files changed, 50 insertions, 76 deletions
diff --git a/libFLAC/lpc.c b/libFLAC/lpc.c
index 0356867..f7c643a 100644
--- a/libFLAC/lpc.c
+++ b/libFLAC/lpc.c
@@ -1,5 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
+ * Copyright (C) 2000-2009 Josh Coalson
+ * Copyright (C) 2011-2014 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,29 +30,39 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
+
#include "FLAC/assert.h"
#include "FLAC/format.h"
+#include "share/compat.h"
#include "private/bitmath.h"
#include "private/lpc.h"
+#include "private/macros.h"
#if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
#include <stdio.h>
#endif
-#ifndef FLAC__INTEGER_ONLY_LIBRARY
-
-#ifndef M_LN2
-/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
-#define M_LN2 0.69314718055994530942
-#endif
-
/* OPT: #undef'ing this may improve the speed on some architectures */
#define FLAC__LPC_UNROLLED_FILTER_LOOPS
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+
+#if !defined(HAVE_LROUND)
+#if defined(_MSC_VER)
+#include <float.h>
+#define copysign _copysign
+#elif defined(__GNUC__)
+#define copysign __builtin_copysign
+#endif
+static inline long int lround(double x) {
+ return (long)(x + copysign (0.5, x));
+}
+/* If this fails, we are in the presence of a mid 90's compiler, move along... */
+#endif
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
{
@@ -112,7 +123,7 @@ void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_le
void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[])
{
unsigned i, j;
- FLAC__double r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER];
+ FLAC__double r, err, lpc[FLAC__MAX_LPC_ORDER];
FLAC__ASSERT(0 != max_order);
FLAC__ASSERT(0 < *max_order);
@@ -126,7 +137,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o
r = -autoc[i+1];
for(j = 0; j < i; j++)
r -= lpc[j] * autoc[i-j];
- ref[i] = (r/=err);
+ r /= err;
/* Update LPC coefficients and total error. */
lpc[i]=r;
@@ -145,7 +156,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o
lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
error[i] = err;
- /* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */
+ /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */
if(err == 0.0) {
*max_order = i+1;
return;
@@ -200,14 +211,8 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
FLAC__int32 q;
for(i = 0; i < order; i++) {
error += lp_coeff[i] * (1 << *shift);
-#if 1 /* unfortunately lround() is C99 */
- if(error >= 0.0)
- q = (FLAC__int32)(error + 0.5);
- else
- q = (FLAC__int32)(error - 0.5);
-#else
q = lround(error);
-#endif
+
#ifdef FLAC__OVERFLOW_DETECT
if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */
fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]);
@@ -235,14 +240,7 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
#endif
for(i = 0; i < order; i++) {
error += lp_coeff[i] / (1 << nshift);
-#if 1 /* unfortunately lround() is C99 */
- if(error >= 0.0)
- q = (FLAC__int32)(error + 0.5);
- else
- q = (FLAC__int32)(error - 0.5);
-#else
q = lround(error);
-#endif
#ifdef FLAC__OVERFLOW_DETECT
if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */
fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]);
@@ -262,7 +260,12 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
return 0;
}
-void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
+#if defined(_MSC_VER)
+// silence MSVC warnings about __restrict modifier
+#pragma warning ( disable : 4028 )
+#endif
+
+void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo;
@@ -285,13 +288,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u
for(j = 0; j < order; j++) {
sum += qlp_coeff[j] * (*(--history));
sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
-#if defined _MSC_VER
- if(sumo > 2147483647I64 || sumo < -2147483648I64)
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
-#else
- if(sumo > 2147483647ll || sumo < -2147483648ll)
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo);
-#endif
+ fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo);
}
*(residual++) = *(data++) - (sum >> lp_quantization);
}
@@ -528,7 +525,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u
}
#endif
-void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
+void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
unsigned i, j;
@@ -549,19 +546,11 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
for(j = 0; j < order; j++)
sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
-#if defined _MSC_VER
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization);
-#else
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization));
-#endif
+ fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization));
break;
}
if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
-#if defined _MSC_VER
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%I64d, residual=%I64d\n", i, *data, sum >> lp_quantization, (FLAC__int64)(*data) - (sum >> lp_quantization));
-#else
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%lld, residual=%lld\n", i, *data, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*data) - (sum >> lp_quantization)));
-#endif
+ fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization)));
break;
}
*(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization);
@@ -792,7 +781,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
+void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo;
@@ -815,15 +804,8 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c
for(j = 0; j < order; j++) {
sum += qlp_coeff[j] * (*(--history));
sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
-#ifdef FLAC__OVERFLOW_DETECT_VERBOSE
-#if defined _MSC_VER
- if(sumo > 2147483647I64 || sumo < -2147483648I64)
- fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
-#else
if(sumo > 2147483647ll || sumo < -2147483648ll)
- fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo);
-#endif
-#endif
+ fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo);
}
*(data++) = *(r++) + (sum >> lp_quantization);
}
@@ -1060,7 +1042,7 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c
}
#endif
-void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
+void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data)
#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
unsigned i, j;
@@ -1081,23 +1063,11 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
for(j = 0; j < order; j++)
sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
-#ifdef FLAC__OVERFLOW_DETECT_VERBOSE
-#ifdef _MSC_VER
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization);
-#else
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization));
-#endif
-#endif
+ fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization));
break;
}
if(FLAC__bitmath_silog2_wide((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) {
-#ifdef FLAC__OVERFLOW_DETECT_VERBOSE
-#ifdef _MSC_VER
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%I64d, data=%I64d\n", i, *r, sum >> lp_quantization, (FLAC__int64)(*r) + (sum >> lp_quantization));
-#else
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%lld, data=%lld\n", i, *r, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*r) + (sum >> lp_quantization)));
-#endif
-#endif
+ fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization)));
break;
}
*(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization);
@@ -1326,6 +1296,10 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
}
#endif
+#if defined(_MSC_VER)
+#pragma warning ( default : 4028 )
+#endif
+
#ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)
@@ -1334,7 +1308,7 @@ FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lp
FLAC__ASSERT(total_samples > 0);
- error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
+ error_scale = 0.5 / (FLAC__double)total_samples;
return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale);
}
@@ -1358,26 +1332,26 @@ FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scal
unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order)
{
- unsigned order, index, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */
+ unsigned order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */
FLAC__double bits, best_bits, error_scale;
FLAC__ASSERT(max_order > 0);
FLAC__ASSERT(total_samples > 0);
- error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
+ error_scale = 0.5 / (FLAC__double)total_samples;
best_index = 0;
best_bits = (unsigned)(-1);
- for(index = 0, order = 1; index < max_order; index++, order++) {
- bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[index], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order);
+ for(indx = 0, order = 1; indx < max_order; indx++, order++) {
+ bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order);
if(bits < best_bits) {
- best_index = index;
+ best_index = indx;
best_bits = bits;
}
}
- return best_index+1; /* +1 since index of lpc_error[] is order-1 */
+ return best_index+1; /* +1 since indx of lpc_error[] is order-1 */
}
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */