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

📄 specrec.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 4 页
字号:
                {
                    ics->sect_sfb_offset[0][i] = swb_offset_512_window[sf_index][i];
                    ics->swb_offset[i] = swb_offset_512_window[sf_index][i];
                }
            } else /* if (hDecoder->frameLength == 480) */ {
                for (i = 0; i < ics->num_swb; i++)
                {
                    ics->sect_sfb_offset[0][i] = swb_offset_480_window[sf_index][i];
                    ics->swb_offset[i] = swb_offset_480_window[sf_index][i];
                }
            }
            ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
            ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
        } else {
#endif
            for (i = 0; i < ics->num_swb; i++)
            {
                ics->group[0].sfb[i].sect_sfb_offset = swb_offset_1024_window[sf_index][i];
                ics->swb_offset[i] = swb_offset_1024_window[sf_index][i];
            }
            ics->group[0].sfb[ics->num_swb].sect_sfb_offset = hDecoder->frameLength;
            ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
#ifdef LD_DEC
        }
#endif
        return 0;
    case EIGHT_SHORT_SEQUENCE:
        ics->num_windows = 8;
        ics->group_end = ics->group+1;
        ics->group[0].window_group_length = 1;
        ics->num_swb = num_swb_128_window[sf_index];

        for (i = 0; i < ics->num_swb; i++)
            ics->swb_offset[i] = swb_offset_128_window[sf_index][i];
        ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8;

        for (i = 0; i < ics->num_windows-1; i++) {
            if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
            {
                ics->group_end->window_group_length = 1;
                ++ics->group_end;
            } else {
                ics->group_end[-1].window_group_length += 1;
            }
        }

        /* preparation of sect_sfb_offset for short blocks */
        for (g = ics->group; g != ics->group_end; g++)
        {
            uint16_t width;
            uint8_t sect_sfb = 0;
            uint16_t offset = 0;

            for (i = 0; i < ics->num_swb; i++)
            {
                if (i+1 == ics->num_swb)
                {
                    width = (hDecoder->frameLength/8) - swb_offset_128_window[sf_index][i];
                } else {
                    width = swb_offset_128_window[sf_index][i+1] -
                        swb_offset_128_window[sf_index][i];
                }
                width *= g->window_group_length;
                g->sfb[sect_sfb++].sect_sfb_offset = offset;
                offset += width;
            }
            g->sfb[sect_sfb].sect_sfb_offset = offset;
        }
        return 0;
    default:
        return 1;
    }
}

/* iquant() *
/* output = sign(input)*abs(input)^(4/3) */
/**/
static INLINE real_t iquant(int16_t q, const real_t *tab, uint8_t *error)
{
#ifdef FIXED_POINT
/* For FIXED_POINT the iq_table is prescaled by 3 bits (iq_table[]/8) */
/* BIG_IQ_TABLE allows you to use the full 8192 value table, if this is not
 * defined a 1026 value table and interpolation will be used
 */
#ifndef BIG_IQ_TABLE
    static const real_t errcorr[] = {
        REAL_CONST(0), REAL_CONST(1.0/8.0), REAL_CONST(2.0/8.0), REAL_CONST(3.0/8.0),
        REAL_CONST(4.0/8.0),  REAL_CONST(5.0/8.0), REAL_CONST(6.0/8.0), REAL_CONST(7.0/8.0),
        REAL_CONST(0)
    };
    real_t x1, x2;
#endif
    int16_t sgn = 1;

    if (q < 0)
    {
        q = -q;
        sgn = -1;
    }

    if (q < IQ_TABLE_SIZE)
    {
//#define IQUANT_PRINT
#ifdef IQUANT_PRINT
        //printf("0x%.8X\n", sgn * tab[q]);
        printf("%d\n", sgn * tab[q]);
#endif
        return sgn * tab[q];
    }

#ifndef BIG_IQ_TABLE
    if (q >= 8192)
    {
        *error = 17;
        return 0;
    }

    /* linear interpolation */
    x1 = tab[q>>3];
    x2 = tab[(q>>3) + 1];
    return sgn * 16 * (MUL_R(errcorr[q&7],(x2-x1)) + x1);
#else
    *error = 17;
    return 0;
#endif

#else
    if (q < 0)
    {
        /* tab contains a value for all possible q [0,8192] */
        if (-q < IQ_TABLE_SIZE)
            return -tab[-q];

        *error = 17;
        return 0;
    } else {
        /* tab contains a value for all possible q [0,8192] */
        if (q < IQ_TABLE_SIZE)
            return tab[q];

        *error = 17;
        return 0;
    }
#endif
}

