diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2007-08-02 04:47:33 +0000 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2007-08-02 04:47:33 +0000 |
commit | 206e883e78fe6bb5d65b150b757d7a9af76f472e (patch) | |
tree | 424b5c80c9ebe6f587dbd3bb93fcdb59b6374140 /apps/codecs/libwma/wmadeci.c | |
parent | 66029a58aeac41340f57d6b6c4f5c79eae04cc4a (diff) | |
download | rockbox-206e883e78fe6bb5d65b150b757d7a9af76f472e.tar.gz rockbox-206e883e78fe6bb5d65b150b757d7a9af76f472e.zip |
Initial attept at supporting Line Spectral Pairs. Various issues remain, and the ffmpeg decoder itself often fails on certain valid LSP files. Expect some issues.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14134 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwma/wmadeci.c')
-rw-r--r-- | apps/codecs/libwma/wmadeci.c | 99 |
1 files changed, 61 insertions, 38 deletions
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c index ecde2fd034..552f85183c 100644 --- a/apps/codecs/libwma/wmadeci.c +++ b/apps/codecs/libwma/wmadeci.c | |||
@@ -286,10 +286,9 @@ int ff_mdct_init(MDCTContext *s, int nbits, int inverse) | |||
286 | s->tsin[i] = - fsincos(ip<<16, &(s->tcos[i])); //I can't remember why this works, but it seems to agree for ~24 bits, maybe more! | 286 | s->tsin[i] = - fsincos(ip<<16, &(s->tcos[i])); //I can't remember why this works, but it seems to agree for ~24 bits, maybe more! |
287 | s->tcos[i] *=-1; | 287 | s->tcos[i] *=-1; |
288 | } | 288 | } |
289 | s->fft.nbits = s->nbits - 2; | 289 | (&s->fft)->nbits = nbits-2; |
290 | 290 | ||
291 | 291 | (&s->fft)->inverse = inverse; | |
292 | s->fft.inverse = inverse; | ||
293 | 292 | ||
294 | return 0; | 293 | return 0; |
295 | 294 | ||
@@ -733,8 +732,10 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) | |||
733 | s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; | 732 | s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; |
734 | /* high freq computation */ | 733 | /* high freq computation */ |
735 | 734 | ||
736 | fixed32 tmp = high_freq*2; | 735 | fixed32 tmp1 = high_freq*2; /* high_freq is a fixed32!*/ |
737 | s->high_band_start[k] = fixtoi32(fixdiv32(tmp, itofix32(s->sample_rate)) *block_len +0x8000); | 736 | fixed32 tmp2=itofix32(s->sample_rate>>1); |
737 | s->high_band_start[k] = fixtoi32( fixdiv32(tmp1, tmp2) * (block_len>>1) +0x8000); | ||
738 | |||
738 | /* | 739 | /* |
739 | s->high_band_start[k] = (int)((block_len * 2 * high_freq) / | 740 | s->high_band_start[k] = (int)((block_len * 2 * high_freq) / |
740 | s->sample_rate + 0.5);*/ | 741 | s->sample_rate + 0.5);*/ |
@@ -935,48 +936,57 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) | |||
935 | static inline fixed32 pow_m1_4(WMADecodeContext *s, fixed32 x) | 936 | static inline fixed32 pow_m1_4(WMADecodeContext *s, fixed32 x) |
936 | { | 937 | { |
937 | union { | 938 | union { |
938 | fixed64 f; | 939 | float f; |
939 | unsigned int v; | 940 | unsigned int v; |
940 | } u, t; | 941 | } u, t; |
941 | unsigned int e, m; | 942 | unsigned int e, m; |
942 | fixed64 a, b; | 943 | fixed32 a, b; |
943 | 944 | ||
944 | u.f = x; | 945 | u.f = fixtof64(x); |
945 | e = u.v >> 23; | 946 | e = u.v >> 23; |
946 | m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); | 947 | m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); |
947 | /* build interpolation scale: 1 <= t < 2. */ | 948 | /* build interpolation scale: 1 <= t < 2. */ |
948 | t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); | 949 | t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); |
949 | a = s->lsp_pow_m_table1[m]; | 950 | a = s->lsp_pow_m_table1[m]; |
950 | b = s->lsp_pow_m_table2[m]; | 951 | b = s->lsp_pow_m_table2[m]; |
951 | return lsp_pow_e_table[e] * (a + b * t.f); | 952 | |
953 | /*lsp_pow_e_table contains 32.32 format */ | ||
954 | /*TODO: Since we're unlikely have value that cover the whole | ||
955 | * IEEE754 range, we probably don't need to have all possible exponents*/ | ||
956 | |||
957 | return (lsp_pow_e_table[e] * (a + fixmul32(b, ftofix32(t.f))) >>32); | ||
952 | } | 958 | } |
953 | 959 | ||
954 | static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) | 960 | static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) |
955 | { | 961 | { |
956 | fixed32 wdel, a, b; | 962 | fixed32 wdel, a, b, temp, temp2; |
957 | int i, m; | 963 | int i, m; |
958 | 964 | ||
959 | wdel = fixdiv32(M_PI_F, itofix32(frame_len)); | 965 | wdel = fixdiv32(M_PI_F, itofix32(frame_len)); |
966 | temp = fixdiv32(itofix32(1), itofix32(frame_len)); | ||
960 | for (i=0; i<frame_len; ++i) | 967 | for (i=0; i<frame_len; ++i) |
961 | { | 968 | { |
962 | s->lsp_cos_table[i] = 0x20000 * fixcos32(wdel * i); //wdel*i between 0 and pi | 969 | /*TODO: can probably reuse the trig_init values here */ |
970 | fsincos((temp*i)<<15, &temp2); | ||
971 | /*get 3 bits headroom + 1 bit from not doubleing the values*/ | ||
972 | s->lsp_cos_table[i] = temp2>>3; | ||
963 | 973 | ||
964 | } | 974 | } |
965 | |||
966 | |||
967 | /* NOTE: these two tables are needed to avoid two operations in | 975 | /* NOTE: these two tables are needed to avoid two operations in |
968 | pow_m1_4 */ | 976 | pow_m1_4 */ |
969 | b = itofix32(1); | 977 | b = itofix32(1); |
970 | int ix = 0; | 978 | int ix = 0; |
979 | |||
980 | /*double check this later*/ | ||
971 | for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) | 981 | for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) |
972 | { | 982 | { |
973 | m = (1 << LSP_POW_BITS) + i; | 983 | m = (1 << LSP_POW_BITS) + i; |
974 | a = m * (0x8000 / (1 << LSP_POW_BITS)); //PJJ | 984 | a = pow_a_table[ix++]<<4; |
975 | a = pow_a_table[ix++]; // PJJ : further refinement | ||
976 | s->lsp_pow_m_table1[i] = 2 * a - b; | 985 | s->lsp_pow_m_table1[i] = 2 * a - b; |
977 | s->lsp_pow_m_table2[i] = b - a; | 986 | s->lsp_pow_m_table2[i] = b - a; |
978 | b = a; | 987 | b = a; |
979 | } | 988 | } |
989 | |||
980 | } | 990 | } |
981 | 991 | ||
982 | /* NOTE: We use the same code as Vorbis here */ | 992 | /* NOTE: We use the same code as Vorbis here */ |
@@ -988,27 +998,42 @@ static void wma_lsp_to_curve(WMADecodeContext *s, | |||
988 | fixed32 *lsp) | 998 | fixed32 *lsp) |
989 | { | 999 | { |
990 | int i, j; | 1000 | int i, j; |
991 | fixed32 p, q, w, v, val_max; | 1001 | fixed32 p, q, w, v, val_max, temp, temp2; |
992 | 1002 | ||
993 | val_max = 0; | 1003 | val_max = 0; |
994 | for(i=0;i<n;++i) | 1004 | for(i=0;i<n;++i) |
995 | { | 1005 | { |
996 | p = 0x8000; | 1006 | /* shift by 2 now to reduce rounding error, |
997 | q = 0x8000; | 1007 | * we can renormalize right before pow_m1_4 |
1008 | */ | ||
1009 | |||
1010 | p = 0x8000<<5; | ||
1011 | q = 0x8000<<5; | ||
998 | w = s->lsp_cos_table[i]; | 1012 | w = s->lsp_cos_table[i]; |
1013 | |||
999 | for (j=1;j<NB_LSP_COEFS;j+=2) | 1014 | for (j=1;j<NB_LSP_COEFS;j+=2) |
1000 | { | 1015 | { |
1001 | q *= w - lsp[j - 1]; | 1016 | |
1002 | p *= w - lsp[j]; | 1017 | /*w is 5.27 format, lsp is in 16.16, temp2 becomes 5.27 format*/ |
1018 | temp2 = ((w - (lsp[j - 1]<<11))); | ||
1019 | temp = q; | ||
1020 | /*q is 16.16 format, temp2 is 5.27, q becomes 16.16 */ | ||
1021 | q = fixmul32b(q, temp2 )<<4; | ||
1022 | p = fixmul32b(p, (w - (lsp[j]<<11)))<<4; | ||
1003 | } | 1023 | } |
1004 | p *= p * (0x20000 - w); | 1024 | |
1005 | q *= q * (0x20000 + w); | 1025 | /* 2 in 5.27 format is 0x10000000 */ |
1006 | v = p + q; | 1026 | p = fixmul32(p, fixmul32b(p, (0x10000000 - w)))<<3; |
1007 | v = pow_m1_4(s, v); // PJJ | 1027 | q = fixmul32(q, fixmul32b(q, (0x10000000 + w)))<<3; |
1028 | |||
1029 | v = (p + q) >>9; /* p/q end up as 16.16 */ | ||
1030 | v = pow_m1_4(s, v); | ||
1008 | if (v > val_max) | 1031 | if (v > val_max) |
1009 | val_max = v; | 1032 | val_max = v; |
1010 | out[i] = v; | 1033 | out[i] = v; |
1034 | |||
1011 | } | 1035 | } |
1036 | |||
1012 | *val_max_ptr = val_max; | 1037 | *val_max_ptr = val_max; |
1013 | } | 1038 | } |
1014 | 1039 | ||
@@ -1392,13 +1417,11 @@ static int wma_decode_block(WMADecodeContext *s) | |||
1392 | coefs1 = s->coefs1[ch]; | 1417 | coefs1 = s->coefs1[ch]; |
1393 | exponents = s->exponents[ch]; | 1418 | exponents = s->exponents[ch]; |
1394 | esize = s->exponents_bsize[ch]; | 1419 | esize = s->exponents_bsize[ch]; |
1395 | mult = fixdiv64(pow_table[total_gain],Fixed32To64(s->max_exponent[ch])); | 1420 | mult = fixdiv64(pow_table[total_gain+20],Fixed32To64(s->max_exponent[ch])); |
1396 | // mul = fixtof64(pow_table[total_gain])/(s->block_len/2)/fixtof64(s->max_exponent[ch]); | ||
1397 | |||
1398 | mult = fixmul64byfixed(mult, mdct_norm); //what the hell? This is actually fixed64*2^16! | 1421 | mult = fixmul64byfixed(mult, mdct_norm); //what the hell? This is actually fixed64*2^16! |
1399 | coefs = (*(s->coefs))[ch]; //VLC exponenents are used to get MDCT coef here! | 1422 | coefs = (*(s->coefs))[ch]; |
1400 | 1423 | ||
1401 | n=0; | 1424 | n=0; |
1402 | 1425 | ||
1403 | if (s->use_noise_coding) | 1426 | if (s->use_noise_coding) |
1404 | { | 1427 | { |
@@ -1428,8 +1451,9 @@ static int wma_decode_block(WMADecodeContext *s) | |||
1428 | e2 = 0; | 1451 | e2 = 0; |
1429 | for(i = 0;i < n; ++i) | 1452 | for(i = 0;i < n; ++i) |
1430 | { | 1453 | { |
1431 | v = exp_ptr[i]>>5; /*v is noramlized later on so its fixed format is irrelevant*/ | 1454 | /*v is noramlized later on so its fixed format is irrelevant*/ |
1432 | e2 += fixmul32(v, v); | 1455 | v = exp_ptr[i]>>4; |
1456 | e2 += fixmul32(v, v)>>3; | ||
1433 | } | 1457 | } |
1434 | exp_power[j] = e2/n; /*n is an int...*/ | 1458 | exp_power[j] = e2/n; /*n is an int...*/ |
1435 | last_high_band = j; | 1459 | last_high_band = j; |
@@ -1456,7 +1480,8 @@ static int wma_decode_block(WMADecodeContext *s) | |||
1456 | fixed32 tmp = fixdiv32(exp_power[j],exp_power[last_high_band]); | 1480 | fixed32 tmp = fixdiv32(exp_power[j],exp_power[last_high_band]); |
1457 | mult1 = (fixed64)fixsqrt32(tmp); | 1481 | mult1 = (fixed64)fixsqrt32(tmp); |
1458 | /* XXX: use a table */ | 1482 | /* XXX: use a table */ |
1459 | mult1 = mult1 * pow_table[s->high_band_values[ch][j]] >> PRECISION; | 1483 | /*mult1 is 48.16, pow_table is 48.16*/ |
1484 | mult1 = mult1 * pow_table[s->high_band_values[ch][j]+20] >> PRECISION; | ||
1460 | 1485 | ||
1461 | /*this step has a fairly high degree of error for some reason*/ | 1486 | /*this step has a fairly high degree of error for some reason*/ |
1462 | mult1 = fixdiv64(mult1,fixmul32(s->max_exponent[ch],s->noise_mult)); | 1487 | mult1 = fixdiv64(mult1,fixmul32(s->max_exponent[ch],s->noise_mult)); |
@@ -1481,9 +1506,9 @@ static int wma_decode_block(WMADecodeContext *s) | |||
1481 | 1506 | ||
1482 | /*don't forget to renormalize the noise*/ | 1507 | /*don't forget to renormalize the noise*/ |
1483 | temp1 = (((int32_t)*coefs1++)<<16) + (noise>>4); | 1508 | temp1 = (((int32_t)*coefs1++)<<16) + (noise>>4); |
1484 | temp2 = fixmul32(*exponents, mult>>16); | 1509 | temp2 = fixmul32(*exponents, mult>>17); |
1485 | *coefs++ = fixmul32(temp1, temp2)>>1; | 1510 | *coefs++ = fixmul32(temp1, temp2); |
1486 | ++exponents; | 1511 | ++exponents; |
1487 | } | 1512 | } |
1488 | } | 1513 | } |
1489 | } | 1514 | } |
@@ -1637,10 +1662,8 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples) | |||
1637 | 1662 | ||
1638 | for (i=0;i<n;++i) | 1663 | for (i=0;i<n;++i) |
1639 | { | 1664 | { |
1640 | a = fixtoi32(*iptr++)<<1; //ugly but good enough for now | ||
1641 | |||
1642 | |||
1643 | 1665 | ||
1666 | a = fixtoi32(*iptr++)<<1; //ugly but good enough for now | ||
1644 | 1667 | ||
1645 | 1668 | ||
1646 | if (a > 32767) | 1669 | if (a > 32767) |