summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Beurden <mvanb1@gmail.com>2022-04-04 20:21:41 +0200
committerMartijn van Beurden <mvanb1@gmail.com>2022-06-12 18:38:21 +0200
commit0fe187b54511b575892fb38e01d8e2ab809fb0fe (patch)
treec62147020a216f8714a77b7aa1f9adf4b6c320cb
parent9df24ac202149214a170e105604a35e04e65be15 (diff)
downloadflac-0fe187b54511b575892fb38e01d8e2ab809fb0fe.tar.gz
Add 32-bit encoding, including limiting of residual to 32-bit int
-rw-r--r--src/flac/encode.c45
-rw-r--r--src/flac/main.c4
-rw-r--r--src/libFLAC/bitwriter.c10
-rw-r--r--src/libFLAC/fixed.c180
-rw-r--r--src/libFLAC/include/private/bitwriter.h1
-rw-r--r--src/libFLAC/include/private/fixed.h6
-rw-r--r--src/libFLAC/include/private/lpc.h4
-rw-r--r--src/libFLAC/include/private/memory.h1
-rw-r--r--src/libFLAC/lpc.c145
-rw-r--r--src/libFLAC/memory.c29
-rw-r--r--src/libFLAC/stream_encoder.c225
-rw-r--r--src/libFLAC/stream_encoder_framing.c29
12 files changed, 594 insertions, 85 deletions
diff --git a/src/flac/encode.c b/src/flac/encode.c
index 85279f2a..5f616689 100644
--- a/src/flac/encode.c
+++ b/src/flac/encode.c
@@ -1027,7 +1027,7 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, encoder_session.info.sample_rate);
return EncoderSession_finish_error(&encoder_session);
}
- if(encoder_session.info.bits_per_sample-encoder_session.info.shift < 4 || encoder_session.info.bits_per_sample-encoder_session.info.shift > 24) {
+ if(encoder_session.info.bits_per_sample-encoder_session.info.shift < 4 || encoder_session.info.bits_per_sample-encoder_session.info.shift > 32) {
flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
return EncoderSession_finish_error(&encoder_session);
}
@@ -2441,8 +2441,49 @@ FLAC__bool format_input(FLAC__int32 *dest[], uint32_t wide_samples, FLAC__bool i
}
}
}
+ else if(bps == 32) {
+ if(!is_big_endian) {
+ uint8_t tmp;
+ const uint32_t bytes = wide_samples * channels * (bps >> 3);
+ uint32_t b;
+ for(b = 0; b < bytes; b += 4) {
+ tmp = ubuffer.u8[b];
+ ubuffer.u8[b] = ubuffer.u8[b+3];
+ ubuffer.u8[b+3] = tmp;
+
+ tmp = ubuffer.u8[b+1];
+ ubuffer.u8[b+1] = ubuffer.u8[b+2];
+ ubuffer.u8[b+2] = tmp;
+ }
+ }
+ if(is_unsigned_samples) {
+ uint32_t b;
+ for(b = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
+ for(channel = 0; channel < channels; channel++, sample++) {
+ uint32_t t;
+ t = ubuffer.u8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++];
+ out[channel][wide_sample] = (FLAC__int32)t - 0x80000000;
+ }
+ }
+ else {
+ uint32_t b;
+ for(b = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
+ for(channel = 0; channel < channels; channel++, sample++) {
+ uint32_t t;
+ t = ubuffer.s8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++]; t <<= 8;
+ t |= ubuffer.u8[b++];
+ out[channel][wide_sample] = t;
+ }
+ }
+ }
else {
- FLAC__ASSERT(0);
+ flac__utils_printf(stderr, 1, "ERROR: unsupported input format\n");
+ return false;
}
if(shift > 0) {
FLAC__int32 mask = (1<<shift)-1;
diff --git a/src/flac/main.c b/src/flac/main.c
index 360b2fdd..c47c7ce1 100644
--- a/src/flac/main.c
+++ b/src/flac/main.c
@@ -391,8 +391,8 @@ int do_it(void)
return usage_error("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", option_values.format_channels, FLAC__MAX_CHANNELS);
}
if(option_values.format_bps >= 0) {
- if(option_values.format_bps != 8 && option_values.format_bps != 16 && option_values.format_bps != 24)
- return usage_error("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", option_values.format_bps);
+ if(option_values.format_bps != 8 && option_values.format_bps != 16 && option_values.format_bps != 24 && option_values.format_bps != 32)
+ return usage_error("ERROR: invalid bits per sample '%u' (must be 8/16/24/32)\n", option_values.format_bps);
}
if(option_values.format_sample_rate >= 0) {
if(!FLAC__format_sample_rate_is_valid(option_values.format_sample_rate))
diff --git a/src/libFLAC/bitwriter.c b/src/libFLAC/bitwriter.c
index 13e79d4d..a7f3b3d4 100644
--- a/src/libFLAC/bitwriter.c
+++ b/src/libFLAC/bitwriter.c
@@ -397,6 +397,15 @@ inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__ui
return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
}
+inline FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits)
+{
+ FLAC__uint64 uval = val;
+ /* zero-out unused bits */
+ if(bits < 64)
+ uval &= (~(UINT64_MAX << bits));
+ return FLAC__bitwriter_write_raw_uint64(bw, uval, bits);
+}
+
inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val)
{
/* this doesn't need to be that fast as currently it is only used for vorbis comments */
@@ -888,5 +897,6 @@ extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bit
extern FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits);
extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits);
extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits);
+extern FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits);
extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val);
extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals);
diff --git a/src/libFLAC/fixed.c b/src/libFLAC/fixed.c
index 134fbff4..26f46e6c 100644
--- a/src/libFLAC/fixed.c
+++ b/src/libFLAC/fixed.c
@@ -47,6 +47,11 @@
#endif
#define local_abs(x) ((uint32_t)((x)<0? -(x) : (x)))
+#ifdef local_abs64
+#undef local_abs64
+#endif
+#define local_abs64(x) ((uint64_t)((x)<0? -(x) : (x)))
+
#ifdef FLAC__INTEGER_ONLY_LIBRARY
/* rbps stands for residual bits per sample
*
@@ -344,6 +349,119 @@ uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint3
return order;
}
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+#define CHECK_ORDER_IS_VALID(macro_order) \
+if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \
+ order = macro_order; \
+ smallest_error = total_error_##macro_order ; \
+ residual_bits_per_sample[ macro_order ] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); \
+} \
+else \
+ residual_bits_per_sample[ macro_order ] = 34.0f;
+#else
+#define CHECK_ORDER_IS_VALID(macro_order) \
+if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \
+ order = macro_order; \
+ smallest_error = total_error_##macro_order ; \
+ residual_bits_per_sample[ macro_order ] = (total_error_##macro_order > 0) ? local__compute_rbps_wide_integerized(total_error_##macro_order, data_len) : 0; \
+} \
+else \
+ residual_bits_per_sample[ macro_order ] = 34 * FLAC__FP_ONE;
+#endif
+
+
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#else
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#endif
+{
+ FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX;
+ FLAC__uint64 error_0, error_1, error_2, error_3, error_4;
+ FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true;
+ uint32_t order = 0;
+
+ for(int i = 0; i < (int)data_len; i++) {
+ error_0 = local_abs64((FLAC__int64)data[i]);
+ error_1 = (i > 0) ? local_abs64((FLAC__int64)data[i] - data[i-1]) : 0 ;
+ error_2 = (i > 1) ? local_abs64((FLAC__int64)data[i] - 2 * (FLAC__int64)data[i-1] + data[i-2]) : 0;
+ error_3 = (i > 2) ? local_abs64((FLAC__int64)data[i] - 3 * (FLAC__int64)data[i-1] + 3 * (FLAC__int64)data[i-2] - data[i-3]) : 0;
+ error_4 = (i > 3) ? local_abs64((FLAC__int64)data[i] - 4 * (FLAC__int64)data[i-1] + 6 * (FLAC__int64)data[i-2] - 4 * (FLAC__int64)data[i-3] + data[i-4]) : 0;
+
+ total_error_0 += error_0;
+ total_error_1 += error_1;
+ total_error_2 += error_2;
+ total_error_3 += error_3;
+ total_error_4 += error_4;
+
+ /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+ if(error_0 > INT32_MAX)
+ order_0_is_valid = false;
+ if(error_1 > INT32_MAX)
+ order_1_is_valid = false;
+ if(error_2 > INT32_MAX)
+ order_2_is_valid = false;
+ if(error_3 > INT32_MAX)
+ order_3_is_valid = false;
+ if(error_4 > INT32_MAX)
+ order_4_is_valid = false;
+ }
+
+ CHECK_ORDER_IS_VALID(0);
+ CHECK_ORDER_IS_VALID(1);
+ CHECK_ORDER_IS_VALID(2);
+ CHECK_ORDER_IS_VALID(3);
+ CHECK_ORDER_IS_VALID(4);
+
+ return order;
+}
+
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#else
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+#endif
+{
+ FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX;
+ FLAC__uint64 error_0, error_1, error_2, error_3, error_4;
+ FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true;
+ uint32_t order = 0;
+
+ for(int i = 0; i < (int)data_len; i++) {
+ error_0 = local_abs64(data[i]);
+ error_1 = (i > 0) ? local_abs64(data[i] - data[i-1]) : 0 ;
+ error_2 = (i > 1) ? local_abs64(data[i] - 2 * data[i-1] + data[i-2]) : 0;
+ error_3 = (i > 2) ? local_abs64(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]) : 0;
+ error_4 = (i > 3) ? local_abs64(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]) : 0;
+
+ total_error_0 += error_0;
+ total_error_1 += error_1;
+ total_error_2 += error_2;
+ total_error_3 += error_3;
+ total_error_4 += error_4;
+
+ /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+ if(error_0 > INT32_MAX)
+ order_0_is_valid = false;
+ if(error_1 > INT32_MAX)
+ order_1_is_valid = false;
+ if(error_2 > INT32_MAX)
+ order_2_is_valid = false;
+ if(error_3 > INT32_MAX)
+ order_3_is_valid = false;
+ if(error_4 > INT32_MAX)
+ order_4_is_valid = false;
+ }
+
+ CHECK_ORDER_IS_VALID(0);
+ CHECK_ORDER_IS_VALID(1);
+ CHECK_ORDER_IS_VALID(2);
+ CHECK_ORDER_IS_VALID(3);
+ CHECK_ORDER_IS_VALID(4);
+
+ return order;
+}
+
void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
{
const int idata_len = (int)data_len;
@@ -375,6 +493,68 @@ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, u
}
}
+void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
+{
+ const int idata_len = (int)data_len;
+ int i;
+
+ switch(order) {
+ case 0:
+ FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
+ memcpy(residual, data, sizeof(residual[0])*data_len);
+ break;
+ case 1:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = (FLAC__int64)data[i] - data[i-1];
+ break;
+ case 2:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = (FLAC__int64)data[i] - 2*(FLAC__int64)data[i-1] + data[i-2];
+ break;
+ case 3:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = (FLAC__int64)data[i] - 3*(FLAC__int64)data[i-1] + 3*(FLAC__int64)data[i-2] - data[i-3];
+ break;
+ case 4:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = (FLAC__int64)data[i] - 4*(FLAC__int64)data[i-1] + 6*(FLAC__int64)data[i-2] - 4*(FLAC__int64)data[i-3] + data[i-4];
+ break;
+ default:
+ FLAC__ASSERT(0);
+ }
+}
+
+void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[])
+{
+ const int idata_len = (int)data_len;
+ int i;
+
+ switch(order) {
+ case 0:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = data[i];
+ break;
+ case 1:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = data[i] - data[i-1];
+ break;
+ case 2:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = data[i] - 2*data[i-1] + data[i-2];
+ break;
+ case 3:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3];
+ break;
+ case 4:
+ for(i = 0; i < idata_len; i++)
+ residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4];
+ break;
+ default:
+ FLAC__ASSERT(0);
+ }
+}
+
#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
/* The attribute below is to silence the undefined sanitizer of oss-fuzz.
* Because fuzzing feeds bogus predictors and residual samples to the
diff --git a/src/libFLAC/include/private/bitwriter.h b/src/libFLAC/include/private/bitwriter.h
index 672f282a..a7d822ff 100644
--- a/src/libFLAC/include/private/bitwriter.h
+++ b/src/libFLAC/include/private/bitwriter.h
@@ -83,6 +83,7 @@ FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bits);
FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits);
FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits);
FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits);
+FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits);
FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/
FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals);
FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t val);
diff --git a/src/libFLAC/include/private/fixed.h b/src/libFLAC/include/private/fixed.h
index 7046e2b9..4920d127 100644
--- a/src/libFLAC/include/private/fixed.h
+++ b/src/libFLAC/include/private/fixed.h
@@ -56,6 +56,8 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY
uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
# ifndef FLAC__NO_ASM
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
# ifdef FLAC__SSE2_SUPPORTED
@@ -74,6 +76,8 @@ uint32_t FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32
#else
uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
#endif
/*
@@ -88,6 +92,8 @@ uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint3
* OUT residual[0,data_len-1] residual signal
*/
void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
+void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
+void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]);
/*
* FLAC__fixed_restore_signal()
diff --git a/src/libFLAC/include/private/lpc.h b/src/libFLAC/include/private/lpc.h
index 318666aa..99f62de8 100644
--- a/src/libFLAC/include/private/lpc.h
+++ b/src/libFLAC/include/private/lpc.h
@@ -55,6 +55,7 @@
* IN data_len
*/
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len);
+void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len);
/*
* FLAC__lpc_compute_autocorrelation()
@@ -156,7 +157,8 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order,
*/
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
-
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
#ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_ARM64
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]);
diff --git a/src/libFLAC/include/private/memory.h b/src/libFLAC/include/private/memory.h
index a6d3faff..7637310e 100644
--- a/src/libFLAC/include/private/memory.h
+++ b/src/libFLAC/include/private/memory.h
@@ -48,6 +48,7 @@
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address);
FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer);
FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer);
+FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer);
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer);
FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
diff --git a/src/libFLAC/lpc.c b/src/libFLAC/lpc.c
index c2d07654..3fe3a2b7 100644
--- a/src/libFLAC/lpc.c
+++ b/src/libFLAC/lpc.c
@@ -71,6 +71,13 @@ void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FL
out[i] = in[i] * window[i];
}
+void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len)
+{
+ uint32_t i;
+ for(i = 0; i < data_len; i++)
+ out[i] = in[i] * window[i];
+}
+
void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[])
{
/* a readable, but slower, version */
@@ -546,10 +553,6 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
history = data;
for(j = 0; j < order; j++)
sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
- if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) {
- 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((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
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;
@@ -588,7 +591,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 11 */
@@ -605,7 +608,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
@@ -623,7 +626,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 9 */
@@ -638,7 +641,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
@@ -656,7 +659,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 7 */
@@ -669,7 +672,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
@@ -683,7 +686,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 5 */
@@ -694,7 +697,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
@@ -708,7 +711,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 3 */
@@ -717,7 +720,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
@@ -727,12 +730,12 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum = 0;
sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
else { /* order == 1 */
for(i = 0; i < (int)data_len; i++)
- residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
+ residual[i] = data[i] - ((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
}
}
}
@@ -774,12 +777,120 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f
sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2];
sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
}
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
+ residual[i] = data[i] - (sum >> lp_quantization);
}
}
}
#endif
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual)
+{
+ int i;
+ FLAC__int64 sum, residual_to_check;
+
+ FLAC__ASSERT(order > 0);
+ FLAC__ASSERT(order <= 32);
+
+ for(i = 0; i < (int)data_len; i++) {
+ sum = 0;
+ switch(order) {
+ case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; /* Falls through. */
+ case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; /* Falls through. */
+ case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; /* Falls through. */
+ case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; /* Falls through. */
+ case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; /* Falls through. */
+ case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; /* Falls through. */
+ case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; /* Falls through. */
+ case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; /* Falls through. */
+ case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; /* Falls through. */
+ case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; /* Falls through. */
+ case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; /* Falls through. */
+ case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; /* Falls through. */
+ case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; /* Falls through. */
+ case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; /* Falls through. */
+ case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; /* Falls through. */
+ case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; /* Falls through. */
+ case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; /* Falls through. */
+ case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; /* Falls through. */
+ case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; /* Falls through. */
+ case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; /* Falls through. */
+ case 12: sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; /* Falls through. */
+ case 11: sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; /* Falls through. */
+ case 10: sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; /* Falls through. */
+ case 9: sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; /* Falls through. */
+ case 8: sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; /* Falls through. */
+ case 7: sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; /* Falls through. */
+ case 6: sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; /* Falls through. */
+ case 5: sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; /* Falls through. */
+ case 4: sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; /* Falls through. */
+ case 3: sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; /* Falls through. */
+ case 2: sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; /* Falls through. */
+ case 1: sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
+ }
+ residual_to_check = data[i] - (sum >> lp_quantization);
+ /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+ if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX)
+ return false;
+ else
+ residual[i] = residual_to_check;
+ }
+ return true;
+}
+
+FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual)
+{
+ int i;
+ FLAC__int64 sum, residual_to_check;
+
+ FLAC__ASSERT(order > 0);
+ FLAC__ASSERT(order <= 32);
+
+ for(i = 0; i < (int)data_len; i++) {
+ sum = 0;
+ switch(order) {
+ case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */
+ case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */
+ case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */
+ case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */
+ case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */
+ case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */
+ case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */
+ case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */
+ case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */
+ case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */
+ case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */
+ case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */
+ case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */
+ case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */
+ case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */
+ case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */
+ case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */
+ case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */
+ case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */
+ case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */
+ case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */
+ case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */
+ case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */
+ case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */
+ case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */
+ case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */
+ case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */
+ case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */
+ case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */
+ case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */
+ case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */
+ case 1: sum += qlp_coeff[ 0] * data[i- 1];
+ }
+ residual_to_check = data[i] - (sum >> lp_quantization);
+ /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */
+ if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX)
+ return false;
+ else
+ residual[i] = residual_to_check;
+ }
+ return true;
+}
+
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order)
diff --git a/src/libFLAC/memory.c b/src/libFLAC/memory.c
index 4d320a43..f30703d1 100644
--- a/src/libFLAC/memory.c
+++ b/src/libFLAC/memory.c
@@ -118,6 +118,35 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32
}
}
+FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer)
+{
+ FLAC__int64 *pu; /* unaligned pointer */
+ union { /* union needed to comply with C99 pointer aliasing rules */
+ FLAC__int64 *pa; /* aligned pointer */
+ void *pv; /* aligned pointer alias */
+ } u;
+
+ FLAC__ASSERT(elements > 0);
+ FLAC__ASSERT(0 != unaligned_pointer);
+ FLAC__ASSERT(0 != aligned_pointer);
+ FLAC__ASSERT(unaligned_pointer != aligned_pointer);
+
+ if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
+ if(0 == pu) {
+ return false;
+ }
+ else {
+ if(*unaligned_pointer != 0)
+ free(*unaligned_pointer);
+ *unaligned_pointer = pu;
+ *aligned_pointer = u.pa;
+ return true;
+ }
+}
+
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
{
FLAC__uint64 *pu; /* unaligned pointer */
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index 4d8e5a84..34222174 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -149,7 +149,7 @@ static FLAC__bool process_subframe_(
uint32_t max_partition_order,
const FLAC__FrameHeader *frame_header,
uint32_t subframe_bps,
- const FLAC__int32 integer_signal[],
+ const void *integer_signal,
FLAC__Subframe *subframe[2],
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
FLAC__int32 *residual[2],
@@ -167,7 +167,7 @@ static FLAC__bool add_subframe_(
static uint32_t evaluate_constant_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal,
+ const FLAC__int64 signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
@@ -175,7 +175,7 @@ static uint32_t evaluate_constant_subframe_(
static uint32_t evaluate_fixed_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
@@ -194,7 +194,7 @@ static uint32_t evaluate_fixed_subframe_(
#ifndef FLAC__INTEGER_ONLY_LIBRARY
static uint32_t evaluate_lpc_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
@@ -215,7 +215,7 @@ static uint32_t evaluate_lpc_subframe_(
static uint32_t evaluate_verbatim_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
@@ -273,6 +273,7 @@ static FLAC__bool set_partitioned_rice_(
);
static uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples);
+static uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples);
/* verify-related routines: */
static void append_to_verify_fifo_(
@@ -313,6 +314,7 @@ typedef struct FLAC__StreamEncoderPrivate {
uint32_t input_capacity; /* current size (in samples) of the signal and residual buffers */
FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */
FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */
+ FLAC__int64 *integer_signal_33bit_side; /* 33-bit side for 32-bit stereo decorrelation */
#ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) the floating-point version of the input signal */
FLAC__real *real_signal_mid_side[2]; /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */
@@ -386,6 +388,7 @@ typedef struct FLAC__StreamEncoderPrivate {
/* unaligned (original) pointers to allocated data */
FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS];
FLAC__int32 *integer_signal_mid_side_unaligned[2];
+ FLAC__int64 *integer_signal_33bit_side_unaligned;
#ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */
FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */
@@ -650,10 +653,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
else if(!encoder->protected_->do_mid_side_stereo)
encoder->protected_->loose_mid_side_stereo = false;
- if(encoder->protected_->bits_per_sample >= 32)
- encoder->protected_->do_mid_side_stereo = false; /* since we currently do 32-bit math, the side channel would have 33 bps and overflow */
-
- if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE)
+ if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE)
return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE;
if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate))
@@ -720,7 +720,8 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
encoder->protected_->bits_per_sample != 12 &&
encoder->protected_->bits_per_sample != 16 &&
encoder->protected_->bits_per_sample != 20 &&
- encoder->protected_->bits_per_sample != 24
+ encoder->protected_->bits_per_sample != 24 &&
+ encoder->protected_->bits_per_sample != 32
)
return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER)
@@ -833,6 +834,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
#endif
}
+ encoder->private_->integer_signal_33bit_side_unaligned = encoder->private_->integer_signal_33bit_side = 0;
#ifndef FLAC__INTEGER_ONLY_LIBRARY
for(i = 0; i < encoder->protected_->num_apodizations; i++)
encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0;
@@ -2195,7 +2197,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__Strea
FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], uint32_t samples)
{
uint32_t i, j = 0, k = 0, channel;
- const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
+ const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize, bps = encoder->protected_->bits_per_sample;
const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample);
const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample);
@@ -2228,10 +2230,16 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c
if(encoder->protected_->do_mid_side_stereo) {
FLAC__ASSERT(channels == 2);
/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
- for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
- encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
- encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
- }
+ if(bps < 32)
+ for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
+ encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
+ encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
+ }
+ else
+ for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
+ encoder->private_->integer_signal_33bit_side[i] = (FLAC__int64)buffer[0][j] - (FLAC__int64)buffer[1][j];
+ encoder->private_->integer_signal_mid_side[0][i] = ((FLAC__int64)buffer[0][j] + (FLAC__int64)buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
+ }
}
else
j += n;
@@ -2249,7 +2257,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c
encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
if(encoder->protected_->do_mid_side_stereo) {
encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
- encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+ if(bps < 32)
+ encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+ else
+ encoder->private_->integer_signal_33bit_side[0] = encoder->private_->integer_signal_33bit_side[blocksize];
}
encoder->private_->current_sample_number = 1;
}
@@ -2261,8 +2272,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c
FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], uint32_t samples)
{
uint32_t i, j, k, channel;
- FLAC__int32 x, mid, side;
- const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
+ const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize, bps = encoder->protected_->bits_per_sample;
const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample);
const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample);
@@ -2293,14 +2303,16 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
- encoder->private_->integer_signal[0][i] = mid = side = buffer[k++];
- x = buffer[k++];
- encoder->private_->integer_signal[1][i] = x;
- mid += x;
- side -= x;
- mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */
- encoder->private_->integer_signal_mid_side[1][i] = side;
- encoder->private_->integer_signal_mid_side[0][i] = mid;
+ encoder->private_->integer_signal[0][i] = buffer[k++];
+ encoder->private_->integer_signal[1][i] = buffer[k++];
+ if(bps < 32){
+ encoder->private_->integer_signal_mid_side[1][i] = encoder->private_->integer_signal[0][i] - encoder->private_->integer_signal[1][i];
+ encoder->private_->integer_signal_mid_side[0][i] = (encoder->private_->integer_signal[0][i] + encoder->private_->integer_signal[1][i]) >> 1;
+ }
+ else {
+ encoder->private_->integer_signal_33bit_side[i] = (FLAC__int64)encoder->private_->integer_signal[0][i] - (FLAC__int64)encoder->private_->integer_signal[1][i];
+ encoder->private_->integer_signal_mid_side[0][i] = ((FLAC__int64)encoder->private_->integer_signal[0][i] + (FLAC__int64)encoder->private_->integer_signal[1][i]) >> 1;
+ }
}
encoder->private_->current_sample_number = i;
/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
@@ -2313,7 +2325,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder
encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize];
encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize];
encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
- encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+ if(bps < 32)
+ encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
+ else
+ encoder->private_->integer_signal_33bit_side[0] = encoder->private_->integer_signal_33bit_side[blocksize];
encoder->private_->current_sample_number = 1;
}
} while(j < samples);
@@ -2454,6 +2469,10 @@ void free_(FLAC__StreamEncoder *encoder)
}
#endif
}
+ if(0 != encoder->private_->integer_signal_33bit_side_unaligned){
+ free(encoder->private_->integer_signal_33bit_side_unaligned);
+ encoder->private_->integer_signal_33bit_side_unaligned = 0;
+ }
#ifndef FLAC__INTEGER_ONLY_LIBRARY
for(i = 0; i < encoder->protected_->num_apodizations; i++) {
if(0 != encoder->private_->window_unaligned[i]) {
@@ -2544,6 +2563,7 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize)
#endif
#endif
}
+ ok = ok && FLAC__memory_alloc_aligned_int64_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_33bit_side_unaligned, &encoder->private_->integer_signal_33bit_side);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
if(ok && encoder->protected_->max_lpc_order > 0) {
for(i = 0; ok && i < encoder->protected_->num_apodizations; i++)
@@ -3258,7 +3278,12 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder)
if(do_mid_side) {
FLAC__ASSERT(encoder->protected_->channels == 2);
for(channel = 0; channel < 2; channel++) {
- uint32_t w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+ uint32_t w;
+ if(encoder->protected_->bits_per_sample < 32 || channel == 0)
+ w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+ else
+ w = get_wasted_bits_wide_(encoder->private_->integer_signal_33bit_side, encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
+
if (w > encoder->protected_->bits_per_sample) {
w = encoder->protected_->bits_per_sample;
}
@@ -3306,6 +3331,11 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder)
FLAC__ASSERT(encoder->protected_->channels == 2);
for(channel = 0; channel < 2; channel++) {
+ void *integer_signal_;
+ if(encoder->private_->subframe_bps_mid_side[channel] <= 32)
+ integer_signal_ = encoder->private_->integer_signal_mid_side[channel];
+ else
+ integer_signal_ = encoder->private_->integer_signal_33bit_side;
if(!
process_subframe_(
encoder,
@@ -3313,7 +3343,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder)
max_partition_order,
&frame_header,
encoder->private_->subframe_bps_mid_side[channel],
- encoder->private_->integer_signal_mid_side[channel],
+ integer_signal_,
encoder->private_->subframe_workspace_ptr_mid_side[channel],
encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel],
encoder->private_->residual_workspace_mid_side[channel],
@@ -3456,7 +3486,7 @@ FLAC__bool process_subframe_(
uint32_t max_partition_order,
const FLAC__FrameHeader *frame_header,
uint32_t subframe_bps,
- const FLAC__int32 integer_signal[],
+ const void *integer_signal,
FLAC__Subframe *subframe[2],
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
FLAC__int32 *residual[2],
@@ -3490,6 +3520,7 @@ FLAC__bool process_subframe_(
_best_bits = UINT32_MAX;
else
_best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
+ *best_bits = _best_bits;
if(frame_header->blocksize > FLAC__MAX_FIXED_ORDER) {
uint32_t signal_is_constant = false;
@@ -3501,10 +3532,18 @@ FLAC__bool process_subframe_(
* maximum_sample_value * (blocksize - order) * 17. As ilog2(x)
* calculates floor(2log(x)), the result must be 31 or lower
*/
- if(subframe_bps + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)*17) < 32)
- guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+ if(subframe_bps < 28){
+ if(subframe_bps + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)*17) < 32)
+ guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+ else
+ guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+ }
else
- guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+ if(subframe_bps <= 32)
+ guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual(((FLAC__int32 *)integer_signal),frame_header->blocksize, fixed_residual_bits_per_sample);
+ else
+ guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual_33bit(((FLAC__int64 *)integer_signal),frame_header->blocksize, fixed_residual_bits_per_sample);
+
/* check for constant subframe */
if(
!encoder->private_->disable_constant_subframes &&
@@ -3517,15 +3556,31 @@ FLAC__bool process_subframe_(
/* the above means it's possible all samples are the same value; now double-check it: */
uint32_t i;
signal_is_constant = true;
- for(i = 1; i < frame_header->blocksize; i++) {
- if(integer_signal[0] != integer_signal[i]) {
- signal_is_constant = false;
- break;
+ if(subframe_bps <= 32){
+ const FLAC__int32 *integer_signal_ = integer_signal;
+ for(i = 1; i < frame_header->blocksize; i++) {
+ if(integer_signal_[0] != integer_signal_[i]) {
+ signal_is_constant = false;
+ break;
+ }
+ }
+ }
+ else {
+ const FLAC__int64 *integer_signal_ = integer_signal;
+ for(i = 1; i < frame_header->blocksize; i++) {
+ if(integer_signal_[0] != integer_signal_[i]) {
+ signal_is_constant = false;
+ break;
+ }
}
}
}
if(signal_is_constant) {
- _candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+ if(subframe_bps <= 32)
+ _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int32 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+ else
+ _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int64 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
+
if(_candidate_bits < _best_bits) {
_best_subframe = !_best_subframe;
_best_bits = _candidate_bits;
@@ -3586,7 +3641,10 @@ FLAC__bool process_subframe_(
if(max_lpc_order > 0) {
uint32_t a;
for (a = 0; a < encoder->protected_->num_apodizations; a++) {
- FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
+ if(subframe_bps <= 32)
+ FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
+ else
+ FLAC__lpc_window_data_wide(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc);
/* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
if(autoc[0] != 0.0) {
@@ -3749,7 +3807,7 @@ static void spotcheck_subframe_estimate_(
uint32_t evaluate_constant_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal,
+ const FLAC__int64 signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
@@ -3772,7 +3830,7 @@ uint32_t evaluate_constant_subframe_(
uint32_t evaluate_fixed_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
@@ -3791,7 +3849,12 @@ uint32_t evaluate_fixed_subframe_(
uint32_t i, residual_bits, estimate;
const uint32_t residual_samples = blocksize - order;
- FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual);
+ if((subframe_bps + order) <= 32)
+ FLAC__fixed_compute_residual(((FLAC__int32 *)signal)+order, residual_samples, order, residual);
+ else if(subframe_bps <= 32)
+ FLAC__fixed_compute_residual_wide(((FLAC__int32 *)signal)+order, residual_samples, order, residual);
+ else
+ FLAC__fixed_compute_residual_wide_33bit(((FLAC__int64 *)signal)+order, residual_samples, order, residual);
subframe->type = FLAC__SUBFRAME_TYPE_FIXED;
@@ -3817,8 +3880,12 @@ uint32_t evaluate_fixed_subframe_(
);
subframe->data.fixed.order = order;
- for(i = 0; i < order; i++)
- subframe->data.fixed.warmup[i] = signal[i];
+ if(subframe_bps <= 32)
+ for(i = 0; i < order; i++)
+ subframe->data.fixed.warmup[i] = ((FLAC__int32 *)signal)[i];
+ else
+ for(i = 0; i < order; i++)
+ subframe->data.fixed.warmup[i] = ((FLAC__int64 *)signal)[i];
estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps);
if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow
@@ -3836,7 +3903,7 @@ uint32_t evaluate_fixed_subframe_(
#ifndef FLAC__INTEGER_ONLY_LIBRARY
uint32_t evaluate_lpc_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
@@ -3870,13 +3937,23 @@ 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(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);
+ if(FLAC__lpc_max_residual_bps(subframe_bps, qlp_coeff, order, quantization) > 32) {
+ if(subframe_bps <= 32){
+ if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual))
+ return 0;
+ }
else
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+ if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(((FLAC__int64 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual))
+ return 0;
+ }
else
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+ 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(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
+ else
+ encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
+ else
+ encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual);
subframe->type = FLAC__SUBFRAME_TYPE_LPC;
@@ -3905,8 +3982,13 @@ uint32_t evaluate_lpc_subframe_(
subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
subframe->data.lpc.quantization_level = quantization;
memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER);
- for(i = 0; i < order; i++)
- subframe->data.lpc.warmup[i] = signal[i];
+ if(subframe_bps <= 32)
+ for(i = 0; i < order; i++)
+ subframe->data.lpc.warmup[i] = ((FLAC__int32 *)signal)[i];
+ else
+ for(i = 0; i < order; i++)
+ subframe->data.lpc.warmup[i] = ((FLAC__int64 *)signal)[i];
+
estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps));
if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow
@@ -3924,7 +4006,7 @@ uint32_t evaluate_lpc_subframe_(
uint32_t evaluate_verbatim_subframe_(
FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
+ const void *signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
@@ -3934,8 +4016,14 @@ uint32_t evaluate_verbatim_subframe_(
subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
- subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32;
- subframe->data.verbatim.data.int32 = signal;
+ if(subframe_bps <= 32){
+ subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32;
+ subframe->data.verbatim.data.int32 = signal;
+ }
+ else {
+ subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64;
+ subframe->data.verbatim.data.int64 = signal;
+ }
estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps);
@@ -4323,7 +4411,7 @@ FLAC__bool set_partitioned_rice_(
#endif
if(search_for_escapes) {
partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
- if(partition_bits <= best_partition_bits) {
+ if(partition_bits <= best_partition_bits && raw_bits_per_partition[partition] < 32) {
raw_bits[partition] = raw_bits_per_partition[partition];
best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
best_partition_bits = partition_bits;
@@ -4367,6 +4455,31 @@ uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples)
return shift;
}
+uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples)
+{
+ uint32_t i, shift;
+ FLAC__int64 x = 0;
+
+ for(i = 0; i < samples && !(x&1); i++)
+ x |= signal_wide[i];
+
+ if(x == 0) {
+ shift = 1;
+ }
+ else {
+ for(shift = 0; !(x&1); shift++)
+ x >>= 1;
+ }
+
+ if(shift > 0) {
+ for(i = 0; i < samples; i++)
+ signal[i] = (FLAC__int32)(signal_wide[i] >> shift);
+ }
+
+ return shift;
+}
+
+
void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples)
{
uint32_t channel;
diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c
index af1822bd..b132bdb6 100644
--- a/src/libFLAC/stream_encoder_framing.c
+++ b/src/libFLAC/stream_encoder_framing.c
@@ -323,6 +323,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
case 16: u = 4; break;
case 20: u = 5; break;
case 24: u = 6; break;
+ case 32: u = 7; break;
default: u = 0; break;
}
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN))
@@ -375,7 +376,7 @@ FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe,
ok =
FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) &&
(wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) &&
- FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps)
+ FLAC__bitwriter_write_raw_int64(bw, subframe->value, subframe_bps)
;
return ok;
@@ -392,7 +393,7 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, uint32
return false;
for(i = 0; i < subframe->order; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
+ if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps))
return false;
if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
@@ -430,7 +431,7 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t r
return false;
for(i = 0; i < subframe->order; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
+ if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps))
return false;
if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
@@ -468,7 +469,6 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t r
FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw)
{
uint32_t i;
- const FLAC__int32 *signal = subframe->data.int32;
if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
return false;
@@ -476,9 +476,24 @@ FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe,
if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
return false;
- for(i = 0; i < samples; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
- return false;
+ if(subframe->data_type == FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32) {
+ const FLAC__int32 *signal = subframe->data.int32;
+
+ FLAC__ASSERT(subframe_bps < 33);
+
+ for(i = 0; i < samples; i++)
+ if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
+ return false;
+ }
+ else {
+ const FLAC__int64 *signal = subframe->data.int64;
+
+ FLAC__ASSERT(subframe_bps == 33);
+
+ for(i = 0; i < samples; i++)
+ if(!FLAC__bitwriter_write_raw_int64(bw, (FLAC__int64)signal[i], subframe_bps))
+ return false;
+ }
return true;
}