From 0fe187b54511b575892fb38e01d8e2ab809fb0fe Mon Sep 17 00:00:00 2001 From: Martijn van Beurden Date: Mon, 4 Apr 2022 20:21:41 +0200 Subject: [PATCH] Add 32-bit encoding, including limiting of residual to 32-bit int --- src/flac/encode.c | 45 ++++- src/flac/main.c | 4 +- src/libFLAC/bitwriter.c | 10 ++ src/libFLAC/fixed.c | 180 +++++++++++++++++++ src/libFLAC/include/private/bitwriter.h | 1 + src/libFLAC/include/private/fixed.h | 6 + src/libFLAC/include/private/lpc.h | 4 +- src/libFLAC/include/private/memory.h | 1 + src/libFLAC/lpc.c | 145 +++++++++++++-- src/libFLAC/memory.c | 29 +++ src/libFLAC/stream_encoder.c | 225 ++++++++++++++++++------ src/libFLAC/stream_encoder_framing.c | 29 ++- 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< 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; }