Add 32-bit encoding, including limiting of residual to 32-bit int

This commit is contained in:
Martijn van Beurden 2022-04-04 20:21:41 +02:00
parent 9df24ac202
commit 0fe187b545
12 changed files with 594 additions and 85 deletions

View File

@ -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;

View File

@ -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))

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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()

View File

@ -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[]);

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}