/* Decodes signs of excitation */ void SKP_Silk_decode_signs(SKP_Silk_range_coder_state * sRC, /* I/O Range coder state */ int q[], /* I/O pulse signal */ const int length, /* I length of output */ const int sigtype, /* I Signal type */ const int QuantOffsetType, /* I Quantization offset type */ const int RateLevelIndex /* I Rate Level Index */ ) { int i; int data; const uint16_t *cdf; i = SKP_SMULBB(N_RATE_LEVELS - 1, SKP_LSHIFT(sigtype, 1) + QuantOffsetType) + RateLevelIndex; cdf = SKP_Silk_sign_CDF[i]; for (i = 0; i < length; i++) { if (q[i] > 0) { SKP_Silk_range_decoder(&data, sRC, cdf, 1); /* attach sign */ /* implementation with shift, subtraction, multiplication */ q[i] *= SKP_dec_map(data); } } }
/* Range decoder for multiple symbols */ void SKP_Silk_range_decoder_multi( SKP_int data[], /* O uncompressed data [nSymbols] */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_uint16 * const prob[], /* I cumulative density functions */ const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */ const SKP_int nSymbols /* I number of data symbols */ ) { SKP_int k; for( k = 0; k < nSymbols; k++ ) { SKP_Silk_range_decoder( &data[ k ], psRC, prob[ k ], probStartIx[ k ] ); } }
static inline void decode_split(int *p_child1, /* O: pulse amplitude of first child subframe */ int *p_child2, /* O: pulse amplitude of second child subframe */ SKP_Silk_range_coder_state * sRC, /* I/O: compressor data structure */ const int p, /* I: pulse amplitude of current subframe */ const uint16_t * shell_table /* I: table of shell cdfs */ ) { int cdf_middle; const uint16_t *cdf; if (p > 0) { cdf_middle = SKP_RSHIFT(p, 1); cdf = &shell_table[SKP_Silk_shell_code_table_offsets[p]]; SKP_Silk_range_decoder(p_child1, sRC, cdf, cdf_middle); p_child2[0] = p - p_child1[0]; } else { p_child1[0] = 0; p_child2[0] = 0; } }
void SKP_Silk_decode_pulses( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int q[], /* O Excitation signal */ const SKP_int frame_length /* I Frame length (preliminary) */ ) { SKP_int i, j, k, iter, abs_q, nLS, bit; SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ]; SKP_int *pulses_ptr; const SKP_uint16 *cdf_ptr; /*********************/ /* Decode rate level */ /*********************/ SKP_Silk_range_decoder( &psDecCtrl->RateLevelIndex, psRC, SKP_Silk_rate_levels_CDF[ psDecCtrl->sigtype ], SKP_Silk_rate_levels_CDF_offset ); /* Calculate number of shell blocks */ iter = frame_length / SHELL_CODEC_FRAME_LENGTH; /***************************************************/ /* Sum-Weighted-Pulses Decoding */ /***************************************************/ cdf_ptr = SKP_Silk_pulses_per_block_CDF[ psDecCtrl->RateLevelIndex ]; for( i = 0; i < iter; i++ ) { nLshifts[ i ] = 0; SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, cdf_ptr, SKP_Silk_pulses_per_block_CDF_offset ); /* LSB indication */ while( sum_pulses[ i ] == ( MAX_PULSES + 1 ) ) { nLshifts[ i ]++; SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ], SKP_Silk_pulses_per_block_CDF_offset ); } } /***************************************************/ /* Shell decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( sum_pulses[ i ] > 0 ) { SKP_Silk_shell_decoder( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRC, sum_pulses[ i ] ); } else { SKP_memset( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( SKP_int ) ); } } /***************************************************/ /* LSB Decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( nLshifts[ i ] > 0 ) { nLS = nLshifts[ i ]; pulses_ptr = &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ]; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_q = pulses_ptr[ k ]; for( j = 0; j < nLS; j++ ) { abs_q = SKP_LSHIFT( abs_q, 1 ); SKP_Silk_range_decoder( &bit, psRC, SKP_Silk_lsb_CDF, 1 ); abs_q += bit; } pulses_ptr[ k ] = abs_q; } } } /****************************************/ /* Decode and add signs to pulse signal */ /****************************************/ SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl->sigtype, psDecCtrl->QuantOffsetType, psDecCtrl->RateLevelIndex); }