shithub: opus

Download patch

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