diff --git a/celt/vq.c b/celt/vq.c index 737916eb0aec7602e61c892ae51da3eec1f2e7bc..c743f9d74d32b8fc018fe53368ca0addf80eebcb 100644 --- a/celt/vq.c +++ b/celt/vq.c @@ -258,7 +258,7 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc #endif if (pulsesLeft > N+3) { - opus_val16 tmp = pulsesLeft; + opus_val16 tmp = (opus_val16)pulsesLeft; yy = MAC16_16(yy, tmp, tmp); yy = MAC16_16(yy, tmp, y[0]); iy[0] += pulsesLeft; diff --git a/silk/enc_API.c b/silk/enc_API.c index 1320de469e535c5b9767567853d1c8e0140cd10d..01a7e96bd5caed735a5ea81a6529987ffd3798a5 100644 --- a/silk/enc_API.c +++ b/silk/enc_API.c @@ -214,7 +214,7 @@ opus_int silk_Encode( TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 ); for( n = 0; n < encControl->nChannelsInternal; n++ ) { - /* JMV: Force the side channel to the same rate as the mid. Is this the right way? */ + /* Force the side channel to the same rate as the mid */ opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { silk_assert( 0 ); @@ -426,9 +426,6 @@ opus_int silk_Encode( /* Handling rate constraints */ maxBits = encControl->maxBits; - /*if( encControl->useCBR ) { - maxBits = (encControl->bitRate * nBlocksOf10ms / 800) * 8; - }*/ if( tot_blocks == 2 && curr_block == 0 ) { maxBits = maxBits * 3 / 5; } else if( tot_blocks == 3 ) { diff --git a/silk/fixed/encode_frame_FIX.c b/silk/fixed/encode_frame_FIX.c index 2ce9502f81f501ec10e7f44141c0732678dfb84a..ab1b1a62d3af5e1ea6a53744950acaf33eeead2a 100644 --- a/silk/fixed/encode_frame_FIX.c +++ b/silk/fixed/encode_frame_FIX.c @@ -92,6 +92,7 @@ opus_int silk_encode_frame_FIX( ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int32 gainsID, gainsID_lower, gainsID_upper; opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; @@ -178,60 +179,68 @@ TIC(NSQ) } TOC(NSQ) } else { - /* Loop over quantizer and entroy coding to control bitrate */ + /* Loop over quantizer and entropy coding to control bitrate */ maxIter = 5; gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + gainsID_lower = -1; + gainsID_upper = -1; + /* Copy part of the input state */ + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + seed_copy = psEnc->sCmn.indices.Seed; + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; for( iter = 0; ; iter++ ) { - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ -TIC(NSQ) - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + if( gainsID == gainsID_lower ) { + nBits = nBits_lower; + } else if( gainsID == gainsID_upper ) { + nBits = nBits_upper; } else { - silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); - } + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ +TIC(NSQ) + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } else { + silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } TOC(NSQ) - /****************************************/ - /* Encode Parameters */ - /****************************************/ + /****************************************/ + /* Encode Parameters */ + /****************************************/ TIC(ENCODE_PARAMS) - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); TOC(ENCODE_PARAMS) - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ TIC(ENCODE_PULSES) - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); TOC(ENCODE_PULSES) - nBits = ec_tell( psRangeEnc ); + nBits = ec_tell( psRangeEnc ); - if( maxBits == 0 || ( useCBR == 0 && iter == 0 && nBits <= maxBits ) ) { - break; + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { + break; + } } if( iter == maxIter ) { - if( nBits > maxBits && found_lower ) { + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { /* Restore output state from earlier iteration that did meet the bitrate budget */ silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - silk_assert( sRangeEnc_copy2.offs<=1275 ); + silk_assert( sRangeEnc_copy2.offs <= 1275 ); silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); psEnc->sShape.LastGainIndex = LastGainIndex_copy2; @@ -243,6 +252,7 @@ TOC(ENCODE_PULSES) found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; + gainsID_upper = gainsID; if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff */ sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); @@ -251,12 +261,15 @@ TOC(ENCODE_PULSES) found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - silk_assert( psRangeEnc->offs<=1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + if( gainsID != gainsID_lower ) { + gainsID_lower = gainsID; + /* Copy part of the output state */ + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); + silk_assert( psRangeEnc->offs <= 1275 ); + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + } } else { /* Within 5 bits of budget: close enough */ break; @@ -266,6 +279,7 @@ TOC(ENCODE_PULSES) /* Adjust gain according to high-rate rate/distortion curve */ opus_int32 gain_factor_Q16; gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); + gain_factor_Q16 = silk_min_32(gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); if( nBits > maxBits ) { gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); } @@ -274,23 +288,26 @@ TOC(ENCODE_PULSES) /* Adjust gain by interpolating */ gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); } else - if( gainMult_Q8 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); - } + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); + } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); } + + /* Quantize gains */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - - /* Noise shaping quantization */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + /* Unique identifier of gains vector */ + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + /* Restore part of the input state */ silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); diff --git a/silk/fixed/process_gains_FIX.c b/silk/fixed/process_gains_FIX.c index c3d5664d41d0eb925ecbe9abeb98231b5026555a..f56a8f2f3fcceabadbb9ea0780862bcb0f6f76cf 100644 --- a/silk/fixed/process_gains_FIX.c +++ b/silk/fixed/process_gains_FIX.c @@ -90,7 +90,7 @@ void silk_process_gains_FIX( silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; - /* Noise shaping quantization */ + /* Quantize gains */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c index 8206459df9e054c967fb84035f727939d4442ce7..2330476a906defccb9512e95da443127b67dd781 100644 --- a/silk/float/encode_frame_FLP.c +++ b/silk/float/encode_frame_FLP.c @@ -95,6 +95,7 @@ opus_int silk_encode_frame_FLP( ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int32 gainsID, gainsID_lower, gainsID_upper; opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; @@ -185,50 +186,58 @@ TOC(NSQ) gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + gainsID_lower = -1; + gainsID_upper = -1; + /* Copy part of the input state */ + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + seed_copy = psEnc->sCmn.indices.Seed; + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; for( iter = 0; ; iter++ ) { - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ + if( gainsID == gainsID_lower ) { + nBits = nBits_lower; + } else if( gainsID == gainsID_upper ) { + nBits = nBits_upper; + } else { + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ TIC(NSQ) - silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); + silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); TOC(NSQ) - /****************************************/ - /* Encode Parameters */ - /****************************************/ + /****************************************/ + /* Encode Parameters */ + /****************************************/ TIC(ENCODE_PARAMS) - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); TOC(ENCODE_PARAMS) - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ TIC(ENCODE_PULSES) - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); TOC(ENCODE_PULSES) + + nBits = ec_tell( psRangeEnc ); - nBits = ec_tell( psRangeEnc ); - - if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { - break; + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { + break; + } } if( iter == maxIter ) { - if( nBits > maxBits && found_lower ) { + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { /* Restore output state from earlier iteration that did meet the bitrate budget */ - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - silk_assert( sRangeEnc_copy2.offs<=1275 ); - silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); - psEnc->sShape.LastGainIndex = LastGainIndex_copy2; + silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); + silk_assert( sRangeEnc_copy2.offs <= 1275 ); + silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); + psEnc->sShape.LastGainIndex = LastGainIndex_copy2; } break; } @@ -237,7 +246,8 @@ TOC(ENCODE_PULSES) found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; - if( found_lower == 0 && iter >= 3 ) { + gainsID_upper = gainsID; + if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff */ sEncCtrl.Lambda *= 1.5f; } @@ -245,12 +255,15 @@ TOC(ENCODE_PULSES) found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - silk_assert( psRangeEnc->offs<=1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + if( gainsID != gainsID_lower ) { + gainsID_lower = gainsID; + /* Copy part of the output state */ + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); + silk_assert( psRangeEnc->offs <= 1275 ); + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + } } else { /* Within 5 bits of budget: close enough */ break; @@ -269,23 +282,26 @@ TOC(ENCODE_PULSES) /* Adjust gain by interpolating */ gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); } else - if( gainMult_Q8 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); - } + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); + } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); } - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - /* Noise shaping quantization */ + /* Quantize gains */ + psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + /* Unique identifier of gains vector */ + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; diff --git a/silk/float/process_gains_FLP.c b/silk/float/process_gains_FLP.c index 0708a5c2a752521d098f52645e0bec2be8ed4c3e..f9b57f462cf1287c7b63bd6588287397519b8eb4 100644 --- a/silk/float/process_gains_FLP.c +++ b/silk/float/process_gains_FLP.c @@ -71,7 +71,7 @@ void silk_process_gains_FLP( silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; - /* Noise shaping quantization */ + /* Quantize gains */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); diff --git a/silk/gain_quant.c b/silk/gain_quant.c index 9b52a32e164f6e415c225d8228d923125d51fc86..189f5fdd4a6ffe4b6c749a874ff5a977d67d3066 100644 --- a/silk/gain_quant.c +++ b/silk/gain_quant.c @@ -121,3 +121,20 @@ void silk_gains_dequant( gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ } } + +/* Compute unique identifier of gain indices vector */ +opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int k; + opus_int32 gainsID; + + gainsID = 0; + for( k = 0; k < nb_subfr; k++ ) { + gainsID = silk_ADD_LSHIFT32( ind[ k ], gainsID, 8 ); + } + + return gainsID; +} diff --git a/silk/main.h b/silk/main.h index f5238136c61c1e5b1a01b3f8003e1bc32c4747ca..29c4521756bdec84eb8bc54f89b93ea6aabcfe20 100644 --- a/silk/main.h +++ b/silk/main.h @@ -192,6 +192,12 @@ void silk_gains_dequant( const opus_int nb_subfr /* I number of subframes */ ); +/* Compute unique identifier of gain indices vector */ +opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + const opus_int nb_subfr /* I number of subframes */ +); + /* Interpolate two vectors */ void silk_interpolate( opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 4944ace4253dfdb15a967dde47fd835dcdd82cca..46f3faa7e61a80c6fc041c1d38085a7d0925ee09 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -499,7 +499,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->bitrate_bps = cbrBytes * (8*frame_rate); max_data_bytes = cbrBytes; } - max_rate = frame_rate*max_data_bytes; + max_rate = frame_rate*max_data_bytes*8; /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */ equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);