diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2012-04-30 23:28:57 -0400 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2012-05-01 05:42:38 +0200 |
commit | 87d3dde15a1f0af6eaac21107d74aa240515fd0c (patch) | |
tree | f0148dd45df72e22b610b9069d5d1563adc715b7 | |
parent | f5d9a45e3ffb1326dced431025cc10814ea4b7d8 (diff) |
Fix corrupt when repeatidly playing very low bitrate WMA files.
The LSP feature in WMA requires that the noise table values be
doubled verses when it is not used. Unfortunately, the previous
code would double the same values every time a LSP file was
decoded without first resetting them to their original values.
Change the code to check if the values are already doubled, and
then double/halve them as needed. This is still a bit ugly,
in the future consider using the built in rockbox dither instead
of a lookup table.
Fixes playback when skipping back and forth between low and high
bitrate WMA.
Change-Id: I4c393092e4a789bc8f98d74274fe207400b9550e
Reviewed-on: http://gerrit.rockbox.org/226
Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
Tested-by: Michael Giacomelli <giac2000@hotmail.com>
-rwxr-xr-x[-rw-r--r--] | lib/rbcodec/codecs/libwma/wmadata.h | 3 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/rbcodec/codecs/libwma/wmadeci.c | 20 |
2 files changed, 17 insertions, 6 deletions
diff --git a/lib/rbcodec/codecs/libwma/wmadata.h b/lib/rbcodec/codecs/libwma/wmadata.h index 07a55df19a..7f97a75676 100644..100755 --- a/lib/rbcodec/codecs/libwma/wmadata.h +++ b/lib/rbcodec/codecs/libwma/wmadata.h @@ -1578,7 +1578,8 @@ const fixed64 lsp_pow_e_table[] ICONST_ATTR_WMA_XL_IRAM = 0x0LL }; -/* table of exp noise values multiplied by 16 in order to reduce rounding error */ +/* table of exp noise values multiplied by 16 in order to reduce rounding error, + * note that that first value (0x5) is used as a magic number in the init code*/ fixed32 noisetable_exp[] = { 0x5, 0xfffffa2e, 0xc2c, 0xb47, 0xffffaebe, 0xfffffa63, 0xfffff7ff, 0x16bd, diff --git a/lib/rbcodec/codecs/libwma/wmadeci.c b/lib/rbcodec/codecs/libwma/wmadeci.c index d7a836dd97..69bdbeaca2 100644..100755 --- a/lib/rbcodec/codecs/libwma/wmadeci.c +++ b/lib/rbcodec/codecs/libwma/wmadeci.c @@ -487,23 +487,33 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) s->reset_block_lengths = 1; - if (s->use_noise_coding) + if (s->use_noise_coding) /* init the noise generator */ { - /* init the noise generator */ + /* LSP values are simply 2x the EXP values */ if (s->use_exp_vlc) { s->noise_mult = 0x51f; + /*unlikely, but we may have previoiusly used this table for LSP, + so halve the values if needed*/ + if(noisetable_exp[0] == 0x10) { + for (i=0;i<NOISE_TAB_SIZE;++i) + noisetable_exp[i] >>= 1; + } s->noise_table = noisetable_exp; } else { s->noise_mult = 0xa3d; - /* LSP values are simply 2x the EXP values */ - for (i=0;i<NOISE_TAB_SIZE;++i) - noisetable_exp[i] = noisetable_exp[i]<< 1; + /*check that we haven't already doubled this table*/ + if(noisetable_exp[0] == 0x5) { + for (i=0;i<NOISE_TAB_SIZE;++i) + noisetable_exp[i] <<= 1; + } s->noise_table = noisetable_exp; } #if 0 +/*TODO: Rockbox has a dither function. Consider using it for noise coding*/ + /* We use a lookup table computered in advance, so no need to do this*/ { unsigned int seed; |