Ejemplo n.º 1
0
/* Resamples by a factor 3/2 */
void SKP_Silk_resample_3_2(int16_t * out,	/*   O: Fs_high signal  [inLen*3/2]             */
			   int32_t * S,	/* I/O: State vector    [7+4]                   */
			   const int16_t * in,	/* I:   Fs_low signal   [inLen]                 */
			   int inLen	/* I:   Input length, must be a multiple of 2   */
    )
{
	int LSubFrameIn, LSubFrameOut;
	int16_t outH[3 * IN_SUBFR_LEN_RESAMPLE_3_2];
	int32_t scratch[(9 * IN_SUBFR_LEN_RESAMPLE_3_2) / 2];

	/* Check that input is multiple of 2 */
	assert(inLen % 2 == 0);

	while (inLen > 0) {
		LSubFrameIn = SKP_min_int(IN_SUBFR_LEN_RESAMPLE_3_2, inLen);
		LSubFrameOut = SKP_SMULWB(98304, LSubFrameIn);

		/* Upsample by a factor 3 */
		SKP_Silk_resample_3_1(outH, &S[0], in, LSubFrameIn);

		/* Downsample by a factor 2 */
		/* Scratch size needs to be: 3 * LSubFrameOut * sizeof( int32_t ) */
		SKP_Silk_resample_1_2_coarse(outH, &S[7], out, scratch,
					     LSubFrameOut);

		in += LSubFrameIn;
		out += LSubFrameOut;
		inLen -= LSubFrameIn;
	}
}
Ejemplo n.º 2
0
/* Resamples by a factor 3/4 */
void SKP_Silk_resample_3_4(int16_t * out,	/* O:   Fs_high signal  [inLen*3/4]              */
			   int32_t * S,	/* I/O: State vector    [7+2+6]                  */
			   const int16_t * in,	/* I:   Fs_low signal   [inLen]                  */
			   int inLen	/* I:   Input length, must be a multiple of 4    */
    )
{
	int LSubFrameIn, LSubFrameOut;
	int16_t outH[3 * IN_SUBFR_LEN_RESAMPLE_3_4];
	int16_t outL[(3 * IN_SUBFR_LEN_RESAMPLE_3_4) / 2];
	int32_t scratch[(9 * IN_SUBFR_LEN_RESAMPLE_3_4) / 2];

	/* Check that input is multiple of 4 */
	assert(inLen % 4 == 0);

	while (inLen > 0) {
		LSubFrameIn = SKP_min_int(IN_SUBFR_LEN_RESAMPLE_3_4, inLen);
		LSubFrameOut = SKP_SMULWB(49152, LSubFrameIn);

		/* Upsample by a factor 3 */
		SKP_Silk_resample_3_1(outH, &S[0], in, LSubFrameIn);

		/* Downsample by a factor 2 twice */
		/* Scratch size needs to be: 3 * 2 * LSubFrameOut * sizeof( int32_t ) */
		/* I: state vector [2], scratch memory [3*len] */
		SKP_Silk_resample_1_2_coarsest(outH, &S[7], outL, scratch,
					       SKP_LSHIFT(LSubFrameOut, 1));

		/* Scratch size needs to be: 3 * LSubFrameOut * sizeof( int32_t ) */
		/* I: state vector [6], scratch memory [3*len]    */
		SKP_Silk_resample_1_2_coarse(outL, &S[9], out, scratch,
					     LSubFrameOut);

		in += LSubFrameIn;
		out += LSubFrameOut;
		inLen -= LSubFrameIn;
	}
}
/* Control encoder SNR */
SKP_int SKP_Silk_control_encoder_FIX( 
    SKP_Silk_encoder_state_FIX  *psEnc,             /* I/O  Pointer to Silk encoder state                   */
    const SKP_int               API_fs_kHz,         /* I    External (API) sampling rate (kHz)              */
    const SKP_int               PacketSize_ms,      /* I    Packet length (ms)                              */
    SKP_int32                   TargetRate_bps,     /* I    Target max bitrate (bps) (used if SNR_dB == 0)  */
    const SKP_int               PacketLoss_perc,    /* I    Packet loss rate (in percent)                   */
    const SKP_int               INBandFec_enabled,  /* I    Enable (1) / disable (0) inband FEC             */
    const SKP_int               DTX_enabled,        /* I    Enable / disable DTX                            */
    const SKP_int               InputFramesize_ms,  /* I    Inputframe in ms                                */
    const SKP_int               Complexity          /* I    Complexity (0->low; 1->medium; 2->high)         */
)
{
    SKP_int32 LBRRRate_thres_bps;
    SKP_int   k, fs_kHz, ret = 0;
    SKP_int32 frac_Q6;
    const SKP_int32 *rateTable;

    /* State machine for the SWB/WB switching */
    fs_kHz = psEnc->sCmn.fs_kHz;
    
    /* Only switch during low speech activity, when no frames are sitting in the payload buffer */
    if( API_fs_kHz == 8 || fs_kHz == 0 || API_fs_kHz < fs_kHz ) {
        // Switching is not possible, encoder just initialized, or internal mode higher than external
        fs_kHz = API_fs_kHz;
    } else {

        /* Resample all valid data in x_buf. Resampling the last part gets rid of a click, 5ms after switching  */
        /* this is because the same state is used when downsampling in API.c and is then up to date             */
        /* the click immidiatly after switching is most of the time still there                                 */

        if( psEnc->sCmn.fs_kHz == 24 ) {
            /* Accumulate the difference between the target rate and limit */
            if( psEnc->sCmn.fs_kHz_changed == 0 ) {
                psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS_INITIAL );
            } else {
                psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS );
            }
            psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 );

            /* Check if we should switch from 24 to 16 kHz */
