⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 takehiro.c

📁 音频编码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	MP3 huffman table selecting and bit counting * *	Copyright (c) 1999-2005 Takehiro TOMINAGA *	Copyright (c) 2002-2005 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* $Id: takehiro.c,v 1.61.2.1 2005/11/20 14:08:25 bouvigne Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <assert.h>#include "util.h"#include "l3side.h"#include "tables.h"#include "quantize_pvt.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endifstatic const struct{    const int region0_count;    const int region1_count;} subdv_table[ 23 ] ={{0, 0}, /* 0 bands */{0, 0}, /* 1 bands */{0, 0}, /* 2 bands */{0, 0}, /* 3 bands */{0, 0}, /* 4 bands */{0, 1}, /* 5 bands */{1, 1}, /* 6 bands */{1, 1}, /* 7 bands */{1, 2}, /* 8 bands */{2, 2}, /* 9 bands */{2, 3}, /* 10 bands */{2, 3}, /* 11 bands */{3, 4}, /* 12 bands */{3, 4}, /* 13 bands */{3, 4}, /* 14 bands */{4, 5}, /* 15 bands */{4, 5}, /* 16 bands */{4, 6}, /* 17 bands */{5, 6}, /* 18 bands */{5, 6}, /* 19 bands */{5, 7}, /* 20 bands */{6, 7}, /* 21 bands */{6, 7}, /* 22 bands */};/********************************************************************* * nonlinear quantization of xr  * More accurate formula than the ISO formula.  Takes into account * the fact that we are quantizing xr -> ix, but we want ix^4/3 to be  * as close as possible to x^4/3.  (taking the nearest int would mean * ix is as close as possible to xr, which is different.) * * From Segher Boessenkool <segher@eastsite.nl>  11/1999 * * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro * Tominaga. If you need the ASM code, check CVS circa Aug 2000. * * 01/2004: Optimizations by Gabriel Bouvigne *********************************************************************/void quantize_lines_xrpow_01(int l, FLOAT istep, const FLOAT* xr, int* ix){    const FLOAT compareval0 = (1.0 - 0.4054)/istep;    assert (l>0);    l= l>>1;    while (l--) {        *(ix++) = (compareval0 > *xr++) ? 0 : 1;        *(ix++) = (compareval0 > *xr++) ? 0 : 1;    }}#ifdef TAKEHIRO_IEEE754_HACKtypedef union {    float f;    int i;} fi_union;#define MAGIC_FLOAT (65536*(128))#define MAGIC_INT 0x4b000000void quantize_lines_xrpow(int l, FLOAT istep, const FLOAT* xp, int* pi){    fi_union *fi;    int remaining;    assert (l>0);    fi = (fi_union *)pi;    l = l>>1;    remaining = l%2;    l = l>>1;    while (l--) {	    double x0 = istep * xp[0];	    double x1 = istep * xp[1];	    double x2 = istep * xp[2];	    double x3 = istep * xp[3];	    x0 += MAGIC_FLOAT; fi[0].f = x0;	    x1 += MAGIC_FLOAT; fi[1].f = x1;	    x2 += MAGIC_FLOAT; fi[2].f = x2;	    x3 += MAGIC_FLOAT; fi[3].f = x3;	    fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];	    fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];	    fi[2].f = x2 + (adj43asm - MAGIC_INT)[fi[2].i];	    fi[3].f = x3 + (adj43asm - MAGIC_INT)[fi[3].i];	    fi[0].i -= MAGIC_INT;	    fi[1].i -= MAGIC_INT;	    fi[2].i -= MAGIC_INT;	    fi[3].i -= MAGIC_INT;	    fi += 4;	    xp += 4;    };    if (remaining) {	    double x0 = istep * xp[0];	    double x1 = istep * xp[1];	    x0 += MAGIC_FLOAT; fi[0].f = x0;	    x1 += MAGIC_FLOAT; fi[1].f = x1;	    fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];	    fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];	    fi[0].i -= MAGIC_INT;	    fi[1].i -= MAGIC_INT;    }}#  define ROUNDFAC -0.0946void quantize_lines_xrpow_ISO(int l, FLOAT istep, const FLOAT* xp, int* pi){    fi_union *fi;    int remaining;    assert (l>0);    fi = (fi_union *)pi;    l = l>>1;    remaining = l%2;    l = l>>1;    while (l--) {	        fi[0].f = istep * xp[0] + (ROUNDFAC + MAGIC_FLOAT);	        fi[1].f = istep * xp[1] + (ROUNDFAC + MAGIC_FLOAT);	        fi[2].f = istep * xp[2] + (ROUNDFAC + MAGIC_FLOAT);	        fi[3].f = istep * xp[3] + (ROUNDFAC + MAGIC_FLOAT);	        fi[0].i -= MAGIC_INT;	        fi[1].i -= MAGIC_INT;	        fi[2].i -= MAGIC_INT;	        fi[3].i -= MAGIC_INT;	        fi+=4;	        xp+=4;    };    if (remaining) {	        fi[0].f = istep * xp[0] + (ROUNDFAC + MAGIC_FLOAT);	        fi[1].f = istep * xp[1] + (ROUNDFAC + MAGIC_FLOAT);	        fi[0].i -= MAGIC_INT;	        fi[1].i -= MAGIC_INT;    }}#else/********************************************************************* * XRPOW_FTOI is a macro to convert floats to ints.   * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x] *                                         ROUNDFAC= -0.0946 * * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]    *                                   ROUNDFAC=0.4054 * * Note: using floor() or (int) is extremely slow. On machines where * the TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile * to write some ASM for XRPOW_FTOI().   *********************************************************************/#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))#define QUANTFAC(rx)  adj43[rx]#define ROUNDFAC 0.4054void quantize_lines_xrpow(int l, FLOAT istep, const FLOAT* xr, int* ix){    int remaining;    assert (l>0);    l = l>>1;    remaining = l%2;    l = l>>1;    while (l--) {	    FLOAT	x0, x1, x2, x3;	    int	rx0, rx1, rx2, rx3;        x0 = *xr++ * istep;	    x1 = *xr++ * istep;	    XRPOW_FTOI(x0, rx0);	    x2 = *xr++ * istep;	    XRPOW_FTOI(x1, rx1);	    x3 = *xr++ * istep;	    XRPOW_FTOI(x2, rx2);	    x0 += QUANTFAC(rx0);	    XRPOW_FTOI(x3, rx3);	    x1 += QUANTFAC(rx1);	    XRPOW_FTOI(x0,*ix++);	    x2 += QUANTFAC(rx2);	    XRPOW_FTOI(x1,*ix++);	    x3 += QUANTFAC(rx3);	    XRPOW_FTOI(x2,*ix++);	    XRPOW_FTOI(x3,*ix++);    };    if (remaining) {	    FLOAT	x0, x1;	    int	rx0, rx1;        x0 = *xr++ * istep;	    x1 = *xr++ * istep;	    XRPOW_FTOI(x0, rx0);	    XRPOW_FTOI(x1, rx1);	    x0 += QUANTFAC(rx0);	    x1 += QUANTFAC(rx1);	    XRPOW_FTOI(x0,*ix++);	    XRPOW_FTOI(x1,*ix++);    }}void quantize_lines_xrpow_ISO(int l, FLOAT istep, const FLOAT* xr, int* ix){    const FLOAT compareval0 = (1.0 - 0.4054)/istep;    const FLOAT compareval1 = (2.0 - 0.4054)/istep;    assert (l>0);    /* depending on architecture, it may be worth calculating a few more    compareval's.    eg.  compareval1 = (2.0 - 0.4054)/istep;    .. and then after the first compare do this ...    if compareval1>*xr then ix = 1;    On a pentium166, it's only worth doing the one compare (as done here),    as the second compare becomes more expensive than just calculating    the value. Architectures with slow FP operations may want to add some    more comparevals. try it and send your diffs statistically speaking    73% of all xr*istep values give ix=0    16% will give 1    4%  will give 2    */    while (l--) {        if (compareval0 > *xr) {            *(ix++) = 0;            xr++;        } else if (compareval1 > *xr) {            *(ix++) = 1;            xr++;        } else {            /*    *(ix++) = (int)( istep*(*(xr++))  + 0.4054); */            XRPOW_FTOI(  istep*(*(xr++))  + ROUNDFAC , *(ix++) );        }    }}#endif/********************************************************************* * Quantization function * This function will select which lines to quantize and call the * proper quantization function *********************************************************************/static void quantize_xrpow(const FLOAT *xp, int *pi, FLOAT istep, gr_info * const cod_info, calc_noise_data* prev_noise, lame_internal_flags * const gfc){    /* quantize on xr^(3/4) instead of xr */    int sfb;    int sfbmax;    int j=0;    int prev_data_use;    int *iData;    int accumulate=0;    int accumulate01=0;    int *acc_iData;    const FLOAT *acc_xp;    iData = pi;    acc_xp = xp;    acc_iData = iData;    /* Reusing previously computed data does not seems to work if global gain    is changed. Finding why it behaves this way would allow to use a cache of     previously computed values (let's 10 cached values per sfb) that would     probably provide a noticeable speedup*/    prev_data_use = (prev_noise  &&                     (cod_info->global_gain == prev_noise->global_gain));    if (cod_info->block_type == SHORT_TYPE)        sfbmax = 38;    else         sfbmax = 21;    for (sfb = 0; sfb <= sfbmax; sfb++) {	    int step = -1;        if (prev_data_use || cod_info->block_type == NORM_TYPE) {            step =	            cod_info->global_gain	            - ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0))	               << (cod_info->scalefac_scale + 1))	            - cod_info->subblock_gain[cod_info->window[sfb]] * 8;        }        assert( cod_info->width[sfb] >= 0 );        if (prev_data_use && (prev_noise->step[sfb] == step)){            /* do not recompute this part,               but compute accumulated lines */            if (accumulate) {                gfc->quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);                accumulate = 0;            }            if (accumulate01) {                quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);                accumulate01 = 0;            }        } else { /*should compute this part*/            int l;            l = cod_info->width[sfb];            if ((j+cod_info->width[sfb])>cod_info->max_nonzero_coeff) {                /*do not compute upper zero part*/                int usefullsize;                usefullsize = cod_info->max_nonzero_coeff - j +1;                memset(&pi[cod_info->max_nonzero_coeff],0,                    sizeof(int)*(576-cod_info->max_nonzero_coeff));                l = usefullsize;                if (l<0) {                    l = 0;                }                /* no need to compute higher sfb values */                sfb = sfbmax + 1;            }            /*accumulate lines to quantize*/            if (!accumulate && !accumulate01) {                acc_iData = iData;                acc_xp = xp;            }            if (prev_noise &&                prev_noise->sfb_count1 > 0 &&                sfb >= prev_noise->sfb_count1 &&                prev_noise->step[sfb] > 0 &&                step >= prev_noise->step[sfb]) {                if (accumulate) {                    gfc->quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);                    accumulate = 0;                    acc_iData = iData;                    acc_xp = xp;                }                accumulate01 += l;            } else {                if (accumulate01) {                    quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);                    accumulate01 = 0;                    acc_iData = iData;                    acc_xp = xp;                }                accumulate += l;            }            if ( l <= 0 ) {                /*  rh: 20040215                 *  may happen due to "prev_data_use" optimization                  */                if (accumulate01) {                    quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);                    accumulate01 = 0;                }                if (accumulate) {                    gfc->quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);                    accumulate = 0;                }                break;  /* ends for-loop */            }        }        if (sfb <= sfbmax) {            iData += cod_info->width[sfb];            xp += cod_info->width[sfb];            j += cod_info->width[sfb];        }    }    if (accumulate) { /*last data part*/        gfc->quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);        accumulate = 0;    }    if (accumulate01) { /*last data part*/        quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);        accumulate01 = 0;    }}void quantize_init (lame_internal_flags * const gfc){    if (gfc->quantization)        gfc->quantize_lines_xrpow = quantize_lines_xrpow;    else        gfc->quantize_lines_xrpow = quantize_lines_xrpow_ISO;}/*************************************************************************//*	      ix_max							 *//*************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -