summaryrefslogtreecommitdiff
path: root/apps/codecs/libwma/wmadeci.c
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2007-08-02 04:47:33 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2007-08-02 04:47:33 +0000
commit206e883e78fe6bb5d65b150b757d7a9af76f472e (patch)
tree424b5c80c9ebe6f587dbd3bb93fcdb59b6374140 /apps/codecs/libwma/wmadeci.c
parent66029a58aeac41340f57d6b6c4f5c79eae04cc4a (diff)
downloadrockbox-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.c99
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)
935static inline fixed32 pow_m1_4(WMADecodeContext *s, fixed32 x) 936static 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
954static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) 960static 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)