diff options
author | Timothy B. Terriberry <tterribe@xiph.org> | 2011-10-12 14:24:19 -0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-12 14:24:19 -0400 |
commit | e2a6aaa73158d4e9415a7e053f84f83314e2d9e3 (patch) | |
tree | d96a5db529b20fb87691d3acb65260fb5fb7ce46 /silk/NLSF2A.c | |
parent | d5158a42d1010e3a2c4431dbada17314496b6ce3 (diff) | |
download | opus-e2a6aaa73158d4e9415a7e053f84f83314e2d9e3.tar.gz |
Improves accuracy of NLSF2A by reordering the polynomial roots
Diffstat (limited to 'silk/NLSF2A.c')
-rw-r--r-- | silk/NLSF2A.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/silk/NLSF2A.c b/silk/NLSF2A.c index d0a8667b..d43b61de 100644 --- a/silk/NLSF2A.c +++ b/silk/NLSF2A.c @@ -69,6 +69,15 @@ void silk_NLSF2A( const opus_int d /* I filter order (should be even) */ ) { + /* This ordering was found to maximize quality. It improves numerical accuracy of + silk_NLSF2A_find_poly() compared to "standard" ordering. */ + static const unsigned char ordering16[16] = { + 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 + }; + static const unsigned char ordering10[10] = { + 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 + }; + const unsigned char *ordering; opus_int k, i, dd; opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; @@ -80,6 +89,7 @@ void silk_NLSF2A( silk_assert( d==10||d==16 ); /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ + ordering = d == 16 ? ordering16 : ordering10; for( k = 0; k < d; k++ ) { silk_assert(NLSF[k] >= 0 ); silk_assert(NLSF[k] <= 32767 ); @@ -98,7 +108,7 @@ void silk_NLSF2A( delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ /* Linear interpolation */ - cos_LSF_QA[k] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */ + cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */ } dd = silk_RSHIFT( d, 1 ); |