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

📄 vbrquantize.c

📁 音频编码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	MP3 quantization * *	Copyright (c) 1999-2000 Mark Taylor *	Copyright (c) 2000-2005 Robert Hegemann * * 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: vbrquantize.c,v 1.103.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 "quantize_pvt.h"#include "vbrquantize.h"#ifdef WITH_DMALLOC#  include <dmalloc.h>#endifstruct algo_s;typedef struct algo_s algo_t;typedef void (*quantize_f) (const algo_t *);typedef int (*find_f) (const FLOAT *, const FLOAT *, FLOAT, int, int);typedef int (*alloc_sf_f) (const algo_t *, int *, const int *, int);struct algo_s {    find_f  find;    quantize_f quantize;    alloc_sf_f alloc;    const FLOAT *xr34orig;    lame_internal_flags *gfc;    gr_info *cod_info;    int mingain_l;    int mingain_s[3];};/*  Remarks on optimizing compilers: * *  the MSVC compiler may get into aliasing problems when accessing *  memory through the fi_union. declaring it volatile does the trick here * *  the calc_sfb_noise_* functions are not inlined because the intel compiler *  optimized executeables won't work as expected anymore */#ifdef _MSC_VER#  define VOLATILE volatile#else#  define VOLATILE#endiftypedef VOLATILE union {    float   f;    int     i;} fi_union;#define DOUBLEX double#define MAGIC_FLOAT_def (65536*(128))#define MAGIC_INT_def    0x4b000000#ifdef TAKEHIRO_IEEE754_HACK#  define ROUNDFAC_def -0.0946f#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 *********************************************************************/#  define QUANTFAC(rx)  adj43[rx]#  define ROUNDFAC_def 0.4054f#  define XRPOW_FTOI(src,dest) ((dest) = (int)(src))#endifstatic int const MAGIC_INT = MAGIC_INT_def;static DOUBLEX const ROUNDFAC = ROUNDFAC_def;static DOUBLEX const MAGIC_FLOAT = (65536 * (128));static DOUBLEX const ROUNDFAC_plus_MAGIC_FLOAT = ROUNDFAC_def + MAGIC_FLOAT_def;static intvalid_sf(int sf){    return (sf >= 0 ? (sf <= 255 ? sf : 255) : 0);}static  FLOATmax_x34(const FLOAT * xr34, unsigned int bw){    FLOAT   xfsf = 0;    int     j = bw >> 1;    int     remaining = j % 2;    assert(bw >= 0);    for (j >>= 1; j > 0; --j) {        if (xfsf < xr34[0]) {            xfsf = xr34[0];        }        if (xfsf < xr34[1]) {            xfsf = xr34[1];        }        if (xfsf < xr34[2]) {            xfsf = xr34[2];        }        if (xfsf < xr34[3]) {            xfsf = xr34[3];        }        xr34 += 4;    }    if (remaining) {        if (xfsf < xr34[0]) {            xfsf = xr34[0];        }        if (xfsf < xr34[1]) {            xfsf = xr34[1];        }    }    return xfsf;}static intfind_lowest_scalefac(const FLOAT xr34){    FLOAT   xfsf;    int     sf = 128, sf_ok = 10000, delsf = 128, i;    for (i = 0; i < 8; ++i) {        delsf >>= 1;        xfsf = IPOW20(sf) * xr34;        if (xfsf <= IXMAX_VAL) {            sf_ok = sf;            sf -= delsf;        }        else {            sf += delsf;        }    }    if (sf_ok < 255) {        sf = sf_ok;    }    return sf;}static voidk_34_4(DOUBLEX x[4], int l3[4]){#ifdef TAKEHIRO_IEEE754_HACK    fi_union fi[4];    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);    x[0] += MAGIC_FLOAT;    fi[0].f = x[0];    x[1] += MAGIC_FLOAT;    fi[1].f = x[1];    x[2] += MAGIC_FLOAT;    fi[2].f = x[2];    x[3] += MAGIC_FLOAT;    fi[3].f = x[3];    fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT];    fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT];    fi[2].f = x[2] + adj43asm[fi[2].i - MAGIC_INT];    fi[3].f = x[3] + adj43asm[fi[3].i - MAGIC_INT];    l3[0] = fi[0].i - MAGIC_INT;    l3[1] = fi[1].i - MAGIC_INT;    l3[2] = fi[2].i - MAGIC_INT;    l3[3] = fi[3].i - MAGIC_INT;#else    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);    XRPOW_FTOI(x[0], l3[0]);    XRPOW_FTOI(x[1], l3[1]);    XRPOW_FTOI(x[2], l3[2]);    XRPOW_FTOI(x[3], l3[3]);    x[0] += QUANTFAC(l3[0]);    x[1] += QUANTFAC(l3[1]);    x[2] += QUANTFAC(l3[2]);    x[3] += QUANTFAC(l3[3]);    XRPOW_FTOI(x[0], l3[0]);    XRPOW_FTOI(x[1], l3[1]);    XRPOW_FTOI(x[2], l3[2]);    XRPOW_FTOI(x[3], l3[3]);#endif}static voidk_34_2(DOUBLEX x[2], int l3[2]){#ifdef TAKEHIRO_IEEE754_HACK    fi_union fi[2];    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL);    x[0] += MAGIC_FLOAT;    fi[0].f = x[0];    x[1] += MAGIC_FLOAT;    fi[1].f = x[1];    fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT];    fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT];    l3[0] = fi[0].i - MAGIC_INT;    l3[1] = fi[1].i - MAGIC_INT;#else    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL);    XRPOW_FTOI(x[0], l3[0]);    XRPOW_FTOI(x[1], l3[1]);    x[0] += QUANTFAC(l3[0]);    x[1] += QUANTFAC(l3[1]);    XRPOW_FTOI(x[0], l3[0]);    XRPOW_FTOI(x[1], l3[1]);#endif}static voidk_iso_4(DOUBLEX x[4], int l3[4]){#ifdef TAKEHIRO_IEEE754_HACK    fi_union fi[4];    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);    x[0] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[0].f = x[0];    x[1] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[1].f = x[1];    x[2] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[2].f = x[2];    x[3] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[3].f = x[3];    l3[0] = fi[0].i - MAGIC_INT;    l3[1] = fi[1].i - MAGIC_INT;    l3[2] = fi[2].i - MAGIC_INT;    l3[3] = fi[3].i - MAGIC_INT;#else    l3[0] = x[0] + ROUNDFAC;    l3[1] = x[1] + ROUNDFAC;    l3[2] = x[2] + ROUNDFAC;    l3[3] = x[3] + ROUNDFAC;#endif}static voidk_iso_2(DOUBLEX x[2], int l3[2]){#ifdef TAKEHIRO_IEEE754_HACK    fi_union fi[2];    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL);    x[0] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[0].f = x[0];    x[1] += ROUNDFAC_plus_MAGIC_FLOAT;    fi[1].f = x[1];    l3[0] = fi[0].i - MAGIC_INT;    l3[1] = fi[1].i - MAGIC_INT;#else    l3[0] = x[0] + ROUNDFAC;    l3[1] = x[1] + ROUNDFAC;#endif}/*  do call the calc_sfb_noise_* functions only with sf values *  for which holds: sfpow34*xr34 <= IXMAX_VAL */static  FLOATcalc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, int sf){    DOUBLEX x[4];    int     l3[4];    const int SF = valid_sf(sf);    const FLOAT sfpow = POW20(SF); /*pow(2.0,sf/4.0); */    const FLOAT sfpow34 = IPOW20(SF); /*pow(sfpow,-3.0/4.0); */    FLOAT   xfsf = 0;    int     j = bw >> 1;    int     remaining = j % 2;    assert(bw >= 0);    for (j >>= 1; j > 0; --j) {        x[0] = sfpow34 * xr34[0];        x[1] = sfpow34 * xr34[1];        x[2] = sfpow34 * xr34[2];        x[3] = sfpow34 * xr34[3];        k_34_4(x, l3);        x[0] = fabs(xr[0]) - sfpow * pow43[l3[0]];        x[1] = fabs(xr[1]) - sfpow * pow43[l3[1]];        x[2] = fabs(xr[2]) - sfpow * pow43[l3[2]];        x[3] = fabs(xr[3]) - sfpow * pow43[l3[3]];        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);        xr += 4;        xr34 += 4;    }    if (remaining) {        x[0] = sfpow34 * xr34[0];        x[1] = sfpow34 * xr34[1];        k_34_2(x, l3);        x[0] = fabs(xr[0]) - sfpow * pow43[l3[0]];        x[1] = fabs(xr[1]) - sfpow * pow43[l3[1]];        xfsf += x[0] * x[0] + x[1] * x[1];    }    return xfsf;}static  FLOATcalc_sfb_noise_ISO(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, int sf){    DOUBLEX x[4];    int     l3[4];    const int SF = valid_sf(sf);    const FLOAT sfpow = POW20(SF); /*pow(2.0,sf/4.0); */    const FLOAT sfpow34 = IPOW20(SF); /*pow(sfpow,-3.0/4.0); */    FLOAT   xfsf = 0;    int     j = bw >> 1;    int     remaining = j % 2;    assert(bw >= 0);    for (j >>= 1; j > 0; --j) {        x[0] = sfpow34 * xr34[0];        x[1] = sfpow34 * xr34[1];        x[2] = sfpow34 * xr34[2];        x[3] = sfpow34 * xr34[3];        k_iso_4(x, l3);        x[0] = fabs(xr[0]) - sfpow * pow43[l3[0]];        x[1] = fabs(xr[1]) - sfpow * pow43[l3[1]];        x[2] = fabs(xr[2]) - sfpow * pow43[l3[2]];        x[3] = fabs(xr[3]) - sfpow * pow43[l3[3]];        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);        xr += 4;        xr34 += 4;    }    if (remaining) {        x[0] = sfpow34 * xr34[0];        x[1] = sfpow34 * xr34[1];        k_iso_2(x, l3);        x[0] = fabs(xr[0]) - sfpow * pow43[l3[0]];        x[1] = fabs(xr[1]) - sfpow * pow43[l3[1]];        xfsf += x[0] * x[0] + x[1] * x[1];    }    return xfsf;}/* the find_scalefac* routines calculate * a quantization step size which would * introduce as much noise as is allowed. * The larger the step size the more * quantization noise we'll get. The * scalefactors are there to lower the * global step size, allowing limited * differences in quantization step sizes * per band (shaping the noise). */static intfind_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, int bw, int sf_min){    int     sf = 128, sf_ok = 10000, delsf = 128, i;    for (i = 0; i < 8; ++i) {        delsf >>= 1;        if (sf <= sf_min) {            sf += delsf;        }        else {            if ((sf < 255 && calc_sfb_noise_x34(xr, xr34, bw, sf + 1) > l3_xmin)                || calc_sfb_noise_x34(xr, xr34, bw, sf) > l3_xmin                || calc_sfb_noise_x34(xr, xr34, bw, sf - 1) > l3_xmin) {                /* distortion.  try a smaller scalefactor */                sf -= delsf;            }            else {                sf_ok = sf;                sf += delsf;            }        }    }    /*  returning a scalefac without distortion, if possible     */    if (sf_ok <= 255) {        sf = sf_ok;    }    return sf;}static intfind_scalefac_ISO(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, int bw, int sf_min){    int     sf = 128, sf_ok = 10000, delsf = 128, i;    for (i = 0; i < 8; ++i) {        delsf >>= 1;        if (sf <= sf_min) {            sf += delsf;        }        else {            if ((sf < 255 && calc_sfb_noise_ISO(xr, xr34, bw, sf + 1) > l3_xmin)                || calc_sfb_noise_ISO(xr, xr34, bw, sf) > l3_xmin                || calc_sfb_noise_ISO(xr, xr34, bw, sf - 1) > l3_xmin) {                /* distortion.  try a smaller scalefactor */                sf -= delsf;            }            else {                sf_ok = sf;                sf += delsf;

⌨️ 快捷键说明

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