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

📄 wmadec.c

📁 tcpmp播放器的flv插件
💻 C
📖 第 1 页 / 共 3 页
字号:
                tprintf(" %d", s->exponent_bands[i][j]);            tprintf("\n");        }    }#endif    /* init MDCT */    for(i = 0; i < s->nb_block_sizes; i++)        ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1);        /* init MDCT windows : simple sinus window */    for(i = 0; i < s->nb_block_sizes; i++) {        int n, j;        float alpha;        n = 1 << (s->frame_len_bits - i);        window = av_malloc(sizeof(float) * n);        alpha = M_PI / (2.0 * n);        for(j=0;j<n;j++) {            window[n - j - 1] = sin((j + 0.5) * alpha);        }        s->windows[i] = window;    }    s->reset_block_lengths = 1;        if (s->use_noise_coding) {        /* init the noise generator */        if (s->use_exp_vlc)            s->noise_mult = 0.02;        else            s->noise_mult = 0.04;               #ifdef TRACE        for(i=0;i<NOISE_TAB_SIZE;i++)            s->noise_table[i] = 1.0 * s->noise_mult;#else        {            unsigned int seed;            float norm;            seed = 1;            norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult;            for(i=0;i<NOISE_TAB_SIZE;i++) {                seed = seed * 314159 + 1;                s->noise_table[i] = (float)((int)seed) * norm;            }        }#endif        init_vlc(&s->hgain_vlc, 9, sizeof(hgain_huffbits),                  hgain_huffbits, 1, 1,                 hgain_huffcodes, 2, 2, 0);    }    if (s->use_exp_vlc) {        init_vlc(&s->exp_vlc, 9, sizeof(scale_huffbits),                  scale_huffbits, 1, 1,                 scale_huffcodes, 4, 4, 0);    } else {        wma_lsp_to_curve_init(s, s->frame_len);    }    /* choose the VLC tables for the coefficients */    coef_vlc_table = 2;    if (s->sample_rate >= 32000) {        if (bps1 < 0.72)            coef_vlc_table = 0;        else if (bps1 < 1.16)            coef_vlc_table = 1;    }    init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0],                  &coef_vlcs[coef_vlc_table * 2]);    init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1],                  &coef_vlcs[coef_vlc_table * 2 + 1]);    return 0;}/* interpolate values for a bigger or smaller block. The block must   have multiple sizes */static void interpolate_array(float *scale, int old_size, int new_size){    int i, j, jincr, k;    float 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++) {            scale[i] = scale[j];            j += jincr;        }    }}/* compute x^-0.25 with an exponent and mantissa table. We use linear   interpolation to reduce the mantissa table size at a small speed   expense (linear interpolation approximately doubles the number of   bits of precision). */static inline float pow_m1_4(WMADecodeContext *s, float x){    union {        float f;        unsigned int v;    } u, t;    unsigned int e, m;    float a, b;    u.f = x;    e = u.v >> 23;    m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1);    /* build interpolation scale: 1 <= t < 2. */    t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23);    a = s->lsp_pow_m_table1[m];    b = s->lsp_pow_m_table2[m];    return s->lsp_pow_e_table[e] * (a + b * t.f);}static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len){      float wdel, a, b;    int i, e, m;    wdel = M_PI / frame_len;    for(i=0;i<frame_len;i++)        s->lsp_cos_table[i] = 2.0f * cos(wdel * i);    /* tables for x^-0.25 computation */    for(i=0;i<256;i++) {        e = i - 126;        s->lsp_pow_e_table[i] = pow(2.0, e * -0.25);    }    /* NOTE: these two tables are needed to avoid two operations in       pow_m1_4 */    b = 1.0;    for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) {        m = (1 << LSP_POW_BITS) + i;        a = (float)m * (0.5 / (1 << LSP_POW_BITS));        a = pow(a, -0.25);        s->lsp_pow_m_table1[i] = 2 * a - b;        s->lsp_pow_m_table2[i] = b - a;        b = a;    }#if 0    for(i=1;i<20;i++) {        float v, r1, r2;        v = 5.0 / i;        r1 = pow_m1_4(s, v);        r2 = pow(v,-0.25);        printf("%f^-0.25=%f e=%f\n", v, r1, r2 - r1);    }#endif}/* NOTE: We use the same code as Vorbis here *//* XXX: optimize it further with SSE/3Dnow */static void wma_lsp_to_curve(WMADecodeContext *s,                              float *out, float *val_max_ptr,                              int n, float *lsp){    int i, j;    float p, q, w, v, val_max;    val_max = 0;    for(i=0;i<n;i++) {        p = 0.5f;        q = 0.5f;        w = s->lsp_cos_table[i];        for(j=1;j<NB_LSP_COEFS;j+=2){            q *= w - lsp[j - 1];            p *= w - lsp[j];        }        p *= p * (2.0f - w);        q *= q * (2.0f + w);        v = p + q;        v = pow_m1_4(s, v);        if (v > val_max)            val_max = v;        out[i] = v;    }    *val_max_ptr = val_max;}/* decode exponents coded with LSP coefficients (same idea as Vorbis) */static void decode_exp_lsp(WMADecodeContext *s, int ch){    float lsp_coefs[NB_LSP_COEFS];    int val, i;    for(i = 0; i < NB_LSP_COEFS; i++) {        if (i == 0 || i >= 8)            val = get_bits(&s->gb, 3);        else            val = get_bits(&s->gb, 4);        lsp_coefs[i] = lsp_codebook[i][val];    }    wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch],                     s->block_len, lsp_coefs);}/* decode exponents coded with VLC codes */static int decode_exp_vlc(WMADecodeContext *s, int ch){    int last_exp, n, code;    const uint16_t *ptr, *band_ptr;    float v, *q, max_scale, *q_end;        band_ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits];    ptr = band_ptr;    q = s->exponents[ch];    q_end = q + s->block_len;    max_scale = 0;    if (s->version == 1) {        last_exp = get_bits(&s->gb, 5) + 10;        /* XXX: use a table */        v = pow(10, last_exp * (1.0 / 16.0));        max_scale = v;        n = *ptr++;        do {            *q++ = v;        } while (--n);    }    last_exp = 36;    while (q < q_end) {        code = get_vlc(&s->gb, &s->exp_vlc);        if (code < 0)            return -1;        /* NOTE: this offset is the same as MPEG4 AAC ! */        last_exp += code - 60;        /* XXX: use a table */        v = pow(10, last_exp * (1.0 / 16.0));        if (v > max_scale)            max_scale = v;        n = *ptr++;        do {            *q++ = v;        } while (--n);    }    s->max_exponent[ch] = max_scale;    return 0;}/* return 0 if OK. return 1 if last block of frame. return -1 if   unrecorrable error. */static int wma_decode_block(WMADecodeContext *s){    int n, v, a, ch, code, bsize;    int coef_nb_bits, total_gain, parse_exponents;    float window[BLOCK_MAX_SIZE * 2];// XXX: FIXME!! there's a bug somewhere which makes this mandatory under altivec#ifdef HAVE_ALTIVEC    volatile int nb_coefs[MAX_CHANNELS] __attribute__((aligned(16)));#else    int nb_coefs[MAX_CHANNELS];#endif    float mdct_norm;#ifdef TRACE    tprintf("***decode_block: %d:%d\n", s->frame_count - 1, s->block_num);#endif    /* compute current block length */    if (s->use_variable_block_len) {        n = av_log2(s->nb_block_sizes - 1) + 1;            if (s->reset_block_lengths) {            s->reset_block_lengths = 0;            v = get_bits(&s->gb, n);            if (v >= s->nb_block_sizes)                return -1;            s->prev_block_len_bits = s->frame_len_bits - v;            v = get_bits(&s->gb, n);            if (v >= s->nb_block_sizes)                return -1;            s->block_len_bits = s->frame_len_bits - v;        } else {            /* update block lengths */            s->prev_block_len_bits = s->block_len_bits;            s->block_len_bits = s->next_block_len_bits;        }        v = get_bits(&s->gb, n);        if (v >= s->nb_block_sizes)            return -1;        s->next_block_len_bits = s->frame_len_bits - v;    } else {        /* fixed block len */        s->next_block_len_bits = s->frame_len_bits;        s->prev_block_len_bits = s->frame_len_bits;        s->block_len_bits = s->frame_len_bits;    }    /* now check if the block length is coherent with the frame length */    s->block_len = 1 << s->block_len_bits;    if ((s->block_pos + s->block_len) > s->frame_len)        return -1;    if (s->nb_channels == 2) {        s->ms_stereo = get_bits(&s->gb, 1);    }    v = 0;    for(ch = 0; ch < s->nb_channels; ch++) {        a = get_bits(&s->gb, 1);        s->channel_coded[ch] = a;        v |= a;    }    /* if no channel coded, no need to go further */    /* XXX: fix potential framing problems */    if (!v)        goto next;    bsize = s->frame_len_bits - s->block_len_bits;    /* read total gain and extract corresponding number of bits for       coef escape coding */    total_gain = 1;    for(;;) {        a = get_bits(&s->gb, 7);        total_gain += a;        if (a != 127)            break;    }        if (total_gain < 15)        coef_nb_bits = 13;    else if (total_gain < 32)        coef_nb_bits = 12;    else if (total_gain < 40)        coef_nb_bits = 11;    else if (total_gain < 45)        coef_nb_bits = 10;    else        coef_nb_bits = 9;    /* compute number of coefficients */    n = s->coefs_end[bsize] - s->coefs_start;    for(ch = 0; ch < s->nb_channels; ch++)        nb_coefs[ch] = n;    /* complex coding */    if (s->use_noise_coding) {        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                int i, n, a;                n = s->exponent_high_sizes[bsize];                for(i=0;i<n;i++) {                    a = get_bits(&s->gb, 1);                    s->high_band_coded[ch][i] = a;                    /* if noise coding, the coefficients are not transmitted */                    if (a)                        nb_coefs[ch] -= s->exponent_high_bands[bsize][i];                }            }        }        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                int i, n, val, code;                n = s->exponent_high_sizes[bsize];                val = (int)0x80000000;                for(i=0;i<n;i++) {                    if (s->high_band_coded[ch][i]) {                        if (val == (int)0x80000000) {                            val = get_bits(&s->gb, 7) - 19;                        } else {                            code = get_vlc(&s->gb, &s->hgain_vlc);                            if (code < 0)                                return -1;                            val += code - 18;                        }                        s->high_band_values[ch][i] = val;                    }                }            }        }    }               /* exposant can be interpolated in short blocks. */    parse_exponents = 1;    if (s->block_len_bits != s->frame_len_bits) {        parse_exponents = get_bits(&s->gb, 1);    }        if (parse_exponents) {        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                if (s->use_exp_vlc) {                    if (decode_exp_vlc(s, ch) < 0)                        return -1;                } else {                    decode_exp_lsp(s, ch);                }            }        }    } else {        for(ch = 0; ch < s->nb_channels; ch++) {            if (s->channel_coded[ch]) {                interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits,                                   s->block_len);            }        }    }    /* parse spectral coefficients : just RLE encoding */    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            VLC *coef_vlc;            int level, run, sign, tindex;            int16_t *ptr, *eptr;            const int16_t *level_table, *run_table;            /* special VLC tables are used for ms stereo because               there is potentially less energy there */            tindex = (ch == 1 && s->ms_stereo);            coef_vlc = &s->coef_vlc[tindex];            run_table = s->run_table[tindex];            level_table = s->level_table[tindex];            /* XXX: optimize */            ptr = &s->coefs1[ch][0];            eptr = ptr + nb_coefs[ch];            memset(ptr, 0, s->block_len * sizeof(int16_t));            for(;;) {                code = get_vlc(&s->gb, coef_vlc);                if (code < 0)                    return -1;                if (code == 1) {                    /* EOB */                    break;                } else if (code == 0) {                    /* escape */                    level = get_bits(&s->gb, coef_nb_bits);                    /* NOTE: this is rather suboptimal. reading                       block_len_bits would be better */                    run = get_bits(&s->gb, s->frame_len_bits);                } else {

⌨️ 快捷键说明

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