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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
143int 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
189Word16 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
258int 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
296Word16 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
356void 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
391void 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
466static 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
571static 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
718Word16 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
860Word16 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