#ifndef FIXED_POINT
ALIGN static const real_t pow2sf_tab[] = {
    2.9802322387695313E-008, 5.9604644775390625E-008, 1.1920928955078125E-007,
    2.384185791015625E-007, 4.76837158203125E-007, 9.5367431640625E-007,
    1.9073486328125E-006, 3.814697265625E-006, 7.62939453125E-006,
    1.52587890625E-005, 3.0517578125E-005, 6.103515625E-005,
    0.0001220703125, 0.000244140625, 0.00048828125,
    0.0009765625, 0.001953125, 0.00390625,
    0.0078125, 0.015625, 0.03125,
    0.0625, 0.125, 0.25,
    0.5, 1.0, 2.0,
    4.0, 8.0, 16.0, 32.0,
    64.0, 128.0, 256.0,
    512.0, 1024.0, 2048.0,
    4096.0, 8192.0, 16384.0,
    32768.0, 65536.0, 131072.0,
    262144.0, 524288.0, 1048576.0,
    2097152.0, 4194304.0, 8388608.0,
    16777216.0, 33554432.0, 67108864.0,
    134217728.0, 268435456.0, 536870912.0,
    1073741824.0, 2147483648.0, 4294967296.0,
    8589934592.0, 17179869184.0, 34359738368.0,
    68719476736.0, 137438953472.0, 274877906944.0
};
#endif

/* quant_to_spec: perform dequantisation and scaling
 * and in case of short block it also does the deinterleaving
 */
