changeset 957:f3ccef1dcd61 trunk

[svn] Hammer the WMA plugin into shape enough to bolt the following upstream commit on: "WMA decoder improvement, output closer to the dmo binary. Patch by Ian Braithwaite ian braithwaite dot dk".
author chainsaw
date Sat, 14 Apr 2007 17:38:32 -0700
parents 88ba14f18587
children 30e515b6e651
files ChangeLog src/wma/libffwma/dsputil.h src/wma/libffwma/wma.h src/wma/libffwma/wmadata.h src/wma/libffwma/wmadec.c
diffstat 5 files changed, 249 insertions(+), 202 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Apr 14 16:09:21 2007 -0700
+++ b/ChangeLog	Sat Apr 14 17:38:32 2007 -0700
@@ -1,3 +1,12 @@
+2007-04-14 23:09:21 +0000  Tony Vroon <chainsaw@gentoo.org>
+  revision [2052]
+  I said to indent it, not to break it, hmmkay?
+  trunk/src/adplug/core/fprovide.cxx |   47 -
+  trunk/src/adplug/core/players.cxx  |   82 +-
+  trunk/src/adplug/core/rol.cxx      | 1024 ++++++++++++++++---------------------
+  3 files changed, 523 insertions(+), 630 deletions(-)
+
+
 2007-04-14 22:23:50 +0000  Tony Vroon <chainsaw@gentoo.org>
   revision [2050]
   Run indent -ts4 -nut -bli0 -cdw on this messy lot. Upstream is not consistent with whitespace anyway, no loss there.
--- a/src/wma/libffwma/dsputil.h	Sat Apr 14 16:09:21 2007 -0700
+++ b/src/wma/libffwma/dsputil.h	Sat Apr 14 17:38:32 2007 -0700
@@ -60,16 +60,13 @@
 extern uint32_t squareTbl[512];
 extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
 
