FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/g_pitch.c @ 367:bd4f660eb75a
libtwamr: integrate g_pitch.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 03:08:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
366:1588a7d9e732 | 367:bd4f660eb75a |
---|---|
1 /* | |
2 ******************************************************************************** | |
3 * | |
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 | |
5 * R99 Version 3.3.0 | |
6 * REL-4 Version 4.1.0 | |
7 * | |
8 ******************************************************************************** | |
9 * | |
10 * File : g_pitch.c | |
11 * Purpose : Compute the pitch (adaptive codebook) gain. | |
12 * | |
13 ******************************************************************************** | |
14 */ | |
15 /* | |
16 ******************************************************************************** | |
17 * MODULE INCLUDE FILE AND VERSION ID | |
18 ******************************************************************************** | |
19 */ | |
20 #include "namespace.h" | |
21 #include "g_pitch.h" | |
22 | |
23 /* | |
24 ******************************************************************************** | |
25 * INCLUDE FILES | |
26 ******************************************************************************** | |
27 */ | |
28 #include "tw_amr.h" | |
29 #include "typedef.h" | |
30 #include "basic_op.h" | |
31 #include "oper_32b.h" | |
32 #include "no_count.h" | |
33 #include "cnst.h" | |
34 | |
35 /* | |
36 ******************************************************************************** | |
37 * PUBLIC PROGRAM CODE | |
38 ******************************************************************************** | |
39 */ | |
40 /************************************************************************* | |
41 * | |
42 * FUNCTION: G_pitch | |
43 * | |
44 * PURPOSE: Compute the pitch (adaptive codebook) gain. | |
45 * Result in Q14 (NOTE: 12.2 bit exact using Q12) | |
46 * | |
47 * DESCRIPTION: | |
48 * The adaptive codebook gain is given by | |
49 * | |
50 * g = <x[], y[]> / <y[], y[]> | |
51 * | |
52 * where x[] is the target vector, y[] is the filtered adaptive | |
53 * codevector, and <> denotes dot product. | |
54 * The gain is limited to the range [0,1.2] (=0..19661 Q14) | |
55 * | |
56 *************************************************************************/ | |
57 Word16 G_pitch ( /* o : Gain of pitch lag saturated to 1.2 */ | |
58 enum Mode mode, /* i : AMR mode */ | |
59 Word16 xn[], /* i : Pitch target. */ | |
60 Word16 y1[], /* i : Filtered adaptive codebook. */ | |
61 Word16 g_coeff[], /* i : Correlations need for gain quantization */ | |
62 Word16 L_subfr /* i : Length of subframe. */ | |
63 ) | |
64 { | |
65 Word16 i; | |
66 Word16 xy, yy, exp_xy, exp_yy, gain; | |
67 Word32 s; | |
68 | |
69 Word16 scaled_y1[L_SUBFR]; /* Usually dynamic allocation of (L_subfr) */ | |
70 | |
71 /* divide "y1[]" by 4 to avoid overflow */ | |
72 | |
73 for (i = 0; i < L_subfr; i++) | |
74 { | |
75 scaled_y1[i] = shr (y1[i], 2); move16 (); | |
76 } | |
77 | |
78 /* Compute scalar product <y1[],y1[]> */ | |
79 | |
80 /* Q12 scaling / MR122 */ | |
81 Overflow = 0; move16 (); | |
82 s = 1L; move32 (); /* Avoid case of all zeros */ | |
83 for (i = 0; i < L_subfr; i++) | |
84 { | |
85 s = L_mac (s, y1[i], y1[i]); | |
86 } | |
87 test (); | |
88 if (Overflow == 0) /* Test for overflow */ | |
89 { | |
90 exp_yy = norm_l (s); | |
91 yy = round (L_shl (s, exp_yy)); | |
92 } | |
93 else | |
94 { | |
95 s = 1L; move32 (); /* Avoid case of all zeros */ | |
96 for (i = 0; i < L_subfr; i++) | |
97 { | |
98 s = L_mac (s, scaled_y1[i], scaled_y1[i]); | |
99 } | |
100 exp_yy = norm_l (s); | |
101 yy = round (L_shl (s, exp_yy)); | |
102 exp_yy = sub (exp_yy, 4); | |
103 } | |
104 | |
105 /* Compute scalar product <xn[],y1[]> */ | |
106 | |
107 Overflow = 0; move16 (); | |
108 s = 1L; move32 (); /* Avoid case of all zeros */ | |
109 | |
110 for (i = 0; i < L_subfr; i++) | |
111 { | |
112 s = L_mac(s, xn[i], y1[i]); | |
113 } | |
114 test (); | |
115 if (Overflow == 0) | |
116 { | |
117 exp_xy = norm_l (s); | |
118 xy = round (L_shl (s, exp_xy)); | |
119 } | |
120 else | |
121 { | |
122 s = 1L; move32 (); /* Avoid case of all zeros */ | |
123 for (i = 0; i < L_subfr; i++) | |
124 { | |
125 s = L_mac (s, xn[i], scaled_y1[i]); | |
126 } | |
127 exp_xy = norm_l (s); | |
128 xy = round (L_shl (s, exp_xy)); | |
129 exp_xy = sub (exp_xy, 2); | |
130 } | |
131 | |
132 g_coeff[0] = yy; move16 (); | |
133 g_coeff[1] = sub (15, exp_yy); move16 (); | |
134 g_coeff[2] = xy; move16 (); | |
135 g_coeff[3] = sub (15, exp_xy); move16 (); | |
136 | |
137 /* If (xy < 4) gain = 0 */ | |
138 | |
139 i = sub (xy, 4); | |
140 | |
141 test (); | |
142 if (i < 0) | |
143 return ((Word16) 0); | |
144 | |
145 /* compute gain = xy/yy */ | |
146 | |
147 xy = shr (xy, 1); /* Be sure xy < yy */ | |
148 gain = div_s (xy, yy); | |
149 | |
150 i = sub (exp_xy, exp_yy); /* Denormalization of division */ | |
151 gain = shr (gain, i); | |
152 | |
153 /* if(gain >1.2) gain = 1.2 */ | |
154 | |
155 test (); | |
156 if (sub (gain, 19661) > 0) | |
157 { | |
158 gain = 19661; move16 (); | |
159 } | |
160 | |
161 test (); | |
162 if (sub(mode, MR122) == 0) | |
163 { | |
164 /* clear 2 LSBits */ | |
165 gain = gain & 0xfffC; logic16 (); | |
166 } | |
167 | |
168 return (gain); | |
169 } |