1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/******************************************************************
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iLBC Speech Coder ANSI-C Source Code
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIlbcfix_Encode.c
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org******************************************************************/
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "defines.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "lpc_encode.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "frame_classify.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "state_search.h"
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "state_construct.h"
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "constants.h"
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "cb_search.h"
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "cb_construct.h"
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "index_conv_enc.h"
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pack_bits.h"
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "hp_input.h"
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "unpack_bits.h"
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "index_conv_dec.h"
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
35d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "swap_bytes.h"
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*----------------------------------------------------------------*
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  main encoder function
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *---------------------------------------------------------------*/
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIlbcfix_EncodeImpl(
44fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    uint16_t *bytes,     /* (o) encoded data bits iLBC */
45fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    const int16_t *block, /* (i) speech vector to encode */
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     state */
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                          ){
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int n, meml_gotten, Nfor, Nback;
50fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t diff, start_pos;
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int index;
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int subcount, subframe;
53fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t start_count, end_count;
54fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *residual;
55fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int32_t en1, en2;
56fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t scale, max;
57fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *syntdenum;
58fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *decresidual;
59fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *reverseResidual;
60fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *reverseDecresidual;
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* Stack based */
62fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
63fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t dataVec[BLOCKL_MAX + LPC_FILTERORDER];
64fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t memVec[CB_MEML+CB_FILTERLEN];
65fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t bitsMemory[sizeof(iLBC_bits)/sizeof(int16_t)];
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  iLBC_bits *iLBCbits_inst = (iLBC_bits*)bitsMemory;
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
70fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *weightdenumbuf = iLBCenc_inst->weightdenumbuf;
71fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t last_bit;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
74fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *data = &dataVec[LPC_FILTERORDER];
75fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  int16_t *mem = &memVec[CB_HALFFILTERLEN];
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* Reuse som buffers to save stack memory */
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  residual = &iLBCenc_inst->lpc_buffer[LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl];
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  syntdenum = mem;      /* syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX] and mem are used non overlapping in the code */
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  decresidual = residual;     /* Already encoded residual is overwritten by the decoded version */
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  reverseResidual = data;     /* data and reverseResidual are used non overlapping in the code */
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  reverseDecresidual = reverseResidual; /* Already encoded residual is overwritten by the decoded version */
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
86fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  WebRtcSpl_MemSetW16 (  (int16_t *) iLBCbits_inst, 0,
87fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org                         (int16_t) (sizeof(iLBC_bits) / sizeof(int16_t))  );
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  start_pos = iLBCenc_inst->start_pos;
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  diff = iLBCenc_inst->diff;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (iLBCenc_inst->section != 0){
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (weightdenum, weightdenumbuf,
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Un-Packetize the frame into parameters */
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    last_bit = WebRtcIlbcfix_UnpackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (last_bit)
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* adjust index */
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_IndexConvDec (iLBCbits_inst->cb_index);
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->section == 1){
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* Save first 80 samples of a 160/240 sample frame for 20/30msec */
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples, block, 80);
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else{ // iLBCenc_inst->section == 2 AND mode = 30ms
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* Save second 80 samples of a 240 sample frame for 30msec */
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples + 80, block, 80);
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  else{ // iLBCenc_inst->section == 0
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* form a complete frame of 160/240 for 20msec/30msec mode */
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (data + (iLBCenc_inst->mode * 8) - 80, block, 80);
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (data, iLBCenc_inst->past_samples,
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           (iLBCenc_inst->mode * 8) - 80);
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->Nfor_flag = 0;
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->Nback_flag = 0;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* copy input block to data*/
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16(data,block,iLBCenc_inst->blockl);
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* high pass filtering of input signal and scale down the residual (*0.5) */
124fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    WebRtcIlbcfix_HpInput(data, (int16_t*)WebRtcIlbcfix_kHpInCoefs,
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                          iLBCenc_inst->hpimemy, iLBCenc_inst->hpimemx,
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                          iLBCenc_inst->blockl);
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* LPC of hp filtered input data */
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_LpcEncode(syntdenum, weightdenum, iLBCbits_inst->lsf, data,
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                            iLBCenc_inst);
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Set up state */
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16(dataVec, iLBCenc_inst->anaMem, LPC_FILTERORDER);
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* inverse filter to get residual */
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (n=0; n<iLBCenc_inst->nsub; n++ ) {
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcSpl_FilterMAFastQ12(
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          &data[n*SUBL], &residual[n*SUBL],
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          &syntdenum[n*(LPC_FILTERORDER+1)],
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          LPC_FILTERORDER+1, SUBL);
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Copy the state for next frame */
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->anaMem, &data[iLBCenc_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* find state location */
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCbits_inst->startIdx = WebRtcIlbcfix_FrameClassify(iLBCenc_inst,residual);
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* check if state should be in first or last part of the
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       two subframes */
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    index = (iLBCbits_inst->startIdx-1)*SUBL;
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    max=WebRtcSpl_MaxAbsValueW16(&residual[index], 2*SUBL);
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max));
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Scale to maximum 25 bits so that the MAC won't cause overflow */
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    scale = scale - 25;
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(scale < 0) {
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      scale = 0;
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    diff = STATE_LEN - iLBCenc_inst->state_short_len;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    en1=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      iLBCenc_inst->state_short_len, scale);
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    index += diff;
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    en2=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      iLBCenc_inst->state_short_len, scale);
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (en1 > en2) {
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      iLBCbits_inst->state_first = 1;
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      start_pos = (iLBCbits_inst->startIdx-1)*SUBL;
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    } else {
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      iLBCbits_inst->state_first = 0;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      start_pos = (iLBCbits_inst->startIdx-1)*SUBL + diff;
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* scalar quantization of state */
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_StateSearch(iLBCenc_inst, iLBCbits_inst, &residual[start_pos],
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                              &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                              &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)]);
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_StateConstruct(iLBCbits_inst->idxForMax, iLBCbits_inst->idxVec,
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                 &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                 &decresidual[start_pos], iLBCenc_inst->state_short_len
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                 );
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* predictive quantization in state */
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCbits_inst->state_first) { /* put adaptive part in the end */
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* setup memory */
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
194fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org      WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCenc_inst->state_short_len));
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCenc_inst->state_short_len,
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                            decresidual+start_pos, iLBCenc_inst->state_short_len);
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* encode subframes */
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &residual[start_pos+iLBCenc_inst->state_short_len],
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &weightdenum[iLBCbits_inst->startIdx*(LPC_FILTERORDER+1)], 0);
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* construct decoded vector */
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len],
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                diff
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                );
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else { /* put adaptive part in the beginning */
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* create reversed vectors for prediction */
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcSpl_MemCpyReversedOrder(&reverseResidual[diff-1],
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    &residual[(iLBCbits_inst->startIdx+1)*SUBL-STATE_LEN], diff);
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* setup memory */
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      meml_gotten = iLBCenc_inst->state_short_len;
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[start_pos], meml_gotten);
225fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org      WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCenc_inst->state_short_len));
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* encode subframes */
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             reverseResidual, mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             0);
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* construct decoded vector */
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbConstruct(reverseDecresidual,
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                diff
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                );
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* get decoded residual from reversed vector */
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], reverseDecresidual, diff);
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->start_pos = start_pos;
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->diff = diff;
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->section++;
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* adjust index */
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Packetize the parameters into the frame */
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* forward prediction of subframes */
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Nfor = iLBCenc_inst->nsub-iLBCbits_inst->startIdx-1;
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* counter for predicted subframes */
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (iLBCenc_inst->mode == 20)
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    subcount = 1;
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (iLBCenc_inst->mode == 30)
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->section == 1)
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      subcount = 1;
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->section == 2)
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      subcount = 3;
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  subcount=1;
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if( Nfor > 0 ){
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* setup memory */
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                          decresidual+(iLBCbits_inst->startIdx-1)*SUBL, STATE_LEN);
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->Nfor_flag > 0)
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (subframe = 0; subframe < WEBRTC_SPL_MIN (Nfor, 2); subframe++)
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        /* update memory */
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               &decresidual[(iLBCbits_inst->startIdx + 1 +
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                             subframe) * SUBL], SUBL);
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->Nfor_flag++;
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->mode == 20)
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      start_count = 0;
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      end_count = Nfor;
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->mode == 30)
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (iLBCenc_inst->section == 1)
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        start_count = 0;
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end_count = WEBRTC_SPL_MIN (Nfor, 2);
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (iLBCenc_inst->section == 2)
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        start_count = WEBRTC_SPL_MIN (Nfor, 2);
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end_count = Nfor;
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    start_count = 0;
328fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    end_count = (int16_t)Nfor;
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* loop over subframes to encode */
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (subframe = start_count; subframe < end_count; subframe++){
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* encode subframe */
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &residual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             mem, MEM_LF_TBL, SUBL,
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &weightdenum[(iLBCbits_inst->startIdx+1+subframe)*(LPC_FILTERORDER+1)],
342fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org                             (int16_t)subcount);
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* construct decoded vector */
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                mem, MEM_LF_TBL,
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                SUBL
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                );
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* update memory */
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL));
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                            &decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], SUBL);
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      subcount++;
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if ((iLBCenc_inst->section == 1) &&
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      (iLBCenc_inst->mode == 30) && (Nfor > 0) && (end_count == 2))
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->section++;
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* adjust index */
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Packetize the parameters into the frame */
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* backward prediction of subframes */
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Nback = iLBCbits_inst->startIdx-1;
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if( Nback > 0 ){
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* create reverse order vectors
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       (The decresidual does not need to be copied since it is
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       contained in the same vector as the residual)
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    */
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcSpl_MemCpyReversedOrder(&reverseResidual[Nback*SUBL-1], residual, Nback*SUBL);
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* setup memory */
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    meml_gotten = SUBL*(iLBCenc_inst->nsub+1-iLBCbits_inst->startIdx);
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if( meml_gotten > CB_MEML ) {
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      meml_gotten=CB_MEML;
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[Nback*SUBL], meml_gotten);
399fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->Nback_flag > 0)
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (subframe = 0; subframe < WEBRTC_SPL_MAX (2 - Nfor, 0); subframe++)
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        /* update memory */
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               &reverseDecresidual[subframe * SUBL], SUBL);
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->Nback_flag++;
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->mode == 20)
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      start_count = 0;
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      end_count = Nback;
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (iLBCenc_inst->mode == 30)
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (iLBCenc_inst->section == 1)
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        start_count = 0;
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (iLBCenc_inst->section == 2)
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      {
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        start_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end_count = Nback;
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    start_count = 0;
436fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    end_count = (int16_t)Nback;
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* loop over subframes to encode */
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (subframe = start_count; subframe < end_count; subframe++){
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* encode subframe */
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             iLBCbits_inst->gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL],
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             mem, MEM_LF_TBL, SUBL,
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &weightdenum[(iLBCbits_inst->startIdx-2-subframe)*(LPC_FILTERORDER+1)],
449fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org                             (int16_t)subcount);
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* construct decoded vector */
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL],
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                mem, MEM_LF_TBL, SUBL
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                );
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* update memory */
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL));
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                            &reverseDecresidual[subframe*SUBL], SUBL);
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      subcount++;
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* get decoded residual from reversed vector */
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcSpl_MemCpyReversedOrder(&decresidual[SUBL*Nback-1], reverseDecresidual, SUBL*Nback);
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* end encoding part */
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* adjust index */
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WebRtcIlbcfix_IndexConvEnc(iLBCbits_inst->cb_index);
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* Packetize the parameters into the frame */
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if( (iLBCenc_inst->mode==30) && (iLBCenc_inst->section==1) ){
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_PackBits(iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  else{
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
492d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /* Swap bytes for LITTLE ENDIAN since the packbits()
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org     function assumes BIG_ENDIAN machine */
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (( (iLBCenc_inst->section == 1) && (iLBCenc_inst->mode == 20) ) ||
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ( (iLBCenc_inst->section == 2) && (iLBCenc_inst->mode == 30) )){
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef SPLIT_10MS
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (subcount == (iLBCenc_inst->nsub - 1))
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->section = 0;
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  else
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    iLBCenc_inst->section++;
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
519