-
-/* minimum alignment rules ;)
-if u notice errors in the align stuff, need more alignment for some asm code for some cpu
-or need to use a function with less aligned data then send a mail to the ffmpeg-dev list, ...
-
-!warning these alignments might not match reallity, (missing attribute((align)) stuff somewhere possible)
-i (michael) didnt check them, these are just the alignents which i think could be reached easily ...
-
-!future video codecs might need functions with less strict alignment
-*/
+#ifdef __GNUC__
+  #define DECLARE_ALIGNED_8(t,v)       t v __attribute__ ((aligned (8)))
+  #define DECLARE_ALIGNED_16(t,v)       t v __attribute__ ((aligned (16)))
+#else
+  #define DECLARE_ALIGNED_8(t,v)      __declspec(align(8)) t v
+  #define DECLARE_ALIGNED_16(t,v)      __declspec(align(16)) t v
+#endif
 
 /*
 void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wma/libffwma/wma.h	Sat Apr 14 17:38:32 2007 -0700
@@ -0,0 +1,150 @@
+/*
+ * WMA compatible codec
+ * Copyright (c) 2002-2007 The FFmpeg Project.
+ *
+ * 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
+ */
+
+#ifndef WMA_H
+#define WMA_H
+
+/* #include "bitstream.h" */
+#include "dsputil.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)
+
+/* 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 MAX_CHANNELS 2
+
+#define NOISE_TAB_SIZE 8192
+
+#define LSP_POW_BITS 7
+
+//FIXME should be in wmadec
+#define VLCBITS 9
+#define VLCMAX ((22+VLCBITS-1)/VLCBITS)
+
+typedef struct CoefVLCTable {
+    int n;                      ///< total number of codes
+    int max_level;
+    const uint32_t *huffcodes;  ///< VLC bit values
+    const uint8_t *huffbits;    ///< VLC bit size
+    const uint16_t *levels;     ///< table to build run/level tables
+} CoefVLCTable;
+
+typedef struct WMACodecContext {
+    AVCodecContext* avctx;
+    GetBitContext gb;
+    PutBitContext pb;
+    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 */
+//FIXME the following 3 tables should be shared between decoders
+    VLC coef_vlc[2];
+    uint16_t *run_table[2];
+    uint16_t *level_table[2];
+    uint16_t *int_table[2];
+    CoefVLCTable *coef_vlcs[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
+    int exponents_bsize[MAX_CHANNELS];      ///< log2 ratio frame/exp. length
+    DECLARE_ALIGNED_16(float, exponents[MAX_CHANNELS][BLOCK_MAX_SIZE]);
+    float max_exponent[MAX_CHANNELS];
+    int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE];
+    DECLARE_ALIGNED_16(float, coefs[MAX_CHANNELS][BLOCK_MAX_SIZE]);
+    DECLARE_ALIGNED_16(FFTSample, output[BLOCK_MAX_SIZE * 2]);
+    MDCTContext mdct_ctx[BLOCK_NB_SIZES];
+    float *windows[BLOCK_NB_SIZES];
+    DECLARE_ALIGNED_16(FFTSample, mdct_tmp[BLOCK_MAX_SIZE]); ///< temporary storage for imdct
+    /* output buffer for one frame and the last for IMDCT windowing */
+    DECLARE_ALIGNED_16(float, 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;
+    float noise_table[NOISE_TAB_SIZE];
+    int noise_index;
+    float noise_mult; /* XXX: suppress that and integrate it in the noise array */
+    /* lsp_to_curve tables */
+    float lsp_cos_table[BLOCK_MAX_SIZE];
+    float lsp_pow_e_table[256];
+    float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
+    float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
+    DSPContext dsp;
+
+#ifdef TRACE
+    int frame_count;
+#endif
+} WMACodecContext;
+
+extern const uint16_t ff_wma_hgain_huffcodes[37];
+extern const uint8_t ff_wma_hgain_huffbits[37];
+extern const float ff_wma_lsp_codebook[NB_LSP_COEFS][16];
+extern const uint32_t ff_wma_scale_huffcodes[121];
+extern const uint8_t ff_wma_scale_huffbits[121];
+
+int ff_wma_init(AVCodecContext * avctx, int flags2);
+int ff_wma_total_gain_to_bits(int total_gain);
+int ff_wma_end(AVCodecContext *avctx);
+
+#endif
--- a/src/wma/libffwma/wmadata.h	Sat Apr 14 16:09:21 2007 -0700
+++ b/src/wma/libffwma/wmadata.h	Sat Apr 14 17:38:32 2007 -0700
@@ -1,3 +1,24 @@
+/*
+ * WMA compatible decoder
+ * copyright (c) 2002 The FFmpeg Project
+ *
+ * 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 wmadata.h
  * Various WMA tables.
@@ -29,7 +50,7 @@
     { 17,  4,   8,   8,   4,  12,  12,   8,   8,  24,  16,  20,  24,  32,  40,  60,  80, 152, },
 };
 
-static const uint16_t hgain_huffcodes[37] = {
+const uint16_t ff_wma_hgain_huffcodes[37] = {
  0x00003, 0x002e7, 0x00001, 0x005cd, 0x0005d, 0x005c9, 0x0005e, 0x00003,
  0x00016, 0x0000b, 0x00001, 0x00006, 0x00001, 0x00006, 0x00004, 0x00005,
  0x00004, 0x00007, 0x00003, 0x00007, 0x00004, 0x0000a, 0x0000a, 0x00002,
@@ -37,7 +58,7 @@
  0x005c8, 0x000b8, 0x005ca, 0x005cb, 0x005cc,
 };
 
-static const uint8_t hgain_huffbits[37] = {
+const uint8_t ff_wma_hgain_huffbits[37] = {
  10, 12, 10, 13,  9, 13,  9,  8,
   7,  5,  5,  4,  4,  3,  3,  3,
   4,  3,  4,  4,  5,  5,  6,  8,
@@ -45,7 +66,7 @@
  13, 10, 13, 13, 13,
 };
 
-static const float lsp_codebook[NB_LSP_COEFS][16] = {
+const float ff_wma_lsp_codebook[NB_LSP_COEFS][16] = {
  { 1.98732877, 1.97944528, 1.97179088, 1.96260549, 1.95038374, 1.93336114, 1.90719232, 1.86191415, },
  { 1.97260000, 1.96083160, 1.94982586, 1.93806164, 1.92516608, 1.91010199, 1.89232331, 1.87149812,
    1.84564818, 1.81358067, 1.77620070, 1.73265264, 1.67907855, 1.60959081, 1.50829650, 1.33120330, },
@@ -65,7 +86,7 @@
  { -1.56144989, -1.65944032, -1.72689685, -1.77857740, -1.82203011, -1.86220079, -1.90283983, -1.94820479, },
 };
 
-static const uint32_t scale_huffcodes[121] = {
+const uint32_t ff_wma_scale_huffcodes[121] = {
  0x3ffe8, 0x3ffe6, 0x3ffe7, 0x3ffe5, 0x7fff5, 0x7fff1, 0x7ffed, 0x7fff6,
  0x7ffee, 0x7ffef, 0x7fff0, 0x7fffc, 0x7fffd, 0x7ffff, 0x7fffe, 0x7fff7,
  0x7fff8, 0x7fffb, 0x7fff9, 0x3ffe4, 0x7fffa, 0x3ffe3, 0x1ffef, 0x1fff0,
@@ -84,7 +105,7 @@
  0x7fff3,
 };
 
-static const uint8_t scale_huffbits[121] = {
+const uint8_t ff_wma_scale_huffbits[121] = {
  18, 18, 18, 18, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 18, 19, 18, 17, 17,
@@ -1389,24 +1410,24 @@
   1,  1,  1,  1,  1,  1,  1,  1,
   1,  1,  1,  1,  1,  1,  1,  1,
 };
-    
+
 static const CoefVLCTable coef_vlcs[6] = {
-    { 
-        sizeof(coef0_huffbits), coef0_huffcodes, coef0_huffbits, levels0,
+    {
+        sizeof(coef0_huffbits), sizeof(levels0)/2, coef0_huffcodes, coef0_huffbits, levels0,
     },
-    { 
-        sizeof(coef1_huffbits), coef1_huffcodes, coef1_huffbits, levels1,
+    {
+        sizeof(coef1_huffbits), sizeof(levels1)/2, coef1_huffcodes, coef1_huffbits, levels1,
     },
-    { 
-        sizeof(coef2_huffbits), coef2_huffcodes, coef2_huffbits, levels2,
+    {
+        sizeof(coef2_huffbits), sizeof(levels2)/2, coef2_huffcodes, coef2_huffbits, levels2,
     },
-    { 
-        sizeof(coef3_huffbits), coef3_huffcodes, coef3_huffbits, levels3,
+    {
+        sizeof(coef3_huffbits), sizeof(levels3)/2, coef3_huffcodes, coef3_huffbits, levels3,
     },
-    { 
-        sizeof(coef4_huffbits), coef4_huffcodes, coef4_huffbits, levels4,
+    {
+        sizeof(coef4_huffbits), sizeof(levels4)/2, coef4_huffcodes, coef4_huffbits, levels4,
     },
-    { 
-        sizeof(coef5_huffbits), coef5_huffcodes, coef5_huffbits, levels5,
+    {
+        sizeof(coef5_huffbits), sizeof(levels5)/2, coef5_huffcodes, coef5_huffbits, levels5,
     },
 };
--- a/src/wma/libffwma/wmadec.c	Sat Apr 14 16:09:21 2007 -0700
+++ b/src/wma/libffwma/wmadec.c	Sat Apr 14 17:38:32 2007 -0700
@@ -26,108 +26,9 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.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)
-
-/* 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 MAX_CHANNELS 2
-
-#define NOISE_TAB_SIZE 8192
-
-#define LSP_POW_BITS 7
-
-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];
+#include "wma.h"
 
-    /* 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 */
-    float exponents[MAX_CHANNELS][BLOCK_MAX_SIZE] __attribute__((aligned(16)));
-    float max_exponent[MAX_CHANNELS];
-    int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE];
-    float coefs[MAX_CHANNELS][BLOCK_MAX_SIZE] __attribute__((aligned(16)));
-    MDCTContext mdct_ctx[BLOCK_NB_SIZES];
-    float *windows[BLOCK_NB_SIZES];
-    FFTSample mdct_tmp[BLOCK_MAX_SIZE] __attribute__((aligned(16))); /* temporary storage for imdct */
-    /* output buffer for one frame and the last for IMDCT windowing */
-    float frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE * 2] __attribute__((aligned(16)));
-    /* last frame info */
-    uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */
-    int last_bitoffset;
-    int last_superframe_len;
-    float noise_table[NOISE_TAB_SIZE];
-    int noise_index;
-    float noise_mult; /* XXX: suppress that and integrate it in the noise array */
-    /* lsp_to_curve tables */
-    float lsp_cos_table[BLOCK_MAX_SIZE];
-    float lsp_pow_e_table[256];
-    float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
-    float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
-
-#ifdef TRACE
-    int frame_count;
-#endif
-} WMADecodeContext;
-
-typedef struct CoefVLCTable {
-    int n; /* total number of codes */
-    const uint32_t *huffcodes; /* VLC bit values */
-    const uint8_t *huffbits;   /* VLC bit size */
-    const uint16_t *levels; /* table to build run/level tables */
-} CoefVLCTable;
-
-static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len);
+static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len);
 
 #include "wmadata.h"
 
