FreeCalypso > hg > gsmhr-codec-ref
comparison dtx.c @ 0:9008dbc8ca74
import original C code from GSM 06.06
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 14 Jun 2024 23:27:16 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9008dbc8ca74 |
---|---|
1 /*************************************************************************** | |
2 * | |
3 * File Name: dtx.c | |
4 * | |
5 * Purpose: DTX and comfort noise functions of the GSM half rate | |
6 * system | |
7 * | |
8 * Reference: Recommendation GSM 06.41 (DTX) | |
9 * Recommendation GSM 06.22 (Comfort Noise) | |
10 * | |
11 * Below is a listing of all the functions appearing in the file. | |
12 * The functions are arranged according to their purpose. Under | |
13 * each heading, the ordering is hierarchical. | |
14 * | |
15 * Evaluation of comfort noise parameters | |
16 * swComfortNoise() | |
17 * updateCNHist() | |
18 * avgGsHistQntz() | |
19 * gsQuant() | |
20 * avgCNHist() | |
21 * lpcCorrQntz() | |
22 * getPnBits() | |
23 * | |
24 * Interpolation of comfort noise parameters | |
25 * rxInterpR0Lpc() | |
26 * linInterpSid() | |
27 * | |
28 **************************************************************************/ | |
29 | |
30 /*________________________________________________________________________ | |
31 | | | |
32 | Include Files | | |
33 |________________________________________________________________________| | |
34 */ | |
35 | |
36 #include "typedefs.h" | |
37 #include "mathhalf.h" | |
38 #include "mathdp31.h" | |
39 #include "dtx.h" | |
40 #include "sp_dec.h" | |
41 #include "sp_rom.h" | |
42 #include "sp_frm.h" | |
43 | |
44 /*________________________________________________________________________ | |
45 | | | |
46 | Defines | | |
47 |________________________________________________________________________| | |
48 */ | |
49 | |
50 #define PN_XOR_REG (Longword)0x00000005L | |
51 #define PN_XOR_ADD (Longword)0x40000000L | |
52 | |
53 #define OH_SHIFT 3 /* shift corresponding to OVERHANG */ | |
54 | |
55 #define NP_AFLAT 4 | |
56 #define LPC_VQ_SEG 3 | |
57 | |
58 #define ASHIFT 4 | |
59 #define ASCALE 0x0800 | |
60 | |
61 | |
62 /*________________________________________________________________________ | |
63 | | | |
64 | Global Variables | | |
65 |________________________________________________________________________| | |
66 */ | |
67 | |
68 Shortword swVadFrmCnt = 0; /* Indicates the number of sequential | |
69 * frames where VAD == 0 */ | |
70 | |
71 short int siUpdPointer = 0; | |
72 Shortword swNElapsed = 50; | |
73 | |
74 | |
75 Longword pL_GsHist[N_SUB * (OVERHANG - 1)]; | |
76 | |
77 | |
78 /*________________________________________________________________________ | |
79 | | | |
80 | Other External Variables | | |
81 |________________________________________________________________________| | |
82 */ | |
83 | |
84 extern int iLimit; | |
85 | |
86 extern Shortword swR0Dec, | |
87 swOldR0Dec, | |
88 swR0NewCN; | |
89 | |
90 extern Shortword swCNR0, | |
91 pswCNLpc[], | |
92 pswCNGsp0Code[], | |
93 pswCNVSCode1[], | |
94 pswCNVSCode2[]; | |
95 | |
96 /*________________________________________________________________________ | |
97 | | | |
98 | DTX Rom Tables | | |
99 |________________________________________________________________________| | |
100 */ | |
101 | |
102 /* interpolation curve for comfort noise (i*1/12) i=1..12 */ | |
103 Shortword psrCNNewFactor[12] = {0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552, | |
104 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4, | |
105 0x754e, 0x7fff}; | |
106 | |
107 | |
108 /* Values of GS for voicing state 0, all values shifted down by 2 | |
109 shifts */ | |
110 LongwordRom ppLr_gsTable[4][32] = | |
111 { | |
112 { | |
113 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, | |
114 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, | |
115 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, | |
116 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, | |
117 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, | |
118 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, | |
119 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, | |
120 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 | |
121 }, | |
122 | |
123 { | |
124 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, | |
125 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, | |
126 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, | |
127 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, | |
128 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, | |
129 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, | |
130 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, | |
131 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff | |
132 }, | |
133 { | |
134 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, | |
135 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, | |
136 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, | |
137 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, | |
138 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, | |
139 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, | |
140 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, | |
141 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 | |
142 }, | |
143 { | |
144 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, | |
145 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, | |
146 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, | |
147 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, | |
148 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, | |
149 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, | |
150 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, | |
151 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 | |
152 } | |
153 }; | |
154 | |
155 /************************************************************************* | |
156 * | |
157 * FUNCTION NAME: swComfortNoise | |
158 * | |
159 * PURPOSE: | |
160 * | |
161 * This routine perform the following tasks: | |
162 * - generation of the speech flag (swSP) | |
163 * - averaging and encoding of the comfort noise parameters | |
164 * - randomization of the codebook indices | |
165 * | |
166 * | |
167 * INPUTS: | |
168 * | |
169 * swVadFrmCnt (global) - swVadFlag=0 frame counter. | |
170 * If swVadFlag=1 then this counter is 0, the first frame with | |
171 * swVadFlag=0 will set this counter to 1, with each additional | |
172 * swVadFlag=0 frame the counter is incremented. | |
173 * | |
174 * swVadFlag - voise activity flag. swVadFlag=0 frame with | |
175 * no voice activity, swVadFlag=0 frame with voice activity | |
176 * | |
177 * L_UnqntzdR0 - unquantized R(0), 32 bit value, output of | |
178 * FLAT. | |
179 * | |
180 * pL_UnqntzdCorr[NP+1] - unquantized correlation sequence, | |
181 * also an output of FLAT. | |
182 * | |
183 * | |
184 * OUTPUTS: | |
185 * | |
186 * swCNR0 - global variable, the output quantized R0 index | |
187 * | |
188 * pswCNLpc[3] - global variable, the output quantized LPC to the | |
189 * transmitted in the SID frame | |
190 * | |
191 * pswCNGsp0Code[N_SUB] - global variable, the output quantized GSP0 indices | |
192 * | |
193 * pswCNVSCode1[N_SUB] - global variable, the output quantized codevector 1 | |
194 * indices. | |
195 * | |
196 * pswCNVSCode2[N_SUB] - global variable, the output quantized codevector 2 | |
197 * indices. | |
198 * | |
199 * | |
200 * RETURN VALUE: | |
201 * | |
202 * swSP - speech flag, swSP=1 speech frames are generated, swSP=0 | |
203 * SID frames are generated. | |
204 * | |
205 *************************************************************************/ | |
206 | |
207 Shortword swComfortNoise(Shortword swVadFlag, | |
208 Longword L_UnqntzdR0, Longword *pL_UnqntzdCorr) | |
209 { | |
210 | |
211 /*________________________________________________________________________ | |
212 | | | |
213 | Static Variables | | |
214 |________________________________________________________________________| | |
215 */ | |
216 | |
217 /* history of unquantized parameters */ | |
218 static Longword pL_R0Hist[OVERHANG]; | |
219 static Longword ppL_CorrHist[OVERHANG][NP + 1]; | |
220 | |
221 /* quantized reference parameters */ | |
222 static Shortword swQntRefR0, | |
223 swRefGsIndex; | |
224 static int piRefVqCodewds[3]; | |
225 | |
226 /* handling of short speech bursts */ | |
227 static Shortword swShortBurst; | |
228 | |
229 /* state value of random generator */ | |
230 static Longword L_TxPNSeed; | |
231 | |
232 /*_________________________________________________________________________ | |
233 | | | |
234 | Automatic Variables | | |
235 |_________________________________________________________________________| | |
236 */ | |
237 | |
238 Shortword swSP; | |
239 Shortword pswFinalRc[NP]; | |
240 | |
241 /* unquantized reference parameters */ | |
242 Longword L_RefR0; | |
243 Longword pL_RefCorr[NP + 1]; | |
244 Longword L_RefGs; | |
245 | |
246 int i; | |
247 | |
248 | |
249 /*_________________________________________________________________________ | |
250 | | | |
251 | Executable Code | | |
252 |_________________________________________________________________________| | |
253 */ | |
254 | |
255 swSP = 1; | |
256 | |
257 /* VadFrmCnt will indicate the number of sequential frames where */ | |
258 /* swVadFlag == 0 */ | |
259 /* ------------------------------------------------------------- */ | |
260 | |
261 if (swVadFlag) | |
262 swVadFrmCnt = 0; /* Voice acitvity present */ | |
263 else | |
264 swVadFrmCnt = add(swVadFrmCnt, 1); /* no voice activity */ | |
265 | |
266 | |
267 /* swNElapsed will indicate the number of frames that have elapsed */ | |
268 /* since the last SID frame with updated comfort noise parameters */ | |
269 /* was generated */ | |
270 /* --------------------------------------------------------------- */ | |
271 | |
272 swNElapsed = add(swNElapsed, 1); | |
273 | |
274 | |
275 /* If no voice activity was detected. */ | |
276 /* ----------------------------------- */ | |
277 | |
278 if (swVadFrmCnt) | |
279 { | |
280 | |
281 /* Short speech burst ? */ | |
282 /* -------------------- */ | |
283 | |
284 if (swVadFrmCnt == 1) | |
285 { | |
286 if (sub(swNElapsed, 24) < 0) | |
287 swShortBurst = 1; /* short speech burst detected */ | |
288 else | |
289 swShortBurst = 0; /* long speech burst detected */ | |
290 } | |
291 | |
292 | |
293 /* Update history, with this frames data */ | |
294 /* ------------------------------------- */ | |
295 | |
296 updateCNHist(L_UnqntzdR0, pL_UnqntzdCorr, | |
297 pL_R0Hist, ppL_CorrHist); | |
298 | |
299 | |
300 /* first SID frame */ | |
301 /* --------------- */ | |
302 | |
303 if (((swShortBurst == 0) && (swVadFrmCnt == OVERHANG)) || | |
304 ((swShortBurst == 1) && (swVadFrmCnt == 1))) | |
305 { | |
306 | |
307 /* init. random generator */ | |
308 /* ---------------------- */ | |
309 L_TxPNSeed = PN_INIT_SEED; | |
310 | |
311 | |
312 /* average GS */ | |
313 /* ---------- */ | |
314 avgGsHistQntz(pL_GsHist, &L_RefGs); | |
315 | |
316 | |
317 /* GS quantization */ | |
318 /* --------------- */ | |
319 swRefGsIndex = gsQuant(L_RefGs, 0); | |
320 | |
321 } | |
322 | |
323 | |
324 /* No Overhang in case of short speech bursts, */ | |
325 /* generate SID frames with repeated comfort noise parameters */ | |
326 /* ---------------------------------------------------------- */ | |
327 | |
328 if ((swShortBurst == 1) && (swVadFrmCnt < OVERHANG)) | |
329 { | |
330 | |
331 /* generate a SID frame with repeated parameters */ | |
332 /* --------------------------------------------- */ | |
333 | |
334 swSP = 0; | |
335 | |
336 | |
337 /* repeat data: r0, LPC, GS */ | |
338 /* ------------------------ */ | |
339 | |
340 swCNR0 = swQntRefR0; | |
341 | |
342 for (i = 0; i < 3; i++) | |
343 pswCNLpc[i] = piRefVqCodewds[i]; | |
344 | |
345 for (i = 0; i < N_SUB; i++) | |
346 pswCNGsp0Code[i] = swRefGsIndex; | |
347 | |
348 } | |
349 | |
350 | |
351 /* generate SID frames with updated comfort noise parameters */ | |
352 /* --------------------------------------------------------- */ | |
353 | |
354 if (swVadFrmCnt >= OVERHANG) | |
355 { | |
356 | |
357 /* A SID frame with updated parameters */ | |
358 /* ----------------------------------- */ | |
359 | |
360 swSP = 0; | |
361 swNElapsed = 0; | |
362 | |
363 | |
364 /* average R0 and correlation values */ | |
365 /* --------------------------------- */ | |
366 | |
367 avgCNHist(pL_R0Hist, ppL_CorrHist, &L_RefR0, | |
368 pL_RefCorr); | |
369 | |
370 | |
371 /* now quantize the averaged R(0) */ | |
372 /* ------------------------------ */ | |
373 | |
374 swQntRefR0 = r0Quant(L_RefR0); | |
375 | |
376 | |
377 /* Quantize the averaged correlation */ | |
378 /* --------------------------------- */ | |
379 | |
380 lpcCorrQntz(pL_RefCorr, | |
381 pswFinalRc, | |
382 piRefVqCodewds); | |
383 | |
384 | |
385 /* update frame data: r0, LPC */ | |
386 /* -------------------------- */ | |
387 | |
388 swCNR0 = swQntRefR0; | |
389 for (i = 0; i < 3; i++) | |
390 pswCNLpc[i] = piRefVqCodewds[i]; | |
391 | |
392 | |
393 /* update subframe data (unvoiced mode): GSP0 */ | |
394 /* ------------------------------------------ */ | |
395 | |
396 for (i = 0; i < N_SUB; i++) | |
397 pswCNGsp0Code[i] = swRefGsIndex; | |
398 | |
399 } | |
400 | |
401 | |
402 /* random codevectors */ | |
403 /* ------------------ */ | |
404 | |
405 if (swSP == 0) | |
406 { | |
407 for (i = 0; i < N_SUB; i++) | |
408 { | |
409 pswCNVSCode1[i] = getPnBits(7, &L_TxPNSeed); | |
410 pswCNVSCode2[i] = getPnBits(7, &L_TxPNSeed); | |
411 } | |
412 } | |
413 | |
414 | |
415 } | |
416 | |
417 return (swSP); | |
418 } | |
419 | |
420 | |
421 /************************************************************************* | |
422 * | |
423 * FUNCTION NAME: updateCNHist | |
424 * | |
425 * PURPOSE: | |
426 * | |
427 * Add current frame's unquantized R(0) and LPC information to the | |
428 * comfort noise history, so that it will be available for | |
429 * averaging. | |
430 * | |
431 * INPUTS: | |
432 * | |
433 * Unquantized values from the coder: | |
434 * | |
435 * | |
436 * L_UnqntzdR0 - unquantized frame energy R(0), an output of FLAT | |
437 * | |
438 * pL_UnqntzdCorr[NP+1] - unquantized correlation coefficient | |
439 * array. Also an output of FLAT. | |
440 * | |
441 * siUpdPointer (global) - A modulo counter which counts up from | |
442 * 0 to OVERHANG-1. | |
443 * | |
444 * OUTPUTS: | |
445 * | |
446 * pL_R0History[OVERHANG] - history of the OVERHANG frames worth of | |
447 * R(0). | |
448 * | |
449 * ppL_CorrHistory[OVERHANG][NP+1] - - history of the OVERHANG | |
450 * frames worth of pL_UnqntzdCorr[]. | |
451 * | |
452 * RETURN VALUE: | |
453 * | |
454 * none | |
455 * | |
456 *************************************************************************/ | |
457 | |
458 void updateCNHist(Longword L_UnqntzdR0, | |
459 Longword *pL_UnqntzdCorr, | |
460 Longword pL_R0History[], | |
461 Longword ppL_CorrHistory[OVERHANG][NP + 1]) | |
462 { | |
463 | |
464 /*_________________________________________________________________________ | |
465 | | | |
466 | Automatic Variables | | |
467 |_________________________________________________________________________| | |
468 */ | |
469 | |
470 int i; | |
471 | |
472 | |
473 /*_________________________________________________________________________ | |
474 | | | |
475 | Executable Code | | |
476 |_________________________________________________________________________| | |
477 */ | |
478 | |
479 /* update */ | |
480 pL_R0History[siUpdPointer] = L_UnqntzdR0; | |
481 | |
482 for (i = 0; i < NP + 1; i++) | |
483 ppL_CorrHistory[siUpdPointer][i] = pL_UnqntzdCorr[i]; | |
484 | |
485 siUpdPointer = (siUpdPointer + 1) % OVERHANG; | |
486 } | |
487 | |
488 | |
489 /************************************************************************* | |
490 * | |
491 * FUNCTION NAME: avgGsHistQntz | |
492 * | |
493 * PURPOSE: | |
494 * | |
495 * Average gs history, where history is of length OVERHANG-1 | |
496 * frames. The last frame's (i.e. this frame) gs values are not | |
497 * available since quantization would have occured only after the | |
498 * VAD decision is made. | |
499 * | |
500 * INPUTS: | |
501 * | |
502 * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past | |
503 * OVERHANG-1 frames. The GS values are stored shifted down by 2 | |
504 * shifts to avoid overflow (the largest GS is greater than 2.0). | |
505 * | |
506 * | |
507 * OUTPUTS: | |
508 * | |
509 * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down | |
510 * by two shifts. | |
511 * | |
512 * RETURN VALUE: | |
513 * | |
514 * none. | |
515 * | |
516 * | |
517 *************************************************************************/ | |
518 | |
519 void avgGsHistQntz(Longword pL_GsHistory[], Longword *pL_GsAvgd) | |
520 { | |
521 | |
522 /*_________________________________________________________________________ | |
523 | | | |
524 | Automatic Variables | | |
525 |_________________________________________________________________________| | |
526 */ | |
527 | |
528 int i; | |
529 Longword L_avg; | |
530 | |
531 /*_________________________________________________________________________ | |
532 | | | |
533 | Executable Code | | |
534 |_________________________________________________________________________| | |
535 */ | |
536 | |
537 L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); | |
538 | |
539 for (i = 1; i < N_SUB * (OVERHANG - 1); i++) | |
540 L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); | |
541 | |
542 /* avg number x/32 not x/28 */ | |
543 | |
544 *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ | |
545 | |
546 } | |
547 | |
548 | |
549 /************************************************************************* | |
550 * | |
551 * FUNCTION NAME: gsQuant | |
552 * | |
553 * PURPOSE: | |
554 * | |
555 * Quantize a value of gs in any of the voicing modes. Input GS | |
556 * is a 32 bit number. The GSP0 index is returned. | |
557 * | |
558 * INPUTS: | |
559 * | |
560 * L_GsIn - 32 bit GS value, shifted down by 2 shifts. | |
561 * | |
562 * swVoicingMode - voicing level | |
563 * | |
564 * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values | |
565 * have been shifted down by 2 from their true value. | |
566 * | |
567 * OUTPUTS: | |
568 * | |
569 * none | |
570 * | |
571 * RETURN VALUE: | |
572 * | |
573 * | |
574 * GSP0 Index closest to the input value of GS. | |
575 * | |
576 * | |
577 *************************************************************************/ | |
578 | |
579 Shortword gsQuant(Longword L_GsIn, Shortword swVoicingMode) | |
580 { | |
581 | |
582 /*_________________________________________________________________________ | |
583 | | | |
584 | Automatic Variables | | |
585 |_________________________________________________________________________| | |
586 */ | |
587 | |
588 Shortword swGsIndex, | |
589 swBestGs; | |
590 Longword L_diff, | |
591 L_min = LW_MAX; | |
592 | |
593 | |
594 /*_________________________________________________________________________ | |
595 | | | |
596 | Executable Code | | |
597 |_________________________________________________________________________| | |
598 */ | |
599 | |
600 for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) | |
601 { | |
602 L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); | |
603 | |
604 if (L_sub(L_diff, L_min) < 0) | |
605 { | |
606 /* new minimum */ | |
607 /* ----------- */ | |
608 | |
609 swBestGs = swGsIndex; | |
610 L_min = L_diff; | |
611 | |
612 } | |
613 } | |
614 | |
615 return (swBestGs); | |
616 | |
617 } | |
618 | |
619 | |
620 /************************************************************************* | |
621 * | |
622 * FUNCTION NAME: avgCNHist | |
623 * | |
624 * PURPOSE: | |
625 * | |
626 * Average the unquantized R0 and LPC data stored at the encoder | |
627 * to arrive at an average R0 and LPC frame for use in a SID | |
628 * frame. | |
629 * | |
630 * INPUTS: | |
631 * | |
632 * pL_R0History[OVERHANG] - contains unquantized R(0) data from the | |
633 * most recent OVERHANG frame (including this one). | |
634 * | |
635 * ppL_CorrHistory[OVERHANG][NP+1] - Unquantized correlation | |
636 * coefficients from the most recent OVERHANG frame (including this | |
637 * one). The data stored here is an output of FLAT. | |
638 * | |
639 * OUTPUTS: | |
640 * | |
641 * *pL_AvgdR0 - the average of pL_R0History[] | |
642 * | |
643 * pL_AvgdCorrSeq[NP+1] - the average of ppL_CorrHistory[][]. | |
644 * | |
645 * | |
646 * RETURN VALUE: | |
647 * | |
648 * none | |
649 * | |
650 *************************************************************************/ | |
651 | |
652 void avgCNHist(Longword pL_R0History[], | |
653 Longword ppL_CorrHistory[OVERHANG][NP + 1], | |
654 Longword *pL_AvgdR0, | |
655 Longword pL_AvgdCorrSeq[]) | |
656 { | |
657 | |
658 /*_________________________________________________________________________ | |
659 | | | |
660 | Automatic Variables | | |
661 |_________________________________________________________________________| | |
662 */ | |
663 | |
664 int i, | |
665 j; | |
666 Longword L_avg; | |
667 | |
668 /*_________________________________________________________________________ | |
669 | | | |
670 | Executable Code | | |
671 |_________________________________________________________________________| | |
672 */ | |
673 | |
674 /* R0 Averaging */ | |
675 /* ------------ */ | |
676 | |
677 for (L_avg = 0, i = 0; i < OVERHANG; i++) | |
678 L_avg = L_add(L_shr(pL_R0History[i], OH_SHIFT), L_avg); | |
679 | |
680 *pL_AvgdR0 = L_avg; | |
681 | |
682 | |
683 /* LPC: average the last OVERHANG frames */ | |
684 /* ------------------------------------- */ | |
685 | |
686 for (j = 0; j < NP + 1; j++) | |
687 { | |
688 for (L_avg = 0, i = 0; i < OVERHANG; i++) | |
689 { | |
690 L_avg = L_add(L_shift_r(ppL_CorrHistory[i][j], -OH_SHIFT), L_avg); | |
691 } | |
692 | |
693 pL_AvgdCorrSeq[j] = L_avg; | |
694 } | |
695 | |
696 } | |
697 | |
698 | |
699 /*************************************************************************** | |
700 * | |
701 * FUNCTION NAME: lpcCorrQntz | |
702 * | |
703 * PURPOSE: Quantize a correlation sequence | |
704 * | |
705 * | |
706 * INPUT: | |
707 * | |
708 * pL_CorrelSeq[NP+1] | |
709 * Correlation sequence to quantize. | |
710 * | |
711 * OUTPUTS: | |
712 * | |
713 * pswFinalRc[0:NP-1] | |
714 * A quantized set of NP reflection coefficients. | |
715 * | |
716 * piVQCodewds[0:2] | |
717 * An array containing the indices of the 3 reflection | |
718 * coefficient vectors selected from the three segment | |
719 * Rc-VQ. | |
720 * | |
721 * RETURN: | |
722 * None. | |
723 * | |
724 * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients | |
725 * | |
726 *************************************************************************/ | |
727 | |
728 void lpcCorrQntz(Longword pL_CorrelSeq[], | |
729 Shortword pswFinalRc[], | |
730 int piVQCodewds[]) | |
731 { | |
732 | |
733 /*_________________________________________________________________________ | |
734 | | | |
735 | Automatic Variables | | |
736 |_________________________________________________________________________| | |
737 */ | |
738 | |
739 Shortword pswPOldSpace[NP_AFLAT], | |
740 pswPNewSpace[NP_AFLAT], | |
741 pswVOldSpace[2 * NP_AFLAT - 1], | |
742 pswVNewSpace[2 * NP_AFLAT - 1], | |
743 *ppswPAddrs[2], | |
744 *ppswVAddrs[2], | |
745 *pswVBar, | |
746 pswPBar[NP_AFLAT], | |
747 pswVBarSpace[2 * NP_AFLAT - 1], | |
748 pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ | |
749 pswRc[NP + 1]; /* Temp list for the converted RC's */ | |
750 Longword *pL_VBarFull, | |
751 pL_PBarFull[NP], | |
752 pL_VBarFullSpace[2 * NP - 1]; | |
753 | |
754 int i, | |
755 iVec, | |
756 iSeg, | |
757 iCnt; /* Loop counter */ | |
758 struct QuantList quantList, /* A list of vectors */ | |
759 bestPql[4]; /* The four best vectors from | |
760 * the PreQ */ | |
761 struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of | |
762 * the three segments */ | |
763 | |
764 /*_________________________________________________________________________ | |
765 | | | |
766 | Executable Code | | |
767 |_________________________________________________________________________| | |
768 */ | |
769 | |
770 /* Setup pointers temporary space */ | |
771 /*--------------------------------*/ | |
772 | |
773 pswVBar = pswVBarSpace + NP_AFLAT - 1; | |
774 pL_VBarFull = pL_VBarFullSpace + NP - 1; | |
775 ppswPAddrs[0] = pswPOldSpace; | |
776 ppswPAddrs[1] = pswPNewSpace; | |
777 ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; | |
778 ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; | |
779 | |
780 | |
781 /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ | |
782 /* autocorrelation sequence derived from the optimal reflection */ | |
783 /* coefficients computed by FLAT. The initial conditions are shifted */ | |
784 /* right by RSHIFT bits. These initial conditions, stored as */ | |
785 /* Longwords, are used to initialize PBar and VBar arrays for the */ | |
786 /* next VQ segment. */ | |
787 /*--------------------------------------------------------------------*/ | |
788 | |
789 initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); | |
790 | |
791 /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ | |
792 /* and pL_VBarFull arrays initialized above. These are the initial */ | |
793 /* PBar and VBar conditions to be used by the AFLAT recursion at the */ | |
794 /* 1-st Rc-VQ segment. */ | |
795 /*--------------------------------------------------------------------*/ | |
796 | |
797 initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); | |
798 | |
799 for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) | |
800 { | |
801 /* initialize candidate list */ | |
802 /*---------------------------*/ | |
803 | |
804 quantList.iNum = psrPreQSz[iSeg - 1]; | |
805 quantList.iRCIndex = 0; | |
806 | |
807 /* do aflat for all vectors in the list */ | |
808 /*--------------------------------------*/ | |
809 | |
810 setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ | |
811 | |
812 for (iCnt = 0; iCnt < quantList.iNum; iCnt++) | |
813 { | |
814 /* get a vector */ | |
815 /*--------------*/ | |
816 | |
817 getNextVec(pswRc); | |
818 | |
819 /* clear the limiter flag */ | |
820 /*------------------------*/ | |
821 | |
822 iLimit = 0; | |
823 | |
824 /* find the error values for each vector */ | |
825 /*---------------------------------------*/ | |
826 | |
827 quantList.pswPredErr[iCnt] = | |
828 aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], | |
829 pswPBar, pswVBar, | |
830 ppswPAddrs, ppswVAddrs, | |
831 psvqIndex[iSeg - 1].len); | |
832 | |
833 /* check the limiter flag */ | |
834 /*------------------------*/ | |
835 | |
836 if (iLimit) | |
837 quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ | |
838 | |
839 } /* done list loop */ | |
840 | |
841 /* find 4 best prequantizer levels */ | |
842 /*---------------------------------*/ | |
843 | |
844 findBestInQuantList(quantList, 4, bestPql); | |
845 | |
846 for (iVec = 0; iVec < 4; iVec++) | |
847 { | |
848 | |
849 /* initialize quantizer list */ | |
850 /*---------------------------*/ | |
851 | |
852 quantList.iNum = psrQuantSz[iSeg - 1]; | |
853 quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; | |
854 | |
855 setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ | |
856 | |
857 /* do aflat recursion on each element of list */ | |
858 /*--------------------------------------------*/ | |
859 | |
860 for (iCnt = 0; iCnt < quantList.iNum; iCnt++) | |
861 { | |
862 /* get a vector */ | |
863 /*--------------*/ | |
864 | |
865 getNextVec(pswRc); | |
866 | |
867 /* clear the limiter flag */ | |
868 /*------------------------*/ | |
869 | |
870 iLimit = 0; | |
871 | |
872 /* find the error values for each vector */ | |
873 /*---------------------------------------*/ | |
874 | |
875 quantList.pswPredErr[iCnt] = | |
876 aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], | |
877 pswPBar, pswVBar, | |
878 ppswPAddrs, ppswVAddrs, | |
879 psvqIndex[iSeg - 1].len); | |
880 | |
881 /* check the limiter flag */ | |
882 /*------------------------*/ | |
883 | |
884 if (iLimit) | |
885 quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst | |
886 * value */ | |
887 | |
888 } /* done list loop */ | |
889 | |
890 /* find best quantizer vector for this segment, and save it */ | |
891 /*----------------------------------------------------------*/ | |
892 | |
893 findBestInQuantList(quantList, 1, bestQl); | |
894 if (iVec == 0) | |
895 bestQl[iSeg] = bestQl[0]; | |
896 else if (sub(bestQl[iSeg].pswPredErr[0], bestQl[0].pswPredErr[0]) > 0) | |
897 bestQl[iSeg] = bestQl[0]; | |
898 | |
899 } | |
900 | |
901 /* find the quantized reflection coefficients */ | |
902 /*--------------------------------------------*/ | |
903 | |
904 setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ | |
905 getNextVec((Shortword *) (pswFinalRc - 1)); | |
906 | |
907 | |
908 /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ | |
909 /* update the pswPBar and pswVBar for the next Rc-VQ segment */ | |
910 /*--------------------------------------------------------------*/ | |
911 | |
912 if (iSeg < LPC_VQ_SEG) | |
913 aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, | |
914 pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); | |
915 | |
916 } | |
917 | |
918 /* find the quantizer index (the values to be output in the symbol file) */ | |
919 /*-----------------------------------------------------------------*/ | |
920 | |
921 for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) | |
922 piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; | |
923 | |
924 } | |
925 | |
926 | |
927 /************************************************************************* | |
928 * | |
929 * FUNCTION NAME: getPnBits | |
930 * | |
931 * PURPOSE: | |
932 * | |
933 * Generate iBits pseudo-random bits using *pL_PNSeed as the | |
934 * pn-generators seed. | |
935 * | |
936 * INPUTS: | |
937 * | |
938 * iBits - integer indicating how many random bits to return. | |
939 * range [0,15], 0 yields 1 bit output | |
940 * | |
941 * *pL_PNSeed - 32 bit seed (changed by function) | |
942 * | |
943 * OUTPUTS: | |
944 * | |
945 * *pL_PNSeed - 32 bit seed, modified. | |
946 * | |
947 * RETURN VALUE: | |
948 * | |
949 * random bits in iBits LSB's. | |
950 * | |
951 * | |
952 * IMPLEMENTATION: | |
953 * | |
954 * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a | |
955 * PN sequence generator using Longwords generating a 2**31 -1 | |
956 * length pn-sequence. | |
957 * | |
958 *************************************************************************/ | |
959 | |
960 Shortword getPnBits(int iBits, Longword *pL_PNSeed) | |
961 { | |
962 | |
963 /*_________________________________________________________________________ | |
964 | | | |
965 | Automatic Variables | | |
966 |_________________________________________________________________________| | |
967 */ | |
968 | |
969 Shortword swPnBits = 0; | |
970 Longword L_Taps, | |
971 L_FeedBack; | |
972 int i; | |
973 | |
974 /*_________________________________________________________________________ | |
975 | | | |
976 | Executable Code | | |
977 |_________________________________________________________________________| | |
978 */ | |
979 | |
980 for (i = 0; i < iBits; i++) | |
981 { | |
982 /* update the state */ | |
983 /* ---------------- */ | |
984 | |
985 L_Taps = *pL_PNSeed & PN_XOR_REG; | |
986 L_FeedBack = L_Taps; /* Xor tap bits to yield | |
987 * feedback bit */ | |
988 L_Taps = L_shr(L_Taps, 1); | |
989 | |
990 while (L_Taps) | |
991 { | |
992 L_FeedBack = L_FeedBack ^ L_Taps; | |
993 L_Taps = L_shr(L_Taps, 1); | |
994 } | |
995 | |
996 /* LSB of L_FeedBack is next MSB of PN register */ | |
997 | |
998 *pL_PNSeed = L_shr(*pL_PNSeed, 1); | |
999 if (L_FeedBack & 1) | |
1000 *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; | |
1001 | |
1002 /* State update complete. Get the output bit from the state, add/or it | |
1003 * into output */ | |
1004 | |
1005 swPnBits = shl(swPnBits, 1); | |
1006 swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); | |
1007 | |
1008 } | |
1009 return (swPnBits); | |
1010 } | |
1011 | |
1012 | |
1013 /************************************************************************* | |
1014 * | |
1015 * FUNCTION NAME: rxInterpR0Lpc | |
1016 * | |
1017 * PURPOSE: | |
1018 * | |
1019 * Perform part of the comfort noise algorithm at the decoder. | |
1020 * LPC and R0 are derived in this routine | |
1021 * | |
1022 * INPUTS: | |
1023 * | |
1024 * pswOldKs - Last frame's reflection coeffs. | |
1025 * | |
1026 * pswNewKs - This frame's decoded/received reflection coeffs. | |
1027 * This will serve a new endpoint in interpolation. | |
1028 * | |
1029 * swRxDTXState - primary DTX state variable (at the receiver). A | |
1030 * modulo 12 counter, which is 0 at SID frame. | |
1031 * | |
1032 * swDecoMode - actual mode the decoder: speech decoding mode | |
1033 * or comfort noise insertion mode (SPEECH = speech decoding; | |
1034 * CNIFIRSTSID = comfort noise, 1st SID received; CNICONT = comfort | |
1035 * noise, SID frame received, but not 1st SID; CNIBFI = comfort | |
1036 * noise, bad frame received) | |
1037 * | |
1038 * swFrameType - type of the received frame (VALIDSID, INVALIDSID | |
1039 * GOODSPEECH or UNUSABLE) | |
1040 * | |
1041 * swOldR0Dec - global variable, the decoded R0 value from the last | |
1042 * frame . This will be modified. | |
1043 * | |
1044 * swR0NewCN - global variable the decoded R0 value from the frame | |
1045 * just received. Valid information if current frame is a SID frame. | |
1046 * | |
1047 * | |
1048 * OUTPUTS: | |
1049 * | |
1050 * pswNewKs - This frames LPC coeffs. modified to reflect | |
1051 * interpolated correlation sequence pL_CorrSeq[]. | |
1052 * | |
1053 * swR0Dec - global variable, interpolated R0 value | |
1054 * | |
1055 * swR0OldCN - global variable, R0 interpolation point to | |
1056 * interpolate from. | |
1057 * | |
1058 * swR0NewCN - global variable, R0 interpolation point to | |
1059 * interpolate to. | |
1060 * | |
1061 * pL_OldCorrSeq[NP+1] - global variable, starting point for | |
1062 * interpolation of LPC information. | |
1063 * | |
1064 * pL_NewCorrSeq[NP+1] - global variable, end point for | |
1065 * interpolation of LPC information. | |
1066 * | |
1067 * pL_CorrSeq[NP+1] - global variable, interpolated value of LPC | |
1068 * information to be used in this frame. | |
1069 * | |
1070 * | |
1071 * RETURN VALUE: | |
1072 * | |
1073 * None. | |
1074 * | |
1075 * KEYWORDS: interpolation, comfort noise, SID, DTX | |
1076 * | |
1077 *************************************************************************/ | |
1078 | |
1079 void rxInterpR0Lpc(Shortword *pswOldKs, Shortword *pswNewKs, | |
1080 Shortword swRxDTXState, | |
1081 Shortword swDecoMode, Shortword swFrameType) | |
1082 { | |
1083 | |
1084 /*________________________________________________________________________ | |
1085 | | | |
1086 | Static Variables | | |
1087 |________________________________________________________________________| | |
1088 */ | |
1089 | |
1090 static Shortword swR0OldCN; | |
1091 static Longword pL_OldCorrSeq[NP + 1], | |
1092 pL_NewCorrSeq[NP + 1], | |
1093 pL_CorrSeq[NP + 1]; | |
1094 | |
1095 | |
1096 /*_________________________________________________________________________ | |
1097 | | | |
1098 | Automatic Variables | | |
1099 |_________________________________________________________________________| | |
1100 */ | |
1101 | |
1102 int i; | |
1103 | |
1104 | |
1105 /*_________________________________________________________________________ | |
1106 | | | |
1107 | Executable Code | | |
1108 |_________________________________________________________________________| | |
1109 */ | |
1110 | |
1111 if (swDecoMode == CNIFIRSTSID) | |
1112 { | |
1113 /* first SID frame arrived */ | |
1114 /* ----------------------- */ | |
1115 | |
1116 /* use tx'd R0 frame as both endpoints of interp curve. */ | |
1117 /* i.e. no interpolation for the first frames */ | |
1118 /* ---------------------------------------------------- */ | |
1119 | |
1120 | |
1121 swR0OldCN = swOldR0Dec; /* last non-SID, received R0 */ | |
1122 swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); | |
1123 | |
1124 | |
1125 /* generate the LPC end points for interpolation */ | |
1126 /* --------------------------------------------- */ | |
1127 | |
1128 rcToCorrDpL(ASHIFT, ASCALE, pswOldKs, pL_OldCorrSeq); | |
1129 rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); | |
1130 | |
1131 /* linearly interpolate between the two sets of correlation coefs */ | |
1132 /* -------------------------------------------------------------- */ | |
1133 | |
1134 for (i = 0; i < NP + 1; i++) | |
1135 { | |
1136 pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], | |
1137 swRxDTXState); | |
1138 } | |
1139 | |
1140 /* Generate this frames K's (overwrite input) */ | |
1141 /* ------------------------------------------ */ | |
1142 | |
1143 aFlatRcDp(pL_CorrSeq, pswNewKs); | |
1144 | |
1145 } | |
1146 else if ((swDecoMode == CNICONT) && (swFrameType == VALIDSID)) | |
1147 { | |
1148 /* new (not the first) SID frame arrived */ | |
1149 /* ------------------------------------- */ | |
1150 | |
1151 swR0OldCN = swOldR0Dec; /* move current state of R0 to old */ | |
1152 swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); | |
1153 | |
1154 | |
1155 /* LPC: generate new endpoints for interpolation */ | |
1156 /* --------------------------------------------- */ | |
1157 | |
1158 for (i = 0; i < NP + 1; i++) | |
1159 { | |
1160 pL_OldCorrSeq[i] = pL_CorrSeq[i]; | |
1161 } | |
1162 | |
1163 rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); | |
1164 | |
1165 | |
1166 /* linearly interpolate between the two sets of correlation coefs */ | |
1167 /* -------------------------------------------------------------- */ | |
1168 | |
1169 for (i = 0; i < NP + 1; i++) | |
1170 { | |
1171 pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], | |
1172 swRxDTXState); | |
1173 } | |
1174 | |
1175 | |
1176 /* Use interpolated LPC for this frame, overwrite the input K's */ | |
1177 /* ------------------------------------------------------------ */ | |
1178 | |
1179 aFlatRcDp(pL_CorrSeq, pswNewKs); | |
1180 | |
1181 } | |
1182 else | |
1183 { | |
1184 /* in between SID frames / invalid SID frames */ | |
1185 /* ------------------------------------------ */ | |
1186 | |
1187 swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); | |
1188 | |
1189 | |
1190 /* linearly interpolate between the two sets of correlation coefs */ | |
1191 /* -------------------------------------------------------------- */ | |
1192 | |
1193 for (i = 0; i < NP + 1; i++) | |
1194 { | |
1195 pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], | |
1196 swRxDTXState); | |
1197 } | |
1198 | |
1199 | |
1200 /* Use interpolated LPC for this frame, overwrite the input K's */ | |
1201 /* ------------------------------------------------------------ */ | |
1202 | |
1203 aFlatRcDp(pL_CorrSeq, pswNewKs); | |
1204 | |
1205 } | |
1206 } | |
1207 | |
1208 | |
1209 /************************************************************************* | |
1210 * | |
1211 * FUNCTION NAME: linInterpSid | |
1212 * | |
1213 * PURPOSE: | |
1214 * | |
1215 * Linearly interpolate between two input numbers based on what the | |
1216 * current DtxState is. | |
1217 * | |
1218 * INPUTS: | |
1219 * | |
1220 * L_New - longword more current value | |
1221 * | |
1222 * L_Old - longword oldest value | |
1223 * | |
1224 * swDtxState - state is 0 at the transmitted SID Frame. | |
1225 * | |
1226 * | |
1227 * OUTPUTS: | |
1228 * | |
1229 * none | |
1230 * | |
1231 * RETURN VALUE: | |
1232 * | |
1233 * A value between old and new inputs with dtxState+1/12 of the new | |
1234 * (dtxState+1)-12/12 of the old | |
1235 * | |
1236 * | |
1237 *************************************************************************/ | |
1238 | |
1239 Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState) | |
1240 { | |
1241 | |
1242 /*_________________________________________________________________________ | |
1243 | | | |
1244 | Automatic Variables | | |
1245 |_________________________________________________________________________| | |
1246 */ | |
1247 | |
1248 Shortword swOldFactor; | |
1249 | |
1250 | |
1251 /*_________________________________________________________________________ | |
1252 | | | |
1253 | Executable Code | | |
1254 |_________________________________________________________________________| | |
1255 */ | |
1256 | |
1257 /* old factor = (1.0 - newFactor) */ | |
1258 /* ------------------------------ */ | |
1259 | |
1260 swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); | |
1261 swOldFactor = add(0x1, swOldFactor); | |
1262 | |
1263 | |
1264 /* contributions from new and old */ | |
1265 /* ------------------------------ */ | |
1266 | |
1267 L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]); | |
1268 L_Old = L_mpy_ls(L_Old, swOldFactor); | |
1269 | |
1270 return (L_add(L_New, L_Old)); | |
1271 | |
1272 } | |
1273 | |
1274 | |
1275 /************************************************************************* | |
1276 * | |
1277 * FUNCTION NAME: linInterpSidShort | |
1278 * | |
1279 * PURPOSE: | |
1280 * | |
1281 * Linearly interpolate between two input numbers based on what | |
1282 * the current DtxState is. | |
1283 * | |
1284 * INPUTS: | |
1285 * | |
1286 * swNew - 16 bit, more current value | |
1287 * | |
1288 * swOld - 16 bit, oldest value | |
1289 * | |
1290 * swDtxState - state is 0 at the transmitted SID Frame. | |
1291 * | |
1292 * | |
1293 * OUTPUTS: | |
1294 * | |
1295 * none | |
1296 * | |
1297 * RETURN VALUE: | |
1298 * | |
1299 * A value between old and new inputs with dtxState+1/12 of the new | |
1300 * (dtxState+1)-12/12 of the old | |
1301 * | |
1302 *************************************************************************/ | |
1303 | |
1304 Shortword linInterpSidShort(Shortword swNew, Shortword swOld, | |
1305 Shortword swDtxState) | |
1306 { | |
1307 | |
1308 /*_________________________________________________________________________ | |
1309 | | | |
1310 | Automatic Variables | | |
1311 |_________________________________________________________________________| | |
1312 */ | |
1313 | |
1314 Shortword swOldFactor; | |
1315 Longword L_New, | |
1316 L_Old; | |
1317 | |
1318 | |
1319 /*_________________________________________________________________________ | |
1320 | | | |
1321 | Executable Code | | |
1322 |_________________________________________________________________________| | |
1323 */ | |
1324 | |
1325 /* old factor = (1.0 - newFactor) */ | |
1326 /* ------------------------------ */ | |
1327 | |
1328 swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); | |
1329 swOldFactor = add(0x1, swOldFactor); | |
1330 | |
1331 | |
1332 /* contributions from new and old */ | |
1333 /* ------------------------------ */ | |
1334 | |
1335 L_New = L_mult(swNew, psrCNNewFactor[swDtxState]); | |
1336 L_Old = L_mult(swOld, swOldFactor); | |
1337 | |
1338 | |
1339 return (round(L_add(L_New, L_Old))); | |
1340 | |
1341 } |