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,enum Mode mode)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 enum Mode mode
575 )
576 {
577 Word16 i;
578 Word16 max;
579 Word16 corr_int;
580 Word16 minPitch;
581
582 /* Test the fractions around T0 and choose the one which maximizes */
583 /* the interpolated normalized correlation. */
584
585 max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow);
586 /* function result */
587
588 for (i = *frac + 1; i <= last_frac; i++)
589 {
590 corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow);
591 if (corr_int > max)
592 {
593 max = corr_int;
594 *frac = i;
595 }
596 }
597
598 minPitch = (mode == MR122) ? PIT_MIN_MR122 : PIT_MIN;
599 if (flag3 == 0)
600 {
601 /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
602
603 if (*frac == -3)
604 {
605 if (*lag > minPitch)
606 {
607 *frac = 3;
608 (*lag)--;
609 }
610 else
611 {
612 *frac = -2;
613 }
614 }
615 }
616 else
617 {
618 /* limit the fraction value between -1 and 1 */
619
620 if (*frac == -2)
621 {
622 if (*lag > minPitch)
623 {
624 *frac = 1;
625 (*lag)--;
626 }
627 else
628 {
629 *frac = -1;
630 }
631 }
632 else if (*frac == 2)
633 {
634 if (*lag < PIT_MAX)
635 {
636 *frac = -1;
637 (*lag)++;
638 }
639 else
640 {
641 *frac = 1;
642 }
643 }
644 }
645 }
646
647 /****************************************************************************/
648
649
650 /*
651 ------------------------------------------------------------------------------
652 FUNCTION NAME: getRange
653 ------------------------------------------------------------------------------
654 INPUT AND OUTPUT DEFINITIONS
655
656 Inputs:
657 T0 = integer pitch of type Word16
658 delta_low = search start offset of type Word16
659 delta_range = search range of type Word16
660 pitmin = minimum pitch of type Word16
661 pitmax = maximum pitch of type Word16
662 t0_min = search range minimum of type Word16
663 t0_max = search range maximum of type Word16
664
665 Outputs:
666 pOverflow = 1 if the math functions called result in overflow else zero.
667
668 Returns:
669 None
670
671 Global Variables Used:
672 None
673
674 Local Variables Needed:
675 None
676
677 ------------------------------------------------------------------------------
678 FUNCTION DESCRIPTION
679
680 FUNCTION: getRange()
681
682 PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe
683
684 DESCRIPTION:
685 Takes integer pitch T0 and calculates a range around it with
686 t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range
687 t0_min and t0_max are bounded by pitmin and pitmax
688 ------------------------------------------------------------------------------
689 REQUIREMENTS
690
691 None
692
693 ------------------------------------------------------------------------------
694 REFERENCES
695
696 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
697
698 ------------------------------------------------------------------------------
699 PSEUDO-CODE
700
701 static void getRange (
702 Word16 T0, // i : integer pitch
703 Word16 delta_low, // i : search start offset
704 Word16 delta_range, // i : search range
705 Word16 pitmin, // i : minimum pitch
706 Word16 pitmax, // i : maximum pitch
707 Word16 *t0_min, // o : search range minimum
708 Word16 *t0_max) // o : search range maximum
709 {
710 *t0_min = sub(T0, delta_low);
711 if (sub(*t0_min, pitmin) < 0) {
712 *t0_min = pitmin;
713 }
714 *t0_max = add(*t0_min, delta_range);
715 if (sub(*t0_max, pitmax) > 0) {
716 *t0_max = pitmax;
717 *t0_min = sub(*t0_max, delta_range);
718 }
719 }
720
721 ------------------------------------------------------------------------------
722 RESOURCES USED [optional]
723
724 When the code is written for a specific target processor the
725 the resources used should be documented below.
726
727 HEAP MEMORY USED: x bytes
728
729 STACK MEMORY USED: x bytes
730
731 CLOCK CYCLES: (cycle count equation for this function) + (variable
732 used to represent cycle count for each subroutine
733 called)
734 where: (cycle count variable) = cycle count for [subroutine
735 name]
736
737 ------------------------------------------------------------------------------
738 CAUTION [optional]
739 [State any special notes, constraints or cautions for users of this function]
740
741 ------------------------------------------------------------------------------
742 */
getRange(Word16 T0,Word16 delta_low,Word16 delta_range,Word16 pitmin,Word16 pitmax,Word16 * t0_min,Word16 * t0_max,Flag * pOverflow)743 static void getRange(
744 Word16 T0, /* i : integer pitch */
745 Word16 delta_low, /* i : search start offset */
746 Word16 delta_range, /* i : search range */
747 Word16 pitmin, /* i : minimum pitch */
748 Word16 pitmax, /* i : maximum pitch */
749 Word16 *t0_min, /* o : search range minimum */
750 Word16 *t0_max, /* o : search range maximum */
751 Flag *pOverflow)
752 {
753
754 Word16 temp;
755 OSCL_UNUSED_ARG(pOverflow);
756
757 temp = *t0_min;
758 temp = T0 - delta_low;
759 if (temp < pitmin)
760 {
761 temp = pitmin;
762 }
763 *t0_min = temp;
764
765 temp += delta_range;
766 if (temp > pitmax)
767 {
768 temp = pitmax;
769 *t0_min = pitmax - delta_range;
770 }
771 *t0_max = temp;
772
773 }
774
775
776 /****************************************************************************/
777
778
779 /*
780 ------------------------------------------------------------------------------
781 FUNCTION NAME: Pitch_fr_init
782 ------------------------------------------------------------------------------
783 INPUT AND OUTPUT DEFINITIONS
784
785 Inputs:
786 state = pointer to a pointer of structure type Pitch_fr_State.
787
788 Outputs:
789 None
790
791 Returns:
792 Returns a zero if successful and -1 if not successful.
793
794 Global Variables Used:
795 None
796
797 Local Variables Needed:
798 None
799
800 ------------------------------------------------------------------------------
801 FUNCTION DESCRIPTION
802
803 Function: Pitch_fr_init
804 Purpose: Allocates state memory and initializes state memory
805
806 ------------------------------------------------------------------------------
807 REQUIREMENTS
808
809 None
810
811 ------------------------------------------------------------------------------
812 REFERENCES
813
814 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
815
816 ------------------------------------------------------------------------------
817 PSEUDO-CODE
818
819 int Pitch_fr_init (Pitch_frState **state)
820 {
821 Pitch_frState* s;
822
823 if (state == (Pitch_frState **) NULL){
824 // fprintf(stderr, "Pitch_fr_init: invalid parameter\n");
825 return -1;
826 }
827 *state = NULL;
828
829 // allocate memory
830 if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){
831 // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
832 return -1;
833 }
834
835 Pitch_fr_reset(s);
836 *state = s;
837
838 return 0;
839 }
840
841 ------------------------------------------------------------------------------
842 RESOURCES USED [optional]
843
844 When the code is written for a specific target processor the
845 the resources used should be documented below.
846
847 HEAP MEMORY USED: x bytes
848
849 STACK MEMORY USED: x bytes
850
851 CLOCK CYCLES: (cycle count equation for this function) + (variable
852 used to represent cycle count for each subroutine
853 called)
854 where: (cycle count variable) = cycle count for [subroutine
855 name]
856
857 ------------------------------------------------------------------------------
858 CAUTION [optional]
859 [State any special notes, constraints or cautions for users of this function]
860
861 ------------------------------------------------------------------------------
862 */
Pitch_fr_init(Pitch_frState ** state)863 Word16 Pitch_fr_init(Pitch_frState **state)
864 {
865 Pitch_frState* s;
866
867 if (state == (Pitch_frState **) NULL)
868 {
869 /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */
870 return -1;
871 }
872 *state = NULL;
873
874 /* allocate memory */
875 if ((s = (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL)
876 {
877 /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */
878 return -1;
879 }
880
881 Pitch_fr_reset(s);
882 *state = s;
883
884 return 0;
885 }
886
887
888 /****************************************************************************/
889
890
891 /*
892 ------------------------------------------------------------------------------
893 FUNCTION NAME: Pitch_fr_reset
894 ------------------------------------------------------------------------------
895 INPUT AND OUTPUT DEFINITIONS
896
897 Inputs:
898 state = pointer to a pointer of structure type Pitch_fr_State.
899
900 Outputs:
901 None
902
903 Returns:
904 Returns a zero if successful and -1 if not successful.
905
906 Global Variables Used:
907 None
908
909 Local Variables Needed:
910 None
911
912 ------------------------------------------------------------------------------
913 FUNCTION DESCRIPTION
914
915 Function: Pitch_fr_reset
916 Purpose: Initializes state memory to zero
917
918 ------------------------------------------------------------------------------
919 REQUIREMENTS
920
921 None
922
923 ------------------------------------------------------------------------------
924 REFERENCES
925
926 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
927
928 ------------------------------------------------------------------------------
929 PSEUDO-CODE
930
931 int Pitch_fr_reset (Pitch_frState *state)
932 {
933
934 if (state == (Pitch_frState *) NULL){
935 // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n");
936 return -1;
937 }
938
939 state->T0_prev_subframe = 0;
940
941 return 0;
942 }
943
944 ------------------------------------------------------------------------------
945 RESOURCES USED [optional]
946
947 When the code is written for a specific target processor the
948 the resources used should be documented below.
949
950 HEAP MEMORY USED: x bytes
951
952 STACK MEMORY USED: x bytes
953
954 CLOCK CYCLES: (cycle count equation for this function) + (variable
955 used to represent cycle count for each subroutine
956 called)
957 where: (cycle count variable) = cycle count for [subroutine
958 name]
959
960 ------------------------------------------------------------------------------
961 CAUTION [optional]
962 [State any special notes, constraints or cautions for users of this function]
963
964 ------------------------------------------------------------------------------
965 */
Pitch_fr_reset(Pitch_frState * state)966 Word16 Pitch_fr_reset(Pitch_frState *state)
967 {
968
969 if (state == (Pitch_frState *) NULL)
970 {
971 /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */
972 return -1;
973 }
974
975 state->T0_prev_subframe = 0;
976
977 return 0;
978 }
979
980
981 /****************************************************************************/
982
983
984 /*
985 ------------------------------------------------------------------------------
986 FUNCTION NAME: Pitch_fr_exit
987 ------------------------------------------------------------------------------
988 INPUT AND OUTPUT DEFINITIONS
989
990 Inputs:
991 state = pointer to a pointer of structure type Pitch_fr_State.
992
993 Outputs:
994 None
995
996 Returns:
997 None
998
999 Global Variables Used:
1000 None
1001
1002 Local Variables Needed:
1003 None
1004
1005 ------------------------------------------------------------------------------
1006 FUNCTION DESCRIPTION
1007
1008 Function: Pitch_fr_exit
1009 Purpose: The memory for state is freed.
1010
1011 ------------------------------------------------------------------------------
1012 REQUIREMENTS
1013
1014 None
1015
1016 ------------------------------------------------------------------------------
1017 REFERENCES
1018
1019 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1020
1021 ------------------------------------------------------------------------------
1022 PSEUDO-CODE
1023
1024 void Pitch_fr_exit (Pitch_frState **state)
1025 {
1026 if (state == NULL || *state == NULL)
1027 return;
1028
1029 // deallocate memory
1030 free(*state);
1031 *state = NULL;
1032
1033 return;
1034 }
1035
1036 ------------------------------------------------------------------------------
1037 RESOURCES USED [optional]
1038
1039 When the code is written for a specific target processor the
1040 the resources used should be documented below.
1041
1042 HEAP MEMORY USED: x bytes
1043
1044 STACK MEMORY USED: x bytes
1045
1046 CLOCK CYCLES: (cycle count equation for this function) + (variable
1047 used to represent cycle count for each subroutine
1048 called)
1049 where: (cycle count variable) = cycle count for [subroutine
1050 name]
1051
1052 ------------------------------------------------------------------------------
1053 CAUTION [optional]
1054 [State any special notes, constraints or cautions for users of this function]
1055
1056 ------------------------------------------------------------------------------
1057 */
Pitch_fr_exit(Pitch_frState ** state)1058 void Pitch_fr_exit(Pitch_frState **state)
1059 {
1060 if (state == NULL || *state == NULL)
1061 return;
1062
1063 /* deallocate memory */
1064 free(*state);
1065 *state = NULL;
1066
1067 return;
1068 }
1069
1070 /****************************************************************************/
1071
1072
1073 /*
1074 ------------------------------------------------------------------------------
1075 FUNCTION NAME: Pitch_fr
1076 ------------------------------------------------------------------------------
1077 INPUT AND OUTPUT DEFINITIONS
1078
1079 Inputs:
1080 st = pointer to stat structure of type Pitch_frState
1081 mode = codec mode of type enum Mode
1082 T_op[] = pointer to open loop pitch lags of type Word16
1083 exc[] = pointer to excitation buffer of type Word16
1084 xn[] = pointer to target vector of type Word16
1085 h[] = pointer to impulse response of synthesis and weighting filters
1086 of type Word16
1087 L_subfr = length of subframe of type Word16
1088 i_subfr = subframe offset of type Word16
1089
1090 Outputs:
1091 pit_frac = pointer to pitch period (fractional) of type Word16
1092 resu3 = pointer to subsample resolution of type Word16
1093 ana_index = pointer to index of encoding of type Word16
1094
1095 Returns:
1096 None
1097
1098 Global Variables Used:
1099 None
1100
1101 Local Variables Needed:
1102 None
1103
1104 ------------------------------------------------------------------------------
1105 FUNCTION DESCRIPTION
1106
1107 FUNCTION: Pitch_fr()
1108
1109 PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution
1110 (closed loop).
1111
1112 DESCRIPTION:
1113 - find the normalized correlation between the target and filtered
1114 past excitation in the search range.
1115 - select the delay with maximum normalized correlation.
1116 - interpolate the normalized correlation at fractions -3/6 to 3/6
1117 with step 1/6 around the chosen delay.
1118 - The fraction which gives the maximum interpolated value is chosen.
1119
1120 ------------------------------------------------------------------------------
1121 REQUIREMENTS
1122
1123 None
1124
1125 ------------------------------------------------------------------------------
1126 REFERENCES
1127
1128 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1129
1130 ------------------------------------------------------------------------------
1131 PSEUDO-CODE
1132
1133 Word16 Pitch_fr ( // o : pitch period (integer)
1134 Pitch_frState *st, // i/o : State struct
1135 enum Mode mode, // i : codec mode
1136 Word16 T_op[], // i : open loop pitch lags
1137 Word16 exc[], // i : excitation buffer Q0
1138 Word16 xn[], // i : target vector Q0
1139 Word16 h[], // i : impulse response of synthesis and
1140 weighting filters Q12
1141 Word16 L_subfr, // i : Length of subframe
1142 Word16 i_subfr, // i : subframe offset
1143 Word16 *pit_frac, // o : pitch period (fractional)
1144 Word16 *resu3, // o : subsample resolution 1/3 (=1) or 1/6 (=0)
1145 Word16 *ana_index // o : index of encoding
1146 )
1147 {
1148 Word16 i;
1149 Word16 t_min, t_max;
1150 Word16 t0_min, t0_max;
1151 Word16 max, lag, frac;
1152 Word16 tmp_lag;
1153 Word16 *corr;
1154 Word16 corr_v[40]; // Total length = t0_max-t0_min+1+2*L_INTER_SRCH
1155
1156 Word16 max_frac_lag;
1157 Word16 flag3, flag4;
1158 Word16 last_frac;
1159 Word16 delta_int_low, delta_int_range;
1160 Word16 delta_frc_low, delta_frc_range;
1161 Word16 pit_min;
1162 Word16 frame_offset;
1163 Word16 delta_search;
1164
1165 //-----------------------------------------------------------------------
1166 // set mode specific variables
1167 //----------------------------------------------------------------------
1168
1169 max_frac_lag = mode_dep_parm[mode].max_frac_lag;
1170 flag3 = mode_dep_parm[mode].flag3;
1171 frac = mode_dep_parm[mode].first_frac;
1172 last_frac = mode_dep_parm[mode].last_frac;
1173 delta_int_low = mode_dep_parm[mode].delta_int_low;
1174 delta_int_range = mode_dep_parm[mode].delta_int_range;
1175
1176 delta_frc_low = mode_dep_parm[mode].delta_frc_low;
1177 delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1178 pit_min = mode_dep_parm[mode].pit_min;
1179
1180 //-----------------------------------------------------------------------
1181 // decide upon full or differential search
1182 //-----------------------------------------------------------------------
1183
1184 delta_search = 1;
1185
1186 if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) {
1187
1188 // Subframe 1 and 3
1189
1190 if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode,
1191 (Word16)MR515) != 0)) ||
1192 (sub(i_subfr,L_FRAME_BY2) != 0)) {
1193
1194 // set t0_min, t0_max for full search
1195 // this is *not* done for mode MR475, MR515 in subframe 3
1196
1197 delta_search = 0; // no differential search
1198
1199 // calculate index into T_op which contains the open-loop
1200 // pitch estimations for the 2 big subframes
1201
1202 frame_offset = 1;
1203 if (i_subfr == 0)
1204 frame_offset = 0;
1205
1206 // get T_op from the corresponding half frame and
1207 // set t0_min, t0_max
1208
1209 getRange (T_op[frame_offset], delta_int_low, delta_int_range,
1210 pit_min, PIT_MAX, &t0_min, &t0_max);
1211 }
1212 else {
1213
1214 // mode MR475, MR515 and 3. Subframe: delta search as well
1215 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1216 pit_min, PIT_MAX, &t0_min, &t0_max);
1217 }
1218 }
1219 else {
1220
1221 // for Subframe 2 and 4
1222 // get range around T0 of previous subframe for delta search
1223
1224 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1225 pit_min, PIT_MAX, &t0_min, &t0_max);
1226 }
1227
1228 //-----------------------------------------------------------------------
1229 Find interval to compute normalized correlation
1230 -----------------------------------------------------------------------
1231
1232 t_min = sub (t0_min, L_INTER_SRCH);
1233 t_max = add (t0_max, L_INTER_SRCH);
1234
1235 corr = &corr_v[-t_min];
1236
1237 //-----------------------------------------------------------------------
1238 Compute normalized correlation between target and filtered excitation
1239 -----------------------------------------------------------------------
1240
1241 Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
1242
1243 //-----------------------------------------------------------------------
1244 Find integer pitch
1245 -----------------------------------------------------------------------
1246
1247 max = corr[t0_min];
1248 lag = t0_min;
1249
1250 for (i = t0_min + 1; i <= t0_max; i++) {
1251 if (sub (corr[i], max) >= 0) {
1252 max = corr[i];
1253 lag = i;
1254 }
1255 }
1256
1257 //-----------------------------------------------------------------------
1258 Find fractional pitch
1259 -----------------------------------------------------------------------
1260 if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) {
1261
1262 // full search and integer pitch greater than max_frac_lag
1263 // fractional search is not needed, set fractional to zero
1264
1265 frac = 0;
1266 }
1267 else {
1268
1269 // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67
1270 // then search fractional with 4 bits resolution
1271
1272 if ((delta_search != 0) &&
1273 ((sub ((Word16)mode, (Word16)MR475) == 0) ||
1274 (sub ((Word16)mode, (Word16)MR515) == 0) ||
1275 (sub ((Word16)mode, (Word16)MR59) == 0) ||
1276 (sub ((Word16)mode, (Word16)MR67) == 0))) {
1277
1278 // modify frac or last_frac according to position of last
1279 // integer pitch: either search around integer pitch,
1280 // or only on left or right side
1281
1282 tmp_lag = st->T0_prev_subframe;
1283 if ( sub( sub(tmp_lag, t0_min), 5) > 0)
1284 tmp_lag = add (t0_min, 5);
1285 if ( sub( sub(t0_max, tmp_lag), 4) > 0)
1286 tmp_lag = sub (t0_max, 4);
1287
1288 if ((sub (lag, tmp_lag) == 0) ||
1289 (sub (lag, sub(tmp_lag, 1)) == 0)) {
1290
1291 // normal search in fractions around T0
1292
1293 searchFrac (&lag, &frac, last_frac, corr, flag3);
1294
1295 }
1296 else if (sub (lag, sub (tmp_lag, 2)) == 0) {
1297 // limit search around T0 to the right side
1298 frac = 0;
1299 searchFrac (&lag, &frac, last_frac, corr, flag3);
1300 }
1301 else if (sub (lag, add(tmp_lag, 1)) == 0) {
1302 // limit search around T0 to the left side
1303 last_frac = 0;
1304 searchFrac (&lag, &frac, last_frac, corr, flag3);
1305 }
1306 else {
1307 // no fractional search
1308 frac = 0;
1309 }
1310 }
1311 else
1312 // test the fractions around T0
1313 searchFrac (&lag, &frac, last_frac, corr, flag3);
1314 }
1315
1316 //-----------------------------------------------------------------------
1317 // encode pitch
1318 //-----------------------------------------------------------------------
1319
1320 if (flag3 != 0) {
1321 // flag4 indicates encoding with 4 bit resolution;
1322 // this is needed for mode MR475, MR515 and MR59
1323
1324 flag4 = 0;
1325 if ( (sub ((Word16)mode, (Word16)MR475) == 0) ||
1326 (sub ((Word16)mode, (Word16)MR515) == 0) ||
1327 (sub ((Word16)mode, (Word16)MR59) == 0) ||
1328 (sub ((Word16)mode, (Word16)MR67) == 0) ) {
1329 flag4 = 1;
1330 }
1331
1332 // encode with 1/3 subsample resolution
1333
1334 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1335 t0_min, t0_max, delta_search, flag4);
1336 // function result
1337
1338 }
1339 else
1340 {
1341 // encode with 1/6 subsample resolution
1342
1343 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search);
1344 // function result
1345 }
1346
1347 //-----------------------------------------------------------------------
1348 // update state variables
1349 //-----------------------------------------------------------------------
1350
1351 st->T0_prev_subframe = lag;
1352
1353 //-----------------------------------------------------------------------
1354 // update output variables
1355 //-----------------------------------------------------------------------
1356
1357 *resu3 = flag3;
1358
1359 *pit_frac = frac;
1360
1361 return (lag);
1362 }
1363
1364
1365 ------------------------------------------------------------------------------
1366 RESOURCES USED [optional]
1367
1368 When the code is written for a specific target processor the
1369 the resources used should be documented below.
1370
1371 HEAP MEMORY USED: x bytes
1372
1373 STACK MEMORY USED: x bytes
1374
1375 CLOCK CYCLES: (cycle count equation for this function) + (variable
1376 used to represent cycle count for each subroutine
1377 called)
1378 where: (cycle count variable) = cycle count for [subroutine
1379 name]
1380
1381 ------------------------------------------------------------------------------
1382 CAUTION [optional]
1383 [State any special notes, constraints or cautions for users of this function]
1384
1385 ------------------------------------------------------------------------------
1386 */
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)1387 Word16 Pitch_fr( /* o : pitch period (integer) */
1388 Pitch_frState *st, /* i/o : State struct */
1389 enum Mode mode, /* i : codec mode */
1390 Word16 T_op[], /* i : open loop pitch lags */
1391 Word16 exc[], /* i : excitation buffer Q0 */
1392 Word16 xn[], /* i : target vector Q0 */
1393 Word16 h[], /* i : impulse response of synthesis and
1394 weighting filters Q12 */
1395 Word16 L_subfr, /* i : Length of subframe */
1396 Word16 i_subfr, /* i : subframe offset */
1397 Word16 *pit_frac, /* o : pitch period (fractional) */
1398 Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */
1399 Word16 *ana_index, /* o : index of encoding */
1400 Flag *pOverflow
1401 )
1402 {
1403 Word16 i;
1404 Word16 t_min;
1405 Word16 t_max;
1406 Word16 t0_min = 0;
1407 Word16 t0_max;
1408 Word16 max;
1409 Word16 lag;
1410 Word16 frac;
1411 Word16 tmp_lag;
1412 Word16 *corr;
1413 Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
1414
1415 Word16 max_frac_lag;
1416 Word16 flag3;
1417 Word16 flag4;
1418 Word16 last_frac;
1419 Word16 delta_int_low;
1420 Word16 delta_int_range;
1421 Word16 delta_frc_low;
1422 Word16 delta_frc_range;
1423 Word16 pit_min;
1424 Word16 frame_offset;
1425 Word16 delta_search;
1426
1427 /*-----------------------------------------------------------------------*
1428 * set mode specific variables *
1429 *-----------------------------------------------------------------------*/
1430
1431 max_frac_lag = mode_dep_parm[mode].max_frac_lag;
1432 flag3 = mode_dep_parm[mode].flag3;
1433 frac = mode_dep_parm[mode].first_frac;
1434 last_frac = mode_dep_parm[mode].last_frac;
1435 delta_int_low = mode_dep_parm[mode].delta_int_low;
1436 delta_int_range = mode_dep_parm[mode].delta_int_range;
1437
1438 delta_frc_low = mode_dep_parm[mode].delta_frc_low;
1439 delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1440 pit_min = mode_dep_parm[mode].pit_min;
1441
1442 /*-----------------------------------------------------------------------*
1443 * decide upon full or differential search *
1444 *-----------------------------------------------------------------------*/
1445
1446 delta_search = 1;
1447
1448 if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
1449 {
1450
1451 /* Subframe 1 and 3 */
1452
1453 if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2))
1454 {
1455
1456 /* set t0_min, t0_max for full search */
1457 /* this is *not* done for mode MR475, MR515 in subframe 3 */
1458
1459 delta_search = 0; /* no differential search */
1460
1461 /* calculate index into T_op which contains the open-loop */
1462 /* pitch estimations for the 2 big subframes */
1463
1464 frame_offset = 1;
1465 if (i_subfr == 0)
1466 frame_offset = 0;
1467
1468 /* get T_op from the corresponding half frame and */
1469 /* set t0_min, t0_max */
1470
1471 getRange(T_op[frame_offset], delta_int_low, delta_int_range,
1472 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1473 }
1474 else
1475 {
1476
1477 /* mode MR475, MR515 and 3. Subframe: delta search as well */
1478 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1479 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1480 }
1481 }
1482 else
1483 {
1484
1485 /* for Subframe 2 and 4 */
1486 /* get range around T0 of previous subframe for delta search */
1487
1488 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1489 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1490 }
1491
1492 /*-----------------------------------------------------------------------*
1493 * Find interval to compute normalized correlation *
1494 *-----------------------------------------------------------------------*/
1495
1496 t_min = sub(t0_min, L_INTER_SRCH, pOverflow);
1497 t_max = add(t0_max, L_INTER_SRCH, pOverflow);
1498
1499 corr = &corr_v[-t_min];
1500
1501 /*-----------------------------------------------------------------------*
1502 * Compute normalized correlation between target and filtered excitation *
1503 *-----------------------------------------------------------------------*/
1504
1505 Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow);
1506
1507 /*-----------------------------------------------------------------------*
1508 * Find integer pitch *
1509 *-----------------------------------------------------------------------*/
1510
1511 max = corr[t0_min];
1512 lag = t0_min;
1513
1514 for (i = t0_min + 1; i <= t0_max; i++)
1515 {
1516 if (corr[i] >= max)
1517 {
1518 max = corr[i];
1519 lag = i;
1520 }
1521 }
1522
1523 /*-----------------------------------------------------------------------*
1524 * Find fractional pitch *
1525 *-----------------------------------------------------------------------*/
1526 if ((delta_search == 0) && (lag > max_frac_lag))
1527 {
1528
1529 /* full search and integer pitch greater than max_frac_lag */
1530 /* fractional search is not needed, set fractional to zero */
1531
1532 frac = 0;
1533 }
1534 else
1535 {
1536
1537 /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 */
1538 /* then search fractional with 4 bits resolution */
1539
1540 if ((delta_search != 0) &&
1541 ((mode == MR475) || (mode == MR515) ||
1542 (mode == MR59) || (mode == MR67)))
1543 {
1544
1545 /* modify frac or last_frac according to position of last */
1546 /* integer pitch: either search around integer pitch, */
1547 /* or only on left or right side */
1548
1549 tmp_lag = st->T0_prev_subframe;
1550 if (sub(sub(tmp_lag, t0_min, pOverflow), 5, pOverflow) > 0)
1551 tmp_lag = add(t0_min, 5, pOverflow);
1552 if (sub(sub(t0_max, tmp_lag, pOverflow), 4, pOverflow) > 0)
1553 tmp_lag = sub(t0_max, 4, pOverflow);
1554
1555 if ((lag == tmp_lag) || (lag == (tmp_lag - 1)))
1556 {
1557
1558 /* normal search in fractions around T0 */
1559
1560 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1561
1562 }
1563 else if (lag == (tmp_lag - 2))
1564 {
1565 /* limit search around T0 to the right side */
1566 frac = 0;
1567 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1568 }
1569 else if (lag == (tmp_lag + 1))
1570 {
1571 /* limit search around T0 to the left side */
1572 last_frac = 0;
1573 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1574 }
1575 else
1576 {
1577 /* no fractional search */
1578 frac = 0;
1579 }
1580 }
1581 else
1582 /* test the fractions around T0 */
1583 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1584 }
1585
1586 /*-----------------------------------------------------------------------*
1587 * encode pitch *
1588 *-----------------------------------------------------------------------*/
1589
1590 if (flag3 != 0)
1591 {
1592 /* flag4 indicates encoding with 4 bit resolution; */
1593 /* this is needed for mode MR475, MR515 and MR59 */
1594
1595 flag4 = 0;
1596 if ((mode == MR475) || (mode == MR515) ||
1597 (mode == MR59) || (mode == MR67))
1598 {
1599 flag4 = 1;
1600 }
1601
1602 /* encode with 1/3 subsample resolution */
1603
1604 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1605 t0_min, t0_max, delta_search, flag4, pOverflow);
1606 /* function result */
1607
1608 }
1609 else
1610 {
1611 /* encode with 1/6 subsample resolution */
1612
1613 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow);
1614 /* function result */
1615 }
1616
1617 /*-----------------------------------------------------------------------*
1618 * update state variables *
1619 *-----------------------------------------------------------------------*/
1620
1621 st->T0_prev_subframe = lag;
1622
1623 /*-----------------------------------------------------------------------*
1624 * update output variables *
1625 *-----------------------------------------------------------------------*/
1626
1627 *resu3 = flag3;
1628
1629 *pit_frac = frac;
1630
1631 return (lag);
1632 }
1633
1634