Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_wb / dec / src / dec_gain2_amr_wb.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.173
22     ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: dec_gain2_amr_wb.cpp
35
36 ------------------------------------------------------------------------------
37  INPUT AND OUTPUT DEFINITIONS
38
39      int16 index,                 (i)     : index of quantization.
40      int16 nbits,                 (i)     : number of bits (6 or 7)
41      int16 code[],                (i) Q9  : Innovative vector.
42      int16 L_subfr,               (i)     : Subframe lenght.
43      int16 * gain_pit,            (o) Q14 : Pitch gain.
44      int32 * gain_cod,            (o) Q16 : Code gain.
45      int16 bfi,                   (i)     : bad frame indicator
46      int16 prev_bfi,              (i)     : Previous BF indicator
47      int16 state,                 (i)     : State of BFH
48      int16 unusable_frame,        (i)     : UF indicator
49      int16 vad_hist,              (i)     : number of non-speech frames
50      int16 * mem                  (i/o)   : static memory (4 words)
51
52 ------------------------------------------------------------------------------
53  FUNCTION DESCRIPTION
54
55     Decode the pitch and codebook gains
56
57 ------------------------------------------------------------------------------
58  REQUIREMENTS
59
60
61 ------------------------------------------------------------------------------
62  REFERENCES
63
64 ------------------------------------------------------------------------------
65  PSEUDO-CODE
66
67 ------------------------------------------------------------------------------
68 */
69
70
71 /*----------------------------------------------------------------------------
72 ; INCLUDES
73 ----------------------------------------------------------------------------*/
74
75
76 #include "pv_amr_wb_type_defs.h"
77 #include "pvamrwbdecoder_basic_op.h"
78 #include "pvamrwb_math_op.h"
79 #include "pvamrwbdecoder_cnst.h"
80 #include "pvamrwbdecoder_acelp.h"
81
82 #include "qisf_ns.h"
83
84 /*----------------------------------------------------------------------------
85 ; MACROS
86 ; Define module specific macros here
87 ----------------------------------------------------------------------------*/
88
89
90 /*----------------------------------------------------------------------------
91 ; DEFINES
92 ; Include all pre-processor statements here. Include conditional
93 ; compile variables also.
94 ----------------------------------------------------------------------------*/
95
96 #define MEAN_ENER    30
97 #define PRED_ORDER   4
98
99 #define L_LTPHIST 5
100
101 /*----------------------------------------------------------------------------
102 ; LOCAL FUNCTION DEFINITIONS
103 ; Function Prototype declaration
104 ----------------------------------------------------------------------------*/
105
106 /*----------------------------------------------------------------------------
107 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
108 ; Variable declaration - defined here and used outside this module
109 ----------------------------------------------------------------------------*/
110
111 const int16 pdown_unusable[7] = {32767, 31130, 29491, 24576, 7537, 1638, 328};
112 const int16 cdown_unusable[7] = {32767, 16384, 8192, 8192, 8192, 4915, 3277};
113
114 const int16 pdown_usable[7] = {32767, 32113, 31457, 24576, 7537, 1638, 328};
115 const int16 cdown_usable[7] = {32767, 32113, 32113, 32113, 32113, 32113, 22938};
116
117
118 /* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */
119 const int16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};
120
121 /*----------------------------------------------------------------------------
122 ; EXTERNAL FUNCTION REFERENCES
123 ; Declare functions defined elsewhere and referenced in this module
124 ----------------------------------------------------------------------------*/
125
126 /*----------------------------------------------------------------------------
127 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
128 ; Declare variables used in this module but defined elsewhere
129 ----------------------------------------------------------------------------*/
130
131 /*----------------------------------------------------------------------------
132 ; FUNCTION CODE
133 ----------------------------------------------------------------------------*/
134
135
136 /* output  :static memory (4 words)      */
137 void dec_gain2_amr_wb_init(int16 * mem)
138 {
139
140     /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */
141     mem[0] = -14336;                          /* past_qua_en[0] */
142     mem[1] = -14336;                          /* past_qua_en[1] */
143     mem[2] = -14336;                          /* past_qua_en[2] */
144     mem[3] = -14336;                          /* past_qua_en[3] */
145     /* 4  *past_gain_pit  */
146     /* 5  *past_gain_code  */
147     /* 6  *prev_gc  */
148     /* next 5  pbuf[]  */
149     /* next 5  gbuf[]  */
150     /* next 5  pbuf2[]  */
151     pv_memset((void *)&mem[4], 0, 18*sizeof(*mem));
152
153     mem[22] = 21845;
154
155 }
156
157 /*----------------------------------------------------------------------------
158 ; FUNCTION CODE
159 ----------------------------------------------------------------------------*/
160
161 void dec_gain2_amr_wb(
162     int16 index,               /* (i)     : index of quantization.      */
163     int16 nbits,               /* (i)     : number of bits (6 or 7)     */
164     int16 code[],              /* (i) Q9  : Innovative vector.          */
165     int16 L_subfr,             /* (i)     : Subframe lenght.            */
166     int16 * gain_pit,          /* (o) Q14 : Pitch gain.                 */
167     int32 * gain_cod,          /* (o) Q16 : Code gain.                  */
168     int16 bfi,                 /* (i)     : bad frame indicator         */
169     int16 prev_bfi,            /* (i)     : Previous BF indicator       */
170     int16 state,               /* (i)     : State of BFH                */
171     int16 unusable_frame,      /* (i)     : UF indicator                */
172     int16 vad_hist,            /* (i)     : number of non-speech frames */
173     int16 * mem                /* (i/o)   : static memory (4 words)     */
174 )
175 {
176     const int16 *p;
177     int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;
178     int16 *pbuf2;
179     int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;
180     int16 tmp1, g_code;
181     int16 tmp2;
182     int32 L_tmp;
183
184     past_qua_en = mem;
185     past_gain_pit = mem + 4;
186     past_gain_code = mem + 5;
187     prev_gc = mem + 6;
188     pbuf = mem + 7;
189     gbuf = mem + 12;
190     pbuf2 = mem + 17;
191
192     /*
193      *  Find energy of code and compute:
194      *
195      *    L_tmp = 1.0 / sqrt(energy of code/ L_subfr)
196      */
197
198     L_tmp = Dot_product12(code, code, L_subfr, &exp);
199     exp -= 24;                /* exp: -18 (code in Q9), -6 (/L_subfr) */
200
201     one_ov_sqrt_norm(&L_tmp, &exp);
202
203     gcode_inov = extract_h(shl_int32(L_tmp, exp - 3));  /* g_code_inov in Q12 */
204
205     /*
206      * Case of erasure.
207      */
208
209     if (bfi != 0)
210     {
211         tmp = median5(&pbuf[2]);
212         *past_gain_pit = tmp;
213
214         if (*past_gain_pit > 15565)
215         {
216             *past_gain_pit = 15565;        /* 0.95 in Q14 */
217
218         }
219
220         if (unusable_frame != 0)
221         {
222             *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit);
223         }
224         else
225         {
226             *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit);
227         }
228         tmp = median5(&gbuf[2]);
229
230         if (vad_hist > 2)
231         {
232             *past_gain_code = tmp;
233         }
234         else
235         {
236
237             if (unusable_frame != 0)
238             {
239                 *past_gain_code = mult_int16(cdown_unusable[state], tmp);
240             }
241             else
242             {
243                 *past_gain_code = mult_int16(cdown_usable[state], tmp);
244             }
245         }
246
247         /* update table of past quantized energies */
248
249         tmp  = past_qua_en[3];
250         tmp1 = past_qua_en[2];
251         L_tmp  = tmp;
252         L_tmp += tmp1;
253         past_qua_en[3] = tmp;
254         tmp  = past_qua_en[1];
255         tmp1 = past_qua_en[0];
256         L_tmp += tmp;
257         L_tmp += tmp1;
258         past_qua_en[2] = tmp;
259         qua_ener = (int16)(L_tmp >> 3);
260         past_qua_en[1] = tmp1;
261
262
263         qua_ener -= 3072;    /* -3 in Q10 */
264
265         if (qua_ener < -14336)
266         {
267             qua_ener = -14336;                /* -14 in Q10 */
268         }
269
270         past_qua_en[0] = qua_ener;
271
272
273         for (i = 1; i < 5; i++)
274         {
275             gbuf[i - 1] = gbuf[i];
276             pbuf[i - 1] = pbuf[i];
277         }
278         gbuf[4] = *past_gain_code;
279         pbuf[4] = *past_gain_pit;
280
281
282         /* adjust gain according to energy of code */
283         /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */
284         *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov);
285
286         return;
287     }
288     /*
289      * Compute gcode0
290      *  = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code
291      */
292
293     L_tmp = L_deposit_h(MEAN_ENER);        /* MEAN_ENER in Q16 */
294     L_tmp = shl_int32(L_tmp, 8);               /* From Q16 to Q24 */
295     L_tmp = mac_16by16_to_int32(L_tmp, pred[0], past_qua_en[0]);      /* Q13*Q10 -> Q24 */
296     L_tmp = mac_16by16_to_int32(L_tmp, pred[1], past_qua_en[1]);      /* Q13*Q10 -> Q24 */
297     L_tmp = mac_16by16_to_int32(L_tmp, pred[2], past_qua_en[2]);      /* Q13*Q10 -> Q24 */
298     L_tmp = mac_16by16_to_int32(L_tmp, pred[3], past_qua_en[3]);      /* Q13*Q10 -> Q24 */
299
300     gcode0 = extract_h(L_tmp);             /* From Q24 to Q8  */
301
302     /*
303      * gcode0 = pow(10.0, gcode0/20)
304      *        = pow(2, 3.321928*gcode0/20)
305      *        = pow(2, 0.166096*gcode0)
306      */
307
308     L_tmp = ((int32)gcode0 * 5443) >> 7;      /* *0.166096 in Q15 -> Q24     */
309
310     int32_to_dpf(L_tmp, &exp_gcode0, &frac);  /* Extract exponant of gcode0  */
311
312     gcode0 = (int16)(power_of_2(14, frac));    /* Put 14 as exponant so that  */
313     /* output of Pow2() will be:   */
314     /* 16384 < Pow2() <= 32767     */
315     exp_gcode0 -= 14;
316
317     /* Read the quantized gains */
318
319     if (nbits == 6)
320     {
321         p = &t_qua_gain6b[index<<1];
322     }
323     else
324     {
325         p = &t_qua_gain7b[index<<1];
326     }
327     *gain_pit = *p++;                         /* selected pitch gain in Q14 */
328     g_code = *p++;                            /* selected code gain in Q11  */
329
330     L_tmp = mul_16by16_to_int32(g_code, gcode0);        /* Q11*Q0 -> Q12 */
331     L_tmp = shl_int32(L_tmp, exp_gcode0 + 4);   /* Q12 -> Q16 */
332
333     *gain_cod = L_tmp;                        /* gain of code in Q16 */
334
335     if (prev_bfi == 1)
336     {
337         L_tmp = mul_16by16_to_int32(*prev_gc, 5120);    /* prev_gc(Q3) * 1.25(Q12) = Q16 */
338         /* if((*gain_cod > ((*prev_gc) * 1.25)) && (*gain_cod > 100.0)) */
339
340         if ((*gain_cod > L_tmp) && (*gain_cod > 6553600))
341         {
342             *gain_cod = L_tmp;
343         }
344     }
345     /* keep past gain code in Q3 for frame erasure (can saturate) */
346     *past_gain_code = amr_wb_round(shl_int32(*gain_cod, 3));
347     *past_gain_pit = *gain_pit;
348
349
350     *prev_gc = *past_gain_code;
351     tmp  = gbuf[1];
352     tmp1 = pbuf[1];
353     tmp2 = pbuf2[1];
354     for (i = 1; i < 5; i++)
355     {
356         gbuf[i - 1]  = tmp;
357         pbuf[i - 1]  = tmp1;
358         pbuf2[i - 1] = tmp2;
359         tmp  = gbuf[i];
360         tmp1 = pbuf[i];
361         tmp2 = pbuf2[i];
362     }
363     gbuf[4] = *past_gain_code;
364     pbuf[4] = *past_gain_pit;
365     pbuf2[4] = *past_gain_pit;
366
367
368     /* adjust gain according to energy of code */
369     int32_to_dpf(*gain_cod, &exp, &frac);
370     L_tmp = mul_32by16(exp, frac, gcode_inov);
371
372     *gain_cod = shl_int32(L_tmp, 3);              /* gcode_inov in Q12 */
373
374
375     past_qua_en[3] = past_qua_en[2];
376     past_qua_en[2] = past_qua_en[1];
377     past_qua_en[1] = past_qua_en[0];
378
379     /*
380      * qua_ener = 20*log10(g_code)
381      *          = 6.0206*log2(g_code)
382      *          = 6.0206*(log2(g_codeQ11) - 11)
383      */
384     L_tmp = (int32)g_code;
385     amrwb_log_2(L_tmp, &exp, &frac);
386     exp -= 11;
387     L_tmp = mul_32by16(exp, frac, 24660);   /* x 6.0206 in Q12 */
388
389     /* update table of past quantized energies */
390
391     past_qua_en[0] = (int16)(L_tmp >> 3); /* result in Q10 */
392
393     return;
394 }
395
396