ref: 8a8b76efeeccaccf402b0b2b4e469980d0a48311
parent: f90395ba0669dc1c2749ca671cca965cc6dcda8e
author: Koen Vos <[email protected]>
date: Wed Apr 27 17:45:48 EDT 2011
Interface for bandwidth switching
--- a/interface/SKP_Silk_control.h
+++ b/interface/SKP_Silk_control.h
@@ -82,6 +82,12 @@
/* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */
SKP_int32 internalSampleRate;
+
+ /* O: Flag that bandwidth switching is allowed (because low voice activity) */
+ SKP_int allowBandwidthSwitch;
+
+ /* O: Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */
+ SKP_int inWBmodeWithoutVariableLP;
} SKP_SILK_SDK_EncControlStruct;
/**************************************************************************/
--- a/src_FIX/SKP_Silk_main_FIX.h
+++ b/src_FIX/SKP_Silk_main_FIX.h
@@ -70,7 +70,8 @@
SKP_int SKP_Silk_control_encoder(
SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control structure */
- const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
+ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
+ const SKP_int allow_bw_switch /* I Flag to allow switching audio bandwidth */
);
/****************/
--- a/src_FLP/SKP_Silk_main_FLP.h
+++ b/src_FLP/SKP_Silk_main_FLP.h
@@ -68,7 +68,8 @@
SKP_int SKP_Silk_control_encoder(
SKP_Silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control structure */
- const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
+ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
+ const SKP_int allow_bw_switch /* I Flag to allow switching audio bandwidth */
);
/****************/
--- a/src_common/SKP_Silk_control_audio_bandwidth.c
+++ b/src_common/SKP_Silk_control_audio_bandwidth.c
@@ -50,7 +50,11 @@
fs_kHz = SKP_DIV32_16( fs_Hz, 1000 );
} else {
/* State machine for the internal sampling rate switching */
- if( psEncC->API_fs_Hz > 8000 && psEncC->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) {
+ if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
+ /* Stop transition phase */
+ psEncC->sLP.mode = 0;
+ }
+ if( psEncC->allow_bandwidth_switch ) {
/* Check if we should switch down */
if( SKP_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
{
@@ -84,14 +88,12 @@
/* New transition */
psEncC->sLP.transition_frame_no = 0;
+
+ /* Reset transition filter state */
+ SKP_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
}
- if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
- /* Stop transition phase */
- psEncC->sLP.mode = 0;
- } else {
- /* Direction: up */
- psEncC->sLP.mode = 1;
- }
+ /* Direction: up */
+ psEncC->sLP.mode = 1;
}
}
}
--- a/src_common/SKP_Silk_control_codec.c
+++ b/src_common/SKP_Silk_control_codec.c
@@ -60,18 +60,20 @@
SKP_int SKP_Silk_control_encoder(
SKP_Silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control structure */
- const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
+ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
+ const SKP_int allow_bw_switch /* I Flag to allow switching audio bandwidth */
)
{
SKP_int fs_kHz, ret = 0;
- psEnc->sCmn.useDTX = encControl->useDTX;
- psEnc->sCmn.useCBR = encControl->useCBR;
- psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
- psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
- psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
- psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
- psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
+ psEnc->sCmn.useDTX = encControl->useDTX;
+ psEnc->sCmn.useCBR = encControl->useCBR;
+ psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
+ psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
+ psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
+ psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
+ psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
+ psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;
if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {
if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
--- a/src_common/SKP_Silk_enc_API.c
+++ b/src_common/SKP_Silk_enc_API.c
@@ -31,6 +31,7 @@
#include "SKP_Silk_control.h"
#include "SKP_Silk_typedef.h"
#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tuning_parameters.h"
#if FIXED_POINT
#include "SKP_Silk_main_FIX.h"
#define SKP_Silk_encoder_state_Fxx SKP_Silk_encoder_state_FIX
@@ -47,6 +48,8 @@
stereo_state sStereo;
SKP_int32 nBitsExceeded;
SKP_int nChannels;
+ SKP_int timeSinceSwitchAllowed_ms;
+ SKP_int allowBandwidthSwitch;
} SKP_Silk_encoder;
/****************************************/
@@ -138,6 +141,7 @@
{
SKP_int n, i, nBits, flags, tmp_payloadSize_ms, tmp_complexity, MS_predictorIx = 0, ret = 0;
SKP_int nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0;
+ SKP_int speech_act_thr_for_switch_Q8;
SKP_int32 TargetRate_bps, channelRate_bps, LBRR_symbol;
SKP_Silk_encoder *psEnc = ( SKP_Silk_encoder * )encState;
SKP_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ];
@@ -194,7 +198,7 @@
TargetRate_bps = SKP_RSHIFT32( encControl->bitRate, encControl->nChannels - 1 );
for( n = 0; n < encControl->nChannels; n++ ) {
- if( ( ret = SKP_Silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps ) ) != 0 ) {
+ if( ( ret = SKP_Silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch ) ) != 0 ) {
SKP_assert( 0 );
return ret;
}
@@ -232,6 +236,9 @@
samplesIn += nSamplesFromInput * encControl->nChannels;
nSamplesIn -= nSamplesFromInput;
+ /* Default */
+ psEnc->allowBandwidthSwitch = 0;
+
/* Silk encoder */
if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
/* Enough data in input buffer, so encode */
@@ -340,6 +347,17 @@
psEnc->nBitsExceeded += *nBytesOut * 8;
psEnc->nBitsExceeded -= SKP_DIV32_16( SKP_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
psEnc->nBitsExceeded = SKP_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
+
+ /* Update flag indicating if bandwidth switching is allowed */
+ speech_act_thr_for_switch_Q8 = SKP_SMLAWB( SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
+ SKP_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
+ if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
+ psEnc->allowBandwidthSwitch = 1;
+ psEnc->timeSinceSwitchAllowed_ms = 0;
+ } else {
+ psEnc->allowBandwidthSwitch = 0;
+ psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
+ }
}
if( nSamplesIn == 0 ) {
@@ -350,6 +368,8 @@
}
}
+ encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
+ encControl->inWBmodeWithoutVariableLP = ( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 ) && ( psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0 );
encControl->internalSampleRate = SKP_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
if( prefillFlag ) {
encControl->payloadSize_ms = tmp_payloadSize_ms;
--- a/src_common/SKP_Silk_structs.h
+++ b/src_common/SKP_Silk_structs.h
@@ -128,6 +128,7 @@
SKP_Silk_nsq_state sNSQ; /* Noise Shape Quantizer State */
SKP_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ];/* Previously quantized NLSF vector */
SKP_int speech_activity_Q8; /* Speech activity */
+ SKP_int allow_bandwidth_switch; /* Flag indicating that switching of internal bandwidth is allowed */
SKP_int8 LBRRprevLastGainIndex;
SKP_int8 prevSignalType;
SKP_int prevLag;
--- a/src_common/SKP_Silk_tuning_parameters.h
+++ b/src_common/SKP_Silk_tuning_parameters.h
@@ -159,6 +159,9 @@
/* Compensation in bitrate calculations for 10 ms modes */
#define REDUCE_BITRATE_10_MS_BPS 2200
+/* Maximum time before allowing a bandwidth transition */
+#define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000
+
#ifdef __cplusplus
}
#endif