FreeCalypso > hg > gsm-codec-lib
comparison libgsmhr1/dtx_rxfe.c @ 577:d68b2c92464a
libgsmhr1: bring in parts of dtx.[ch] needed for RxFE
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Feb 2025 03:06:11 +0000 |
parents | |
children | 7756b23b78cd |
comparison
equal
deleted
inserted
replaced
576:94f0cc85ad50 | 577:d68b2c92464a |
---|---|
1 /* | |
2 * Here we implement the subset of DTX functions that are used by the Rx | |
3 * front end, i.e., the part of libgsmhr1 that is common between the full | |
4 * decoder and our TFO transform implementation. Note that the same DTX | |
5 * functions will also be used by the speech encoder. | |
6 */ | |
7 | |
8 #include "typedefs.h" | |
9 #include "namespace.h" | |
10 #include "dtx_rxfe.h" | |
11 #include "mathhalf.h" | |
12 #include "mathdp31.h" | |
13 | |
14 /* relevant definitions from original dtx.c */ | |
15 | |
16 #define PN_XOR_REG (Longword)0x00000005L | |
17 #define PN_XOR_ADD (Longword)0x40000000L | |
18 | |
19 #define OH_SHIFT 3 /* shift corresponding to OVERHANG */ | |
20 | |
21 /* Values of GS for voicing state 0, all values shifted down by 2 | |
22 shifts */ | |
23 const LongwordRom ppLr_gsTable[4][32] = | |
24 { | |
25 { | |
26 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, | |
27 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, | |
28 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, | |
29 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, | |
30 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, | |
31 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, | |
32 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, | |
33 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 | |
34 }, | |
35 | |
36 { | |
37 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, | |
38 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, | |
39 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, | |
40 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, | |
41 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, | |
42 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, | |
43 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, | |
44 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff | |
45 }, | |
46 { | |
47 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, | |
48 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, | |
49 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, | |
50 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, | |
51 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, | |
52 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, | |
53 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, | |
54 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 | |
55 }, | |
56 { | |
57 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, | |
58 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, | |
59 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, | |
60 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, | |
61 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, | |
62 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, | |
63 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, | |
64 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 | |
65 } | |
66 }; | |
67 | |
68 /************************************************************************* | |
69 * | |
70 * FUNCTION NAME: avgGsHistQntz | |
71 * | |
72 * PURPOSE: | |
73 * | |
74 * Average gs history, where history is of length OVERHANG-1 | |
75 * frames. The last frame's (i.e. this frame) gs values are not | |
76 * available since quantization would have occured only after the | |
77 * VAD decision is made. | |
78 * | |
79 * INPUTS: | |
80 * | |
81 * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past | |
82 * OVERHANG-1 frames. The GS values are stored shifted down by 2 | |
83 * shifts to avoid overflow (the largest GS is greater than 2.0). | |
84 * | |
85 * | |
86 * OUTPUTS: | |
87 * | |
88 * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down | |
89 * by two shifts. | |
90 * | |
91 * RETURN VALUE: | |
92 * | |
93 * none. | |
94 * | |
95 * | |
96 *************************************************************************/ | |
97 | |
98 void avgGsHistQntz(Longword pL_GsHistory[], Longword *pL_GsAvgd) | |
99 { | |
100 | |
101 /*_________________________________________________________________________ | |
102 | | | |
103 | Automatic Variables | | |
104 |_________________________________________________________________________| | |
105 */ | |
106 | |
107 int i; | |
108 Longword L_avg; | |
109 | |
110 /*_________________________________________________________________________ | |
111 | | | |
112 | Executable Code | | |
113 |_________________________________________________________________________| | |
114 */ | |
115 | |
116 L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); | |
117 | |
118 for (i = 1; i < N_SUB * (OVERHANG - 1); i++) | |
119 L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); | |
120 | |
121 /* avg number x/32 not x/28 */ | |
122 | |
123 *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ | |
124 | |
125 } | |
126 | |
127 /************************************************************************* | |
128 * | |
129 * FUNCTION NAME: gsQuant | |
130 * | |
131 * PURPOSE: | |
132 * | |
133 * Quantize a value of gs in any of the voicing modes. Input GS | |
134 * is a 32 bit number. The GSP0 index is returned. | |
135 * | |
136 * INPUTS: | |
137 * | |
138 * L_GsIn - 32 bit GS value, shifted down by 2 shifts. | |
139 * | |
140 * swVoicingMode - voicing level | |
141 * | |
142 * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values | |
143 * have been shifted down by 2 from their true value. | |
144 * | |
145 * OUTPUTS: | |
146 * | |
147 * none | |
148 * | |
149 * RETURN VALUE: | |
150 * | |
151 * | |
152 * GSP0 Index closest to the input value of GS. | |
153 * | |
154 * | |
155 *************************************************************************/ | |
156 | |
157 Shortword gsQuant(Longword L_GsIn, Shortword swVoicingMode) | |
158 { | |
159 | |
160 /*_________________________________________________________________________ | |
161 | | | |
162 | Automatic Variables | | |
163 |_________________________________________________________________________| | |
164 */ | |
165 | |
166 Shortword swGsIndex, | |
167 swBestGs; | |
168 Longword L_diff, | |
169 L_min = LW_MAX; | |
170 | |
171 | |
172 /*_________________________________________________________________________ | |
173 | | | |
174 | Executable Code | | |
175 |_________________________________________________________________________| | |
176 */ | |
177 | |
178 for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) | |
179 { | |
180 L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); | |
181 | |
182 if (L_sub(L_diff, L_min) < 0) | |
183 { | |
184 /* new minimum */ | |
185 /* ----------- */ | |
186 | |
187 swBestGs = swGsIndex; | |
188 L_min = L_diff; | |
189 | |
190 } | |
191 } | |
192 | |
193 return (swBestGs); | |
194 | |
195 } | |
196 | |
197 /************************************************************************* | |
198 * | |
199 * FUNCTION NAME: getPnBits | |
200 * | |
201 * PURPOSE: | |
202 * | |
203 * Generate iBits pseudo-random bits using *pL_PNSeed as the | |
204 * pn-generators seed. | |
205 * | |
206 * INPUTS: | |
207 * | |
208 * iBits - integer indicating how many random bits to return. | |
209 * range [0,15], 0 yields 1 bit output | |
210 * | |
211 * *pL_PNSeed - 32 bit seed (changed by function) | |
212 * | |
213 * OUTPUTS: | |
214 * | |
215 * *pL_PNSeed - 32 bit seed, modified. | |
216 * | |
217 * RETURN VALUE: | |
218 * | |
219 * random bits in iBits LSB's. | |
220 * | |
221 * | |
222 * IMPLEMENTATION: | |
223 * | |
224 * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a | |
225 * PN sequence generator using Longwords generating a 2**31 -1 | |
226 * length pn-sequence. | |
227 * | |
228 *************************************************************************/ | |
229 | |
230 Shortword getPnBits(int iBits, Longword *pL_PNSeed) | |
231 { | |
232 | |
233 /*_________________________________________________________________________ | |
234 | | | |
235 | Automatic Variables | | |
236 |_________________________________________________________________________| | |
237 */ | |
238 | |
239 Shortword swPnBits = 0; | |
240 Longword L_Taps, | |
241 L_FeedBack; | |
242 int i; | |
243 | |
244 /*_________________________________________________________________________ | |
245 | | | |
246 | Executable Code | | |
247 |_________________________________________________________________________| | |
248 */ | |
249 | |
250 for (i = 0; i < iBits; i++) | |
251 { | |
252 /* update the state */ | |
253 /* ---------------- */ | |
254 | |
255 L_Taps = *pL_PNSeed & PN_XOR_REG; | |
256 L_FeedBack = L_Taps; /* Xor tap bits to yield | |
257 * feedback bit */ | |
258 L_Taps = L_shr(L_Taps, 1); | |
259 | |
260 while (L_Taps) | |
261 { | |
262 L_FeedBack = L_FeedBack ^ L_Taps; | |
263 L_Taps = L_shr(L_Taps, 1); | |
264 } | |
265 | |
266 /* LSB of L_FeedBack is next MSB of PN register */ | |
267 | |
268 *pL_PNSeed = L_shr(*pL_PNSeed, 1); | |
269 if (L_FeedBack & 1) | |
270 *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; | |
271 | |
272 /* State update complete. Get the output bit from the state, add/or it | |
273 * into output */ | |
274 | |
275 swPnBits = shl(swPnBits, 1); | |
276 swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); | |
277 | |
278 } | |
279 return (swPnBits); | |
280 } |