/* Autocorrelations for a warped frequency axis */
void silk_warped_autocorrelation_FIX(
          opus_int32                 *corr,              /* O    Result [order + 1]                      */
          opus_int                   *scale,             /* O    Scaling of the correlation vector       */
    const opus_int16                 *input,             /* I    Input data to correlate                 */
    const opus_int                   warping_Q16,        /* I    Warping coefficient                     */
    const opus_int                   length,             /* I    Length of input                         */
    const opus_int                   order               /* I    Correlation order (even)                */
)
{
    opus_int   n, i, lsh;
    opus_int32 tmp1_QS, tmp2_QS;
    opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
    opus_int64 corr_QC[  MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };

    /* Order must be even */
    SKP_assert( ( order & 1 ) == 0 );
    SKP_assert( 2 * QS - QC >= 0 );

    /* Loop over samples */
    for( n = 0; n < length; n++ ) {
        tmp1_QS = SKP_LSHIFT32( ( opus_int32 )input[ n ], QS );
        /* Loop over allpass sections */
        for( i = 0; i < order; i += 2 ) {
            /* Output of allpass section */
            tmp2_QS = SKP_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
            state_QS[ i ]  = tmp1_QS;
            corr_QC[  i ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
            /* Output of allpass section */
            tmp1_QS = SKP_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
            state_QS[ i + 1 ]  = tmp2_QS;
            corr_QC[  i + 1 ] += SKP_RSHIFT64( SKP_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
        }
        state_QS[ order ] = tmp1_QS;
        corr_QC[  order ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
    }

    lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;
    lsh = SKP_LIMIT( lsh, -12 - QC, 30 - QC );
    *scale = -( QC + lsh ); 
    SKP_assert( *scale >= -30 && *scale <= 12 );
    if( lsh >= 0 ) {
        for( i = 0; i < order + 1; i++ ) {
            corr[ i ] = ( opus_int32 )SKP_CHECK_FIT32( SKP_LSHIFT64( corr_QC[ i ], lsh ) );
        }
    } else {
        for( i = 0; i < order + 1; i++ ) {
            corr[ i ] = ( opus_int32 )SKP_CHECK_FIT32( SKP_RSHIFT64( corr_QC[ i ], -lsh ) );
        }    
    }
    SKP_assert( corr_QC[ 0 ] >= 0 ); // If breaking, decrease QC
}
Exemplo n.º 2
0
/* Control SNR of redidual quantizer */
SKP_int silk_control_SNR(
    silk_encoder_state      *psEncC,            /* I/O  Pointer to Silk encoder state               */
    SKP_int32                   TargetRate_bps      /* I    Target max bitrate (bps)                    */
)
{
    SKP_int k, ret = SILK_NO_ERROR;
    SKP_int32 frac_Q6;
    const SKP_int32 *rateTable;

    /* Set bitrate/coding quality */
    TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
    if( TargetRate_bps != psEncC->TargetRate_bps ) {
        psEncC->TargetRate_bps = TargetRate_bps;

        /* If new TargetRate_bps, translate to SNR_dB value */
        if( psEncC->fs_kHz == 8 ) {
            rateTable = silk_TargetRate_table_NB;
        } else if( psEncC->fs_kHz == 12 ) {
            rateTable = silk_TargetRate_table_MB;
        } else {
            rateTable = silk_TargetRate_table_WB;
        }

        /* Reduce bitrate for 10 ms modes in these calculations */
        if( psEncC->nb_subfr == 2 ) {
            TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;
        }

        /* Find bitrate interval in table and interpolate */
        for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
            if( TargetRate_bps <= rateTable[ k ] ) {
                frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), 
                                                 rateTable[ k ] - rateTable[ k - 1 ] );
                psEncC->SNR_dB_Q7 = SKP_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );
                break;
            }
        }
    }

    return ret;
}
Exemplo n.º 3
0
void silk_NLSF_decode(
          opus_int16             *pNLSF_Q15,             /* O    Quantized NLSF vector [ LPC_ORDER ]     */
          opus_int8              *NLSFIndices,           /* I    Codebook path vector [ LPC_ORDER + 1 ]  */
    const silk_NLSF_CB_struct   *psNLSF_CB              /* I    Codebook object                         */
)
{
    opus_int         i;
    opus_uint8       pred_Q8[  MAX_LPC_ORDER ];
    opus_int16       ec_ix[    MAX_LPC_ORDER ];
    opus_int16       res_Q10[  MAX_LPC_ORDER ];
    opus_int16       W_tmp_QW[ MAX_LPC_ORDER ];
    opus_int32       W_tmp_Q9, NLSF_Q15_tmp;
    const opus_uint8 *pCB_element;

    /* Decode first stage */
    pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
    for( i = 0; i < psNLSF_CB->order; i++ ) {
        pNLSF_Q15[ i ] = SKP_LSHIFT( ( opus_int16 )pCB_element[ i ], 7 );
    }

    /* Unpack entropy table indices and predictor for current CB1 index */
    silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );

    /* Trellis dequantizer */
    silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );

    /* Weights from codebook vector */
    silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );

    /* Apply inverse square-rooted weights and add to output */
    for( i = 0; i < psNLSF_CB->order; i++ ) {
        W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( opus_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
        NLSF_Q15_tmp = SKP_ADD32( pNLSF_Q15[ i ], SKP_DIV32_16( SKP_LSHIFT( ( opus_int32 )res_Q10[ i ], 14 ), W_tmp_Q9 ) );
        pNLSF_Q15[ i ] = (opus_int16)SKP_LIMIT( NLSF_Q15_tmp, 0, 32767 );
    }

    /* NLSF stabilization */
    silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
}
void silk_LTP_scale_ctrl_FLP(
    silk_encoder_state_FLP      *psEnc,             /* I/O  Encoder state FLP                       */
    silk_encoder_control_FLP    *psEncCtrl          /* I/O  Encoder control FLP                     */
)
{
    opus_int   round_loss;

    /* 1st order high-pass filter */
    //g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1);
    psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - 0.5 * psEnc->prevLTPredCodGain, 0.0f ) 
                            + 0.5f * psEnc->HPLTPredCodGain;
    psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain;

    /* Only scale if first frame in packet */
    if( psEnc->sCmn.nFramesEncoded == 0 ) {
        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)SKP_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f );
    } else {
        /* Default is minimum scaling */
        psEnc->sCmn.indices.LTP_scaleIndex = 0;
    }
    psEncCtrl->LTP_scale = (SKP_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
}
Exemplo n.º 5
0
/* Deactivate by setting psEncC->mode = 0;                  */
void silk_LP_variable_cutoff(
    silk_LP_state           *psLP,              /* I/O  LP filter state                             */
    SKP_int16                   *signal,            /* I/O  Low-pass filtered output signal             */
    const SKP_int               frame_length        /* I    Frame length                                */
)
{
    SKP_int32   B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
    SKP_int     ind = 0;

    SKP_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES );

    /* Run filter if needed */
    if( psLP->mode != 0 ) {
        /* Calculate index and interpolation factor for interpolation */
#if( TRANSITION_INT_STEPS == 64 )
        fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 );
