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