Skip to content
Snippets Groups Projects
Commit 748c960c authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Jean-Marc Valin
Browse files

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.
parent 9826ed99
No related branches found
No related tags found
Loading
......@@ -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 */
......
......@@ -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;
}
}
......
......@@ -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 */
......
......@@ -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
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment