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