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

📄 wmadeci.c

📁 wma定点解码算法
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* compute bit reverse table */    for(i=0;i<n;i++)    {        m=0;        for(j=0;j<nbits;j++)        {            m |= ((i >> j) & 1) << (nbits-j-1);        }        s->revtab[i]=m;    }    return 0;fail:    av_freep(&s->revtab);    av_freep(&s->exptab);    av_freep(&s->exptab1);    return -1;}/* butter fly op */#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \{\  fixed32 ax, ay, bx, by;\  bx=pre1;\  by=pim1;\  ax=qre1;\  ay=qim1;\  pre = (bx + ax);\  pim = (by + ay);\  qre = (bx - ax);\  qim = (by - ay);\}/** * Do a complex FFT with the parameters defined in fft_init(). The * input data must be permuted before with s->revtab table. No * 1.0/sqrt(n) normalization is done. */void fft_calc(FFTContext *s, FFTComplex *z){    int ln = s->nbits;    int j, np, np2;    int nblocks, nloops;    register FFTComplex *p, *q;    FFTComplex *exptab = s->exptab;    int l;    fixed32 tmp_re, tmp_im;    np = 1 << ln;    /* pass 0 */    p=&z[0];    j=(np >> 1);    do    {        BF(p[0].re, p[0].im, p[1].re, p[1].im,           p[0].re, p[0].im, p[1].re, p[1].im);        p+=2;    }    while (--j != 0);    /* pass 1 */    p=&z[0];    j=np >> 2;    if (s->inverse)    {        do        {            BF(p[0].re, p[0].im, p[2].re, p[2].im,               p[0].re, p[0].im, p[2].re, p[2].im);            BF(p[1].re, p[1].im, p[3].re, p[3].im,               p[1].re, p[1].im, -p[3].im, p[3].re);            p+=4;        }        while (--j != 0);    }    else    {        do        {            BF(p[0].re, p[0].im, p[2].re, p[2].im,               p[0].re, p[0].im, p[2].re, p[2].im);            BF(p[1].re, p[1].im, p[3].re, p[3].im,               p[1].re, p[1].im, p[3].im, -p[3].re);            p+=4;        }        while (--j != 0);    }    /* pass 2 .. ln-1 */    nblocks = np >> 3;    nloops = 1 << 2;    np2 = np >> 1;    do    {        p = z;        q = z + nloops;        for (j = 0; j < nblocks; ++j)        {            BF(p->re, p->im, q->re, q->im,               p->re, p->im, q->re, q->im);            p++;            q++;            for(l = nblocks; l < np2; l += nblocks)            {                CMUL(&tmp_re, &tmp_im, exptab[l].re, exptab[l].im, q->re, q->im);                BF(p->re, p->im, q->re, q->im,                   p->re, p->im, tmp_re, tmp_im);                p++;                q++;            }            p += nloops;            q += nloops;        }        nblocks = nblocks >> 1;        nloops = nloops << 1;    }    while (nblocks != 0);}/** * Do the permutation needed BEFORE calling fft_calc() */void fft_permute(FFTContext *s, FFTComplex *z){    int j, k, np;    FFTComplex tmp;    const uint16_t *revtab = s->revtab;    /* reverse */    np = 1 << s->nbits;    for(j=0;j<np;j++)    {        k = revtab[j];        if (k < j)        {            tmp = z[k];            z[k] = z[j];            z[j] = tmp;        }    }}void fft_end(FFTContext *s){    av_freep(&s->revtab);    av_freep(&s->exptab);    av_freep(&s->exptab1);}/* VLC decoding */#define GET_DATA(v, table, i, wrap, size) \{\    const uint8_t *ptr = (const uint8_t *)table + i * wrap;\    switch(size) {\    case 1:\        v = *(const uint8_t *)ptr;\        break;\    case 2:\        v = *(const uint16_t *)ptr;\        break;\    default:\        v = *(const uint32_t *)ptr;\        break;\    }\}/* deprecated, dont use get_vlc for new code, use get_vlc2 instead or use GET_VLC directly */static inline int get_vlc(GetBitContext *s, VLC *vlc){    int code;    VLC_TYPE (*table)[2]= vlc->table;    OPEN_READER(re, s)    UPDATE_CACHE(re, s)    GET_VLC(code, re, s, table, vlc->bits, 3)    CLOSE_READER(re, s)    return code;}static int alloc_table(VLC *vlc, int size){    int index;    index = vlc->table_size;    vlc->table_size += size;    if (vlc->table_size > vlc->table_allocated)    {        vlc->table_allocated += (1 << vlc->bits);        vlc->table = av_realloc(vlc->table,                                sizeof(VLC_TYPE) * 2 * vlc->table_allocated);        if (!vlc->table)            return -1;    }    return index;}static int build_table(VLC *vlc, int table_nb_bits,                       int nb_codes,                       const void *bits, int bits_wrap, int bits_size,                       const void *codes, int codes_wrap, int codes_size,                       uint32_t code_prefix, int n_prefix){    int i, j, k, n, table_size, table_index, nb, n1, index;    uint32_t code;    VLC_TYPE (*table)[2];    table_size = 1 << table_nb_bits;    table_index = alloc_table(vlc, table_size);    if (table_index < 0)        return -1;    table = &vlc->table[table_index];    for(i=0;i<table_size;i++)    {        table[i][1] = 0;        table[i][0] = -1;    }    /* first pass: map codes and compute auxillary table sizes */    for(i=0;i<nb_codes;i++)    {        GET_DATA(n, bits, i, bits_wrap, bits_size);        GET_DATA(code, codes, i, codes_wrap, codes_size);        /* we accept tables with holes */        if (n <= 0)            continue;        /* if code matches the prefix, it is in the table */        n -= n_prefix;        if (n > 0 && (code >> n) == code_prefix)        {            if (n <= table_nb_bits)            {                /* no need to add another table */                j = (code << (table_nb_bits - n)) & (table_size - 1);                nb = 1 << (table_nb_bits - n);                for(k=0;k<nb;k++)                {                    table[j][1] = n;                    table[j][0] = i;                    j++;                }            }            else            {                n -= table_nb_bits;                j = (code >> n) & ((1 << table_nb_bits) - 1);                /* compute table size */                n1 = -table[j][1];                if (n > n1)                    n1 = n;                table[j][1] = -n1;            }        }    }    /* second pass : fill auxillary tables recursively */    for(i=0;i<table_size;i++)    {        n = table[i][1];        if (n < 0)        {            n = -n;            if (n > table_nb_bits)            {                n = table_nb_bits;                table[i][1] = -n;            }            index = build_table(vlc, n, nb_codes,                                bits, bits_wrap, bits_size,                                codes, codes_wrap, codes_size,                                (code_prefix << table_nb_bits) | i,                                n_prefix + table_nb_bits);            if (index < 0)                return -1;            /* note: realloc has been done, so reload tables */            table = &vlc->table[table_index];            table[i][0] = index;        }    }    return table_index;}/* Build VLC decoding tables suitable for use with get_vlc().   'nb_bits' set thee decoding table size (2^nb_bits) entries. The   bigger it is, the faster is the decoding. But it should not be too   big to save memory and L1 cache. '9' is a good compromise.   'nb_codes' : number of vlcs codes   'bits' : table which gives the size (in bits) of each vlc code.   'codes' : table which gives the bit pattern of of each vlc code.   'xxx_wrap' : give the number of bytes between each entry of the   'bits' or 'codes' tables.   'xxx_size' : gives the number of bytes of each entry of the 'bits'   or 'codes' tables.   'wrap' and 'size' allows to use any memory configuration and types   (byte/word/long) to store the 'bits' and 'codes' tables.*/int init_vlc(VLC *vlc, int nb_bits, int nb_codes,             const void *bits, int bits_wrap, int bits_size,             const void *codes, int codes_wrap, int codes_size){    vlc->bits = nb_bits;    vlc->table = NULL;    vlc->table_allocated = 0;    vlc->table_size = 0;    if (build_table(vlc, nb_bits, nb_codes,                    bits, bits_wrap, bits_size,                    codes, codes_wrap, codes_size,                    0, 0) < 0)    {        av_free(vlc->table);        return -1;    }    return 0;}/** * init MDCT or IMDCT computation. */int ff_mdct_init(MDCTContext *s, int nbits, int inverse){    int n, n4, i;    fixed32 alpha;    memset(s, 0, sizeof(*s));    n = 1 << nbits;    s->nbits = nbits;    s->n = n;    n4 = n >> 2;    s->tcos = av_malloc(n4 * sizeof(fixed32));    if (!s->tcos)        goto fail;    s->tsin = av_malloc(n4 * sizeof(fixed32));    if (!s->tsin)        goto fail;    for(i=0;i<n4;i++)    {        fixed32 pi2 = fixmul32(0x20000, M_PI_F);        fixed32 ip = itofix32(i) + 0x2000;        ip = fixdiv32(ip,itofix32(n)); /* PJJ optimize */        alpha = fixmul32(pi2, ip);        s->tcos[i] = -fixcos32(alpha);        s->tsin[i] = -fixsin32(alpha);    }    if (fft_inits(&s->fft, s->nbits - 2, inverse) < 0)        goto fail;    return 0;fail:    av_freep(&s->tcos);    av_freep(&s->tsin);    return -1;}/** * Compute inverse MDCT of size N = 2^nbits * @param output N samples * @param input N/2 samples * @param tmp N/2 samples */void ff_imdct_calc(MDCTContext *s,                   fixed32 *output,                   const fixed32 *input,                   FFTComplex *tmp){    int k, n8, n4, n2, n, j;    const uint16_t *revtab = s->fft.revtab;    const fixed32 *tcos = s->tcos;    const fixed32 *tsin = s->tsin;    const fixed32 *in1, *in2;    FFTComplex *z = (FFTComplex *)tmp;    n = 1 << s->nbits;    n2 = n >> 1;    n4 = n >> 2;    n8 = n >> 3;    /* pre rotation */    in1 = input;    in2 = input + n2 - 1;    for(k = 0; k < n4; k++)    {        j=revtab[k];        CMUL(&z[j].re, &z[j].im, *in2, *in1, tcos[k], tsin[k]);        in1 += 2;        in2 -= 2;    }    fft_calc(&s->fft, z);    /* post rotation + reordering */    /* XXX: optimize */    for(k = 0; k < n4; k++)    {        CMUL(&z[k].re, &z[k].im, z[k].re, z[k].im, tcos[k], tsin[k]);    }    for(k = 0; k < n8; k++)    {        fixed32 r1,r2,r3,r4,r1n,r2n,r3n;        r1 = z[n8 + k].im;        r1n = r1 * -1.0;        r2 = z[n8-1-k].re;        r2n = r2 * -1.0;        r3 = z[k+n8].re;        r3n = r3 * -1.0;        r4 = z[n8-k-1].im;        output[2*k] = r1n;        output[n2-1-2*k] = r1;        output[2*k+1] = r2;        output[n2-1-2*k-1] = r2n;        output[n2 + 2*k]= r3n;        output[n-1- 2*k]= r3n;        output[n2 + 2*k+1]= r4;        output[n-2 - 2 * k] = r4;    }}void ff_mdct_end(MDCTContext *s){    av_freep(&s->tcos);    av_freep(&s->tsin);    fft_end(&s->fft);}static void init_coef_vlc(VLC *vlc,                          uint16_t **prun_table, uint16_t **plevel_table,                          const CoefVLCTable *vlc_table){    int n = vlc_table->n;    const uint8_t *table_bits = vlc_table->huffbits;    const uint32_t *table_codes = vlc_table->huffcodes;    const uint16_t *levels_table = vlc_table->levels;    uint16_t *run_table, *level_table;    const uint16_t *p;    int i, l, j, level;    init_vlc(vlc, 9, n, table_bits, 1, 1, table_codes, 4, 4);    run_table = av_malloc(n * sizeof(uint16_t));    level_table = av_malloc(n * sizeof(uint16_t));    p = levels_table;    i = 2;    level = 1;    while (i < n)    {        l = *p++;        for(j=0;j<l;++j)        {            run_table[i] = j;            level_table[i] = level;            ++i;        }        ++level;    }    *prun_table = run_table;    *plevel_table = level_table;}/* interpolate values for a bigger or smaller block. The block must   have multiple sizes */static void interpolate_array(fixed32 *scale, int old_size, int new_size){    int i, j, jincr, k;    fixed32 v;    if (new_size > old_size)    {        jincr = new_size / old_size;        j = new_size;        for(i = old_size - 1; i >=0; --i)        {            v = scale[i];            k = jincr;            do            {                scale[--j] = v;            }            while (--k);        }    }    else if (new_size < old_size)    {        j = 0;        jincr = old_size / new_size;        for(i = 0; i < new_size; ++i)

⌨️ 快捷键说明

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