1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/***********************************************************************
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCopyright (c) 2006-2011, Skype Limited. All rights reserved.
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgRedistribution and use in source and binary forms, with or without
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgmodification, are permitted provided that the following conditions
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgare met:
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions of source code must retain the above copyright notice,
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgthis list of conditions and the following disclaimer.
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions in binary form must reproduce the above copyright
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnotice, this list of conditions and the following disclaimer in the
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgdocumentation and/or other materials provided with the distribution.
11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org- Neither the name of Internet Society, IETF or IETF Trust, nor the
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnames of specific contributors, may be used to endorse or promote
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgproducts derived from this software without specific prior written
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgpermission.
15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgPOSSIBILITY OF SUCH DAMAGE.
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org***********************************************************************/
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "define.h"
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "API.h"
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "control.h"
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "typedef.h"
35e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "stack_alloc.h"
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "structs.h"
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "tuning_parameters.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "main_FIX.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "main_FLP.h"
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
446b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org/***************************************/
456b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org/* Read control structure from encoder */
466b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org/***************************************/
476b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic opus_int silk_QueryEncoder(                      /* O    Returns error code                              */
486b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org    const void                      *encState,          /* I    State                                           */
496b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
506b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org);
516b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/****************************************/
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Encoder functions                    */
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/****************************************/
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_int silk_Get_Encoder_Size(                         /* O    Returns error code                              */
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int                        *encSizeBytes       /* O    Number of bytes in SILK encoder state           */
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int ret = SILK_NO_ERROR;
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    *encSizeBytes = sizeof( silk_encoder );
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return ret;
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*************************/
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Init or Reset encoder */
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*************************/
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_int silk_InitEncoder(                              /* O    Returns error code                              */
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    void                            *encState,          /* I/O  State                                           */
723c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    int                              arch,              /* I    Run-time architecture                           */
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_encoder *psEnc;
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int n, ret = SILK_NO_ERROR;
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc = (silk_encoder *)encState;
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Reset encoder */
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_memset( psEnc, 0, sizeof( silk_encoder ) );
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
843c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( 0 );
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->nChannelsAPI = 1;
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->nChannelsInternal = 1;
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Read control structure */
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if( ret += silk_QueryEncoder( encState, encStatus ) ) {
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        silk_assert( 0 );
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return ret;
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/***************************************/
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Read control structure from encoder */
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/***************************************/
1036b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.orgstatic opus_int silk_QueryEncoder(                      /* O    Returns error code                              */
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const void                      *encState,          /* I    State                                           */
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int ret = SILK_NO_ERROR;
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_encoder_state_Fxx *state_Fxx;
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_encoder *psEnc = (silk_encoder *)encState;
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    state_Fxx = psEnc->state_Fxx;
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->nChannelsAPI              = psEnc->nChannelsAPI;
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->nChannelsInternal         = psEnc->nChannelsInternal;
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->API_sampleRate            = state_Fxx[ 0 ].sCmn.API_fs_Hz;
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->maxInternalSampleRate     = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->minInternalSampleRate     = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->payloadSize_ms            = state_Fxx[ 0 ].sCmn.PacketSize_ms;
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->bitRate                   = state_Fxx[ 0 ].sCmn.TargetRate_bps;
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->packetLossPercentage      = state_Fxx[ 0 ].sCmn.PacketLoss_perc;
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->complexity                = state_Fxx[ 0 ].sCmn.Complexity;
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->useInBandFEC              = state_Fxx[ 0 ].sCmn.useInBandFEC;
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->useDTX                    = state_Fxx[ 0 ].sCmn.useDTX;
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->useCBR                    = state_Fxx[ 0 ].sCmn.useCBR;
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->internalSampleRate        = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->allowBandwidthSwitch      = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return ret;
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/**************************/
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Encode frame with Silk */
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/**************************/
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what                     */
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* encControl->payloadSize_ms is set to                                                                         */
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_int silk_Encode(                                   /* O    Returns error code                              */
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    void                            *encState,          /* I/O  State                                           */
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_EncControlStruct           *encControl,        /* I    Control status                                  */
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int16                *samplesIn,         /* I    Speech sample input vector                      */
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int   n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
151e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    opus_int   nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
152e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    opus_int   nSamplesFromInput = 0, nSamplesFromInputMax;
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int   speech_act_thr_for_switch_Q8;
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_encoder *psEnc = ( silk_encoder * )encState;
156e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    VARDECL( opus_int16, buf );
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int transition, curr_block, tot_blocks;
158e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    SAVE_STACK;
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1603c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    if (encControl->reducedDependency)
1613c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    {
1623c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com       psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
1633c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com       psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
1643c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com    }
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Check values in encoder control structure */
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if( ( ret = check_control_input( encControl ) != 0 ) ) {
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        silk_assert( 0 );
170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        RESTORE_STACK;
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        return ret;
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encControl->switchReady = 0;
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Mono -> Stereo transition: init state of second channel and stereo state */
1783c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com        ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.width_prev_Q14 = 0;
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( psEnc->nChannelsAPI == 2 ) {
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State,     &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State,     sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->nChannelsAPI = encControl->nChannelsAPI;
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->nChannelsInternal = encControl->nChannelsInternal;
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    curr_block = 0;
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if( prefillFlag ) {
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Only accept input length of 10 ms */
203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( nBlocksOf10ms != 1 ) {
204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( 0 );
205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            RESTORE_STACK;
206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Reset Encoder */
209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
2103c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
2113c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            silk_assert( !ret );
212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        tmp_payloadSize_ms = encControl->payloadSize_ms;
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        encControl->payloadSize_ms = 10;
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        tmp_complexity = encControl->complexity;
216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        encControl->complexity = 0;
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    } else {
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Only accept input lengths that are a multiple of 10 ms */
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( 0 );
225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            RESTORE_STACK;
226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Make sure no more than one packet can be produced */
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( 0 );
231e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            RESTORE_STACK;
232e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for( n = 0; n < encControl->nChannelsInternal; n++ ) {
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Force the side channel to the same rate as the mid */
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( 0 );
242e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            RESTORE_STACK;
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            return ret;
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Input buffering/resampling and encoding */
255e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    nSamplesToBufferMax =
256e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
257e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    nSamplesFromInputMax =
258e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        silk_DIV32_16( nSamplesToBufferMax *
259e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                           psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
260e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                       psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
261e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    ALLOC( buf, nSamplesFromInputMax, opus_int16 );
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    while( 1 ) {
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        nSamplesToBuffer  = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
264e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org        nSamplesToBuffer  = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Resample and write to buffer */
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( n = 0; n < nSamplesFromInput; n++ ) {
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                buf[ n ] = samplesIn[ 2 * n ];
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Making sure to start both resamplers from the same state when switching from mono to stereo */
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nSamplesToBuffer  = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nSamplesToBuffer  = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( n = 0; n < nSamplesFromInput; n++ ) {
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                buf[ n ] = samplesIn[ 2 * n + 1 ];
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Combine left and right channels before resampling */
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( n = 0; n < nSamplesFromInput; n++ ) {
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum,  1 );
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* On the first mono frame, average the results for the two resampler states  */
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                  + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        samplesIn  += nSamplesFromInput * encControl->nChannelsAPI;
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        nSamplesIn -= nSamplesFromInput;
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Default */
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        psEnc->allowBandwidthSwitch = 0;
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* Silk encoder */
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Enough data in input buffer, so encode */
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Deal with LBRR data */
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Create space at start of payload for VAD and FEC flags */
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_uint8 iCDF[ 2 ] = { 0, 0 };
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Encode any LBRR data from previous packet */
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Encode LBRR flags */
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    LBRR_symbol = 0;
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Code LBRR indices and excitation signals */
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    for( n = 0; n < encControl->nChannelsInternal; n++ ) {
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            opus_int condCoding;
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            if( encControl->nChannelsInternal == 2 && n == 0 ) {
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                    silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                }
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            }
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            /* Use conditional coding if previous frame available */
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                condCoding = CODE_CONDITIONALLY;
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            } else {
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                condCoding = CODE_INDEPENDENTLY;
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            }
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                            silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        }
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Reset LBRR flags */
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_HP_variable_cutoff( psEnc->state_Fxx );
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Total target bits for packet */
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Subtract half of the bits already used */
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( !prefillFlag ) {
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                nBits -= ec_tell( psRangeEnc ) >> 1;
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Divide by number of uncoded frames left in packet */
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded );
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Convert to bits/second */
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( encControl->payloadSize_ms == 10 ) {
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                TargetRate_bps = silk_SMULBB( nBits, 100 );
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            } else {
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                TargetRate_bps = silk_SMULBB( nBits, 50 );
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Subtract fraction of bits in excess of target in previous packets */
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Never exceed input bitrate */
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Convert Left/Right to Mid/Side */
403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( encControl->nChannelsInternal == 2 ) {
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    /* Reset side channel encoder memory for first frame with side coding */
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( psEnc->prev_decode_only_middle == 1 ) {
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_memset( &psEnc->state_Fxx[ 1 ].sShape,               0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt,             0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ,            0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sCmn.prevLag                 = 100;
417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev            = 100;
418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sShape.LastGainIndex         = 10;
419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sCmn.prevSignalType          = TYPE_NO_VOICE_ACTIVITY;
420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16      = 65536;
421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else {
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( !prefillFlag ) {
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            } else {
434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Buffering */
435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );
439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Encode */
441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( n = 0; n < encControl->nChannelsInternal; n++ ) {
442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                opus_int maxBits, useCBR;
443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Handling rate constraints */
445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                maxBits = encControl->maxBits;
446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( tot_blocks == 2 && curr_block == 0 ) {
447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    maxBits = maxBits * 3 / 5;
448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else if( tot_blocks == 3 ) {
449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( curr_block == 0 ) {
450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        maxBits = maxBits * 2 / 5;
451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    } else if( curr_block == 1 ) {
452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        maxBits = maxBits * 3 / 4;
453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                useCBR = encControl->useCBR && curr_block == tot_blocks - 1;
456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( encControl->nChannelsInternal == 1 ) {
458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    channelRate_bps = TargetRate_bps;
459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else {
460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    channelRate_bps = MStargetRates_bps[ n ];
461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        useCBR = 0;
463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        /* Give mid up to 1/2 of the max bits for that frame */
464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        maxBits -= encControl->maxBits / ( tot_blocks * 2 );
465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( channelRate_bps > 0 ) {
469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    opus_int condCoding;
470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );
472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    /* Use independent coding if no previous frame available */
474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        condCoding = CODE_INDEPENDENTLY;
476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    } else if( n > 0 && psEnc->prev_decode_only_middle ) {
477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        /* If we skipped a side frame in this packet, we don't
478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                           need LTP scaling; the LTP state is well-defined. */
479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    } else {
481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        condCoding = CODE_CONDITIONALLY;
482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        silk_assert( 0 );
485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];
492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Insert VAD and FEC flags at beginning of bitstream */
494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                flags = 0;
496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                for( n = 0; n < encControl->nChannelsInternal; n++ ) {
497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        flags  = silk_LSHIFT( flags, 1 );
499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    flags  = silk_LSHIFT( flags, 1 );
502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( !prefillFlag ) {
505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Return zero bytes if all channels DTXed */
509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    *nBytesOut = 0;
511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->nBitsExceeded += *nBytesOut * 8;
514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                psEnc->nBitsExceeded  = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                /* Update flag indicating if bandwidth switching is allowed */
518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->allowBandwidthSwitch = 1;
522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->timeSinceSwitchAllowed_ms = 0;
523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                } else {
524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->allowBandwidthSwitch = 0;
525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if( nSamplesIn == 0 ) {
530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                break;
531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            break;
534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        curr_block++;
536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;
539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if( prefillFlag ) {
545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        encControl->payloadSize_ms = tmp_payloadSize_ms;
546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        encControl->complexity = tmp_complexity;
547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        for( n = 0; n < encControl->nChannelsInternal; n++ ) {
548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
553e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org    RESTORE_STACK;
554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return ret;
555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
557