Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / pitch_fr.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: 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