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

📄 cook.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * COOK compatible decoder * Copyright (c) 2003 Sascha Sommer * Copyright (c) 2005 Benjamin Larsson * * 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 cook.c * Cook compatible decoder. Bastardization of the G.722.1 standard. * This decoder handles RealNetworks, RealAudio G2 data. * Cook is identified by the codec name cook in RM files. * * To use this decoder, a calling application must supply the extradata * bytes provided from the RM container; 8+ bytes for mono streams and * 16+ for stereo streams (maybe more). * * Codec technicalities (all this assume a buffer length of 1024): * Cook works with several different techniques to achieve its compression. * In the timedomain the buffer is divided into 8 pieces and quantized. If * two neighboring pieces have different quantization index a smooth * quantization curve is used to get a smooth overlap between the different * pieces. * To get to the transformdomain Cook uses a modulated lapped transform. * The transform domain has 50 subbands with 20 elements each. This * means only a maximum of 50*20=1000 coefficients are used out of the 1024 * available. */#include <math.h>#include <stddef.h>#include <mplaylib.h>#include "avcodec.h"#include "bitstream.h"#include "dsputil.h"#include "bytestream.h"#include "random.h"#include "cookdata.h"#undef memcpy#define memcpy uc_memcpy/* the different Cook versions */#define MONO            0x1000001#define STEREO          0x1000002#define JOINT_STEREO    0x1000003#define MC_COOK         0x2000000   //multichannel Cook, not supported#define SUBBAND_SIZE    20#if 1#define COOKFIXED31(a) ( (a) * (1 << 26))//#define COOKFIXED31(a) ( (a) * 0x7fffffff)#define FIXEDSAMPLE(a) ( (a) * (1 << 8))#define FLOATSAMPLE(a) (((float)(a))/(1<<8))#define FIX_31_SQRT2    94906265 /* FFT computation *//* NOTE: soon integer code will be added, so you must use the   FFTSample type */typedef int CookFFTSample;typedef int CookLevel;typedef struct CookFFTComplex {    CookFFTSample re, im;} CookFFTComplex;struct CookMDCTContext;typedef struct CookFFTContext {    int nbits;    int inverse;    uint16_t *revtab;    CookFFTComplex *exptab;} CookFFTContext;/* MDCT computation */typedef struct CookMDCTContext {    int n;  /* size of MDCT (i.e. number of input data * 2) */    int nbits; /* n = 2^nbits */    /* pre/post rotation tables */    CookFFTSample *tcos;    CookFFTSample *tsin;    CookFFTContext fft;} CookMDCTContext;/** * The size of the FFT is 2^nbits. If inverse is TRUE, inverse FFT is * done */int Cook_fft_init(CookFFTContext *s, int nbits, int inverse){    int i, j, m, n;    float alpha, c1, s1, s2;    s->nbits = nbits;    n = 1 << nbits;    s->exptab = av_malloc((n / 2) * sizeof(CookFFTComplex));    if (!s->exptab)        goto fail;    s->revtab = av_malloc(n * sizeof(uint16_t));    if (!s->revtab)        goto fail;    s->inverse = inverse;    s2 = inverse ? 1.0 : -1.0;    for(i=0;i<(n/2);i++) {        alpha = 2 * M_PI * (float)i / (float)n;        c1 = cos(alpha);        s1 = sin(alpha) * s2;        s->exptab[i].re = COOKFIXED31(c1);        s->exptab[i].im = COOKFIXED31(s1);    }    /* 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);    return -1;}/** * init MDCT or IMDCT computation. */int Cook_mdct_init(CookMDCTContext *s, int nbits, int inverse){    int n, n4, i;    float alpha;    memset(s, 0, sizeof(*s));    n = 1 << nbits;    s->nbits = nbits;    s->n = n;    n4 = n >> 2;    s->tcos = av_malloc(n4 * sizeof(CookFFTSample));    if (!s->tcos)        goto fail;    s->tsin = av_malloc(n4 * sizeof(CookFFTSample));    if (!s->tsin)        goto fail;    for(i=0;i<n4;i++) {        alpha = 2 * M_PI * (i + 1.0 / 8.0) / n;        s->tcos[i] = COOKFIXED31(-cos(alpha));        s->tsin[i] = COOKFIXED31(-sin(alpha));    }    if (Cook_fft_init(&s->fft, s->nbits - 2, inverse) < 0)        goto fail;    return 0; fail:    av_freep(&s->tcos);    av_freep(&s->tsin);    return -1;}void Cook_fft_end(CookFFTContext *s){    av_freep(&s->revtab);    av_freep(&s->exptab);}void Cook_mdct_end(CookMDCTContext *s){    av_freep(&s->tcos);    av_freep(&s->tsin);    Cook_fft_end(&s->fft);}/* butter fly op */#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \{\  CookFFTSample ax, ay, bx, by;\  bx=pre1;\  by=pim1;\  ax=qre1;\  ay=qim1;\  pre = (bx + ax);\  pim = (by + ay);\  qre = (bx - ax);\  qim = (by - ay);\}//#define MUL(a,b) ((a) * (b))//#define MUL(a,b) (((long long)(a) * (b))>>26)#define MUL(a,b) \   ({\       long hi, lo;\        __asm__ __volatile__("mult %2, %3"\                            :"=l" (lo), "=h" (hi)\                            :"%r" (a), "r" (b));\      hi << 6;\     })#define CMUL(pre, pim, are, aim, bre, bim) \{\   pre = (MUL(are, bre) - MUL(aim, bim));\   pim = (MUL(are, bim) + MUL(aim, bre));\}/** * Do a complex FFT with the parameters defined in ff_fft_init(). The * input data must be permuted before with s->revtab table. No * 1.0/sqrt(n) normalization is done. */void Cook_fft_calc(CookFFTContext *s, CookFFTComplex *z){    int ln = s->nbits;    int j, np, np2;    int nblocks, nloops;    register CookFFTComplex *p, *q;    CookFFTComplex *exptab = s->exptab;    int l;    CookFFTSample 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);}/** * Compute inverse MDCT of size N = 2^nbits * @param output N samples * @param input N/2 samples * @param tmp N/2 samples */void cook_imdct_calc(CookMDCTContext *s, CookFFTSample *output,                   const CookFFTSample *input, CookFFTSample *tmp){    int k, n8, n4, n2, n, j;    const uint16_t *revtab = s->fft.revtab;    const CookFFTSample *tcos = s->tcos;    const CookFFTSample *tsin = s->tsin;    const CookFFTSample *in1, *in2;    CookFFTSample tmp_in1, tmp_in2;    CookFFTComplex *z = (CookFFTComplex *)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;    }    Cook_fft_calc(&s->fft, z);    /* post rotation + reordering */    /* XXX: optimize */    for(k = 0; k < n4; k++) {        tmp_in1 = z[k].re;        tmp_in2 = z[k].im;        CMUL(z[k].re, z[k].im, tmp_in1, tmp_in2, tcos[k], tsin[k]);    }     for(k = 0; k < n8; k++) {        output[2*k] = -z[n8 + k].im;        output[n2-1-2*k] = z[n8 + k].im;        output[2*k+1] = z[n8-1-k].re;        output[n2-1-2*k-1] = -z[n8-1-k].re;        output[n2 + 2*k]=-z[k+n8].re;        output[n-1- 2*k]=-z[k+n8].re;        output[n2 + 2*k+1]=z[n8-k-1].im;        output[n-2 - 2 * k] = z[n8-k-1].im;    }}#endiftypedef struct {    int *now;    int *previous;} cook_gains;typedef struct cook {    /*     * The following 5 functions provide the lowlevel arithmetic on     * the internal audio buffers.     */    void (* scalar_dequant)(struct cook *q, int index, int quant_index,                            int* subband_coef_index, int* subband_coef_sign,                            CookFFTSample * mlt_p);    void (* decouple) (struct cook *q,                       int subband,                       CookFFTSample f1, CookFFTSample f2,                       CookFFTSample *decode_buffer,                       CookFFTSample *mlt_buffer1, CookFFTSample *mlt_buffer2);    void (* imlt_window) (struct cook *q, CookFFTSample *buffer1,                          cook_gains *gains_ptr, CookFFTSample *previous_buffer);    void (* interpolate) (struct cook *q,CookFFTSample * buffer,                          int gain_index, int gain_index_next);

⌨️ 快捷键说明

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