• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/pitch_ol.c
35   Funtions: Pitch_ol
36             Lag_max
37  
38  ------------------------------------------------------------------------------
39   MODULE DESCRIPTION
40  
41   The modules in this file compute the open loop pitch lag.
42  ------------------------------------------------------------------------------
43  */
44  
45  
46  /*----------------------------------------------------------------------------
47  ; INCLUDES
48  ----------------------------------------------------------------------------*/
49  #include <string.h>
50  
51  #include "pitch_ol.h"
52  #include "typedef.h"
53  #include "basicop_malloc.h"
54  #include "cnst.h"
55  #include "inv_sqrt.h"
56  #include "vad.h"
57  #include "calc_cor.h"
58  #include "hp_max.h"
59  #include "basic_op.h"
60  
61  /*----------------------------------------------------------------------------
62  ; MACROS
63  ; Define module specific macros here
64  ----------------------------------------------------------------------------*/
65  
66  
67  /*----------------------------------------------------------------------------
68  ; DEFINES
69  ; Include all pre-processor statements here. Include conditional
70  ; compile variables also.
71  ----------------------------------------------------------------------------*/
72  #define THRESHOLD 27853
73  
74  /*----------------------------------------------------------------------------
75  ; LOCAL FUNCTION DEFINITIONS
76  ; Function Prototype declaration
77  ----------------------------------------------------------------------------*/
78  
79  /*----------------------------------------------------------------------------
80  ; LOCAL VARIABLE DEFINITIONS
81  ; Variable declaration - defined here and used outside this module
82  ----------------------------------------------------------------------------*/
83  
84  
85  /*
86  ------------------------------------------------------------------------------
87   FUNCTION NAME: Lag_max
88  ------------------------------------------------------------------------------
89   INPUT AND OUTPUT DEFINITIONS (If VAD2 is defined)
90  
91   Inputs
92      corr = pointer to buffer of correlation values (Word32)
93      scal_sig = pointer to buffer of scaled signal values (Word16)
94      scal_fac = scaled signal factor (Word16)
95      scal_flag = EFR compatible scaling flag (Word16)
96      L_frame = length of frame to compute pitch (Word16)
97      lag_max = maximum lag (Word16)
98      lag_min = minimum lag (Word16)
99      cor_max = pointer to the normalized correlation of selected lag (Word16)
100      rmax = pointer to max(<s[i]*s[j]>), (Word32)
101      r0 = pointer to the residual energy (Word32)
102      dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
103  
104   Outputs:
105      cor_max contains the newly calculated normalized correlation of the
106        selected lag
107      rmax contains the newly calculated max(<s[i]*s[j]>)
108      r0 contains the newly calculated residual energy
109  
110   Returns:
111      p_max = lag of the max correlation found (Word16)
112  
113   Global Variables Used:
114      None.
115  
116   Local Variables Needed:
117      None.
118  
119  ------------------------------------------------------------------------------
120   INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined)
121  
122   Inputs
123      vadSt = pointer to a vadState structure
124      corr = pointer to buffer of correlation values (Word32)
125      scal_sig = pointer to buffer of scaled signal values (Word16)
126      scal_fac = scaled signal factor (Word16)
127      scal_flag = EFR compatible scaling flag (Word16)
128      L_frame = length of frame to compute pitch (Word16)
129      lag_max = maximum lag (Word16)
130      lag_min = minimum lag (Word16)
131      cor_max = pointer to the normalized correlation of selected lag (Word16)
132      dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
133      pOverflow = pointer to overflow indicator (Flag)
134  
135   Outputs:
136      cor_max contains the newly calculated normalized correlation of the
137        selected lag
138      vadSt contains the updated VAD state parameters
139      pOverflow -> 1 if the math operations called by this routine saturate
140  
141   Returns:
142      p_max = lag of the max correlation found (Word16)
143  
144   Global Variables Used:
145      None.
146  
147   Local Variables Needed:
148      None.
149  
150  ------------------------------------------------------------------------------
151   FUNCTION DESCRIPTION
152  
153   Find the lag that has maximum correlation of scal_sig in a given delay range.
154   The correlation is given by:
155  
156           cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
157  
158   The function returns the maximum correlation after normalization and the
159   corresponding lag.
160  
161  ------------------------------------------------------------------------------
162   REQUIREMENTS
163  
164   None.
165  
166  ------------------------------------------------------------------------------
167   REFERENCES
168  
169   pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
170  
171  ------------------------------------------------------------------------------
172   PSEUDO-CODE
173  
174  #ifdef VAD2
175  static Word16 Lag_max ( // o   : lag found
176      Word32 corr[],      // i   : correlation vector.
177      Word16 scal_sig[],  // i   : scaled signal.
178      Word16 scal_fac,    // i   : scaled signal factor.
179      Word16 scal_flag,   // i   : if 1 use EFR compatible scaling
180      Word16 L_frame,     // i   : length of frame to compute pitch
181      Word16 lag_max,     // i   : maximum lag
182      Word16 lag_min,     // i   : minimum lag
183      Word16 *cor_max,    // o   : normalized correlation of selected lag
184      Word32 *rmax,       // o   : max(<s[i]*s[j]>)
185      Word32 *r0,         // o   : residual energy
186      Flag dtx            // i   : dtx flag; use dtx=1, do not use dtx=0
187      )
188  #else
189  static Word16 Lag_max ( // o   : lag found
190      vadState *vadSt,    // i/o : VAD state struct
191      Word32 corr[],      // i   : correlation vector.
192      Word16 scal_sig[],  // i   : scaled signal.
193      Word16 scal_fac,    // i   : scaled signal factor.
194      Word16 scal_flag,   // i   : if 1 use EFR compatible scaling
195      Word16 L_frame,     // i   : length of frame to compute pitch
196      Word16 lag_max,     // i   : maximum lag
197      Word16 lag_min,     // i   : minimum lag
198      Word16 *cor_max,    // o   : normalized correlation of selected lag
199      Flag dtx            // i   : dtx flag; use dtx=1, do not use dtx=0
200      )
201  #endif
202  {
203      Word16 i, j;
204      Word16 *p;
205      Word32 max, t0;
206      Word16 max_h, max_l, ener_h, ener_l;
207      Word16 p_max = 0; // initialization only needed to keep gcc silent
208  
209      max = MIN_32;
210      p_max = lag_max;
211  
212      for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--)
213      {
214         if (L_sub (corr[-i], max) >= 0)
215         {
216            max = corr[-i];
217            p_max = i;
218         }
219      }
220  
221      // compute energy
222  
223      t0 = 0;
224      p = &scal_sig[-p_max];
225      for (i = 0; i < L_frame; i++, p++)
226      {
227          t0 = L_mac (t0, *p, *p);
228      }
229      // 1/sqrt(energy)
230  
231      if (dtx)
232      {  // no test() call since this if is only in simulation env
233  #ifdef VAD2
234         *rmax = max;
235         *r0 = t0;
236  #else
237         // check tone
238         vad_tone_detection (vadSt, max, t0);
239  #endif
240      }
241  
242      t0 = Inv_sqrt (t0);
243  
244      if (scal_flag)
245      {
246         t0 = L_shl (t0, 1);
247      }
248  
249      // max = max/sqrt(energy)
250  
251      L_Extract (max, &max_h, &max_l);
252      L_Extract (t0, &ener_h, &ener_l);
253  
254      t0 = Mpy_32 (max_h, max_l, ener_h, ener_l);
255  
256      if (scal_flag)
257      {
258        t0 = L_shr (t0, scal_fac);
259        *cor_max = extract_h (L_shl (t0, 15)); // divide by 2
260      }
261      else
262      {
263        *cor_max = extract_l(t0);
264      }
265  
266      return (p_max);
267  }
268  
269  ------------------------------------------------------------------------------
270   RESOURCES USED [optional]
271  
272   When the code is written for a specific target processor the
273   the resources used should be documented below.
274  
275   HEAP MEMORY USED: x bytes
276  
277   STACK MEMORY USED: x bytes
278  
279   CLOCK CYCLES: (cycle count equation for this function) + (variable
280                  used to represent cycle count for each subroutine
281                  called)
282       where: (cycle count variable) = cycle count for [subroutine
283                                       name]
284  
285  ------------------------------------------------------------------------------
286   CAUTION [optional]
287   [State any special notes, constraints or cautions for users of this function]
288  
289  ------------------------------------------------------------------------------
290  */
291  
292  #ifdef VAD2
Lag_max(Word32 corr[],Word16 scal_sig[],Word16 scal_fac,Word16 scal_flag,Word16 L_frame,Word16 lag_max,Word16 lag_min,Word16 * cor_max,Word32 * rmax,Word32 * r0,Flag dtx,Flag * pOverflow)293  static Word16 Lag_max(  /* o   : lag found                               */
294      Word32 corr[],      /* i   : correlation vector.                     */
295      Word16 scal_sig[],  /* i   : scaled signal.                          */
296      Word16 scal_fac,    /* i   : scaled signal factor.                   */
297      Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
298      Word16 L_frame,     /* i   : length of frame to compute pitch        */
299      Word16 lag_max,     /* i   : maximum lag                             */
300      Word16 lag_min,     /* i   : minimum lag                             */
301      Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
302      Word32 *rmax,       /* o   : max(<s[i]*s[j]>)                        */
303      Word32 *r0,         /* o   : residual energy                         */
304      Flag dtx,           /* i   : dtx flag; use dtx=1, do not use dtx=0   */
305      Flag *pOverflow     /* i/o : overflow Flag                           */
306  )
307  #else
308  static Word16 Lag_max(  /* o   : lag found                               */
309      vadState *vadSt,    /* i/o : VAD state struct                        */
310      Word32 corr[],      /* i   : correlation vector.                     */
311      Word16 scal_sig[],  /* i   : scaled signal.                          */
312      Word16 scal_fac,    /* i   : scaled signal factor.                   */
313      Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
314      Word16 L_frame,     /* i   : length of frame to compute pitch        */
315      Word16 lag_max,     /* i   : maximum lag                             */
316      Word16 lag_min,     /* i   : minimum lag                             */
317      Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
318      Flag dtx,           /* i   : dtx flag; use dtx=1, do not use dtx=0   */
319      Flag *pOverflow     /* i/o : overflow Flag                           */
320  )
321  #endif
322  {
323      register Word16 i;
324      Word16 *p;
325      Word32 max;
326      Word32 t0;
327      Word16 max_h;
328      Word16 max_l;
329      Word16 ener_h;
330      Word16 ener_l;
331      Word16 p_max = 0; /* initialization only needed to keep gcc silent */
332      Word32 L_temp;
333      Word32 L_temp_2;
334      Word32 L_temp_3;
335      Word32  *p_corr = &corr[-lag_max];
336  
337      max = MIN_32;
338      p_max = lag_max;
339  
340      for (i = lag_max; i >= lag_min; i--)
341      {
342          /* The negative array index is equivalent to a negative */
343          /* address offset, i.e., corr[-i] == *(corr - i)        */
344          if (*(p_corr++) >= max)
345          {
346              p_corr--;
347              max = *(p_corr++);
348              p_max = i;
349          }
350      }
351  
352      /* compute energy */
353  
354      t0 = 0;
355  
356      /* The negative array index is equivalent to a negative          */
357      /* address offset, i.e., scal_sig[-p_max] == *(scal_sig - p_max) */
358      p = &scal_sig[-p_max];
359      for (i = (L_frame >> 2); i != 0; i--)
360      {
361          t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
362          p++;
363          t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
364          p++;
365          t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
366          p++;
367          t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
368          p++;
369      }
370  
371      t0 <<= 1;
372      /* 1/sqrt(energy) */
373  
374      if (dtx)
375      {  /* no test() call since this if is only in simulation env */
376          /* check tone */
377  #ifdef VAD2
378          *rmax = max;
379          *r0 = t0;
380  #else
381          /* check tone */
382          vad_tone_detection(vadSt, max, t0, pOverflow);
383  #endif
384      }
385  
386      t0 = Inv_sqrt(t0, pOverflow);
387  
388      if (scal_flag)
389      {
390          if (t0 > (Word32) 0x3fffffffL)
391          {
392              t0 = MAX_32;
393          }
394          else
395          {
396              t0 = t0 << 1;
397          }
398      }
399  
400      /* max = max/sqrt(energy)  */
401      /* The following code is an inlined version of */
402      /* L_Extract (max, &max_h, &max_l), i.e.       */
403      /*                                             */
404      /* *max_h = extract_h (max);                   */
405      max_h = (Word16)(max >> 16);
406  
407      /* L_temp_2 = L_shr(max,1), which is used in      */
408      /* the calculation of *max_l (see next operation) */
409      L_temp_2 = max >> 1;
410  
411      /* *max_l = extract_l (L_msu (L_shr (max, 1), *max_h, 16384)); */
412      L_temp_3 = (Word32)(max_h << 15);
413  
414      L_temp = L_temp_2 - L_temp_3;
415  
416      max_l = (Word16)L_temp;
417  
418      /* The following code is an inlined version of */
419      /* L_Extract (t0, &ener_h, &ener_l), i.e.      */
420      /*                                             */
421      /* *ener_h = extract_h (t0);                   */
422      ener_h = (Word16)(t0 >> 16);
423  
424      /* L_temp_2 = L_shr(t0,1), which is used in        */
425      /* the calculation of *ener_l (see next operation) */
426  
427      L_temp_2 = t0 >> 1;
428  
429      L_temp_3 = (Word32)(ener_h << 15);
430  
431      L_temp = L_temp_2 - L_temp_3;
432  
433      ener_l = (Word16)L_temp;
434  
435      t0 = Mpy_32(max_h, max_l, ener_h, ener_l, pOverflow);
436  
437      if (scal_flag)
438      {
439          t0 = L_shr(t0, scal_fac, pOverflow);
440  
441          if (t0 > (Word32) 0X0000FFFFL)
442          {
443              *cor_max = MAX_16;
444          }
445          else if (t0 < (Word32) 0xFFFF0000L)
446          {
447              *cor_max = MIN_16;
448          }
449          else
450          {
451              *cor_max = (Word16)(t0 >> 1);
452          }
453      }
454      else
455      {
456          *cor_max = (Word16)t0;
457      }
458  
459      return (p_max);
460  }
461  
462  /*----------------------------------------------------------------------------
463  ; End Function: Lag_max
464  ----------------------------------------------------------------------------*/
465  
466  
467  /*
468  ------------------------------------------------------------------------------
469   FUNCTION NAME: Lag_max_wrapper
470  ------------------------------------------------------------------------------
471   INPUT AND OUTPUT DEFINITIONS
472  
473   Inputs
474      corr = pointer to buffer of correlation values (Word32)
475      scal_sig = pointer to buffer of scaled signal values (Word16)
476      scal_fac = scaled signal factor (Word16)
477      scal_flag = EFR compatible scaling flag (Word16)
478      L_frame = length of frame to compute pitch (Word16)
479      lag_max = maximum lag (Word16)
480      lag_min = minimum lag (Word16)
481      cor_max = pointer to the normalized correlation of selected lag (Word16)
482      rmax = pointer to max(<s[i]*s[j]>), (Word32)
483      r0 = pointer to the residual energy (Word32)
484      dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
485      pOverflow = pointer to overflow indicator (Flag)
486  
487   Outputs:
488      cor_max contains the newly calculated normalized correlation of the
489        selected lag
490      rmax contains the newly calculated max(<s[i]*s[j]>)
491      r0 contains the newly calculated residual energy
492      pOverflow -> 1 if the math operations called by this routine saturate
493  
494   Returns:
495      p_max = lag of the max correlation found (Word16)
496  
497   Global Variables Used:
498      None.
499  
500   Local Variables Needed:
501      None.
502  
503  ------------------------------------------------------------------------------
504   INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined)
505  
506   Inputs
507      vadSt = pointer to a vadState structure
508      corr = pointer to buffer of correlation values (Word32)
509      scal_sig = pointer to buffer of scaled signal values (Word16)
510      scal_fac = scaled signal factor (Word16)
511      scal_flag = EFR compatible scaling flag (Word16)
512      L_frame = length of frame to compute pitch (Word16)
513      lag_max = maximum lag (Word16)
514      lag_min = minimum lag (Word16)
515      cor_max = pointer to the normalized correlation of selected lag (Word16)
516      dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
517      pOverflow = pointer to overflow indicator (Flag)
518  
519   Outputs:
520      cor_max contains the newly calculated normalized correlation of the
521        selected lag
522      vadSt contains the updated VAD state parameters
523      pOverflow -> 1 if the math operations called by this routine saturate
524  
525   Returns:
526      p_max = lag of the max correlation found (Word16)
527  
528   Global Variables Used:
529      None.
530  
531   Local Variables Needed:
532      None.
533  
534  ------------------------------------------------------------------------------
535   FUNCTION DESCRIPTION
536  
537   This function provides external access to the local function Lag_max.
538  
539  ------------------------------------------------------------------------------
540   REQUIREMENTS
541  
542   None
543  
544  ------------------------------------------------------------------------------
545   REFERENCES
546  
547   pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
548  
549  ------------------------------------------------------------------------------
550   PSEUDO-CODE
551  
552  #ifdef VAD2
553   CALL Lag_max(corr = corr
554            scal_sig = scal_sig
555            scal_fac = scal_fac
556            scal_flag = scal_flag
557            L_frame = L_frame
558            lag_max = lag_max
559            lag_min = lag_min
560            cor_max = cor_max
561            rmax = rmax
562            r0 = r0
563            dtx = dtx
564            pOverflow = pOverflow)
565     MODIFYING(nothing)
566     RETURNING(temp)
567  
568  #else
569   CALL Lag_max(vadSt = vadSt
570            corr = corr
571            scal_sig = scal_sig
572            scal_fac = scal_fac
573            scal_flag = scal_flag
574            L_frame = L_frame
575            lag_max = lag_max
576            lag_min = lag_min
577            cor_max = cor_max
578            dtx = dtx
579            pOverflow = pOverflow)
580     MODIFYING(nothing)
581     RETURNING(temp)
582  
583  #endif
584  
585  ------------------------------------------------------------------------------
586   RESOURCES USED [optional]
587  
588   When the code is written for a specific target processor the
589   the resources used should be documented below.
590  
591   HEAP MEMORY USED: x bytes
592  
593   STACK MEMORY USED: x bytes
594  
595   CLOCK CYCLES: (cycle count equation for this function) + (variable
596                  used to represent cycle count for each subroutine
597                  called)
598       where: (cycle count variable) = cycle count for [subroutine
599                                       name]
600  
601  ------------------------------------------------------------------------------
602   CAUTION [optional]
603   [State any special notes, constraints or cautions for users of this function]
604  
605  ------------------------------------------------------------------------------
606  */
607  
608  #ifdef VAD2
Lag_max_wrapper(Word32 corr[],Word16 scal_sig[],Word16 scal_fac,Word16 scal_flag,Word16 L_frame,Word16 lag_max,Word16 lag_min,Word16 * cor_max,Word32 * rmax,Word32 * r0,Flag dtx,Flag * pOverflow)609  Word16 Lag_max_wrapper(  /* o   : lag found                          */
610      Word32 corr[],      /* i   : correlation vector.                     */
611      Word16 scal_sig[],  /* i   : scaled signal.                          */
612      Word16 scal_fac,    /* i   : scaled signal factor.                   */
613      Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
614      Word16 L_frame,     /* i   : length of frame to compute pitch        */
615      Word16 lag_max,     /* i   : maximum lag                             */
616      Word16 lag_min,     /* i   : minimum lag                             */
617      Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
618      Word32 *rmax,       /* o   : max(<s[i]*s[j]>)                        */
619      Word32 *r0,         /* o   : residual energy                         */
620      Flag dtx,           /* i   : dtx flag; use dtx=1, do not use dtx=0   */
621      Flag *pOverflow     /* i/o : overflow Flag                           */
622  )
623  {
624      Word16 temp;
625  
626      temp = Lag_max(corr, scal_sig, scal_fac, scal_flag, L_frame, lag_max,
627                     lag_min, cor_max, rmax, r0, dtx, pOverflow);
628  
629      return(temp);
630  }
631  
632  #else
Lag_max_wrapper(vadState * vadSt,Word32 corr[],Word16 scal_sig[],Word16 scal_fac,Word16 scal_flag,Word16 L_frame,Word16 lag_max,Word16 lag_min,Word16 * cor_max,Flag dtx,Flag * pOverflow)633  Word16 Lag_max_wrapper(  /* o   : lag found                          */
634      vadState *vadSt,    /* i/o : VAD state struct                        */
635      Word32 corr[],      /* i   : correlation vector.                     */
636      Word16 scal_sig[],  /* i   : scaled signal.                          */
637      Word16 scal_fac,    /* i   : scaled signal factor.                   */
638      Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
639      Word16 L_frame,     /* i   : length of frame to compute pitch        */
640      Word16 lag_max,     /* i   : maximum lag                             */
641      Word16 lag_min,     /* i   : minimum lag                             */
642      Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
643      Flag dtx,           /* i   : dtx flag; use dtx=1, do not use dtx=0   */
644      Flag *pOverflow     /* i/o : overflow Flag                           */
645  )
646  {
647      Word16 temp;
648  
649      temp = Lag_max(vadSt, corr, scal_sig, scal_fac, scal_flag, L_frame,
650                     lag_max, lag_min, cor_max, dtx, pOverflow);
651  
652      return(temp);
653  }
654  
655  #endif
656  
657  /*----------------------------------------------------------------------------
658  ; End Function: Lag_max_wrapper
659  ----------------------------------------------------------------------------*/
660  
661  /*
662  ------------------------------------------------------------------------------
663   FUNCTION NAME: Pitch_ol
664  ------------------------------------------------------------------------------
665   INPUT AND OUTPUT DEFINITIONS
666  
667   Inputs:
668      vadSt = pointer to a vadState structure
669      mode =  data of type enum Mode specifies the mode.
670      signal = pointer to buffer of signal used to compute the open loop
671           pitch
672      where signal[-pit_max] to signal[-1] should be known
673      pit_min = 16 bit value specifies the minimum pitch lag
674      pit_max = 16 bit value specifies the maximum pitch lag
675      L_frame = 16 bit value specifies the length of frame to compute pitch
676      idx = 16 bit value specifies the frame index
677      dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0
678      pOverflow = pointer to overflow indicator (Flag)
679  
680   Outputs
681      vadSt = The vadSt state structure may be modified.
682      pOverflow -> 1 if the math operations called by this routine saturate
683  
684   Returns:
685      p_max1 = 16 bit value representing the open loop pitch lag.
686  
687   Global Variables Used:
688      None.
689  
690   Local Variables Needed:
691      None.
692  
693  ------------------------------------------------------------------------------
694   FUNCTION DESCRIPTION
695  
696   This function computes the open loop pitch lag based on the perceptually
697   weighted speech signal. This is done in the following steps:
698         - find three maxima of the correlation <sw[n],sw[n-T]>,
699           dividing the search range into three parts:
700                pit_min ... 2*pit_min-1
701              2*pit_min ... 4*pit_min-1
702              4*pit_min ...   pit_max
703         - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at
704           that maximum correlation.
705         - select the delay of maximum normalized correlation (among the
706           three candidates) while favoring the lower delay ranges.
707  
708  
709  ------------------------------------------------------------------------------
710   REQUIREMENTS
711  
712   None.
713  
714  ------------------------------------------------------------------------------
715   REFERENCES
716  
717   pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
718  
719  ------------------------------------------------------------------------------
720   PSEUDO-CODE
721  
722  Word16 Pitch_ol (      // o   : open loop pitch lag
723      vadState *vadSt,   // i/o : VAD state struct
724      enum Mode mode,    // i   : coder mode
725      Word16 signal[],   // i   : signal used to compute the open loop pitch
726                         //    signal[-pit_max] to signal[-1] should be known
727      Word16 pit_min,    // i   : minimum pitch lag
728      Word16 pit_max,    // i   : maximum pitch lag
729      Word16 L_frame,    // i   : length of frame to compute pitch
730      Word16 idx,        // i   : frame index
731      Flag dtx           // i   : dtx flag; use dtx=1, do not use dtx=0
732      )
733  {
734      Word16 i, j;
735      Word16 max1, max2, max3;
736      Word16 p_max1, p_max2, p_max3;
737      Word16 scal_flag = 0;
738      Word32 t0;
739  #ifdef VAD2
740      Word32  r01, r02, r03;
741      Word32  rmax1, rmax2, rmax3;
742  #else
743      Word16 corr_hp_max;
744  #endif
745      Word32 corr[PIT_MAX+1], *corr_ptr;
746  
747      // Scaled signal
748  
749      Word16 scaled_signal[L_FRAME + PIT_MAX];
750      Word16 *scal_sig, scal_fac;
751  
752  #ifndef VAD2
753      if (dtx)
754      {  // no test() call since this if is only in simulation env
755         // update tone detection
756         if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0))
757         {
758            vad_tone_detection_update (vadSt, 1);
759         }
760         else
761         {
762            vad_tone_detection_update (vadSt, 0);
763         }
764      }
765  #endif
766  
767      scal_sig = &scaled_signal[pit_max];
768  
769      t0 = 0L;
770      for (i = -pit_max; i < L_frame; i++)
771      {
772          t0 = L_mac (t0, signal[i], signal[i]);
773      }
774  
775       *--------------------------------------------------------*
776       * Scaling of input signal.                               *
777       *                                                        *
778       *   if Overflow        -> scal_sig[i] = signal[i]>>3     *
779       *   else if t0 < 1^20  -> scal_sig[i] = signal[i]<<3     *
780       *   else               -> scal_sig[i] = signal[i]        *
781       *--------------------------------------------------------*
782  
783       *--------------------------------------------------------*
784       *  Verification for risk of overflow.                    *
785       *--------------------------------------------------------*
786  
787      if (L_sub (t0, MAX_32) == 0L)               // Test for overflow
788      {
789          for (i = -pit_max; i < L_frame; i++)
790          {
791              scal_sig[i] = shr (signal[i], 3);
792          }
793          scal_fac = 3;
794      }
795      else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
796          // if (t0 < 2^20)
797      {
798          for (i = -pit_max; i < L_frame; i++)
799          {
800              scal_sig[i] = shl (signal[i], 3);
801          }
802          scal_fac = -3;
803      }
804      else
805      {
806          for (i = -pit_max; i < L_frame; i++)
807          {
808              scal_sig[i] = signal[i];
809          }
810          scal_fac = 0;
811      }
812  
813      // calculate all coreelations of scal_sig, from pit_min to pit_max
814      corr_ptr = &corr[pit_max];
815      comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
816  
817       *--------------------------------------------------------------------*
818       *  The pitch lag search is divided in three sections.                *
819       *  Each section cannot have a pitch multiple.                        *
820       *  We find a maximum for each section.                               *
821       *  We compare the maximum of each section by favoring small lags.    *
822       *                                                                    *
823       *  First section:  lag delay = pit_max     downto 4*pit_min          *
824       *  Second section: lag delay = 4*pit_min-1 downto 2*pit_min          *
825       *  Third section:  lag delay = 2*pit_min-1 downto pit_min            *
826       *--------------------------------------------------------------------*
827  
828      // mode dependent scaling in Lag_max
829      if (sub(mode, MR122) == 0)
830      {
831         scal_flag = 1;
832      }
833      else
834      {
835         scal_flag = 0;
836      }
837  
838  #ifdef VAD2
839      j = shl (pit_min, 2);
840      p_max1 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
841                        pit_max, j, &max1, &rmax1, &r01, dtx);
842  
843      i = sub (j, 1);
844      j = shl (pit_min, 1);
845      p_max2 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
846                        i, j, &max2, &rmax2, &r02, dtx);
847  
848      i = sub (j, 1);
849      p_max3 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
850                        i, pit_min, &max3, &rmax3, &r03, dtx);
851  #else
852      j = shl (pit_min, 2);
853      p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
854                        pit_max, j, &max1, dtx);
855  
856      i = sub (j, 1);
857      j = shl (pit_min, 1);
858      p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
859                        i, j, &max2, dtx);
860  
861      i = sub (j, 1);
862      p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
863                        i, pit_min, &max3, dtx);
864  
865      if (dtx)
866      {  // no test() call since this if is only in simulation env
867         if (sub(idx, 1) == 0)
868         {
869            // calculate max high-passed filtered correlation of all lags
870            hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
871  
872            // update complex background detector
873            vad_complex_detection_update(vadSt, corr_hp_max);
874         }
875      }
876  #endif
877  
878       *--------------------------------------------------------------------*
879       * Compare the 3 sections maximum, and favor small lag.               *
880       *--------------------------------------------------------------------*
881  
882      if (sub (mult (max1, THRESHOLD), max2) < 0)
883      {
884          max1 = max2;
885          p_max1 = p_max2;
886  #ifdef VAD2
887          if (dtx)
888          {
889              rmax1 = rmax2;
890              r01 = r02;
891  #endif
892      }
893      if (sub (mult (max1, THRESHOLD), max3) < 0)
894      {
895          p_max1 = p_max3;
896  #ifdef VAD2
897          if (dtx)
898          {
899              rmax1 = rmax3;
900              r01 = r03;
901          }
902  #endif
903      }
904  
905  #ifdef VAD2
906      if (dtx)
907      {
908          vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1);   // Save max correlation
909          vadSt->L_R0 =   L_add(vadSt->L_R0, r01);        // Save max energy
910      }
911  #endif
912  
913      return (p_max1);
914  }
915  
916  ------------------------------------------------------------------------------
917   RESOURCES USED [optional]
918  
919   When the code is written for a specific target processor the
920   the resources used should be documented below.
921  
922   HEAP MEMORY USED: x bytes
923  
924   STACK MEMORY USED: x bytes
925  
926   CLOCK CYCLES: (cycle count equation for this function) + (variable
927                  used to represent cycle count for each subroutine
928                  called)
929       where: (cycle count variable) = cycle count for [subroutine
930                                       name]
931  
932  ------------------------------------------------------------------------------
933   CAUTION [optional]
934   [State any special notes, constraints or cautions for users of this function]
935  
936  ------------------------------------------------------------------------------
937  */
938  
Pitch_ol(vadState * vadSt,enum Mode mode,Word16 signal[],Word16 pit_min,Word16 pit_max,Word16 L_frame,Word16 idx,Flag dtx,Flag * pOverflow)939  Word16 Pitch_ol(       /* o   : open loop pitch lag                         */
940      vadState *vadSt,   /* i/o : VAD state struct                            */
941      enum Mode mode,    /* i   : coder mode                                  */
942      Word16 signal[],   /* i   : signal used to compute the open loop pitch  */
943      /*    signal[-pit_max] to signal[-1] should be known */
944      Word16 pit_min,    /* i   : minimum pitch lag                           */
945      Word16 pit_max,    /* i   : maximum pitch lag                           */
946      Word16 L_frame,    /* i   : length of frame to compute pitch            */
947      Word16 idx,        /* i   : frame index                                 */
948      Flag dtx,          /* i   : dtx flag; use dtx=1, do not use dtx=0       */
949      Flag *pOverflow    /* i/o : overflow Flag                               */
950  )
951  {
952      Word16 i;
953      Word16 j;
954      Word16 max1;
955      Word16 max2;
956      Word16 max3;
957      Word16 p_max1;
958      Word16 p_max2;
959      Word16 p_max3;
960      Word16 scal_flag = 0;
961      Word32 t0;
962  
963  #ifdef VAD2
964      Word32 r01;
965      Word32 r02;
966      Word32 r03;
967      Word32 rmax1;
968      Word32 rmax2;
969      Word32 rmax3;
970  #else
971      Word16 corr_hp_max;
972  #endif
973      Word32 corr[PIT_MAX+1];
974      Word32 *corr_ptr;
975  
976      /* Scaled signal */
977  
978      Word16 scaled_signal[L_FRAME + PIT_MAX];
979      Word16 *scal_sig;
980      Word16 *p_signal;
981      Word16 scal_fac;
982      Word32 L_temp;
983  
984  #ifndef VAD2
985      if (dtx)
986      {   /* no test() call since this if is only in simulation env */
987          /* update tone detection */
988          if ((mode == MR475) || (mode == MR515))
989          {
990              vad_tone_detection_update(vadSt, 1, pOverflow);
991          }
992          else
993          {
994              vad_tone_detection_update(vadSt, 0, pOverflow);
995          }
996      }
997  #endif
998  
999  
1000      t0 = 0L;
1001      p_signal = &signal[-pit_max];
1002  
1003      for (i = -pit_max; i < L_frame; i++)
1004      {
1005          t0 += (((Word32) * (p_signal)) * *(p_signal)) << 1;
1006          p_signal++;
1007          if (t0 < 0)
1008          {
1009              t0 = MAX_32;
1010              break;
1011          }
1012  
1013      }
1014  
1015      /*--------------------------------------------------------*
1016       * Scaling of input signal.                               *
1017       *                                                        *
1018       *   if Overflow        -> scal_sig[i] = signal[i]>>3     *
1019       *   else if t0 < 1^20  -> scal_sig[i] = signal[i]<<3     *
1020       *   else               -> scal_sig[i] = signal[i]        *
1021       *--------------------------------------------------------*/
1022  
1023      /*--------------------------------------------------------*
1024       *  Verification for risk of overflow.                    *
1025       *--------------------------------------------------------*/
1026  
1027      scal_sig = &scaled_signal[0];
1028      p_signal = &signal[-pit_max];
1029  
1030      if (t0 == MAX_32)     /* Test for overflow */
1031      {
1032  
1033          for (i = (pit_max + L_frame) >> 1; i != 0; i--)
1034          {
1035              *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3));
1036              *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3));
1037          }
1038  
1039          if ((pit_max + L_frame) & 1)
1040          {
1041              *(scal_sig) = (Word16)(((Word32) * (p_signal) >> 3));
1042          }
1043  
1044          scal_fac = 3;
1045      }
1046      else if (t0 < (Word32)1048576L)
1047          /* if (t0 < 2^20) */
1048      {
1049          for (i = (pit_max + L_frame) >> 1; i != 0; i--)
1050          {
1051              *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3));
1052              *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3));
1053          }
1054  
1055          if ((pit_max + L_frame) & 1)
1056          {
1057              *(scal_sig) = (Word16)(((Word32) * (p_signal) << 3));
1058          }
1059          scal_fac = -3;
1060      }
1061      else
1062      {
1063  
1064          memcpy(scal_sig, p_signal, (L_frame + pit_max)*sizeof(*signal));
1065          scal_fac = 0;
1066      }
1067  
1068      /* calculate all coreelations of scal_sig, from pit_min to pit_max */
1069      corr_ptr = &corr[pit_max];
1070  
1071      scal_sig = &scaled_signal[pit_max];
1072  
1073      comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr);
1074  
1075      /*--------------------------------------------------------------------*
1076       *  The pitch lag search is divided in three sections.                *
1077       *  Each section cannot have a pitch multiple.                        *
1078       *  We find a maximum for each section.                               *
1079       *  We compare the maximum of each section by favoring small lags.    *
1080       *                                                                    *
1081       *  First section:  lag delay = pit_max     downto 4*pit_min          *
1082       *  Second section: lag delay = 4*pit_min-1 downto 2*pit_min          *
1083       *  Third section:  lag delay = 2*pit_min-1 downto pit_min            *
1084       *--------------------------------------------------------------------*/
1085  
1086      /* mode dependent scaling in Lag_max */
1087  
1088      if (mode == MR122)
1089      {
1090          scal_flag = 1;
1091      }
1092      else
1093      {
1094          scal_flag = 0;
1095      }
1096  
1097  #ifdef VAD2
1098      L_temp = ((Word32)pit_min) << 2;
1099      if (L_temp != (Word32)((Word16) L_temp))
1100      {
1101          *pOverflow = 1;
1102          j = (pit_min > 0) ? MAX_16 : MIN_16;
1103      }
1104      else
1105      {
1106          j = (Word16)L_temp;
1107      }
1108  
1109      p_max1 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1110                       pit_max, j, &max1, &rmax1, &r01, dtx, pOverflow);
1111  
1112      i = j - 1;
1113  
1114      j = pit_min << 1;
1115  
1116      p_max2 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1117                       i, j, &max2, &rmax2, &r02, dtx, pOverflow);
1118  
1119      i = j - 1;
1120  
1121      p_max3 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1122                       i, pit_min, &max3, &rmax3, &r03, dtx, pOverflow);
1123  
1124  #else
1125      L_temp = ((Word32)pit_min) << 2;
1126      if (L_temp != (Word32)((Word16) L_temp))
1127      {
1128          *pOverflow = 1;
1129          j = (pit_min > 0) ? MAX_16 : MIN_16;
1130      }
1131      else
1132      {
1133          j = (Word16)L_temp;
1134      }
1135  
1136      p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1137                       pit_max, j, &max1, dtx, pOverflow);
1138  
1139      i = j - 1;
1140  
1141  
1142      j = pit_min << 1;
1143  
1144  
1145      p_max2 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1146                       i, j, &max2, dtx, pOverflow);
1147  
1148      i = j - 1;
1149      p_max3 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame,
1150                       i, pit_min, &max3, dtx, pOverflow);
1151  
1152      if (dtx)
1153      {  /* no test() call since this if is only in simulation env */
1154  
1155          if (idx == 1)
1156          {
1157              /* calculate max high-passed filtered correlation of all lags */
1158              hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max,
1159                     pOverflow);
1160  
1161              /* update complex background detector */
1162              vad_complex_detection_update(vadSt, corr_hp_max);
1163          }
1164      }
1165  #endif
1166  
1167      /*--------------------------------------------------------------------*
1168       * Compare the 3 sections maximum, and favor small lag.               *
1169       *--------------------------------------------------------------------*/
1170  
1171      i =  mult(max1, THRESHOLD, pOverflow);
1172  
1173      if (i < max2)
1174      {
1175          max1 = max2;
1176          p_max1 = p_max2;
1177  
1178  #ifdef VAD2
1179          if (dtx)
1180          {
1181              rmax1 = rmax2;
1182              r01 = r02;
1183          }
1184  #endif
1185      }
1186  
1187      i =  mult(max1, THRESHOLD, pOverflow);
1188  
1189      if (i < max3)
1190      {
1191          p_max1 = p_max3;
1192  
1193  #ifdef VAD2
1194          if (dtx)
1195          {
1196              rmax1 = rmax3;
1197              r01 = r03;
1198          }
1199  #endif
1200      }
1201  
1202  #ifdef VAD2
1203      if (dtx)
1204      {
1205          /* Save max correlation */
1206          vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1, pOverflow);
1207          /* Save max energy */
1208          vadSt->L_R0 =   L_add(vadSt->L_R0, r01, pOverflow);
1209      }
1210  #endif
1211  
1212      return (p_max1);
1213  }
1214