Пример #1
0
/* Can handle slowly varying filter coefficients */
void SKP_Silk_biquad(
    const SKP_int16      *in,        /* I:    input signal               */
    const SKP_int16      *B,         /* I:    MA coefficients, Q13 [3]   */
    const SKP_int16      *A,         /* I:    AR coefficients, Q13 [2]   */
    SKP_int32            *S,         /* I/O:  state vector [2]           */
    SKP_int16            *out,       /* O:    output signal              */
    const SKP_int32      len         /* I:    signal length              */
)
{
    SKP_int   k, in16;
    SKP_int32 A0_neg, A1_neg, S0, S1, out32, tmp32;

    S0 = S[ 0 ];
    S1 = S[ 1 ];
    A0_neg = -A[ 0 ];
    A1_neg = -A[ 1 ];
    for( k = 0; k < len; k++ ) {
        /* S[ 0 ], S[ 1 ]: Q13 */
        in16  = in[ k ];
        out32 = SKP_SMLABB( S0, in16, B[ 0 ] );

        S0 = SKP_SMLABB( S1, in16, B[ 1 ] );
        S0 += SKP_LSHIFT( SKP_SMULWB( out32, A0_neg ), 3 );

        S1 = SKP_LSHIFT( SKP_SMULWB( out32, A1_neg ), 3 );
        S1 = SKP_SMLABB( S1, in16, B[ 2 ] );
        tmp32    = SKP_RSHIFT_ROUND( out32, 13 ) + 1;
        out[ k ] = (SKP_int16)SKP_SAT16( tmp32 );
    }
    S[ 0 ] = S0;
    S[ 1 ] = S1;
}
Пример #2
0
/* helper function for NLSF2A(..) */
static inline void SKP_Silk_NLSF2A_find_poly(int32_t * out,	/* o    intermediate polynomial, Q20            */
					  const int32_t * cLSF,	/* i    vector of interleaved 2*cos(LSFs), Q20  */
					  int dd	/* i    polynomial order (= 1/2 * filter order) */
    )
{
	int k, n;
	int32_t ftmp;

	out[0] = SKP_LSHIFT(1, 20);
	out[1] = -cLSF[0];
	for (k = 1; k < dd; k++) {
		ftmp = cLSF[2 * k];	// Q20
		out[k + 1] =
		    SKP_LSHIFT(out[k - 1],
			       1) - (int32_t) SKP_RSHIFT_ROUND64(SKP_SMULL(ftmp,
									   out
									   [k]),
								 20);
		for (n = k; n > 1; n--) {
			out[n] +=
			    out[n - 2] -
			    (int32_t)
			    SKP_RSHIFT_ROUND64(SKP_SMULL(ftmp, out[n - 1]), 20);
		}
		out[1] -= ftmp;
	}
}
Пример #3
0
/* Split signal into two decimated bands using first-order allpass filters */
void SKP_Silk_ana_filt_bank_1(const int16_t * in,	/* I:    Input signal [N]       */
			      int32_t * S,	/* I/O: State vector [2]        */
			      int16_t * outL,	/* O:    Low band [N/2]         */
			      int16_t * outH,	/* O:    High band [N/2]        */
			      int32_t * scratch,	/* I:    Scratch memory [3*N/2] */
			      const int32_t N	/* I:   Number of input samples */
    )
{
	int k, N2 = SKP_RSHIFT(N, 1);
	int32_t out_tmp;

	/* De-interleave three allpass inputs, and convert Q15 -> Q25 */
	for (k = 0; k < N2; k++) {
		scratch[k + N] = SKP_LSHIFT((int32_t) in[2 * k], 10);
		scratch[k + N2] = SKP_LSHIFT((int32_t) in[2 * k + 1], 10);
	}

	/* Allpass filters */
	SKP_Silk_allpass_int(scratch + N2, S + 0, A_fb1_20[0], scratch, N2);
	SKP_Silk_allpass_int(scratch + N, S + 1, A_fb1_21[0], scratch + N2, N2);

	/* Add and subtract two allpass outputs to create bands */
	for (k = 0; k < N2; k++) {
		out_tmp = scratch[k] + scratch[k + N2];
		outL[k] = (int16_t) SKP_SAT16(SKP_RSHIFT_ROUND(out_tmp, 11));

		out_tmp = scratch[k] - scratch[k + N2];
		outH[k] = (int16_t) SKP_SAT16(SKP_RSHIFT_ROUND(out_tmp, 11));
	}
}
/* Downsample by a factor 2, coarsest */
void SKP_Silk_resample_1_2_coarsest(
    const SKP_int16     *in,                /* I:   16 kHz signal [2*len]   */
    SKP_int32           *S,                 /* I/O: State vector [2]        */
    SKP_int16           *out,               /* O:   8 kHz signal [len]      */
    SKP_int32           *scratch,           /* I:   Scratch memory [3*len]  */
    const SKP_int32     len                 /* I:   Number of OUTPUT samples*/
)
{
    SKP_int32 k, idx;

    /* De-interleave allpass inputs, and convert Q15 -> Q25 */
    for( k = 0; k < len; k++ ) {
        idx = SKP_LSHIFT( k, 1 );
        scratch[ k ]       = SKP_LSHIFT( (SKP_int32)in[ idx     ], 10 );
        scratch[ k + len ] = SKP_LSHIFT( (SKP_int32)in[ idx + 1 ], 10 );
    }

    idx = SKP_LSHIFT( len, 1 );
    /* Allpass filters */
    SKP_Silk_allpass_int( scratch,       S,     A21cst[ 0 ], scratch + idx, len );
    SKP_Silk_allpass_int( scratch + len, S + 1, A20cst[ 0 ], scratch,       len );

    /* Add two allpass outputs */
    for( k = 0; k < len; k++ ) {
        out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( scratch[ k ] + scratch[ k + idx ], 11 ) );
    }
}
/* Upsample by a factor 2, coarser */
void SKP_Silk_resample_2_1_coarse(
    const SKP_int16      *in,            /* I:   8 kHz signal [len]      */
    SKP_int32            *S,             /* I/O: State vector [4]        */
    SKP_int16            *out,           /* O:   16 kHz signal [2*len]   */
    SKP_int32            *scratch,       /* I:   Scratch memory [3*len]  */
    const SKP_int32      len             /* I:   Number of INPUT samples */
)
{
    SKP_int32 k, idx;
    
    /* Coefficients for coarser 2-fold resampling */
    const SKP_int16 A20c[ 2 ] = { 2119, 16663 };
    const SKP_int16 A21c[ 2 ] = { 8050, 26861 };

    /* Convert Q15 -> Q25 */
    for( k = 0; k < len; k++ ) {
        scratch[ k ] = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
    }
       
    idx = SKP_LSHIFT( len, 1 );
    
    /* Allpass filters */
    SKP_Silk_allpass_int( scratch,       S,     A20c[ 0 ], scratch + idx, len );
    SKP_Silk_allpass_int( scratch + idx, S + 1, A20c[ 1 ], scratch + len, len );

    SKP_Silk_allpass_int( scratch,       S + 2, A21c[ 0 ], scratch + idx, len );
    SKP_Silk_allpass_int( scratch + idx, S + 3, A21c[ 1 ], scratch,       len );

    /* Interleave two allpass outputs */
    for( k = 0; k < len; k++ ) {
        idx = SKP_LSHIFT( k, 1 );
        out[ idx     ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( scratch[ k + len ], 10 ) );
        out[ idx + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( scratch[ k ],       10 ) );
    }
}
Пример #6
0
void SKP_Silk_MA_Prediction_Q13(
    const SKP_int16      *in,            /* I:   input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q13 [order]     */
    SKP_int32            *S,             /* I/O: state vector [order]                        */
    SKP_int16            *out,           /* O:   output signal                               */
    SKP_int32            len,            /* I:   signal length                               */
    SKP_int32            order           /* I:   filter order                                */
)
{
	SKP_int   k, in16;
	SKP_int32 out32;

	switch(order) {
	case 8:
		for( k = 0; k < len; k++ ) {
			in16 = in[ k ];
			out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];
			out32 = SKP_RSHIFT_ROUND( out32, 13 );
			FILTER_LOOP_ORDER_8(S, B, in16);
			out[ k ] = (SKP_int16) SKP_SAT16(out32);
		}
		break;
	case 10:
		for( k = 0; k < len; k++ ) {
			in16 = in[ k ];
			out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];
			out32 = SKP_RSHIFT_ROUND( out32, 13 );
			FILTER_LOOP_ORDER_10(S, B, in16);
			out[ k ] = (SKP_int16) SKP_SAT16(out32);
		}
		break;
	case 12:
		for( k = 0; k < len; k++ ) {
			in16 = in[ k ];
			out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];
			out32 = SKP_RSHIFT_ROUND( out32, 13 );
			FILTER_LOOP_ORDER_12(S, B, in16);
			out[ k ] = (SKP_int16) SKP_SAT16(out32);
		}
		break;
	case 16:
		for( k = 0; k < len; k++ ) {
			in16 = in[ k ];
			out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];
			out32 = SKP_RSHIFT_ROUND( out32, 13 );
			FILTER_LOOP_ORDER_16(S, B, in16);
			out[ k ] = (SKP_int16) SKP_SAT16(out32);
		}
		break;
	default:
		for( k = 0; k < len; k++ ) {
			in16 = in[ k ];
			out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];
			out32 = SKP_RSHIFT_ROUND( out32, 13 );
			FILTER_LOOP_ORDER_ANY(S, B, in16, order);
			out[ k ] = (SKP_int16) SKP_SAT16(out32);
		}
	}
}
Пример #7
0
/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
void SKP_Silk_LPC_analysis_filter(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int16            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      Order           /* I:   Filter order                                */
)
{
    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
    SKP_int32 Btmp, B_align_Q12[ SigProc_MAX_ORDER_LPC >> 1 ], out32_Q12, out32;
    SKP_int16 SA, SB;
    /* Order must be even */
    SKP_assert( 2 * Order_half == Order );

    /* Combine two A_Q12 values and ensure 32-bit alignment */
    for( k = 0; k < Order_half; k++ ) {
        idx = SKP_SMULBB( 2, k );
        B_align_Q12[ k ] = ( ( (SKP_int32)B[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( (SKP_int32)B[ idx + 1 ], 16 );
    }

    /* S[] values are in Q0 */
    for( k = 0; k < len; k++ ) {
        SA = S[ 0 ];
        out32_Q12 = 0;
        for( j = 0; j < ( Order_half - 1 ); j++ ) {
            idx = SKP_SMULBB( 2, j ) + 1;
            /* Multiply-add two prediction coefficients for each loop */
            Btmp = B_align_Q12[ j ];
            SB = S[ idx ];
            S[ idx ] = SA;
            out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );
            out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );
            SA = S[ idx + 1 ];
            S[ idx + 1 ] = SB;
        }

        /* Unrolled loop: epilog */
        Btmp = B_align_Q12[ Order_half - 1 ];
        SB = S[ Order - 1 ];
        S[ Order - 1 ] = SA;
        out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );
        out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );

        /* Subtract prediction */
        out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );

        /* Scale to Q0 */
        out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );

        /* Saturate output */
        out[ k ] = (SKP_int16)SKP_SAT16( out32 );

        /* Move input line */
        S[ 0 ] = in[ k ];
    }
}
Пример #8
0
/* every other sample of window is linearly interpolated, for speed         */
void SKP_Silk_apply_sine_window(
    SKP_int16                        px_win[],            /* O    Pointer to windowed signal                  */
    const SKP_int16                  px[],                /* I    Pointer to input signal                     */
    const SKP_int                    win_type,            /* I    Selects a window type                       */
    const SKP_int                    length               /* I    Window length, multiple of 4                */
)
{
    SKP_int   k;
    SKP_int32 f_Q16, c_Q20, S0_Q16, S1_Q16;
    /* Length must be multiple of 4 */
    SKP_assert( ( length & 3 ) == 0 );

    /* Input pointer must be 4-byte aligned */
    SKP_assert( ( (SKP_int64)px & 3 ) == 0 );

    if( win_type == 0 ) {
        f_Q16 = SKP_DIV32_16( 411775, length + 1 );        // 411775 = 2 * 65536 * pi
    } else {
        f_Q16 = SKP_DIV32_16( 205887, length + 1 );        // 205887 = 65536 * pi
    }

    /* factor used for cosine approximation */
    c_Q20 = -SKP_RSHIFT( SKP_MUL( f_Q16, f_Q16 ), 12 );

    /* c_Q20 becomes too large if length is too small */
    SKP_assert( c_Q20 >= -32768 );

    /* initialize state */
    if( win_type < 2 ) {
        /* start from 0 */
        S0_Q16 = 0;
        /* approximation of sin(f) */
        S1_Q16 = f_Q16;
    } else {
        /* start from 1 */
        S0_Q16 = ( 1 << 16 );
        /* approximation of cos(f) */
        S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q20, 5 );
    }


    /* Uses the recursive equation:   sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f)    */
    /* 4 samples at a time */
    for( k = 0; k < length; k += 4 ) {
        px_win[ k ]     = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
        px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] );
        S0_Q16 = SKP_RSHIFT( SKP_MUL( c_Q20, S1_Q16 ), 20 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
        S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) );

        px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
        px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] );
        S1_Q16 = SKP_RSHIFT( SKP_MUL( c_Q20, S0_Q16 ), 20 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16;
        S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) );
    }
}
Пример #9
0
/* uses SMLAWB(), requiring armv5E and higher.                          */ 
SKP_int32 SKP_Silk_schur(                     /* O:    Returns residual energy                     */
    SKP_int16            *rc_Q15,               /* O:    reflection coefficients [order] Q15         */
    const SKP_int32      *c,                    /* I:    correlations [order+1]                      */
    const SKP_int32      order                  /* I:    prediction order                            */
)
{
    SKP_int        k, n, lz;
    SKP_int32    C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ];
    SKP_int32    Ctmp1, Ctmp2, rc_tmp_Q15;

    /* Get number of leading zeros */
    lz = SKP_Silk_CLZ32( c[ 0 ] );

    /* Copy correlations and adjust level to Q30 */
    if( lz < 2 ) {
        /* lz must be 1, so shift one to the right */
        for( k = 0; k < order + 1; k++ ) {
            C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_RSHIFT( c[ k ], 1 );
        }
    } else if( lz > 2 ) {
        /* Shift to the left */
        lz -= 2; 
        for( k = 0; k < order + 1; k++ ) {
            C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_LSHIFT( c[k], lz );
        }
    } else {
        /* No need to shift */
        for( k = 0; k < order + 1; k++ ) {
            C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
        }
    }

    for( k = 0; k < order; k++ ) {
        
        /* Get reflection coefficient */
        rc_tmp_Q15 = -SKP_DIV32_16( C[ k + 1 ][ 0 ], SKP_max_32( SKP_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );

        /* Clip (shouldn't happen for properly conditioned inputs) */
        rc_tmp_Q15 = SKP_SAT16( rc_tmp_Q15 );

        /* Store */
        rc_Q15[ k ] = (SKP_int16)rc_tmp_Q15;

        /* Update correlations */
        for( n = 0; n < order - k; n++ ) {
            Ctmp1 = C[ n + k + 1 ][ 0 ];
            Ctmp2 = C[ n ][ 1 ];
            C[ n + k + 1 ][ 0 ] = SKP_SMLAWB( Ctmp1, SKP_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
            C[ n ][ 1 ]         = SKP_SMLAWB( Ctmp2, SKP_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
        }
    }

    /* return residual energy */
    return C[0][1];
}
Пример #10
0
/* Variable order MA prediction error filter */
void SKP_Silk_MA_Prediction(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int32            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      order           /* I:   Filter order                                */
)
{
    SKP_int   k, d, in16;
    SKP_int32 out32;
    SKP_int32 B32;

    if( ( order & 1 ) == 0 && (SKP_int32)( (SKP_int_ptr_size)B & 3 ) == 0 ) {
        /* Even order and 4-byte aligned coefficient array */

        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the    */
        /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be      */
        /* loaded in reverse order and the code will give the wrong result. In that case swapping    */
        /* the SMLABB and SMLABT instructions should solve the problem.                              */
        for( k = 0; k < len; k++ ) {
            in16 = in[ k ];
            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
            out32 = SKP_RSHIFT_ROUND( out32, 12 );
            
            for( d = 0; d < order - 2; d += 2 ) {
                B32 = *( (SKP_int32*)&B[ d ] );                /* read two coefficients at once */
                S[ d ]     = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B32 );
                S[ d + 1 ] = SKP_SMLABT_ovflw( S[ d + 2 ], in16, B32 );
            }
            B32 = *( (SKP_int32*)&B[ d ] );                    /* read two coefficients at once */
            S[ order - 2 ] = SKP_SMLABB_ovflw( S[ order - 1 ], in16, B32 );
            S[ order - 1 ] = SKP_SMULBT( in16, B32 );

            /* Limit */
            out[ k ] = (SKP_int16)SKP_SAT16( out32 );
        }
    } else {
        /* Odd order or not 4-byte aligned coefficient array */
        for( k = 0; k < len; k++ ) {
            in16 = in[ k ];
            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
            out32 = SKP_RSHIFT_ROUND( out32, 12 );
            
            for( d = 0; d < order - 1; d++ ) {
                S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
            }
            S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );

            /* Limit */
            out[ k ] = (SKP_int16)SKP_SAT16( out32 );
        }
    }
}
/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal                           */
SKP_INLINE void SKP_Silk_prefilt_FIX(
    SKP_Silk_prefilter_state_FIX *P,                    /* I/O state                          */
    SKP_int32   st_res_Q12[],                           /* I short term residual signal       */
    SKP_int16   xw[],                                   /* O prefiltered signal               */
    SKP_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */
    SKP_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */
    SKP_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/
    SKP_int     lag,                                    /* I Lag for harmonic shaping         */
    SKP_int     length                                  /* I Length of signals                */
)
{
    SKP_int   i, idx, LTP_shp_buf_idx;
    SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
    SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
    SKP_int16 *LTP_shp_buf;

    /* To speed up use temp variables instead of using the struct */
    LTP_shp_buf     = P->sLTP_shp;
    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;
    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;

    for( i = 0; i < length; i++ ) {
        if( lag > 0 ) {
            /* unrolled loop */
            SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
            idx = lag + LTP_shp_buf_idx;
            n_LTP_Q12 = SKP_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
            n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
            n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
        } else {
            n_LTP_Q12 = 0;
        }

        n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
        n_LF_Q10   = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );

        sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) );
        sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12,  SKP_LSHIFT( n_LF_Q10,   2 ) );

        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
        LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );

        xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );
    }

    /* Copy temp variable back to state */
    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;
    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;
    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
}
Пример #12
0
/* Gains scalar dequantization, uniform on log scale */
void SKP_Silk_gains_dequant(
    SKP_int32                       gain_Q16[ MAX_NB_SUBFR ],   /* O    quantized gains                         */
    const SKP_int8                  ind[ MAX_NB_SUBFR ],        /* I    gain indices                            */
    SKP_int8                        *prev_ind,                  /* I/O  last index in previous frame            */
    const SKP_int                   conditional,                /* I    first gain is delta coded if 1          */
    const SKP_int                   nb_subfr                    /* I    number of subframes                     */
)
{
    SKP_int   k, ind_tmp, double_step_size_threshold;

    for( k = 0; k < nb_subfr; k++ ) {
        if( k == 0 && conditional == 0 ) {
            *prev_ind = ind[ k ];
        } else {
            /* Delta index */
            ind_tmp = ind[ k ] + MIN_DELTA_GAIN_QUANT;

            /* Accumulate deltas */
            double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind;
            if( ind_tmp > double_step_size_threshold ) {
                *prev_ind += SKP_LSHIFT( ind_tmp, 1 ) - double_step_size_threshold;
            } else {
                *prev_ind += ind_tmp;
            }
        }

        /* Convert to linear scale and scale */
        gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */
    }
}
Пример #13
0
/*
  Variable order MA prediction error filter. Inverse filter of
  SKP_Silk_LPC_synthesis_filter.

  The inlined assembly makes it over 30% faster than the generic C.
*/
void SKP_Silk_LPC_analysis_filter(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int16            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      Order           /* I:   Filter order                                */
)
{
	SKP_int  k;
	SKP_int32 out32_Q12, out32;
	/* Order must be even */
	SKP_assert( 2 * Order_half == Order );

	/* S[] values are in Q0 */
	for( k = 0; k < len; k++ ) {
		LPC_ANALYSYS(out32_Q12, S, B, Order);
		/* Subtract prediction */
		out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT(
			(SKP_int32)in[ k ], 12 ), out32_Q12 );
		/* Scale to Q0 */
		out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );
		out[ k ] = (SKP_int16)SKP_SAT16( out32 );
		/* Move input line */
		S[ 0 ] = in[ k ];
	}
}
Пример #14
0
void SKP_Silk_VAD_GetNoiseLevels(
    const SKP_int32                 pX[ VAD_N_BANDS ],  /* I    subband energies                            */
    SKP_Silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */ 
)
{
    SKP_int   k;
    SKP_int32 nl, nrg, inv_nrg;
    SKP_int   coef, min_coef;

    /* Initially faster smoothing */
    if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
        min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );  
    } else {
        min_coef = 0;
    }

    for( k = 0; k < VAD_N_BANDS; k++ ) {
        /* Get old noise level estimate for current band */
        nl = psSilk_VAD->NL[ k ];
        SKP_assert( nl >= 0 );
        
        /* Add bias */
        nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); 
        SKP_assert( nrg > 0 );
        
        /* Invert energies */
        inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg );
        SKP_assert( inv_nrg >= 0 );
        
        /* Less update when subband energy is high */
        if( nrg > SKP_LSHIFT( nl, 3 ) ) {
            coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
        } else if( nrg < nl ) {
Пример #15
0
/* Resamples by a factor 3/1 */
void SKP_Silk_resample_3_1(
    SKP_int16           *out,       /* O:   Fs_high signal [inLen*3]        */
    SKP_int32           *S,         /* I/O: State vector   [7]              */
    const SKP_int16     *in,        /* I:   Fs_low signal  [inLen]          */
    const SKP_int32     inLen       /* I:   Input length                    */
)
{
    SKP_int     k, LSubFrameIn, LSubFrameOut;
    SKP_int32   out_tmp, idx, inLenTmp = inLen;
    SKP_int32   scratch00[    IN_SUBFR_LEN_RESAMPLE_3_1 ];
    SKP_int32   scratch0[ 3 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
    SKP_int32   scratch1[ 3 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
    
    /* Coefficients for 3-fold resampling */
    const SKP_int16 A30[ 2 ] = {  1773, 17818 };
    const SKP_int16 A31[ 2 ] = {  4942, 25677 };
    const SKP_int16 A32[ 2 ] = { 11786, 29304 };

    while( inLenTmp > 0 ) {
        LSubFrameIn  = SKP_min_int( IN_SUBFR_LEN_RESAMPLE_3_1, inLenTmp );
        LSubFrameOut = SKP_SMULBB( 3, LSubFrameIn );

        /* Convert Q15 -> Q25 */
        for( k = 0; k < LSubFrameIn; k++ ) {
            scratch00[k] = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
        }

        /* Allpass filtering */
        /* Scratch size: 2 * 3* LSubFrame * sizeof(SKP_int32) */
        SKP_Silk_allpass_int( scratch00, S + 1, A30[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 2, A30[ 1 ], scratch0, LSubFrameIn );

        SKP_Silk_allpass_int( scratch00, S + 3, A31[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 4, A31[ 1 ], scratch0 +     IN_SUBFR_LEN_RESAMPLE_3_1, LSubFrameIn );

        SKP_Silk_allpass_int( scratch00, S + 5, A32[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 6, A32[ 1 ], scratch0 + 2 * IN_SUBFR_LEN_RESAMPLE_3_1, LSubFrameIn );

        /* Interleave three allpass outputs */
        for( k = 0; k < LSubFrameIn; k++ ) {
            idx = SKP_SMULBB( 3, k );
            scratch1[ idx     ] = scratch0[ k ];
            scratch1[ idx + 1 ] = scratch0[ k +     IN_SUBFR_LEN_RESAMPLE_3_1 ];
            scratch1[ idx + 2 ] = scratch0[ k + 2 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
        }

        /* Low-pass filtering */
        SKP_Silk_lowpass_int( scratch1, S, scratch0, LSubFrameOut );

        /* Saturate and convert to SKP_int16 */
        for( k = 0; k < LSubFrameOut; k++ ) {
            out_tmp  = scratch0[ k ];
            out[ k ] = (SKP_int16) SKP_SAT16( SKP_RSHIFT_ROUND( out_tmp, 10 ) );
        }

        in       += LSubFrameIn;
        inLenTmp -= LSubFrameIn;
        out      += LSubFrameOut;
    }
}
Пример #16
0
void SKP_Silk_LBRR_embed(
    SKP_Silk_encoder_state      *psEncC,            /* I/O  Encoder state                               */
    ec_enc                      *psRangeEnc         /* I/O  Compressor data structure                   */
)
{
    SKP_int   i;
    SKP_int32 LBRR_symbol;

    /* Encode LBRR flags */
    LBRR_symbol = 0;
    for( i = 0; i < psEncC->nFramesPerPacket; i++ ) {
        LBRR_symbol |= SKP_LSHIFT( psEncC->LBRR_flags[ i ], i );
    }
    psEncC->LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
    if( LBRR_symbol && psEncC->nFramesPerPacket > 1 ) {
        ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, SKP_Silk_LBRR_flags_iCDF_ptr[ psEncC->nFramesPerPacket - 2 ], 8 );
    }

    /* Code indices and excitation signals */
    for( i = 0; i < psEncC->nFramesPerPacket; i++ ) {
        if( psEncC->LBRR_flags[ i ] ) {
            SKP_Silk_encode_indices( psEncC, psRangeEnc, i, 1 );
            SKP_Silk_encode_pulses( psRangeEnc, psEncC->indices_LBRR[i].signalType, 
                psEncC->indices_LBRR[i].quantOffsetType, psEncC->pulses_LBRR[ i ], psEncC->frame_length );
        }
    }
}
Пример #17
0
/* Variable order MA prediction error filter */
void SKP_Silk_MA_Prediction(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int32            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      order           /* I:   Filter order                                */
)
{
    SKP_int   k, d, in16;
    SKP_int32 out32;

    for( k = 0; k < len; k++ ) {
        in16 = in[ k ];
        out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
        out32 = SKP_RSHIFT_ROUND( out32, 12 );
        
        for( d = 0; d < order - 1; d++ ) {
            S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
        }
        S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );

        /* Limit */
        out[ k ] = (SKP_int16)SKP_SAT16( out32 );
    }
}
Пример #18
0
/* Decodes signs of excitation */
void SKP_Silk_decode_signs(SKP_Silk_range_coder_state * sRC,	/* I/O  Range coder state                           */
			   int q[],	/* I/O  pulse signal                                */
			   const int length,	/* I    length of output                            */
			   const int sigtype,	/* I    Signal type                                 */
			   const int QuantOffsetType,	/* I    Quantization offset type                    */
			   const int RateLevelIndex	/* I    Rate Level Index                            */
    )
{
	int i;
	int data;
	const uint16_t *cdf;

	i = SKP_SMULBB(N_RATE_LEVELS - 1,
		       SKP_LSHIFT(sigtype,
				  1) + QuantOffsetType) + RateLevelIndex;
	cdf = SKP_Silk_sign_CDF[i];

	for (i = 0; i < length; i++) {
		if (q[i] > 0) {
			SKP_Silk_range_decoder(&data, sRC, cdf, 1);
			/* attach sign */
			/* implementation with shift, subtraction, multiplication */
			q[i] *= SKP_dec_map(data);
		}
	}
}
Пример #19
0
/* Encodes signs of excitation */
void SKP_Silk_encode_signs(
    SKP_Silk_range_coder_state      *sRC,               /* I/O  Range coder state                       */
    const SKP_int8                  q[],                /* I    Pulse signal                            */
    const SKP_int                   length,             /* I    Length of input                         */
    const SKP_int                   sigtype,            /* I    Signal type                             */
    const SKP_int                   QuantOffsetType,    /* I    Quantization offset type                */
    const SKP_int                   RateLevelIndex      /* I    Rate level index                        */
)
{
    SKP_int i;
    SKP_int inData;
    SKP_uint16 cdf[ 3 ];

    i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
    cdf[ 0 ] = 0;
    cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
    cdf[ 2 ] = 65535;
    
    for( i = 0; i < length; i++ ) {
        if( q[ i ] != 0 ) {
            inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */
            SKP_Silk_range_encoder( sRC, inData, cdf );
        }
    }
}
Пример #20
0
/* Processing of gains */
void silk_process_gains_FIX(
    silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state_FIX                           */
    silk_encoder_control_FIX    *psEncCtrl      /* I/O  Encoder control_FIX                         */
)
{
    silk_shape_state_FIX    *psShapeSt = &psEnc->sShape;
    opus_int     k;
    opus_int32   s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;

    /* Gain reduction when LTP coding gain is high */
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
        /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
        s_Q16 = -silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
            psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
        }
    }

    /* Limit the quantized signal */
    /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
    InvMaxSqrVal_Q16 = SKP_DIV32_16( silk_log2lin(
                                         SKP_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );

    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
        /* Soft limit on ratio residual energy and squared gains */
        ResNrg     = psEncCtrl->ResNrg[ k ];
        ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
        if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
            ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
        } else {
            if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
                ResNrgPart = SKP_int32_MAX;
            } else {
                ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
            }
        }
        gain = psEncCtrl->Gains_Q16[ k ];
        gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) );
        if( gain_squared < SKP_int16_MAX ) {
            /* recalculate with higher precision */
            gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain );
            SKP_assert( gain_squared > 0 );
            gain = silk_SQRT_APPROX( gain_squared );                    /* Q8   */
            gain = SKP_min( gain, SKP_int32_MAX >> 8 );
            psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 );        /* Q16  */
        } else {
Пример #21
0
/* Convert input to a log scale    */ 
opus_int32 silk_lin2log( const opus_int32 inLin )    /* I:    Input in linear scale */
{
    opus_int32 lz, frac_Q7;

    silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );

    /* Piece-wise parabolic approximation */
    return SKP_LSHIFT( 31 - lz, 7 ) + SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 );
}
/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
void SKP_Silk_NLSF_VQ_sum_error_FIX(int32_t * err_Q20,	/* O    Weighted quantization errors  [N*K]         */
				    const int *in_Q15,	/* I    Input vectors to be quantized [N*LPC_order] */
				    const int *w_Q6,	/* I    Weighting vectors             [N*LPC_order] */
				    const int16_t * pCB_Q15,	/* I    Codebook vectors              [K*LPC_order] */
				    const int N,	/* I    Number of input vectors                     */
				    const int K,	/* I    Number of codebook vectors                  */
				    const int LPC_order	/* I    Number of LPCs                              */
    )
{
	int i, n, m;
	int32_t diff_Q15, sum_error, Wtmp_Q6;
	int32_t Wcpy_Q6[MAX_LPC_ORDER / 2];
	const int16_t *cb_vec_Q15;

	assert(LPC_order <= 16);
	assert((LPC_order & 1) == 0);

	memzero(Wcpy_Q6, (MAX_LPC_ORDER / 2) * sizeof(int32_t));

	/* Copy to local stack and pack two weights per int32 */
	for (m = 0; m < SKP_RSHIFT(LPC_order, 1); m++) {
		Wcpy_Q6[m] =
		    w_Q6[2 * m] | SKP_LSHIFT((int32_t) w_Q6[2 * m + 1], 16);
	}

	/* Loop over input vectors */
	for (n = 0; n < N; n++) {
		/* Loop over codebook */
		cb_vec_Q15 = pCB_Q15;
		for (i = 0; i < K; i++) {
			sum_error = 0;
			for (m = 0; m < LPC_order; m += 2) {
				/* Get two weights packed in an int32 */
				Wtmp_Q6 = Wcpy_Q6[SKP_RSHIFT(m, 1)];

				/* Compute weighted squared quantization error for index m */
				diff_Q15 = in_Q15[m] - *cb_vec_Q15++;	// range: [ -32767 : 32767 ]
				sum_error =
				    SKP_SMLAWB(sum_error,
					       SKP_SMULBB(diff_Q15, diff_Q15),
					       Wtmp_Q6);

				/* Compute weighted squared quantization error for index m + 1 */
				diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++;	// range: [ -32767 : 32767 ]
				sum_error =
				    SKP_SMLAWT(sum_error,
					       SKP_SMULBB(diff_Q15, diff_Q15),
					       Wtmp_Q6);
			}
			assert(sum_error >= 0);
			err_Q20[i] = sum_error;
		}
		err_Q20 += K;
		in_Q15 += LPC_order;
	}
}
Пример #23
0
/* Step up function, converts reflection coefficients to prediction coefficients */
void SKP_Silk_k2a(
    SKP_int32            *A_Q24,                 /* O:    Prediction coefficients [order] Q24         */
    const SKP_int16      *rc_Q15,                /* I:    Reflection coefficients [order] Q15         */
    const SKP_int32      order                   /* I:    Prediction order                            */
)
{
    SKP_int   k, n;
    SKP_int32 Atmp[ SKP_Silk_MAX_ORDER_LPC ];

    for( k = 0; k < order; k++ ) {
        for( n = 0; n < k; n++ ) {
            Atmp[ n ] = A_Q24[ n ];
        }
        for( n = 0; n < k; n++ ) {
            A_Q24[ n ] = SKP_SMLAWB( A_Q24[ n ], SKP_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
        }
        A_Q24[ k ] = -SKP_LSHIFT( (SKP_int32)rc_Q15[ k ], 9 );
    }
}
Пример #24
0
/* Glues concealed frames with new good recieved frames             */
void SKP_Silk_PLC_glue_frames(
    SKP_Silk_decoder_state      *psDec,             /* I/O decoder state    */
    SKP_Silk_decoder_control    *psDecCtrl,         /* I/O Decoder control  */
    SKP_int16                   signal[],           /* I/O signal           */
    SKP_int                     length              /* I length of residual */
)
{
    SKP_int   i, energy_shift;
    SKP_int32 energy;
    SKP_Silk_PLC_struct *psPLC;
    psPLC = &psDec->sPLC;

    if( psDec->lossCnt ) {
        /* Calculate energy in concealed residual */
        SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length );
        
        psPLC->last_frame_lost = 1;
    } else {
        if( psDec->sPLC.last_frame_lost ) {
            /* Calculate residual in decoded signal if last frame was lost */
            SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length );

            /* Normalize energies */
            if( energy_shift > psPLC->conc_energy_shift ) {
                psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );
            } else if( energy_shift < psPLC->conc_energy_shift ) {
                energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );
            }

            /* Fade in the energy difference */
            if( energy > psPLC->conc_energy ) {
                SKP_int32 frac_Q24, LZ;
                SKP_int32 gain_Q12, slope_Q12;

                LZ = SKP_Silk_CLZ32( psPLC->conc_energy );
                LZ = LZ - 1;
                psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ );
                energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) );
                
                frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) );
                
                gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 );
                slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length );

                for( i = 0; i < length; i++ ) {
                    signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 );
                    gain_Q12 += slope_Q12;
                    gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) );
                }
            }
        }
        psPLC->last_frame_lost = 0;

    }
}
Пример #25
0
void SKP_Silk_shell_insertion_sort_increasing(
    SKP_int32           *a,             /* I/O:  Unsorted / Sorted vector               */
    SKP_int             *index,         /* O:    Index vector for the sorted elements   */
    const SKP_int       L,              /* I:    Vector length                          */
    const SKP_int       K               /* I:    Number of correctly sorted positions   */
)
{
    SKP_int32    value, inc_Q16_tmp;
    SKP_int      i, j, inc, idx;
   
    /* Safety checks */
    SKP_assert( K >  0 );
    SKP_assert( L >  0 );
    SKP_assert( L >= K );
    
    /* Calculate initial step size */
    inc_Q16_tmp = SKP_LSHIFT( (SKP_int32)L, 15 );
    inc = SKP_RSHIFT( inc_Q16_tmp, 16 );

    /* Write start indices in index vector */
    for( i = 0; i < K; i++ ) {
        index[ i ] = i;
    }

    /* Shell sort first values */
    while( inc > 0 ) {
        for( i = inc; i < K; i++ ) {
            value = a[ i ];
            idx   = index[ i ];
            for( j = i - inc; ( j >= 0 ) && ( value < a[ j ] ); j -= inc ) {
                a[ j + inc ]     = a[ j ];     /* Shift value */
                index[ j + inc ] = index[ j ]; /* Shift index */
            }
            a[ j + inc ]     = value; /* Write value */
            index[ j + inc ] = idx;   /* Write index */
        }
        inc_Q16_tmp = SKP_SMULWB( inc_Q16_tmp, 29789 ); // 29789_Q16 = 2.2^(-1)_Q0
        inc = SKP_RSHIFT_ROUND( inc_Q16_tmp, 16 );
    }

    /* If less than L values are asked for, check the remaining values, */
    /* but only spend CPU to ensure that the K first values are correct */
    /* Insertion sort remaining values */
    for( i = K; i < L; i++ ) {
        value = a[ i ];
        if( value < a[ K - 1 ] ) {
            for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {
                a[ j + 1 ]     = a[ j ];     /* Shift value */
                index[ j + 1 ] = index[ j ]; /* Shift index */
            }
            a[ j + 1 ]     = value; /* Write value */
            index[ j + 1 ] = i;     /* Write index */
        }
    }
}
Пример #26
0
/* Compute autocorrelation */
void SKP_Silk_autocorr( 
    SKP_int32        *results,                   /* O    Result (length correlationCount)            */
    SKP_int          *scale,                     /* O    Scaling of the correlation vector           */
    const SKP_int16  *inputData,                 /* I    Input data to correlate                     */
    const SKP_int    inputDataSize,              /* I    Length of input                             */
    const SKP_int    correlationCount            /* I    Number of correlation taps to compute       */
)
{
    SKP_int   i, lz, nRightShifts, corrCount;
    SKP_int64 corr64;

    corrCount = SKP_min_int( inputDataSize, correlationCount );

    /* compute energy (zero-lag correlation) */
    corr64 = SKP_Silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );

    /* deal with all-zero input data */
    corr64 += 1;

    /* number of leading zeros */
    lz = SKP_Silk_CLZ64( corr64 );

    /* scaling: number of right shifts applied to correlations */
    nRightShifts = 35 - lz;
    *scale = nRightShifts;

    if( nRightShifts <= 0 ) {
        results[ 0 ] = SKP_LSHIFT( (SKP_int32)SKP_CHECK_FIT32( corr64 ), -nRightShifts );

        /* compute remaining correlations based on int32 inner product */
          for( i = 1; i < corrCount; i++ ) {
            results[ i ] = SKP_LSHIFT( SKP_Silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
        }
    } else {
        results[ 0 ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( corr64, nRightShifts ) );

        /* compute remaining correlations based on int64 inner product */
          for( i = 1; i < corrCount; i++ ) {
            results[ i ] =  (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
        }
    }
}
Пример #27
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;
}
Пример #28
0
/* Uses SMULL(), available on armv4                                     */ 
SKP_int32 SKP_Silk_schur64(                    /* O:    Returns residual energy                     */
    SKP_int32            rc_Q16[],               /* O:    Reflection coefficients [order] Q16         */
    const SKP_int32      c[],                    /* I:    Correlations [order+1]                      */
    SKP_int32            order                   /* I:    Prediction order                            */
)
{
    SKP_int   k, n;
    SKP_int32 C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ];
    SKP_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;

    /* Check for invalid input */
    if( c[ 0 ] <= 0 ) {
        SKP_memset( rc_Q16, 0, order * sizeof( SKP_int32 ) );
        return 0;
    }
    
    for( k = 0; k < order + 1; k++ ) {
        C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
    }

    for( k = 0; k < order; k++ ) {
        /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
        rc_tmp_Q31 = SKP_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );

        /* Save the output */
        rc_Q16[ k ] = SKP_RSHIFT_ROUND( rc_tmp_Q31, 15 );

        /* Update correlations */
        for( n = 0; n < order - k; n++ ) {
            Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
            Ctmp2_Q30 = C[ n ][ 1 ];
            
            /* Multiply and add the highest int32 */
            C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
            C[ n ][ 1 ]         = Ctmp2_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
        }
    }

    return( C[ 0 ][ 1 ] );
}
void SKP_Silk_noise_shape_analysis_FIX(
    SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state FIX                           */
    SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Encoder control FIX                         */
    const SKP_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */
    const SKP_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */
)
{
    SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
    SKP_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
    SKP_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
    SKP_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
    SKP_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
    SKP_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
    SKP_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
    SKP_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];
    SKP_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];
    SKP_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];
    SKP_int32   sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ];
    const SKP_int16 *x_ptr, *pitch_res_ptr;

    /* Point to start of first LPC analysis block */
    x_ptr = x - psEnc->sCmn.la_shape;

    /****************/
    /* CONTROL SNR  */
    /****************/
    /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */
    psEncCtrl->current_SNR_dB_Q7 = psEnc->SNR_dB_Q7 - SKP_SMULBB( psEnc->BufferedInChannel_ms, SKP_FIX_CONST( 0.1, 7 ) );

    /* Reduce SNR_dB because of any inband FEC used */
    psEncCtrl->current_SNR_dB_Q7 -= psEnc->inBandFEC_SNR_comp_Q7;

    /****************/
    /* GAIN CONTROL */
    /****************/
    /* Input quality is the average of the quality in the lowest two VAD bands */
    psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ] 
        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );

    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
    psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->current_SNR_dB_Q7 - 
        SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );

    /* Reduce coding SNR during low speech activity */
    SNR_adj_dB_Q7 = psEncCtrl->current_SNR_dB_Q7;
    if( psEnc->sCmn.useCBR == 0 ) {
        b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
        b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );
        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,
            SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       // Q11
            SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     // Q12
    }