#else
        fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES );
#endif
        ind      = SKP_RSHIFT( fac_Q16, 16 );
        fac_Q16 -= SKP_LSHIFT( ind, 16 );

        SKP_assert( ind >= 0 );
        SKP_assert( ind < TRANSITION_INT_NUM );

        /* Interpolate filter coefficients */
        silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );

        /* Update transition frame number for next frame */
        psLP->transition_frame_no = SKP_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES );

        /* ARMA low-pass filtering */
        SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
        silk_biquad_alt( signal, B_Q28, A_Q28, psLP->In_LP_State, signal, frame_length );
    }
}
Exemplo n.º 6
0
/* NLSF stabilizer, for a single input data vector */
void SKP_Silk_NLSF_stabilize(
          SKP_int    *NLSF_Q15,            /* I/O:  Unstable/stabilized normalized LSF vector in Q15 [L]                    */
    const SKP_int    *NDeltaMin_Q15,       /* I:    Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
    const SKP_int     L                    /* I:    Number of NLSF parameters in the input vector                           */
)
{
    SKP_int        center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
    SKP_int32    min_diff_Q15;
    SKP_int        loops;
    SKP_int        i, I=0, k;

    /* This is necessary to ensure an output within range of a SKP_int16 */
    SKP_assert( NDeltaMin_Q15[L] >= 1 );

    for( loops = 0; loops < MAX_LOOPS; loops++ ) {
        /**************************/
        /* Find smallest distance */
        /**************************/
        /* First element */
        min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
        I = 0;
        /* Middle elements */
        for( i = 1; i <= L-1; i++ ) {
            diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
            if( diff_Q15 < min_diff_Q15 ) {
                min_diff_Q15 = diff_Q15;
                I = i;
            }
        }
        /* Last element */
        diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
        if( diff_Q15 < min_diff_Q15 ) {
            min_diff_Q15 = diff_Q15;
            I = L;
        }

        /***************************************************/
        /* Now check if the smallest distance non-negative */
        /***************************************************/
        if (min_diff_Q15 >= 0) {
            return;
        }

        if( I == 0 ) {
            /* Move away from lower limit */
            NLSF_Q15[0] = NDeltaMin_Q15[0];
        
        } else if( I == L) {
            /* Move away from higher limit */
            NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];
        
        } else {
            /* Find the lower extreme for the location of the current center frequency */ 
            min_center_Q15 = 0;
            for( k = 0; k < I; k++ ) {
                min_center_Q15 += NDeltaMin_Q15[k];
            }
            min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );

            /* Find the upper extreme for the location of the current center frequency */
            max_center_Q15 = (1<<15);
            for( k = L; k > I; k-- ) {
                max_center_Q15 -= NDeltaMin_Q15[k];
            }
            max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );

            /* Move apart, sorted by value, keeping the same center frequency */
            center_freq_Q15 = SKP_LIMIT( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
                min_center_Q15, max_center_Q15 );
            NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
            NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
        }
    }

    /* Safe and simple fall back method, which is less ideal than the above */
    if( loops == MAX_LOOPS )
    {
        /* Insertion sort (fast for already almost sorted arrays):   */
        /* Best case:  O(n)   for an already sorted array            */
        /* Worst case: O(n^2) for an inversely sorted array          */
        SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);
            
        /* First NLSF should be no less than NDeltaMin[0] */
        NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
        
        /* Keep delta_min distance between the NLSFs */
        for( i = 1; i < L; i++ )
            NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );

        /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
        NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );

        /* Keep NDeltaMin distance between the NLSFs */
        for( i = L-2; i >= 0; i-- ) 
            NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
    }
}
/* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */
void SKP_Silk_LBRR_encode_FIX(SKP_Silk_encoder_state_FIX * psEnc,	/* I/O  Pointer to Silk encoder state           */
			      SKP_Silk_encoder_control_FIX * psEncCtrl,	/* I/O  Pointer to Silk encoder control struct  */
			      uint8_t * pCode,	/* O    Pointer to payload                      */
			      int16_t * pnBytesOut,	/* I/O  Pointer to number of payload bytes      */
			      int16_t xfw[]	/* I    Input signal                            */
    )
{
	int i, TempGainsIndices[NB_SUBFR], frame_terminator;
	int nBytes, nFramesInPayloadBuf;
	int32_t TempGains_Q16[NB_SUBFR];
	int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;
    /*******************************************/
	/* Control use of inband LBRR              */
    /*******************************************/
	SKP_Silk_LBRR_ctrl_FIX(psEnc, psEncCtrl);

	if (psEnc->sCmn.LBRR_enabled) {
		/* Save original Gains */
		SKP_memcpy(TempGainsIndices, psEncCtrl->sCmn.GainsIndices,
			   NB_SUBFR * sizeof(int));
		SKP_memcpy(TempGains_Q16, psEncCtrl->Gains_Q16,
			   NB_SUBFR * sizeof(int32_t));

		typeOffset = psEnc->sCmn.typeOffsetPrev;	// Temp save as cannot be overwritten
		LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;

		/* Set max rate where quant signal is encoded */
		if (psEnc->sCmn.fs_kHz == 8) {
			Rate_only_parameters = 13500;
		} else if (psEnc->sCmn.fs_kHz == 12) {
			Rate_only_parameters = 15500;
		} else if (psEnc->sCmn.fs_kHz == 16) {
			Rate_only_parameters = 17500;
		} else if (psEnc->sCmn.fs_kHz == 24) {
			Rate_only_parameters = 19500;
		} else {
			assert(0);
		}

		if (psEnc->sCmn.Complexity > 0
		    && psEnc->sCmn.TargetRate_bps > Rate_only_parameters) {
			if (psEnc->sCmn.nFramesInPayloadBuf == 0) {
				/* First frame in packet copy Everything */
				SKP_memcpy(&psEnc->sNSQ_LBRR, &psEnc->sNSQ,
					   sizeof(SKP_Silk_nsq_state));

				psEnc->sCmn.LBRRprevLastGainIndex =
				    psEnc->sShape.LastGainIndex;
				/* Increase Gains to get target LBRR rate */
				psEncCtrl->sCmn.GainsIndices[0] =
				    psEncCtrl->sCmn.GainsIndices[0] +
				    psEnc->sCmn.LBRR_GainIncreases;
				psEncCtrl->sCmn.GainsIndices[0] =
				    SKP_LIMIT(psEncCtrl->sCmn.GainsIndices[0],
					      0, N_LEVELS_QGAIN - 1);
			}
			/* Decode to get Gains in sync with decoder         */
			/* Overwrite unquantized gains with quantized gains */
			SKP_Silk_gains_dequant(psEncCtrl->Gains_Q16,
					       psEncCtrl->sCmn.GainsIndices,
					       &psEnc->sCmn.
					       LBRRprevLastGainIndex,
					       psEnc->sCmn.nFramesInPayloadBuf);
	    /*****************************************/
			/* Noise shaping quantization            */
	    /*****************************************/
			psEnc->NoiseShapingQuantizer(&psEnc->sCmn,
						     &psEncCtrl->sCmn,
						     &psEnc->sNSQ_LBRR, xfw,
						     &psEnc->sCmn.q_LBRR[psEnc->
									 sCmn.
									 nFramesInPayloadBuf
									 *
									 psEnc->
									 sCmn.
									 frame_length],
						     psEncCtrl->sCmn.
						     NLSFInterpCoef_Q2,
						     psEncCtrl->PredCoef_Q12[0],
						     psEncCtrl->LTPCoef_Q14,
						     psEncCtrl->AR2_Q13,
						     psEncCtrl->
						     HarmShapeGain_Q14,
						     psEncCtrl->Tilt_Q14,
						     psEncCtrl->LF_shp_Q14,
						     psEncCtrl->Gains_Q16,
						     psEncCtrl->Lambda_Q10,
						     psEncCtrl->LTP_scale_Q14);
		} else {
			SKP_memset(&psEnc->sCmn.
				   q_LBRR[psEnc->sCmn.nFramesInPayloadBuf *
					  psEnc->sCmn.frame_length], 0,
				   psEnc->sCmn.frame_length * sizeof(int));
			psEncCtrl->sCmn.LTP_scaleIndex = 0;
		}
	/****************************************/
		/* Initialize arithmetic coder          */
	/****************************************/
		if (psEnc->sCmn.nFramesInPayloadBuf == 0) {
			SKP_Silk_range_enc_init(&psEnc->sCmn.sRC_LBRR);
			psEnc->sCmn.nBytesInPayloadBuf = 0;
		}

	/****************************************/
		/* Encode Parameters                    */
	/****************************************/
		if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) {
			SKP_Silk_encode_parameters_v4(&psEnc->sCmn,
						      &psEncCtrl->sCmn,
						      &psEnc->sCmn.sRC_LBRR);
		} else {
			SKP_Silk_encode_parameters(&psEnc->sCmn,
						   &psEncCtrl->sCmn,
						   &psEnc->sCmn.sRC_LBRR,
						   &psEnc->sCmn.q_LBRR[psEnc->
								       sCmn.
								       nFramesInPayloadBuf
								       *
								       psEnc->
								       sCmn.
								       frame_length]);
		}

		if (psEnc->sCmn.sRC_LBRR.error) {
			/* encoder returned error: clear payload buffer */
			nFramesInPayloadBuf = 0;
		} else {
			nFramesInPayloadBuf =
			    psEnc->sCmn.nFramesInPayloadBuf + 1;
		}

	/****************************************/
		/* finalize payload and copy to output  */
	/****************************************/
		if (SKP_SMULBB(nFramesInPayloadBuf, FRAME_LENGTH_MS) >=
		    psEnc->sCmn.PacketSize_ms) {

			/* Check if FEC information should be added */
			frame_terminator = SKP_SILK_LAST_FRAME;

			/* Add the frame termination info to stream */
			SKP_Silk_range_encoder(&psEnc->sCmn.sRC_LBRR,
					       frame_terminator,
					       SKP_Silk_FrameTermination_CDF);

			if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) {
		/*********************************************/
				/* Encode quantization indices of excitation */
		/*********************************************/
				for (i = 0; i < nFramesInPayloadBuf; i++) {
					SKP_Silk_encode_pulses(&psEnc->sCmn.
							       sRC_LBRR,
							       psEnc->sCmn.
							       sigtype[i],
							       psEnc->sCmn.
							       QuantOffsetType
							       [i],
							       &psEnc->sCmn.
							       q_LBRR[i *
								      psEnc->
								      sCmn.
								      frame_length],
							       psEnc->sCmn.
							       frame_length);
				}
			}
			/* payload length so far */
			SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC_LBRR,
							&nBytes);

			/* check that there is enough space in external output buffer, and move data */
			if (*pnBytesOut >= nBytes) {
				SKP_Silk_range_enc_wrap_up(&psEnc->sCmn.
							   sRC_LBRR);
				SKP_memcpy(pCode, psEnc->sCmn.sRC_LBRR.buffer,
					   nBytes * sizeof(uint8_t));

				*pnBytesOut = nBytes;
			} else {
				/* not enough space: payload will be discarded */
				*pnBytesOut = 0;
				assert(0);
			}
		} else {
			/* no payload for you this time */
			*pnBytesOut = 0;

			/* Encode that more frames follows */
			frame_terminator = SKP_SILK_MORE_FRAMES;
			SKP_Silk_range_encoder(&psEnc->sCmn.sRC_LBRR,
					       frame_terminator,
					       SKP_Silk_FrameTermination_CDF);
		}

		/* Restore original Gains */
		SKP_memcpy(psEncCtrl->sCmn.GainsIndices, TempGainsIndices,
			   NB_SUBFR * sizeof(int));
		SKP_memcpy(psEncCtrl->Gains_Q16, TempGains_Q16,
			   NB_SUBFR * sizeof(int32_t));

		/* Restore LTP scale index and typeoffset */
		psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;
		psEnc->sCmn.typeOffsetPrev = typeOffset;
	}
}
int SKP_Silk_encode_frame_FIX(SKP_Silk_encoder_state_FIX * psEnc,	/* I/O  Pointer to Silk FIX encoder state           */
			      uint8_t * pCode,	/* O    Pointer to payload                          */
			      int16_t * pnBytesOut,	/* I/O  Pointer to number of payload bytes          */
			      /*      input: max length; output: used             */
			      const int16_t * pIn	/* I    Pointer to input speech frame               */
    ) {
	SKP_Silk_encoder_control_FIX sEncCtrl;
	int i, nBytes, ret = 0;
	int16_t *x_frame, *res_pitch_frame;
	int16_t xfw[MAX_FRAME_LENGTH];
	int16_t pIn_HP[MAX_FRAME_LENGTH];
	int16_t res_pitch[2 * MAX_FRAME_LENGTH + LA_PITCH_MAX];
	int LBRR_idx, frame_terminator, SNR_dB_Q7;
	const uint16_t *FrameTermination_CDF;

	/* Low bitrate redundancy parameters */
	uint8_t LBRRpayload[MAX_ARITHM_BYTES];
	int16_t nBytesLBRR;

	//int32_t   Seed[ MAX_LAYERS ];
	sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;

    /**************************************************************/
	/* Setup Input Pointers, and insert frame in input buffer    */
    /*************************************************************/
	x_frame = psEnc->x_buf + psEnc->sCmn.frame_length;	/* start of frame to encode */
	res_pitch_frame = res_pitch + psEnc->sCmn.frame_length;	/* start of pitch LPC residual frame */

    /****************************/
	/* Voice Activity Detection */
    /****************************/
	ret =
	    SKP_Silk_VAD_GetSA_Q8(&psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8,
				  &SNR_dB_Q7, sEncCtrl.input_quality_bands_Q15,
				  &sEncCtrl.input_tilt_Q15, pIn,
				  psEnc->sCmn.frame_length);

    /*******************************************/
	/* High-pass filtering of the input signal */
    /*******************************************/
#if HIGH_PASS_INPUT
	/* Variable high-pass filter */
	SKP_Silk_HP_variable_cutoff_FIX(psEnc, &sEncCtrl, pIn_HP, pIn);
#else
	SKP_memcpy(pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof(int16_t));
#endif

#if SWITCH_TRANSITION_FILTERING
	/* Ensure smooth bandwidth transitions */
	SKP_Silk_LP_variable_cutoff(&psEnc->sCmn.sLP,
				    x_frame + psEnc->sCmn.la_shape, pIn_HP,
				    psEnc->sCmn.frame_length);
#else
	SKP_memcpy(x_frame + psEnc->sCmn.la_shape, pIn_HP,
		   psEnc->sCmn.frame_length * sizeof(int16_t));
#endif

    /*****************************************/
	/* Find pitch lags, initial LPC analysis */
    /*****************************************/
	SKP_Silk_find_pitch_lags_FIX(psEnc, &sEncCtrl, res_pitch, x_frame);

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

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

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

    /****************************************/
	/* Process gains                        */
    /****************************************/
	SKP_Silk_process_gains_FIX(psEnc, &sEncCtrl);

	psEnc->sCmn.sigtype[psEnc->sCmn.nFramesInPayloadBuf] =
	    sEncCtrl.sCmn.sigtype;
	psEnc->sCmn.QuantOffsetType[psEnc->sCmn.nFramesInPayloadBuf] =
	    sEncCtrl.sCmn.QuantOffsetType;

    /****************************************/
	/* Low Bitrate Redundant Encoding       */
    /****************************************/
	nBytesLBRR = MAX_ARITHM_BYTES;
	SKP_Silk_LBRR_encode_FIX(psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR,
				 xfw);

    /*****************************************/
	/* Noise shaping quantization            */
    /*****************************************/
	psEnc->NoiseShapingQuantizer(&psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ,
				     xfw,
				     &psEnc->sCmn.q[psEnc->sCmn.
						    nFramesInPayloadBuf *
						    psEnc->sCmn.frame_length],
				     sEncCtrl.sCmn.NLSFInterpCoef_Q2,
				     sEncCtrl.PredCoef_Q12[0],
				     sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13,
				     sEncCtrl.HarmShapeGain_Q14,
				     sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14,
				     sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10,
				     sEncCtrl.LTP_scale_Q14);

    /**************************************************/
	/* Convert speech activity into VAD and DTX flags */
    /**************************************************/
	if (psEnc->speech_activity_Q8 < SPEECH_ACTIVITY_DTX_THRES_Q8) {
		psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;
		psEnc->sCmn.noSpeechCounter++;
		if (psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX) {
			psEnc->sCmn.inDTX = 1;
		}
		if (psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX) {
			psEnc->sCmn.noSpeechCounter = 0;
			psEnc->sCmn.inDTX = 0;
		}
	} else {
		psEnc->sCmn.noSpeechCounter = 0;
		psEnc->sCmn.inDTX = 0;
		psEnc->sCmn.vadFlag = VOICE_ACTIVITY;
	}

    /****************************************/
	/* Initialize arithmetic coder          */
    /****************************************/
	if (psEnc->sCmn.nFramesInPayloadBuf == 0) {
		SKP_Silk_range_enc_init(&psEnc->sCmn.sRC);
		psEnc->sCmn.nBytesInPayloadBuf = 0;
	}

    /****************************************/
	/* Encode Parameters                    */
    /****************************************/
	if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) {
		SKP_Silk_encode_parameters_v4(&psEnc->sCmn, &sEncCtrl.sCmn,
					      &psEnc->sCmn.sRC);
		FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF;
	} else {
		SKP_Silk_encode_parameters(&psEnc->sCmn, &sEncCtrl.sCmn,
					   &psEnc->sCmn.sRC,
					   &psEnc->sCmn.q[psEnc->sCmn.
							  nFramesInPayloadBuf *
							  psEnc->sCmn.
							  frame_length]);
		FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;
	}

    /****************************************/
	/* Update Buffers and State             */
    /****************************************/
	/* Update Input buffer */
	SKP_memmove(psEnc->x_buf, &psEnc->x_buf[psEnc->sCmn.frame_length],
		    (psEnc->sCmn.frame_length +
		     psEnc->sCmn.la_shape) * sizeof(int16_t));

	/* parameters needed for next frame */
	psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype;
	psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[NB_SUBFR - 1];
	psEnc->sCmn.first_frame_after_reset = 0;

	if (psEnc->sCmn.sRC.error) {
		/* encoder returned error: clear payload buffer */
		psEnc->sCmn.nFramesInPayloadBuf = 0;
	} else {
		psEnc->sCmn.nFramesInPayloadBuf++;
	}

    /****************************************/
	/* finalize payload and copy to output  */
    /****************************************/
	if (psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >=
	    psEnc->sCmn.PacketSize_ms) {

		LBRR_idx = (psEnc->sCmn.oldest_LBRR_idx + 1) & LBRR_IDX_MASK;

		/* Check if FEC information should be added */
		frame_terminator = SKP_SILK_LAST_FRAME;
		if (psEnc->sCmn.LBRR_buffer[LBRR_idx].usage ==
		    SKP_SILK_ADD_LBRR_TO_PLUS1) {
			frame_terminator = SKP_SILK_LBRR_VER1;
		}
		if (psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx].
		    usage == SKP_SILK_ADD_LBRR_TO_PLUS2) {
			frame_terminator = SKP_SILK_LBRR_VER2;
			LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;
		}
		/* Add the frame termination info to stream */
		SKP_Silk_range_encoder(&psEnc->sCmn.sRC, frame_terminator,
				       FrameTermination_CDF);

		if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) {
			/* Code excitation signal */
			for (i = 0; i < psEnc->sCmn.nFramesInPayloadBuf; i++) {
				SKP_Silk_encode_pulses(&psEnc->sCmn.sRC,
						       psEnc->sCmn.sigtype[i],
						       psEnc->sCmn.
						       QuantOffsetType[i],
						       &psEnc->sCmn.q[i *
								      psEnc->
								      sCmn.
								      frame_length],
						       psEnc->sCmn.
						       frame_length);
			}
		}
		/* payload length so far */
		SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC, &nBytes);

		/* check that there is enough space in external output buffer, and move data */
		if (*pnBytesOut >= nBytes) {
			SKP_Silk_range_enc_wrap_up(&psEnc->sCmn.sRC);
			SKP_memcpy(pCode, psEnc->sCmn.sRC.buffer,
				   nBytes * sizeof(uint8_t));

			if (frame_terminator > SKP_SILK_MORE_FRAMES &&
			    *pnBytesOut >=
			    nBytes + psEnc->sCmn.LBRR_buffer[LBRR_idx].nBytes) {
				/* Get old packet and add to payload. */
				SKP_memcpy(&pCode[nBytes],
					   psEnc->sCmn.LBRR_buffer[LBRR_idx].
					   payload,
					   psEnc->sCmn.LBRR_buffer[LBRR_idx].
					   nBytes * sizeof(uint8_t));
				nBytes +=
				    psEnc->sCmn.LBRR_buffer[LBRR_idx].nBytes;
			}

			*pnBytesOut = nBytes;

			/* Update FEC buffer */
			SKP_memcpy(psEnc->sCmn.
				   LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx].
				   payload, LBRRpayload,
				   nBytesLBRR * sizeof(uint8_t));
			psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx].
			    nBytes = nBytesLBRR;
			/* This line tells describes how FEC should be used */
			psEnc->sCmn.LBRR_buffer[psEnc->sCmn.oldest_LBRR_idx].
			    usage = sEncCtrl.sCmn.LBRR_usage;
			psEnc->sCmn.oldest_LBRR_idx =
			    (psEnc->sCmn.oldest_LBRR_idx + 1) & LBRR_IDX_MASK;

			/* Reset number of frames in payload buffer */
			psEnc->sCmn.nFramesInPayloadBuf = 0;
		} else {
			/* Not enough space: Payload will be discarded */
			*pnBytesOut = 0;
			nBytes = 0;
			psEnc->sCmn.nFramesInPayloadBuf = 0;
			ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;
		}
	} else {
		/* no payload for you this time */
		*pnBytesOut = 0;

		/* Encode that more frames follows */
		frame_terminator = SKP_SILK_MORE_FRAMES;
		SKP_Silk_range_encoder(&psEnc->sCmn.sRC, frame_terminator,
				       FrameTermination_CDF);

		/* payload length so far */
		SKP_Silk_range_coder_get_length(&psEnc->sCmn.sRC, &nBytes);

		if (psEnc->sCmn.bitstream_v == BIT_STREAM_V4) {
			/* Take into account the q signal that isnt in the bitstream yet */
			nBytes += SKP_Silk_pulses_to_bytes(&psEnc->sCmn,
							   &psEnc->sCmn.
							   q[(psEnc->sCmn.
							      nFramesInPayloadBuf
							      -
							      1) *
							     psEnc->sCmn.
							     frame_length]);
		}
	}

	/* Check for arithmetic coder errors */
	if (psEnc->sCmn.sRC.error) {
		ret = SKP_SILK_ENC_INTERNAL_ERROR;
	}

	/* simulate number of ms buffered in channel because of exceeding TargetRate */
	assert((8 * 1000 *
		    ((int64_t) nBytes -
		     (int64_t) psEnc->sCmn.nBytesInPayloadBuf)) ==
		   SKP_SAT32(8 * 1000 *
			     ((int64_t) nBytes -
			      (int64_t) psEnc->sCmn.nBytesInPayloadBuf)));
	assert(psEnc->sCmn.TargetRate_bps > 0);
	psEnc->BufferedInChannel_ms +=
	    SKP_DIV32(8 * 1000 * (nBytes - psEnc->sCmn.nBytesInPayloadBuf),
		      psEnc->sCmn.TargetRate_bps);
	psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS;
	psEnc->BufferedInChannel_ms =
	    SKP_LIMIT(psEnc->BufferedInChannel_ms, 0, 100);
	psEnc->sCmn.nBytesInPayloadBuf = nBytes;

	if (psEnc->speech_activity_Q8 > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES_Q8) {
		psEnc->sCmn.sSWBdetect.ActiveSpeech_ms =
		    SKP_ADD_POS_SAT32(psEnc->sCmn.sSWBdetect.ActiveSpeech_ms,
				      FRAME_LENGTH_MS);
	}

	return (ret);
}
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
void SKP_Silk_HP_variable_cutoff_FIX(
    SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O  Encoder state FIX                           */
    SKP_Silk_encoder_control_FIX    *psEncCtrl,         /* I/O  Encoder control FIX                         */
    SKP_int16                       *out,               /* O    high-pass filtered output signal            */
    const SKP_int16                 *in                 /* I    input signal                                */
)
{
    SKP_int   quality_Q15;
    SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ];
    SKP_int32 Fc_Q19, r_Q28, r_Q22;
    SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;

    /*********************************************/
    /* Estimate Low End of Pitch Frequency Range */
    /*********************************************/
    if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) {
        /* difference, in log domain */
        pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag );
        pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70

        /* adjustment based on quality */
        quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ];
        pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ),
            pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) );
        pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( 19661 - quality_Q15, 9 ) ); // 19661_Q15 = 0.6_Q0

        //delta_freq = pitch_freq_log - psEnc->variable_HP_smth1;
        delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 );
        if( delta_freq_Q7 < 0 ) {
            /* less smoothing for decreasing pitch frequency, to track something close to the minimum */
            delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 );
        }

        /* limit delta, to reduce impact of outliers */
        delta_freq_Q7 = SKP_LIMIT( delta_freq_Q7, -VARIABLE_HP_MAX_DELTA_FREQ_Q7, VARIABLE_HP_MAX_DELTA_FREQ_Q7 );

        /* update smoother */
        psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15,
            SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), VARIABLE_HP_SMTH_COEF1_Q16 );
    }
    /* second smoother */
    psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15,
        psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, VARIABLE_HP_SMTH_COEF2_Q16 );

    /* convert from log scale to Hertz */
    psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) ); //pow( 2.0, psEnc->variable_HP_smth2 );

    /* limit frequency range */
    psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT( psEncCtrl->pitch_freq_low_Hz, VARIABLE_HP_MIN_FREQ_Q0, VARIABLE_HP_MAX_FREQ_Q0 );

    /********************************/
    /* Compute Filter Coefficients  */
    /********************************/
    /* compute cut-off frequency, in radians */
    //Fc_num   = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz );
    //Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz );
    SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 );
    Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits
    SKP_assert( Fc_Q19 >=  3704 );
    SKP_assert( Fc_Q19 <= 27787 );

    r_Q28 = ( 1 << 28 ) - SKP_MUL( 471, Fc_Q19 ); // 471_Q9 = 0.92_Q0, range: 255347779 to 266690872, 27-28 bits
    SKP_assert( r_Q28 >= 255347779 );
    SKP_assert( r_Q28 <= 266690872 );

    /* b = r * [ 1; -2; 1 ]; */
    /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
    B_Q28[ 0 ] = r_Q28;
    B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 );
    B_Q28[ 2 ] = r_Q28;

    // -r * ( 2 - Fc * Fc );
    r_Q22  = SKP_RSHIFT( r_Q28, 6 );
    A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - ( 2 << 22 ) );
    A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 );

    /********************************/
    /* High-Pass Filter             */
    /********************************/
    SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length );
}
Exemplo n.º 10
0
void SKP_Silk_NSQ_wrapper_FLP(
    SKP_Silk_encoder_state_FLP      *psEnc,         /* I/O  Encoder state FLP                           */
    SKP_Silk_encoder_control_FLP    *psEncCtrl,     /* I/O  Encoder control FLP                         */
    const SKP_float                 x[],            /* I    Prefiltered input signal                    */
          SKP_int8                  q[],            /* O    Quantized pulse signal                      */
    const SKP_int                   useLBRR         /* I    LBRR flag                                   */
)
{
    SKP_int     i, j;
    SKP_float   tmp_float;
    SKP_int16   x_16[ MAX_FRAME_LENGTH ];
    /* Prediction and coding parameters */
    SKP_int32   Gains_Q16[ NB_SUBFR ];
    SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
    SKP_int16   LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ];
    SKP_int     LTP_scale_Q14;

    /* Noise shaping parameters */
    /* Testing */
    SKP_int16   AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
    SKP_int32   LF_shp_Q14[ NB_SUBFR ];         /* Packs two int16 coefficients per int32 value             */
    SKP_int     Lambda_Q10;
    SKP_int     Tilt_Q14[ NB_SUBFR ];
    SKP_int     HarmShapeGain_Q14[ NB_SUBFR ];

    /* Convert control struct to fix control struct */
    /* Noise shape parameters */
    for( i = 0; i < NB_SUBFR * MAX_SHAPE_LPC_ORDER; i++ ) {
        AR2_Q13[ i ] = SKP_float2int( psEncCtrl->AR2[ i ] * 8192.0f );
    }

    for( i = 0; i < NB_SUBFR; i++ ) {
        LF_shp_Q14[ i ] =   SKP_LSHIFT32( SKP_float2int( psEncCtrl->LF_AR_shp[ i ]     * 16384.0f ), 16 ) |
                              (SKP_uint16)SKP_float2int( psEncCtrl->LF_MA_shp[ i ]     * 16384.0f );
        Tilt_Q14[ i ]   =        (SKP_int)SKP_float2int( psEncCtrl->Tilt[ i ]          * 16384.0f );
        HarmShapeGain_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f );    
    }
    Lambda_Q10 = ( SKP_int )SKP_float2int( psEncCtrl->Lambda * 1024.0f );

    /* prediction and coding parameters */
    for( i = 0; i < NB_SUBFR * LTP_ORDER; i++ ) {
        LTPCoef_Q14[ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );
    }

    for( j = 0; j < NB_SUBFR >> 1; j++ ) {
        for( i = 0; i < MAX_LPC_ORDER; i++ ) {
            PredCoef_Q12[ j ][ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );
        }
    }

    for( i = 0; i < NB_SUBFR; i++ ) {
        tmp_float = SKP_LIMIT( ( psEncCtrl->Gains[ i ] * 65536.0f ), 2147483000.0f, -2147483000.0f );
        Gains_Q16[ i ] = SKP_float2int( tmp_float );
        if( psEncCtrl->Gains[ i ] > 0.0f ) {
            SKP_assert( tmp_float >= 0.0f );
            SKP_assert( Gains_Q16[ i ] >= 0 );
        }
    }

    if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
        LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ];
    } else {
        LTP_scale_Q14 = 0;
    }

    /* Convert input to fix */
    SKP_float2short_array( x_16, x, psEnc->sCmn.frame_length );

    /* Call NSQ */
    if( useLBRR ) {
        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
            SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, 
                x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, 
                HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 );
        } else {
            SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, 
                x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, 
                HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 );
        }
    } else {
        if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
            SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ, 
                x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, 
                HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 );
        } else {
            SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ, 
                x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, 
                HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 );
        }
    }
}
Exemplo n.º 11
0
static SKP_int process_enc_control_struct( 
    SKP_Silk_encoder_state_Fxx          *psEnc,         /* I/O: State                                           */
    SKP_Silk_EncodeControlStruct        *encControl     /* I:   Control structure                               */
)
{
    SKP_int   max_internal_fs_kHz, min_internal_fs_kHz, Complexity, PacketSize_ms, PacketLoss_perc, UseInBandFEC, ret = SKP_SILK_NO_ERROR;
    SKP_int32 TargetRate_bps, API_fs_Hz;

    SKP_assert( encControl != NULL );

    /* Check sampling frequency first, to avoid divide by zero later */
    if( ( ( encControl->API_sampleRate        !=  8000 ) &&
          ( encControl->API_sampleRate        != 12000 ) &&
          ( encControl->API_sampleRate        != 16000 ) &&
          ( encControl->API_sampleRate        != 24000 ) && 
          ( encControl->API_sampleRate        != 32000 ) &&
          ( encControl->API_sampleRate        != 44100 ) &&
          ( encControl->API_sampleRate        != 48000 ) ) ||
        ( ( encControl->maxInternalSampleRate !=  8000 ) &&
          ( encControl->maxInternalSampleRate != 12000 ) &&
          ( encControl->maxInternalSampleRate != 16000 ) ) ||
        ( ( encControl->minInternalSampleRate !=  8000 ) &&
          ( encControl->minInternalSampleRate != 12000 ) &&
          ( encControl->minInternalSampleRate != 16000 ) ) ||
          ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
        ret = SKP_SILK_ENC_FS_NOT_SUPPORTED;
        SKP_assert( 0 );
        return( ret );
    }
    if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
        ret = SKP_SILK_ENC_INVALID_DTX_SETTING;
    }
	if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
        ret = SKP_SILK_ENC_INVALID_CBR_SETTING;
    }

    /* Set encoder parameters from control structure */
    API_fs_Hz           =            encControl->API_sampleRate;
    max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1;   /* convert Hz -> kHz */
    min_internal_fs_kHz = (SKP_int)( encControl->minInternalSampleRate >> 10 ) + 1;   /* convert Hz -> kHz */
    PacketSize_ms       =            encControl->payloadSize_ms;
    TargetRate_bps      =            encControl->bitRate;
    PacketLoss_perc     =            encControl->packetLossPercentage;
    UseInBandFEC        =            encControl->useInBandFEC;
    Complexity          =            encControl->complexity;
    psEnc->sCmn.useDTX  =            encControl->useDTX;
	psEnc->sCmn.useCBR  =			 encControl->useCBR;

    /* Save values in state */
    psEnc->sCmn.API_fs_Hz          = API_fs_Hz;
    psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz;
    psEnc->sCmn.minInternal_fs_kHz = min_internal_fs_kHz;
    psEnc->sCmn.useInBandFEC       = UseInBandFEC;

    TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
    if( ( ret = SKP_Silk_control_encoder_Fxx( psEnc, PacketSize_ms, TargetRate_bps, 
                        PacketLoss_perc, Complexity) ) != 0 ) {
        SKP_assert( 0 );
        return( ret );
    }

    encControl->internalSampleRate = SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 );
    
    return ret;
}
void SKP_Silk_find_pred_coefs_FIX(SKP_Silk_encoder_state_FIX * psEnc,	/* I/O  encoder state                               */
				  SKP_Silk_encoder_control_FIX * psEncCtrl,	/* I/O  encoder control                             */
				  const int16_t res_pitch[]	/* I    Residual from pitch analysis                */
    )
{
	int i;
	int32_t WLTP[NB_SUBFR * LTP_ORDER * LTP_ORDER];
	int32_t invGains_Q16[NB_SUBFR], local_gains_Qx[NB_SUBFR],
	    Wght_Q15[NB_SUBFR];
	int NLSF_Q15[MAX_LPC_ORDER];
	const int16_t *x_ptr;
	int16_t *x_pre_ptr,
	    LPC_in_pre[NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH];

	int32_t tmp, min_gain_Q16;
#if !VARQ
	int LZ;
#endif
	int LTP_corrs_rshift[NB_SUBFR];

	/* weighting for weighted least squares */
	min_gain_Q16 = int32_t_MAX >> 6;
	for (i = 0; i < NB_SUBFR; i++) {
		min_gain_Q16 = SKP_min(min_gain_Q16, psEncCtrl->Gains_Q16[i]);
	}
#if !VARQ
	LZ = SKP_Silk_CLZ32(min_gain_Q16) - 1;
	LZ = SKP_LIMIT(LZ, 0, 16);
	min_gain_Q16 = SKP_RSHIFT(min_gain_Q16, 2);	/* Ensure that maximum invGains_Q16 is within range of a 16 bit int */
#endif
	for (i = 0; i < NB_SUBFR; i++) {
		/* Divide to Q16 */
		assert(psEncCtrl->Gains_Q16[i] > 0);
#if VARQ
		/* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
		invGains_Q16[i] =
		    SKP_DIV32_varQ(min_gain_Q16, psEncCtrl->Gains_Q16[i],
				   16 - 2);
#else
		invGains_Q16[i] =
		    SKP_DIV32(SKP_LSHIFT(min_gain_Q16, LZ),
			      SKP_RSHIFT(psEncCtrl->Gains_Q16[i], 16 - LZ));
#endif

		/* Ensure Wght_Q15 a minimum value 1 */
		invGains_Q16[i] = SKP_max(invGains_Q16[i], 363);

		/* Square the inverted gains */
		assert(invGains_Q16[i] == SKP_SAT16(invGains_Q16[i]));
		tmp = SKP_SMULWB(invGains_Q16[i], invGains_Q16[i]);
		Wght_Q15[i] = SKP_RSHIFT(tmp, 1);

		/* Invert the inverted and normalized gains */
		local_gains_Qx[i] =
		    SKP_DIV32((1 << (16 + Qx)), invGains_Q16[i]);
	}

	if (psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED) {
	/**********/
		/* VOICED */
	/**********/
		assert(psEnc->sCmn.frame_length -
			   psEnc->sCmn.predictLPCOrder >=
			   psEncCtrl->sCmn.pitchL[0] + LTP_ORDER / 2);

		/* LTP analysis */
		SKP_Silk_find_LTP_FIX(psEncCtrl->LTPCoef_Q14, WLTP,
				      &psEncCtrl->LTPredCodGain_Q7, res_pitch,
				      res_pitch +
				      SKP_RSHIFT(psEnc->sCmn.frame_length, 1),
				      psEncCtrl->sCmn.pitchL, Wght_Q15,
				      psEnc->sCmn.subfr_length,
				      psEnc->sCmn.frame_length,
				      LTP_corrs_rshift);

		/* Quantize LTP gain parameters */
		SKP_Silk_quant_LTP_gains_FIX(psEncCtrl->LTPCoef_Q14,
					     psEncCtrl->sCmn.LTPIndex,
					     &psEncCtrl->sCmn.PERIndex, WLTP,
					     psEnc->mu_LTP_Q8,
					     psEnc->sCmn.LTPQuantLowComplexity);

		/* Control LTP scaling */
		SKP_Silk_LTP_scale_ctrl_FIX(psEnc, psEncCtrl);

		/* Create LTP residual */
		SKP_Silk_LTP_analysis_filter_FIX(LPC_in_pre,
						 psEnc->x_buf +
						 psEnc->sCmn.frame_length -
						 psEnc->sCmn.predictLPCOrder,
						 psEncCtrl->LTPCoef_Q14,
						 psEncCtrl->sCmn.pitchL,
						 invGains_Q16, 16,
						 psEnc->sCmn.subfr_length,
						 psEnc->sCmn.predictLPCOrder);

	} else {
	/************/
		/* UNVOICED */
	/************/
		/* Create signal with prepended subframes, scaled by inverse gains */
		x_ptr =
		    psEnc->x_buf + psEnc->sCmn.frame_length -
		    psEnc->sCmn.predictLPCOrder;
		x_pre_ptr = LPC_in_pre;
		for (i = 0; i < NB_SUBFR; i++) {
			SKP_Silk_scale_copy_vector16(x_pre_ptr, x_ptr,
						     invGains_Q16[i],
						     psEnc->sCmn.subfr_length +
						     psEnc->sCmn.
						     predictLPCOrder);
			x_pre_ptr +=
			    psEnc->sCmn.subfr_length +
			    psEnc->sCmn.predictLPCOrder;
			x_ptr += psEnc->sCmn.subfr_length;
		}

		SKP_memset(psEncCtrl->LTPCoef_Q14, 0,
			   NB_SUBFR * LTP_ORDER * sizeof(int16_t));
		psEncCtrl->LTPredCodGain_Q7 = 0;
	}

	/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
	TIC(FIND_LPC)
	    SKP_Silk_find_LPC_FIX(NLSF_Q15, &psEncCtrl->sCmn.NLSFInterpCoef_Q2,
				  psEnc->sPred.prev_NLSFq_Q15,
				  psEnc->sCmn.useInterpolatedNLSFs * (1 -
								      psEnc->
								      sCmn.
								      first_frame_after_reset),
				  psEnc->sCmn.predictLPCOrder, LPC_in_pre,
				  psEnc->sCmn.subfr_length +
				  psEnc->sCmn.predictLPCOrder);
	TOC(FIND_LPC)

	    /* Quantize LSFs */
	    TIC(PROCESS_LSFS)
	    SKP_Silk_process_NLSFs_FIX(psEnc, psEncCtrl, NLSF_Q15);
	TOC(PROCESS_LSFS)

	    /* Calculate residual energy using quantized LPC coefficients */
	    SKP_Silk_residual_energy_FIX(psEncCtrl->ResNrg, psEncCtrl->ResNrgQ,
					 LPC_in_pre, (const int16_t(*)[])psEncCtrl->PredCoef_Q12,
					 local_gains_Qx, Qx,
					 psEnc->sCmn.subfr_length,
					 psEnc->sCmn.predictLPCOrder);

	/* Copy to prediction struct for use in next frame for fluctuation reduction */
	SKP_memcpy(psEnc->sPred.prev_NLSFq_Q15, NLSF_Q15,
		   psEnc->sCmn.predictLPCOrder * sizeof(int));

}