/*
  For ONLY_LONG_SEQUENCE windows (num_window_groups = 1,
  window_group_length[0] = 1) the spectral data is in ascending spectral
  order.
  For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the
  grouping in the following manner:
  - Groups are ordered sequentially
  - Within a group, a scalefactor band consists of the spectral data of all
    grouped SHORT_WINDOWs for the associated scalefactor window band. To
    clarify via example, the length of a group is in the range of one to eight
    SHORT_WINDOWs.
  - If there are eight groups each with length one (num_window_groups = 8,
    window_group_length[0..7] = 1), the result is a sequence of eight spectra,
    each in ascending spectral order.
  - If there is only one group with length eight (num_window_groups = 1,
    window_group_length[0] = 8), the result is that spectral data of all eight
    SHORT_WINDOWs is interleaved by scalefactor window bands.
  - Within a scalefactor window band, the coefficients are in ascending
    spectral order.
*/
static uint8_t quant_to_spec(NeAACDecHandle hDecoder,
                             ic_stream *ics, int16_t *quant_data,
                             uint16_t frame_len)
{
    ALIGN static const real_t pow2_table[] =
    {
        COEF_CONST(1.0),
        COEF_CONST(1.1892071150027210667174999705605), /* 2^0.25 */
        COEF_CONST(1.4142135623730950488016887242097), /* 2^0.5 */
        COEF_CONST(1.6817928305074290860622509524664) /* 2^0.75 */
    };
    const real_t *tab = iq_table;
	real_t *spec_data = ics->buffer;

    uint8_t sfb, win;
    uint16_t width, bin, k, gindex, wa, wb;
    uint8_t error = 0; /* Init error flag */
#ifndef FIXED_POINT
    real_t scf;
#endif
	ic_group *g;

    k = 0;
    gindex = 0;

    for (g = ics->group; g != ics->group_end; g++)
    {
        uint16_t j = 0;
        uint16_t gincrease = 0;
        uint16_t win_inc = ics->swb_offset[ics->num_swb];

        for (sfb = 0; sfb < ics->num_swb; sfb++)
        {
            int32_t exp, frac;

            width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb];

            /* this could be scalefactor for IS or PNS, those can be negative or bigger then 255 */
            /* just ignore them */
            if (g->sfb[sfb].scale_factors < 0 || g->sfb[sfb].scale_factors > 255)
            {
                exp = 0;
                frac = 0;
            } else {
                /* ics->scale_factors[g][sfb] must be between 0 and 255 */
                exp = (g->sfb[sfb].scale_factors /* - 100 */) >> 2;
                /* frac must always be > 0 */
                frac = (g->sfb[sfb].scale_factors /* - 100 */) & 3;
            }

#ifdef FIXED_POINT
            exp -= 25;
            /* IMDCT pre-scaling */
            if (hDecoder->object_type == LD)
            {
                exp -= 6 /*9*/;
            } else {
                if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
                    exp -= 4 /*7*/;
                else
                    exp -= 7 /*10*/;
            }
#endif

            wa = gindex + j;

#ifndef FIXED_POINT
            scf = pow2sf_tab[exp/*+25*/] * pow2_table[frac];
#endif

            for (win = 0; win < g->window_group_length; win++)
            {
                for (bin = 0; bin < width; bin += 4)
                {
#ifndef FIXED_POINT
                    wb = wa + bin;

                    spec_data[wb+0] = iquant(quant_data[k+0], tab, &error) * scf;
                    spec_data[wb+1] = iquant(quant_data[k+1], tab, &error) * scf;                        
                    spec_data[wb+2] = iquant(quant_data[k+2], tab, &error) * scf;                        
                    spec_data[wb+3] = iquant(quant_data[k+3], tab, &error) * scf;
                        
#else
                    real_t iq0 = iquant(quant_data[k+0], tab, &error);
                    real_t iq1 = iquant(quant_data[k+1], tab, &error);
                    real_t iq2 = iquant(quant_data[k+2], tab, &error);
                    real_t iq3 = iquant(quant_data[k+3], tab, &error);

                    wb = wa + bin;

                    if (exp < 0)
                    {
                        spec_data[wb+0] = iq0 >>= -exp;
                        spec_data[wb+1] = iq1 >>= -exp;
                        spec_data[wb+2] = iq2 >>= -exp;
                        spec_data[wb+3] = iq3 >>= -exp;
                    } else {
                        spec_data[wb+0] = iq0 <<= exp;
                        spec_data[wb+1] = iq1 <<= exp;
                        spec_data[wb+2] = iq2 <<= exp;
                        spec_data[wb+3] = iq3 <<= exp;
                    }
                    if (frac != 0)
                    {
                        spec_data[wb+0] = MUL_C(spec_data[wb+0],pow2_table[frac]);
                        spec_data[wb+1] = MUL_C(spec_data[wb+1],pow2_table[frac]);
                        spec_data[wb+2] = MUL_C(spec_data[wb+2],pow2_table[frac]);
                        spec_data[wb+3] = MUL_C(spec_data[wb+3],pow2_table[frac]);
                    }

//#define SCFS_PRINT
#ifdef SCFS_PRINT
                    printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+0]);
                    printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+1]);
                    printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+2]);
                    printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+3]);
                    //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+0]);
                    //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+1]);
                    //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+2]);
                    //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+3]);
#endif
#endif

                    k += 4;
                }

                wa += win_inc;
            }
            j += width;

			gincrease += width * g->window_group_length;
        }
        gindex += gincrease;
    }

    return error;
}

static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
                                       uint8_t output_channels)
{
    uint8_t mul = 1;

⌨️ 快捷键说明

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