int silk_encode_frame_FIX(silk_encoder_state_FIX * psEnc,	/* I/O  Pointer to Silk FIX encoder state                                           */
			       int32_t * pnBytesOut,	/* O    Pointer to number of payload bytes;                                         */
			       ec_enc * psRangeEnc,	/* I/O  compressor data structure                                                   */
			       int condCoding,	/* I    The type of conditional coding to use                                       */
			       int maxBits,	/* I    If > 0: maximum number of output bits                                       */
			       int useCBR	/* I    Flag to force constant-bitrate operation                                    */
    ) {
	silk_encoder_control_FIX sEncCtrl;
	int i, iter, maxIter, found_upper, found_lower, ret = 0;
	int16_t *x_frame;
	ec_enc sRangeEnc_copy, sRangeEnc_copy2;
	silk_nsq_state sNSQ_copy, sNSQ_copy2;
	int32_t seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower,
	    gainMult_upper;
	int32_t gainsID, gainsID_lower, gainsID_upper;
	int16_t gainMult_Q8;
	int16_t ec_prevLagIndex_copy;
	int ec_prevSignalType_copy;
	int8_t LastGainIndex_copy2;

	/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
	LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower =
	    gainMult_upper = 0;

	psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;

    /**************************************************************/
	/* Set up Input Pointers, and insert frame in input buffer   */
    /*************************************************************/
	/* start of frame to encode */
	x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;

    /***************************************/
	/* Ensure smooth bandwidth transitions */
    /***************************************/
	silk_LP_variable_cutoff(&psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1,
				psEnc->sCmn.frame_length);

    /*******************************************/
	/* Copy new frame to front of input buffer */
    /*******************************************/
	memcpy(x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz,
		    psEnc->sCmn.inputBuf + 1,
		    psEnc->sCmn.frame_length * sizeof(int16_t));

	if (!psEnc->sCmn.prefillFlag) {

		int16_t *res_pitch_frame;

		int16_t res_pitch[psEnc->sCmn.la_pitch +
				     psEnc->sCmn.frame_length +
				     psEnc->sCmn.ltp_mem_length];
		/* start of pitch LPC residual frame */
		res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;

	/*****************************************/
		/* Find pitch lags, initial LPC analysis */
	/*****************************************/
		silk_find_pitch_lags_FIX(psEnc, &sEncCtrl, res_pitch, x_frame,
					 psEnc->sCmn.arch);

	/************************/
		/* Noise shape analysis */
	/************************/
		silk_noise_shape_analysis_FIX(psEnc, &sEncCtrl, res_pitch_frame,
					      x_frame, psEnc->sCmn.arch);

	/***************************************************/
		/* Find linear prediction coefficients (LPC + LTP) */
	/***************************************************/
		silk_find_pred_coefs_FIX(psEnc, &sEncCtrl, res_pitch, x_frame,
					 condCoding);

	/****************************************/
		/* Process gains                        */
	/****************************************/
		silk_process_gains_FIX(psEnc, &sEncCtrl, condCoding);

	/*****************************************/
		/* Prefiltering for noise shaper         */
	/*****************************************/
		int32_t xfw_Q3[psEnc->sCmn.frame_length];
		silk_prefilter_FIX(psEnc, &sEncCtrl, xfw_Q3, x_frame);

	/****************************************/
		/* Low Bitrate Redundant Encoding       */
	/****************************************/
		silk_LBRR_encode_FIX(psEnc, &sEncCtrl, xfw_Q3, condCoding);

		/* Loop over quantizer and entropy coding to control bitrate */
		maxIter = 6;
		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 */
		memcpy(&sRangeEnc_copy, psRangeEnc, sizeof(ec_enc));
		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;
		uint8_t ec_buf_copy[1275];
		for (iter = 0;; iter++) {
			if (gainsID == gainsID_lower) {
				nBits = nBits_lower;
			} else if (gainsID == gainsID_upper) {
				nBits = nBits_upper;
			} else {
				/* Restore part of the input state */
				if (iter > 0) {
					memcpy(psRangeEnc, &sRangeEnc_copy,
						    sizeof(ec_enc));
					memcpy(&psEnc->sCmn.sNSQ,
						    &sNSQ_copy,
						    sizeof(silk_nsq_state));
					psEnc->sCmn.indices.Seed = seed_copy;
					psEnc->sCmn.ec_prevLagIndex =
					    ec_prevLagIndex_copy;
					psEnc->sCmn.ec_prevSignalType =
					    ec_prevSignalType_copy;
				}

		/*****************************************/
				/* Noise shaping quantization            */
		/*****************************************/
				if (psEnc->sCmn.nStatesDelayedDecision > 1
				    || psEnc->sCmn.warping_Q16 > 0) {
					silk_NSQ_del_dec(&psEnc->sCmn,
							 &psEnc->sCmn.sNSQ,
							 &psEnc->sCmn.indices,
							 xfw_Q3,
							 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_Q3,
						 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);
				}

		/****************************************/
				/* Encode Parameters                    */
		/****************************************/
				silk_encode_indices(&psEnc->sCmn, psRangeEnc,
						    psEnc->sCmn.nFramesEncoded,
						    0, condCoding);

		/****************************************/
				/* Encode Excitation Signal             */
		/****************************************/
				silk_encode_pulses(psRangeEnc,
						   psEnc->sCmn.indices.
						   signalType,
						   psEnc->sCmn.indices.
						   quantOffsetType,
						   psEnc->sCmn.pulses,
						   psEnc->sCmn.frame_length);

				nBits = ec_tell(psRangeEnc);

				if (useCBR == 0 && iter == 0
				    && nBits <= maxBits) {
					break;
				}
			}

			if (iter == maxIter) {
				if (found_lower
				    && (gainsID == gainsID_lower
					|| nBits > maxBits)) {
					/* Restore output state from earlier iteration that did meet the bitrate budget */
					memcpy(psRangeEnc,
						    &sRangeEnc_copy2,
						    sizeof(ec_enc));
					assert(sRangeEnc_copy2.offs <=
						    1275);
					memcpy(psRangeEnc->buf,
						    ec_buf_copy,
						    sRangeEnc_copy2.offs);
					memcpy(&psEnc->sCmn.sNSQ,
						    &sNSQ_copy2,
						    sizeof(silk_nsq_state));
					psEnc->sShape.LastGainIndex =
					    LastGainIndex_copy2;
				}
				break;
			}

			if (nBits > maxBits) {
				if (found_lower == 0 && iter >= 2) {
					/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
					sEncCtrl.Lambda_Q10 =
					    silk_ADD_RSHIFT32(sEncCtrl.
							      Lambda_Q10,
							      sEncCtrl.
							      Lambda_Q10, 1);
					found_upper = 0;
					gainsID_upper = -1;
				} else {
					found_upper = 1;
					nBits_upper = nBits;
					gainMult_upper = gainMult_Q8;
					gainsID_upper = gainsID;
				}
			} else if (nBits < maxBits - 5) {
				found_lower = 1;
				nBits_lower = nBits;
				gainMult_lower = gainMult_Q8;
				if (gainsID != gainsID_lower) {
					gainsID_lower = gainsID;
					/* Copy part of the output state */
					memcpy(&sRangeEnc_copy2,
						    psRangeEnc, sizeof(ec_enc));
					assert(psRangeEnc->offs <= 1275);
					memcpy(ec_buf_copy,
						    psRangeEnc->buf,
						    psRangeEnc->offs);
					memcpy(&sNSQ_copy2,
						    &psEnc->sCmn.sNSQ,
						    sizeof(silk_nsq_state));
					LastGainIndex_copy2 =
					    psEnc->sShape.LastGainIndex;
				}
			} else {
				/* Within 5 bits of budget: close enough */
				break;
			}

			if ((found_lower & found_upper) == 0) {
				/* Adjust gain according to high-rate rate/distortion curve */
				int32_t 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));
				}
				gainMult_Q8 =
				    silk_SMULWB(gain_factor_Q16, gainMult_Q8);
			} else {
				/* Adjust gain by interpolating */
				assert(nBits_upper != nBits_lower);
				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 >
				    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 <
					   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;
			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);
		}
	}

	/* Update input buffer */
	memmove(psEnc->x_buf, &psEnc->x_buf[psEnc->sCmn.frame_length],
		(psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz) * sizeof(int16_t));

	/* Exit without entropy coding */
	if (psEnc->sCmn.prefillFlag) {
		/* No payload */
		*pnBytesOut = 0;

		return ret;
	}

	/* Parameters needed for next frame */
	psEnc->sCmn.prevLag = sEncCtrl.pitchL[psEnc->sCmn.nb_subfr - 1];
	psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;

    /****************************************/
	/* Finalize payload                     */
    /****************************************/
	psEnc->sCmn.first_frame_after_reset = 0;
	/* Payload size */
	*pnBytesOut = silk_RSHIFT(ec_tell(psRangeEnc) + 7, 3);

	return ret;
}
Exemple #2
0
opus_int silk_encode_frame_FLP(
    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
    opus_int32                      *pnBytesOut,                        /* O    Number of payload bytes;                    */
    ec_enc                          *psRangeEnc,                        /* I/O  compressor data structure                   */
    opus_int                        condCoding,                         /* I    The type of conditional coding to use       */
    opus_int                        maxBits,                            /* I    If > 0: maximum number of output bits       */
    opus_int                        useCBR                              /* I    Flag to force constant-bitrate operation    */
)
{
    silk_encoder_control_FLP sEncCtrl;
    opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
    silk_float   *x_frame, *res_pitch_frame;
    silk_float   xfw[ MAX_FRAME_LENGTH ];
    silk_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
    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;
    opus_int8    LastGainIndex_copy2;
    opus_int32   pGains_Q16[ MAX_NB_SUBFR ];
    opus_uint8   ec_buf_copy[ 1275 ];

    /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
    LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;

    psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;

    /**************************************************************/
    /* Set up Input Pointers, and insert frame in input buffer    */
    /**************************************************************/
    /* pointers aligned with start of frame to encode */
    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */
    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */

    /***************************************/
    /* Ensure smooth bandwidth transitions */
    /***************************************/
    silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );

    /*******************************************/
    /* Copy new frame to front of input buffer */
    /*******************************************/
    silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );

    /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
    for( i = 0; i < 8; i++ ) {
        x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;
    }

    if( !psEnc->sCmn.prefillFlag ) {
        /*****************************************/
        /* Find pitch lags, initial LPC analysis */
        /*****************************************/
        silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame );

        /************************/
        /* Noise shape analysis */
        /************************/
        silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );

        /***************************************************/
        /* Find linear prediction coefficients (LPC + LTP) */
        /***************************************************/
        silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );

        /****************************************/
        /* Process gains                        */
        /****************************************/
        silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );

        /*****************************************/
        /* Prefiltering for noise shaper         */
        /*****************************************/
        silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );

        /****************************************/
        /* Low Bitrate Redundant Encoding       */
        /****************************************/
        silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );

        /* Loop over quantizer and entroy coding to control bitrate */
        maxIter = 6;
        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++ ) {
            if( gainsID == gainsID_lower ) {
                nBits = nBits_lower;
            } else if( gainsID == gainsID_upper ) {
                nBits = nBits_upper;
            } else {
                /* Restore part of the input state */
                if( iter > 0 ) {
                    silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
                    silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
                    psEnc->sCmn.indices.Seed = seed_copy;
                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
                }

                /*****************************************/
                /* Noise shaping quantization            */
                /*****************************************/
                silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );

                /****************************************/
                /* Encode Parameters                    */
                /****************************************/
                silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );

                /****************************************/
                /* Encode Excitation Signal             */
                /****************************************/
                silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
                      psEnc->sCmn.pulses, psEnc->sCmn.frame_length );

                nBits = ec_tell( psRangeEnc );

                if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
                    break;
                }
            }

            if( iter == maxIter ) {
                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;
                }
                break;
            }

            if( nBits > maxBits ) {
                if( found_lower == 0 && iter >= 2 ) {
                    /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
                    sEncCtrl.Lambda *= 1.5f;
                    found_upper = 0;
                    gainsID_upper = -1;
                } else {
                    found_upper = 1;
                    nBits_upper = nBits;
                    gainMult_upper = gainMult_Q8;
                    gainsID_upper = gainsID;
                }
            } else if( nBits < maxBits - 5 ) {
                found_lower = 1;
                nBits_lower = nBits;
                gainMult_lower = gainMult_Q8;
                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;
            }

            if( ( found_lower & found_upper ) == 0 ) {
                /* 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 ) );
                }
                gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
            } else {
                /* 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 > 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 < 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 );
            }

            /* 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;
            }
        }
    }

    /* Update input buffer */
    silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
        ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );

    /* Parameters needed for next frame */
    psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
    psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;

    /* Exit without entropy coding */
    if( psEnc->sCmn.prefillFlag ) {
        /* No payload */
        *pnBytesOut = 0;
        return ret;
    }

    /****************************************/
    /* Finalize payload                     */
    /****************************************/
    psEnc->sCmn.first_frame_after_reset = 0;
    /* Payload size */
    *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );

    return ret;
}
Exemple #3
0
/* encControl->payloadSize_ms is set to                                                                         */
opus_int silk_Encode(                                   /* O    Returns error code                              */
    void                            *encState,          /* I/O  State                                           */
    silk_EncControlStruct           *encControl,        /* I    Control status                                  */
    const opus_int16                *samplesIn,         /* I    Speech sample input vector                      */
    opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */
    ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */
    opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */
    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */
)
{
    opus_int   n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
    opus_int   nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
    opus_int   nSamplesFromInput = 0, nSamplesFromInputMax;
    opus_int   speech_act_thr_for_switch_Q8;
    opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
    silk_encoder *psEnc = ( silk_encoder * )encState;
    VARDECL( opus_int16, buf );
    opus_int transition, curr_block, tot_blocks;
    SAVE_STACK;

    if (encControl->reducedDependency)
    {
       psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
       psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
    }
    psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;

    /* Check values in encoder control structure */
    if( ( ret = check_control_input( encControl ) ) != 0 ) {
        silk_assert( 0 );
        RESTORE_STACK;
        return ret;
    }

    encControl->switchReady = 0;

    if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
        /* Mono -> Stereo transition: init state of second channel and stereo state */
        ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
        silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
        silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
        psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
        psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
        psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
        psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
        psEnc->sStereo.width_prev_Q14 = 0;
        psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
        if( psEnc->nChannelsAPI == 2 ) {
            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State,     &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State,     sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );
        }
    }

    transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);

    psEnc->nChannelsAPI = encControl->nChannelsAPI;
    psEnc->nChannelsInternal = encControl->nChannelsInternal;

    nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
    tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
    curr_block = 0;
    if( prefillFlag ) {
        /* Only accept input length of 10 ms */
        if( nBlocksOf10ms != 1 ) {
            silk_assert( 0 );
            RESTORE_STACK;
            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
        }
        /* Reset Encoder */
        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
            ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
            silk_assert( !ret );
        }
        tmp_payloadSize_ms = encControl->payloadSize_ms;
        encControl->payloadSize_ms = 10;
        tmp_complexity = encControl->complexity;
        encControl->complexity = 0;
        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
        }
    } else {
        /* Only accept input lengths that are a multiple of 10 ms */
        if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
            silk_assert( 0 );
            RESTORE_STACK;
            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
        }
        /* Make sure no more than one packet can be produced */
        if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
            silk_assert( 0 );
            RESTORE_STACK;
            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
        }
    }

    TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );
    for( n = 0; n < encControl->nChannelsInternal; n++ ) {
        /* 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 );
            RESTORE_STACK;
            return ret;
        }
        if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
            for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
                psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
            }
        }
        psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
    }
    silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );

    /* Input buffering/resampling and encoding */
    nSamplesToBufferMax =
        10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
    nSamplesFromInputMax =
        silk_DIV32_16( nSamplesToBufferMax *
                           psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
                       psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
    ALLOC( buf, nSamplesFromInputMax, opus_int16 );
    while( 1 ) {
        nSamplesToBuffer  = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
        nSamplesToBuffer  = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
        nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
        /* Resample and write to buffer */
        if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
            opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
            for( n = 0; n < nSamplesFromInput; n++ ) {
                buf[ n ] = samplesIn[ 2 * n ];
            }
            /* Making sure to start both resamplers from the same state when switching from mono to stereo */
            if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
               silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
            }

            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;

            nSamplesToBuffer  = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
            nSamplesToBuffer  = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
            for( n = 0; n < nSamplesFromInput; n++ ) {
                buf[ n ] = samplesIn[ 2 * n + 1 ];
            }
            ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
                &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );

            psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
        } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
            /* Combine left and right channels before resampling */
            for( n = 0; n < nSamplesFromInput; n++ ) {
                sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
                buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum,  1 );
            }
            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
            /* On the first mono frame, average the results for the two resampler states  */
            if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
               ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
                   &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
               for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
                  psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
                        silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
                                  + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
               }
            }
            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
        } else {
            silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
            silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
        }

        samplesIn  += nSamplesFromInput * encControl->nChannelsAPI;
        nSamplesIn -= nSamplesFromInput;

        /* Default */
        psEnc->allowBandwidthSwitch = 0;

        /* Silk encoder */
        if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
            /* Enough data in input buffer, so encode */
            silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
            silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );

            /* Deal with LBRR data */
            if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
                /* Create space at start of payload for VAD and FEC flags */
                opus_uint8 iCDF[ 2 ] = { 0, 0 };
                iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
                ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );

                /* Encode any LBRR data from previous packet */
                /* Encode LBRR flags */
                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
                    LBRR_symbol = 0;
                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
                        LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
                    }
                    psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
                    if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
                        ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
                    }
                }

                /* Code LBRR indices and excitation signals */
                for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
                    for( n = 0; n < encControl->nChannelsInternal; n++ ) {
                        if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
                            opus_int condCoding;

                            if( encControl->nChannelsInternal == 2 && n == 0 ) {
                                silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
                                /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
                                if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
                                    silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
                                }
                            }
                            /* Use conditional coding if previous frame available */
                            if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
                                condCoding = CODE_CONDITIONALLY;
                            } else {
                                condCoding = CODE_INDEPENDENTLY;
                            }
                            silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
                            silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
                                psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
                        }
                    }
                }

                /* Reset LBRR flags */
                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
                    silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
                }

                psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
            }

            silk_HP_variable_cutoff( psEnc->state_Fxx );

            /* Total target bits for packet */
            nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
            /* Subtract bits used for LBRR */
            if( !prefillFlag ) {
                nBits -= psEnc->nBitsUsedLBRR;
            }
            /* Divide by number of uncoded frames left in packet */
            nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
            /* Convert to bits/second */
            if( encControl->payloadSize_ms == 10 ) {
                TargetRate_bps = silk_SMULBB( nBits, 100 );
            } else {
                TargetRate_bps = silk_SMULBB( nBits, 50 );
            }
            /* Subtract fraction of bits in excess of target in previous frames and packets */
            TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
            if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
                /* Compare actual vs target bits so far in this packet */
                opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
                TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
            }
            /* Never exceed input bitrate */
            TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );

            /* Convert Left/Right to Mid/Side */
            if( encControl->nChannelsInternal == 2 ) {
                silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
                    psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
                    MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
                    psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
                if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
                    /* Reset side channel encoder memory for first frame with side coding */
                    if( psEnc->prev_decode_only_middle == 1 ) {
                        silk_memset( &psEnc->state_Fxx[ 1 ].sShape,               0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
                        silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt,             0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );
                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ,            0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
                        silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
                        psEnc->state_Fxx[ 1 ].sCmn.prevLag                 = 100;
                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev            = 100;
                        psEnc->state_Fxx[ 1 ].sShape.LastGainIndex         = 10;
                        psEnc->state_Fxx[ 1 ].sCmn.prevSignalType          = TYPE_NO_VOICE_ACTIVITY;
                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16      = 65536;
                        psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
                    }
                    silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );
                } else {
                    psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
                }
                if( !prefillFlag ) {
                    silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
                    if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
                        silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
                    }
                }
            } else {
                /* Buffering */
                silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
                silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
            }
            silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );

            /* Encode */
            for( n = 0; n < encControl->nChannelsInternal; n++ ) {
                opus_int maxBits, useCBR;

                /* Handling rate constraints */
                maxBits = encControl->maxBits;
                if( tot_blocks == 2 && curr_block == 0 ) {
                    maxBits = maxBits * 3 / 5;
                } else if( tot_blocks == 3 ) {
                    if( curr_block == 0 ) {
                        maxBits = maxBits * 2 / 5;
                    } else if( curr_block == 1 ) {
                        maxBits = maxBits * 3 / 4;
                    }
                }
                useCBR = encControl->useCBR && curr_block == tot_blocks - 1;

                if( encControl->nChannelsInternal == 1 ) {
                    channelRate_bps = TargetRate_bps;
                } else {
                    channelRate_bps = MStargetRates_bps[ n ];
                    if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
                        useCBR = 0;
                        /* Give mid up to 1/2 of the max bits for that frame */
                        maxBits -= encControl->maxBits / ( tot_blocks * 2 );
                    }
                }

                if( channelRate_bps > 0 ) {
                    opus_int condCoding;

                    silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );

                    /* Use independent coding if no previous frame available */
                    if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
                        condCoding = CODE_INDEPENDENTLY;
                    } else if( n > 0 && psEnc->prev_decode_only_middle ) {
                        /* If we skipped a side frame in this packet, we don't
                           need LTP scaling; the LTP state is well-defined. */
                        condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
                    } else {
                        condCoding = CODE_CONDITIONALLY;
                    }
                    if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
                        silk_assert( 0 );
                    }
                }
                psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
                psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
                psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
            }
            psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];

            /* Insert VAD and FEC flags at beginning of bitstream */
            if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
                flags = 0;
                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
                        flags  = silk_LSHIFT( flags, 1 );
                        flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
                    }
                    flags  = silk_LSHIFT( flags, 1 );
                    flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
                }
                if( !prefillFlag ) {
                    ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
                }

                /* Return zero bytes if all channels DTXed */
                if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
                    *nBytesOut = 0;
                }

                psEnc->nBitsExceeded += *nBytesOut * 8;
                psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
                psEnc->nBitsExceeded  = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );

                /* Update flag indicating if bandwidth switching is allowed */
                speech_act_thr_for_switch_Q8 = (opus_int) silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
                    SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
                if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
                    psEnc->allowBandwidthSwitch = 1;
                    psEnc->timeSinceSwitchAllowed_ms = 0;
                } else {
                    psEnc->allowBandwidthSwitch = 0;
                    psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
                }
            }

            if( nSamplesIn == 0 ) {
                break;
            }
        } else {
            break;
        }
        curr_block++;
    }

    psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;

    encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
    encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
    encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
    encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
    if( prefillFlag ) {
        encControl->payloadSize_ms = tmp_payloadSize_ms;
        encControl->complexity = tmp_complexity;
        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
        }
    }

    RESTORE_STACK;
    return ret;
}