657 lines
36 KiB
C
657 lines
36 KiB
C
/***********************************************************************
|
|
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, (subject to the limitations in the disclaimer below)
|
|
are permitted provided that the following conditions are met:
|
|
- Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
- Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
- Neither the name of Skype Limited, nor the names of specific
|
|
contributors, may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
|
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
***********************************************************************/
|
|
|
|
#include "SKP_Silk_main_FIX.h"
|
|
|
|
/* 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 ) {
|
|
|
|
/* Check if we should switch from 12 to 16 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 >= MB2WB_BITRATE_BPS ) &&
|
|
( 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 = 16;
|
|
|
|
/* Reset state of the resampler to be used */
|
|
if( API_fs_kHz == 24 ) {
|
|
|
|
SKP_int16 x_bufout[ 2 * 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 3 ];
|
|
|
|
/* Intermediate upsampling of x_bufFIX from 12 to 24 kHz */
|
|
SKP_int16 x_buf24[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 scratch[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 resample12To24state[6];
|
|
|
|
SKP_memset( resample12To24state, 0, sizeof( resample12To24state ) );
|
|
SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample12To24state, &x_buf24[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
|
|
|
|
SKP_memset( psEnc->sCmn.resample24To16state, 0, sizeof( psEnc->sCmn.resample24To16state ) );
|
|
|
|
#if LOW_COMPLEXITY_ONLY
|
|
SKP_assert( sizeof( SKP_int16 ) * ( 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ) <= sizeof( scratch ) );
|
|
SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ), (SKP_int16*)scratch );
|
|
#else
|
|
SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );
|
|
#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.mode = 1; /* Switch up */
|
|
#endif
|
|
} else {
|
|
/* accumulate the difference between the target rate and limit */
|
|
psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - MB2NB_BITRATE_BPS );
|
|
psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 );
|
|
|
|
/* Check if we should switch from 12 to 8 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 ) &&
|
|
#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 = 8;
|
|
|
|
if( API_fs_kHz == 24 ) {
|
|
|
|
SKP_int32 scratch[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
/* Intermediate upsampling of x_buf from 12 to 24 kHz */
|
|
SKP_int16 x_buf24[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 resample12To24state[ 6 ];
|
|
|
|
SKP_memset( resample12To24state, 0, sizeof( resample12To24state ) );
|
|
SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample12To24state, &x_buf24[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
|
|
|
|
/* Update the state of the resampler used in API.c, from 24 to 8 kHz */
|
|
SKP_memset( psEnc->sCmn.resample24To8state, 0, sizeof( psEnc->sCmn.resample24To8state ) );
|
|
SKP_Silk_resample_1_3( &x_buf[ 0 ], psEnc->sCmn.resample24To8state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );
|
|
|
|
/* set the first frame to zero, no performance difference was noticed though */
|
|
SKP_memset( x_buf, 0, 160 * 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 ) {
|
|
/* Intermediate upsampling of x_bufFIX from 12 to 16 kHz */
|
|
SKP_int16 x_buf16[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ];
|
|
SKP_int32 resample12To16state[11];
|
|
|
|
SKP_memset( resample12To16state, 0, sizeof( resample12To16state ) );
|
|
SKP_Silk_resample_3_2( &x_buf16[ 0 ], resample12To16state, &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_buf, 0, 160 * 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 == 12 ) {
|
|
SKP_int16 x_bufout[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 3 ];
|
|
SKP_memset( psEnc->sCmn.resample12To8state, 0, sizeof( psEnc->sCmn.resample12To8state ) );
|
|
#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.resample12To8state, &x_buf[ 0 ],
|
|
SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, scratch );
|
|
}
|
|
#else
|
|
SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample12To8state, &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, 160 * 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 == 8 ) {
|
|
|
|
/* Check if we should switch from 8 to 12 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 >= NB2MB_BITRATE_BPS ) &&
|
|
( 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;
|
|
|
|
/* Reset state of the resampler to be used */
|
|
if( API_fs_kHz == 24 ) {
|
|
SKP_int16 x_buf24[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 scratch[ 3 * 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ];
|
|
SKP_int32 resample8To24state[ 7 ];
|
|
|
|
/* Intermediate upsampling of x_bufFIX from 8 to 24 kHz */
|
|
SKP_memset( resample8To24state, 0, sizeof( resample8To24state ) );
|
|
SKP_Silk_resample_3_1( &x_buf24[ 0 ], resample8To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
|
|
|
|
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 ), 1 ) );
|
|
|
|
/* 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_buf16[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 scratch[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];
|
|
SKP_int32 resample8To16state[ 6 ];
|
|
|
|
/* Intermediate upsampling of x_bufFIX from 8 to 16 kHz */
|
|
SKP_memset( resample8To16state, 0, sizeof( resample8To16state ) );
|
|
SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample8To16state, &x_buf16[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );
|
|
|
|
SKP_memset( psEnc->sCmn.resample16To12state, 0, sizeof( psEnc->sCmn.resample16To12state ) );
|
|
|
|
SKP_Silk_resample_3_4( &x_buf[ 0 ], psEnc->sCmn.resample16To12state, &x_buf16[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );
|
|
|
|
/* 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 ) );
|
|
}
|
|
#if SWITCH_TRANSITION_FILTERING
|
|
psEnc->sCmn.sLP.mode = 1; /* Switch up */
|
|
#endif
|
|
}
|
|
} else {
|
|
// Internal sample frequency not supported!
|
|
SKP_assert( 0 );
|
|
}
|
|
}
|
|
|
|
#if SWITCH_TRANSITION_FILTERING
|
|
/* After switching up, stop transition filter during speech inactivity */
|
|
if( ( psEnc->sCmn.sLP.mode == 1 ) &&
|
|
( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) &&
|
|
( psEnc->speech_activity_Q8 < 128 ) &&
|
|
( psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {
|
|
|
|
psEnc->sCmn.sLP.transition_frame_no = 0;
|
|
|
|
/* Reset transition filter state */
|
|
SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/* Set internal sampling frequency */
|
|
if( psEnc->sCmn.fs_kHz != fs_kHz ) {
|
|
/* reset part of the state */
|
|
SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FIX ) );
|
|
SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FIX ) );
|
|
SKP_memset( &psEnc->sNSQ, 0, sizeof( SKP_Silk_nsq_state ) );
|
|
SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FIX ) );
|
|
SKP_memset( psEnc->sNSQ.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );
|
|
SKP_memset( psEnc->sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );
|
|
SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) );
|
|
#if SWITCH_TRANSITION_FILTERING
|
|
SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
|
|
if( psEnc->sCmn.sLP.mode == 1 ) {
|
|
/* Begin transition phase */
|
|
psEnc->sCmn.sLP.transition_frame_no = 1;
|
|
} else {
|
|
/* End transition phase */
|
|
psEnc->sCmn.sLP.transition_frame_no = 0;
|
|
}
|
|
#endif
|
|
psEnc->sCmn.inputBufIx = 0;
|
|
psEnc->sCmn.nFramesInPayloadBuf = 0;
|
|
psEnc->sCmn.nBytesInPayloadBuf = 0;
|
|
psEnc->sCmn.oldest_LBRR_idx = 0;
|
|
psEnc->sCmn.TargetRate_bps = 0; /* ensures that psEnc->SNR_dB is recomputed */
|
|
|
|
SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
|
|
|
|
/* Initialize non-zero parameters */
|
|
psEnc->sCmn.prevLag = 100;
|
|
psEnc->sCmn.prev_sigtype = SIG_TYPE_UNVOICED;
|
|
psEnc->sCmn.first_frame_after_reset = 1;
|
|
psEnc->sPrefilt.lagPrev = 100;
|
|
psEnc->sShape.LastGainIndex = 1;
|
|
psEnc->sNSQ.lagPrev = 100;
|
|
psEnc->sNSQ.prev_inv_gain_Q16 = 65536;
|
|
psEnc->sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
|
|
psEnc->sCmn.fs_kHz = fs_kHz;
|
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
|
psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
|
|
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
|
|
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
|
|
} else {
|
|
psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
|
|
psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
|
|
psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
|
|
}
|
|
psEnc->sCmn.frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
|
|
psEnc->sCmn.subfr_length = SKP_DIV32_16( psEnc->sCmn.frame_length, NB_SUBFR );
|
|
psEnc->sCmn.la_pitch = SKP_SMULBB( LA_PITCH_MS, fs_kHz );
|
|
psEnc->sCmn.la_shape = SKP_SMULBB( LA_SHAPE_MS, fs_kHz );
|
|
psEnc->sPred.min_pitch_lag = SKP_SMULBB( 3, fs_kHz );
|
|
psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz );
|
|
psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
|
|
if( psEnc->sCmn.fs_kHz == 24 ) {
|
|
psEnc->mu_LTP_Q8 = MU_LTP_QUANT_SWB_Q8;
|
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
|
psEnc->mu_LTP_Q8 = MU_LTP_QUANT_WB_Q8;
|
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
|
psEnc->mu_LTP_Q8 = MU_LTP_QUANT_MB_Q8;
|
|
} else {
|
|
psEnc->mu_LTP_Q8 = MU_LTP_QUANT_NB_Q8;
|
|
}
|
|
psEnc->sCmn.fs_kHz_changed = 1;
|
|
|
|
/* Check that settings are valid */
|
|
SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length );
|
|
}
|
|
|
|
/* Set encoding complexity */
|
|
if( Complexity == 0 || LOW_COMPLEXITY_ONLY ) {
|
|
/* Low complexity */
|
|
psEnc->sCmn.Complexity = 0;
|
|
psEnc->sCmn.pitchEstimationComplexity = PITCH_EST_COMPLEXITY_LC_MODE;
|
|
psEnc->pitchEstimationThreshold_Q16 = FIND_PITCH_CORRELATION_THRESHOLD_Q16_LC_MODE;
|
|
psEnc->sCmn.pitchEstimationLPCOrder = 8;
|
|
psEnc->sCmn.shapingLPCOrder = 12;
|
|
psEnc->sCmn.nStatesDelayedDecision = 1;
|
|
psEnc->NoiseShapingQuantizer = SKP_Silk_NSQ;
|
|
psEnc->sCmn.useInterpolatedNLSFs = 0;
|
|
psEnc->sCmn.LTPQuantLowComplexity = 1;
|
|
psEnc->sCmn.NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_LC_MODE;
|
|
} else if( Complexity == 1 ) {
|
|
/* Medium complexity */
|
|
psEnc->sCmn.Complexity = 1;
|
|
psEnc->sCmn.pitchEstimationComplexity = PITCH_EST_COMPLEXITY_MC_MODE;
|
|
psEnc->pitchEstimationThreshold_Q16 = FIND_PITCH_CORRELATION_THRESHOLD_Q16_MC_MODE;
|
|
psEnc->sCmn.pitchEstimationLPCOrder = 12;
|
|
psEnc->sCmn.shapingLPCOrder = 16;
|
|
psEnc->sCmn.nStatesDelayedDecision = 2;
|
|
psEnc->NoiseShapingQuantizer = SKP_Silk_NSQ_del_dec;
|
|
psEnc->sCmn.useInterpolatedNLSFs = 0;
|
|
psEnc->sCmn.LTPQuantLowComplexity = 0;
|
|
psEnc->sCmn.NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_MC_MODE;
|
|
} else if( Complexity == 2 ) {
|
|
/* High complexity */
|
|
psEnc->sCmn.Complexity = 2;
|
|
psEnc->sCmn.pitchEstimationComplexity = PITCH_EST_COMPLEXITY_HC_MODE;
|
|
psEnc->pitchEstimationThreshold_Q16 = FIND_PITCH_CORRELATION_THRESHOLD_Q16_HC_MODE;
|
|
psEnc->sCmn.pitchEstimationLPCOrder = 16;
|
|
psEnc->sCmn.shapingLPCOrder = 16;
|
|
psEnc->sCmn.nStatesDelayedDecision = 4;
|
|
psEnc->NoiseShapingQuantizer = SKP_Silk_NSQ_del_dec;
|
|
psEnc->sCmn.useInterpolatedNLSFs = 1;
|
|
psEnc->sCmn.LTPQuantLowComplexity = 0;
|
|
psEnc->sCmn.NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS;
|
|
} else {
|
|
ret = SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING;
|
|
}
|
|
|
|
/* Dont have higher Pitch estimation LPC order than predict LPC order */
|
|
psEnc->sCmn.pitchEstimationLPCOrder = SKP_min_int( psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.predictLPCOrder );
|
|
|
|
SKP_assert( psEnc->sCmn.pitchEstimationLPCOrder <= FIND_PITCH_LPC_ORDER_MAX );
|
|
SKP_assert( psEnc->sCmn.shapingLPCOrder <= SHAPE_LPC_ORDER_MAX );
|
|
SKP_assert( psEnc->sCmn.nStatesDelayedDecision <= DEL_DEC_STATES_MAX );
|
|
|
|
/* Set bitrate/coding quality */
|
|
TargetRate_bps = SKP_min( TargetRate_bps, 100000 );
|
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
|
TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_NB_BPS );
|
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
|
TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_MB_BPS );
|
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
|
TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_WB_BPS );
|
|
} else {
|
|
TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_SWB_BPS );
|
|
}
|
|
if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {
|
|
psEnc->sCmn.TargetRate_bps = TargetRate_bps;
|
|
|
|
/* if new TargetRate_bps, translate to SNR_dB value */
|
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
|
rateTable = TargetRate_table_NB;
|
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
|
rateTable = TargetRate_table_MB;
|
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
|
rateTable = TargetRate_table_WB;
|
|
} else {
|
|
rateTable = TargetRate_table_SWB;
|
|
}
|
|
for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
|
|
/* find bitrate interval in table and interpolate */
|
|
if( TargetRate_bps < rateTable[ k ] ) {
|
|
frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] );
|
|
psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set packet size */
|
|
if( ( PacketSize_ms != 20 ) &&
|
|
( PacketSize_ms != 40 ) &&
|
|
( PacketSize_ms != 60 ) &&
|
|
( PacketSize_ms != 80 ) &&
|
|
( PacketSize_ms != 100 ) ) {
|
|
ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
|
|
} else {
|
|
if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
|
|
psEnc->sCmn.PacketSize_ms = PacketSize_ms;
|
|
|
|
/* Packet length changes. Reset LBRR buffer */
|
|
SKP_Silk_LBRR_reset( &psEnc->sCmn );
|
|
}
|
|
}
|
|
|
|
/* Set packet loss rate measured by farend */
|
|
if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) {
|
|
ret = SKP_SILK_ENC_WRONG_LOSS_RATE;
|
|
}
|
|
psEnc->sCmn.PacketLoss_perc = PacketLoss_perc;
|
|
|
|
#if USE_LBRR
|
|
if( INBandFec_enabled < 0 || INBandFec_enabled > 1 ) {
|
|
ret = SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING;
|
|
}
|
|
|
|
/* Only change settings if first frame in packet */
|
|
if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
|
|
|
|
psEnc->sCmn.LBRR_enabled = INBandFec_enabled;
|
|
if( psEnc->sCmn.fs_kHz == 8 ) {
|
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;
|
|
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;;
|
|
} else if( psEnc->sCmn.fs_kHz == 16 ) {
|
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;
|
|
} else {
|
|
LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;
|
|
}
|
|
|
|
if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {
|
|
/* Set gain increase / rate reduction for LBRR usage */
|
|
/* Coarse tuned with pesq for now. */
|
|
/* Linear regression coefs G = 8 - 0.5 * loss */
|
|
/* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */
|
|
psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );
|
|
|
|
/* Set main stream rate compensation */
|
|
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {
|
|
/* Tuned to give aprox same mean / weighted bitrate as no inband FEC */
|
|
psEnc->inBandFEC_SNR_comp_Q8 = ( 6 << 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 );
|
|
} else {
|
|
psEnc->inBandFEC_SNR_comp_Q8 = 0;
|
|
psEnc->sCmn.LBRR_enabled = 0;
|
|
}
|
|
} else {
|
|
psEnc->inBandFEC_SNR_comp_Q8 = 0;
|
|
psEnc->sCmn.LBRR_enabled = 0;
|
|
}
|
|
}
|
|
#else
|
|
psEnc->sCmn.LBRR_enabled = 0;
|
|
#endif
|
|
|
|
/* Set DTX mode */
|
|
if( DTX_enabled < 0 || DTX_enabled > 1 ) {
|
|
ret = SKP_SILK_ENC_WRONG_DTX_SETTING;
|
|
}
|
|
psEnc->sCmn.useDTX = DTX_enabled;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Control low bitrate redundancy usage */
|
|
void SKP_Silk_LBRR_ctrl_FIX(
|
|
SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
|
SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control */
|
|
)
|
|
{
|
|
SKP_int LBRR_usage;
|
|
|
|
if( psEnc->sCmn.LBRR_enabled ) {
|
|
/* Control LBRR */
|
|
|
|
/* Usage Control based on sensitivity and packet loss caracteristics */
|
|
/* For now only enable adding to next for active frames. Make more complex later */
|
|
LBRR_usage = SKP_SILK_NO_LBRR;
|
|
if( psEnc->speech_activity_Q8 > LBRR_SPEECH_ACTIVITY_THRES_Q8 && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity
|
|
//if( psEnc->PacketLoss_burst > BURST_THRES )
|
|
// psEncCtrl->LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS2;
|
|
//} else {
|
|
LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1;//SKP_SILK_NO_LBRR
|
|
//}
|
|
}
|
|
psEncCtrl->sCmn.LBRR_usage = LBRR_usage;
|
|
} else {
|
|
psEncCtrl->sCmn.LBRR_usage = SKP_SILK_NO_LBRR;
|
|
}
|
|
}
|