@@ -198,7 +99,7 @@
 
 static int wma_decode_init(AVCodecContext * avctx)
 {
-    WMADecodeContext *s = avctx->priv_data;
+    WMACodecContext *s = avctx->priv_data;
     int i, flags1, flags2;
     float *window;
     uint8_t *extradata;
@@ -486,15 +387,15 @@
             }
         }
 #endif
-        init_vlc(&s->hgain_vlc, 9, sizeof(hgain_huffbits), 
-                 hgain_huffbits, 1, 1,
-                 hgain_huffcodes, 2, 2);
+        init_vlc(&s->hgain_vlc, 9, sizeof(ff_wma_hgain_huffbits), 
+                 ff_wma_hgain_huffbits, 1, 1,
+                 ff_wma_hgain_huffcodes, 2, 2);
     }
 
     if (s->use_exp_vlc) {
-        init_vlc(&s->exp_vlc, 9, sizeof(scale_huffbits), 
-                 scale_huffbits, 1, 1,
-                 scale_huffcodes, 4, 4);
+        init_vlc(&s->exp_vlc, 9, sizeof(ff_wma_scale_huffbits), 
+                 ff_wma_scale_huffbits, 1, 1,
+                 ff_wma_scale_huffcodes, 4, 4);
     } else {
         wma_lsp_to_curve_init(s, s->frame_len);
     }
