Tizen 2.0 Release
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / p_ol_wgh.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: p_ol_wgh.cpp
35  Functions: p_ol_wgh_init
36            p_ol_wgh_reset
37            p_ol_wgh_exit
38            Lag_max
39            Pitch_ol_wgh
40
41 ------------------------------------------------------------------------------
42  MODULE DESCRIPTION
43
44  The modules in this file compute the open loop pitch lag with weighting.
45 ------------------------------------------------------------------------------
46 */
47
48
49 /*----------------------------------------------------------------------------
50 ; INCLUDES
51 ----------------------------------------------------------------------------*/
52 #include "p_ol_wgh.h"
53 #include "typedef.h"
54 #include "cnst.h"
55 #include "basic_op.h"
56 #include "gmed_n.h"
57 #include "inv_sqrt.h"
58 #include "vad1.h"
59 #include "calc_cor.h"
60 #include "hp_max.h"
61 #include "oscl_mem.h"
62
63 /*----------------------------------------------------------------------------
64 ; MACROS
65 ; Define module specific macros here
66 ----------------------------------------------------------------------------*/
67
68
69 /*----------------------------------------------------------------------------
70 ; DEFINES
71 ; Include all pre-processor statements here. Include conditional
72 ; compile variables also.
73 ----------------------------------------------------------------------------*/
74
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; Function Prototype declaration
78 ----------------------------------------------------------------------------*/
79
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; Variable declaration - defined here and used outside this module
83 ----------------------------------------------------------------------------*/
84
85
86 /*
87 ------------------------------------------------------------------------------
88  FUNCTION NAME: p_ol_wgh_init
89 ------------------------------------------------------------------------------
90  INPUT AND OUTPUT DEFINITIONS
91
92  Inputs
93     state = pointer to a pointer of structure type pitchOLWghtState
94
95  Outputs:
96     None
97
98  Returns:
99     0 if the memory allocation is a success
100     -1 if the memory allocation fails
101
102  Global Variables Used:
103     None.
104
105  Local Variables Needed:
106     None.
107
108 ------------------------------------------------------------------------------
109  FUNCTION DESCRIPTION
110
111  This function allocates state memory and initializes state memory
112
113 ------------------------------------------------------------------------------
114  REQUIREMENTS
115
116  None.
117
118 ------------------------------------------------------------------------------
119  REFERENCES
120
121  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
122
123 ------------------------------------------------------------------------------
124  PSEUDO-CODE
125
126 int p_ol_wgh_init (pitchOLWghtState **state)
127 {
128     pitchOLWghtState* s;
129
130     if (state == (pitchOLWghtState **) NULL){
131         // fprintf(stderr, "p_ol_wgh_init: invalid parameter\n");
132         return -1;
133     }
134     *state = NULL;
135
136     // allocate memory
137     if ((s= (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL){
138         // fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n");
139         return -1;
140     }
141
142     p_ol_wgh_reset(s);
143
144     *state = s;
145
146     return 0;
147 }
148
149 ------------------------------------------------------------------------------
150  CAUTION [optional]
151  [State any special notes, constraints or cautions for users of this function]
152
153 ------------------------------------------------------------------------------
154 */
155
156 Word16 p_ol_wgh_init(pitchOLWghtState **state)
157 {
158     pitchOLWghtState* s;
159
160     if (state == (pitchOLWghtState **) NULL)
161     {
162         /* fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); */
163         return -1;
164     }
165     *state = NULL;
166
167     /* allocate memory */
168     if ((s = (pitchOLWghtState *) oscl_malloc(sizeof(pitchOLWghtState))) == NULL)
169     {
170         /* fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); */
171         return -1;
172     }
173
174     p_ol_wgh_reset(s);
175
176     *state = s;
177
178     return 0;
179 }
180
181 /*----------------------------------------------------------------------------
182 ; End Function: p_ol_wgh_init
183 ----------------------------------------------------------------------------*/
184
185 /*
186 ------------------------------------------------------------------------------
187  FUNCTION NAME: p_ol_wgh_reset
188 ------------------------------------------------------------------------------
189  INPUT AND OUTPUT DEFINITIONS
190
191  Inputs
192     st = pointer to structure type pitchOLWghtState
193
194  Outputs:
195     None
196
197  Returns:
198     0 if the memory initialization is a success
199     -1 if the memory initialization fails
200
201  Global Variables Used:
202     None.
203
204  Local Variables Needed:
205     None.
206
207 ------------------------------------------------------------------------------
208  FUNCTION DESCRIPTION
209
210  This function initializes state memory to zero
211
212 ------------------------------------------------------------------------------
213  REQUIREMENTS
214
215  None.
216
217 ------------------------------------------------------------------------------
218  REFERENCES
219
220  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
221
222 ------------------------------------------------------------------------------
223  PSEUDO-CODE
224
225 int p_ol_wgh_reset (pitchOLWghtState *st)
226 {
227    if (st == (pitchOLWghtState *) NULL){
228       // fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n");
229       return -1;
230    }
231
232    // Reset pitch search states
233    st->old_T0_med = 40;
234    st->ada_w = 0;
235    st->wght_flg = 0;
236
237    return 0;
238 }
239
240 ------------------------------------------------------------------------------
241  CAUTION [optional]
242  [State any special notes, constraints or cautions for users of this function]
243
244 ------------------------------------------------------------------------------
245 */
246
247 Word16 p_ol_wgh_reset(pitchOLWghtState *st)
248 {
249     if (st == (pitchOLWghtState *) NULL)
250     {
251         /* fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); */
252         return -1;
253     }
254
255     /* Reset pitch search states */
256     st->old_T0_med = 40;
257     st->ada_w = 0;
258     st->wght_flg = 0;
259
260     return 0;
261 }
262
263 /*----------------------------------------------------------------------------
264 ; End Function: p_ol_wgh_reset
265 ----------------------------------------------------------------------------*/
266
267 /*
268 ------------------------------------------------------------------------------
269  FUNCTION NAME: p_ol_wgh_exit
270 ------------------------------------------------------------------------------
271  INPUT AND OUTPUT DEFINITIONS
272
273  Inputs
274     st = pointer to a pointer of structure type pitchOLWghtState
275
276  Outputs:
277     None
278
279  Returns:
280     0 if the memory initialization is a success
281     -1 if the memory initialization fails
282
283  Global Variables Used:
284     None.
285
286  Local Variables Needed:
287     None.
288
289 ------------------------------------------------------------------------------
290  FUNCTION DESCRIPTION
291
292  This function frees the memory used for state memory
293
294 ------------------------------------------------------------------------------
295  REQUIREMENTS
296
297  None.
298
299 ------------------------------------------------------------------------------
300  REFERENCES
301
302  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
303
304 ------------------------------------------------------------------------------
305  PSEUDO-CODE
306
307 void p_ol_wgh_exit (pitchOLWghtState **state)
308 {
309     if (state == NULL || *state == NULL)
310         return;
311
312     // deallocate memory
313     free(*state);
314     *state = NULL;
315
316     return;
317 }
318
319 ------------------------------------------------------------------------------
320  CAUTION [optional]
321  [State any special notes, constraints or cautions for users of this function]
322
323 ------------------------------------------------------------------------------
324 */
325
326 void p_ol_wgh_exit(pitchOLWghtState **state)
327 {
328     if (state == NULL || *state == NULL)
329         return;
330
331     /* deallocate memory */
332     oscl_free(*state);
333     *state = NULL;
334
335     return;
336 }
337
338
339 /*----------------------------------------------------------------------------
340 ; End Function: p_ol_wgh_exit
341 ----------------------------------------------------------------------------*/
342 /*
343 ------------------------------------------------------------------------------
344  FUNCTION NAME: Lag_max
345 ------------------------------------------------------------------------------
346  INPUT AND OUTPUT DEFINITIONS
347
348  Inputs:
349     corr = pointer to buffer of correlation values (Word32)
350     scal_sig = pointer to buffer of scaled signal values (Word16)
351     scal_fac = scaled signal factor (Word16)
352     scal_flag = EFR compatible scaling flag (Word16)
353     L_frame = length of frame to compute pitch (Word16)
354     lag_max = maximum lag (Word16)
355     lag_min = minimum lag (Word16)
356     cor_max = pointer to the normalized correlation of selected lag (Word16)
357     rmax = pointer to max(<s[i]*s[j]>), (Word32)
358     r0 = pointer to the residual energy (Word32)
359     dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
360     pOverflow = Pointer to overflow (Flag)
361
362  Outputs:
363     cor_max contains the newly calculated normalized correlation of the
364       selected lag
365     rmax contains the newly calculated max(<s[i]*s[j]>)
366     r0 contains the newly calculated residual energy
367     pOverflow -> 1 if the math functions called by this routine saturate.
368
369  Returns:
370     p_max = lag of the max correlation found (Word16)
371
372  Global Variables Used:
373     None.
374
375  Local Variables Needed:
376     None.
377
378 ------------------------------------------------------------------------------
379  FUNCTION DESCRIPTION
380
381  This function finds the lag that has maximum correlation of scal_sig[] in a
382  given delay range.
383  The correlation is given by
384     cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
385  The functions outputs the maximum correlation after normalization and the
386  corresponding lag.
387
388 ------------------------------------------------------------------------------
389  REQUIREMENTS
390
391  None.
392
393 ------------------------------------------------------------------------------
394  REFERENCES
395
396  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
397
398 ------------------------------------------------------------------------------
399  PSEUDO-CODE
400
401 static Word16 Lag_max ( // o : lag found
402     vadState *vadSt,    // i/o : VAD state struct
403     Word32 corr[],      // i   : correlation vector.
404     Word16 scal_sig[],  // i : scaled signal.
405     Word16 L_frame,     // i : length of frame to compute pitch
406     Word16 lag_max,     // i : maximum lag
407     Word16 lag_min,     // i : minimum lag
408     Word16 old_lag,     // i : old open-loop lag
409     Word16 *cor_max,    // o : normalized correlation of selected lag
410     Word16 wght_flg,    // i : is weighting function used
411     Word16 *gain_flg,   // o : open-loop flag
412     Flag dtx            // i   : dtx flag; use dtx=1, do not use dtx=0
413     )
414 {
415     Word16 i, j;
416     Word16 *p, *p1;
417     Word32 max, t0;
418     Word16 t0_h, t0_l;
419     Word16 p_max;
420     const Word16 *ww, *we;
421     Word32 t1;
422
423     ww = &corrweight[250];
424     we = &corrweight[123 + lag_max - old_lag];
425
426     max = MIN_32;
427     p_max = lag_max;
428
429     for (i = lag_max; i >= lag_min; i--)
430     {
431        t0 = corr[-i];
432
433        // Weighting of the correlation function.
434        L_Extract (corr[-i], &t0_h, &t0_l);
435        t0 = Mpy_32_16 (t0_h, t0_l, *ww);
436        ww--;
437        if (wght_flg > 0) {
438           // Weight the neighbourhood of the old lag
439           L_Extract (t0, &t0_h, &t0_l);
440           t0 = Mpy_32_16 (t0_h, t0_l, *we);
441           we--;
442        }
443
444        if (L_sub (t0, max) >= 0)
445        {
446           max = t0;
447           p_max = i;
448        }
449     }
450
451     p  = &scal_sig[0];
452     p1 = &scal_sig[-p_max];
453     t0 = 0;
454     t1 = 0;
455
456     for (j = 0; j < L_frame; j++, p++, p1++)
457     {
458        t0 = L_mac (t0, *p, *p1);
459        t1 = L_mac (t1, *p1, *p1);
460     }
461
462     if (dtx)
463     {  // no test() call since this if is only in simulation env
464 #ifdef VAD2
465        vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0);   // Save max correlation
466        vadSt->L_R0 =   L_add(vadSt->L_R0, t1);        // Save max energy
467 #else
468        // update and detect tone
469        vad_tone_detection_update (vadSt, 0);
470        vad_tone_detection (vadSt, t0, t1);
471 #endif
472     }
473
474     // gain flag is set according to the open_loop gain
475     // is t2/t1 > 0.4 ?
476     *gain_flg = pv_round(L_msu(t0, pv_round(t1), 13107));
477
478     *cor_max = 0;
479
480     return (p_max);
481 }
482
483 ------------------------------------------------------------------------------
484  CAUTION [optional]
485  [State any special notes, constraints or cautions for users of this function]
486
487 ------------------------------------------------------------------------------
488 */
489
490 static Word16 Lag_max(  /* o : lag found                               */
491     vadState *vadSt,    /* i/o : VAD state struct                      */
492     Word32 corr[],      /* i   : correlation vector.                   */
493     Word16 scal_sig[],  /* i : scaled signal.                          */
494     Word16 L_frame,     /* i : length of frame to compute pitch        */
495     Word16 lag_max,     /* i : maximum lag                             */
496     Word16 lag_min,     /* i : minimum lag                             */
497     Word16 old_lag,     /* i : old open-loop lag                       */
498     Word16 *cor_max,    /* o : normalized correlation of selected lag  */
499     Word16 wght_flg,    /* i : is weighting function used              */
500     Word16 *gain_flg,   /* o : open-loop flag                          */
501     Flag dtx,           /* i : dtx flag; use dtx=1, do not use dtx=0   */
502     Flag   *pOverflow   /* o : overflow flag                           */
503 )
504 {
505     Word16 i;
506     Word16 j;
507     Word16 *p;
508     Word16 *p1;
509     Word32 max;
510     Word32 t0;
511     Word16 t0_h;
512     Word16 t0_l;
513     Word16 p_max;
514     const Word16 *ww;
515     const Word16 *we;
516     Word32 t1;
517     Word16 temp;
518
519     ww = &corrweight[250];
520     we = &corrweight[123 + lag_max - old_lag];
521
522     max = MIN_32;
523     p_max = lag_max;
524
525     for (i = lag_max; i >= lag_min; i--)
526     {
527         t0 = corr[-i];
528
529         /* Weighting of the correlation function.   */
530         L_Extract(corr[-i], &t0_h, &t0_l, pOverflow);
531         t0 = Mpy_32_16(t0_h, t0_l, *ww, pOverflow);
532         ww--;
533         if (wght_flg > 0)
534         {
535             /* Weight the neighbourhood of the old lag. */
536             L_Extract(t0, &t0_h, &t0_l, pOverflow);
537             t0 = Mpy_32_16(t0_h, t0_l, *we, pOverflow);
538             we--;
539         }
540
541         /*       if (L_sub (t0, max) >= 0) */
542         if (t0 >= max)
543         {
544             max = t0;
545             p_max = i;
546         }
547     }
548     p  = &scal_sig[0];
549     p1 = &scal_sig[-p_max];
550     t0 = 0;
551     t1 = 0;
552
553     for (j = 0; j < L_frame; j++, p++, p1++)
554     {
555         t0 = L_mac(t0, *p, *p1, pOverflow);
556         t1 = L_mac(t1, *p1, *p1, pOverflow);
557     }
558
559     if (dtx)
560     {  /* no test() call since this if is only in simulation env */
561 #ifdef VAD2
562         /* Save max correlation */
563         vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0, pOverflow);
564         /* Save max energy */
565         vadSt->L_R0 =   L_add(vadSt->L_R0, t1, pOverflow);
566 #else
567         /* update and detect tone */
568         vad_tone_detection_update(vadSt, 0, pOverflow);
569         vad_tone_detection(vadSt, t0, t1, pOverflow);
570 #endif
571     }
572
573     /* gain flag is set according to the open_loop gain */
574     /* is t2/t1 > 0.4 ? */
575     temp = pv_round(t1, pOverflow);
576     t1 = L_msu(t0, temp, 13107, pOverflow);
577     *gain_flg = pv_round(t1, pOverflow);
578
579     *cor_max = 0;
580
581     return (p_max);
582 }
583 /*----------------------------------------------------------------------------
584 ; End Function: Lag_max
585 ----------------------------------------------------------------------------*/
586
587 /*
588 ------------------------------------------------------------------------------
589  FUNCTION NAME: Pitch_ol_wgh
590 ------------------------------------------------------------------------------
591  INPUT AND OUTPUT DEFINITIONS
592
593  Inputs:
594     st = pointer to pitchOLWghtState structure
595     vadSt = pointer to a vadState structure
596     signal = pointer to buffer of signal used to compute the open loop
597          pitch where signal[-pit_max] to signal[-1] should be known
598     pit_min = 16 bit value specifies the minimum pitch lag
599     pit_max = 16 bit value specifies the maximum pitch lag
600     L_frame = 16 bit value specifies the length of frame to compute pitch
601     old_lags = pointer to history with old stored Cl lags (Word16)
602     ol_gain_flg = pointer to OL gain flag (Word16)
603     idx = 16 bit value specifies the frame index
604     dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0
605     pOverflow = pointer to Overflow indicator (Flag)
606  Outputs
607     st = The pitchOLWghtState may be modified
608     vadSt = The vadSt state structure may be modified.
609     pOverflow -> 1 if the math functions invoked by this routine saturate.
610
611  Returns:
612     p_max1 = 16 bit value representing the open loop pitch lag.
613
614  Global Variables Used:
615     None.
616
617  Local Variables Needed:
618     None.
619
620 ------------------------------------------------------------------------------
621  FUNCTION DESCRIPTION
622
623  This function performs an open-loop pitch search with weighting
624 ------------------------------------------------------------------------------
625  REQUIREMENTS
626
627  None.
628
629 ------------------------------------------------------------------------------
630  REFERENCES
631
632  pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
633
634 ------------------------------------------------------------------------------
635  PSEUDO-CODE
636
637 Word16 Pitch_ol_wgh (     // o   : open loop pitch lag
638     pitchOLWghtState *st, // i/o : State struct
639     vadState *vadSt,      // i/o : VAD state struct/
640     Word16 signal[],      // i   : signal used to compute the open loop pitch
641                           //       signal[-pit_max] to signal[-1] should be known
642     Word16 pit_min,       // i   : minimum pitch lag
643     Word16 pit_max,       // i   : maximum pitch lag
644     Word16 L_frame,       // i   : length of frame to compute pitch
645     Word16 old_lags[],    // i   : history with old stored Cl lags
646     Word16 ol_gain_flg[], // i   : OL gain flag
647     Word16 idx,           // i   : index
648     Flag dtx              // i   : dtx flag; use dtx=1, do not use dtx=0
649     )
650 {
651     Word16 i;
652     Word16 max1;
653     Word16 p_max1;
654     Word32 t0;
655 #ifndef VAD2
656     Word16 corr_hp_max;
657 #endif
658     Word32 corr[PIT_MAX+1], *corr_ptr;
659
660     // Scaled signal
661     Word16 scaled_signal[PIT_MAX + L_FRAME];
662     Word16 *scal_sig;
663
664     scal_sig = &scaled_signal[pit_max];
665
666     t0 = 0L;
667     for (i = -pit_max; i < L_frame; i++)
668     {
669         t0 = L_mac (t0, signal[i], signal[i]);
670     }
671     //
672     // Scaling of input signal
673     //
674     //   if Overflow        -> scal_sig[i] = signal[i]>>2
675     //   else if t0 < 1^22  -> scal_sig[i] = signal[i]<<2
676     //   else               -> scal_sig[i] = signal[i]
677
678     //
679     //  Verification for risk of overflow.
680     //
681
682     // Test for overflow
683     if (L_sub (t0, MAX_32) == 0L)
684     {
685         for (i = -pit_max; i < L_frame; i++)
686         {
687             scal_sig[i] = shr (signal[i], 3);
688         }
689     }
690     else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
691     {
692         for (i = -pit_max; i < L_frame; i++)
693         {
694             scal_sig[i] = shl (signal[i], 3);
695         }
696     }
697     else
698     {
699         for (i = -pit_max; i < L_frame; i++)
700         {
701             scal_sig[i] = signal[i];
702         }
703     }
704
705     // calculate all coreelations of scal_sig, from pit_min to pit_max
706     corr_ptr = &corr[pit_max];
707     comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
708
709     p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
710                       st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
711                       dtx);
712
713     if (ol_gain_flg[idx] > 0)
714     {
715        // Calculate 5-point median of previous lag
716        for (i = 4; i > 0; i--) // Shift buffer
717        {
718           old_lags[i] = old_lags[i-1];
719        }
720        old_lags[0] = p_max1;
721        st->old_T0_med = gmed_n (old_lags, 5);
722        st->ada_w = 32767; // Q15 = 1.0
723     }
724     else
725     {
726        st->old_T0_med = p_max1;
727        st->ada_w = mult(st->ada_w, 29491);      // = ada_w = ada_w * 0.9
728     }
729
730     if (sub(st->ada_w, 9830) < 0)  // ada_w - 0.3
731     {
732        st->wght_flg = 0;
733     }
734     else
735     {
736        st->wght_flg = 1;
737     }
738
739 #ifndef VAD2
740     if (dtx)
741     {  // no test() call since this if is only in simulation env
742        if (sub(idx, 1) == 0)
743        {
744           // calculate max high-passed filtered correlation of all lags
745           hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
746
747           // update complex background detector
748           vad_complex_detection_update(vadSt, corr_hp_max);
749        }
750     }
751 #endif
752
753     return (p_max1);
754 }
755
756 ------------------------------------------------------------------------------
757  CAUTION [optional]
758  [State any special notes, constraints or cautions for users of this function]
759
760 ------------------------------------------------------------------------------
761 */
762
763 Word16 Pitch_ol_wgh(      /* o   : open loop pitch lag                            */
764     pitchOLWghtState *st, /* i/o : State struct                                   */
765     vadState *vadSt,      /* i/o : VAD state struct                               */
766     Word16 signal[],      /* i   : signal used to compute the open loop pitch     */
767     /*       signal[-pit_max] to signal[-1] should be known */
768     Word16 pit_min,       /* i   : minimum pitch lag                              */
769     Word16 pit_max,       /* i   : maximum pitch lag                              */
770     Word16 L_frame,       /* i   : length of frame to compute pitch               */
771     Word16 old_lags[],    /* i   : history with old stored Cl lags                */
772     Word16 ol_gain_flg[], /* i   : OL gain flag                                   */
773     Word16 idx,           /* i   : index                                          */
774     Flag dtx,             /* i   : dtx flag; use dtx=1, do not use dtx=0          */
775     Flag   *pOverflow     /* o   : overflow flag                                  */
776 )
777 {
778     Word16 i;
779     Word16 max1;
780     Word16 p_max1;
781     Word32 t0;
782 #ifndef VAD2
783     Word16 corr_hp_max;
784 #endif
785     Word32 corr[PIT_MAX+1], *corr_ptr;
786
787     /* Scaled signal */
788     Word16 scaled_signal[PIT_MAX + L_FRAME];
789     Word16 *scal_sig;
790
791     scal_sig = &scaled_signal[pit_max];
792
793     t0 = 0L;
794     for (i = -pit_max; i < L_frame; i++)
795     {
796         t0 = L_mac(t0, signal[i], signal[i], pOverflow);
797     }
798     /*--------------------------------------------------------*
799      * Scaling of input signal.                               *
800      *                                                        *
801      *   if Overflow        -> scal_sig[i] = signal[i]>>2     *
802      *   else if t0 < 1^22  -> scal_sig[i] = signal[i]<<2     *
803      *   else               -> scal_sig[i] = signal[i]        *
804      *--------------------------------------------------------*/
805
806     /*--------------------------------------------------------*
807      *  Verification for risk of overflow.                    *
808      *--------------------------------------------------------*/
809
810     /* Test for overflow */
811     if (L_sub(t0, MAX_32, pOverflow) == 0L)
812     {
813         for (i = -pit_max; i < L_frame; i++)
814         {
815             scal_sig[i] = shr(signal[i], 3, pOverflow);
816         }
817     }
818     else if (L_sub(t0, (Word32) 1048576L, pOverflow) < (Word32) 0)
819     {
820         for (i = -pit_max; i < L_frame; i++)
821         {
822             scal_sig[i] = shl(signal[i], 3, pOverflow);
823         }
824     }
825     else
826     {
827         for (i = -pit_max; i < L_frame; i++)
828         {
829             scal_sig[i] = signal[i];
830         }
831     }
832
833     /* calculate all coreelations of scal_sig, from pit_min to pit_max */
834     corr_ptr = &corr[pit_max];
835     comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr);
836
837     p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
838                      st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
839                      dtx, pOverflow);
840
841     if (ol_gain_flg[idx] > 0)
842     {
843         /* Calculate 5-point median of previous lags */
844         for (i = 4; i > 0; i--) /* Shift buffer */
845         {
846             old_lags[i] = old_lags[i-1];
847         }
848         old_lags[0] = p_max1;
849         st->old_T0_med = gmed_n(old_lags, 5);
850         st->ada_w = 32767; /* Q15 = 1.0 */
851     }
852     else
853     {
854         st->old_T0_med = p_max1;
855         /* = ada_w = ada_w * 0.9 */
856         st->ada_w = (Word16)((Word32)(st->ada_w * 29491) >> 15);
857     }
858
859     if (sub(st->ada_w, 9830, pOverflow) < 0)  /* ada_w - 0.3 */
860     {
861         st->wght_flg = 0;
862     }
863     else
864     {
865         st->wght_flg = 1;
866     }
867
868 #ifndef VAD2
869     if (dtx)
870     {  /* no test() call since this if is only in simulation env */
871         if (sub(idx, 1, pOverflow) == 0)
872         {
873             /* calculate max high-passed filtered correlation of all lags */
874             hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, pOverflow);
875
876             /* update complex background detector */
877             vad_complex_detection_update(vadSt, corr_hp_max);
878         }
879     }
880 #endif
881
882     return (p_max1);
883 }
884
885 /*----------------------------------------------------------------------------
886 ; End Function: Pitch_ol_wgh
887 ----------------------------------------------------------------------------*/
888
889
890
891
892