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

📄 wmadeci.c

📁 wma定点解码算法
💻 C
📖 第 1 页 / 共 5 页
字号:
                /* 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 */                        fixed32 tmp = fixdiv32(exp_power[j],exp_power[last_high_band]);                        mult1 = (fixed64)fixsqrt32(tmp);                        /* XXX: use a table */                        mult1 = mult1 * pow_table[s->high_band_values[ch][j]];                        mult1 = fixdiv64(mult1,fixmul32(s->max_exponent[ch],s->noise_mult));                        mult1 = fixmul64byfixed(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++ = fixmul32(fixmul32(*exponents,noise),Fixed32From64(mult1));                            ++exponents;                        }                    }                    else                    {                        /* coded values + small noise */                        for(i = 0;i < n; ++i)                        {                            /* PJJ: check code path */                            noise = s->noise_table[s->noise_index];                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);                            *coefs++ = fixmul32(fixmul32(((*coefs1++) + noise),*exponents),mult);                            ++exponents;                        }                    }                }                /* very high freqs : noise */                n = s->block_len - s->coefs_end[bsize];                mult1 = fixmul32(mult,exponents[-1]);                for (i = 0; i < n; ++i)                {                    *coefs++ = fixmul32(s->noise_table[s->noise_index],Fixed32From64(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;                n = nb_coefs[ch];                for(i = 0;i < n; ++i)                {                    *coefs++ = fixmul32(fixmul32(coefs1[i],exponents[i]),mult);                }                n = s->block_len - s->coefs_end[bsize];                for(i = 0;i < n; ++i)                    *coefs++ = 0;            }        }    }    if (s->ms_stereo && s->channel_coded[1])    {        fixed32 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])        {            memset(s->coefs[0], 0, sizeof(fixed32) * 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;        fixed32 *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++ = itofix32(1);            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;        }        /* 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 = itofix32(1);            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;        }    }    for(ch = 0; ch < s->nb_channels; ++ch)    {        if (s->channel_coded[ch])        {            fixed32 output[BLOCK_MAX_SIZE * 2];            fixed32 *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] = fixmul32(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;    fixed32 *iptr;    /* 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 = fixtoi32(*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(fixed32));        /* XXX: suppress this */        memset(&s->frame_out[ch][s->frame_len], 0,               s->frame_len * sizeof(fixed32));    }    return 0;}/* Public entry point */static int wma_decode_init_fixed(CodecContext * avctx){    WMADecodeContext *s = avctx->priv_data;    int i, flags1, flags2;    fixed32 *window;    uint8_t *extradata;    fixed64 bps1;    fixed32 high_freq;    fixed64 bps;    int sample_rate1;    int coef_vlc_table;    s->sample_rate = avctx->sample_rate;    s->nb_channels = avctx->channels;    s->bit_rate = avctx->bit_rate;    s->block_align = avctx->block_align;    if (avctx->codec->id == CODEC_ID_WMAV1)    {        s->version = 1;    }    else    {        s->version = 2;    }    /* extract flag infos */    flags1 = 0;    flags2 = 0;    extradata = avctx->extradata;    if (s->version == 1 && avctx->extradata_size >= 4)    {        flags1 = extradata[0] | (extradata[1] << 8);        flags2 = extradata[2] | (extradata[3] << 8);    }    else if (s->version == 2 && avctx->extradata_size >= 6)    {        flags1 = extradata[0] | (extradata[1] << 8) |                 (extradata[2] << 16) | (extradata[3] << 24);        flags2 = extradata[4] | (extradata[5] << 8);    }    s->use_exp_vlc = flags2 & 0x0001;    s->use_bit_reservoir = flags2 & 0x0002;    s->use_variable_block_len = flags2 & 0x0004;    /* compute MDCT block size */    if (s->sample_rate <= 16000)    {        s->frame_len_bits = 9;    }    else if (s->sample_rate <= 22050 ||             (s->sample_rate <= 32000 && s->version == 1))    {        s->frame_len_bits = 10;    }    else    {        s->frame_len_bits = 11;    }    s->frame_len = 1 << s->frame_len_bits;    if (s->use_variable_block_len)    {        int nb_max, nb;        nb = ((flags2 >> 3) & 3) + 1;        if ((s->bit_rate / s->nb_channels) >= 32000)        {            nb += 2;        }        nb_max = s->frame_len_bits - BLOCK_MIN_BITS;        if (nb > nb_max)            nb = nb_max;        s->nb_block_sizes = nb + 1;    }    else    {        s->nb_block_sizes = 1;    }    /* init rate dependant parameters */    s->use_noise_coding = 1;    high_freq = fixmul64byfixed(itofix64(s->sample_rate), 0x8000);    /* if version 2, then the rates are normalized */    sample_rate1 = s->sample_rate;    if (s->version == 2)    {        if (sample_rate1 >= 44100)            sample_rate1 = 44100;        else if (sample_rate1 >= 22050)            sample_rate1 = 22050;        else if (sample_rate1 >= 16000)            sample_rate1 = 16000;        else if (sample_rate1 >= 11025)            sample_rate1 = 11025;        else if (sample_rate1 >= 8000)            sample_rate1 = 8000;    }    fixed64 tmp = itofix64(s->bit_rate);    fixed64 tmp2 = itofix64(s->nb_channels * s->sample_rate);    bps = fixdiv64(tmp, tmp2);    fixed64 tim = fixmul64byfixed(bps, s->frame_len);    fixed64 tmpi = fixdiv64(tim,itofix64(8));    s->byte_offset_bits = av_log2(fixtoi64(tmpi)) + 2;    /* compute high frequency value and choose if noise coding should       be activated */    bps1 = bps;    if (s->nb_channels == 2)        bps1 = fixmul32(bps,0x1999a);    if (sample_rate1 == 44100)    {        if (bps1 >= 0x9c29)            s->use_noise_coding = 0;        else            high_freq = fixmul64byfixed(high_freq,0x6666);    }    else if (sample_rate1 == 22050)    {        if (bps1 >= 0x128f6)            s->use_noise_coding = 0;        else if (bps1 >= 0xb852)            high_freq = fixmul64byfixed(high_freq,0xb333);        else            high_freq = fixmul64byfixed(high_freq,0x999a);    }    else if (sample_rate1 == 16000)    {        if (bps > 0x8000)            high_freq = fixmul64byfixed(high_freq,0x8000);        else            high_freq = fixmul64byfixed(high_freq,0x4ccd);    }    else if (sample_rate1 == 11025)    {        high_freq = fixmul64byfixed(high_freq,0xb3333);    }    else if (sample_rate1 == 8000)    {        if (bps <= 0xa000)        {            high_freq = fixmul64byfixed(high_freq,0x8000);        }        else if (bps > 0xc000)        {            s->use_noise_coding = 0;        }        else        {            high_freq = fixmul64byfixed(high_freq,0xa666);        }    }    else    {        if (bps >= 0xcccd)        {            high_freq = fixmul64byfixed(high_freq,0xc000);        }        else if (bps >= 0x999a)        {            high_freq = fixmul64byfixed(high_freq,0x999a);        }        else        {            high_freq = fixmul64byfixed(high_freq,0x8000);        }    }    /* compute the scale factor band sizes for each MDCT block size */    {        int a, b, pos, lpos, k, block_len, i, j, n;        const uint8_t *table;        if (s->version == 1)        {            s->coefs_start = 3;        }        else        {            s->coefs_start = 0;        }        for(k = 0; k < s->nb_block_sizes; ++k)        {            block_len = s->frame_len >> k;            if (s->version == 1)            {                lpos = 0;                for(i=0;i<25;++i)                {                    a = wma_critical_freqs[i];                    b = s->sample_rate;                    pos = ((block_len * 2 * a)  + (b >> 1)) / b;                    if (pos > block_len)                        pos = block_len;                    s->exponent_bands[0][i] = pos - lpos;                    if (pos >= block_len)                    {                        ++i;                        break;                    }                    lpos = pos;                }                s->exponent_sizes[0] = i;            }            else            {                /* hardcoded tables */                table = NULL;                a = s->frame_len_bits - BLOCK_MIN_BITS - k;                if (a < 3)                {                    if (s->sample_rate >= 44100)                        table = exponent_band_44100[a];                    else if (s->sample_rate >= 32000)                        table = exponent_band_32000[a];                    else if (s->sample_rate >= 22050)                        table = exponent_band_22050[a];                }                if (table)                {                    n = *table++;                    for(i=0;i<n;++i)                        s->exponent_bands[k][i] = table[i];                    s->exponent_sizes[k] = n;                }                else                {                    j = 0;                    lpos = 0;                    for(i=0;i<25;++i)                    {                        a = wma_critical_freqs[i];                        b = s->sample_rate;                        pos = ((block_len * 2 * a)  + (b << 1)) / (4 * b);                        pos <<= 2;                        if (pos > block_len)                            pos =

⌨️ 快捷键说明

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