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

📄 wmadeci.c

📁 wma定点解码算法
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: $ * * Copyright (C) 2005 Dave Chapman * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************//* * WMA decoder : Fixed (16.16) point decoding based originally on the ffmpeg * WMA decoder source : http://ffmpeg.sourceforge.net. * This version 01/04/06 Marsdaddy <pajojo@gmail.com> */#include "malloc.h"#include "memory.h"/* size of blocks */#define BLOCK_MIN_BITS 7#define BLOCK_MAX_BITS 11#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS)#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1)#define HIGH_BAND_MAX_SIZE 16#define NB_LSP_COEFS 10#define MAX_CODED_SUPERFRAME_SIZE 16384#define M_PI_F  0x3243f /* in fixed 32 format */#define MAX_CHANNELS 2#define NOISE_TAB_SIZE 8192#define LSP_POW_BITS 7#define VLC_TYPE int16_ttypedef unsigned char uint8_t;typedef char int8_t;typedef unsigned short uint16_t;typedef short int16_t;typedef long long int64_t;typedef int int32_t;typedef unsigned int uint32_t;typedef unsigned long long uint64_t;#define fixed32         int32_t#define fixed64         int64_t#include "codeccontext.h"#include "wmadeci.h"#define IGNORE_OVERFLOW#define FAST_FILTERS#define PRECISION       16#define PRECISION64     16static fixed64 IntTo64(int x){    fixed64 res = 0;    unsigned char *p = (unsigned char *)&res;    p[2] = x & 0xff;    p[3] = (x & 0xff00)>>8;    p[4] = (x & 0xff0000)>>16;    p[5] = (x & 0xff000000)>>24;    return res;}static int IntFrom64(fixed64 x){    int res = 0;    unsigned char *p = (unsigned char *)&x;    res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);    return res;}static fixed32 Fixed32From64(fixed64 x){  return x & 0xFFFFFFFF;}static fixed64 Fixed32To64(fixed32 x){  return (fixed64)x;}#define itofix64(x)       (IntTo64(x))#define itofix32(x)       ((x) << PRECISION)#define fixtoi32(x)       ((x) >> PRECISION)#define fixtoi64(x)       (IntFrom64(x))static fixed64 fixmul64byfixed(fixed64 x, fixed32 y){    return x * y;}/* Portions of this 32 bit fixed code modified from the GPL Hawksoftsource <http://www.hawkfost.com> by Phil Frisbie, Jr. <phil@hawksoft.com> */static fixed32 fixmul32(fixed32 x, fixed32 y){    fixed64 temp;    temp = x;    temp *= y;    temp >>= PRECISION;#ifndef IGNORE_OVERFLOW    if(temp > 0x7fffffff)    {        return 0x7fffffff;    }    else if(temp < -0x7ffffffe)    {        return -0x7ffffffe;    }#endif    return (fixed32)temp;}static fixed32 fixdiv32(fixed32 x, fixed32 y){    fixed64 temp;    if(x == 0)        return 0;    if(y == 0)        return 0x7fffffff;    temp = x;    temp <<= PRECISION;    return (fixed32)(temp / y);}static fixed64 fixdiv64(fixed64 x, fixed64 y){    fixed64 temp;    if(x == 0)        return 0;    if(y == 0)        return 0x07ffffffffffffffLL;    temp = x;    temp <<= PRECISION64;    return (fixed64)(temp / y);}static fixed32 fixsqrt32(fixed32 x){    unsigned long r = 0, s, v = (unsigned long)x;#define STEP(k) s = r + (1 << k * 2); r >>= 1; \    if (s <= v) { v -= s; r |= (1 << k * 2); }    STEP(15);    STEP(14);    STEP(13);    STEP(12);    STEP(11);    STEP(10);    STEP(9);    STEP(8);    STEP(7);    STEP(6);    STEP(5);    STEP(4);    STEP(3);    STEP(2);    STEP(1);    STEP(0);    return (fixed32)(r << (PRECISION / 2));}__inline fixed32 fixsin32(fixed32 x){    fixed64 x2, temp;    int     sign = 1;    if(x < 0)    {        sign = -1;        x = -x;    }    while (x > 0x19220)    {        x -= M_PI_F;        sign = -sign;    }    if (x > 0x19220)    {        x = M_PI_F - x;    }    x2 = (fixed64)x * x;    x2 >>= PRECISION;    if(sign != 1)    {        x = -x;    }    /**    temp = ftofix32(-.0000000239f) * x2;    temp >>= PRECISION;    **/    temp = 0; /* PJJ */    temp = (temp + 0x0) * x2;    temp >>= PRECISION;    temp = (temp - 0xd) * x2;    temp >>= PRECISION;    temp = (temp + 0x222) * x2;    temp >>= PRECISION;    temp = (temp - 0x2aab) * x2;    temp >>= PRECISION;    temp += 0x10000;    temp = temp * x;    temp >>= PRECISION;    return  (fixed32)(temp);}__inline fixed32 fixcos32(fixed32 x){    return fixsin32(x - (M_PI_F>>1))*-1;}__inline fixed32 fixasin32(fixed32 x){    fixed64 temp;    int     sign = 1;    if(x > 0x10000 || x < 0xffff0000)    {        return 0;    }    if(x < 0)    {        sign = -1;        x = -x;    }    temp = 0xffffffad * (fixed64)x;    temp >>= PRECISION;    temp = (temp + 0x1b5) * x;    temp >>= PRECISION;    temp = (temp - 0x460) * x;    temp >>= PRECISION;    temp = (temp + 0x7e9) * x;    temp >>= PRECISION;    temp = (temp - 0xcd8) * x;    temp >>= PRECISION;    temp = (temp + 0x16c7) * x;    temp >>= PRECISION;    temp = (temp - 0x36f0) * x;    temp >>= PRECISION;    temp = (temp + 0x19220) * fixsqrt32(0x10000 - x);    temp >>= PRECISION;    return sign * ((M_PI_F>>1) - (fixed32)temp);}#define ALT_BITSTREAM_READER#define unaligned32(a) (*(uint32_t*)(a))uint16_t bswap_16(uint16_t x){    uint16_t hi = x & 0xff00;    uint16_t lo = x & 0x00ff;    return (hi >> 8) | (lo << 8);}uint32_t bswap_32(uint32_t x){    uint32_t b1 = x & 0xff000000;    uint32_t b2 = x & 0x00ff0000;    uint32_t b3 = x & 0x0000ff00;    uint32_t b4 = x & 0x000000ff;    return (b1 >> 24) | (b2 >> 8) | (b3 << 8) | (b4 << 24);}/* PJJ : reinstate macro */void CMUL(fixed32 *pre,          fixed32 *pim,          fixed32 are,          fixed32 aim,          fixed32 bre,          fixed32 bim){    fixed32 _aref = are;    fixed32 _aimf = aim;    fixed32 _bref = bre;    fixed32 _bimf = bim;    fixed32 _r1 = fixmul32(_aref, _bref);    fixed32 _r2 = fixmul32(_aimf, _bimf);    fixed32 _r3 = fixmul32(_aref, _bimf);    fixed32 _r4 = fixmul32(_aimf, _bref);    *pre = _r1 - _r2;    *pim = _r3 + _r4;}#ifdef WORDS_BIGENDIAN#define be2me_16(x) (x)#define be2me_32(x) (x)#define be2me_64(x) (x)#define le2me_16(x) bswap_16(x)#define le2me_32(x) bswap_32(x)#define le2me_64(x) bswap_64(x)#else#define be2me_16(x) bswap_16(x)#define be2me_32(x) bswap_32(x)#define be2me_64(x) bswap_64(x)#define le2me_16(x) (x)#define le2me_32(x) (x)#define le2me_64(x) (x)#endif#define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))static inline int unaligned32_be(const void *v){#ifdef CONFIG_ALIGN    const uint8_t *p=v;    return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]);#else    return be2me_32( unaligned32(v)); /* original */#endif}typedef struct GetBitContext{    const uint8_t *buffer, *buffer_end;#ifdef ALT_BITSTREAM_READER    int index;#elif defined LIBMPEG2_BITSTREAM_READER    uint8_t *buffer_ptr;    uint32_t cache;    int bit_count;#elif defined A32_BITSTREAM_READER    uint32_t *buffer_ptr;    uint32_t cache0;    uint32_t cache1;    int bit_count;#endif    int size_in_bits;}GetBitContext;typedef struct VLC{    int bits;    VLC_TYPE (*table)[2];    int table_size, table_allocated;}VLC;typedef struct FFTComplex{    fixed32 re, im;}FFTComplex;typedef struct FFTContext{    int nbits;    int inverse;    uint16_t *revtab;    FFTComplex *exptab;    FFTComplex *exptab1; /* only used by SSE code */    void (*fft_calc)(struct FFTContext *s, FFTComplex *z);}FFTContext;typedef struct MDCTContext{    int n;  /* size of MDCT (i.e. number of input data * 2) */    int nbits; /* n = 2^nbits */    /* pre/post rotation tables */    fixed32 *tcos;    fixed32 *tsin;    FFTContext fft;}MDCTContext;typedef struct WMADecodeContext{    GetBitContext gb;    int sample_rate;    int nb_channels;    int bit_rate;    int version; /* 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) */    int block_align;    int use_bit_reservoir;    int use_variable_block_len;    int use_exp_vlc;  /* exponent coding: 0 = lsp, 1 = vlc + delta */    int use_noise_coding; /* true if perceptual noise is added */    int byte_offset_bits;    VLC exp_vlc;    int exponent_sizes[BLOCK_NB_SIZES];    uint16_t exponent_bands[BLOCK_NB_SIZES][25];    int high_band_start[BLOCK_NB_SIZES]; /* index of first coef in high band */    int coefs_start;               /* first coded coef */    int coefs_end[BLOCK_NB_SIZES]; /* max number of coded coefficients */    int exponent_high_sizes[BLOCK_NB_SIZES];    int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE];    VLC hgain_vlc;    /* coded values in high bands */    int high_band_coded[MAX_CHANNELS][HIGH_BAND_MAX_SIZE];    int high_band_values[MAX_CHANNELS][HIGH_BAND_MAX_SIZE];    /* there are two possible tables for spectral coefficients */    VLC coef_vlc[2];    uint16_t *run_table[2];    uint16_t *level_table[2];    /* frame info */    int frame_len;       /* frame length in samples */    int frame_len_bits;  /* frame_len = 1 << frame_len_bits */    int nb_block_sizes;  /* number of block sizes */    /* block info */    int reset_block_lengths;    int block_len_bits; /* log2 of current block length */    int next_block_len_bits; /* log2 of next block length */    int prev_block_len_bits; /* log2 of prev block length */    int block_len; /* block length in samples */    int block_num; /* block number in current frame */    int block_pos; /* current position in frame */    uint8_t ms_stereo; /* true if mid/side stereo mode */    uint8_t channel_coded[MAX_CHANNELS]; /* true if channel is coded */    fixed32 exponents[MAX_CHANNELS][BLOCK_MAX_SIZE];    fixed32 max_exponent[MAX_CHANNELS];    int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE];    fixed32 coefs[MAX_CHANNELS][BLOCK_MAX_SIZE];    MDCTContext mdct_ctx[BLOCK_NB_SIZES];    fixed32 *windows[BLOCK_NB_SIZES];    FFTComplex mdct_tmp[BLOCK_MAX_SIZE]; /* temporary storage for imdct */    /* output buffer for one frame and the last for IMDCT windowing */    fixed32 frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE * 2];    /* last frame info */    uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */    int last_bitoffset;    int last_superframe_len;    fixed32 noise_table[NOISE_TAB_SIZE];    int noise_index;    fixed32 noise_mult; /* XXX: suppress that and integrate it in the noise array */    /* lsp_to_curve tables */    fixed32 lsp_cos_table[BLOCK_MAX_SIZE];    fixed64 lsp_pow_e_table[256];    fixed64 lsp_pow_m_table1[(1 << LSP_POW_BITS)];    fixed64 lsp_pow_m_table2[(1 << LSP_POW_BITS)];#ifdef TRACE    int frame_count;#endif} WMADecodeContext;/*** Prototypes ***/static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len);void fft_calc(FFTContext *s, FFTComplex *z);void av_free(void *ptr); /* PJJ found below */static inline int av_log2(unsigned int v){    int n;    n = 0;    if (v & 0xffff0000)    {        v >>= 16;        n += 16;    }    if (v & 0xff00)    {        v >>= 8;        n += 8;    }    n += ff_log2_tab[v];    return n;

⌨️ 快捷键说明

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