2 /******************************************************************
4 iLBC Speech Coder ANSI-C Source Code
12 ******************************************************************/
18 #include "iLBC_define.h"
19 #include "LPCencode.h"
20 #include "FrameClassify.h"
21 #include "StateSearchW.h"
22 #include "StateConstructW.h"
24 #include "constants.h"
26 #include "iCBSearch.h"
27 #include "iCBConstruct.h"
29 #include "anaFilter.h"
30 #include "syntFilter.h"
32 /*----------------------------------------------------------------*
33 * Initiation of encoder instance.
34 *---------------------------------------------------------------*/
36 short initEncode( /* (o) Number of bytes encoded */
37 iLBC_Enc_Inst_t
*iLBCenc_inst
, /* (i/o) Encoder instance */
41 int mode
/* (i) frame size mode */
43 iLBCenc_inst
->mode
= mode
;
45 iLBCenc_inst
->blockl
= BLOCKL_30MS
;
46 iLBCenc_inst
->nsub
= NSUB_30MS
;
47 iLBCenc_inst
->nasub
= NASUB_30MS
;
48 iLBCenc_inst
->lpc_n
= LPC_N_30MS
;
49 iLBCenc_inst
->no_of_bytes
= NO_OF_BYTES_30MS
;
50 iLBCenc_inst
->no_of_words
= NO_OF_WORDS_30MS
;
51 iLBCenc_inst
->state_short_len
=STATE_SHORT_LEN_30MS
;
53 iLBCenc_inst
->ULP_inst
=&ULP_30msTbl
;
56 iLBCenc_inst
->blockl
= BLOCKL_20MS
;
57 iLBCenc_inst
->nsub
= NSUB_20MS
;
58 iLBCenc_inst
->nasub
= NASUB_20MS
;
59 iLBCenc_inst
->lpc_n
= LPC_N_20MS
;
60 iLBCenc_inst
->no_of_bytes
= NO_OF_BYTES_20MS
;
61 iLBCenc_inst
->no_of_words
= NO_OF_WORDS_20MS
;
62 iLBCenc_inst
->state_short_len
=STATE_SHORT_LEN_20MS
;
64 iLBCenc_inst
->ULP_inst
=&ULP_20msTbl
;
70 memset((*iLBCenc_inst
).anaMem
, 0,
71 LPC_FILTERORDER
*sizeof(float));
72 memcpy((*iLBCenc_inst
).lsfold
, lsfmeanTbl
,
73 LPC_FILTERORDER
*sizeof(float));
74 memcpy((*iLBCenc_inst
).lsfdeqold
, lsfmeanTbl
,
75 LPC_FILTERORDER
*sizeof(float));
76 memset((*iLBCenc_inst
).lpc_buffer
, 0,
77 (LPC_LOOKBACK
+BLOCKL_MAX
)*sizeof(float));
78 memset((*iLBCenc_inst
).hpimem
, 0, 4*sizeof(float));
80 return (iLBCenc_inst
->no_of_bytes
);
83 /*----------------------------------------------------------------*
84 * main encoder function
85 *---------------------------------------------------------------*/
88 unsigned char *bytes
, /* (o) encoded data bits iLBC */
89 float *block
, /* (o) speech vector to encode */
90 iLBC_Enc_Inst_t
*iLBCenc_inst
/* (i/o) the general encoder
97 float data
[BLOCKL_MAX
];
98 float residual
[BLOCKL_MAX
], reverseResidual
[BLOCKL_MAX
];
100 int start
, idxForMax
, idxVec
[STATE_LEN
];
101 float reverseDecresidual
[BLOCKL_MAX
], mem
[CB_MEML
];
102 int n
, k
, meml_gotten
, Nfor
, Nback
, i
, pos
;
103 int gain_index
[CB_NSTAGES
*NASUB_MAX
],
104 extra_gain_index
[CB_NSTAGES
];
105 int cb_index
[CB_NSTAGES
*NASUB_MAX
],extra_cb_index
[CB_NSTAGES
];
106 int lsf_i
[LSF_NSPLIT
*LPC_N_MAX
];
107 unsigned char *pbytes
;
108 int diff
, start_pos
, state_first
;
110 int index
, ulp
, firstpart
;
111 int subcount
, subframe
;
112 float weightState
[LPC_FILTERORDER
];
113 float syntdenum
[NSUB_MAX
*(LPC_FILTERORDER
+1)];
114 float weightdenum
[NSUB_MAX
*(LPC_FILTERORDER
+1)];
115 float decresidual
[BLOCKL_MAX
];
117 /* high pass filtering of input signal if such is not done
118 prior to calling this function */
120 hpInput(block
, iLBCenc_inst
->blockl
,
121 data
, (*iLBCenc_inst
).hpimem
);
123 /* otherwise simply copy */
125 /*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
127 /* LPC of hp filtered input data */
129 LPCencode(syntdenum
, weightdenum
, lsf_i
, data
, iLBCenc_inst
);
132 /* inverse filter to get residual */
134 for (n
=0; n
<iLBCenc_inst
->nsub
; n
++) {
135 anaFilter(&data
[n
*SUBL
], &syntdenum
[n
*(LPC_FILTERORDER
+1)],
136 SUBL
, &residual
[n
*SUBL
], iLBCenc_inst
->anaMem
);
139 /* find state location */
141 start
= FrameClassify(iLBCenc_inst
, residual
);
143 /* check if state should be in first or last part of the
146 diff
= STATE_LEN
- iLBCenc_inst
->state_short_len
;
148 index
= (start
-1)*SUBL
;
149 for (i
= 0; i
< iLBCenc_inst
->state_short_len
; i
++) {
153 en1
+= residual
[index
+i
]*residual
[index
+i
];
156 index
= (start
-1)*SUBL
+diff
;
157 for (i
= 0; i
< iLBCenc_inst
->state_short_len
; i
++) {
158 en2
+= residual
[index
+i
]*residual
[index
+i
];
164 start_pos
= (start
-1)*SUBL
;
167 start_pos
= (start
-1)*SUBL
+ diff
;
170 /* scalar quantization of state */
172 StateSearchW(iLBCenc_inst
, &residual
[start_pos
],
173 &syntdenum
[(start
-1)*(LPC_FILTERORDER
+1)],
174 &weightdenum
[(start
-1)*(LPC_FILTERORDER
+1)], &idxForMax
,
175 idxVec
, iLBCenc_inst
->state_short_len
, state_first
);
177 StateConstructW(idxForMax
, idxVec
,
178 &syntdenum
[(start
-1)*(LPC_FILTERORDER
+1)],
179 &decresidual
[start_pos
], iLBCenc_inst
->state_short_len
);
181 /* predictive quantization in state */
183 if (state_first
) { /* put adaptive part in the end */
188 (CB_MEML
-iLBCenc_inst
->state_short_len
)*sizeof(float));
189 memcpy(mem
+CB_MEML
-iLBCenc_inst
->state_short_len
,
190 decresidual
+start_pos
,
191 iLBCenc_inst
->state_short_len
*sizeof(float));
192 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
194 /* encode subframes */
196 iCBSearch(iLBCenc_inst
, extra_cb_index
, extra_gain_index
,
197 &residual
[start_pos
+iLBCenc_inst
->state_short_len
],
198 mem
+CB_MEML
-stMemLTbl
,
199 stMemLTbl
, diff
, CB_NSTAGES
,
200 &weightdenum
[start
*(LPC_FILTERORDER
+1)], weightState
, 0);
202 /* construct decoded vector */
205 &decresidual
[start_pos
+iLBCenc_inst
->state_short_len
],
209 extra_cb_index
, extra_gain_index
, mem
+CB_MEML
-stMemLTbl
,
210 stMemLTbl
, diff
, CB_NSTAGES
);
213 else { /* put adaptive part in the beginning */
215 /* create reversed vectors for prediction */
217 for (k
=0; k
<diff
; k
++) {
218 reverseResidual
[k
] = residual
[(start
+1)*SUBL
-1
219 -(k
+iLBCenc_inst
->state_short_len
)];
224 meml_gotten
= iLBCenc_inst
->state_short_len
;
225 for (k
=0; k
<meml_gotten
; k
++) {
226 mem
[CB_MEML
-1-k
] = decresidual
[start_pos
+ k
];
228 memset(mem
, 0, (CB_MEML
-k
)*sizeof(float));
229 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
231 /* encode subframes */
233 iCBSearch(iLBCenc_inst
, extra_cb_index
, extra_gain_index
,
234 reverseResidual
, mem
+CB_MEML
-stMemLTbl
, stMemLTbl
, diff
,
235 CB_NSTAGES
, &weightdenum
[(start
-1)*(LPC_FILTERORDER
+1)],
238 /* construct decoded vector */
240 iCBConstruct(reverseDecresidual
, extra_cb_index
,
241 extra_gain_index
, mem
+CB_MEML
-stMemLTbl
, stMemLTbl
, diff
,
244 /* get decoded residual from reversed vector */
246 for (k
=0; k
<diff
; k
++) {
247 decresidual
[start_pos
-1-k
] = reverseDecresidual
[k
];
251 /* counter for predicted subframes */
255 /* forward prediction of subframes */
257 Nfor
= iLBCenc_inst
->nsub
-start
-1;
267 memset(mem
, 0, (CB_MEML
-STATE_LEN
)*sizeof(float));
268 memcpy(mem
+CB_MEML
-STATE_LEN
, decresidual
+(start
-1)*SUBL
,
269 STATE_LEN
*sizeof(float));
270 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
272 /* loop over subframes to encode */
274 for (subframe
=0; subframe
<Nfor
; subframe
++) {
276 /* encode subframe */
278 iCBSearch(iLBCenc_inst
, cb_index
+subcount
*CB_NSTAGES
,
279 gain_index
+subcount
*CB_NSTAGES
,
280 &residual
[(start
+1+subframe
)*SUBL
],
281 mem
+CB_MEML
-memLfTbl
[subcount
], memLfTbl
[subcount
],
283 &weightdenum
[(start
+1+subframe
)*(LPC_FILTERORDER
+1)],
284 weightState
, subcount
+1);
286 /* construct decoded vector */
288 iCBConstruct(&decresidual
[(start
+1+subframe
)*SUBL
],
289 cb_index
+subcount
*CB_NSTAGES
,
290 gain_index
+subcount
*CB_NSTAGES
,
291 mem
+CB_MEML
-memLfTbl
[subcount
], memLfTbl
[subcount
],
296 memcpy(mem
, mem
+SUBL
, (CB_MEML
-SUBL
)*sizeof(float));
297 memcpy(mem
+CB_MEML
-SUBL
,
298 &decresidual
[(start
+1+subframe
)*SUBL
],
300 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
307 /* backward prediction of subframes */
314 /* create reverse order vectors */
316 for (n
=0; n
<Nback
; n
++) {
317 for (k
=0; k
<SUBL
; k
++) {
321 reverseResidual
[n
*SUBL
+k
] =
322 residual
[(start
-1)*SUBL
-1-n
*SUBL
-k
];
323 reverseDecresidual
[n
*SUBL
+k
] =
324 decresidual
[(start
-1)*SUBL
-1-n
*SUBL
-k
];
330 meml_gotten
= SUBL
*(iLBCenc_inst
->nsub
+1-start
);
333 if ( meml_gotten
> CB_MEML
) {
336 for (k
=0; k
<meml_gotten
; k
++) {
337 mem
[CB_MEML
-1-k
] = decresidual
[(start
-1)*SUBL
+ k
];
339 memset(mem
, 0, (CB_MEML
-k
)*sizeof(float));
340 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
342 /* loop over subframes to encode */
344 for (subframe
=0; subframe
<Nback
; subframe
++) {
346 /* encode subframe */
348 iCBSearch(iLBCenc_inst
, cb_index
+subcount
*CB_NSTAGES
,
349 gain_index
+subcount
*CB_NSTAGES
,
350 &reverseResidual
[subframe
*SUBL
],
351 mem
+CB_MEML
-memLfTbl
[subcount
], memLfTbl
[subcount
],
353 &weightdenum
[(start
-2-subframe
)*(LPC_FILTERORDER
+1)],
354 weightState
, subcount
+1);
356 /* construct decoded vector */
358 iCBConstruct(&reverseDecresidual
[subframe
*SUBL
],
359 cb_index
+subcount
*CB_NSTAGES
,
360 gain_index
+subcount
*CB_NSTAGES
,
361 mem
+CB_MEML
-memLfTbl
[subcount
],
362 memLfTbl
[subcount
], SUBL
, CB_NSTAGES
);
366 memcpy(mem
, mem
+SUBL
, (CB_MEML
-SUBL
)*sizeof(float));
367 memcpy(mem
+CB_MEML
-SUBL
,
368 &reverseDecresidual
[subframe
*SUBL
],
370 memset(weightState
, 0, LPC_FILTERORDER
*sizeof(float));
379 /* get decoded residual from reversed vector */
381 for (i
=0; i
<SUBL
*Nback
; i
++) {
382 decresidual
[SUBL
*Nback
- i
- 1] =
383 reverseDecresidual
[i
];
386 /* end encoding part */
389 index_conv_enc(cb_index
);
396 /* loop over the 3 ULP classes */
398 for (ulp
=0; ulp
<3; ulp
++) {
401 for (k
=0; k
<LSF_NSPLIT
*iLBCenc_inst
->lpc_n
; k
++) {
402 packsplit(&lsf_i
[k
], &firstpart
, &lsf_i
[k
],
403 iLBCenc_inst
->ULP_inst
->lsf_bits
[k
][ulp
],
404 iLBCenc_inst
->ULP_inst
->lsf_bits
[k
][ulp
]+
405 iLBCenc_inst
->ULP_inst
->lsf_bits
[k
][ulp
+1]+
406 iLBCenc_inst
->ULP_inst
->lsf_bits
[k
][ulp
+2]);
407 dopack( &pbytes
, firstpart
,
408 iLBCenc_inst
->ULP_inst
->lsf_bits
[k
][ulp
], &pos
);
411 /* Start block info */
413 packsplit(&start
, &firstpart
, &start
,
414 iLBCenc_inst
->ULP_inst
->start_bits
[ulp
],
415 iLBCenc_inst
->ULP_inst
->start_bits
[ulp
]+
416 iLBCenc_inst
->ULP_inst
->start_bits
[ulp
+1]+
417 iLBCenc_inst
->ULP_inst
->start_bits
[ulp
+2]);
418 dopack( &pbytes
, firstpart
,
419 iLBCenc_inst
->ULP_inst
->start_bits
[ulp
], &pos
);
421 packsplit(&state_first
, &firstpart
, &state_first
,
422 iLBCenc_inst
->ULP_inst
->startfirst_bits
[ulp
],
423 iLBCenc_inst
->ULP_inst
->startfirst_bits
[ulp
]+
424 iLBCenc_inst
->ULP_inst
->startfirst_bits
[ulp
+1]+
425 iLBCenc_inst
->ULP_inst
->startfirst_bits
[ulp
+2]);
426 dopack( &pbytes
, firstpart
,
427 iLBCenc_inst
->ULP_inst
->startfirst_bits
[ulp
], &pos
);
429 packsplit(&idxForMax
, &firstpart
, &idxForMax
,
433 iLBCenc_inst
->ULP_inst
->scale_bits
[ulp
],
434 iLBCenc_inst
->ULP_inst
->scale_bits
[ulp
]+
435 iLBCenc_inst
->ULP_inst
->scale_bits
[ulp
+1]+
436 iLBCenc_inst
->ULP_inst
->scale_bits
[ulp
+2]);
437 dopack( &pbytes
, firstpart
,
438 iLBCenc_inst
->ULP_inst
->scale_bits
[ulp
], &pos
);
440 for (k
=0; k
<iLBCenc_inst
->state_short_len
; k
++) {
441 packsplit(idxVec
+k
, &firstpart
, idxVec
+k
,
442 iLBCenc_inst
->ULP_inst
->state_bits
[ulp
],
443 iLBCenc_inst
->ULP_inst
->state_bits
[ulp
]+
444 iLBCenc_inst
->ULP_inst
->state_bits
[ulp
+1]+
445 iLBCenc_inst
->ULP_inst
->state_bits
[ulp
+2]);
446 dopack( &pbytes
, firstpart
,
447 iLBCenc_inst
->ULP_inst
->state_bits
[ulp
], &pos
);
450 /* 23/22 (20ms/30ms) sample block */
452 for (k
=0;k
<CB_NSTAGES
;k
++) {
453 packsplit(extra_cb_index
+k
, &firstpart
,
455 iLBCenc_inst
->ULP_inst
->extra_cb_index
[k
][ulp
],
456 iLBCenc_inst
->ULP_inst
->extra_cb_index
[k
][ulp
]+
457 iLBCenc_inst
->ULP_inst
->extra_cb_index
[k
][ulp
+1]+
458 iLBCenc_inst
->ULP_inst
->extra_cb_index
[k
][ulp
+2]);
459 dopack( &pbytes
, firstpart
,
460 iLBCenc_inst
->ULP_inst
->extra_cb_index
[k
][ulp
],
464 for (k
=0;k
<CB_NSTAGES
;k
++) {
465 packsplit(extra_gain_index
+k
, &firstpart
,
467 iLBCenc_inst
->ULP_inst
->extra_cb_gain
[k
][ulp
],
468 iLBCenc_inst
->ULP_inst
->extra_cb_gain
[k
][ulp
]+
469 iLBCenc_inst
->ULP_inst
->extra_cb_gain
[k
][ulp
+1]+
470 iLBCenc_inst
->ULP_inst
->extra_cb_gain
[k
][ulp
+2]);
471 dopack( &pbytes
, firstpart
,
472 iLBCenc_inst
->ULP_inst
->extra_cb_gain
[k
][ulp
],
476 /* The two/four (20ms/30ms) 40 sample sub blocks */
478 for (i
=0; i
<iLBCenc_inst
->nasub
; i
++) {
479 for (k
=0; k
<CB_NSTAGES
; k
++) {
480 packsplit(cb_index
+i
*CB_NSTAGES
+k
, &firstpart
,
481 cb_index
+i
*CB_NSTAGES
+k
,
482 iLBCenc_inst
->ULP_inst
->cb_index
[i
][k
][ulp
],
483 iLBCenc_inst
->ULP_inst
->cb_index
[i
][k
][ulp
]+
484 iLBCenc_inst
->ULP_inst
->cb_index
[i
][k
][ulp
+1]+
485 iLBCenc_inst
->ULP_inst
->cb_index
[i
][k
][ulp
+2]);
489 dopack( &pbytes
, firstpart
,
490 iLBCenc_inst
->ULP_inst
->cb_index
[i
][k
][ulp
],
495 for (i
=0; i
<iLBCenc_inst
->nasub
; i
++) {
496 for (k
=0; k
<CB_NSTAGES
; k
++) {
497 packsplit(gain_index
+i
*CB_NSTAGES
+k
, &firstpart
,
498 gain_index
+i
*CB_NSTAGES
+k
,
499 iLBCenc_inst
->ULP_inst
->cb_gain
[i
][k
][ulp
],
500 iLBCenc_inst
->ULP_inst
->cb_gain
[i
][k
][ulp
]+
501 iLBCenc_inst
->ULP_inst
->cb_gain
[i
][k
][ulp
+1]+
502 iLBCenc_inst
->ULP_inst
->cb_gain
[i
][k
][ulp
+2]);
503 dopack( &pbytes
, firstpart
,
504 iLBCenc_inst
->ULP_inst
->cb_gain
[i
][k
][ulp
],
510 /* set the last unused bit to zero */
511 dopack( &pbytes
, 0, 1, &pos
);