/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia_FLP( 
          SKP_float     *pXW,           /* 0: Pointer to input vector weights           [D x 1] */
    const SKP_float     *pX,            /* I: Pointer to input vector                   [D x 1] */ 
    const SKP_int        D              /* I: Input vector dimension                            */
)
{
    SKP_int   k;
    SKP_float tmp1, tmp2;
    
    /* Safety checks */
    SKP_assert( D > 0 );
    SKP_assert( ( D & 1 ) == 0 );
    
    /* First value */
    tmp1 = 1.0f / SKP_max_float( pX[ 0 ],           MIN_NDELTA );
    tmp2 = 1.0f / SKP_max_float( pX[ 1 ] - pX[ 0 ], MIN_NDELTA );
    pXW[ 0 ] = tmp1 + tmp2;
    
    /* Main loop */
    for( k = 1; k < D - 1; k += 2 ) {
        tmp1 = 1.0f / SKP_max_float( pX[ k + 1 ] - pX[ k ], MIN_NDELTA );
        pXW[ k ] = tmp1 + tmp2;

        tmp2 = 1.0f / SKP_max_float( pX[ k + 2 ] - pX[ k + 1 ], MIN_NDELTA );
        pXW[ k + 1 ] = tmp1 + tmp2;
    }
    
    /* Last value */
    tmp1 = 1.0f / SKP_max_float( 1.0f - pX[ D - 1 ], MIN_NDELTA );
    pXW[ D - 1 ] = tmp1 + tmp2;
}
Esempio n. 2
0
/* Generates excitation for CNG LPC synthesis */
SKP_INLINE void SKP_Silk_CNG_exc(
    SKP_int16                       residual[],         /* O    CNG residual signal Q0                      */
    SKP_int32                       exc_buf_Q10[],      /* I    Random samples buffer Q10                   */
    SKP_int32                       Gain_Q16,           /* I    Gain to apply                               */
    SKP_int                         length,             /* I    Length                                      */
    SKP_int32                       *rand_seed          /* I/O  Seed to random index generator              */
)
{
    SKP_int32 seed;
    SKP_int   i, idx, exc_mask;

    exc_mask = CNG_BUF_MASK_MAX;
    while( exc_mask > length ) {
        exc_mask = SKP_RSHIFT( exc_mask, 1 );
    }

    seed = *rand_seed;
    for( i = 0; i < length; i++ ) {
        seed = SKP_RAND( seed );
        idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
        SKP_assert( idx >= 0 );
        SKP_assert( idx <= CNG_BUF_MASK_MAX );
        residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );
    }
    *rand_seed = seed;
}
Esempio n. 3
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 ) {
Esempio n. 4
0
/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
void silk_NLSF_VQ(
    SKP_int32                   err_Q26[],              /* O    Quantization errors [K]                     */
    const SKP_int16             in_Q15[],               /* I    Input vectors to be quantized [LPC_order]   */
    const SKP_uint8             pCB_Q8[],               /* I    Codebook vectors [K*LPC_order]              */
    const SKP_int               K,                      /* I    Number of codebook vectors                  */
    const SKP_int               LPC_order               /* I    Number of LPCs                              */
)
{
    SKP_int        i, m;
    SKP_int32      diff_Q15, sum_error_Q30, sum_error_Q26;

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

    /* Loop over codebook */
    for( i = 0; i < K; i++ ) {
        sum_error_Q26 = 0;
        for( m = 0; m < LPC_order; m += 2 ) {
            /* Compute weighted squared quantization error for index m */
            diff_Q15 = SKP_SUB_LSHIFT32( in_Q15[ m ], ( SKP_int32 )*pCB_Q8++, 7 ); // range: [ -32767 : 32767 ]
            sum_error_Q30 = SKP_SMULBB( diff_Q15, diff_Q15 );

            /* Compute weighted squared quantization error for index m + 1 */
            diff_Q15 = SKP_SUB_LSHIFT32( in_Q15[m + 1], ( SKP_int32 )*pCB_Q8++, 7 ); // range: [ -32767 : 32767 ]
            sum_error_Q30 = SKP_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );

            sum_error_Q26 = SKP_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );

            SKP_assert( sum_error_Q26 >= 0 );
            SKP_assert( sum_error_Q30 >= 0 );
        }
        err_Q26[ i ] = sum_error_Q26;
    }
}
Esempio n. 5
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 */
        }
    }
}
Esempio n. 6
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 ) );
    }
}
/* 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
}
void SKP_Silk_LDL_FLP(
    SKP_float           *A,      /* (I/O) Pointer to Symetric Square Matrix */
    SKP_int             M,       /* (I) Size of Matrix */
    SKP_float           *L,      /* (I/O) Pointer to Square Upper triangular Matrix */
    SKP_float           *Dinv    /* (I/O) Pointer to vector holding the inverse diagonal elements of D */
)
{
    SKP_int i, j, k, loop_count, err = 1;
    SKP_float *ptr1, *ptr2;
    double temp, diag_min_value;
    SKP_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; // temp arrays

    SKP_assert( M <= MAX_MATRIX_SIZE );

    diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] ); 
    for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) {
        err = 0;
        for( j = 0; j < M; j++ ) {
            ptr1 = matrix_adr( L, j, 0, M );
            temp = matrix_ptr( A, j, j, M ); // element in row j column j
            for( i = 0; i < j; i++ ) {
                v[ i ] = ptr1[ i ] * D[ i ];
                temp  -= ptr1[ i ] * v[ i ];
            }
            if( temp < diag_min_value ) {
                /* Badly conditioned matrix: add white noise and run again */
                temp = ( loop_count + 1 ) * diag_min_value - temp;
                for( i = 0; i < M; i++ ) {
                    matrix_ptr( A, i, i, M ) += ( SKP_float )temp;
                }
                err = 1;
                break;
            }
            D[ j ]    = ( SKP_float )temp;
            Dinv[ j ] = ( SKP_float )( 1.0f / temp );
            matrix_ptr( L, j, j, M ) = 1.0f;
            
            ptr1 = matrix_adr( A, j, 0, M );
            ptr2 = matrix_adr( L, j + 1, 0, M);
            for( i = j + 1; i < M; i++ ) {
                temp = 0.0;
                for( k = 0; k < j; k++ ) {
                    temp += ptr2[ k ] * v[ k ];
                }
                matrix_ptr( L, i, j, M ) = ( SKP_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] );
                ptr2 += M; // go to next column
            }   
        }
    }
    SKP_assert( err == 0 );
}
/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
void SKP_Silk_NLSF_VQ_sum_error_FIX(
    SKP_int32                       *err_Q20,           /* O    Weighted quantization errors  [N*K]         */
    const SKP_int                   *in_Q15,            /* I    Input vectors to be quantized [N*LPC_order] */
    const SKP_int                   *w_Q6,              /* I    Weighting vectors             [N*LPC_order] */
    const SKP_int16                 *pCB_Q15,           /* I    Codebook vectors              [K*LPC_order] */
    const SKP_int                   N,                  /* I    Number of input vectors                     */
    const SKP_int                   K,                  /* I    Number of codebook vectors                  */
    const SKP_int                   LPC_order           /* I    Number of LPCs                              */
)
{
    SKP_int         i, n, m;
    SKP_int32       diff_Q15, sum_error, Wtmp_Q6;
    SKP_int32       Wcpy_Q6[ MAX_LPC_ORDER / 2 ];
    const SKP_int16 *cb_vec_Q15;

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

    /* 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( ( SKP_int32 )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 );
            }
            SKP_assert( sum_error >= 0 );
            err_Q20[ i ] = sum_error;
        }
        err_Q20 += K;
        in_Q15 += LPC_order;
    }
}
/* Convert NLSF parameters to stable AR prediction filter coefficients */
void SKP_Silk_NLSF2A_stable(
    SKP_int16                       pAR_Q12[ MAX_LPC_ORDER ],   /* O    Stabilized AR coefs [LPC_order]     */ 
    const SKP_int                   pNLSF[ MAX_LPC_ORDER ],     /* I    NLSF vector         [LPC_order]     */
    const SKP_int                   LPC_order                   /* I    LPC/LSF order                       */
)
{
    SKP_int   i;
    SKP_int32 invGain_Q30;

    SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );

    /* Ensure stable LPCs */
    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
        if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
            SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) );		/* 10_Q16 = 0.00015 */
        } else {
            break;
        }
    }

    /* Reached the last iteration */
    if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
        SKP_assert( 0 );
        for( i = 0; i < LPC_order; i++ ) {
            pAR_Q12[ i ] = 0;
        }
    }
}
/* sum of squares of a SKP_float array, with result as double */
double SKP_Silk_energy_FLP( 
    const SKP_float     *data, 
    SKP_int             dataSize
)
{
    SKP_int  i, dataSize4;
    double   result;

    /* 4x unrolled loop */
    result = 0.0f;
    dataSize4 = dataSize & 0xFFFC;
    for( i = 0; i < dataSize4; i += 4 ) {
        result += data[ i + 0 ] * data[ i + 0 ] + 
                  data[ i + 1 ] * data[ i + 1 ] +
                  data[ i + 2 ] * data[ i + 2 ] +
                  data[ i + 3 ] * data[ i + 3 ];
    }

    /* add any remaining products */
    for( ; i < dataSize; i++ ) {
        result += data[ i ] * data[ i ];
    }

    SKP_assert( result >= 0.0 );
    return result;
}
/* Shell decoder, operates on one shell code frame of 16 pulses */
void SKP_Silk_shell_decoder(
    SKP_int                         *pulses0,           /* O    data: nonnegative pulse amplitudes          */
    ec_dec                          *psRangeDec,        /* I/O  Compressor data structure                   */
    const SKP_int                   pulses4             /* I    number of pulses per pulse-subframe         */
)
{
    SKP_int pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ];

    /* this function operates on one shell code frame of 16 pulses */
    SKP_assert( SHELL_CODEC_FRAME_LENGTH == 16 );

    decode_split( &pulses3[  0 ], &pulses3[  1 ], psRangeDec, pulses4,      SKP_Silk_shell_code_table3 );

    decode_split( &pulses2[  0 ], &pulses2[  1 ], psRangeDec, pulses3[ 0 ], SKP_Silk_shell_code_table2 );

    decode_split( &pulses1[  0 ], &pulses1[  1 ], psRangeDec, pulses2[ 0 ], SKP_Silk_shell_code_table1 );
    decode_split( &pulses0[  0 ], &pulses0[  1 ], psRangeDec, pulses1[ 0 ], SKP_Silk_shell_code_table0 );
    decode_split( &pulses0[  2 ], &pulses0[  3 ], psRangeDec, pulses1[ 1 ], SKP_Silk_shell_code_table0 );

    decode_split( &pulses1[  2 ], &pulses1[  3 ], psRangeDec, pulses2[ 1 ], SKP_Silk_shell_code_table1 );
    decode_split( &pulses0[  4 ], &pulses0[  5 ], psRangeDec, pulses1[ 2 ], SKP_Silk_shell_code_table0 );
    decode_split( &pulses0[  6 ], &pulses0[  7 ], psRangeDec, pulses1[ 3 ], SKP_Silk_shell_code_table0 );

    decode_split( &pulses2[  2 ], &pulses2[  3 ], psRangeDec, pulses3[ 1 ], SKP_Silk_shell_code_table2 );

    decode_split( &pulses1[  4 ], &pulses1[  5 ], psRangeDec, pulses2[ 2 ], SKP_Silk_shell_code_table1 );
    decode_split( &pulses0[  8 ], &pulses0[  9 ], psRangeDec, pulses1[ 4 ], SKP_Silk_shell_code_table0 );
    decode_split( &pulses0[ 10 ], &pulses0[ 11 ], psRangeDec, pulses1[ 5 ], SKP_Silk_shell_code_table0 );

    decode_split( &pulses1[  6 ], &pulses1[  7 ], psRangeDec, pulses2[ 3 ], SKP_Silk_shell_code_table1 );
    decode_split( &pulses0[ 12 ], &pulses0[ 13 ], psRangeDec, pulses1[ 6 ], SKP_Silk_shell_code_table0 );
    decode_split( &pulses0[ 14 ], &pulses0[ 15 ], psRangeDec, pulses1[ 7 ], SKP_Silk_shell_code_table0 );
}
Esempio n. 13
0
/* Calculates correlation vector X'*t */
void SKP_Silk_corrVector_FIX(
    const SKP_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
    const SKP_int16                 *t,         /* I    target vector [L]                                   */
    const SKP_int                   L,          /* I    Length of vectors                                   */
    const SKP_int                   order,      /* I    Max lag for correlation                             */
    SKP_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */
    const SKP_int                   rshifts     /* I    Right shifts of correlations                        */
)
{
    SKP_int         lag, i;
    const SKP_int16 *ptr1, *ptr2;
    SKP_int32       inner_prod;

    ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
    ptr2 = t;
    /* Calculate X'*t */
    if( rshifts > 0 ) {
        /* Right shifting used */
        for( lag = 0; lag < order; lag++ ) {
            inner_prod = 0;
            for( i = 0; i < L; i++ ) {
                inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
            }
            Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
            ptr1--; /* Go to next column of X */
        }
    } else {
        SKP_assert( rshifts == 0 );
        for( lag = 0; lag < order; lag++ ) {
            Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
            ptr1--; /* Go to next column of X */
        }
    }
}
Esempio n. 14
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 ];
	}
}
Esempio n. 15
0
void SKP_Silk_insertion_sort_decreasing_FLP(
    SKP_float            *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_float value;
    SKP_int   i, j;

    /* Safety checks */
    SKP_assert( K >  0 );
    SKP_assert( L >  0 );
    SKP_assert( L >= K );

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

    /* Sort vector elements by value, decreasing order */
    for( i = 1; i < K; i++ ) {
        value = a[ i ];
        for( j = i - 1; ( 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 */
    }

    /* If less than L values are asked check the remaining values,      */
    /* but only spend CPU to ensure that the K first values are correct */
    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 */
        }
    }
}
Esempio n. 16
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 ];
    }
}
/*  2 -> sine window from pi/2 to pi                                                                    */
void SKP_Silk_apply_sine_window_FLP(
          SKP_float                 px_win[],           /* O    Pointer to windowed signal              */
    const SKP_float                 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_float freq, c, S0, S1;

	SKP_assert( win_type == 1 || win_type == 2 );

    /* Length must be multiple of 4 */
    SKP_assert( ( length & 3 ) == 0 );

    freq = PI / ( length + 1 );

    /* Approximation of 2 * cos(f) */
    c = 2.0f - freq * freq;

    /* Initialize state */
    if( win_type < 2 ) {
        /* Start from 0 */
        S0 = 0.0f;
        /* Approximation of sin(f) */
        S1 = freq;
    } else {
        /* Start from 1 */
        S0 = 1.0f;
        /* Approximation of cos(f) */
        S1 = 0.5f * c;
    }

    /* 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 + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );
        px_win[ k + 1 ] = px[ k + 1 ] * S1;
        S0 = c * S1 - S0;
        px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );
        px_win[ k + 3 ] = px[ k + 3 ] * S0;
        S1 = c * S0 - S1;
    }
}
void silk_LPC_analysis_filter_FLP(
          SKP_float                 r_LPC[],            /* O    LPC residual signal                     */
    const SKP_float                 PredCoef[],         /* I    LPC coefficients                        */
    const SKP_float                 s[],                /* I    Input signal                            */
    const opus_int                   length,             /* I    Length of input signal                  */
    const opus_int                   Order               /* I    LPC order                               */
)
{
    SKP_assert( Order <= length );

    switch( Order ) {
        case 6:
            silk_LPC_analysis_filter6_FLP(  r_LPC, PredCoef, s, length );
        break;

        case 8:
            silk_LPC_analysis_filter8_FLP(  r_LPC, PredCoef, s, length );
        break;

        case 10:
            silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );
        break;

        case 12:
            silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );
        break;

        case 14:
            silk_LPC_analysis_filter14_FLP( r_LPC, PredCoef, s, length );
        break;

        case 16:
            silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );
        break;

        default:
            SKP_assert( 0 );
        break;
    }

    /* Set first Order output samples to zero */
    SKP_memset( r_LPC, 0, Order * sizeof( SKP_float ) );
}
/* Upsample by a factor 4, Note: very low quality, only use with output sampling rates above 96 kHz. */
void SKP_Silk_resampler_private_up4(
    SKP_int32                       *S,             /* I/O: State vector [ 2 ]                      */
    SKP_int16                       *out,           /* O:   Output signal [ 4 * len ]               */
    const SKP_int16                 *in,            /* I:   Input signal [ len ]                    */
    SKP_int32                       len             /* I:   Number of INPUT samples                 */
)
{
    SKP_int32 k;
    SKP_int32 in32, out32, Y, X;
    SKP_int16 out16;

    SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 );
    SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 );

    /* Internal variables and state are in Q10 format */
    for( k = 0; k < len; k++ ) {
        /* Convert to Q10 */
        in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );

        /* All-pass section for even output sample */
        Y      = SKP_SUB32( in32, S[ 0 ] );
        X      = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 );
        out32  = SKP_ADD32( S[ 0 ], X );
        S[ 0 ] = SKP_ADD32( in32, X );

        /* Convert back to int16 and store to output */
        out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
        out[ 4 * k ]     = out16;
        out[ 4 * k + 1 ] = out16;

        /* All-pass section for odd output sample */
        Y      = SKP_SUB32( in32, S[ 1 ] );
        X      = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 );
        out32  = SKP_ADD32( S[ 1 ], X );
        S[ 1 ] = SKP_ADD32( in32, X );

        /* Convert back to int16 and store to output */
        out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
        out[ 4 * k + 2 ] = out16;
        out[ 4 * k + 3 ] = out16;
    }
}
Esempio n. 20
0
/* Helper function, interpolates the filter taps */
SKP_INLINE void silk_LP_interpolate_filter_taps( 
    SKP_int32           B_Q28[ TRANSITION_NB ], 
    SKP_int32           A_Q28[ TRANSITION_NA ],
    const SKP_int       ind,
    const SKP_int32     fac_Q16
)
{
    SKP_int nb, na;

    if( ind < TRANSITION_INT_NUM - 1 ) {
        if( fac_Q16 > 0 ) {
            if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */
                /* Piece-wise linear interpolation of B and A */
                for( nb = 0; nb < TRANSITION_NB; nb++ ) {
                    B_Q28[ nb ] = SKP_SMLAWB(
                        silk_Transition_LP_B_Q28[ ind     ][ nb ],
                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
                        silk_Transition_LP_B_Q28[ ind     ][ nb ],
                        fac_Q16 );
                }
                for( na = 0; na < TRANSITION_NA; na++ ) {
                    A_Q28[ na ] = SKP_SMLAWB(
                        silk_Transition_LP_A_Q28[ ind     ][ na ],
                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
                        silk_Transition_LP_A_Q28[ ind     ][ na ],
                        fac_Q16 );
                }
            } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */
                SKP_assert( fac_Q16 - ( 1 << 16 ) == SKP_SAT16( fac_Q16 - ( 1 << 16 ) ) );
                /* Piece-wise linear interpolation of B and A */
                for( nb = 0; nb < TRANSITION_NB; nb++ ) {
                    B_Q28[ nb ] = SKP_SMLAWB(
                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
                        silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
                        silk_Transition_LP_B_Q28[ ind     ][ nb ],
                        fac_Q16 - ( 1 << 16 ) );
                }
                for( na = 0; na < TRANSITION_NA; na++ ) {
                    A_Q28[ na ] = SKP_SMLAWB(
                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
                        silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
                        silk_Transition_LP_A_Q28[ ind     ][ na ],
                        fac_Q16 - ( 1 << 16 ) );
                }
            }
        } else {
            SKP_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) );
            SKP_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) );
        }
    } else {
        SKP_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) );
        SKP_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) );
    }
}
/* Entropy code the mid/side quantization indices */
void silk_stereo_encode_pred(
    ec_enc              *psRangeEnc,                    /* I/O  Compressor data structure                   */
    opus_int8            ix[ 2 ][ 4 ]                    /* I    Quantization indices                        */
)
{
    opus_int   n;
    
    /* Entropy coding */
    n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];
    SKP_assert( n < 25 );
    ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );
    for( n = 0; n < 2; n++ ) {
        SKP_assert( ix[ n ][ 0 ] < 3 );
        SKP_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
        ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );
        ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );
    }

    /* Encode flag that only mid channel is coded */
    ec_enc_icdf( psRangeEnc, ix[ 0 ][ 3 ], silk_stereo_only_code_mid_iCDF, 8 );
}
Esempio n. 22
0
/*
* Prefilter for finding Quantizer input signal    
*/
SKP_INLINE void silk_prefilt_FLP(
    silk_prefilter_state_FLP *P,/* I/O state */
    SKP_float st_res[],				/* I */
    SKP_float xw[],					/* O */
    SKP_float *HarmShapeFIR,		/* I */
    SKP_float Tilt,					/* I */
    SKP_float LF_MA_shp,			/* I */
    SKP_float LF_AR_shp,			/* I */
    opus_int   lag,					/* I */
    opus_int   length				/* I */
)
{
    opus_int   i;
    opus_int   idx, LTP_shp_buf_idx;
    SKP_float n_Tilt, n_LF, n_LTP; 
    SKP_float sLF_AR_shp, sLF_MA_shp;
    SKP_float *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      = P->sLF_AR_shp;
    sLF_MA_shp      = P->sLF_MA_shp;

    for( i = 0; i < length; i++ ) {
        if( lag > 0 ) {
            SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
            idx = lag + LTP_shp_buf_idx;
            n_LTP  = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
        } else {
            n_LTP = 0;
        }

        n_Tilt = sLF_AR_shp * Tilt;
        n_LF   = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;

        sLF_AR_shp = st_res[ i ] - n_Tilt;
        sLF_MA_shp = sLF_AR_shp - n_LF;

        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
        LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;

        xw[ i ] = sLF_MA_shp - n_LTP;
    }
    /* Copy temp variable back to state */
    P->sLF_AR_shp       = sLF_AR_shp;
    P->sLF_MA_shp       = sLF_MA_shp;
    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
}
/* 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;
}
Esempio n. 24
0
/* Downsample by a factor 2, mediocre quality */
void SKP_Silk_resampler_down2(
    SKP_int32                           *S,         /* I/O: State vector [ 2 ]                  */
    SKP_int16                           *out,       /* O:   Output signal [ len ]               */
    const SKP_int16                     *in,        /* I:   Input signal [ floor(len/2) ]       */
    SKP_int32                           inLen       /* I:   Number of input samples             */
)
{
    SKP_int32 k, len2 = SKP_RSHIFT32( inLen, 1 );
    SKP_int32 in32, out32, Y, X;

    SKP_assert( SKP_Silk_resampler_down2_0 > 0 );
    SKP_assert( SKP_Silk_resampler_down2_1 < 0 );

    /* Internal variables and state are in Q10 format */
    for( k = 0; k < len2; k++ ) {
        /* Convert to Q10 */
        in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 );

        /* All-pass section for even input sample */
        Y      = SKP_SUB32( in32, S[ 0 ] );
        X      = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 );
        out32  = SKP_ADD32( S[ 0 ], X );
        S[ 0 ] = SKP_ADD32( in32, X );

        /* Convert to Q10 */
        in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 );

        /* All-pass section for odd input sample, and add to output of previous section */
        Y      = SKP_SUB32( in32, S[ 1 ] );
        X      = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 );
        out32  = SKP_ADD32( out32, S[ 1 ] );
        out32  = SKP_ADD32( out32, X );
        S[ 1 ] = SKP_ADD32( in32, X );

        /* Add, convert back to int16 and store to output */
        out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) );
    }
}
Esempio n. 25
0
SKP_int SKP_Silk_SDK_InitEncoder(
    void                            *encState,          /* I/O: State                                           */
    SKP_Silk_EncodeControlStruct    *encStatus          /* O:   Control structure                               */
)
{
    SKP_Silk_encoder_state_Fxx *psEnc;
    SKP_int ret = SKP_SILK_NO_ERROR;

        
    psEnc = ( SKP_Silk_encoder_state_Fxx* )encState;

    /* Reset Encoder */
    if( ret += SKP_Silk_init_encoder_Fxx( psEnc ) ) {
        SKP_assert( 0 );
    }

    /* Read control structure */
    if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) {
        SKP_assert( 0 );
    }


    return ret;
}
Esempio n. 26
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 );
    }
}
/* even order AR filter */
void SKP_Silk_LPC_synthesis_filter(
    const SKP_int16 *in,        /* I:   excitation signal */
    const SKP_int16 *A_Q12,     /* I:   AR coefficients [Order], between -8_Q0 and 8_Q0 */
    const SKP_int32 Gain_Q26,   /* I:   gain */
    SKP_int32 *S,               /* I/O: state vector [Order] */
    SKP_int16 *out,             /* O:   output signal */
    const SKP_int32 len,        /* I:   signal length */
    const SKP_int Order         /* I:   filter order, must be even */
)
{
    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
    SKP_int32 SA, SB, out32_Q10, out32;

    /* Order must be even */
    SKP_assert( 2 * Order_half == Order );

    /* S[] values are in Q14 */
    for( k = 0; k < len; k++ ) {
        SA = S[ Order - 1 ];
        out32_Q10 = 0;
        for( j = 0; j < ( Order_half - 1 ); j++ ) {
            idx = SKP_SMULBB( 2, j ) + 1;
            SB = S[ Order - 1 - idx ];
            S[ Order - 1 - idx ] = SA;
            out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
            out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
            SA = S[ Order - 2 - idx ];
            S[ Order - 2 - idx ] = SB;
        }

        /* unrolled loop: epilog */
        SB = S[ 0 ];
        S[ 0 ] = SA;
        out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
        out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
        /* apply gain to excitation signal and add to prediction */
        out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );

        /* scale to Q0 */
        out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );

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

        /* move result into delay line */
        S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
    }
}
/* 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 {
Esempio n. 29
0
void silk_insertion_sort_increasing_all_values_int16(
    SKP_int16           *a,             /* I/O: Unsorted / Sorted vector                */
    const SKP_int       L               /* I:   Vector length                           */
)
{
    SKP_int    value;
    SKP_int    i, j;

    /* Safety checks */
    SKP_assert( L >  0 );

    /* Sort vector elements by value, increasing order */
    for( i = 1; i < L; i++ ) {
        value = a[ i ];
        for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {
            a[ j + 1 ] = a[ j ]; /* Shift value */
        }
        a[ j + 1 ] = value; /* Write value */
    }
}
Esempio n. 30
0
void silk_warped_LPC_analysis_filter_FLP(
          SKP_float                 state[],            /* I/O  State [order + 1]                       */
          SKP_float                 res[],              /* O    Residual signal [length]                */
    const SKP_float                 coef[],             /* I    Coefficients [order]                    */
    const SKP_float                 input[],            /* I    Input signal [length]                   */
    const SKP_float                 lambda,             /* I    Warping factor                          */
    const opus_int                   length,             /* I    Length of input signal                  */
    const opus_int                   order               /* I    Filter order (even)                     */
)
{
    opus_int     n, i;
    SKP_float   acc, tmp1, tmp2;

    /* Order must be even */
    SKP_assert( ( order & 1 ) == 0 );

    for( n = 0; n < length; n++ ) {
        /* Output of lowpass section */
        tmp2 = state[ 0 ] + lambda * state[ 1 ];
        state[ 0 ] = input[ n ];
        /* Output of allpass section */
        tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
        state[ 1 ] = tmp2;
        acc = coef[ 0 ] * tmp2;
        /* Loop over allpass sections */
        for( i = 2; i < order; i += 2 ) {
            /* Output of allpass section */
            tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
            state[ i ] = tmp1;
            acc += coef[ i - 1 ] * tmp1;
            /* Output of allpass section */
            tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
            state[ i + 1 ] = tmp2;
            acc += coef[ i ] * tmp2;
        }
        state[ order ] = tmp1;
        acc += coef[ order - 1 ] * tmp1;
        res[ n ] = input[ n ] - acc;
    }
}