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 }