From 5f2b46d0314085189627e8b47453fd99ee172cb0 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Tue, 9 Nov 2004 01:34:01 +0000 Subject: [PATCH] finished integerized flavor of library; sections with floating point are either #ifdef'd out or written in fixed-point --- src/libFLAC/fixed.c | 191 +++++++++++++++++++++++ src/libFLAC/include/private/fixed.h | 17 +- src/libFLAC/include/private/lpc.h | 8 + src/libFLAC/include/private/memory.h | 2 + src/libFLAC/lpc.c | 8 + src/libFLAC/memory.c | 4 + src/libFLAC/seekable_stream_decoder.c | 32 +++- src/libFLAC/stream_encoder.c | 121 ++++++++++++-- src/libOggFLAC/seekable_stream_decoder.c | 8 + 9 files changed, 363 insertions(+), 28 deletions(-) diff --git a/src/libFLAC/fixed.c b/src/libFLAC/fixed.c index abf74d1d..1c46c331 100644 --- a/src/libFLAC/fixed.c +++ b/src/libFLAC/fixed.c @@ -30,6 +30,7 @@ */ #include +#include "private/bitmath.h" #include "private/fixed.h" #include "FLAC/assert.h" @@ -48,7 +49,177 @@ #endif #define local_abs(x) ((unsigned)((x)<0? -(x) : (x))) +#ifdef FLAC__INTEGER_ONLY_LIBRARY +/* rbps stands for residual bits per sample + * + * (ln(2) * err) + * rbps = log (-----------) + * 2 ( n ) + */ +static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) +{ + FLAC__uint32 rbps; + unsigned bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if(err <= n) + return 0; + /* + * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + * These allow us later to know we won't lose too much precision in the + * fixed-point division (err< 0); + bits = FLAC__bitmath_ilog2(err)+1; + if(bits > 16) { + err >>= (bits-16); + fracbits -= (bits-16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if(f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); + + if(rbps == 0) + return 0; + + /* + * The return value must have 16 fractional bits. Since the whole part + * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + * must be >= -3, these assertion allows us to be able to shift rbps + * left if necessary to get 16 fracbits without losing any bits of the + * whole part of rbps. + * + * There is a slight chance due to accumulated error that the whole part + * will require 6 bits, so we use 6 in the assertion. Really though as + * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if(fracbits < 16) + return rbps << (16-fracbits); + else if(fracbits > 16) + return rbps >> (fracbits-16); + else + return rbps; +} + +static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) +{ + FLAC__uint32 rbps; + unsigned bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if(err <= n) + return 0; + /* + * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + * These allow us later to know we won't lose too much precision in the + * fixed-point division (err< 0); + bits = FLAC__bitmath_ilog2_wide(err)+1; + if(bits > 16) { + err >>= (bits-16); + fracbits -= (bits-16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if(f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); + + if(rbps == 0) + return 0; + + /* + * The return value must have 16 fractional bits. Since the whole part + * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + * must be >= -3, these assertion allows us to be able to shift rbps + * left if necessary to get 16 fracbits without losing any bits of the + * whole part of rbps. + * + * There is a slight chance due to accumulated error that the whole part + * will require 6 bits, so we use 6 in the assertion. Really though as + * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if(fracbits < 16) + return rbps << (16-fracbits); + else if(fracbits > 16) + return rbps >> (fracbits-16); + else + return rbps; +} +#endif + +#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif { FLAC__int32 last_error_0 = data[-1]; FLAC__int32 last_error_1 = data[-1] - data[-2]; @@ -85,16 +256,28 @@ unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned d FLAC__ASSERT(data_len > 0 || total_error_2 == 0); FLAC__ASSERT(data_len > 0 || total_error_3 == 0); FLAC__ASSERT(data_len > 0 || total_error_4 == 0); +#ifndef FLAC__INTEGER_ONLY_LIBRARY residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); +#else + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; +#endif return order; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif { FLAC__int32 last_error_0 = data[-1]; FLAC__int32 last_error_1 = data[-1] - data[-2]; @@ -135,6 +318,7 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig FLAC__ASSERT(data_len > 0 || total_error_2 == 0); FLAC__ASSERT(data_len > 0 || total_error_3 == 0); FLAC__ASSERT(data_len > 0 || total_error_4 == 0); +#ifndef FLAC__INTEGER_ONLY_LIBRARY #if defined _MSC_VER || defined __MINGW32__ /* with VC++ you have to spoon feed it the casting */ residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); @@ -149,6 +333,13 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); #endif +#else + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; +#endif return order; } diff --git a/src/libFLAC/include/private/fixed.h b/src/libFLAC/include/private/fixed.h index 5d3d056f..8949c9b1 100644 --- a/src/libFLAC/include/private/fixed.h +++ b/src/libFLAC/include/private/fixed.h @@ -51,15 +51,20 @@ * IN data_len * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); -#ifndef FLAC__NO_ASM -#ifdef FLAC__CPU_IA32 -#ifdef FLAC__HAS_NASM +# ifndef FLAC__NO_ASM +# ifdef FLAC__CPU_IA32 +# ifdef FLAC__HAS_NASM unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); -#endif -#endif -#endif +# endif +# endif +# endif unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#else +unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#endif /* * FLAC__fixed_compute_residual() diff --git a/src/libFLAC/include/private/lpc.h b/src/libFLAC/include/private/lpc.h index c99ca9ef..4938111e 100644 --- a/src/libFLAC/include/private/lpc.h +++ b/src/libFLAC/include/private/lpc.h @@ -39,6 +39,8 @@ #include "private/float.h" #include "FLAC/format.h" +#ifndef FLAC__INTEGER_ONLY_LIBRARY + /* * FLAC__lpc_compute_autocorrelation() * -------------------------------------------------------------------- @@ -130,6 +132,8 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__i # endif #endif +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + /* * FLAC__lpc_restore_signal() * -------------------------------------------------------------------- @@ -159,6 +163,8 @@ void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residu # endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */ #endif /* FLAC__NO_ASM */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY + /* * FLAC__lpc_compute_expected_bits_per_residual_sample() * -------------------------------------------------------------------- @@ -186,4 +192,6 @@ FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scal */ unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample); +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + #endif diff --git a/src/libFLAC/include/private/memory.h b/src/libFLAC/include/private/memory.h index fc4e99ae..2b78a3fd 100644 --- a/src/libFLAC/include/private/memory.h +++ b/src/libFLAC/include/private/memory.h @@ -49,6 +49,8 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); +#endif #endif diff --git a/src/libFLAC/lpc.c b/src/libFLAC/lpc.c index 4e284cb5..7b3af558 100644 --- a/src/libFLAC/lpc.c +++ b/src/libFLAC/lpc.c @@ -38,6 +38,8 @@ #include #endif +#ifndef FLAC__INTEGER_ONLY_LIBRARY + #ifndef M_LN2 /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ #define M_LN2 0.69314718055994530942 @@ -287,6 +289,8 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 dat } } +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ + void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) { #ifdef FLAC__OVERFLOW_DETECT @@ -369,6 +373,8 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) { FLAC__double error_scale; @@ -420,3 +426,5 @@ unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned m return best_order+1; /* +1 since index of lpc_error[] is order-1 */ } + +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/src/libFLAC/memory.c b/src/libFLAC/memory.c index 294dd1e3..8d165e04 100644 --- a/src/libFLAC/memory.c +++ b/src/libFLAC/memory.c @@ -157,6 +157,8 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned } } +#ifndef FLAC__INTEGER_ONLY_LIBRARY + FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) { FLAC__real *pu; /* unaligned pointer */ @@ -182,3 +184,5 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real * return true; } } + +#endif diff --git a/src/libFLAC/seekable_stream_decoder.c b/src/libFLAC/seekable_stream_decoder.c index db38a47e..0f794290 100644 --- a/src/libFLAC/seekable_stream_decoder.c +++ b/src/libFLAC/seekable_stream_decoder.c @@ -949,12 +949,20 @@ FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__ else if(upper_seek_point >= 0) { const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number; const FLAC__uint64 range_samples = decoder->private_->seek_table->points[upper_seek_point].sample_number - decoder->private_->seek_table->points[lower_seek_point].sample_number; - const FLAC__uint64 range_bytes = upper_bound - lower_bound; + const FLAC__uint64 range_bytes = (upper_bound>lower_bound? upper_bound - lower_bound - 1 : 0); +#ifndef FLAC__INTEGER_ONLY_LIBRARY #if defined _MSC_VER || defined __MINGW32__ /* with VC++ you have to spoon feed it the casting */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)target_offset / (FLAC__double)(FLAC__int64)range_samples * (FLAC__double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame; + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_offset / (FLAC__double)(FLAC__int64)range_samples) * (FLAC__double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame; #else - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)target_offset / (FLAC__double)range_samples * (FLAC__double)(range_bytes-1)) - approx_bytes_per_frame; + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)target_offset / (FLAC__double)range_samples) * (FLAC__double)range_bytes) - approx_bytes_per_frame; +#endif +#else + /* a little less accurate: */ + if (range_bytes <= 0xffffffff) + pos = (FLAC__int64)lower_bound + (FLAC__int64)((target_offset * range_bytes) / range_samples) - approx_bytes_per_frame; + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_offset>>8) * (range_bytes>>8)) / (range_samples>>16)) - approx_bytes_per_frame; #endif } } @@ -965,11 +973,25 @@ FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__ * frame with the correct sample. */ if(pos < 0 && total_samples > 0) { + /* + * For max accuracy we should be using + * (stream_length-first_frame_offset-1) in the divisor, but the + * difference is trivial and (stream_length-first_frame_offset) + * has no chance of underflow. + */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY #if defined _MSC_VER || defined __MINGW32__ /* with VC++ you have to spoon feed it the casting */ - pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((FLAC__double)(FLAC__int64)target_sample / (FLAC__double)(FLAC__int64)total_samples * (FLAC__double)(FLAC__int64)(stream_length-first_frame_offset-1)) - approx_bytes_per_frame; + pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_sample / (FLAC__double)(FLAC__int64)total_samples) * (FLAC__double)(FLAC__int64)(stream_length-first_frame_offset)) - approx_bytes_per_frame; #else - pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((FLAC__double)target_sample / (FLAC__double)total_samples * (FLAC__double)(stream_length-first_frame_offset-1)) - approx_bytes_per_frame; + pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)target_sample / (FLAC__double)total_samples) * (FLAC__double)(stream_length-first_frame_offset)) - approx_bytes_per_frame; +#endif +#else + /* a little less accurate: */ + if (stream_length < 0xffffffff) + pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((target_sample * (stream_length-first_frame_offset)) / total_samples) - approx_bytes_per_frame; + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((target_sample>>8) * ((stream_length-first_frame_offset)>>8)) / (total_samples>>16)) - approx_bytes_per_frame; #endif } diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 65b8540a..f9be720f 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -100,7 +100,9 @@ static FLAC__bool process_subframe_( const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], +#ifndef FLAC__INTEGER_ONLY_LIBRARY const FLAC__real real_signal[], +#endif FLAC__Subframe *subframe[2], FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], FLAC__int32 *residual[2], @@ -142,6 +144,7 @@ static unsigned evaluate_fixed_subframe_( FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents ); +#ifndef FLAC__INTEGER_ONLY_LIBRARY static unsigned evaluate_lpc_subframe_( FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], @@ -163,6 +166,7 @@ static unsigned evaluate_lpc_subframe_( FLAC__Subframe *subframe, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents ); +#endif static unsigned evaluate_verbatim_subframe_( const FLAC__int32 signal[], @@ -315,8 +319,10 @@ typedef struct FLAC__StreamEncoderPrivate { unsigned 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) */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */ FLAC__real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */ +#endif unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */ unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */ FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */ @@ -337,7 +343,6 @@ typedef struct FLAC__StreamEncoderPrivate { FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ FLAC__BitBuffer *frame; /* the current frame being worked on */ - FLAC__double loose_mid_side_stereo_frames_exact; /* exact number of frames the encoder will use before trying both independent and mid/side frames again */ unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ FLAC__ChannelAssignment last_channel_assignment; @@ -346,11 +351,17 @@ typedef struct FLAC__StreamEncoderPrivate { unsigned current_frame_number; struct FLAC__MD5Context md5context; FLAC__CPUInfo cpuinfo; +#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#else + unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +#endif +#ifndef FLAC__INTEGER_ONLY_LIBRARY void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 data[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 data[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 data[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +#endif FLAC__bool use_wide_by_block; /* use slow 64-bit versions of some functions because of the block size */ FLAC__bool use_wide_by_partition; /* use slow 64-bit versions of some functions because of the min partition order and blocksize */ FLAC__bool use_wide_by_order; /* use slow 64-bit versions of some functions because of the lpc order */ @@ -364,8 +375,10 @@ 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]; +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; FLAC__real *real_signal_mid_side_unaligned[2]; +#endif FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2]; FLAC__int32 *residual_workspace_mid_side_unaligned[2][2]; FLAC__uint32 *abs_residual_unaligned; @@ -375,7 +388,9 @@ typedef struct FLAC__StreamEncoderPrivate { * These fields have been moved here from private function local * declarations merely to save stack space during encoding. */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */ +#endif FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */ /* * The data for the verify section @@ -698,11 +713,15 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder encoder->private_->input_capacity = 0; for(i = 0; i < encoder->protected_->channels; i++) { encoder->private_->integer_signal_unaligned[i] = encoder->private_->integer_signal[i] = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal_unaligned[i] = encoder->private_->real_signal[i] = 0; +#endif } for(i = 0; i < 2; i++) { encoder->private_->integer_signal_mid_side_unaligned[i] = encoder->private_->integer_signal_mid_side[i] = 0; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0; +#endif } for(i = 0; i < encoder->protected_->channels; i++) { encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0; @@ -717,8 +736,17 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder encoder->private_->abs_residual_unaligned = encoder->private_->abs_residual = 0; encoder->private_->abs_residual_partition_sums_unaligned = encoder->private_->abs_residual_partition_sums = 0; encoder->private_->raw_bits_per_partition_unaligned = encoder->private_->raw_bits_per_partition = 0; - encoder->private_->loose_mid_side_stereo_frames_exact = (FLAC__double)encoder->protected_->sample_rate * 0.4 / (FLAC__double)encoder->protected_->blocksize; - encoder->private_->loose_mid_side_stereo_frames = (unsigned)(encoder->private_->loose_mid_side_stereo_frames_exact + 0.5); +#ifndef FLAC__INTEGER_ONLY_LIBRARY + encoder->private_->loose_mid_side_stereo_frames = (unsigned)((FLAC__double)encoder->protected_->sample_rate * 0.4 / (FLAC__double)encoder->protected_->blocksize + 0.5); +#else + /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */ + /* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ + FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350); + FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535); + FLAC__ASSERT(encoder->protected_->sample_rate <= 655350); + FLAC__ASSERT(encoder->protected_->blocksize <= 65535); + encoder->private_->loose_mid_side_stereo_frames = (unsigned)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF); +#endif if(encoder->private_->loose_mid_side_stereo_frames == 0) encoder->private_->loose_mid_side_stereo_frames = 1; encoder->private_->loose_mid_side_stereo_frame_count = 0; @@ -734,18 +762,23 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder */ FLAC__cpu_info(&encoder->private_->cpuinfo); /* first default to the non-asm routines */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; +#endif encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients; +#endif /* now override with asm where appropriate */ -#ifndef FLAC__NO_ASM +#ifndef FLAC__INTEGER_ONLY_LIBRARY +# ifndef FLAC__NO_ASM if(encoder->private_->cpuinfo.use_asm) { -#ifdef FLAC__CPU_IA32 +# ifdef FLAC__CPU_IA32 FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); -#ifdef FLAC__HAS_NASM -#ifdef FLAC__SSE_OS +# ifdef FLAC__HAS_NASM +# ifdef FLAC__SSE_OS if(encoder->private_->cpuinfo.data.ia32.sse) { if(encoder->protected_->max_lpc_order < 4) encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4; @@ -757,13 +790,11 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; } else -#endif +# endif /* FLAC__SSE_OS */ if(encoder->private_->cpuinfo.data.ia32._3dnow) encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow; else encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; - if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov) - encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; if(encoder->private_->cpuinfo.data.ia32.mmx) { encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; @@ -772,10 +803,13 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; } -#endif -#endif + if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov) + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; +# endif /* FLAC__HAS_NASM */ +# endif /* FLAC__CPU_IA32 */ } -#endif +# endif /* !FLAC__NO_ASM */ +#endif /* !FLAC__INTEGER_ONLY_LIBRARY */ /* finally override based on wide-ness if necessary */ if(encoder->private_->use_wide_by_block) { encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide; @@ -1348,17 +1382,23 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { x = mid = side = buffer[0][j]; encoder->private_->integer_signal[0][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[0][i] = (FLAC__real)x; +#endif x = buffer[1][j]; encoder->private_->integer_signal[1][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[1][i] = (FLAC__real)x; +#endif mid += x; side -= x; mid >>= 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ encoder->private_->integer_signal_mid_side[1][i] = side; encoder->private_->integer_signal_mid_side[0][i] = mid; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal_mid_side[1][i] = (FLAC__real)side; encoder->private_->real_signal_mid_side[0][i] = (FLAC__real)mid; +#endif encoder->private_->current_sample_number++; } if(i == blocksize) { @@ -1376,7 +1416,9 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c for(channel = 0; channel < channels; channel++) { x = buffer[channel][j]; encoder->private_->integer_signal[channel][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[channel][i] = (FLAC__real)x; +#endif } encoder->private_->current_sample_number++; } @@ -1408,17 +1450,23 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { x = mid = side = buffer[k++]; encoder->private_->integer_signal[0][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[0][i] = (FLAC__real)x; +#endif x = buffer[k++]; encoder->private_->integer_signal[1][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[1][i] = (FLAC__real)x; +#endif 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; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal_mid_side[1][i] = (FLAC__real)side; encoder->private_->real_signal_mid_side[0][i] = (FLAC__real)mid; +#endif encoder->private_->current_sample_number++; } if(i == blocksize) { @@ -1436,7 +1484,9 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder for(channel = 0; channel < channels; channel++) { x = buffer[k++]; encoder->private_->integer_signal[channel][i] = x; +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[channel][i] = (FLAC__real)x; +#endif } encoder->private_->current_sample_number++; } @@ -1498,20 +1548,24 @@ void free_(FLAC__StreamEncoder *encoder) free(encoder->private_->integer_signal_unaligned[i]); encoder->private_->integer_signal_unaligned[i] = 0; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY if(0 != encoder->private_->real_signal_unaligned[i]) { free(encoder->private_->real_signal_unaligned[i]); encoder->private_->real_signal_unaligned[i] = 0; } +#endif } for(i = 0; i < 2; i++) { if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) { free(encoder->private_->integer_signal_mid_side_unaligned[i]); encoder->private_->integer_signal_mid_side_unaligned[i] = 0; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) { free(encoder->private_->real_signal_mid_side_unaligned[i]); encoder->private_->real_signal_mid_side_unaligned[i] = 0; } +#endif } for(channel = 0; channel < encoder->protected_->channels; channel++) { for(i = 0; i < 2; i++) { @@ -1575,13 +1629,17 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size) for(i = 0; ok && i < encoder->protected_->channels; i++) { ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size+4, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]); +#ifndef FLAC__INTEGER_ONLY_LIBRARY ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]); +#endif memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4); encoder->private_->integer_signal[i] += 4; } for(i = 0; ok && i < 2; i++) { ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size+4, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]); +#ifndef FLAC__INTEGER_ONLY_LIBRARY ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]); +#endif memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); encoder->private_->integer_signal_mid_side[i] += 4; } @@ -1796,7 +1854,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f &frame_header, encoder->private_->subframe_bps[channel], encoder->private_->integer_signal[channel], +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal[channel], +#endif encoder->private_->subframe_workspace_ptr[channel], encoder->private_->partitioned_rice_contents_workspace_ptr[channel], encoder->private_->residual_workspace[channel], @@ -1824,7 +1884,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f &frame_header, encoder->private_->subframe_bps_mid_side[channel], encoder->private_->integer_signal_mid_side[channel], +#ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->real_signal_mid_side[channel], +#endif 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], @@ -1958,7 +2020,9 @@ FLAC__bool process_subframe_( const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], +#ifndef FLAC__INTEGER_ONLY_LIBRARY const FLAC__real real_signal[], +#endif FLAC__Subframe *subframe[2], FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], FLAC__int32 *residual[2], @@ -1966,13 +2030,19 @@ FLAC__bool process_subframe_( unsigned *best_bits ) { +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; +#else + FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; +#endif +#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__double lpc_residual_bits_per_sample; FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */ FLAC__double lpc_error[FLAC__MAX_LPC_ORDER]; unsigned min_lpc_order, max_lpc_order, lpc_order; - unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; +#endif + unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; unsigned rice_parameter; unsigned _candidate_bits, _best_bits; unsigned _best_subframe; @@ -1988,11 +2058,18 @@ FLAC__bool process_subframe_( unsigned signal_is_constant = false; 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); /* check for constant subframe */ - if(!encoder->private_->disable_constant_subframes && fixed_residual_bits_per_sample[1] == 0.0) { - /* the above means integer_signal+FLAC__MAX_FIXED_ORDER is constant, now we just have to check the warmup samples */ + if( + !encoder->private_->disable_constant_subframes && +#ifndef FLAC__INTEGER_ONLY_LIBRARY + fixed_residual_bits_per_sample[1] == 0.0 +#else + fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO +#endif + ) { + /* the above means it's possible all samples are the same value; now double-check it: */ unsigned i; signal_is_constant = true; - for(i = 1; i <= FLAC__MAX_FIXED_ORDER; i++) { + for(i = 1; i < frame_header->blocksize; i++) { if(integer_signal[0] != integer_signal[i]) { signal_is_constant = false; break; @@ -2017,9 +2094,15 @@ FLAC__bool process_subframe_( min_fixed_order = max_fixed_order = guess_fixed_order; } for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) { +#ifndef FLAC__INTEGER_ONLY_LIBRARY if(fixed_residual_bits_per_sample[fixed_order] >= (FLAC__float)subframe_bps) continue; /* don't even try */ rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */ +#else + if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps) + continue; /* don't even try */ + rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ +#endif #ifndef FLAC__SYMMETRIC_RICE rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ #endif @@ -2056,6 +2139,7 @@ FLAC__bool process_subframe_( } } +#ifndef FLAC__INTEGER_ONLY_LIBRARY /* encode lpc */ if(encoder->protected_->max_lpc_order > 0) { if(encoder->protected_->max_lpc_order >= frame_header->blocksize) @@ -2133,6 +2217,7 @@ FLAC__bool process_subframe_( } } } +#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ } } @@ -2256,6 +2341,7 @@ unsigned evaluate_fixed_subframe_( return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (order * subframe_bps) + residual_bits; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned evaluate_lpc_subframe_( FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], @@ -2335,6 +2421,7 @@ unsigned evaluate_lpc_subframe_( return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits; } +#endif unsigned evaluate_verbatim_subframe_( const FLAC__int32 signal[], diff --git a/src/libOggFLAC/seekable_stream_decoder.c b/src/libOggFLAC/seekable_stream_decoder.c index cabfb61f..c9ad6fbc 100644 --- a/src/libOggFLAC/seekable_stream_decoder.c +++ b/src/libOggFLAC/seekable_stream_decoder.c @@ -863,11 +863,19 @@ FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLA pos = (right_pos + left_pos) / 2; } else { +#ifndef FLAC__INTEGER_ONLY_LIBRARY #if defined _MSC_VER || defined __MINGW32__ /* with MSVC you have to spoon feed it the casting */ pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos)); #else pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos)); +#endif +#else + /* a little less accurate: */ + if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) + pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample)); + else /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16)); #endif /* @@@ TODO: might want to limit pos to some distance * before EOF, to make sure we land before the last frame,