#if SWITCH_TRANSITION_FILTERING
            if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */
                ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) &&
                ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {
                psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */
                psEnc->sCmn.sLP.mode = 0; /* Switch down */
            }

            if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */
#else
            if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) &&
#endif
                ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {

                    SKP_int16 x_buf[    2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; 
                    SKP_int16 x_bufout[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];
                    
                    psEnc->sCmn.bitrateDiff = 0;
                    fs_kHz = 16;

                    SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );

                    SKP_memset( psEnc->sCmn.resample24To16state, 0, sizeof( psEnc->sCmn.resample24To16state ) );
                    
#if LOW_COMPLEXITY_ONLY
                    {
                        SKP_int16 scratch[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ];
                        SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, (SKP_int16*)scratch );
                    }
#else
                    SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
#endif

                    /* set the first frame to zero, no performance difference was noticed though */
                    SKP_memset( x_bufout, 0, 320 * sizeof( SKP_int16 ) );
                    SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );

#if SWITCH_TRANSITION_FILTERING
                    psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */
#endif
            }
        } else if( psEnc->sCmn.fs_kHz == 16 ) {

            /* Check if we should switch from 16 to 24 kHz */
#if SWITCH_TRANSITION_FILTERING
            if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* No transition phase running, ready to switch */
#else
            if(
#endif
                ( API_fs_kHz > psEnc->sCmn.fs_kHz && TargetRate_bps >= WB2SWB_BITRATE_BPS && psEnc->sCmn.sSWBdetect.WB_detected == 0 ) && 
                ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {

                SKP_int16 x_buf[          2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; 
                SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; 
                SKP_int32 resample16To24state[ 11 ];

                psEnc->sCmn.bitrateDiff = 0;
                fs_kHz = 24;
                
                SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );

                SKP_memset( resample16To24state, 0, sizeof(resample16To24state) );
                
                SKP_Silk_resample_3_2( &x_bufout[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );

                /* set the first frame to zero, no performance difference was noticed though */
                SKP_memset( x_bufout, 0, 480 * sizeof( SKP_int16 ) );
                SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );
#if SWITCH_TRANSITION_FILTERING
                psEnc->sCmn.sLP.mode = 1; /* Switch up */
#endif
            } else { 
                /* accumulate the difference between the target rate and limit */
                psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - WB2MB_BITRATE_BPS );
                psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 );

                /* Check if we should switch from 16 to 12 kHz */
#if SWITCH_TRANSITION_FILTERING
                if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */
                    ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&
                    ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {
                    psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */
                    psEnc->sCmn.sLP.mode = 0; /* Switch down */
                }

                if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */
#else
                if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&
#endif
                    ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {

                    SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; 

                    SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );
    
                    psEnc->sCmn.bitrateDiff = 0;
                    fs_kHz = 12;
                    
                    if( API_fs_kHz == 24 ) {

                        /* Intermediate upsampling of x_bufFIX from 16 to 24 kHz */
                        SKP_int16 x_buf24[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; 
                        SKP_int32 scratch[    3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
                        SKP_int32 resample16To24state[ 11 ];

                        SKP_memset( resample16To24state, 0, sizeof( resample16To24state ) );
                        SKP_Silk_resample_3_2( &x_buf24[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );

                        /* Update the state of the resampler used in API.c, from 24 to 12 kHz */
                        SKP_memset( psEnc->sCmn.resample24To12state, 0, sizeof( psEnc->sCmn.resample24To12state ) );
                        SKP_Silk_resample_1_2_coarse( &x_buf24[ 0 ], psEnc->sCmn.resample24To12state, &x_buf[ 0 ], scratch, SKP_RSHIFT( SKP_SMULBB( 3, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ), 2 ) );

                        /* set the first frame to zero, no performance difference was noticed though */
                        SKP_memset( x_buf, 0, 240 * sizeof( SKP_int16 ) );
                        SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );

                    } else if( API_fs_kHz == 16 ) {
                        SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 4 ]; 
                        SKP_memset( psEnc->sCmn.resample16To12state, 0, sizeof( psEnc->sCmn.resample16To12state ) );
                        
                        SKP_Silk_resample_3_4( &x_bufout[ 0 ], psEnc->sCmn.resample16To12state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
                    
                        /* set the first frame to zero, no performance difference was noticed though */
                        SKP_memset( x_bufout, 0, 240 * sizeof( SKP_int16 ) );
                        SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );
                    }
#if SWITCH_TRANSITION_FILTERING
                    psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */
#endif
                }
            }
        } else if( psEnc->sCmn.fs_kHz == 12 ) {