summaryrefslogtreecommitdiff
path: root/silk
diff options
context:
space:
mode:
authorTimothy B. Terriberry <tterribe@xiph.org>2011-09-17 12:44:19 -0700
committerJean-Marc Valin <jmvalin@jmvalin.ca>2011-09-27 20:28:31 -0400
commit748c960cf7ab61a92adc323fe5bbae03af9949f4 (patch)
treef35748461ac7a2906a76e3195c9af129960c989d /silk
parent9826ed99c36504ad466feeadacf5e2ced1518c4a (diff)
downloadopus-748c960cf7ab61a92adc323fe5bbae03af9949f4.tar.gz
Add support for coding signs with 0 pulses.
The SILK bitstream allowed coding 0 pulses in a shell block, but a non-zero number of LSb's, meaning some excitation coefficients could be non-zero, but would not have a corresponding sign. To fix this without breaking already-encoded bitstreams, this patch adds a set of sign PDFs for the 0 pulses case. This is occasionally more efficient than the normal encoding if there are a large number of coefficients with positive signs, since these cost more than 1 bit when using the > 0 pulse PDFs. It only saves 0.33 bits per second (on average: it does better at high rates), but that's probably enough to justify the two redundant ways of coding things (and it's too late now to remove the second one entirely, anyway). This patch does not include the encoder modifications required to check if this coding method is more efficient and switch to it.
Diffstat (limited to 'silk')
-rw-r--r--silk/code_signs.c8
-rw-r--r--silk/decode_pulses.c2
-rw-r--r--silk/tables.h2
-rw-r--r--silk/tables_pulses_per_block.c13
4 files changed, 14 insertions, 11 deletions
diff --git a/silk/code_signs.c b/silk/code_signs.c
index 65187e61..02a3aeb3 100644
--- a/silk/code_signs.c
+++ b/silk/code_signs.c
@@ -54,13 +54,13 @@ void silk_encode_signs(
icdf[ 1 ] = 0;
q_ptr = pulses;
- i = silk_SMULBB( 6, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
+ i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
icdf_ptr = &silk_sign_iCDF[ i ];
length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
for( i = 0; i < length; i++ ) {
p = sum_pulses[ i ];
if( p > 0 ) {
- icdf[ 0 ] = icdf_ptr[ silk_min( p - 1, 5 ) ];
+ icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
if( q_ptr[ j ] != 0 ) {
ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 );
@@ -88,13 +88,13 @@ void silk_decode_signs(
icdf[ 1 ] = 0;
q_ptr = pulses;
- i = silk_SMULBB( 6, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
+ i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
icdf_ptr = &silk_sign_iCDF[ i ];
length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
for( i = 0; i < length; i++ ) {
p = sum_pulses[ i ];
if( p > 0 ) {
- icdf[ 0 ] = icdf_ptr[ silk_min( p - 1, 5 ) ];
+ icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
if( q_ptr[ j ] > 0 ) {
/* attach sign */
diff --git a/silk/decode_pulses.c b/silk/decode_pulses.c
index 8b3fae70..692ab925 100644
--- a/silk/decode_pulses.c
+++ b/silk/decode_pulses.c
@@ -103,6 +103,8 @@ void silk_decode_pulses(
}
pulses_ptr[ k ] = abs_q;
}
+ /* Mark the number of pulses non-zero for sign decoding. */
+ sum_pulses[ i ] |= nLS << 5;
}
}
diff --git a/silk/tables.h b/silk/tables.h
index de1fd028..1b8b68fd 100644
--- a/silk/tables.h
+++ b/silk/tables.h
@@ -63,7 +63,7 @@ extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ];
extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */
-extern const opus_uint8 silk_sign_iCDF[ 36 ]; /* 36 */
+extern const opus_uint8 silk_sign_iCDF[ 42 ]; /* 42 */
extern const opus_uint8 silk_uniform3_iCDF[ 3 ]; /* 3 */
extern const opus_uint8 silk_uniform4_iCDF[ 4 ]; /* 4 */
diff --git a/silk/tables_pulses_per_block.c b/silk/tables_pulses_per_block.c
index 51c9e554..9859e326 100644
--- a/silk/tables_pulses_per_block.c
+++ b/silk/tables_pulses_per_block.c
@@ -254,10 +254,11 @@ const opus_uint8 silk_shell_code_table_offsets[ 17 ] = {
135
};
-const opus_uint8 silk_sign_iCDF[ 36 ] = {
- 49, 67, 77, 82, 93, 99, 11, 18,
- 24, 31, 36, 45, 46, 66, 78, 87,
- 94, 104, 14, 21, 32, 42, 51, 66,
- 94, 104, 109, 112, 115, 118, 53, 69,
- 80, 88, 95, 102
+const opus_uint8 silk_sign_iCDF[ 42 ] = {
+ 254, 49, 67, 77, 82, 93, 99,
+ 198, 11, 18, 24, 31, 36, 45,
+ 255, 46, 66, 78, 87, 94, 104,
+ 208, 14, 21, 32, 42, 51, 66,
+ 255, 94, 104, 109, 112, 115, 118,
+ 248, 53, 69, 80, 88, 95, 102
};