diff options
author | Dave Chapman <dave@dchapman.com> | 2007-07-03 09:25:36 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-07-03 09:25:36 +0000 |
commit | c72824786a0e8c68921ebb9b72f02a2e80aaee17 (patch) | |
tree | adf8dac26d074ee3620df4ab482ff108561ead01 /apps/codecs/libwma/wmadec.h | |
parent | 2ca895bae7a25ea8ef7f295b4e8ab01ff75a4914 (diff) |
Initial, work-in-progress, version of a WMA codec using Michael Giacomelli's fixed-point and malloc-less WMA decoder (based on the ffmpeg WMA decoder from early 2006, and also building on the work started by Paul Jones). The codec itself and the ASF parsing code were written by me, inspired by the ASF parser in libasf. Current performance is around 400% realtime on gigabeat, 100% realtime on PP and 20% realtime on Coldfire.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13769 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwma/wmadec.h')
-rw-r--r-- | apps/codecs/libwma/wmadec.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/apps/codecs/libwma/wmadec.h b/apps/codecs/libwma/wmadec.h new file mode 100644 index 0000000000..89c100daba --- /dev/null +++ b/apps/codecs/libwma/wmadec.h @@ -0,0 +1,162 @@ +#ifndef _WMADEC_H +#define _WMADEC_H + +#include "asf.h" +#include "common.h" /* For GetBitContext */ +//#include "dsputil.h" /* For MDCTContext */ + + +//#define TRACE +/* 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) + +/* XXX: find exact max size */ +#define HIGH_BAND_MAX_SIZE 16 + +#define NB_LSP_COEFS 10 + +/* XXX: is it a suitable value ? */ +#define MAX_CODED_SUPERFRAME_SIZE 16384 + +#define M_PI 3.14159265358979323846 + +#define M_PI_F 0x3243f // in fixed 32 format +#define TWO_M_PI_F 0x6487f //in fixed 32 + +#define MAX_CHANNELS 2 + +#define NOISE_TAB_SIZE 8192 + +#define LSP_POW_BITS 7 + +#define VLC_TYPE int16_t + +typedef struct VLC +{ + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} +VLC; + +#define fixed32 int32_t +#define fixed64 int64_t + +typedef fixed32 FFTSample; + +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 */ + int (*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 nb_block_sizes; /* number of block sizes */ + + 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 */ + + /* 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; + +int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx); +int wma_decode_superframe(WMADecodeContext* s, + void *data, int *data_size, + uint8_t *buf, int buf_size); +int wma_decode_end(WMADecodeContext *s); + +#endif |