FreeCalypso > hg > gsm-codec-lib
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 } |