Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / c_g_aver.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.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 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: c_g_aver.cpp
35  Functions:
36             Cb_gain_average_reset
37             Cb_gain_average
38
39 ------------------------------------------------------------------------------
40  MODULE DESCRIPTION
41
42  This file contains functions that reset and perform
43  codebook gain calculations.
44
45 ------------------------------------------------------------------------------
46 */
47
48
49 /*----------------------------------------------------------------------------
50 ; INCLUDES
51 ----------------------------------------------------------------------------*/
52 #include    "c_g_aver.h"
53 #include    "typedef.h"
54 #include    "mode.h"
55 #include    "cnst.h"
56
57 #include    "basic_op.h"
58 #include    "oscl_mem.h"
59
60 /*----------------------------------------------------------------------------
61 ; MACROS
62 ; Define module specific macros here
63 ----------------------------------------------------------------------------*/
64
65
66 /*----------------------------------------------------------------------------
67 ; DEFINES
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
71
72 /*----------------------------------------------------------------------------
73 ; LOCAL FUNCTION DEFINITIONS
74 ; Function Prototype declaration
75 ----------------------------------------------------------------------------*/
76
77 /*----------------------------------------------------------------------------
78 ; LOCAL VARIABLE DEFINITIONS
79 ; Variable declaration - defined here and used outside this module
80 ----------------------------------------------------------------------------*/
81
82 /*
83 ------------------------------------------------------------------------------
84  FUNCTION NAME: Cb_gain_average_reset
85 ------------------------------------------------------------------------------
86  INPUT AND OUTPUT DEFINITIONS
87
88  Inputs:
89     state = pointer to a structure of type Cb_gain_averageState
90
91  Outputs:
92     Structure pointed to by state is initialized to zeros
93
94  Returns:
95     Returns 0 if memory was successfully initialized,
96         otherwise returns -1.
97
98  Global Variables Used:
99     None.
100
101  Local Variables Needed:
102     None.
103
104 ------------------------------------------------------------------------------
105  FUNCTION DESCRIPTION
106
107  Resets state memory
108
109 ------------------------------------------------------------------------------
110  REQUIREMENTS
111
112  None.
113
114 ------------------------------------------------------------------------------
115  REFERENCES
116
117  c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
118
119 ------------------------------------------------------------------------------
120  PSEUDO-CODE
121
122 Word16 Cb_gain_average_reset (Cb_gain_averageState *state)
123 {
124    if (state == (Cb_gain_averageState *) NULL){
125       fprintf(stderr, "Cb_gain_average_reset: invalid parameter\n");
126       return -1;
127    }
128
129    // Static vectors to zero
130    Set_zero (state->cbGainHistory, L_CBGAINHIST);
131
132    // Initialize hangover handling
133    state->hangVar = 0;
134    state->hangCount= 0;
135
136    return 0;
137 }
138
139 ------------------------------------------------------------------------------
140  CAUTION [optional]
141  [State any special notes, constraints or cautions for users of this function]
142
143 ------------------------------------------------------------------------------
144 */
145
146 Word16  Cb_gain_average_reset(Cb_gain_averageState *state)
147 {
148     if (state == (Cb_gain_averageState *) NULL)
149     {
150         /* fprint(stderr, "Cb_gain_average_reset: invalid parameter\n");  */
151         return(-1);
152     }
153
154     /* Static vectors to zero */
155     oscl_memset(state->cbGainHistory, 0, L_CBGAINHIST*sizeof(Word16));
156
157     /* Initialize hangover handling */
158     state->hangVar = 0;
159     state->hangCount = 0;
160
161     return(0);
162 }
163
164 /****************************************************************************/
165
166 /*
167 ------------------------------------------------------------------------------
168  FUNCTION NAME: Cb_gain_average
169 ------------------------------------------------------------------------------
170  INPUT AND OUTPUT DEFINITIONS
171
172  Inputs:
173     st = pointer to structure of type Cb_gain_averageState
174     mode = AMR mode (enum Mode)
175     gain_code = CB gain (Word16)
176     lsp = the LSP for the current frame (Word16)
177     lspAver = the average of LSP for 8 frames (Word16)
178     bfi = bad frame indication flag (Word16)
179     prev_bf = previous bad frame indication flag (Word16)
180     pdfi = potential degraded bad frame ind flag (Word16)
181     prev_pdf = prev pot. degraded bad frame ind flag (Word16)
182     inBackgroundNoise = background noise decision (Word16)
183     voicedHangover = # of frames after last voiced frame (Word16)
184     pOverflow = address of overflow (Flag)
185
186  Returns:
187     cbGainMix = codebook gain (Word16)
188
189  Outputs:
190     None.
191
192  Global Variables Used:
193     None.
194
195  Local Variables Needed:
196     None.
197
198 ------------------------------------------------------------------------------
199  FUNCTION DESCRIPTION
200
201  The mix cb gains for MR475, MR515, MR59, MR67, MR102; gain_code other modes
202
203 ------------------------------------------------------------------------------
204  REQUIREMENTS
205
206  None.
207
208 ------------------------------------------------------------------------------
209  REFERENCES
210
211  c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
212
213 ------------------------------------------------------------------------------
214  PSEUDO-CODE
215
216 Word16 Cb_gain_average (
217    Cb_gain_averageState *st, // i/o : State variables for CB gain avergeing
218    enum Mode mode,           // i   : AMR mode
219    Word16 gain_code,         // i   : CB gain                              Q1
220    Word16 lsp[],             // i   : The LSP for the current frame       Q15
221    Word16 lspAver[],         // i   : The average of LSP for 8 frames     Q15
222    Word16 bfi,               // i   : bad frame indication flag
223    Word16 prev_bf,           // i   : previous bad frame indication flag
224    Word16 pdfi,              // i   : potential degraded bad frame ind flag
225    Word16 prev_pdf,          // i   : prev pot. degraded bad frame ind flag
226    Word16 inBackgroundNoise, // i   : background noise decision
227    Word16 voicedHangover     // i   : # of frames after last voiced frame
228    )
229 {
230    //---------------------------------------------------------*
231     * Compute mixed cb gain, used to make cb gain more        *
232     * smooth in background noise for modes 5.15, 5.9 and 6.7  *
233     * states that needs to be updated by all                  *
234     *---------------------------------------------------------
235    Word16 i;
236    Word16 cbGainMix, diff, tmp_diff, bgMix, cbGainMean;
237    Word32 L_sum;
238    Word16 tmp[M], tmp1, tmp2, shift1, shift2, shift;
239
240    // set correct cbGainMix for MR74, MR795, MR122
241    cbGainMix = gain_code;
242
243     *-------------------------------------------------------*
244     *   Store list of CB gain needed in the CB gain         *
245     *   averaging                                           *
246     *-------------------------------------------------------*
247    for (i = 0; i < (L_CBGAINHIST-1); i++)
248    {
249       st->cbGainHistory[i] = st->cbGainHistory[i+1];
250    }
251    st->cbGainHistory[L_CBGAINHIST-1] = gain_code;
252
253    // compute lsp difference
254    for (i = 0; i < M; i++) {
255       tmp1 = abs_s(sub(lspAver[i], lsp[i]));  // Q15
256       shift1 = sub(norm_s(tmp1), 1);          // Qn
257       tmp1 = shl(tmp1, shift1);               // Q15+Qn
258       shift2 = norm_s(lspAver[i]);            // Qm
259       tmp2 = shl(lspAver[i], shift2);         // Q15+Qm
260       tmp[i] = div_s(tmp1, tmp2);             // Q15+(Q15+Qn)-(Q15+Qm)
261       shift = sub(add(2, shift1), shift2);
262       if (shift >= 0)
263       {
264          tmp[i] = shr(tmp[i], shift); // Q15+Qn-Qm-Qx=Q13
265       }
266       else
267       {
268          tmp[i] = shl(tmp[i], negate(shift)); // Q15+Qn-Qm-Qx=Q13
269       }
270    }
271
272    diff = tmp[0];
273    for (i = 1; i < M; i++) {
274       diff = add(diff, tmp[i]);       // Q13
275    }
276
277    // Compute hangover
278    if (sub(diff, 5325) > 0)  // 0.65 in Q11
279    {
280       st->hangVar = add(st->hangVar, 1);
281    }
282    else
283    {
284       st->hangVar = 0;
285    }
286
287    if (sub(st->hangVar, 10) > 0)
288    {
289       st->hangCount = 0;  // Speech period, reset hangover variable
290    }
291
292    // Compute mix constant (bgMix)
293    bgMix = 8192;    // 1 in Q13
294    if ((sub(mode, MR67) <= 0) || (sub(mode, MR102) == 0))
295       // MR475, MR515, MR59, MR67, MR102
296    {
297       // if errors and presumed noise make smoothing probability stronger
298       if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || (prev_bf != 0)) &&
299           (sub(voicedHangover, 1) > 0) && (inBackgroundNoise != 0) &&
300           ((sub(mode, MR475) == 0) ||
301            (sub(mode, MR515) == 0) ||
302            (sub(mode, MR59) == 0)) ))
303       {
304          // bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25;
305          tmp_diff = sub(diff, 4506);   // 0.55 in Q13
306
307          // max(0.0, diff-0.55)
308          if (tmp_diff > 0)
309          {
310             tmp1 = tmp_diff;
311          }
312          else
313          {
314             tmp1 = 0;
315          }
316
317          // min(0.25, tmp1)
318          if (sub(2048, tmp1) < 0)
319          {
320             bgMix = 8192;
321          }
322          else
323          {
324             bgMix = shl(tmp1, 2);
325          }
326       }
327       else
328       {
329          // bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25;
330          tmp_diff = sub(diff, 3277); // 0.4 in Q13
331
332          // max(0.0, diff-0.40)
333          if (tmp_diff > 0)
334          {
335             tmp1 = tmp_diff;
336          }
337          else
338          {
339             tmp1 = 0;
340          }
341
342          // min(0.25, tmp1)
343          if (sub(2048, tmp1) < 0)
344          {
345             bgMix = 8192;
346          }
347          else
348          {
349             bgMix = shl(tmp1, 2);
350          }
351       }
352
353       if ((sub(st->hangCount, 40) < 0) || (sub(diff, 5325) > 0)) // 0.65 in Q13
354       {
355          bgMix = 8192;  // disable mix if too short time since
356       }
357
358       // Smoothen the cb gain trajectory
359       // smoothing depends on mix constant bgMix
360       L_sum = L_mult(6554, st->cbGainHistory[2]); // 0.2 in Q15; L_sum in Q17
361       for (i = 3; i < L_CBGAINHIST; i++)
362       {
363          L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i]);
364       }
365       cbGainMean = pv_round(L_sum);                      // Q1
366
367       // more smoothing in error and bg noise (NB no DFI used  here)
368       if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) &&
369           ((sub(mode, MR475) == 0) ||
370            (sub(mode, MR515) == 0) ||
371            (sub(mode, MR59) == 0)) )
372       {
373          L_sum = L_mult(4681, st->cbGainHistory[0]); // 0.143 in Q15; L_sum in Q17
374          for (i = 1; i < L_CBGAINHIST; i++)
375          {
376             L_sum = L_mac(L_sum, 4681, st->cbGainHistory[i]);
377          }
378          cbGainMean = pv_round(L_sum);                   // Q1
379       }
380
381       // cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean;
382       L_sum = L_mult(bgMix, cbGainMix);               // L_sum in Q15
383       L_sum = L_mac(L_sum, 8192, cbGainMean);
384       L_sum = L_msu(L_sum, bgMix, cbGainMean);
385       cbGainMix = pv_round(L_shl(L_sum, 2));             // Q1
386    }
387
388    st->hangCount = add(st->hangCount, 1);
389    return cbGainMix;
390 }
391
392 ------------------------------------------------------------------------------
393  CAUTION [optional]
394  [State any special notes, constraints or cautions for users of this function]
395
396 ------------------------------------------------------------------------------
397 */
398
399 Word16 Cb_gain_average(
400     Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */
401     enum Mode mode,           /* i   : AMR mode                              */
402     Word16 gain_code,         /* i   : CB gain                            Q1 */
403     Word16 lsp[],             /* i   : The LSP for the current frame     Q15 */
404     Word16 lspAver[],         /* i   : The average of LSP for 8 frames   Q15 */
405     Word16 bfi,               /* i   : bad frame indication flag             */
406     Word16 prev_bf,           /* i   : previous bad frame indication flag    */
407     Word16 pdfi,              /* i   : potential degraded bad frame ind flag */
408     Word16 prev_pdf,          /* i   : prev pot. degraded bad frame ind flag */
409     Word16 inBackgroundNoise, /* i   : background noise decision             */
410     Word16 voicedHangover,    /* i   : # of frames after last voiced frame   */
411     Flag   *pOverflow
412 )
413 {
414     Word16 i;
415     Word16 cbGainMix;
416     Word16 diff;
417     Word16 tmp_diff;
418     Word16 bgMix;
419     Word16 cbGainMean;
420     Word32 L_sum;
421     Word16 tmp[M];
422     Word16 tmp1;
423     Word16 tmp2;
424     Word16 shift1;
425     Word16 shift2;
426     Word16 shift;
427
428     /*---------------------------------------------------------*
429      * Compute mixed cb gain, used to make cb gain more        *
430      * smooth in background noise for modes 5.15, 5.9 and 6.7  *
431      * states that needs to be updated by all                  *
432      *---------------------------------------------------------*/
433
434     /* set correct cbGainMix for MR74, MR795, MR122 */
435     cbGainMix = gain_code;
436
437     /*-------------------------------------------------------*
438      *   Store list of CB gain needed in the CB gain         *
439      *   averaging                                           *
440      *-------------------------------------------------------*/
441     for (i = 0; i < (L_CBGAINHIST - 1); i++)
442     {
443         st->cbGainHistory[i] = st->cbGainHistory[i+1];
444     }
445     st->cbGainHistory[L_CBGAINHIST-1] = gain_code;
446
447     diff = 0;
448
449     /* compute lsp difference */
450     for (i = 0; i < M; i++)
451     {
452         tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow));
453         /* Q15      */
454         shift1 = norm_s(tmp1) - 1 ;                     /* Qn       */
455         tmp1 = shl(tmp1, shift1, pOverflow);            /* Q15+Qn   */
456         shift2 = norm_s(*(lspAver + i));                /* Qm       */
457         tmp2 = shl(*(lspAver + i), shift2, pOverflow);  /* Q15+Qm   */
458         tmp[i] = div_s(tmp1, tmp2);        /* Q15+(Q15+Qn)-(Q15+Qm) */
459
460         shift = 2 + shift1 - shift2;
461
462         if (shift >= 0)
463         {
464             *(tmp + i) = shr(*(tmp + i), shift, pOverflow);
465             /* Q15+Qn-Qm-Qx=Q13 */
466         }
467         else
468         {
469             *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow);
470             /* Q15+Qn-Qm-Qx=Q13 */
471         }
472
473         diff = add_16(diff, *(tmp + i), pOverflow);           /* Q13 */
474     }
475
476     /* Compute hangover */
477
478     if (diff > 5325)                /* 0.65 in Q11 */
479     {
480         st->hangVar += 1;
481     }
482     else
483     {
484         st->hangVar = 0;
485     }
486
487
488     if (st->hangVar > 10)
489     {
490         /* Speech period, reset hangover variable */
491         st->hangCount = 0;
492     }
493
494     /* Compute mix constant (bgMix) */
495     bgMix = 8192;    /* 1 in Q13 */
496
497     if ((mode <= MR67) || (mode == MR102))
498         /* MR475, MR515, MR59, MR67, MR102 */
499     {
500         /* if errors and presumed noise make smoothing probability stronger */
501
502         if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) ||
503                 (prev_bf != 0))
504                 && (voicedHangover > 1)
505                 && (inBackgroundNoise != 0)
506                 && ((mode == MR475) || (mode == MR515) ||
507                     (mode == MR59))))
508         {
509             /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */
510             tmp_diff = diff - 4506;   /* 0.55 in Q13 */
511         }
512         else
513         {
514             /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */
515             tmp_diff = diff - 3277; /* 0.4 in Q13 */
516         }
517
518         /* max(0.0, diff-0.55)  or  */
519         /* max(0.0, diff-0.40) */
520         if (tmp_diff > 0)
521         {
522             tmp1 = tmp_diff;
523         }
524         else
525         {
526             tmp1 = 0;
527         }
528
529         /* min(0.25, tmp1) */
530         if (2048 < tmp1)
531         {
532             bgMix = 8192;
533         }
534         else
535         {
536             bgMix = shl(tmp1, 2, pOverflow);
537         }
538
539         if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */
540         {
541             /* disable mix if too short time since */
542             bgMix = 8192;
543         }
544
545         /* Smoothen the cb gain trajectory  */
546         /* smoothing depends on mix constant bgMix */
547         L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow);
548         /* 0.2 in Q15; L_sum in Q17 */
549
550         for (i = 3; i < L_CBGAINHIST; i++)
551         {
552             L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow);
553         }
554         cbGainMean = pv_round(L_sum, pOverflow);               /* Q1 */
555
556         /* more smoothing in error and bg noise (NB no DFI used here) */
557
558         if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0)
559                 && ((mode == MR475) || (mode == MR515)
560                     || (mode == MR59)))
561         {
562             /* 0.143 in Q15; L_sum in Q17    */
563             L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow);
564             for (i = 1; i < L_CBGAINHIST; i++)
565             {
566                 L_sum =
567                     L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow);
568             }
569             cbGainMean = pv_round(L_sum, pOverflow);              /* Q1 */
570         }
571
572         /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */
573         /* L_sum in Q15 */
574         L_sum = L_mult(bgMix, cbGainMix, pOverflow);
575         L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow);
576         L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow);
577         cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow);  /* Q1 */
578     }
579
580     st->hangCount += 1;
581
582     return (cbGainMix);
583 }
584