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

📄 wmadec.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
                    level = level_table[code];                }                sign = get_bits(&s->gb, 1);                if (!sign)                    level = -level;                ptr += run;                if (ptr >= eptr)                    return -1;                *ptr++ = level;                /* NOTE: EOB can be omitted */                if (ptr >= eptr)                    break;            }        }        if (s->version == 1 && s->nb_channels >= 2) {            align_get_bits(&s->gb);        }    }         /* normalize */    {        int n4 = s->block_len / 2;        mdct_norm = 1.0 / (float)n4;        if (s->version == 1) {            mdct_norm *= sqrt(n4);        }    }    /* finally compute the MDCT coefficients */    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            int16_t *coefs1;            float *coefs, *exponents, mult, mult1, noise, *exp_ptr;            int i, j, n, n1, last_high_band;            float exp_power[HIGH_BAND_MAX_SIZE];            coefs1 = s->coefs1[ch];            exponents = s->exponents[ch];            mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];            mult *= mdct_norm;            coefs = s->coefs[ch];            if (s->use_noise_coding) {                mult1 = mult;                /* very low freqs : noise */                for(i = 0;i < s->coefs_start; i++) {                    *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * mult1;                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                }                                n1 = s->exponent_high_sizes[bsize];                /* compute power of high bands */                exp_ptr = exponents +                     s->high_band_start[bsize] -                     s->coefs_start;                last_high_band = 0; /* avoid warning */                for(j=0;j<n1;j++) {                    n = s->exponent_high_bands[s->frame_len_bits -                                               s->block_len_bits][j];                    if (s->high_band_coded[ch][j]) {                        float e2, v;                        e2 = 0;                        for(i = 0;i < n; i++) {                            v = exp_ptr[i];                            e2 += v * v;                        }                        exp_power[j] = e2 / n;                        last_high_band = j;                        tprintf("%d: power=%f (%d)\n", j, exp_power[j], n);                    }                    exp_ptr += n;                }                /* main freqs and high freqs */                for(j=-1;j<n1;j++) {                    if (j < 0) {                        n = s->high_band_start[bsize] -                             s->coefs_start;                    } else {                        n = s->exponent_high_bands[s->frame_len_bits -                                                   s->block_len_bits][j];                    }                    if (j >= 0 && s->high_band_coded[ch][j]) {                        /* use noise with specified power */                        mult1 = sqrt(exp_power[j] / exp_power[last_high_band]);                        /* XXX: use a table */                        mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05);                        mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult);                        mult1 *= mdct_norm;                        for(i = 0;i < n; i++) {                            noise = s->noise_table[s->noise_index];                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                            *coefs++ = (*exponents++) * noise * mult1;                        }                    } else {                        /* coded values + small noise */                        for(i = 0;i < n; i++) {                            noise = s->noise_table[s->noise_index];                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                            *coefs++ = ((*coefs1++) + noise) * (*exponents++) * mult;                        }                    }                }                /* very high freqs : noise */                n = s->block_len - s->coefs_end[bsize];                mult1 = mult * exponents[-1];                for(i = 0; i < n; i++) {                    *coefs++ = s->noise_table[s->noise_index] * mult1;                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                }            } else {                /* XXX: optimize more */                for(i = 0;i < s->coefs_start; i++)                    *coefs++ = 0.0;                n = nb_coefs[ch];                for(i = 0;i < n; i++) {                    *coefs++ = coefs1[i] * exponents[i] * mult;                }                n = s->block_len - s->coefs_end[bsize];                for(i = 0;i < n; i++)                    *coefs++ = 0.0;            }        }    }#ifdef TRACE    for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            dump_floats("exponents", 3, s->exponents[ch], s->block_len);            dump_floats("coefs", 1, s->coefs[ch], s->block_len);        }    }#endif        if (s->ms_stereo && s->channel_coded[1]) {        float a, b;        int i;        /* nominal case for ms stereo: we do it before mdct */        /* no need to optimize this case because it should almost           never happen */        if (!s->channel_coded[0]) {            tprintf("rare ms-stereo case happened\n");            memset(s->coefs[0], 0, sizeof(float) * s->block_len);            s->channel_coded[0] = 1;        }                for(i = 0; i < s->block_len; i++) {            a = s->coefs[0][i];            b = s->coefs[1][i];            s->coefs[0][i] = a + b;            s->coefs[1][i] = a - b;        }    }    /* build the window : we ensure that when the windows overlap       their squared sum is always 1 (MDCT reconstruction rule) */    /* XXX: merge with output */    {        int i, next_block_len, block_len, prev_block_len, n;        float *wptr;        block_len = s->block_len;        prev_block_len = 1 << s->prev_block_len_bits;        next_block_len = 1 << s->next_block_len_bits;        /* right part */        wptr = window + block_len;        if (block_len <= next_block_len) {            for(i=0;i<block_len;i++)                *wptr++ = s->windows[bsize][i];        } else {            /* overlap */            n = (block_len / 2) - (next_block_len / 2);            for(i=0;i<n;i++)                *wptr++ = 1.0;            for(i=0;i<next_block_len;i++)                *wptr++ = s->windows[s->frame_len_bits - s->next_block_len_bits][i];            for(i=0;i<n;i++)                *wptr++ = 0.0;        }        /* left part */        wptr = window + block_len;        if (block_len <= prev_block_len) {            for(i=0;i<block_len;i++)                *--wptr = s->windows[bsize][i];        } else {            /* overlap */            n = (block_len / 2) - (prev_block_len / 2);            for(i=0;i<n;i++)                *--wptr = 1.0;            for(i=0;i<prev_block_len;i++)                *--wptr = s->windows[s->frame_len_bits - s->prev_block_len_bits][i];            for(i=0;i<n;i++)                *--wptr = 0.0;        }    }        for(ch = 0; ch < s->nb_channels; ch++) {        if (s->channel_coded[ch]) {            FFTSample output[BLOCK_MAX_SIZE * 2] __attribute__((aligned(16)));            float *ptr;            int i, n4, index, n;            n = s->block_len;            n4 = s->block_len / 2;            ff_imdct_calc(&s->mdct_ctx[bsize],                           output, s->coefs[ch], s->mdct_tmp);            /* XXX: optimize all that by build the window and               multipying/adding at the same time */            /* multiply by the window */            for(i=0;i<n * 2;i++) {                output[i] *= window[i];            }            /* add in the frame */            index = (s->frame_len / 2) + s->block_pos - n4;            ptr = &s->frame_out[ch][index];            for(i=0;i<n * 2;i++) {                *ptr += output[i];                ptr++;            }            /* specific fast case for ms-stereo : add to second               channel if it is not coded */            if (s->ms_stereo && !s->channel_coded[1]) {                ptr = &s->frame_out[1][index];                for(i=0;i<n * 2;i++) {                    *ptr += output[i];                    ptr++;                }            }        }    } next:    /* update block number */    s->block_num++;    s->block_pos += s->block_len;    if (s->block_pos >= s->frame_len)        return 1;    else        return 0;}/* decode a frame of frame_len samples */static int wma_decode_frame(WMADecodeContext *s, int16_t *samples){    int ret, i, n, a, ch, incr;    int16_t *ptr;    float *iptr;#ifdef TRACE    tprintf("***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len);#endif    /* read each block */    s->block_num = 0;    s->block_pos = 0;    for(;;) {        ret = wma_decode_block(s);        if (ret < 0)             return -1;        if (ret)            break;    }    /* convert frame to integer */    n = s->frame_len;    incr = s->nb_channels;    for(ch = 0; ch < s->nb_channels; ch++) {        ptr = samples + ch;        iptr = s->frame_out[ch];        for(i=0;i<n;i++) {            a = lrintf(*iptr++);            if (a > 32767)                a = 32767;            else if (a < -32768)                a = -32768;            *ptr = a;            ptr += incr;        }        /* prepare for next block */        memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],                s->frame_len * sizeof(float));        /* XXX: suppress this */        memset(&s->frame_out[ch][s->frame_len], 0,                s->frame_len * sizeof(float));    }#ifdef TRACE    dump_shorts("samples", samples, n * s->nb_channels);#endif    return 0;}static int wma_decode_superframe(AVCodecContext *avctx,                                  void *data, int *data_size,                                 uint8_t *buf, int buf_size){    WMADecodeContext *s = avctx->priv_data;    int nb_frames, bit_offset, i, pos, len;    uint8_t *q;    int16_t *samples;        tprintf("***decode_superframe:\n");    samples = data;    init_get_bits(&s->gb, buf, buf_size*8);        if (s->use_bit_reservoir) {        /* read super frame header */        get_bits(&s->gb, 4); /* super frame index */        nb_frames = get_bits(&s->gb, 4) - 1;        bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);        if (s->last_superframe_len > 0) {            //        printf("skip=%d\n", s->last_bitoffset);            /* add bit_offset bits to last frame */            if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) >                 MAX_CODED_SUPERFRAME_SIZE)                goto fail;            q = s->last_superframe + s->last_superframe_len;            len = bit_offset;            while (len > 0) {                *q++ = (get_bits)(&s->gb, 8);                len -= 8;            }            if (len > 0) {                *q++ = (get_bits)(&s->gb, len) << (8 - len);            }                        /* XXX: bit_offset bits into last frame */            init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8);            /* skip unused bits */            if (s->last_bitoffset > 0)                skip_bits(&s->gb, s->last_bitoffset);            /* this frame is stored in the last superframe and in the               current one */            if (wma_decode_frame(s, samples) < 0)                goto fail;            samples += s->nb_channels * s->frame_len;        }        /* read each frame starting from bit_offset */        pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3;        init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8);        len = pos & 7;        if (len > 0)            skip_bits(&s->gb, len);            s->reset_block_lengths = 1;        for(i=0;i<nb_frames;i++) {            if (wma_decode_frame(s, samples) < 0)                goto fail;            samples += s->nb_channels * s->frame_len;        }        /* we copy the end of the frame in the last frame buffer */        pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7);        s->last_bitoffset = pos & 7;        pos >>= 3;        len = buf_size - pos;        if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) {            goto fail;        }        s->last_superframe_len = len;        memcpy(s->last_superframe, buf + pos, len);    } else {        /* single frame decode */        if (wma_decode_frame(s, samples) < 0)            goto fail;        samples += s->nb_channels * s->frame_len;    }    *data_size = (int8_t *)samples - (int8_t *)data;    return s->block_align; fail:    /* when error, we reset the bit reservoir */    s->last_superframe_len = 0;    return -1;}static int wma_decode_end(AVCodecContext *avctx){    WMADecodeContext *s = avctx->priv_data;    int i;    for(i = 0; i < s->nb_block_sizes; i++)        ff_mdct_end(&s->mdct_ctx[i]);    for(i = 0; i < s->nb_block_sizes; i++)        av_free(s->windows[i]);    if (s->use_exp_vlc) {        free_vlc(&s->exp_vlc);    }    if (s->use_noise_coding) {        free_vlc(&s->hgain_vlc);    }    for(i = 0;i < 2; i++) {        free_vlc(&s->coef_vlc[i]);        av_free(s->run_table[i]);        av_free(s->level_table[i]);    }        return 0;}AVCodec wmav1_decoder ={    "wmav1",    CODEC_TYPE_AUDIO,    CODEC_ID_WMAV1,    sizeof(WMADecodeContext),    wma_decode_init,    NULL,    wma_decode_end,    wma_decode_superframe,};AVCodec wmav2_decoder ={    "wmav2",    CODEC_TYPE_AUDIO,    CODEC_ID_WMAV2,    sizeof(WMADecodeContext),    wma_decode_init,    NULL,    wma_decode_end,    wma_decode_superframe,};

⌨️ 快捷键说明

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