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

📄 imc.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * IMC compatible decoder * Copyright (c) 2002-2004 Maxim Poliakovski * Copyright (c) 2006 Benjamin Larsson * Copyright (c) 2006 Konstantin Shishkov * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** *  @file imc.c IMC - Intel Music Coder *  A mdct based codec using a 256 points large transform *  divied into 32 bands with some mix of scale factors. *  Only mono is supported. * */#include <math.h>#include <stddef.h>#include <stdio.h>#define ALT_BITSTREAM_READER#include "avcodec.h"#include "bitstream.h"#include "dsputil.h"#include "imcdata.h"#define IMC_BLOCK_SIZE 64#define IMC_FRAME_ID 0x21#define BANDS 32#define COEFFS 256typedef struct {    float old_floor[BANDS];    float flcoeffs1[BANDS];    float flcoeffs2[BANDS];    float flcoeffs3[BANDS];    float flcoeffs4[BANDS];    float flcoeffs5[BANDS];    float flcoeffs6[BANDS];    float CWdecoded[COEFFS];    /** MDCT tables */    //@{    float mdct_sine_window[COEFFS];    float post_cos[COEFFS];    float post_sin[COEFFS];    float pre_coef1[COEFFS];    float pre_coef2[COEFFS];    float last_fft_im[COEFFS];    //@}    int bandWidthT[BANDS];     ///< codewords per band    int bitsBandT[BANDS];      ///< how many bits per codeword in band    int CWlengthT[COEFFS];     ///< how many bits in each codeword    int levlCoeffBuf[BANDS];    int bandFlagsBuf[BANDS];   ///< flags for each band    int sumLenArr[BANDS];      ///< bits for all coeffs in band    int skipFlagRaw[BANDS];    ///< skip flags are stored in raw form or not    int skipFlagBits[BANDS];   ///< bits used to code skip flags    int skipFlagCount[BANDS];  ///< skipped coeffients per band    int skipFlags[COEFFS];     ///< skip coefficient decoding or not    int codewords[COEFFS];     ///< raw codewords read from bitstream    float sqrt_tab[30];    GetBitContext gb;    VLC huffman_vlc[4][4];    int decoder_reset;    float one_div_log2;    DSPContext dsp;    FFTContext fft;    DECLARE_ALIGNED_16(FFTComplex, samples[COEFFS/2]);    DECLARE_ALIGNED_16(float, out_samples[COEFFS]);} IMCContext;static int imc_decode_init(AVCodecContext * avctx){    int i, j;    IMCContext *q = avctx->priv_data;    double r1, r2;    q->decoder_reset = 1;    for(i = 0; i < BANDS; i++)        q->old_floor[i] = 1.0;    /* Build mdct window, a simple sine window normalized with sqrt(2) */    for(i = 0; i < COEFFS; i++)        q->mdct_sine_window[i] = sin((i + 0.5) / 512.0 * M_PI) * sqrt(2.0);    for(i = 0; i < COEFFS/2; i++){        q->post_cos[i] = cos(i / 256.0 * M_PI);        q->post_sin[i] = sin(i / 256.0 * M_PI);        r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);        r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);        if (i & 0x1)        {            q->pre_coef1[i] =  (r1 + r2) * sqrt(2.0);            q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);        }        else        {            q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);            q->pre_coef2[i] =  (r1 - r2) * sqrt(2.0);        }        q->last_fft_im[i] = 0;    }    /* Generate a square root table */    for(i = 0; i < 30; i++) {        q->sqrt_tab[i] = sqrt(i);    }    /* initialize the VLC tables */    for(i = 0; i < 4 ; i++) {        for(j = 0; j < 4; j++) {            init_vlc (&q->huffman_vlc[i][j], 9, imc_huffman_sizes[i],                     imc_huffman_lens[i][j], 1, 1,                     imc_huffman_bits[i][j], 2, 2, 1);        }    }    q->one_div_log2 = 1/log(2);    ff_fft_init(&q->fft, 7, 1);    dsputil_init(&q->dsp, avctx);    return 0;}static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeffs2, int* bandWidthT,                                float* flcoeffs3, float* flcoeffs5){    float   workT1[BANDS];    float   workT2[BANDS];    float   workT3[BANDS];    float   snr_limit = 1.e-30;    float   accum = 0.0;    int i, cnt2;    for(i = 0; i < BANDS; i++) {        flcoeffs5[i] = workT2[i] = 0.0;        if (bandWidthT[i]){            workT1[i] = flcoeffs1[i] * flcoeffs1[i];            flcoeffs3[i] = 2.0 * flcoeffs2[i];        } else {            workT1[i] = 0.0;            flcoeffs3[i] = -30000.0;        }        workT3[i] = bandWidthT[i] * workT1[i] * 0.01;        if (workT3[i] <= snr_limit)            workT3[i] = 0.0;    }    for(i = 0; i < BANDS; i++) {        for(cnt2 = i; cnt2 < cyclTab[i]; cnt2++)            flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];        workT2[cnt2-1] = workT2[cnt2-1] + workT3[i];    }    for(i = 1; i < BANDS; i++) {        accum = (workT2[i-1] + accum) * imc_weights1[i-1];        flcoeffs5[i] += accum;    }    for(i = 0; i < BANDS; i++)        workT2[i] = 0.0;    for(i = 0; i < BANDS; i++) {        for(cnt2 = i-1; cnt2 > cyclTab2[i]; cnt2--)            flcoeffs5[cnt2] += workT3[i];        workT2[cnt2+1] += workT3[i];    }    accum = 0.0;    for(i = BANDS-2; i >= 0; i--) {        accum = (workT2[i+1] + accum) * imc_weights2[i];        flcoeffs5[i] += accum;        //there is missing code here, but it seems to never be triggered    }}static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* levlCoeffs){    int i;    VLC *hufftab[4];    int start = 0;    const uint8_t *cb_sel;    int s;    s = stream_format_code >> 1;    hufftab[0] = &q->huffman_vlc[s][0];    hufftab[1] = &q->huffman_vlc[s][1];    hufftab[2] = &q->huffman_vlc[s][2];    hufftab[3] = &q->huffman_vlc[s][3];    cb_sel = imc_cb_select[s];    if(stream_format_code & 4)        start = 1;    if(start)        levlCoeffs[0] = get_bits(&q->gb, 7);    for(i = start; i < BANDS; i++){        levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, hufftab[cb_sel[i]]->bits, 2);        if(levlCoeffs[i] == 17)            levlCoeffs[i] += get_bits(&q->gb, 4);    }}static void imc_decode_level_coefficients(IMCContext* q, int* levlCoeffBuf, float* flcoeffs1,                                         float* flcoeffs2){    int i, level;    float tmp, tmp2;    //maybe some frequency division thingy    flcoeffs1[0] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125    flcoeffs2[0] = log(flcoeffs1[0])/log(2);    tmp = flcoeffs1[0];    tmp2 = flcoeffs2[0];    for(i = 1; i < BANDS; i++) {        level = levlCoeffBuf[i];        if (level == 16) {            flcoeffs1[i] = 1.0;            flcoeffs2[i] = 0.0;        } else {            if (level < 17)                level -=7;            else if (level <= 24)                level -=32;            else                level -=16;            tmp  *= imc_exp_tab[15 + level];            tmp2 += 0.83048 * level;  // 0.83048 = log2(10) * 0.25            flcoeffs1[i] = tmp;            flcoeffs2[i] = tmp2;        }    }}static void imc_decode_level_coefficients2(IMCContext* q, int* levlCoeffBuf, float* old_floor, float* flcoeffs1,                                          float* flcoeffs2) {    int i;        //FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors        //      and flcoeffs2 old scale factors        //      might be incomplete due to a missing table that is in the binary code    for(i = 0; i < BANDS; i++) {        flcoeffs1[i] = 0;        if(levlCoeffBuf[i] < 16) {            flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i];            flcoeffs2[i] = (levlCoeffBuf[i]-7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25        } else {            flcoeffs1[i] = old_floor[i];        }    }}/** * Perform bit allocation depending on bits available */static int bit_allocation (IMCContext* q, int stream_format_code, int freebits, int flag) {    int i, j;    const float limit = -1.e20;    float highest = 0.0;    int indx;    int t1 = 0;    int t2 = 1;    float summa = 0.0;    int iacc = 0;    int summer = 0;    int rres, cwlen;    float lowest = 1.e10;    int low_indx = 0;    float workT[32];    int flg;    int found_indx = 0;    for(i = 0; i < BANDS; i++)        highest = FFMAX(highest, q->flcoeffs1[i]);    for(i = 0; i < BANDS-1; i++) {        q->flcoeffs4[i] = q->flcoeffs3[i] - log(q->flcoeffs5[i])/log(2);    }    q->flcoeffs4[BANDS - 1] = limit;    highest = highest * 0.25;    for(i = 0; i < BANDS; i++) {        indx = -1;        if ((band_tab[i+1] - band_tab[i]) == q->bandWidthT[i])            indx = 0;        if ((band_tab[i+1] - band_tab[i]) > q->bandWidthT[i])            indx = 1;        if (((band_tab[i+1] - band_tab[i])/2) >= q->bandWidthT[i])            indx = 2;        if (indx == -1)            return -1;        q->flcoeffs4[i] = q->flcoeffs4[i] + xTab[(indx*2 + (q->flcoeffs1[i] < highest)) * 2 + flag];    }    if (stream_format_code & 0x2) {        q->flcoeffs4[0] = limit;        q->flcoeffs4[1] = limit;        q->flcoeffs4[2] = limit;        q->flcoeffs4[3] = limit;    }    for(i = (stream_format_code & 0x2)?4:0; i < BANDS-1; i++) {        iacc += q->bandWidthT[i];        summa += q->bandWidthT[i] * q->flcoeffs4[i];    }    q->bandWidthT[BANDS-1] = 0;    summa = (summa * 0.5 - freebits) / iacc;    for(i = 0; i < BANDS/2; i++) {        rres = summer - freebits;        if((rres >= -8) && (rres <= 8)) break;        summer = 0;        iacc = 0;        for(j = (stream_format_code & 0x2)?4:0; j < BANDS; j++) {            cwlen = av_clip((int)((q->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);            q->bitsBandT[j] = cwlen;            summer += q->bandWidthT[j] * cwlen;            if (cwlen > 0)                iacc += q->bandWidthT[j];        }        flg = t2;        t2 = 1;        if (freebits < summer)            t2 = -1;        if (i == 0)            flg = t2;        if(flg != t2)            t1++;        summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;    }    for(i = (stream_format_code & 0x2)?4:0; i < BANDS; i++) {        for(j = band_tab[i]; j < band_tab[i+1]; j++)            q->CWlengthT[j] = q->bitsBandT[i];    }    if (freebits > summer) {        for(i = 0; i < BANDS; i++) {            workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415);        }        highest = 0.0;        do{            if (highest <= -1.e20)                break;            found_indx = 0;            highest = -1.e20;            for(i = 0; i < BANDS; i++) {                if (workT[i] > highest) {                    highest = workT[i];                    found_indx = i;                }            }            if (highest > -1.e20) {                workT[found_indx] -= 2.0;                if (++(q->bitsBandT[found_indx]) == 6)                    workT[found_indx] = -1.e20;                for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (freebits > summer); j++){                    q->CWlengthT[j]++;                    summer++;                }            }        }while (freebits > summer);    }    if (freebits < summer) {

⌨️ 快捷键说明

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