Пример #30
0
/* Gain scalar quantization with hysteresis, uniform on log scale */
void SKP_Silk_gains_quant(
    SKP_int8                        ind[ MAX_NB_SUBFR ],        /* O    gain indices                            */
    SKP_int32                       gain_Q16[ MAX_NB_SUBFR ],   /* I/O  gains (quantized out)                   */
    SKP_int8                        *prev_ind,                  /* I/O  last index in previous frame            */
    const SKP_int                   conditional,                /* I    first gain is delta coded if 1          */
    const SKP_int                   nb_subfr                    /* I    number of subframes                     */
)
{
    SKP_int k, double_step_size_threshold;

    for( k = 0; k < nb_subfr; k++ ) {
        /* Add half of previous quantization error, convert to log scale, scale, floor() */
        ind[ k ] = SKP_SMULWB( SCALE_Q16, SKP_Silk_lin2log( gain_Q16[ k ] ) - OFFSET );

        /* Round towards previous quantized gain (hysteresis) */
        if( ind[ k ] < *prev_ind ) {
            ind[ k ]++;
        }
        ind[ k ] = SKP_max_int( ind[ k ], 0 );

        /* Compute delta indices and limit */
        if( k == 0 && conditional == 0 ) {
            /* Full index */
            ind[ k ] = SKP_LIMIT_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT, N_LEVELS_QGAIN - 1 );
            *prev_ind = ind[ k ];
        } else {
            /* Delta index */
            ind[ k ] = ind[ k ] - *prev_ind;

            /* Double the quantization step size for large gain increases, so that the max gain level can be reached */
            double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind;
            if( ind[ k ] > double_step_size_threshold ) {
                ind[ k ] = double_step_size_threshold + SKP_RSHIFT( ind[ k ] - double_step_size_threshold + 1, 1 );
            }

            ind[ k ] = SKP_LIMIT_int( ind[ k ], MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT );

            /* Accumulate deltas */
            if( ind[ k ] > double_step_size_threshold ) {
                *prev_ind += SKP_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
            } else {
                *prev_ind += ind[ k ];
            }

            /* Shift to make non-negative */
            ind[ k ] -= MIN_DELTA_GAIN_QUANT;
        }

        /* Convert to linear scale and scale */
        gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */
    }
}