@@ -515,38 +416,11 @@
     return 0;
 }
 
-/* interpolate values for a bigger or smaller block. The block must
-   have multiple sizes */
-static void interpolate_array(float *scale, int old_size, int new_size)
-{
-    int i, j, jincr, k;
-    float v;
-
-    if (new_size > old_size) {
-        jincr = new_size / old_size;
-        j = new_size;
-        for(i = old_size - 1; i >=0; i--) {
-            v = scale[i];
-            k = jincr;
-            do {
-                scale[--j] = v;
-            } while (--k);
-        }
-    } else if (new_size < old_size) {
-        j = 0;
-        jincr = old_size / new_size;
-        for(i = 0; i < new_size; i++) {
-            scale[i] = scale[j];
-            j += jincr;
-        }
-    }
-}
-
 /* compute x^-0.25 with an exponent and mantissa table. We use linear
    interpolation to reduce the mantissa table size at a small speed
    expense (linear interpolation approximately doubles the number of
    bits of precision). */
-static inline float pow_m1_4(WMADecodeContext *s, float x)
+static inline float pow_m1_4(WMACodecContext *s, float x)
 {
     union {
         float f;
@@ -565,7 +439,7 @@
     return s->lsp_pow_e_table[e] * (a + b * t.f);
 }
 
-static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len)
+static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len)
 {  
     float wdel, a, b;
     int i, e, m;
@@ -604,7 +478,7 @@
 
 /* NOTE: We use the same code as Vorbis here */
 /* XXX: optimize it further with SSE/3Dnow */
-static void wma_lsp_to_curve(WMADecodeContext *s, 
+static void wma_lsp_to_curve(WMACodecContext *s, 
                              float *out, float *val_max_ptr, 
                              int n, float *lsp)
 {
@@ -632,7 +506,7 @@
 }
 
 /* decode exponents coded with LSP coefficients (same idea as Vorbis) */
-static void decode_exp_lsp(WMADecodeContext *s, int ch)
+static void decode_exp_lsp(WMACodecContext *s, int ch)
 {
     float lsp_coefs[NB_LSP_COEFS];
     int val, i;
@@ -642,7 +516,7 @@
             val = get_bits(&s->gb, 3);
         else
             val = get_bits(&s->gb, 4);
-        lsp_coefs[i] = lsp_codebook[i][val];
+        lsp_coefs[i] = ff_wma_lsp_codebook[i][val];
     }
 
     wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch],
@@ -650,7 +524,7 @@
 }
 
 /* decode exponents coded with VLC codes */
