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