1 /*
2  *  Copyright (c) 2011 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_DecodeResidual.c
16 
17 ******************************************************************/
18 
19 #include <string.h>
20 
21 #include "defines.h"
22 #include "state_construct.h"
23 #include "cb_construct.h"
24 #include "index_conv_dec.h"
25 #include "do_plc.h"
26 #include "constants.h"
27 #include "enhancer_interface.h"
28 #include "xcorr_coef.h"
29 #include "lsf_check.h"
30 
31 /*----------------------------------------------------------------*
32  *  frame residual decoder function (subrutine to iLBC_decode)
33  *---------------------------------------------------------------*/
34 
WebRtcIlbcfix_DecodeResidual(IlbcDecoder * iLBCdec_inst,iLBC_bits * iLBC_encbits,int16_t * decresidual,int16_t * syntdenum)35 void WebRtcIlbcfix_DecodeResidual(
36     IlbcDecoder *iLBCdec_inst,
37     /* (i/o) the decoder state structure */
38     iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
39                                 for the decoding  */
40     int16_t *decresidual,  /* (o) decoded residual frame */
41     int16_t *syntdenum   /* (i) the decoded synthesis filter
42                                   coefficients */
43                                   ) {
44   size_t meml_gotten, diff, start_pos;
45   size_t subcount, subframe;
46   int16_t *reverseDecresidual = iLBCdec_inst->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */
47   int16_t *memVec = iLBCdec_inst->prevResidual;  /* Memory for codebook and filter state (reuse memory in state) */
48   int16_t *mem = &memVec[CB_HALFFILTERLEN];   /* Memory for codebook */
49 
50   diff = STATE_LEN - iLBCdec_inst->state_short_len;
51 
52   if (iLBC_encbits->state_first == 1) {
53     start_pos = (iLBC_encbits->startIdx-1)*SUBL;
54   } else {
55     start_pos = (iLBC_encbits->startIdx-1)*SUBL + diff;
56   }
57 
58   /* decode scalar part of start state */
59 
60   WebRtcIlbcfix_StateConstruct(iLBC_encbits->idxForMax,
61                                iLBC_encbits->idxVec, &syntdenum[(iLBC_encbits->startIdx-1)*(LPC_FILTERORDER+1)],
62                                &decresidual[start_pos], iLBCdec_inst->state_short_len
63                                );
64 
65   if (iLBC_encbits->state_first) { /* put adaptive part in the end */
66 
67     /* setup memory */
68 
69     WebRtcSpl_MemSetW16(mem, 0, CB_MEML - iLBCdec_inst->state_short_len);
70     WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos,
71                           iLBCdec_inst->state_short_len);
72 
73     /* construct decoded vector */
74 
75     WebRtcIlbcfix_CbConstruct(
76         &decresidual[start_pos+iLBCdec_inst->state_short_len],
77         iLBC_encbits->cb_index, iLBC_encbits->gain_index,
78         mem+CB_MEML-ST_MEM_L_TBL,
79         ST_MEM_L_TBL, diff);
80 
81   }
82   else {/* put adaptive part in the beginning */
83 
84     /* setup memory */
85 
86     meml_gotten = iLBCdec_inst->state_short_len;
87     WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
88                                   decresidual+start_pos, meml_gotten);
89     WebRtcSpl_MemSetW16(mem, 0, CB_MEML - meml_gotten);
90 
91     /* construct decoded vector */
92 
93     WebRtcIlbcfix_CbConstruct(
94         reverseDecresidual,
95         iLBC_encbits->cb_index, iLBC_encbits->gain_index,
96         mem+CB_MEML-ST_MEM_L_TBL,
97         ST_MEM_L_TBL, diff
98                               );
99 
100     /* get decoded residual from reversed vector */
101 
102     WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1],
103                                   reverseDecresidual, diff);
104   }
105 
106   /* counter for predicted subframes */
107 
108   subcount=1;
109 
110   /* forward prediction of subframes */
111 
112   if (iLBCdec_inst->nsub > iLBC_encbits->startIdx + 1) {
113 
114     /* setup memory */
115     WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
116     WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
117                           decresidual+(iLBC_encbits->startIdx-1)*SUBL, STATE_LEN);
118 
119     /* loop over subframes to encode */
120 
121     size_t Nfor = iLBCdec_inst->nsub - iLBC_encbits->startIdx - 1;
122     for (subframe=0; subframe<Nfor; subframe++) {
123 
124       /* construct decoded vector */
125       WebRtcIlbcfix_CbConstruct(
126           &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL],
127           iLBC_encbits->cb_index+subcount*CB_NSTAGES,
128           iLBC_encbits->gain_index+subcount*CB_NSTAGES,
129           mem, MEM_LF_TBL, SUBL
130                                 );
131 
132       /* update memory */
133       memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
134       WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
135                             &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], SUBL);
136 
137       subcount++;
138     }
139 
140   }
141 
142   /* backward prediction of subframes */
143 
144   if (iLBC_encbits->startIdx > 1) {
145 
146     /* setup memory */
147 
148     meml_gotten = SUBL*(iLBCdec_inst->nsub+1-iLBC_encbits->startIdx);
149     if( meml_gotten > CB_MEML ) {
150       meml_gotten=CB_MEML;
151     }
152 
153     WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
154                                   decresidual+(iLBC_encbits->startIdx-1)*SUBL, meml_gotten);
155     WebRtcSpl_MemSetW16(mem, 0, CB_MEML - meml_gotten);
156 
157     /* loop over subframes to decode */
158 
159     size_t Nback = iLBC_encbits->startIdx - 1;
160     for (subframe=0; subframe<Nback; subframe++) {
161 
162       /* construct decoded vector */
163       WebRtcIlbcfix_CbConstruct(
164           &reverseDecresidual[subframe*SUBL],
165           iLBC_encbits->cb_index+subcount*CB_NSTAGES,
166           iLBC_encbits->gain_index+subcount*CB_NSTAGES,
167           mem, MEM_LF_TBL, SUBL
168                                 );
169 
170       /* update memory */
171       memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
172       WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
173                             &reverseDecresidual[subframe*SUBL], SUBL);
174 
175       subcount++;
176     }
177 
178     /* get decoded residual from reversed vector */
179     WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1,
180                                   reverseDecresidual, SUBL*Nback);
181   }
182 }
183