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