Home | History | Annotate | Download | only in ilbc
      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