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