📄 fixed.c
字号:
/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <math.h>#include "private/bitmath.h"#include "private/fixed.h"#include "FLAC/assert.h"#ifndef M_LN2/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */#define M_LN2 0.69314718055994530942#endif#ifdef min#undef min#endif#define min(x,y) ((x) < (y)? (x) : (y))#ifdef local_abs#undef local_abs#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<<fracbits)/n. */ fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1); err <<= fracbits; err /= n; /* err now holds err/n with fracbits fractional bits */ /* * Whittle err down to 16 bits max. 16 significant bits is enough for * our purposes. */ FLAC__ASSERT(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<<fracbits)/n. */ fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1); err <<= fracbits; err /= n; /* err now holds err/n with fracbits fractional bits */ /* * Whittle err down to 16 bits max. 16 significant bits is enough for * our purposes. */ FLAC__ASSERT(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -