blob: 912e23ca8b07a02456f885cd48dc76f8f6a9eb78 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
turaj@webrtc.org01ad7582012-07-03 21:35:46 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/******************************************************************
12
13 iLBC Speech Coder ANSI-C Source Code
14
15 WebRtcIlbcfix_Encode.c
16
17******************************************************************/
18
bjornv@webrtc.org52275342014-08-20 10:09:34 +000019#include <string.h>
20
Niels Möllera12c42a2018-07-25 16:05:48 +020021// Defines WEBRTC_ARCH_BIG_ENDIAN, used below.
22#include "rtc_base/system/arch.h"
23
Mirko Bonadei06c2aa92018-02-01 15:11:41 +010024#include "modules/audio_coding/codecs/ilbc/defines.h"
25#include "modules/audio_coding/codecs/ilbc/lpc_encode.h"
26#include "modules/audio_coding/codecs/ilbc/frame_classify.h"
27#include "modules/audio_coding/codecs/ilbc/state_search.h"
28#include "modules/audio_coding/codecs/ilbc/state_construct.h"
29#include "modules/audio_coding/codecs/ilbc/constants.h"
30#include "modules/audio_coding/codecs/ilbc/cb_search.h"
31#include "modules/audio_coding/codecs/ilbc/cb_construct.h"
32#include "modules/audio_coding/codecs/ilbc/index_conv_enc.h"
33#include "modules/audio_coding/codecs/ilbc/pack_bits.h"
34#include "modules/audio_coding/codecs/ilbc/hp_input.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/checks.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000036
37#ifdef SPLIT_10MS
Mirko Bonadei06c2aa92018-02-01 15:11:41 +010038#include "modules/audio_coding/codecs/ilbc/unpack_bits.h"
39#include "modules/audio_coding/codecs/ilbc/index_conv_dec.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000040#endif
andrew@webrtc.org621df672013-10-22 10:27:23 +000041#ifndef WEBRTC_ARCH_BIG_ENDIAN
Mirko Bonadei06c2aa92018-02-01 15:11:41 +010042#include "modules/audio_coding/codecs/ilbc/swap_bytes.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000043#endif
44
45/*----------------------------------------------------------------*
46 * main encoder function
47 *---------------------------------------------------------------*/
48
49void WebRtcIlbcfix_EncodeImpl(
pbos@webrtc.org0946a562013-04-09 00:28:06 +000050 uint16_t *bytes, /* (o) encoded data bits iLBC */
51 const int16_t *block, /* (i) speech vector to encode */
pbos@webrtc.orgeb544462014-12-17 15:23:29 +000052 IlbcEncoder *iLBCenc_inst /* (i/o) the general encoder
niklase@google.com470e71d2011-07-07 08:21:25 +000053 state */
54 ){
Peter Kastingdce40cf2015-08-24 14:52:23 -070055 size_t n, meml_gotten, Nfor;
56 size_t diff, start_pos;
57 size_t index;
58 size_t subcount, subframe;
59 size_t start_count, end_count;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000060 int16_t *residual;
61 int32_t en1, en2;
62 int16_t scale, max;
63 int16_t *syntdenum;
64 int16_t *decresidual;
65 int16_t *reverseResidual;
66 int16_t *reverseDecresidual;
niklase@google.com470e71d2011-07-07 08:21:25 +000067 /* Stack based */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000068 int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
69 int16_t dataVec[BLOCKL_MAX + LPC_FILTERORDER];
70 int16_t memVec[CB_MEML+CB_FILTERLEN];
71 int16_t bitsMemory[sizeof(iLBC_bits)/sizeof(int16_t)];
niklase@google.com470e71d2011-07-07 08:21:25 +000072 iLBC_bits *iLBCbits_inst = (iLBC_bits*)bitsMemory;
73
74
75#ifdef SPLIT_10MS
pbos@webrtc.org0946a562013-04-09 00:28:06 +000076 int16_t *weightdenumbuf = iLBCenc_inst->weightdenumbuf;
77 int16_t last_bit;
niklase@google.com470e71d2011-07-07 08:21:25 +000078#endif
79
pbos@webrtc.org0946a562013-04-09 00:28:06 +000080 int16_t *data = &dataVec[LPC_FILTERORDER];
81 int16_t *mem = &memVec[CB_HALFFILTERLEN];
niklase@google.com470e71d2011-07-07 08:21:25 +000082
83 /* Reuse som buffers to save stack memory */
84 residual = &iLBCenc_inst->lpc_buffer[LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl];
85 syntdenum = mem; /* syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX] and mem are used non overlapping in the code */
86 decresidual = residual; /* Already encoded residual is overwritten by the decoded version */
87 reverseResidual = data; /* data and reverseResidual are used non overlapping in the code */
88 reverseDecresidual = reverseResidual; /* Already encoded residual is overwritten by the decoded version */
89
90#ifdef SPLIT_10MS
91
pbos@webrtc.org0946a562013-04-09 00:28:06 +000092 WebRtcSpl_MemSetW16 ( (int16_t *) iLBCbits_inst, 0,
Peter Kastingdce40cf2015-08-24 14:52:23 -070093 sizeof(iLBC_bits) / sizeof(int16_t) );
niklase@google.com470e71d2011-07-07 08:21:25 +000094
95 start_pos = iLBCenc_inst->start_pos;
96 diff = iLBCenc_inst->diff;
97
98 if (iLBCenc_inst->section != 0){
99 WEBRTC_SPL_MEMCPY_W16 (weightdenum, weightdenumbuf,
100 SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
101 /* Un-Packetize the frame into parameters */
102 last_bit = WebRtcIlbcfix_UnpackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
103 if (last_bit)
104 return;
105 /* adjust index */
106 WebRtcIlbcfix_IndexConvDec (iLBCbits_inst->cb_index);
107
108 if (iLBCenc_inst->section == 1){
109 /* Save first 80 samples of a 160/240 sample frame for 20/30msec */
110 WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples, block, 80);
111 }
112 else{ // iLBCenc_inst->section == 2 AND mode = 30ms
113 /* Save second 80 samples of a 240 sample frame for 30msec */
114 WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples + 80, block, 80);
115 }
116 }
117 else{ // iLBCenc_inst->section == 0
118 /* form a complete frame of 160/240 for 20msec/30msec mode */
119 WEBRTC_SPL_MEMCPY_W16 (data + (iLBCenc_inst->mode * 8) - 80, block, 80);
120 WEBRTC_SPL_MEMCPY_W16 (data, iLBCenc_inst->past_samples,
121 (iLBCenc_inst->mode * 8) - 80);
122 iLBCenc_inst->Nfor_flag = 0;
123 iLBCenc_inst->Nback_flag = 0;
124#else
125 /* copy input block to data*/
126 WEBRTC_SPL_MEMCPY_W16(data,block,iLBCenc_inst->blockl);
127#endif
128
129 /* high pass filtering of input signal and scale down the residual (*0.5) */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000130 WebRtcIlbcfix_HpInput(data, (int16_t*)WebRtcIlbcfix_kHpInCoefs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 iLBCenc_inst->hpimemy, iLBCenc_inst->hpimemx,
132 iLBCenc_inst->blockl);
133
134 /* LPC of hp filtered input data */
135 WebRtcIlbcfix_LpcEncode(syntdenum, weightdenum, iLBCbits_inst->lsf, data,
136 iLBCenc_inst);
137
138 /* Set up state */
139 WEBRTC_SPL_MEMCPY_W16(dataVec, iLBCenc_inst->anaMem, LPC_FILTERORDER);
140
141 /* inverse filter to get residual */
142 for (n=0; n<iLBCenc_inst->nsub; n++ ) {
143 WebRtcSpl_FilterMAFastQ12(
144 &data[n*SUBL], &residual[n*SUBL],
145 &syntdenum[n*(LPC_FILTERORDER+1)],
146 LPC_FILTERORDER+1, SUBL);
147 }
148
149 /* Copy the state for next frame */
150 WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->anaMem, &data[iLBCenc_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
151
152 /* find state location */
153
154 iLBCbits_inst->startIdx = WebRtcIlbcfix_FrameClassify(iLBCenc_inst,residual);
155
156 /* check if state should be in first or last part of the
157 two subframes */
158
159 index = (iLBCbits_inst->startIdx-1)*SUBL;
160 max=WebRtcSpl_MaxAbsValueW16(&residual[index], 2*SUBL);
bjornv@webrtc.orgba97ea62015-02-13 09:51:40 +0000161 scale = WebRtcSpl_GetSizeInBits((uint32_t)(max * max));
niklase@google.com470e71d2011-07-07 08:21:25 +0000162
163 /* Scale to maximum 25 bits so that the MAC won't cause overflow */
164 scale = scale - 25;
165 if(scale < 0) {
166 scale = 0;
167 }
168
169 diff = STATE_LEN - iLBCenc_inst->state_short_len;
170 en1=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
171 iLBCenc_inst->state_short_len, scale);
172 index += diff;
173 en2=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
174 iLBCenc_inst->state_short_len, scale);
175 if (en1 > en2) {
176 iLBCbits_inst->state_first = 1;
177 start_pos = (iLBCbits_inst->startIdx-1)*SUBL;
178 } else {
179 iLBCbits_inst->state_first = 0;
180 start_pos = (iLBCbits_inst->startIdx-1)*SUBL + diff;
181 }
182
183 /* scalar quantization of state */
184
185 WebRtcIlbcfix_StateSearch(iLBCenc_inst, iLBCbits_inst, &residual[start_pos],
186 &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
187 &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)]);
188
189 WebRtcIlbcfix_StateConstruct(iLBCbits_inst->idxForMax, iLBCbits_inst->idxVec,
190 &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
191 &decresidual[start_pos], iLBCenc_inst->state_short_len
192 );
193
194 /* predictive quantization in state */
195
196 if (iLBCbits_inst->state_first) { /* put adaptive part in the end */
197
198 /* setup memory */
199
Peter Kastingb7e50542015-06-11 12:55:50 -0700200 WebRtcSpl_MemSetW16(mem, 0, CB_MEML - iLBCenc_inst->state_short_len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000201 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCenc_inst->state_short_len,
202 decresidual+start_pos, iLBCenc_inst->state_short_len);
203
204 /* encode subframes */
205
206 WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
207 &residual[start_pos+iLBCenc_inst->state_short_len],
208 mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
209 &weightdenum[iLBCbits_inst->startIdx*(LPC_FILTERORDER+1)], 0);
210
211 /* construct decoded vector */
212
kwiberg619a2112016-08-24 02:46:44 -0700213 RTC_CHECK(WebRtcIlbcfix_CbConstruct(
214 &decresidual[start_pos + iLBCenc_inst->state_short_len],
215 iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
216 mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff));
niklase@google.com470e71d2011-07-07 08:21:25 +0000217
218 }
219 else { /* put adaptive part in the beginning */
220
221 /* create reversed vectors for prediction */
222
223 WebRtcSpl_MemCpyReversedOrder(&reverseResidual[diff-1],
224 &residual[(iLBCbits_inst->startIdx+1)*SUBL-STATE_LEN], diff);
225
226 /* setup memory */
227
228 meml_gotten = iLBCenc_inst->state_short_len;
229 WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[start_pos], meml_gotten);
Peter Kastingb7e50542015-06-11 12:55:50 -0700230 WebRtcSpl_MemSetW16(mem, 0, CB_MEML - iLBCenc_inst->state_short_len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000231
232 /* encode subframes */
233 WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
234 reverseResidual, mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
235 &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
236 0);
237
238 /* construct decoded vector */
kwiberg619a2112016-08-24 02:46:44 -0700239 RTC_CHECK(WebRtcIlbcfix_CbConstruct(
240 reverseDecresidual, iLBCbits_inst->cb_index,
241 iLBCbits_inst->gain_index, mem + CB_MEML - ST_MEM_L_TBL,
242 ST_MEM_L_TBL, diff));
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
244 /* get decoded residual from reversed vector */
245
246 WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], reverseDecresidual, diff);
247 }
248
249#ifdef SPLIT_10MS
250 iLBCenc_inst->start_pos = start_pos;
251 iLBCenc_inst->diff = diff;
252 iLBCenc_inst->section++;
253 /* adjust index */
254 WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
255 /* Packetize the parameters into the frame */
256 WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
257 WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
258 SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
259 return;
260 }
261#endif
262
263 /* forward prediction of subframes */
264
265 Nfor = iLBCenc_inst->nsub-iLBCbits_inst->startIdx-1;
266
267 /* counter for predicted subframes */
268#ifdef SPLIT_10MS
269 if (iLBCenc_inst->mode == 20)
270 {
271 subcount = 1;
272 }
273 if (iLBCenc_inst->mode == 30)
274 {
275 if (iLBCenc_inst->section == 1)
276 {
277 subcount = 1;
278 }
279 if (iLBCenc_inst->section == 2)
280 {
281 subcount = 3;
282 }
283 }
284#else
285 subcount=1;
286#endif
287
288 if( Nfor > 0 ){
289
290 /* setup memory */
291
292 WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
293 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
294 decresidual+(iLBCbits_inst->startIdx-1)*SUBL, STATE_LEN);
295
296#ifdef SPLIT_10MS
297 if (iLBCenc_inst->Nfor_flag > 0)
298 {
299 for (subframe = 0; subframe < WEBRTC_SPL_MIN (Nfor, 2); subframe++)
300 {
301 /* update memory */
302 WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
303 WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
304 &decresidual[(iLBCbits_inst->startIdx + 1 +
305 subframe) * SUBL], SUBL);
306 }
307 }
308
309 iLBCenc_inst->Nfor_flag++;
310
311 if (iLBCenc_inst->mode == 20)
312 {
313 start_count = 0;
314 end_count = Nfor;
315 }
316 if (iLBCenc_inst->mode == 30)
317 {
318 if (iLBCenc_inst->section == 1)
319 {
320 start_count = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700321 end_count = WEBRTC_SPL_MIN (Nfor, (size_t)2);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 }
323 if (iLBCenc_inst->section == 2)
324 {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700325 start_count = WEBRTC_SPL_MIN (Nfor, (size_t)2);
niklase@google.com470e71d2011-07-07 08:21:25 +0000326 end_count = Nfor;
327 }
328 }
329#else
330 start_count = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700331 end_count = Nfor;
niklase@google.com470e71d2011-07-07 08:21:25 +0000332#endif
333
334 /* loop over subframes to encode */
335
336 for (subframe = start_count; subframe < end_count; subframe++){
337
338 /* encode subframe */
339
340 WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
341 iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
342 &residual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
343 mem, MEM_LF_TBL, SUBL,
344 &weightdenum[(iLBCbits_inst->startIdx+1+subframe)*(LPC_FILTERORDER+1)],
Peter Kastingdce40cf2015-08-24 14:52:23 -0700345 subcount);
niklase@google.com470e71d2011-07-07 08:21:25 +0000346
347 /* construct decoded vector */
kwiberg619a2112016-08-24 02:46:44 -0700348 RTC_CHECK(WebRtcIlbcfix_CbConstruct(
349 &decresidual[(iLBCbits_inst->startIdx + 1 + subframe) * SUBL],
350 iLBCbits_inst->cb_index + subcount * CB_NSTAGES,
351 iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
352 SUBL));
niklase@google.com470e71d2011-07-07 08:21:25 +0000353
354 /* update memory */
355
bjornv@webrtc.org52275342014-08-20 10:09:34 +0000356 memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
358 &decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], SUBL);
359
360 subcount++;
361 }
362 }
363
364#ifdef SPLIT_10MS
365 if ((iLBCenc_inst->section == 1) &&
366 (iLBCenc_inst->mode == 30) && (Nfor > 0) && (end_count == 2))
367 {
368 iLBCenc_inst->section++;
369 /* adjust index */
370 WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
371 /* Packetize the parameters into the frame */
372 WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
373 WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
374 SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
375 return;
376 }
377#endif
378
379 /* backward prediction of subframes */
380
Peter Kastingf045e4d2015-06-10 21:15:38 -0700381 if (iLBCbits_inst->startIdx > 1) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000382
383 /* create reverse order vectors
384 (The decresidual does not need to be copied since it is
385 contained in the same vector as the residual)
386 */
387
Peter Kastingdce40cf2015-08-24 14:52:23 -0700388 size_t Nback = iLBCbits_inst->startIdx - 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000389 WebRtcSpl_MemCpyReversedOrder(&reverseResidual[Nback*SUBL-1], residual, Nback*SUBL);
390
391 /* setup memory */
392
393 meml_gotten = SUBL*(iLBCenc_inst->nsub+1-iLBCbits_inst->startIdx);
394 if( meml_gotten > CB_MEML ) {
395 meml_gotten=CB_MEML;
396 }
397
398 WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[Nback*SUBL], meml_gotten);
Peter Kastingb7e50542015-06-11 12:55:50 -0700399 WebRtcSpl_MemSetW16(mem, 0, CB_MEML - meml_gotten);
niklase@google.com470e71d2011-07-07 08:21:25 +0000400
401#ifdef SPLIT_10MS
402 if (iLBCenc_inst->Nback_flag > 0)
403 {
404 for (subframe = 0; subframe < WEBRTC_SPL_MAX (2 - Nfor, 0); subframe++)
405 {
406 /* update memory */
407 WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
408 WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
409 &reverseDecresidual[subframe * SUBL], SUBL);
410 }
411 }
412
413 iLBCenc_inst->Nback_flag++;
414
415
416 if (iLBCenc_inst->mode == 20)
417 {
418 start_count = 0;
419 end_count = Nback;
420 }
421 if (iLBCenc_inst->mode == 30)
422 {
423 if (iLBCenc_inst->section == 1)
424 {
425 start_count = 0;
Peter Kastingf045e4d2015-06-10 21:15:38 -0700426 end_count = (Nfor >= 2) ? 0 : (2 - NFor);
niklase@google.com470e71d2011-07-07 08:21:25 +0000427 }
428 if (iLBCenc_inst->section == 2)
429 {
Peter Kastingf045e4d2015-06-10 21:15:38 -0700430 start_count = (Nfor >= 2) ? 0 : (2 - NFor);
niklase@google.com470e71d2011-07-07 08:21:25 +0000431 end_count = Nback;
432 }
433 }
434#else
435 start_count = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700436 end_count = Nback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000437#endif
438
439 /* loop over subframes to encode */
440
441 for (subframe = start_count; subframe < end_count; subframe++){
442
443 /* encode subframe */
444
445 WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
446 iLBCbits_inst->gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL],
447 mem, MEM_LF_TBL, SUBL,
448 &weightdenum[(iLBCbits_inst->startIdx-2-subframe)*(LPC_FILTERORDER+1)],
Peter Kastingdce40cf2015-08-24 14:52:23 -0700449 subcount);
niklase@google.com470e71d2011-07-07 08:21:25 +0000450
451 /* construct decoded vector */
kwiberg619a2112016-08-24 02:46:44 -0700452 RTC_CHECK(WebRtcIlbcfix_CbConstruct(
453 &reverseDecresidual[subframe * SUBL],
454 iLBCbits_inst->cb_index + subcount * CB_NSTAGES,
455 iLBCbits_inst->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL,
456 SUBL));
niklase@google.com470e71d2011-07-07 08:21:25 +0000457
458 /* update memory */
bjornv@webrtc.org52275342014-08-20 10:09:34 +0000459 memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
niklase@google.com470e71d2011-07-07 08:21:25 +0000460 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
461 &reverseDecresidual[subframe*SUBL], SUBL);
462
463 subcount++;
464
465 }
466
467 /* get decoded residual from reversed vector */
468
469 WebRtcSpl_MemCpyReversedOrder(&decresidual[SUBL*Nback-1], reverseDecresidual, SUBL*Nback);
470 }
471 /* end encoding part */
472
473 /* adjust index */
474
475 WebRtcIlbcfix_IndexConvEnc(iLBCbits_inst->cb_index);
476
477 /* Packetize the parameters into the frame */
478
479#ifdef SPLIT_10MS
480 if( (iLBCenc_inst->mode==30) && (iLBCenc_inst->section==1) ){
481 WebRtcIlbcfix_PackBits(iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
482 }
483 else{
484 WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
485 }
486#else
487 WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
488#endif
489
andrew@webrtc.org621df672013-10-22 10:27:23 +0000490#ifndef WEBRTC_ARCH_BIG_ENDIAN
niklase@google.com470e71d2011-07-07 08:21:25 +0000491 /* Swap bytes for LITTLE ENDIAN since the packbits()
492 function assumes BIG_ENDIAN machine */
493#ifdef SPLIT_10MS
494 if (( (iLBCenc_inst->section == 1) && (iLBCenc_inst->mode == 20) ) ||
495 ( (iLBCenc_inst->section == 2) && (iLBCenc_inst->mode == 30) )){
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000496 WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
niklase@google.com470e71d2011-07-07 08:21:25 +0000497 }
498#else
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000499 WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
niklase@google.com470e71d2011-07-07 08:21:25 +0000500#endif
501#endif
502
503#ifdef SPLIT_10MS
504 if (subcount == (iLBCenc_inst->nsub - 1))
505 {
506 iLBCenc_inst->section = 0;
507 }
508 else
509 {
510 iLBCenc_inst->section++;
511 WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
512 SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
513 }
514#endif
515
516}