-static int decode_exp_vlc(WMADecodeContext *s, int ch)
+static int decode_exp_vlc(WMACodecContext *s, int ch)
 {
     int last_exp, n, code;
     const uint16_t *ptr, *band_ptr;
@@ -693,10 +567,10 @@
 
 /* return 0 if OK. return 1 if last block of frame. return -1 if
    unrecorrable error. */
-static int wma_decode_block(WMADecodeContext *s)
+static int wma_decode_block(WMACodecContext *s)
 {
     int n, v, a, ch, code, bsize;
-    int coef_nb_bits, total_gain, parse_exponents;
+    int coef_nb_bits, total_gain;
     float window[BLOCK_MAX_SIZE * 2];
 
 #ifdef HAVE_ALTIVEC
@@ -826,13 +700,9 @@
         }
     }
            
-    /* exposant can be interpolated in short blocks. */
-    parse_exponents = 1;
-    if (s->block_len_bits != s->frame_len_bits) {
-        parse_exponents = get_bits(&s->gb, 1);
-    }
-    
-    if (parse_exponents) {
+    /* exponents can be reused in short blocks. */
+    if ((s->block_len_bits == s->frame_len_bits) ||
+        get_bits(&s->gb, 1)) {
         for(ch = 0; ch < s->nb_channels; ch++) {
             if (s->channel_coded[ch]) {
                 if (s->use_exp_vlc) {
@@ -841,13 +711,7 @@
                 } else {
                     decode_exp_lsp(s, ch);
                 }
-            }
-        }
-    } else {
-        for(ch = 0; ch < s->nb_channels; ch++) {
-            if (s->channel_coded[ch]) {
-                interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits, 
-                                  s->block_len);
+                s->exponents_bsize[ch] = bsize;
             }
         }
     }
@@ -921,12 +785,13 @@
     for(ch = 0; ch < s->nb_channels; ch++) {
         if (s->channel_coded[ch]) {
             int16_t *coefs1;
-            float *coefs, *exponents, mult, mult1, noise, *exp_ptr;
-            int i, j, n, n1, last_high_band;
+            float *coefs, *exponents, mult, mult1, noise;
+            int i, j, n, n1, last_high_band, esize;
             float exp_power[HIGH_BAND_MAX_SIZE];
 
             coefs1 = s->coefs1[ch];
             exponents = s->exponents[ch];
+            esize = s->exponents_bsize[ch];
             mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];
             mult *= mdct_norm;
             coefs = s->coefs[ch];
@@ -934,16 +799,16 @@
                 mult1 = mult;
                 /* very low freqs : noise */
                 for(i = 0;i < s->coefs_start; i++) {
-                    *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * mult1;
+                    *coefs++ = s->noise_table[s->noise_index] *
+                      exponents[i<<bsize>>esize] * mult1;
                     s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);
                 }
                 
                 n1 = s->exponent_high_sizes[bsize];
 
                 /* compute power of high bands */
