comparison libgsmefr/g_pitch.c @ 53:49dd1ac8e75b

libgsmefr: import most *.c files from ETSI source
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 25 Nov 2022 16:18:21 +0000
parents
children d9229fdac1c7
comparison
equal deleted inserted replaced
52:988fd7ff514f 53:49dd1ac8e75b
1 /*************************************************************************
2 *
3 * FUNCTION: G_pitch
4 *
5 * PURPOSE: Compute the pitch (adaptive codebook) gain. Result in Q12
6 *
7 * DESCRIPTION:
8 * The adaptive codebook gain is given by
9 *
10 * g = <x[], y[]> / <y[], y[]>
11 *
12 * where x[] is the target vector, y[] is the filtered adaptive
13 * codevector, and <> denotes dot product.
14 * The gain is limited to the range [0,1.2]
15 *
16 *************************************************************************/
17
18 #include "typedef.h"
19 #include "basic_op.h"
20 #include "oper_32b.h"
21 #include "count.h"
22 #include "sig_proc.h"
23
24 Word16 G_pitch ( /* (o) : Gain of pitch lag saturated to 1.2 */
25 Word16 xn[], /* (i) : Pitch target. */
26 Word16 y1[], /* (i) : Filtered adaptive codebook. */
27 Word16 L_subfr /* : Length of subframe. */
28 )
29 {
30 Word16 i;
31 Word16 xy, yy, exp_xy, exp_yy, gain;
32 Word32 s;
33
34 Word16 scaled_y1[80]; /* Usually dynamic allocation of (L_subfr) */
35
36 /* divide by 2 "y1[]" to avoid overflow */
37
38 for (i = 0; i < L_subfr; i++)
39 {
40 scaled_y1[i] = shr (y1[i], 2); move16 ();
41 }
42
43 /* Compute scalar product <y1[],y1[]> */
44
45 s = 0L; move32 (); /* Avoid case of all zeros */
46 for (i = 0; i < L_subfr; i++)
47 {
48 s = L_mac (s, y1[i], y1[i]);
49 }
50 test ();
51 if (L_sub (s, MAX_32) != 0L) /* Test for overflow */
52 {
53 s = L_add (s, 1L); /* Avoid case of all zeros */
54 exp_yy = norm_l (s);
55 yy = round (L_shl (s, exp_yy));
56 }
57 else
58 {
59 s = 1L; move32 (); /* Avoid case of all zeros */
60 for (i = 0; i < L_subfr; i++)
61 {
62 s = L_mac (s, scaled_y1[i], scaled_y1[i]);
63 }
64 exp_yy = norm_l (s);
65 yy = round (L_shl (s, exp_yy));
66 exp_yy = sub (exp_yy, 4);
67 }
68
69 /* Compute scalar product <xn[],y1[]> */
70
71 Overflow = 0; move16 ();
72 s = 1L; move32 (); /* Avoid case of all zeros */
73 for (i = 0; i < L_subfr; i++)
74 {
75 Carry = 0; move16 ();
76 s = L_macNs (s, xn[i], y1[i]);
77
78 test ();
79 if (Overflow != 0)
80 {
81 break;
82 }
83 }
84 test ();
85 if (Overflow == 0)
86 {
87 exp_xy = norm_l (s);
88 xy = round (L_shl (s, exp_xy));
89 }
90 else
91 {
92 s = 1L; move32 (); /* Avoid case of all zeros */
93 for (i = 0; i < L_subfr; i++)
94 {
95 s = L_mac (s, xn[i], scaled_y1[i]);
96 }
97 exp_xy = norm_l (s);
98 xy = round (L_shl (s, exp_xy));
99 exp_xy = sub (exp_xy, 2);
100 }
101
102 /* If (xy < 4) gain = 0 */
103
104 i = sub (xy, 4);
105
106 test ();
107 if (i < 0)
108 return ((Word16) 0);
109
110 /* compute gain = xy/yy */
111
112 xy = shr (xy, 1); /* Be sure xy < yy */
113 gain = div_s (xy, yy);
114
115 i = add (exp_xy, 3 - 1); /* Denormalization of division */
116 i = sub (i, exp_yy);
117
118 gain = shr (gain, i);
119
120 /* if(gain >1.2) gain = 1.2 */
121
122 test ();
123 if (sub (gain, 4915) > 0)
124 {
125 gain = 4915; move16 ();
126 }
127 return (gain);
128 }