1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20 
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24 
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31 
32 
33 
34  Filename: pitch_fr.cpp
35 
36 ------------------------------------------------------------------------------
37  MODULE DESCRIPTION
38 
39       File             : pitch_fr.c
40       Purpose          : Find the pitch period with 1/3 or 1/6 subsample
41                        : resolution (closed loop).
42 
43 ------------------------------------------------------------------------------
44 */
45 
46 /*----------------------------------------------------------------------------
47 ; INCLUDES
48 ----------------------------------------------------------------------------*/
49 #include "pitch_fr.h"
50 #include "oper_32b.h"
51 #include "cnst.h"
52 #include "enc_lag3.h"
53 #include "enc_lag6.h"
54 #include "inter_36.h"
55 #include "inv_sqrt.h"
56 #include "convolve.h"
57 
58 #include "basic_op.h"
59 #include "oscl_mem.h"
60 
61 
62 /*----------------------------------------------------------------------------
63 ; MACROS
64 ; Define module specific macros here
65 ----------------------------------------------------------------------------*/
66 
67 /*----------------------------------------------------------------------------
68 ; DEFINES
69 ; Include all pre-processor statements here. Include conditional
70 ; compile variables also.
71 ----------------------------------------------------------------------------*/
72 
73 /*----------------------------------------------------------------------------
74 ; LOCAL FUNCTION DEFINITIONS
75 ; Function Prototype declaration
76 ----------------------------------------------------------------------------*/
77 
78 /*----------------------------------------------------------------------------
79 ; LOCAL VARIABLE DEFINITIONS
80 ; Variable declaration - defined here and used outside this module
81 ----------------------------------------------------------------------------*/
82 
83 /*
84  * mode dependent parameters used in Pitch_fr()
85  * Note: order of MRxx in 'enum Mode' is important!
86  */
87 static const struct
88 {
89     Word16 max_frac_lag;     /* lag up to which fractional lags are used    */
90     Word16 flag3;            /* enable 1/3 instead of 1/6 fract. resolution */
91     Word16 first_frac;       /* first fractional to check                   */
92     Word16 last_frac;        /* last fractional to check                    */
93     Word16 delta_int_low;    /* integer lag below TO to start search from   */
94     Word16 delta_int_range;  /* integer range around T0                     */
95     Word16 delta_frc_low;    /* fractional below T0                         */
96     Word16 delta_frc_range;  /* fractional range around T0                  */
97     Word16 pit_min;          /* minimum pitch                               */
98 } mode_dep_parm[N_MODES] =
99 {
100     /* MR475 */  { 84,  1, -2,  2,  5, 10,  5,  9, PIT_MIN },
101     /* MR515 */  { 84,  1, -2,  2,  5, 10,  5,  9, PIT_MIN },
102     /* MR59  */  { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
103     /* MR67  */  { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
104     /* MR74  */  { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
105     /* MR795 */  { 84,  1, -2,  2,  3,  6, 10, 19, PIT_MIN },
106     /* MR102 */  { 84,  1, -2,  2,  3,  6,  5,  9, PIT_MIN },
107     /* MR122 */  { 94,  0, -3,  3,  3,  6,  5,  9, PIT_MIN_MR122 }
108 };
109 
110 /*
111 ------------------------------------------------------------------------------
112  FUNCTION NAME: Norm_Corr
113 ------------------------------------------------------------------------------
114  INPUT AND OUTPUT DEFINITIONS
115 
116  Inputs:
117     exc[] = pointer to buffer of type Word16
118     xn[]  = pointer to buffer of type Word16
119     h[]   = pointer to buffer of type Word16
120     L_subfr = length of sub frame (Word16)
121     t_min  = the minimum table value of type Word16
122     t_max = the maximum table value of type Word16
123     corr_norm[] = pointer to buffer of type Word16
124 
125  Outputs:
126     pOverflow = 1 if the math functions called result in overflow else zero.
127 
128  Returns:
129     None
130 
131  Global Variables Used:
132     None
133 
134  Local Variables Needed:
135     None
136 
137 ------------------------------------------------------------------------------
138  FUNCTION DESCRIPTION
139 
140   FUNCTION:   Norm_Corr()
141 
142   PURPOSE: Find the normalized correlation between the target vector
143            and the filtered past excitation.
144 
145   DESCRIPTION:
146      The normalized correlation is given by the correlation between the
147      target and filtered past excitation divided by the square root of
148      the energy of filtered excitation.
149                    corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[])
150      where x[] is the target vector and y_k[] is the filtered past
151      excitation at delay k.
152 
153 
154 ------------------------------------------------------------------------------
155  REQUIREMENTS
156 
157  None
158 
159 ------------------------------------------------------------------------------
160  REFERENCES
161 
162  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
163 
164 ------------------------------------------------------------------------------
165  PSEUDO-CODE
166 
167 static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
168                        Word16 t_min, Word16 t_max, Word16 corr_norm[])
169 {
170     Word16 i, j, k;
171     Word16 corr_h, corr_l, norm_h, norm_l;
172     Word32 s;
173 
174     // Usally dynamic allocation of (L_subfr)
175     Word16 excf[L_SUBFR];
176     Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];
177 
178     k = -t_min;
179 
180     // compute the filtered excitation for the first delay t_min
181 
182     Convolve (&exc[k], h, excf, L_subfr);
183 
184     // scale "excf[]" to avoid overflow
185 
186     for (j = 0; j < L_subfr; j++) {
187         scaled_excf[j] = shr (excf[j], 2);
188     }
189 
190     // Compute 1/sqrt(energy of excf[])
191 
192     s = 0;
193     for (j = 0; j < L_subfr; j++) {
194         s = L_mac (s, excf[j], excf[j]);
195     }
196     if (L_sub (s, 67108864L) <= 0) {            // if (s <= 2^26)
197         s_excf = excf;
198         h_fac = 15 - 12;
199         scaling = 0;
200     }
201     else {
202         // "excf[]" is divided by 2
203         s_excf = scaled_excf;
204         h_fac = 15 - 12 - 2;
205         scaling = 2;
206     }
207 
208     // loop for every possible period
209 
210     for (i = t_min; i <= t_max; i++) {
211         // Compute 1/sqrt(energy of excf[])
212 
213         s = 0;
214         for (j = 0; j < L_subfr; j++) {
215             s = L_mac (s, s_excf[j], s_excf[j]);
216         }
217 
218         s = Inv_sqrt (s);
219         L_Extract (s, &norm_h, &norm_l);
220 
221         // Compute correlation between xn[] and excf[]
222 
223         s = 0;
224         for (j = 0; j < L_subfr; j++) {
225             s = L_mac (s, xn[j], s_excf[j]);
226         }
227         L_Extract (s, &corr_h, &corr_l);
228 
229         // Normalize correlation = correlation * (1/sqrt(energy))
230 
231         s = Mpy_32 (corr_h, corr_l, norm_h, norm_l);
232 
233         corr_norm[i] = extract_h (L_shl (s, 16));
234 
235             // modify the filtered excitation excf[] for the next iteration
236 
237         if (sub (i, t_max) != 0) {
238             k--;
239             for (j = L_subfr - 1; j > 0; j--) {
240                 s = L_mult (exc[k], h[j]);
241                 s = L_shl (s, h_fac);
242                 s_excf[j] = add (extract_h (s), s_excf[j - 1]);
243             }
244             s_excf[0] = shr (exc[k], scaling);
245         }
246     }
247     return;
248 }
249 
250 ------------------------------------------------------------------------------
251  CAUTION [optional]
252  [State any special notes, constraints or cautions for users of this function]
253 
254 ------------------------------------------------------------------------------
255 */
256 
257 static void Norm_Corr(Word16 exc[],
258                       Word16 xn[],
259                       Word16 h[],
260                       Word16 L_subfr,
261                       Word16 t_min,
262                       Word16 t_max,
263                       Word16 corr_norm[],
264                       Flag *pOverflow)
265 {
266     Word16 i;
267     Word16 j;
268     Word16 k;
269     Word16 corr_h;
270     Word16 corr_l;
271     Word16 norm_h;
272     Word16 norm_l;
273     Word32 s;
274     Word32 s2;
275     Word16 excf[L_SUBFR];
276     Word16 scaling;
277     Word16 h_fac;
278     Word16 *s_excf;
279     Word16 scaled_excf[L_SUBFR];
280     Word16 *p_s_excf;
281     Word16 *p_excf;
282     Word16  temp;
283     Word16 *p_x;
284     Word16 *p_h;
285 
286     k = -t_min;
287 
288     /* compute the filtered excitation for the first delay t_min */
289 
290     Convolve(&exc[k], h, excf, L_subfr);
291 
292     /* scale "excf[]" to avoid overflow */
293     s = 0;
294     p_s_excf = scaled_excf;
295     p_excf   = excf;
296 
297     for (j = (L_subfr >> 1); j != 0; j--)
298     {
299         temp = *(p_excf++);
300         *(p_s_excf++) = temp >> 2;
301         s += (Word32) temp * temp;
302         temp = *(p_excf++);
303         *(p_s_excf++) = temp >> 2;
304         s += (Word32) temp * temp;
305     }
306 
307 
308     if (s <= (67108864L >> 1))
309     {
310         s_excf = excf;
311         h_fac = 12;
312         scaling = 0;
313     }
314     else
315     {
316         /* "excf[]" is divided by 2 */
317         s_excf = scaled_excf;
318         h_fac = 14;
319         scaling = 2;
320     }
321 
322     /* loop for every possible period */
323 
324     for (i = t_min; i <= t_max; i++)
325     {
326         /* Compute 1/sqrt(energy of excf[]) */
327 
328         s   = s2 = 0;
329         p_x      = xn;
330         p_s_excf = s_excf;
331         j        = L_subfr >> 1;
332 
333         while (j--)
334         {
335             s  += (Word32) * (p_x++) * *(p_s_excf);
336             s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
337             p_s_excf++;
338             s  += (Word32) * (p_x++) * *(p_s_excf);
339             s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
340             p_s_excf++;
341         }
342 
343         s2     = s2 << 1;
344         s2     = Inv_sqrt(s2, pOverflow);
345         norm_h = (Word16)(s2 >> 16);
346         norm_l = (Word16)((s2 >> 1) - (norm_h << 15));
347         corr_h = (Word16)(s >> 15);
348         corr_l = (Word16)((s) - (corr_h << 15));
349 
350         /* Normalize correlation = correlation * (1/sqrt(energy)) */
351 
352         s = Mpy_32(corr_h, corr_l, norm_h, norm_l, pOverflow);
353 
354         corr_norm[i] = (Word16) s ;
355 
356         /* modify the filtered excitation excf[] for the next iteration */
357         if (i != t_max)
358         {
359             k--;
360             temp = exc[k];
361             p_s_excf = &s_excf[L_subfr - 1];
362             p_h = &h[L_subfr - 1];
363 
364             p_excf = &s_excf[L_subfr - 2];
365             for (j = (L_subfr - 1) >> 1; j != 0; j--)
366             {
367                 s = ((Word32) temp * *(p_h--)) >> h_fac;
368                 *(p_s_excf--) = (Word16) s  + *(p_excf--);
369                 s = ((Word32) temp * *(p_h--)) >> h_fac;
370                 *(p_s_excf--) = (Word16) s  + *(p_excf--);
371             }
372 
373             s = ((Word32) temp * *(p_h)) >> h_fac;
374             *(p_s_excf--) = (Word16) s  + *(p_excf);
375 
376             *(p_s_excf) = temp >> scaling;
377         }
378 
379     }
380     return;
381 }
382 
383 /****************************************************************************/
384 
385 
386 /*
387 ------------------------------------------------------------------------------
388  FUNCTION NAME: searchFrac
389 ------------------------------------------------------------------------------
390  INPUT AND OUTPUT DEFINITIONS
391 
392  Inputs:
393     lag = pointer to integer pitch of type Word16
394     frac = pointer to starting point of search fractional pitch of type Word16
395     last_frac = endpoint of search  of type Word16
396     corr[] = pointer to normalized correlation of type Word16
397     flag3 = subsample resolution (3: =1 / 6: =0) of type Word16
398 
399  Outputs:
400     None
401 
402  Returns:
403     None
404 
405  Global Variables Used:
406     None
407 
408  Local Variables Needed:
409     None
410 
411 ------------------------------------------------------------------------------
412  FUNCTION DESCRIPTION
413 
414    FUNCTION:   searchFrac()
415 
416    PURPOSE: Find fractional pitch
417 
418    DESCRIPTION:
419       The function interpolates the normalized correlation at the
420       fractional positions around lag T0. The position at which the
421       interpolation function reaches its maximum is the fractional pitch.
422       Starting point of the search is frac, end point is last_frac.
423       frac is overwritten with the fractional pitch.
424 
425 ------------------------------------------------------------------------------
426  REQUIREMENTS
427 
428  None
429 
430 ------------------------------------------------------------------------------
431  REFERENCES
432 
433  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
434 
435 ------------------------------------------------------------------------------
436  PSEUDO-CODE
437 
438 static void searchFrac (
439     Word16 *lag,       // i/o : integer pitch
440     Word16 *frac,      // i/o : start point of search -
441                                fractional pitch
442     Word16 last_frac,  // i   : endpoint of search
443     Word16 corr[],     // i   : normalized correlation
444     Word16 flag3       // i   : subsample resolution
445                                 (3: =1 / 6: =0)
446 )
447 {
448     Word16 i;
449     Word16 max;
450     Word16 corr_int;
451 
452     // Test the fractions around T0 and choose the one which maximizes
453     // the interpolated normalized correlation.
454 
455     max = Interpol_3or6 (&corr[*lag], *frac, flag3); // function result
456 
457     for (i = add (*frac, 1); i <= last_frac; i++) {
458         corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
459         if (sub (corr_int, max) > 0) {
460             max = corr_int;
461             *frac = i;
462         }
463     }
464 
465     if (flag3 == 0) {
466         // Limit the fraction value in the interval [-2,-1,0,1,2,3]
467 
468         if (sub (*frac, -3) == 0) {
469             *frac = 3;
470             *lag = sub (*lag, 1);
471         }
472     }
473     else {
474         // limit the fraction value between -1 and 1
475 
476         if (sub (*frac, -2) == 0) {
477             *frac = 1;
478             *lag = sub (*lag, 1);
479         }
480         if (sub (*frac, 2) == 0) {
481             *frac = -1;
482             *lag = add (*lag, 1);
483         }
484     }
485 }
486 
487 ------------------------------------------------------------------------------
488  CAUTION [optional]
489  [State any special notes, constraints or cautions for users of this function]
490 
491 ------------------------------------------------------------------------------
492 */
493 
494 static void searchFrac(
495     Word16 *lag,       /* i/o : integer pitch           */
496     Word16 *frac,      /* i/o : start point of search -
497                                 fractional pitch        */
498     Word16 last_frac,  /* i   : endpoint of search      */
499     Word16 corr[],     /* i   : normalized correlation  */
500     Word16 flag3,      /* i   : subsample resolution
501                                 (3: =1 / 6: =0)         */
502     Flag   *pOverflow
503 )
504 {
505     Word16 i;
506     Word16 max;
507     Word16 corr_int;
508 
509     /* Test the fractions around T0 and choose the one which maximizes   */
510     /* the interpolated normalized correlation.                          */
511 
512     max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow);
513     /* function result */
514 
515     for (i = *frac + 1; i <= last_frac; i++)
516     {
517         corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow);
518         if (corr_int > max)
519         {
520             max = corr_int;
521             *frac = i;
522         }
523     }
524 
525     if (flag3 == 0)
526     {
527         /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
528 
529         if (*frac == -3)
530         {
531             *frac = 3;
532             (*lag)--;
533         }
534     }
535     else
536     {
537         /* limit the fraction value between -1 and 1 */
538 
539         if (*frac == -2)
540         {
541             *frac = 1;
542             (*lag)--;
543         }
544         if (*frac == 2)
545         {
546             *frac = -1;
547             (*lag)++;
548         }
549     }
550 }
551 
552 /****************************************************************************/
553 
554 
555 /*
556 ------------------------------------------------------------------------------
557  FUNCTION NAME: getRange
558 ------------------------------------------------------------------------------
559  INPUT AND OUTPUT DEFINITIONS
560 
561  Inputs:
562     T0 = integer pitch of type Word16
563     delta_low = search start offset of type Word16
564     delta_range = search range of type Word16
565     pitmin = minimum pitch of type Word16
566     pitmax = maximum pitch of type Word16
567     t0_min = search range minimum of type Word16
568     t0_max = search range maximum of type Word16
569 
570  Outputs:
571     pOverflow = 1 if the math functions called result in overflow else zero.
572 
573  Returns:
574     None
575 
576  Global Variables Used:
577     None
578 
579  Local Variables Needed:
580     None
581 
582 ------------------------------------------------------------------------------
583  FUNCTION DESCRIPTION
584 
585    FUNCTION:   getRange()
586 
587    PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe
588 
589    DESCRIPTION:
590       Takes integer pitch T0 and calculates a range around it with
591         t0_min = T0-delta_low  and t0_max = (T0-delta_low) + delta_range
592       t0_min and t0_max are bounded by pitmin and pitmax
593 ------------------------------------------------------------------------------
594  REQUIREMENTS
595 
596  None
597 
598 ------------------------------------------------------------------------------
599  REFERENCES
600 
601  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
602 
603 ------------------------------------------------------------------------------
604  PSEUDO-CODE
605 
606 static void getRange (
607     Word16 T0,           // i : integer pitch
608     Word16 delta_low,    // i : search start offset
609     Word16 delta_range,  // i : search range
610     Word16 pitmin,       // i : minimum pitch
611     Word16 pitmax,       // i : maximum pitch
612     Word16 *t0_min,      // o : search range minimum
613     Word16 *t0_max)      // o : search range maximum
614 {
615     *t0_min = sub(T0, delta_low);
616     if (sub(*t0_min, pitmin) < 0) {
617         *t0_min = pitmin;
618     }
619     *t0_max = add(*t0_min, delta_range);
620     if (sub(*t0_max, pitmax) > 0) {
621         *t0_max = pitmax;
622         *t0_min = sub(*t0_max, delta_range);
623     }
624 }
625 
626 ------------------------------------------------------------------------------
627  CAUTION [optional]
628  [State any special notes, constraints or cautions for users of this function]
629 
630 ------------------------------------------------------------------------------
631 */
632 static void getRange(
633     Word16 T0,           /* i : integer pitch          */
634     Word16 delta_low,    /* i : search start offset    */
635     Word16 delta_range,  /* i : search range           */
636     Word16 pitmin,       /* i : minimum pitch          */
637     Word16 pitmax,       /* i : maximum pitch          */
638     Word16 *t0_min,      /* o : search range minimum   */
639     Word16 *t0_max,      /* o : search range maximum   */
640     Flag   *pOverflow)
641 {
642 
643     Word16 temp;
644     OSCL_UNUSED_ARG(pOverflow);
645 
646     temp = *t0_min;
647     temp = T0 - delta_low;
648     if (temp < pitmin)
649     {
650         temp = pitmin;
651     }
652     *t0_min = temp;
653 
654     temp +=  delta_range;
655     if (temp > pitmax)
656     {
657         temp = pitmax;
658         *t0_min = pitmax - delta_range;
659     }
660     *t0_max = temp;
661 
662 }
663 
664 
665 /****************************************************************************/
666 
667 
668 /*
669 ------------------------------------------------------------------------------
670  FUNCTION NAME: Pitch_fr_init
671 ------------------------------------------------------------------------------
672  INPUT AND OUTPUT DEFINITIONS
673 
674  Inputs:
675     state = pointer to a pointer of structure type Pitch_fr_State.
676 
677  Outputs:
678     None
679 
680  Returns:
681     Returns a zero if successful and -1 if not successful.
682 
683  Global Variables Used:
684     None
685 
686  Local Variables Needed:
687     None
688 
689 ------------------------------------------------------------------------------
690  FUNCTION DESCRIPTION
691 
692   Function:   Pitch_fr_init
693   Purpose:    Allocates state memory and initializes state memory
694 
695 ------------------------------------------------------------------------------
696  REQUIREMENTS
697 
698  None
699 
700 ------------------------------------------------------------------------------
701  REFERENCES
702 
703  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
704 
705 ------------------------------------------------------------------------------
706  PSEUDO-CODE
707 
708 int Pitch_fr_init (Pitch_frState **state)
709 {
710     Pitch_frState* s;
711 
712     if (state == (Pitch_frState **) NULL){
713         // fprintf(stderr, "Pitch_fr_init: invalid parameter\n");
714         return -1;
715     }
716     *state = NULL;
717 
718     // allocate memory
719     if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){
720         // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
721         return -1;
722     }
723 
724     Pitch_fr_reset(s);
725     *state = s;
726 
727     return 0;
728 }
729 
730 ------------------------------------------------------------------------------
731  CAUTION [optional]
732  [State any special notes, constraints or cautions for users of this function]
733 
734 ------------------------------------------------------------------------------
735 */
736 Word16 Pitch_fr_init(Pitch_frState **state)
737 {
738     Pitch_frState* s;
739 
740     if (state == (Pitch_frState **) NULL)
741     {
742         /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */
743         return -1;
744     }
745     *state = NULL;
746 
747     /* allocate memory */
748     if ((s = (Pitch_frState *) oscl_malloc(sizeof(Pitch_frState))) == NULL)
749     {
750         /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */
751         return -1;
752     }
753 
754     Pitch_fr_reset(s);
755     *state = s;
756 
757     return 0;
758 }
759 
760 
761 /****************************************************************************/
762 
763 
764 /*
765 ------------------------------------------------------------------------------
766  FUNCTION NAME: Pitch_fr_reset
767 ------------------------------------------------------------------------------
768  INPUT AND OUTPUT DEFINITIONS
769 
770  Inputs:
771     state = pointer to a pointer of structure type Pitch_fr_State.
772 
773  Outputs:
774     None
775 
776  Returns:
777     Returns a zero if successful and -1 if not successful.
778 
779  Global Variables Used:
780     None
781 
782  Local Variables Needed:
783     None
784 
785 ------------------------------------------------------------------------------
786  FUNCTION DESCRIPTION
787 
788   Function:   Pitch_fr_reset
789   Purpose:    Initializes state memory to zero
790 
791 ------------------------------------------------------------------------------
792  REQUIREMENTS
793 
794  None
795 
796 ------------------------------------------------------------------------------
797  REFERENCES
798 
799  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
800 
801 ------------------------------------------------------------------------------
802  PSEUDO-CODE
803 
804 int Pitch_fr_reset (Pitch_frState *state)
805 {
806 
807     if (state == (Pitch_frState *) NULL){
808         // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n");
809         return -1;
810     }
811 
812     state->T0_prev_subframe = 0;
813 
814     return 0;
815 }
816 
817 ------------------------------------------------------------------------------
818  CAUTION [optional]
819  [State any special notes, constraints or cautions for users of this function]
820 
821 ------------------------------------------------------------------------------
822 */
823 Word16 Pitch_fr_reset(Pitch_frState *state)
824 {
825 
826     if (state == (Pitch_frState *) NULL)
827     {
828         /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */
829         return -1;
830     }
831 
832     state->T0_prev_subframe = 0;
833 
834     return 0;
835 }
836 
837 
838 /****************************************************************************/
839 
840 
841 /*
842 ------------------------------------------------------------------------------
843  FUNCTION NAME: Pitch_fr_exit
844 ------------------------------------------------------------------------------
845  INPUT AND OUTPUT DEFINITIONS
846 
847  Inputs:
848     state = pointer to a pointer of structure type Pitch_fr_State.
849 
850  Outputs:
851     None
852 
853  Returns:
854     None
855 
856  Global Variables Used:
857     None
858 
859  Local Variables Needed:
860     None
861 
862 ------------------------------------------------------------------------------
863  FUNCTION DESCRIPTION
864 
865   Function:   Pitch_fr_exit
866   Purpose:    The memory for state is freed.
867 
868 ------------------------------------------------------------------------------
869  REQUIREMENTS
870 
871  None
872 
873 ------------------------------------------------------------------------------
874  REFERENCES
875 
876  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
877 
878 ------------------------------------------------------------------------------
879  PSEUDO-CODE
880 
881 void Pitch_fr_exit (Pitch_frState **state)
882 {
883     if (state == NULL || *state == NULL)
884         return;
885 
886     // deallocate memory
887     free(*state);
888     *state = NULL;
889 
890     return;
891 }
892 
893 ------------------------------------------------------------------------------
894  CAUTION [optional]
895  [State any special notes, constraints or cautions for users of this function]
896 
897 ------------------------------------------------------------------------------
898 */
899 void Pitch_fr_exit(Pitch_frState **state)
900 {
901     if (state == NULL || *state == NULL)
902         return;
903 
904     /* deallocate memory */
905     oscl_free(*state);
906     *state = NULL;
907 
908     return;
909 }
910 
911 /****************************************************************************/
912 
913 
914 /*
915 ------------------------------------------------------------------------------
916  FUNCTION NAME: Pitch_fr
917 ------------------------------------------------------------------------------
918  INPUT AND OUTPUT DEFINITIONS
919 
920  Inputs:
921     st = pointer to stat structure of type Pitch_frState
922     mode = codec mode of type enum Mode
923     T_op[] = pointer to open loop pitch lags of type Word16
924     exc[] = pointer to excitation buffer of type Word16
925     xn[] = pointer to target vector of type Word16
926     h[] = pointer to impulse response of synthesis and weighting filters
927           of type Word16
928     L_subfr = length of subframe of type Word16
929     i_subfr = subframe offset of type Word16
930 
931  Outputs:
932     pit_frac = pointer to pitch period (fractional) of type Word16
933     resu3 = pointer to subsample resolution of type Word16
934     ana_index = pointer to index of encoding of type Word16
935 
936  Returns:
937     None
938 
939  Global Variables Used:
940     None
941 
942  Local Variables Needed:
943     None
944 
945 ------------------------------------------------------------------------------
946  FUNCTION DESCRIPTION
947 
948    FUNCTION:   Pitch_fr()
949 
950    PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution
951             (closed loop).
952 
953    DESCRIPTION:
954          - find the normalized correlation between the target and filtered
955            past excitation in the search range.
956          - select the delay with maximum normalized correlation.
957          - interpolate the normalized correlation at fractions -3/6 to 3/6
958            with step 1/6 around the chosen delay.
959          - The fraction which gives the maximum interpolated value is chosen.
960 
961 ------------------------------------------------------------------------------
962  REQUIREMENTS
963 
964  None
965 
966 ------------------------------------------------------------------------------
967  REFERENCES
968 
969  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
970 
971 ------------------------------------------------------------------------------
972  PSEUDO-CODE
973 
974 Word16 Pitch_fr (        // o   : pitch period (integer)
975     Pitch_frState *st,   // i/o : State struct
976     enum Mode mode,      // i   : codec mode
977     Word16 T_op[],       // i   : open loop pitch lags
978     Word16 exc[],        // i   : excitation buffer                      Q0
979     Word16 xn[],         // i   : target vector                          Q0
980     Word16 h[],          // i   : impulse response of synthesis and
981                                   weighting filters                     Q12
982     Word16 L_subfr,      // i   : Length of subframe
983     Word16 i_subfr,      // i   : subframe offset
984     Word16 *pit_frac,    // o   : pitch period (fractional)
985     Word16 *resu3,       // o   : subsample resolution 1/3 (=1) or 1/6 (=0)
986     Word16 *ana_index    // o   : index of encoding
987 )
988 {
989     Word16 i;
990     Word16 t_min, t_max;
991     Word16 t0_min, t0_max;
992     Word16 max, lag, frac;
993     Word16 tmp_lag;
994     Word16 *corr;
995     Word16 corr_v[40];    // Total length = t0_max-t0_min+1+2*L_INTER_SRCH
996 
997     Word16 max_frac_lag;
998     Word16 flag3, flag4;
999     Word16 last_frac;
1000     Word16 delta_int_low, delta_int_range;
1001     Word16 delta_frc_low, delta_frc_range;
1002     Word16 pit_min;
1003     Word16 frame_offset;
1004     Word16 delta_search;
1005 
1006     //-----------------------------------------------------------------------
1007      //                      set mode specific variables
1008      //----------------------------------------------------------------------
1009 
1010     max_frac_lag    = mode_dep_parm[mode].max_frac_lag;
1011     flag3           = mode_dep_parm[mode].flag3;
1012     frac            = mode_dep_parm[mode].first_frac;
1013     last_frac       = mode_dep_parm[mode].last_frac;
1014     delta_int_low   = mode_dep_parm[mode].delta_int_low;
1015     delta_int_range = mode_dep_parm[mode].delta_int_range;
1016 
1017     delta_frc_low   = mode_dep_parm[mode].delta_frc_low;
1018     delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1019     pit_min         = mode_dep_parm[mode].pit_min;
1020 
1021     //-----------------------------------------------------------------------
1022     //                 decide upon full or differential search
1023     //-----------------------------------------------------------------------
1024 
1025     delta_search = 1;
1026 
1027     if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) {
1028 
1029         // Subframe 1 and 3
1030 
1031         if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode,
1032             (Word16)MR515) != 0)) ||
1033             (sub(i_subfr,L_FRAME_BY2) != 0)) {
1034 
1035             // set t0_min, t0_max for full search
1036             // this is *not* done for mode MR475, MR515 in subframe 3
1037 
1038             delta_search = 0; // no differential search
1039 
1040             // calculate index into T_op which contains the open-loop
1041             // pitch estimations for the 2 big subframes
1042 
1043             frame_offset = 1;
1044             if (i_subfr == 0)
1045                 frame_offset = 0;
1046 
1047             // get T_op from the corresponding half frame and
1048             // set t0_min, t0_max
1049 
1050             getRange (T_op[frame_offset], delta_int_low, delta_int_range,
1051                       pit_min, PIT_MAX, &t0_min, &t0_max);
1052         }
1053         else {
1054 
1055             // mode MR475, MR515 and 3. Subframe: delta search as well
1056             getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1057                       pit_min, PIT_MAX, &t0_min, &t0_max);
1058         }
1059     }
1060     else {
1061 
1062         // for Subframe 2 and 4
1063         // get range around T0 of previous subframe for delta search
1064 
1065         getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1066                   pit_min, PIT_MAX, &t0_min, &t0_max);
1067     }
1068 
1069     //-----------------------------------------------------------------------
1070                 Find interval to compute normalized correlation
1071      -----------------------------------------------------------------------
1072 
1073     t_min = sub (t0_min, L_INTER_SRCH);
1074     t_max = add (t0_max, L_INTER_SRCH);
1075 
1076     corr = &corr_v[-t_min];
1077 
1078     //-----------------------------------------------------------------------
1079       Compute normalized correlation between target and filtered excitation
1080      -----------------------------------------------------------------------
1081 
1082     Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
1083 
1084     //-----------------------------------------------------------------------
1085                                 Find integer pitch
1086      -----------------------------------------------------------------------
1087 
1088     max = corr[t0_min];
1089     lag = t0_min;
1090 
1091     for (i = t0_min + 1; i <= t0_max; i++) {
1092         if (sub (corr[i], max) >= 0) {
1093             max = corr[i];
1094             lag = i;
1095         }
1096     }
1097 
1098     //-----------------------------------------------------------------------
1099                              Find fractional pitch
1100      -----------------------------------------------------------------------
1101     if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) {
1102 
1103         // full search and integer pitch greater than max_frac_lag
1104         // fractional search is not needed, set fractional to zero
1105 
1106         frac = 0;
1107     }
1108     else {
1109 
1110         // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67
1111         // then search fractional with 4 bits resolution
1112 
1113        if ((delta_search != 0) &&
1114            ((sub ((Word16)mode, (Word16)MR475) == 0) ||
1115             (sub ((Word16)mode, (Word16)MR515) == 0) ||
1116             (sub ((Word16)mode, (Word16)MR59) == 0) ||
1117             (sub ((Word16)mode, (Word16)MR67) == 0))) {
1118 
1119           // modify frac or last_frac according to position of last
1120           // integer pitch: either search around integer pitch,
1121           // or only on left or right side
1122 
1123           tmp_lag = st->T0_prev_subframe;
1124           if ( sub( sub(tmp_lag, t0_min), 5) > 0)
1125              tmp_lag = add (t0_min, 5);
1126           if ( sub( sub(t0_max, tmp_lag), 4) > 0)
1127                tmp_lag = sub (t0_max, 4);
1128 
1129           if ((sub (lag, tmp_lag) == 0) ||
1130               (sub (lag, sub(tmp_lag, 1)) == 0)) {
1131 
1132              // normal search in fractions around T0
1133 
1134              searchFrac (&lag, &frac, last_frac, corr, flag3);
1135 
1136           }
1137           else if (sub (lag, sub (tmp_lag, 2)) == 0) {
1138              // limit search around T0 to the right side
1139              frac = 0;
1140              searchFrac (&lag, &frac, last_frac, corr, flag3);
1141           }
1142           else if (sub (lag, add(tmp_lag, 1)) == 0) {
1143              // limit search around T0 to the left side
1144              last_frac = 0;
1145              searchFrac (&lag, &frac, last_frac, corr, flag3);
1146           }
1147           else {
1148              // no fractional search
1149              frac = 0;
1150             }
1151        }
1152        else
1153           // test the fractions around T0
1154           searchFrac (&lag, &frac, last_frac, corr, flag3);
1155     }
1156 
1157     //-----------------------------------------------------------------------
1158      //                           encode pitch
1159      //-----------------------------------------------------------------------
1160 
1161     if (flag3 != 0) {
1162        // flag4 indicates encoding with 4 bit resolution;
1163        // this is needed for mode MR475, MR515 and MR59
1164 
1165        flag4 = 0;
1166        if ( (sub ((Word16)mode, (Word16)MR475) == 0) ||
1167             (sub ((Word16)mode, (Word16)MR515) == 0) ||
1168             (sub ((Word16)mode, (Word16)MR59) == 0) ||
1169             (sub ((Word16)mode, (Word16)MR67) == 0) ) {
1170           flag4 = 1;
1171        }
1172 
1173        // encode with 1/3 subsample resolution
1174 
1175        *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1176                              t0_min, t0_max, delta_search, flag4);
1177        // function result
1178 
1179     }
1180     else
1181     {
1182        // encode with 1/6 subsample resolution
1183 
1184        *ana_index = Enc_lag6(lag, frac, t0_min, delta_search);
1185        // function result
1186     }
1187 
1188      //-----------------------------------------------------------------------
1189      //                          update state variables
1190      //-----------------------------------------------------------------------
1191 
1192     st->T0_prev_subframe = lag;
1193 
1194      //-----------------------------------------------------------------------
1195      //                      update output variables
1196      //-----------------------------------------------------------------------
1197 
1198     *resu3    = flag3;
1199 
1200     *pit_frac = frac;
1201 
1202     return (lag);
1203 }
1204 
1205 
1206 ------------------------------------------------------------------------------
1207  CAUTION [optional]
1208  [State any special notes, constraints or cautions for users of this function]
1209 
1210 ------------------------------------------------------------------------------
1211 */
1212 Word16 Pitch_fr(         /* o   : pitch period (integer)                    */
1213     Pitch_frState *st,   /* i/o : State struct                              */
1214     enum Mode mode,      /* i   : codec mode                                */
1215     Word16 T_op[],       /* i   : open loop pitch lags                      */
1216     Word16 exc[],        /* i   : excitation buffer                      Q0 */
1217     Word16 xn[],         /* i   : target vector                          Q0 */
1218     Word16 h[],          /* i   : impulse response of synthesis and
1219                                   weighting filters                     Q12 */
1220     Word16 L_subfr,      /* i   : Length of subframe                        */
1221     Word16 i_subfr,      /* i   : subframe offset                           */
1222     Word16 *pit_frac,    /* o   : pitch period (fractional)                 */
1223     Word16 *resu3,       /* o   : subsample resolution 1/3 (=1) or 1/6 (=0) */
1224     Word16 *ana_index,   /* o   : index of encoding                         */
1225     Flag   *pOverflow
1226 )
1227 {
1228     Word16 i;
1229     Word16 t_min;
1230     Word16 t_max;
1231     Word16 t0_min = 0;
1232     Word16 t0_max;
1233     Word16 max;
1234     Word16 lag;
1235     Word16 frac;
1236     Word16 tmp_lag;
1237     Word16 *corr;
1238     Word16 corr_v[40];    /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
1239 
1240     Word16 max_frac_lag;
1241     Word16 flag3;
1242     Word16 flag4;
1243     Word16 last_frac;
1244     Word16 delta_int_low;
1245     Word16 delta_int_range;
1246     Word16 delta_frc_low;
1247     Word16 delta_frc_range;
1248     Word16 pit_min;
1249     Word16 frame_offset;
1250     Word16 delta_search;
1251 
1252     /*-----------------------------------------------------------------------*
1253      *                      set mode specific variables                      *
1254      *-----------------------------------------------------------------------*/
1255 
1256     max_frac_lag    = mode_dep_parm[mode].max_frac_lag;
1257     flag3           = mode_dep_parm[mode].flag3;
1258     frac            = mode_dep_parm[mode].first_frac;
1259     last_frac       = mode_dep_parm[mode].last_frac;
1260     delta_int_low   = mode_dep_parm[mode].delta_int_low;
1261     delta_int_range = mode_dep_parm[mode].delta_int_range;
1262 
1263     delta_frc_low   = mode_dep_parm[mode].delta_frc_low;
1264     delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1265     pit_min         = mode_dep_parm[mode].pit_min;
1266 
1267     /*-----------------------------------------------------------------------*
1268      *                 decide upon full or differential search               *
1269      *-----------------------------------------------------------------------*/
1270 
1271     delta_search = 1;
1272 
1273     if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
1274     {
1275 
1276         /* Subframe 1 and 3 */
1277 
1278         if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2))
1279         {
1280 
1281             /* set t0_min, t0_max for full search */
1282             /* this is *not* done for mode MR475, MR515 in subframe 3 */
1283 
1284             delta_search = 0; /* no differential search */
1285 
1286             /* calculate index into T_op which contains the open-loop */
1287             /* pitch estimations for the 2 big subframes */
1288 
1289             frame_offset = 1;
1290             if (i_subfr == 0)
1291                 frame_offset = 0;
1292 
1293             /* get T_op from the corresponding half frame and */
1294             /* set t0_min, t0_max */
1295 
1296             getRange(T_op[frame_offset], delta_int_low, delta_int_range,
1297                      pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1298         }
1299         else
1300         {
1301 
1302             /* mode MR475, MR515 and 3. Subframe: delta search as well */
1303             getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1304                      pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1305         }
1306     }
1307     else
1308     {
1309 
1310         /* for Subframe 2 and 4 */
1311         /* get range around T0 of previous subframe for delta search */
1312 
1313         getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1314                  pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1315     }
1316 
1317     /*-----------------------------------------------------------------------*
1318      *           Find interval to compute normalized correlation             *
1319      *-----------------------------------------------------------------------*/
1320 
1321     t_min = t0_min - L_INTER_SRCH;
1322     t_max = t0_max + L_INTER_SRCH;
1323 
1324     corr = &corr_v[-t_min];
1325 
1326     /*-----------------------------------------------------------------------*
1327      * Compute normalized correlation between target and filtered excitation *
1328      *-----------------------------------------------------------------------*/
1329 
1330     Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow);
1331 
1332     /*-----------------------------------------------------------------------*
1333      *                           Find integer pitch                          *
1334      *-----------------------------------------------------------------------*/
1335 
1336     max = corr[t0_min];
1337     lag = t0_min;
1338 
1339     for (i = t0_min + 1; i <= t0_max; i++)
1340     {
1341         if (corr[i] >= max)
1342         {
1343             max = corr[i];
1344             lag = i;
1345         }
1346     }
1347 
1348     /*-----------------------------------------------------------------------*
1349      *                        Find fractional pitch                          *
1350      *-----------------------------------------------------------------------*/
1351     if ((delta_search == 0) && (lag > max_frac_lag))
1352     {
1353 
1354         /* full search and integer pitch greater than max_frac_lag */
1355         /* fractional search is not needed, set fractional to zero */
1356 
1357         frac = 0;
1358     }
1359     else
1360     {
1361 
1362         /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67   */
1363         /* then search fractional with 4 bits resolution           */
1364 
1365         if ((delta_search != 0) &&
1366                 ((mode == MR475) || (mode == MR515) ||
1367                  (mode == MR59) || (mode == MR67)))
1368         {
1369 
1370             /* modify frac or last_frac according to position of last */
1371             /* integer pitch: either search around integer pitch, */
1372             /* or only on left or right side */
1373 
1374             tmp_lag = st->T0_prev_subframe;
1375             if ((tmp_lag - t0_min) > 5)
1376             {
1377                 tmp_lag = t0_min + 5;
1378             }
1379             if ((t0_max - tmp_lag) > 4)
1380             {
1381                 tmp_lag = t0_max - 4;
1382             }
1383 
1384             if ((lag == tmp_lag) || (lag == (tmp_lag - 1)))
1385             {
1386 
1387                 /* normal search in fractions around T0 */
1388 
1389                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1390 
1391             }
1392             else if (lag == (tmp_lag - 2))
1393             {
1394                 /* limit search around T0 to the right side */
1395                 frac = 0;
1396                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1397             }
1398             else if (lag == (tmp_lag + 1))
1399             {
1400                 /* limit search around T0 to the left side */
1401                 last_frac = 0;
1402                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1403             }
1404             else
1405             {
1406                 /* no fractional search */
1407                 frac = 0;
1408             }
1409         }
1410         else
1411             /* test the fractions around T0 */
1412             searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1413     }
1414 
1415     /*-----------------------------------------------------------------------*
1416      *                           encode pitch                                *
1417      *-----------------------------------------------------------------------*/
1418 
1419     if (flag3 != 0)
1420     {
1421         /* flag4 indicates encoding with 4 bit resolution;         */
1422         /* this is needed for mode MR475, MR515 and MR59           */
1423 
1424         flag4 = 0;
1425         if ((mode == MR475) || (mode == MR515) ||
1426                 (mode == MR59) || (mode == MR67))
1427         {
1428             flag4 = 1;
1429         }
1430 
1431         /* encode with 1/3 subsample resolution */
1432 
1433         *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1434                               t0_min, t0_max, delta_search, flag4, pOverflow);
1435         /* function result */
1436 
1437     }
1438     else
1439     {
1440         /* encode with 1/6 subsample resolution */
1441 
1442         *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow);
1443         /* function result */
1444     }
1445 
1446     /*-----------------------------------------------------------------------*
1447      *                          update state variables                       *
1448      *-----------------------------------------------------------------------*/
1449 
1450     st->T0_prev_subframe = lag;
1451 
1452     /*-----------------------------------------------------------------------*
1453      *                      update output variables                          *
1454      *-----------------------------------------------------------------------*/
1455 
1456     *resu3    = flag3;
1457 
1458     *pit_frac = frac;
1459 
1460     return (lag);
1461 }
1462 
1463