-                exp_ptr = exponents + 
-                    s->high_band_start[bsize] - 
-                    s->coefs_start;
+                exponents = s->exponents[ch] +
+                    (s->high_band_start[bsize]<<bsize);
                 last_high_band = 0; /* avoid warning */
                 for(j=0;j<n1;j++) {
                     n = s->exponent_high_bands[s->frame_len_bits - 
@@ -952,17 +817,18 @@
                         float e2, v;
                         e2 = 0;
                         for(i = 0;i < n; i++) {
-                            v = exp_ptr[i];
+                            v = exponents[i<<bsize>>esize];
                             e2 += v * v;
                         }
                         exp_power[j] = e2 / n;
                         last_high_band = j;
                         tprintf("%d: power=%f (%d)\n", j, exp_power[j], n);
                     }
-                    exp_ptr += n;
+                    exponents += n<<bsize;
                 }
 
                 /* main freqs and high freqs */
+                exponents = s->exponents[ch] + (s->coefs_start<<bsize);
                 for(j=-1;j<n1;j++) {
                     if (j < 0) {
                         n = s->high_band_start[bsize] - 
@@ -981,21 +847,25 @@
                         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++ = (*exponents++) * noise * mult1;
+                            *coefs++ =  noise *
+                                exponents[i<<bsize>>esize] * mult1;
                         }
+                        exponents += n<<bsize;
                     } else {
                         /* coded values + small noise */
                         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++ = ((*coefs1++) + noise) * (*exponents++) * mult;
+                            *coefs++ = ((*coefs1++) + noise) *
+                                exponents[i<<bsize>>esize] * mult;
                         }
+                        exponents += n<<bsize;
                     }
                 }
 
                 /* very high freqs : noise */
                 n = s->block_len - s->coefs_end[bsize];
-                mult1 = mult * exponents[-1];
+                mult1 = mult * exponents[((-1<<bsize))>>esize];
                 for(i = 0; i < n; i++) {
                     *coefs++ = s->noise_table[s->noise_index] * mult1;
                     s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);
@@ -1006,7 +876,7 @@
                     *coefs++ = 0.0;
                 n = nb_coefs[ch];
                 for(i = 0;i < n; i++) {
-                    *coefs++ = coefs1[i] * exponents[i] * mult;
+                    *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult;
                 }
                 n = s->block_len - s->coefs_end[bsize];
                 for(i = 0;i < n; i++)
@@ -1138,7 +1008,7 @@
 }
 
 /* decode a frame of frame_len samples */
-static int wma_decode_frame(WMADecodeContext *s, int16_t *samples)
+static int wma_decode_frame(WMACodecContext *s, int16_t *samples)
 {
     int ret, i, n, a, ch, incr;
     int16_t *ptr;
@@ -1193,7 +1063,7 @@
                                  void *data, int *data_size,
                                  uint8_t *buf, int buf_size)
 {
-    WMADecodeContext *s = avctx->priv_data;
+    WMACodecContext *s = avctx->priv_data;
     int nb_frames, bit_offset, i, pos, len;
     uint8_t *q;
     int16_t *samples;
@@ -1284,7 +1154,7 @@
 
 static int wma_decode_end(AVCodecContext *avctx)
 {
-    WMADecodeContext *s = avctx->priv_data;
+    WMACodecContext *s = avctx->priv_data;
     int i;
 
     for (i = 0; i < s->nb_block_sizes; i++)
@@ -1315,7 +1185,7 @@
     "wmav1",
     CODEC_TYPE_AUDIO,
     CODEC_ID_WMAV1,
-    sizeof(WMADecodeContext),
+    sizeof(WMACodecContext),
     wma_decode_init,
     NULL,
     wma_decode_end,
@@ -1328,7 +1198,7 @@
     "wmav2",
     CODEC_TYPE_AUDIO,
     CODEC_ID_WMAV2,
-    sizeof(WMADecodeContext),
+    sizeof(WMACodecContext),
     wma_decode_init,
     NULL,
     wma_decode_end,