comparison sp_sfrm.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: sp_sfrm.c
4 *
5 * Purpose: Contains all functions for subframe based processing in the
6 * speech encoder. Subframe based processing determines the synthetic
7 * LPC excitation signal, which is composed of the adaptive codebook
8 * (long-term predictor) vector (in voiced modes), the vector-sum
9 * codebook vector (two of these in unvoiced mode), and the vector-
10 * quantized gains applied to these vectors.
11 *
12 * Below is a listing of all the functions appearing in the file.
13 * The functions are arranged according to their purpose. Under
14 * each heading, the ordering is hierarchical.
15 *
16 * sfrmAnalysis
17 * decorr
18 * closedLoopLagSearch
19 * hnwFilt
20 * g_quant_vl
21 * g_corr2
22 * gainTweak
23 * v_srch
24 *
25 *
26 ***************************************************************************/
27 /*_________________________________________________________________________
28 | |
29 | Include Files |
30 |_________________________________________________________________________|
31 */
32
33 #include <stdio.h>
34 #include "mathhalf.h"
35 #include "sp_rom.h"
36 #include "sp_dec.h"
37 #include "sp_frm.h"
38 #include "sp_sfrm.h"
39
40 /*_________________________________________________________________________
41 | |
42 | Local Defines |
43 |_________________________________________________________________________|
44 */
45
46 #define CG_INT_MACS 6
47 #define C_BITS_UV 7
48 #define C_BITS_UV_1 C_BITS_UV-1
49 #define C_BITS_V 9
50 #define C_BITS_V_1 C_BITS_V-1
51 #define DELTA_LEVELS 16
52 #define GSP0_NUM 32
53 #define GSP0_VECTOR_SIZE 5
54 #define GTWEAKMAX 0x5A82 /* sqrt(2)/2 */
55 #define LMAX 142
56 #define LSMAX (LMAX + CG_INT_MACS/2)
57 #define HNW_BUFF_LEN LSMAX
58 #define LSP_MASK 0xffff
59 #define LTP_LEN 147 /* maximum ltp lag */
60 #define MAX_CANDIDATE 6 /* maximum number of lag candidates */
61
62
63 /*_________________________________________________________________________
64 | |
65 | State variables (globals) |
66 |_________________________________________________________________________|
67 */
68
69 Shortword pswLtpStateBase[LTP_LEN + S_LEN];
70 Shortword pswHState[NP];
71 Shortword pswHNWState[HNW_BUFF_LEN];
72
73 /***************************************************************************
74 *
75 * FUNCTION NAME: closedLoopLagSearch
76 *
77 * PURPOSE:
78 *
79 * Performs the closed loop search of a list of candidate lags to
80 * determine the best fractional lag.
81 *
82 * INPUTS:
83 *
84 * pswLagList[0:iNumLags] - list of candidate lags
85 * iNumLags - number of candidate lags in LagList
86 * pswLtpState[0:5] - array of past excitations (LTP state)
87 * pswHCoefs[0:9] - coefficient array of spectral weighting filter
88 * pswPVect[0:39] - speech sub frame data
89 *
90 * OUTPUTS:
91 *
92 * pswLag - pointer to put best lag from list of candidates
93 * *pswLtpShift - Number of shifts applied to weighted LTP vector.
94 *
95 * RETURN VALUE:
96 *
97 * siLagCode - code corresponding to the best lag
98 *
99 * IMPLEMENTATION:
100 *
101 * Generate excitation vectors for all candidate lags. Find the candidate
102 * lag that maximizes C**2/G using the calculated excitation.
103 *
104 * DESCRIPTION:
105 *
106 * The function closedLoopLagSearch() searches a very small subset of the
107 * available LTP lags. The lags to be searched are defined by the open
108 * loop lag search. This information is passed in as a list of
109 * oversampled lag values. These values are translated into LTP
110 * vectors extracted from the LTP history.
111 *
112 * GSM document 06.20's b sub L prime variable is called
113 * ppswTVect[L][n] in the C code. The document's variable p(n) is
114 * named pswPVect[] in the C code.
115 *
116 * The function performs a simple maximization of the cross correlation
117 * of the weighted LTP vector and the weighted speech vector divided
118 * by the autocorrelation of the weighted LTP vector. The function is
119 * encumbered slightly by the necessity of scaling.
120 *
121 * REFERENCE: Sub-clause 4.1.8.5 of GSM Recommendation 06.20
122 *
123 * KEYWORDS: closed loop, LTP lag search, adaptive codebook search
124 *
125 **************************************************************************/
126
127 int closedLoopLagSearch(Shortword pswLagList[], int iNumLags,
128 Shortword pswLtpState[], Shortword pswHCoefs[],
129 Shortword pswPVect[],
130 Shortword *pswLag, Shortword *pswLtpShift)
131 {
132
133 /*_________________________________________________________________________
134 | |
135 | Automatic Variables |
136 |_________________________________________________________________________|
137 */
138
139 Longword L_Energy,
140 L_ccNorm,
141 L_cgNorm,
142 L_CrossCorr;
143 Longword pL_CCBuf[MAX_CANDIDATE],
144 pL_CGBuf[MAX_CANDIDATE];
145 Shortword swCCMax,
146 swCCShiftCnt,
147 swCGShiftCnt,
148 swGMax,
149 swLTPEnergy,
150 swSampleA,
151 pswCCBuf[MAX_CANDIDATE],
152 pswCGBuf[MAX_CANDIDATE],
153 ppswTVect[N_SUB][S_LEN];
154 Shortword i,
155 j,
156 siLagOffset,
157 siLagCode;
158
159 /*_________________________________________________________________________
160 | |
161 | Executable Code |
162 |_________________________________________________________________________|
163 */
164
165
166 *pswLtpShift = 0; /* Energy in weighted ltp vector =
167 * [0..0x7ff] */
168 for (i = 0; i < iNumLags; i++)
169 {
170
171 /* Construct the excitation vector for lag i */
172 /* ----------------------------------------- */
173
174 fp_ex(pswLagList[i], &pswLtpState[LTP_LEN]);
175
176 /* Perform all pole filtering */
177 /* -------------------------- */
178
179 lpcZsIir(&pswLtpState[LTP_LEN], pswHCoefs, ppswTVect[i]);
180 }
181
182 /* scale the pitch vector s.t. its energy is strictly */
183 /* less than 1.0 */
184 /*----------------------------------------------------*/
185
186 swSampleA = shr(ppswTVect[0][0], 2);
187 L_Energy = L_mac(0x001dff4cL, swSampleA, swSampleA);
188 for (j = 1; j < S_LEN; j++)
189 {
190 swSampleA = shr(ppswTVect[0][j], 2);
191 L_Energy = L_mac(L_Energy, swSampleA, swSampleA);
192 }
193
194 /* add in the energy of the first sample of the subsequent lags */
195 /*--------------------------------------------------------------*/
196
197 for (i = 1; i < iNumLags; i++)
198 {
199 swSampleA = shr(ppswTVect[i][0], 2);
200 L_Energy = L_mac(L_Energy, swSampleA, swSampleA);
201 }
202
203 /* An upper bound on the weighted pitch vectors energy */
204 /*-----------------------------------------------------*/
205
206 swLTPEnergy = round(L_Energy);
207
208 if (sub(swLTPEnergy, 0x07ff) > 0)
209 { /* E = (0x7ff.. 0x7fff] */
210 if (sub(swLTPEnergy, 0x1fff) > 0)
211 {
212 *pswLtpShift = 2; /* E = (0x1fff..0x7fff] */
213 }
214 else
215 {
216 *pswLtpShift = 1; /* E = (0x7ff.. 0x1fff] */
217 }
218
219 }
220
221 for (i = 0; i < iNumLags; i++)
222 {
223
224 /* shift all vectors down s.t. the largest is has energy < 1.0 */
225 /*-------------------------------------------------------------*/
226
227 for (j = 0; j < S_LEN; j++)
228 ppswTVect[i][j] = shr(ppswTVect[i][j], *pswLtpShift);
229
230 /* Calculate the energy of the subframe */
231 /* ------------------------------------ */
232
233 L_Energy = L_mult(ppswTVect[i][0], ppswTVect[i][0]);
234 for (j = 1; j < S_LEN; j++)
235 L_Energy = L_mac(L_Energy, ppswTVect[i][j], ppswTVect[i][j]);
236
237 pL_CGBuf[i] = L_Energy;
238
239 /* Cross correlate the normalized speech frame and the filtered
240 * subframe */
241 /* ---------------------------------------------------------------------
242 * */
243
244 L_CrossCorr = L_mult(ppswTVect[i][0], pswPVect[0]);
245 for (j = 1; j < S_LEN; j++)
246 L_CrossCorr = L_mac(L_CrossCorr, ppswTVect[i][j], pswPVect[j]);
247
248 pL_CCBuf[i] = L_CrossCorr;
249
250 }
251
252 /* find the shift count associated with the largest CC and G */
253 /* ---------------------------------------------------------- */
254 L_ccNorm = L_abs(pL_CCBuf[0]);
255 L_cgNorm = pL_CGBuf[0];
256
257 for (i = 1; i < iNumLags; i++)
258 {
259 L_ccNorm |= L_abs(pL_CCBuf[i]);
260 L_cgNorm |= pL_CGBuf[i];
261 }
262
263 swCCShiftCnt = norm_l(L_ccNorm);
264 swCGShiftCnt = norm_l(L_cgNorm);
265
266 for (i = 0; i < iNumLags; i++)
267 {
268 pswCCBuf[i] = round(L_shl(pL_CCBuf[i], swCCShiftCnt));
269 pswCGBuf[i] = round(L_shl(pL_CGBuf[i], swCGShiftCnt));
270 }
271
272 /* Maximize C**2/G */
273 /* --------------- */
274 siLagOffset = maxCCOverGWithSign(pswCCBuf, pswCGBuf,
275 &swCCMax, &swGMax,
276 iNumLags);
277
278 /* Determine the offset of the max value into CC buffer */
279 /* ---------------------------------------------------- */
280 *pswLag = pswLagList[siLagOffset];
281
282 /* Store Lag Code for best lag result */
283 /* ---------------------------------- */
284 quantLag(*pswLag, &siLagCode);
285
286 return (siLagCode);
287 }
288
289 /*****************************************************************************
290 *
291 * FUNCTION NAME: decorr
292 *
293 * PURPOSE: Decorrelates(orthogonalizes) a set of vectors from a given
294 * vector.
295 *
296 *
297 * INPUTS: iNumVects - number of vectors to decorrelate
298 * pswGivenVect[0..39] - array of given vectors
299 * pswVects[0..359] (voice) [0..279] (unvoiced) - array of
300 * contiguous vectors to be decorrelated
301 * OUTPUTS: pswVects[0..359] (voice) [0..279] (unvoiced) - output vectors
302 * are written back over input vectors
303 *
304 * RETURN VALUE: none
305 *
306 * IMPLEMENTATION:
307 *
308 * REFERENCE: Sub-clause 4.1.10.1 of GSM Recommendation 06.20
309 *
310 * KEYWORDS: decorrelate, codewords, codevectors, orthogonalize, encoder
311 *
312 ****************************************************************************/
313
314 void decorr(int iNumVects, Shortword pswGivenVect[],
315 Shortword pswVects[])
316 {
317
318 /*___________________________________________________________________________
319 | |
320 | Automatic Variables |
321 |___________________________________________________________________________|
322 */
323 int i,
324 iLoopCnt;
325 Shortword swNorm_energy,
326 swTemp;
327 Shortword swEShift,
328 swCShift,
329 swShiftSum,
330 swQShift;
331 Longword L_Energy,
332 L_Temp1,
333 L_Temp2,
334 L_Accum;
335
336 /*___________________________________________________________________________
337 | |
338 | Executable Code |
339 |___________________________________________________________________________|
340 */
341
342 /* Compute normalized energy in given vector */
343 /*-------------------------------------------*/
344 swEShift = g_corr1(pswGivenVect, &L_Energy);
345 swNorm_energy = extract_h(L_Energy);
346
347 if (swNorm_energy == 0)
348 {
349 return;
350 }
351
352 /* Decorrelate vectors */
353 /*---------------------*/
354
355 for (iLoopCnt = 0; iLoopCnt < iNumVects; iLoopCnt++)
356 {
357
358 swCShift = g_corr2(pswGivenVect, &pswVects[iLoopCnt * S_LEN],
359 &L_Temp1);
360 L_Temp2 = L_Temp1;
361 L_Temp1 = L_abs(L_Temp1);
362 swCShift = sub(swCShift, 1);
363 swShiftSum = sub(swCShift, swEShift);
364 L_Temp1 = L_shr(L_Temp1, 1);
365 swTemp = divide_s(round(L_Temp1), swNorm_energy);
366
367 if (L_Temp2 > 0)
368 swTemp = negate(swTemp);
369
370 swQShift = norm_s(swTemp);
371 swTemp = shl(swTemp, swQShift);
372 swQShift = add(swShiftSum, swQShift);
373
374 if (swQShift > 0)
375 {
376 swTemp = shift_r(swTemp, negate(swQShift));
377 swQShift = 0;
378 }
379 else
380 swQShift = negate(swQShift);
381
382 for (i = 0; i < S_LEN; i++)
383 {
384 L_Accum = L_msu(0x00008000L, pswVects[i + iLoopCnt * S_LEN], SW_MIN);
385 pswVects[iLoopCnt * S_LEN + i] = extract_h(L_mac(L_Accum, swTemp,
386 shl(pswGivenVect[i], swQShift)));
387 }
388 }
389 }
390
391 /***************************************************************************
392 *
393 * FUNCTION NAME: g_corr2
394 *
395 * PURPOSE: Calculates correlation between subframe vectors.
396 *
397 *
398 * INPUT:
399 *
400 * pswIn[0:39]
401 * A subframe vector.
402 *
403 * pswIn2[0:39]
404 * A subframe vector.
405 *
406 *
407 * OUTPUT:
408 *
409 * *pL_out
410 * A Longword containing the normalized correlation
411 * between the input vectors.
412 *
413 * RETURN:
414 *
415 * swOut
416 * Number of right shifts which the accumulator was
417 * shifted to normalize it. Negative number implies
418 * a left shift, and therefore an energy larger than
419 * 1.0.
420 *
421 * REFERENCE: Sub-clauses 4.1.10.1 and 4.1.11.1 of GSM
422 * Recommendation 06.20
423 *
424 * keywords: energy, autocorrelation, correlation, g_corr2
425 *
426 *
427 **************************************************************************/
428
429 Shortword g_corr2(Shortword *pswIn, Shortword *pswIn2,
430 Longword *pL_out)
431 {
432
433 /*_________________________________________________________________________
434 | |
435 | Automatic Variables |
436 |_________________________________________________________________________|
437 */
438
439 Longword L_sum;
440 Shortword swEngyLShft;
441 int i;
442
443 /*_________________________________________________________________________
444 | |
445 | Executable Code |
446 |_________________________________________________________________________|
447 */
448
449 /* Calculate energy in subframe vector (40 samples) */
450 /*--------------------------------------------------*/
451
452 L_sum = L_mult(pswIn[0], pswIn2[0]);
453 for (i = 1; i < S_LEN; i++)
454 {
455 L_sum = L_mac(L_sum, pswIn[i], pswIn2[i]);
456 }
457
458
459
460 if (L_sum != 0)
461 {
462
463 /* Normalize the energy in the output Longword */
464 /*---------------------------------------------*/
465
466 swEngyLShft = norm_l(L_sum);
467 *pL_out = L_shl(L_sum, swEngyLShft); /* normalize output
468 * Longword */
469 }
470 else
471 {
472
473 /* Special case: energy is zero */
474 /*------------------------------*/
475
476 *pL_out = L_sum;
477 swEngyLShft = 0;
478 }
479
480 return (swEngyLShft);
481 }
482
483 /***************************************************************************
484 *
485 * FUNCTION NAME: g_quant_vl
486 *
487 * PURPOSE:
488 *
489 * Joint quantization of excitation gains.
490 * GS represents the subframe energy relative to the frame energy.
491 * P0 represents the relative contribution of the first exctitation
492 * source to the total excitation.
493 *
494 * INPUTS:
495 *
496 * swUVCode - voicing level (Mode 0-3)
497 * pswWInput[0:39] - weighted input p(n) (used in mode 0-3)
498 * swWIShift - weighted input shift factor (right shift, 0,1, or 2)
499 * pswWLTPVec[0:39] - weighted pitch excitation vector (used in mode 1-3)
500 * pswWVSVec1[0:39] - weighted 1st v-s codevector (used in mode 0-3)
501 * pswWVSVec2[0:39] - weighted 2nd v-s codevector (used in mode 0)
502 * snsRs00 - square root of RS/pitch excitation energy (used in mode 1-3)
503 * snsRs11 - square root of RS/1st v-s codevector energy
504 * (used in mode 0-3)
505 * snsRs22 - square root of RS/2nd v-s codevector energy (used in mode 0)
506 *
507 * pppsrGsp0[0:3][0:31][0:4] - lookup table
508 *
509 * OUTPUTS:
510 *
511 * None
512 *
513 * RETURN VALUE:
514 *
515 * siCode - output quantized gain code (5 bits)
516 *
517 * IMPLEMENTATION:
518 *
519 * Calculates first the parameters required for error equation 7.21:
520 *
521 * Rcc(k,j) k = 0,1, j=k,1
522 * Rx(k) k = 0,1
523 * RS
524 * Rpc(k) k = 0,1
525 * a,b,c,d,e
526 *
527 * The constant terms in equation 7.21 are stored in ROM instead of GS
528 * and P0. There is one vector quantizer for each voicing state.
529 *
530 * REFERENCE: Sub-clause 4.1.11 and 4.1.11.1 of GSM Recommendation 06.20
531 *
532 * KEYWORDS: gain quantization, energy domain transforms, p0, gs
533 *
534 **************************************************************************/
535
536 Shortword g_quant_vl(Shortword swUVCode,
537 Shortword pswWInput[], Shortword swWIShift,
538 Shortword pswWLTPVec[],
539 Shortword pswWVSVec1[], Shortword pswWVSVec2[],
540 struct NormSw snsRs00, struct NormSw snsRs11,
541 struct NormSw snsRs22)
542 {
543
544 /*_________________________________________________________________________
545 | |
546 | Automatic Variables |
547 |_________________________________________________________________________|
548 */
549
550 Longword L_Temp,
551 L_Temp2;
552 Shortword swShift;
553 struct NormSw ErrorTerm[6];
554 Shortword i,
555 siCode,
556 siNormShift,
557 siNormMin;
558
559 /*_________________________________________________________________________
560 | |
561 | Executable Code |
562 |_________________________________________________________________________|
563 */
564
565 /* Test voicing level, mode 0-3 */
566 /* ---------------------------- */
567
568 if (swUVCode == 0)
569 {
570
571 /* Unvoiced */
572 /* -------- */
573
574 /* Compute cross correlation Rpc(0) */
575 /* -------------------------------- */
576
577
578 ErrorTerm[0].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
579 ErrorTerm[0].man = round(L_Temp);
580
581 /* Compute cross correlation Rpc(1) */
582 /* -------------------------------- */
583
584 ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec2, &L_Temp);
585 ErrorTerm[1].man = round(L_Temp);
586
587 /* Compute cross correlation Rcc(0,1) */
588 /* ---------------------------------- */
589
590
591 ErrorTerm[2].sh = g_corr2(pswWVSVec1, pswWVSVec2, &L_Temp);
592 ErrorTerm[2].man = round(L_Temp);
593
594 /* Compute correlation Rcc(0,0) */
595 /* ---------------------------- */
596
597 ErrorTerm[3].sh = g_corr1(pswWVSVec1, &L_Temp);
598 ErrorTerm[3].man = round(L_Temp);
599
600 /* Compute correlation Rcc(1,1) */
601 /* ---------------------------- */
602
603 ErrorTerm[4].sh = g_corr1(pswWVSVec2, &L_Temp);
604 ErrorTerm[4].man = round(L_Temp);
605
606 /* Compute correlation Rpp */
607 /* ----------------------- */
608
609 ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
610 ErrorTerm[5].man = round(L_Temp);
611
612 /* Compute gain tweak factor, adjusts A and B error coefs */
613 /* ------------------------------------------------------ */
614 gainTweak(&ErrorTerm[0]);
615
616 /* Compute error coefficient A, equation 5.22 */
617 /* ------------------------------------------ */
618
619 L_Temp = L_mult(ErrorTerm[0].man, snsRs11.man);
620 swShift = norm_s(extract_h(L_Temp));
621 ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
622 ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
623 ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs11.sh);
624 siNormMin = ErrorTerm[0].sh;
625
626 /* Compute error coefficient B, equation 5.23 */
627 /* ------------------------------------------ */
628
629 L_Temp = L_mult(ErrorTerm[1].man, snsRs22.man);
630 swShift = norm_s(extract_h(L_Temp));
631 ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift);
632 ErrorTerm[1].man = round(L_shl(L_Temp, swShift));
633 ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs22.sh);
634 if (sub(ErrorTerm[1].sh, siNormMin) < 0)
635 siNormMin = ErrorTerm[1].sh;
636
637 /* Compute error coefficient C, equation 5.24 */
638 /* ------------------------------------------ */
639
640 L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man);
641 swShift = norm_s(extract_h(L_Temp));
642 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
643 ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
644 L_Temp = L_mult(ErrorTerm[2].man, snsRs22.man);
645 swShift = norm_s(extract_h(L_Temp));
646 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
647 ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
648 ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh);
649 ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs22.sh);
650 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift);
651 if (sub(ErrorTerm[2].sh, siNormMin) < 0)
652 siNormMin = ErrorTerm[2].sh;
653
654 /* Compute error coefficient D, equation 5.25 */
655 /* ------------------------------------------ */
656
657 L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
658 swShift = norm_s(extract_h(L_Temp));
659 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
660 ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
661 L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
662 swShift = norm_s(extract_h(L_Temp));
663 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
664 ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
665 ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
666 ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
667 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift);
668
669 if (sub(ErrorTerm[3].sh, siNormMin) < 0)
670 siNormMin = ErrorTerm[3].sh;
671
672 /* Compute error coefficient E, equation 5.26 */
673 /* ------------------------------------------ */
674
675 L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
676 swShift = norm_s(extract_h(L_Temp));
677 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
678 ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
679 L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
680 swShift = norm_s(extract_h(L_Temp));
681 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
682 ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
683 ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
684 ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
685 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift);
686
687 if (sub(ErrorTerm[4].sh, siNormMin) < 0)
688 siNormMin = ErrorTerm[4].sh;
689
690 }
691
692 else
693 { /* Voicing level */
694
695 /* Voiced */
696 /* ------ */
697
698 /* Compute cross correlation Rpc(0) */
699 /* -------------------------------- */
700
701
702 ErrorTerm[0].sh = g_corr2(pswWInput, pswWLTPVec, &L_Temp);
703 ErrorTerm[0].man = round(L_Temp);
704
705 /* Compute cross correlation Rpc(1) */
706 /* -------------------------------- */
707
708
709 ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
710 ErrorTerm[1].man = round(L_Temp);
711
712 /* Compute cross correlation Rcc(0,1) */
713 /* ---------------------------------- */
714
715
716 ErrorTerm[2].sh = g_corr2(pswWLTPVec, pswWVSVec1, &L_Temp);
717 ErrorTerm[2].man = round(L_Temp);
718
719 /* Compute correlation Rcc(0,0) */
720 /* ---------------------------- */
721
722 ErrorTerm[3].sh = g_corr1(pswWLTPVec, &L_Temp);
723 ErrorTerm[3].man = round(L_Temp);
724
725 /* Compute correlation Rcc(1,1) */
726 /* ---------------------------- */
727
728 ErrorTerm[4].sh = g_corr1(pswWVSVec1, &L_Temp);
729 ErrorTerm[4].man = round(L_Temp);
730
731 /* Compute correlation Rpp */
732 /* ----------------------- */
733
734 ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
735 ErrorTerm[5].man = round(L_Temp);
736
737 /* Compute gain tweak factor, adjusts A and B error coefs */
738 /* ------------------------------------------------------ */
739
740 gainTweak(&ErrorTerm[0]);
741
742 /* Compute error coefficient A, equation 5.22 */
743 /* ------------------------------------------ */
744
745 L_Temp = L_mult(ErrorTerm[0].man, snsRs00.man);
746 swShift = norm_s(extract_h(L_Temp));
747 ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
748 ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
749 ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs00.sh);
750 siNormMin = ErrorTerm[0].sh;
751
752 /* Compute error coefficient B, equation 5.23 */
753 /* ------------------------------------------ */
754
755 L_Temp = L_mult(ErrorTerm[1].man, snsRs11.man);
756 swShift = norm_s(extract_h(L_Temp));
757 ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift);
758 ErrorTerm[1].man = round(L_shl(L_Temp, swShift));
759 ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs11.sh);
760 if (sub(ErrorTerm[1].sh, siNormMin) < 0)
761 siNormMin = ErrorTerm[1].sh;
762
763 /* Compute error coefficient C, equation 5.24 */
764 /* ------------------------------------------ */
765
766 L_Temp = L_mult(ErrorTerm[2].man, snsRs00.man);
767 swShift = norm_s(extract_h(L_Temp));
768 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
769 ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
770 L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man);
771 swShift = norm_s(extract_h(L_Temp));
772 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
773 ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
774 ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs00.sh);
775 ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh);
776 ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift);
777 if (sub(ErrorTerm[2].sh, siNormMin) < 0)
778 siNormMin = ErrorTerm[2].sh;
779
780 /* Compute error coefficient D, equation 5.25 */
781 /* ------------------------------------------ */
782
783 L_Temp = L_mult(ErrorTerm[3].man, snsRs00.man);
784 swShift = norm_s(extract_h(L_Temp));
785 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
786 ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
787 L_Temp = L_mult(ErrorTerm[3].man, snsRs00.man);
788 swShift = norm_s(extract_h(L_Temp));
789 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
790 ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
791 ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs00.sh);
792 ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs00.sh);
793 ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift);
794 if (sub(ErrorTerm[3].sh, siNormMin) < 0)
795 siNormMin = ErrorTerm[3].sh;
796
797 /* Compute error coefficient E, equation 5.26 */
798 /* ------------------------------------------ */
799
800 L_Temp = L_mult(ErrorTerm[4].man, snsRs11.man);
801 swShift = norm_s(extract_h(L_Temp));
802 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
803 ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
804 L_Temp = L_mult(ErrorTerm[4].man, snsRs11.man);
805 swShift = norm_s(extract_h(L_Temp));
806 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
807 ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
808 ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs11.sh);
809 ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs11.sh);
810 ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift);
811 if (sub(ErrorTerm[4].sh, siNormMin) < 0)
812 siNormMin = ErrorTerm[4].sh;
813
814 } /* Voicing level */
815
816
817
818 /* Normalize all error coefficients to same shift count */
819 /* ---------------------------------------------------- */
820
821 for (i = 0; i < GSP0_VECTOR_SIZE; i++)
822 {
823 L_Temp = L_deposit_h(ErrorTerm[i].man);
824 siNormShift = sub(ErrorTerm[i].sh, siNormMin);
825 if (siNormShift > 0)
826 L_Temp = L_shr(L_Temp, siNormShift);
827 ErrorTerm[i].man = round(L_Temp);
828 }
829
830
831 /* Codebook search, find max of error equation 5.21 */
832 /* ------------------------------------------------ */
833
834 L_Temp2 = 0x80000000;
835
836 for (i = 0; i < GSP0_NUM; i++)
837 {
838
839 L_Temp = L_mult(pppsrGsp0[swUVCode][i][0], ErrorTerm[0].man);
840 L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][1], ErrorTerm[1].man);
841 L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][2], ErrorTerm[2].man);
842 L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][3], ErrorTerm[3].man);
843 L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][4], ErrorTerm[4].man);
844 if (L_sub(L_Temp2, L_Temp) < 0)
845 {
846 L_Temp2 = L_Temp;
847 siCode = i; /* Save best code */
848 }
849 }
850 return (siCode);
851 }
852
853 /***************************************************************************
854 *
855 * FUNCTION NAME: gainTweak
856 *
857 * PURPOSE:
858 *
859 * Calculates gain bias factor, limits it, and
860 * applies it to A and B error coefficients.
861 *
862 * INPUTS:
863 *
864 * psErrorTerm[0:5] - array (6) of error coefficients in floating
865 * point format
866 *
867 * OUTPUTS:
868 *
869 * psErrorTerm[0:5] - array of gain adjusted A and B error coefficients
870 *
871 * RETURN VALUE:
872 *
873 * None
874 *
875 * IMPLEMENTATION:
876 *
877 * The gain tweak is:
878 *
879 * Rpp*Rcc(0,0)*Rcc(1,1) - Rpp*Rcc(0,1)*Rcc(0,1)
880 *sqrt(---------------------------------------------------------------------)
881 * Rcc(0,0)*Rpc(1)*Rpc(1)-2*Rcc(0,1)*Rpc(0)*Rpc(1)+Rcc(1,1)*Rpc(0)*Rpc(0)
882 *
883 * REFERENCE: Sub-clause 4.1.11.1 of GSM Recommendation 06.20
884 *
885 * KEYWORDS: gain tweak, g_quant_vl
886 *
887 **************************************************************************/
888
889 void gainTweak(struct NormSw *psErrorTerm)
890 {
891
892 /*_________________________________________________________________________
893 | |
894 | Automatic Variables |
895 |_________________________________________________________________________|
896 */
897
898 Longword L_Temp;
899 Shortword swTemp,
900 swNum,
901 swDenom,
902 swGainTweak,
903 swShift;
904 struct NormSw terms[5];
905 Shortword i,
906 siNormShift,
907 siNorm;
908
909 /*_________________________________________________________________________
910 | |
911 | Executable Code |
912 |_________________________________________________________________________|
913 */
914
915 /* Calculate third order terms in the gain tweak factor, while
916 * maintaining the largest exponent */
917 /* ---------------------------------------------------- */
918
919 /* Compute Rpp*Rcc(0,0)*Rcc(1,1) */
920 /* ----------------------------- */
921
922 L_Temp = L_mult(psErrorTerm[3].man, psErrorTerm[5].man);
923 swShift = norm_s(extract_h(L_Temp));
924 terms[0].sh = add(psErrorTerm[3].sh, swShift);
925 terms[0].man = round(L_shl(L_Temp, swShift));
926 L_Temp = L_mult(terms[0].man, psErrorTerm[4].man);
927 swShift = norm_s(extract_h(L_Temp));
928 terms[0].sh = add(terms[0].sh, swShift);
929 terms[0].man = round(L_shl(L_Temp, swShift));
930 terms[0].sh = add(terms[0].sh, psErrorTerm[4].sh);
931 terms[0].sh = add(terms[0].sh, psErrorTerm[5].sh);
932 /* Init. siNorm */
933 siNorm = terms[0].sh;
934
935 /* Compute Rpp*Rcc(0,1)*Rcc(0,1) */
936 /* ----------------------------- */
937
938 L_Temp = L_mult(psErrorTerm[2].man, psErrorTerm[2].man);
939 swShift = norm_s(extract_h(L_Temp));
940 terms[1].sh = add(psErrorTerm[2].sh, swShift);
941 terms[1].man = round(L_shl(L_Temp, swShift));
942 L_Temp = L_mult(terms[1].man, psErrorTerm[5].man);
943 swShift = norm_s(extract_h(L_Temp));
944 terms[1].sh = add(terms[1].sh, swShift);
945 terms[1].man = round(L_shl(L_Temp, swShift));
946 terms[1].sh = add(terms[1].sh, psErrorTerm[2].sh);
947 terms[1].sh = add(terms[1].sh, psErrorTerm[5].sh);
948 if (sub(terms[1].sh, siNorm) < 0)
949 siNorm = terms[1].sh;
950
951 /* Compute Rcc(0,0)*Rpc(1)*Rpc(1) */
952 /* ------------------------------ */
953
954 L_Temp = L_mult(psErrorTerm[1].man, psErrorTerm[1].man);
955 swShift = norm_s(extract_h(L_Temp));
956 terms[2].sh = add(psErrorTerm[1].sh, swShift);
957 terms[2].man = round(L_shl(L_Temp, swShift));
958 L_Temp = L_mult(terms[2].man, psErrorTerm[3].man);
959 swShift = norm_s(extract_h(L_Temp));
960 terms[2].sh = add(terms[2].sh, swShift);
961 terms[2].man = round(L_shl(L_Temp, swShift));
962 terms[2].sh = add(terms[2].sh, psErrorTerm[1].sh);
963 terms[2].sh = add(terms[2].sh, psErrorTerm[3].sh);
964 if (sub(terms[2].sh, siNorm) < 0)
965 siNorm = terms[2].sh;
966
967 /* Compute 2*Rcc(0,1)*Rpc(0)*Rpc(1) */
968 /* -------------------------------- */
969
970 L_Temp = L_mult(psErrorTerm[0].man, psErrorTerm[1].man);
971 swShift = norm_s(extract_h(L_Temp));
972 terms[3].sh = add(psErrorTerm[0].sh, swShift);
973 terms[3].man = round(L_shl(L_Temp, swShift));
974 L_Temp = L_mult(terms[3].man, psErrorTerm[2].man);
975 swShift = norm_s(extract_h(L_Temp));
976 terms[3].sh = add(terms[3].sh, swShift);
977 terms[3].man = round(L_shl(L_Temp, swShift));
978 terms[3].sh = add(terms[3].sh, psErrorTerm[1].sh);
979 terms[3].sh = add(terms[3].sh, psErrorTerm[2].sh);
980 terms[3].sh = sub(terms[3].sh, 1); /* Multiply by 2 */
981 if (sub(terms[3].sh, siNorm) < 0)
982 siNorm = terms[3].sh;
983
984 /* Compute Rcc(1,1)*Rpc(0)*Rpc(0) */
985 /* ------------------------------ */
986
987 L_Temp = L_mult(psErrorTerm[0].man, psErrorTerm[4].man);
988 swShift = norm_s(extract_h(L_Temp));
989 terms[4].sh = add(psErrorTerm[0].sh, swShift);
990 terms[4].man = round(L_shl(L_Temp, swShift));
991 L_Temp = L_mult(terms[4].man, psErrorTerm[0].man);
992 swShift = norm_s(extract_h(L_Temp));
993 terms[4].sh = add(terms[4].sh, swShift);
994 terms[4].man = round(L_shl(L_Temp, swShift));
995 terms[4].sh = add(terms[4].sh, psErrorTerm[0].sh);
996 terms[4].sh = add(terms[4].sh, psErrorTerm[4].sh);
997 if (sub(terms[4].sh, siNorm) < 0)
998 siNorm = terms[4].sh;
999
1000 /* Normalize all terms to same shift count */
1001 /* --------------------------------------- */
1002
1003 for (i = 0; i < 5; i++)
1004 {
1005 L_Temp = L_deposit_h(terms[i].man);
1006 siNormShift = sub(terms[i].sh, siNorm);
1007 if (siNormShift > 0)
1008 {
1009 L_Temp = L_shr(L_Temp, siNormShift);
1010 }
1011 terms[i].man = round(L_Temp);
1012 }
1013
1014 /* Calculate numerator */
1015 /* ------------------- */
1016
1017 /* Rpp*Rcc(0,0)*Rcc(1,1) - Rpp*Rcc(0,1)*Rcc(0,1) */
1018 /* --------------------------------------------- */
1019
1020 swNum = sub(terms[0].man, terms[1].man);
1021
1022 /* Skip gain tweak if numerator =< 0 */
1023 /* --------------------------------- */
1024
1025 if (swNum <= 0)
1026 return;
1027
1028 /* Calculate denominator */
1029 /* --------------------- */
1030
1031 /* Rcc(0,0)*Rpc(1)*Rpc(1)-2*Rcc(0,1)*Rpc(0)*Rpc(1)+Rcc(1,1)*Rpc(0)*Rpc(0) */
1032 /*----------------------------------------------------------------------*/
1033
1034 swDenom = sub(terms[2].man, terms[3].man);
1035 swDenom = add(swDenom, terms[4].man);
1036
1037 /* Skip gain tweak if denominator =< 0 */
1038 /* ----------------------------------- */
1039
1040 if (swDenom <= 0)
1041 return;
1042
1043 /* Compare numerator to denominator, skip if tweak =< 1 */
1044 /* ---------------------------------------------------- */
1045
1046 swTemp = sub(swNum, swDenom);
1047 if (swTemp <= 0)
1048 return;
1049
1050 /* Normalize and do divide */
1051 /* ----------------------- */
1052
1053 swShift = norm_s(swNum);
1054 siNormShift = sub(swShift, 1); /* Multiply by 2 */
1055 swNum = shl(swNum, swShift);
1056 swNum = shr(swNum, 1);
1057 swShift = norm_s(swDenom);
1058 siNormShift = sub(siNormShift, swShift);
1059 swDenom = shl(swDenom, swShift);
1060 swTemp = divide_s(swNum, swDenom);
1061 swShift = norm_s(swTemp);
1062 siNormShift = add(siNormShift, swShift);
1063 L_Temp = L_shl(L_deposit_h(swTemp), swShift);
1064
1065 /* Calculate square root */
1066 /* --------------------- */
1067
1068 swTemp = sqroot(L_Temp);
1069
1070 /* If odd no. of shifts compensate by sqrt(0.5) */
1071 /* -------------------------------------------- */
1072
1073 if (siNormShift & 1)
1074 {
1075 L_Temp = L_mult(0x5a82, swTemp);
1076 siNormShift = sub(siNormShift, 1);
1077 }
1078 else
1079 L_Temp = L_deposit_h(swTemp);
1080 siNormShift = shr(siNormShift, 1);
1081 swShift = norm_s(extract_h(L_Temp));
1082 siNormShift = add(siNormShift, swShift);
1083 swGainTweak = round(L_shl(L_Temp, swShift));
1084
1085 /* If exponent > -1, skip gain tweak */
1086 /* --------------------------------- */
1087
1088 if (add(1, siNormShift) > 0)
1089 return;
1090
1091 /* If exponent < -1, limit gain tweak to GTWEAKMAX */
1092 /* ----------------------------------------------- */
1093
1094 if (add(1, siNormShift) < 0)
1095 swGainTweak = GTWEAKMAX;
1096 else
1097 {
1098
1099 /* If exponent = -1, compare to GTWEAKMAX */
1100 /* -------------------------------------- */
1101
1102 if (sub(GTWEAKMAX, swGainTweak) < 0)
1103 swGainTweak = GTWEAKMAX;
1104 }
1105
1106 /* Multiply gain tweak factor on A and B error terms */
1107 /* ------------------------------------------------- */
1108
1109 L_Temp = L_mult(swGainTweak, psErrorTerm[0].man);
1110 swShift = norm_s(extract_h(L_Temp));
1111 psErrorTerm[0].sh = add(psErrorTerm[0].sh, swShift);
1112 psErrorTerm[0].sh = sub(psErrorTerm[0].sh, 1);
1113 psErrorTerm[0].man = round(L_shl(L_Temp, swShift));
1114
1115 L_Temp = L_mult(swGainTweak, psErrorTerm[1].man);
1116 swShift = norm_s(extract_h(L_Temp));
1117 psErrorTerm[1].sh = add(psErrorTerm[1].sh, swShift);
1118 psErrorTerm[1].sh = sub(psErrorTerm[1].sh, 1);
1119 psErrorTerm[1].man = round(L_shl(L_Temp, swShift));
1120
1121 }
1122
1123 /***************************************************************************
1124 *
1125 * FUNCTION NAME: hnwFilt
1126 *
1127 * PURPOSE:
1128 * Performs the filtering operation for harmonic noise weighting.
1129 *
1130 * INPUTS:
1131 * pswInSample[0:39] - array of input speech signal,
1132 * pswInSample points to the "oldest" sample of the
1133 * current subframe to be hnw filtered, S_LEN samples
1134 * will be stored in this array, this data is not
1135 * explicitly modified.
1136 *
1137 * pswState[0:183] - array of state of samples, the most
1138 * recent sample is the tail of the state buffer,
1139 * used only for full- state filtering, this data is
1140 * not modified
1141 * pswInCoef[0:5] - array of unmodified filter coefficients
1142 * iStateOffset - address offset from a sample in the subframe back
1143 * to the oldest element of the state used in the interpolating
1144 * filter for that sample. Although the subframe samples and
1145 * state information can come from different buffers, this
1146 * offset represents the case in which the state and sample
1147 * information are in the same buffer
1148 * swZeroState - indicate if the interpolating filter should be
1149 * "zero-state" filtering or "full-state" filtering:
1150 * 0 ==> zero-state filtering
1151 * !0 ==> full-state filtering
1152 * iNumSamples - the number of samples that are to be filtered,
1153 * required to be less than or equal to S_LEN in order to
1154 * correctly match speech samples with sample states for the
1155 * filtering procedure
1156 *
1157 * OUTPUTS:
1158 * pswOutSample[0:39] - array of output filtered speech signal,
1159 * pswOutSample points to the "oldest" sample location, S_LEN
1160 * filtered samples will be stored at the buffer associated with
1161 * this array, can implicitly overwrite input samples with
1162 * with filtered samples by setting pswOutSample = pswInSample
1163 *
1164 * RETURN VALUE:
1165 * none
1166 *
1167 * IMPLEMENTATION:
1168 * The harmonic noise weighting filter is implemented in reverse
1169 * temporal order, from most recent input sample backwards through
1170 * the input sample array. The procedure follows the equation:
1171 * x(n) = x(n) - PW_COEF*x(n - lag)
1172 * where the PW_COEF is the pitch weighting for the current
1173 * subframe and lag is the full-resolution lag for the current
1174 * subframe. x(n - lag) is found by implementing a CG_INT_MACS-
1175 * order FIR interpolating filter
1176 *
1177 * Harmonic noise weighting is discussed in secion 5.5.
1178 *
1179 * REFERENCE: Sub-clause 4.1.9 of GSM Recommendation 06.20
1180 *
1181 * KEYWORDS: T_SUB, LAG, HNW_FILT, PW_COEF, CG_INT_MACS, S_LEN, LSMAX
1182 *
1183 **************************************************************************/
1184
1185 void hnwFilt(Shortword pswInSample[],
1186 Shortword pswOutSample[],
1187 Shortword pswState[],
1188 Shortword pswInCoef[],
1189 int iStateOffset,
1190 Shortword swZeroState,
1191 int iNumSamples)
1192 {
1193
1194 /*_________________________________________________________________________
1195 | |
1196 | Automatic Variables |
1197 |_________________________________________________________________________|
1198 */
1199 Longword L_temp;
1200 int i,
1201 j;
1202
1203 int iStatIndx = S_LEN - 1 + iStateOffset;
1204 int iStatIndx1 = S_LEN + iStateOffset;
1205
1206 /*_________________________________________________________________________
1207 | |
1208 | Executable Code |
1209 |_________________________________________________________________________|
1210 */
1211
1212 if (swZeroState == 0)
1213 {
1214
1215 /* zero state response assumes input and output arrays are the same */
1216 /*------------------------------------------------------------------*/
1217
1218 for (i = 0; i < iNumSamples; i++)
1219 {
1220
1221 /* get input with rounding */
1222 /*-------------------------*/
1223 L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000);
1224
1225 for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--)
1226 /* evaluate taps 1 - 6 that point to input */
1227 /*-----------------------------------------*/
1228 L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]);
1229
1230 pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1));
1231 }
1232 }
1233 else
1234 {
1235 for (i = 0; i < iNumSamples; i++)
1236 {
1237
1238 /* get input with rounding */
1239 /*-------------------------*/
1240 L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000);
1241
1242 for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--)
1243 /* evaluate taps 1 - 6 that point to input */
1244 /*-----------------------------------------*/
1245 L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]);
1246
1247 for (; (j >= 0); j--)
1248 /* evaluate taps 1 - 6 that point to state */
1249 /*----------------------------------------*/
1250 L_temp = L_mac(L_temp, pswState[iStatIndx1 - i + j], pswInCoef[j]);
1251
1252 pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1));
1253 }
1254 }
1255
1256 }
1257
1258 /***************************************************************************
1259 *
1260 * FUNCTION NAME: sfrmAnalysis
1261 *
1262 * PURPOSE:
1263 *
1264 * Determines the synthetic excitation for a subframe.
1265 *
1266 * INPUTS:
1267 *
1268 * pswWSpeech
1269 * Input weighted speech vector to be matched.
1270 *
1271 * swVoicingMode
1272 *
1273 * Voicing mode 0,1,2 or 3. 0 is unvoiced. A
1274 * frame parameter.
1275 *
1276 * snsSqrtRs
1277 *
1278 * Normalized estimate of the excitation energy
1279 *
1280 * pswHCoefs
1281 *
1282 * Coefficientss used in weighted synthesis filter,
1283 * H(z), (a negated version is used). pswHCoefs[0]
1284 * is t=-1 tap, pswHCoefs[9] is t=-10 tap.
1285 *
1286 * pswLagList
1287 *
1288 * List of lags to be searched in the long-term
1289 * predictor, determined by the open-loop lag search.
1290 *
1291 * siNumLags
1292 *
1293 * Number of lags in pswLagList.
1294 *
1295 * swPitch
1296 *
1297 * Fundamental pitch value to be used in harmonic-
1298 * noise-weighting, actualPitch*OS_FCTR.
1299 *
1300 * swHNWCoef
1301 * Coefficient of the harmonic-noise-weighting filter.
1302 *
1303 * ppsrCGIntFilt[0:5][0:5]
1304 *
1305 * polyphase interpolation filter,
1306 * ppsrCGIntFilt[iTap][iPhase], OS_FCTR phases,
1307 * CG_INT_MACS taps per phase. Used to construct
1308 * sequences delayed by fractional lags for Harmonic-
1309 * Noise-Weighting.
1310 *
1311 * pppsrUvCodeVec[0:1][0:6][0:39]
1312 *
1313 * unvoiced codebooks:
1314 * pppsrUvCodeVec[codeBook][vectorNumber][time]
1315 *
1316 * pppsrVcdCodeVec[0][0:8][0:39]
1317 *
1318 * voiced codebook:
1319 * pppsrVcdCodeVect[codebook(=0)][vectorNumber][time]
1320 *
1321 * swSP
1322 * speech flag (DTX mode)
1323 *
1324 * OUTPUTS:
1325 *
1326 * psiLagCode
1327 *
1328 * Lag code: frame- or delta-, or zero if unvoiced.
1329 *
1330 * psiVSCode1
1331 *
1332 * First vector-sum codebook code.
1333 *
1334 * psiVSCode2
1335 *
1336 * Second vector-sum codebook code, or zero if voiced.
1337 *
1338 * psiGsp0Code
1339 *
1340 * Gain quantizer code.
1341 *
1342 * DESCRIPTION:
1343 *
1344 * sfrmAnalysis() is the calling function for the subframe analysis
1345 * functions. All subframe based processing is done by it and its
1346 * daughter functions. All functions in this file are called by
1347 * sfrmAnalysis() or one of its daughter functions. As can be seen
1348 * above, this routine will select the LTP lag, the VSELP
1349 * codevector(s) and the GSP0 codeword. It is called by
1350 * speechEncoder().
1351 *
1352 * The subframe processing can follow one of two paths depending on
1353 * whether the frame is voiced or unvoiced. These two paths are now
1354 * described.
1355 *
1356 * First the zero input response of H(z) is calculated (lpcZiIir());
1357 * then subtracted from the weighted speech (W(z)). The outcome, p(n)
1358 * or pswWSVec[], will be the vector matched by the first excitation
1359 * vector (either adaptive or first VSELP codevector). The p(n)
1360 * vector is scaled to prevent overflow.
1361 *
1362 * If the frame is voiced, the closed loop lag search (closedLoop())
1363 * is performed. An adaptive codevector lag is selected. Using the
1364 * open loop "pitch" value, the harmonic noise weighting
1365 * coefficients are obtained. The adaptive codevector is
1366 * reconstructed (fp_ex()), and weighted through the (zero state)
1367 * spectral (lpcZsIir()) and harmonic noise weighting filters
1368 * (hnwFilt()).
1369 *
1370 * The basis vectors are also filtered through the weighting
1371 * filters. If the frame is unvoiced, there is no spectral noise
1372 * weighting.
1373 *
1374 * If voiced the VSELP basis vectors are decorrelated (decorr())
1375 * from the selected adaptive (LTP) codevector, and the VSELP
1376 * codevector search is initiated (v_srch()).
1377 *
1378 * If unvoiced, the first VSELP codevector search is performed
1379 * (without any decorrelation). After a vector from the first VSELP
1380 * codebook has been selected, the second set of basis vectors are
1381 * decorrelated from the selected vector.
1382 *
1383 * Once all the excitation vectors have been selected, the gain
1384 * quantizer is called, g_quant_vl().
1385 *
1386 * Finally, once all subframe parameters have been found, the
1387 * selected excitation is scaled according to GSP0 (scaleExcite()),
1388 * and the composite excitation is entered into the long term
1389 * predictor history. The final excitation is also used to update
1390 * H(z) and C(z).
1391 *
1392 * REFERENCE: Sub-clauses 4.1.8.5, 4.1.9 - 4.1.12 of GSM
1393 * Recommendation 06.20
1394 *
1395 * Keywords: codewords, lag, codevectors, gsp0, decoding, analysis, t_sub
1396 *
1397 **************************************************************************/
1398
1399 void sfrmAnalysis(Shortword *pswWSpeech,
1400 Shortword swVoicingMode,
1401 struct NormSw snsSqrtRs,
1402 Shortword *pswHCoefs,
1403 Shortword *pswLagList,
1404 short siNumLags,
1405 Shortword swPitch,
1406 Shortword swHNWCoef,
1407 short *psiLagCode,
1408 short *psiVSCode1,
1409 short *psiVSCode2,
1410 short *psiGsp0Code,
1411 Shortword swSP)
1412 {
1413
1414 /*_________________________________________________________________________
1415 | |
1416 | Static Variables |
1417 |_________________________________________________________________________|
1418 */
1419
1420 static short siPrevLagCode;
1421
1422 /*_________________________________________________________________________
1423 | |
1424 | Automatic Variables |
1425 |_________________________________________________________________________|
1426 */
1427
1428 short i,
1429 j,
1430 siCode,
1431 siIntPitch,
1432 siRemainder;
1433 short siHnwOffset,
1434 siHnwNum,
1435 siNumBasisVecs;
1436
1437 Shortword swLag,
1438 swPnEnergy,
1439 swPnShift,
1440 swSampleA;
1441 Shortword swLtpShift;
1442
1443 Longword L_PnEnergy;
1444
1445 struct NormSw snsRs00,
1446 snsRs11,
1447 snsRs22;
1448
1449 Shortword pswWSVec[S_LEN],
1450 pswTempVec[S_LEN];
1451 Shortword pswPVec[S_LEN],
1452 pswWPVec[S_LEN];
1453 Shortword ppswVselpEx[2][S_LEN],
1454 ppswWVselpEx[2][S_LEN];
1455 Shortword pswWBasisVecs[9 * S_LEN],
1456 pswBitArray[9];
1457 Shortword pswHNWCoefs[CG_INT_MACS];
1458
1459 Shortword *pswLtpStateOut;
1460
1461 /*_________________________________________________________________________
1462 | |
1463 | Executable Code |
1464 |_________________________________________________________________________|
1465 */
1466
1467 pswLtpStateOut = pswLtpStateBase + LTP_LEN;
1468
1469 if (swSP == 1) /* DTX mode */
1470 { /* DTX mode */
1471
1472 /* if not in CNI mode */
1473 /*--------------------*/
1474
1475 /* Get the zero-input response of H(z) */
1476 /*-------------------------------------*/
1477
1478 lpcZiIir(pswHCoefs, pswHState, pswTempVec);
1479
1480 /* Subtract the zero-input response of H(z) from W(z)-weighted speech. */
1481 /* The result is the vector to match for the adaptive codebook (long- */
1482 /* term-predictor) search in voiced modes, or the vector to match for */
1483 /* all synthetic excitation searches in unvoiced mode. */
1484 /*---------------------------------------------------------------------*/
1485
1486 for (i = 0; i < S_LEN; i++)
1487 {
1488
1489 pswWSVec[i] = sub(pswWSpeech[i], pswTempVec[i]);
1490 }
1491
1492 /* scale the weighted speech vector (p[n]) s.t. its energy is strictly */
1493 /* less than 1.0 */
1494 /*---------------------------------------------------------------------*/
1495
1496 swSampleA = shr(pswWSVec[0], 2);
1497 L_PnEnergy = L_mac(0x001dff4cL, swSampleA, swSampleA);
1498 for (i = 1; i < S_LEN; i++)
1499 {
1500 swSampleA = shr(pswWSVec[i], 2); /* reduces energy by 16 */
1501 L_PnEnergy = L_mac(L_PnEnergy, swSampleA, swSampleA);
1502 }
1503
1504 swPnEnergy = round(L_PnEnergy);
1505
1506 if (sub(swPnEnergy, 0x7ff) <= 0)
1507 { /* E = [0..0x7ff] */
1508
1509 swPnShift = 0;
1510
1511 }
1512 else
1513 {
1514
1515 if (sub(swPnEnergy, 0x1fff) <= 0)
1516 { /* E = (0x7ff.. 0x1fff] */
1517 swPnShift = 1;
1518
1519 }
1520 else
1521 {
1522
1523 swPnShift = 2; /* E = (0x1fff..0x7fff] */
1524
1525 }
1526 }
1527
1528 /* shift pswWSVect down by the shift factor */
1529 /*------------------------------------------*/
1530
1531 for (i = 0; i < S_LEN; i++)
1532 pswWSVec[i] = shr(pswWSVec[i], swPnShift);
1533
1534
1535 if (swVoicingMode > 0)
1536 {
1537
1538 /* Do restricted adaptive codebook (long-term-predictor) search: */
1539 /* the search is restricted to the lags passed in from the */
1540 /* open-loop lag search */
1541 /*---------------------------------------------------------------*/
1542
1543 siCode = closedLoopLagSearch(pswLagList, siNumLags,
1544 pswLtpStateBase, pswHCoefs, pswWSVec,
1545 &swLag, &swLtpShift);
1546
1547 /* Construct frame-lag code if this is the first subframe, */
1548 /* or delta-lag code if it is not the first subframe */
1549 /*---------------------------------------------------------*/
1550
1551 if (swVoicingMode > 0)
1552 {
1553
1554 if (giSfrmCnt == 0)
1555 {
1556 siPrevLagCode = siCode;
1557 *psiLagCode = siCode;
1558 }
1559 else
1560 {
1561
1562 *psiLagCode = add(sub(siCode, siPrevLagCode), DELTA_LEVELS / 2);
1563 siPrevLagCode = siCode;
1564 }
1565 }
1566
1567 /* From the value of the fundamental pitch obtained in the open-loop */
1568 /* lag search, get the correct phase of the interpolating filter, */
1569 /* and scale the coefficients by the Harmonic-Noise-Weighting */
1570 /* coefficient. The result is the interpolating coefficients scaled */
1571 /* by the HNW coefficient. These will be used in all C(z) filtering */
1572 /*-------------------------------------------------------------------*/
1573
1574 get_ipjj(swPitch, &siIntPitch, &siRemainder);
1575
1576 for (i = 0; i < CG_INT_MACS; i++)
1577 {
1578
1579 pswHNWCoefs[i] = mult_r(negate(ppsrCGIntFilt[i][siRemainder]),
1580 swHNWCoef);
1581 }
1582
1583 /* Calculate a few values which will speed up C(z) filtering: */
1584 /* "HnwOffset" is the distance in samples from the input sample of */
1585 /* the C(z) filter to the first sample tapped by the interpolating */
1586 /* filter. "HnwNum" is the number of samples which need to be */
1587 /* filtered by C(z) in the zero-state case. */
1588 /*-----------------------------------------------------------------*/
1589
1590 siHnwOffset = sub(-CG_INT_MACS / 2, siIntPitch);
1591 siHnwNum = sub(S_LEN + CG_INT_MACS / 2 - 1, siIntPitch);
1592
1593 /* Perform C(z) filter on W(z)-weighted speech, get zero-input */
1594 /* response of H(z)C(z) combo, subtract zero-input response */
1595 /* of H(z)C(z) from W(z)C(z)-weighted speech. The result is */
1596 /* the vector to match for the rest of the synthetic */
1597 /* excitation searches in the voiced modes */
1598 /*-------------------------------------------------------------*/
1599
1600 hnwFilt(pswWSpeech, pswWSVec, &pswWSpeech[-1], pswHNWCoefs,
1601 siHnwOffset, 1, S_LEN);
1602
1603 hnwFilt(pswTempVec, pswTempVec, &pswHNWState[HNW_BUFF_LEN - 1],
1604 pswHNWCoefs, siHnwOffset, 1, S_LEN);
1605
1606 for (i = 0; i < S_LEN; i++)
1607 {
1608
1609 pswWSVec[i] = shr(sub(pswWSVec[i], pswTempVec[i]), swPnShift);
1610
1611 }
1612
1613 /* Recontruct adaptive codebook (long-term-predictor) vector, */
1614 /* weight it through H(z) and C(z), each with zero state */
1615 /*------------------------------------------------------------*/
1616
1617 fp_ex(swLag, pswLtpStateOut);
1618
1619 for (i = 0; i < S_LEN; i++)
1620 pswPVec[i] = pswLtpStateOut[i];
1621
1622 lpcZsIir(pswPVec, pswHCoefs, pswWPVec);
1623
1624 if (siHnwNum > 0)
1625 {
1626 hnwFilt(pswWPVec, pswWPVec, NULL, pswHNWCoefs, siHnwOffset,
1627 0, siHnwNum);
1628 }
1629 for (i = 0; i < S_LEN; i++)
1630 {
1631 pswPVec[i] = shr(pswPVec[i], swLtpShift);
1632 pswWPVec[i] = shr(pswWPVec[i], swLtpShift);
1633 }
1634
1635 }
1636 else
1637 {
1638
1639 /* Unvoiced mode: clear all voiced variables */
1640 /*-------------------------------------------*/
1641
1642 swLag = 0;
1643 *psiLagCode = 0;
1644 siHnwNum = 0;
1645 }
1646
1647 /* "NumBasisVecs" will be the number of basis vectors in */
1648 /* the vector-sum codebook(s) */
1649 /*-------------------------------------------------------*/
1650
1651 if (swVoicingMode > 0)
1652 siNumBasisVecs = C_BITS_V;
1653
1654 else
1655 siNumBasisVecs = C_BITS_UV;
1656
1657 /* Filter the basis vectors through H(z) with zero state, and if */
1658 /* voiced, through C(z) with zero state */
1659 /*----------------------------------------------------------------*/
1660
1661 for (i = 0; i < siNumBasisVecs; i++)
1662 {
1663
1664 if (swVoicingMode > 0)
1665 {
1666
1667 lpcZsIir((Shortword *) pppsrVcdCodeVec[0][i], pswHCoefs,
1668 &pswWBasisVecs[i * S_LEN]);
1669 }
1670 else
1671 {
1672
1673 lpcZsIir((Shortword *) pppsrUvCodeVec[0][i], pswHCoefs,
1674 &pswWBasisVecs[i * S_LEN]);
1675 }
1676
1677 if (siHnwNum > 0)
1678 {
1679
1680 hnwFilt(&pswWBasisVecs[i * S_LEN], &pswWBasisVecs[i * S_LEN],
1681 NULL, pswHNWCoefs, siHnwOffset, 0, siHnwNum);
1682 }
1683 }
1684
1685 /* If voiced, make the H(z)C(z)-weighted basis vectors orthogonal to */
1686 /* the H(z)C(z)-weighted adaptive codebook vector */
1687 /*-------------------------------------------------------------------*/
1688
1689 if (swVoicingMode > 0)
1690 decorr(siNumBasisVecs, pswWPVec, pswWBasisVecs);
1691
1692 /* Do the vector-sum codebook search on the H(z)C(z)-weighted, */
1693 /* orthogonalized basis vectors */
1694 /*-------------------------------------------------------------*/
1695
1696 *psiVSCode1 = v_srch(pswWSVec, pswWBasisVecs, siNumBasisVecs);
1697
1698 /* Construct the chosen vector-sum codebook vector from basis vectors */
1699 /*--------------------------------------------------------------------*/
1700
1701 b_con(*psiVSCode1, siNumBasisVecs, pswBitArray);
1702
1703 if (swVoicingMode > 0)
1704 v_con((Shortword *) pppsrVcdCodeVec[0][0], ppswVselpEx[0], pswBitArray,
1705 siNumBasisVecs);
1706
1707 else
1708 v_con((Shortword *) pppsrUvCodeVec[0][0], ppswVselpEx[0], pswBitArray,
1709 siNumBasisVecs);
1710
1711 if (swVoicingMode == 0)
1712 {
1713
1714 /* Construct the H(z)-weighted 1st-codebook vector */
1715 /*-------------------------------------------------*/
1716
1717 v_con(pswWBasisVecs, ppswWVselpEx[0], pswBitArray, siNumBasisVecs);
1718
1719 /* Filter the 2nd basis vector set through H(z) with zero state */
1720 /*--------------------------------------------------------------*/
1721
1722 for (i = 0; i < siNumBasisVecs; i++)
1723 {
1724
1725 lpcZsIir((Shortword *) pppsrUvCodeVec[1][i], pswHCoefs,
1726 &pswWBasisVecs[i * S_LEN]);
1727 }
1728
1729 /* Make the 2nd set of H(z)-weighted basis vectors orthogonal to the */
1730 /* H(z)-weighted 1st-codebook vector */
1731 /*-------------------------------------------------------------------*/
1732
1733 decorr(siNumBasisVecs, ppswWVselpEx[0], pswWBasisVecs);
1734
1735 /* Do the vector-sum codebook search on the H(z)-weighted, */
1736 /* orthogonalized, 2nd basis vector set */
1737 /*---------------------------------------------------------*/
1738
1739 *psiVSCode2 = v_srch(pswWSVec, pswWBasisVecs, siNumBasisVecs);
1740
1741 /* Construct the chosen vector-sum codebook vector from the 2nd set */
1742 /* of basis vectors */
1743 /*------------------------------------------------------------------*/
1744
1745 b_con(*psiVSCode2, siNumBasisVecs, pswBitArray);
1746
1747 v_con((Shortword *) pppsrUvCodeVec[1][0], ppswVselpEx[1], pswBitArray,
1748 siNumBasisVecs);
1749 }
1750
1751 else
1752 *psiVSCode2 = 0;
1753
1754 /* Filter the 1st-codebook vector through H(z) (also through C(z) */
1755 /* if appropriate) */
1756 /*----------------------------------------------------------------*/
1757
1758 lpcZsIir(ppswVselpEx[0], pswHCoefs, ppswWVselpEx[0]);
1759
1760 if (siHnwNum > 0)
1761 {
1762 hnwFilt(ppswWVselpEx[0], ppswWVselpEx[0], NULL, pswHNWCoefs,
1763 siHnwOffset, 0, siHnwNum);
1764 }
1765
1766 if (swVoicingMode == 0)
1767 {
1768
1769 /* Filter the 2nd-codebook vector through H(z) */
1770 /*---------------------------------------------*/
1771
1772 lpcZsIir(ppswVselpEx[1], pswHCoefs, ppswWVselpEx[1]);
1773 }
1774
1775 /* Get the square-root of the ratio of residual energy to */
1776 /* excitation vector energy for each of the excitation sources */
1777 /*-------------------------------------------------------------*/
1778
1779 if (swVoicingMode > 0)
1780 {
1781
1782 rs_rrNs(pswPVec, snsSqrtRs, &snsRs00);
1783 }
1784
1785 rs_rrNs(ppswVselpEx[0], snsSqrtRs, &snsRs11);
1786
1787 if (swVoicingMode == 0)
1788 {
1789
1790 rs_rrNs(ppswVselpEx[1], snsSqrtRs, &snsRs22);
1791 }
1792
1793 /* Determine the vector-quantized gains for each of the excitations */
1794 /*------------------------------------------------------------------*/
1795
1796 *psiGsp0Code = g_quant_vl(swVoicingMode, pswWSVec, swPnShift,
1797 pswWPVec,
1798 ppswWVselpEx[0], ppswWVselpEx[1], snsRs00,
1799 snsRs11, snsRs22);
1800
1801 } /* DTX mode */
1802 else /* DTX mode */
1803 { /* DTX mode */
1804
1805 /* swSP == 0, currently in comfort noise insertion mode */ /* DTX mode */
1806 /*------------------------------------------------------*/ /* DTX mode */
1807
1808 /* generate the random codevector */ /* DTX mode */
1809 siNumBasisVecs = C_BITS_UV; /* DTX mode */
1810
1811 /* build codevector 1 */ /* DTX mode */
1812
1813 b_con(*psiVSCode1, siNumBasisVecs, pswBitArray); /* DTX mode */
1814 v_con((Shortword *) pppsrUvCodeVec[0][0], ppswVselpEx[0], /* DTX mode */
1815 pswBitArray, siNumBasisVecs); /* DTX mode */
1816
1817 /* build codevector 2 */ /* DTX mode */
1818
1819 b_con(*psiVSCode2, siNumBasisVecs, pswBitArray); /* DTX mode */
1820 v_con((Shortword *) pppsrUvCodeVec[1][0], ppswVselpEx[1], /* DTX mode */
1821 pswBitArray, siNumBasisVecs); /* DTX mode */
1822
1823
1824 /* get rs_rr for the two vectors */ /* DTX mode */
1825 rs_rrNs(ppswVselpEx[0], snsSqrtRs, &snsRs11); /* DTX mode */
1826 rs_rrNs(ppswVselpEx[1], snsSqrtRs, &snsRs22); /* DTX mode */
1827
1828 } /* DTX mode */
1829
1830
1831 /* Scale the excitations, each by its gain, and add them. Put the */
1832 /* result at the end of the adaptive codebook (long-term-predictor */
1833 /* state) */
1834 /*-----------------------------------------------------------------*/
1835
1836 if (swVoicingMode == 0)
1837 {
1838
1839 /* unvoiced */
1840 /* -------- */
1841
1842 scaleExcite(ppswVselpEx[0],
1843 pppsrGsp0[swVoicingMode][*psiGsp0Code][0],
1844 snsRs11, ppswVselpEx[0]);
1845 scaleExcite(ppswVselpEx[1],
1846 pppsrGsp0[swVoicingMode][*psiGsp0Code][1],
1847 snsRs22, ppswVselpEx[1]);
1848
1849 /* now combine the two scaled excitations */
1850 /* -------------------------------------- */
1851 for (i = 0; i < S_LEN; i++)
1852 pswTempVec[i] = add(ppswVselpEx[0][i], ppswVselpEx[1][i]);
1853 }
1854
1855 else
1856 {
1857
1858 /* voiced */
1859 /* ------ */
1860
1861 scaleExcite(pswPVec,
1862 pppsrGsp0[swVoicingMode][*psiGsp0Code][0],
1863 snsRs00, pswPVec);
1864 scaleExcite(ppswVselpEx[0],
1865 pppsrGsp0[swVoicingMode][*psiGsp0Code][1],
1866 snsRs11, ppswVselpEx[0]);
1867
1868 /* now combine the two scaled excitations */
1869 /* -------------------------------------- */
1870 for (i = 0; i < S_LEN; i++)
1871 pswTempVec[i] = add(pswPVec[i], ppswVselpEx[0][i]);
1872 }
1873
1874 /* Update the long-term-predictor state using the synthetic excitation */
1875 /*---------------------------------------------------------------------*/
1876
1877 for (i = -LTP_LEN; i < -S_LEN; i++)
1878 pswLtpStateOut[i] = pswLtpStateOut[i + S_LEN];
1879
1880 for (i = -S_LEN, j = 0; j < S_LEN; i++, j++)
1881 pswLtpStateOut[i] = pswTempVec[j];
1882
1883 /* Filter the synthetic excitation through the weighting filters, */
1884 /* H(z) and C(z), only to update filter states (Note that C(z) */
1885 /* state may be updated without filtering, since it is an FIR) */
1886 /* */
1887 /* First, perform one subframe's worth of delay on C(z) state */
1888 /*----------------------------------------------------------------*/
1889
1890 for (i = 0; i < HNW_BUFF_LEN - S_LEN; i++)
1891 pswHNWState[i] = pswHNWState[i + S_LEN];
1892
1893 /* Second, perform H(z) filter on excitation, output goes into */
1894 /* C(z) state */
1895 /*-------------------------------------------------------------*/
1896
1897 lpcIir(pswTempVec, pswHCoefs, pswHState,
1898 &pswHNWState[HNW_BUFF_LEN - S_LEN]);
1899
1900 } /* end of sfrmAnalysis() */
1901
1902 /***************************************************************************
1903 *
1904 * FUNCTION NAME: v_srch
1905 *
1906 * PURPOSE:
1907 * The purpose of this function is search a vector-sum codebook for the
1908 * optimal vector
1909 *
1910 * INPUTS:
1911 *
1912 * pswWInput[0:S_LEN]
1913 *
1914 * the weighted input speech frame, with the zero-input
1915 * response of H(z) subtracted
1916 *
1917 * pswWBasisVecs[0:S_LEN*siNumBasis]
1918 *
1919 * weighted, decorrelated vector-sum codebook basis
1920 * vectors
1921 *
1922 * siNumBasis
1923 *
1924 * number of basis vectors
1925 *
1926 * OUTPUTS:
1927 *
1928 * none
1929 *
1930 * RETURN VALUE:
1931 *
1932 * sw1
1933 *
1934 * output code
1935 *
1936 * REFERENCE: Sub-clause 4.1.10.2 of GSM Recommendation 06.20
1937 *
1938 * KEYWORDS: v_srch, codebook, search
1939 *
1940 **************************************************************************/
1941
1942 Shortword v_srch(Shortword pswWInput[], Shortword pswWBasisVecs[],
1943 short int siNumBasis)
1944 {
1945
1946 /*_________________________________________________________________________
1947 | |
1948 | Local Constants |
1949 |_________________________________________________________________________|
1950 */
1951
1952 #define V_ARRAY_SIZE ( 1 << (C_BITS_V-1) ) - 1
1953 #define UN_ARRAY_SIZE ( 1 << (C_BITS_UV-1) ) - 1
1954 #define MINUS_HALF -0x4000
1955
1956 /*_________________________________________________________________________
1957 | |
1958 | Local Static Variables |
1959 |_________________________________________________________________________|
1960 */
1961 static Shortword
1962 pswUpdateIndexV[V_ARRAY_SIZE] =
1963 {
1964 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09,
1965 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24, 0x00, 0x09, 0x48, 0x12,
1966 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51,
1967 0x48, 0x2d, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b,
1968 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c, 0x00, 0x09,
1969 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a,
1970 0x00, 0x51, 0x48, 0x36, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51,
1971 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24,
1972 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09,
1973 0x48, 0x5a, 0x00, 0x51, 0x48, 0x75, 0x00, 0x09, 0x48, 0x12,
1974 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51,
1975 0x48, 0x6c, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63,
1976 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x3f, 0x00, 0x09,
1977 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a,
1978 0x00, 0x51, 0x48, 0x24, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51,
1979 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x2d,
1980 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09,
1981 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c, 0x00, 0x09, 0x48, 0x12,
1982 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51,
1983 0x48, 0x7e, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b,
1984 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24, 0x00, 0x09,
1985 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a,
1986 0x00, 0x51, 0x48, 0x75, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51,
1987 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c,
1988 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09,
1989 0x48, 0x5a, 0x00, 0x51, 0x48,
1990 },
1991 pswBitIndexV[V_ARRAY_SIZE] =
1992 {
1993 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02,
1994 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03,
1995 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
1996 0x01, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04,
1997 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02,
1998 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03,
1999 0x01, 0x02, 0x01, 0x07, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2000 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05,
2001 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02,
2002 0x01, 0x03, 0x01, 0x02, 0x01, 0x06, 0x01, 0x02, 0x01, 0x03,
2003 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2004 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04,
2005 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02,
2006 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03,
2007 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2008 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x06,
2009 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02,
2010 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03,
2011 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2012 0x01, 0x07, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04,
2013 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02,
2014 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03,
2015 0x01, 0x02, 0x01, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2016 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05,
2017 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02,
2018 0x01, 0x03, 0x01, 0x02, 0x01,
2019 },
2020 pswModNextBitV[C_BITS_V] =
2021 {
2022 1, 2, 3, 4, 5, 6, 7, 0, 1,
2023 },
2024 pswUpdateIndexUn[UN_ARRAY_SIZE] =
2025 {
2026 0x00, 0x07, 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x15, 0x00, 0x07,
2027 0x2a, 0x38, 0x00, 0x31, 0x2a, 0x1c, 0x00, 0x07, 0x2a, 0x0e,
2028 0x00, 0x31, 0x2a, 0x3f, 0x00, 0x07, 0x2a, 0x38, 0x00, 0x31,
2029 0x2a, 0x23, 0x00, 0x07, 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x15,
2030 0x00, 0x07, 0x2a, 0x38, 0x00, 0x31, 0x2a, 0x46, 0x00, 0x07,
2031 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x3f, 0x00, 0x07, 0x2a, 0x38,
2032 0x00, 0x31, 0x2a,
2033 },
2034 pswBitIndexUn[UN_ARRAY_SIZE] =
2035 {
2036 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02,
2037 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03,
2038 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02,
2039 0x01, 0x00, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04,
2040 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02,
2041 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03,
2042 0x01, 0x02, 0x01,
2043 },
2044 pswModNextBitUV[C_BITS_UV] =
2045 {
2046 1, 2, 3, 4, 5, 0, 1,
2047 };
2048
2049 /*_________________________________________________________________________
2050 | |
2051 | Automatic Variables |
2052 |_________________________________________________________________________|
2053 */
2054
2055 Shortword **pppswDubD[C_BITS_V - 1],
2056 *ppswD[C_BITS_V - 1],
2057 pswCGUpdates[2 * C_BITS_V * (C_BITS_V - 1)],
2058 pswDSpace[2 * C_BITS_V * (C_BITS_V - 1)],
2059 *ppswDPSpace[C_BITS_V * (C_BITS_V - 1)],
2060 pswBits[C_BITS_V - 1],
2061 *pswUpdatePtr,
2062 *pswUIndex,
2063 *pswBIndex,
2064 *pswModNextBit,
2065 *psw0,
2066 *psw1,
2067 *psw2,
2068 swC0,
2069 swG0,
2070 swCC,
2071 swG,
2072 swCCMax,
2073 swGMax,
2074 sw1;
2075 Longword pL_R[C_BITS_V],
2076 L_R,
2077 L_MaxC,
2078 L_C0,
2079 L_D,
2080 L_G0,
2081 L_C,
2082 L_G,
2083 L_1;
2084 short int siI,
2085 siJ,
2086 siK,
2087 siEBits,
2088 siShiftCnt,
2089 siBitIndex,
2090 siBest,
2091 siMask;
2092
2093 /*_________________________________________________________________________
2094 | |
2095 | Executable Code |
2096 |_________________________________________________________________________|
2097 */
2098
2099 /* initialize variables based on voicing mode */
2100 /* ------------------------------------------ */
2101
2102 if (sub(siNumBasis, C_BITS_V) == 0)
2103 {
2104 siEBits = C_BITS_V_1;
2105 pswUIndex = pswUpdateIndexV;
2106 pswBIndex = pswBitIndexV;
2107 pswModNextBit = pswModNextBitV;
2108 }
2109 else
2110 {
2111 siEBits = C_BITS_UV_1;
2112 pswUIndex = pswUpdateIndexUn;
2113 pswBIndex = pswBitIndexUn;
2114 pswModNextBit = pswModNextBitUV;
2115 }
2116
2117 /* initialize pointers */
2118 /* ------------------- */
2119
2120 for (siI = 0; siI < siNumBasis - 1; siI++)
2121 {
2122
2123 pppswDubD[siI] = &ppswDPSpace[siI * siNumBasis];
2124
2125 for (siJ = 0; siJ < siNumBasis; siJ++)
2126 {
2127 ppswDPSpace[(siI * siNumBasis) + siJ] =
2128 &pswDSpace[(siI * siNumBasis * 2) + (siJ * 2)];
2129 }
2130 ppswD[siI] = &pswDSpace[siI * siNumBasis];
2131 }
2132
2133 /* compute correlations (Rm) between given vector and basis vectors, */
2134 /* store in double precision; maintain max C for later scaling of Rm's */
2135 /* ------------------------------------------------------------------- */
2136
2137 L_MaxC = 0L;
2138
2139 for (siI = 0; siI < siNumBasis; siI++)
2140 {
2141
2142 L_R = L_mult(pswWBasisVecs[siI * S_LEN], pswWInput[0]);
2143
2144 for (siJ = 1; siJ < S_LEN; siJ++)
2145 {
2146 L_R = L_mac(L_R, pswWBasisVecs[siJ + (siI * S_LEN)], pswWInput[siJ]);
2147 }
2148 pL_R[siI] = L_R;
2149 L_R = L_abs(L_R);
2150 L_MaxC = L_add(L_R, L_MaxC);
2151 }
2152
2153 /* normalize max C to get scaling shift count */
2154 /* scale Rm's and calculate C(0) */
2155 /* ------------------------------------------ */
2156
2157 /* max abs(C) after scale is <= 0.5 */
2158 siShiftCnt = add(-1, norm_l(L_MaxC));
2159
2160 L_C0 = 0L;
2161
2162 for (siI = 0; siI < siNumBasis; siI++)
2163 {
2164
2165 L_R = L_shl(pL_R[siI], siShiftCnt);
2166
2167 L_C0 = L_sub(L_C0, L_R);
2168
2169 pL_R[siI] = L_shl(L_R, 1);
2170
2171 }
2172 swC0 = extract_h(L_C0);
2173
2174 /* compute correlations (Dmj, for m != j) between the basis vectors */
2175 /* store in double precision */
2176 /* ---------------------------------------------------------------- */
2177
2178 for (siI = 0; siI < siNumBasis - 1; siI++)
2179 {
2180
2181 for (siJ = siI + 1; siJ < siNumBasis; siJ++)
2182 {
2183
2184 L_D = L_mult(pswWBasisVecs[siI * S_LEN], pswWBasisVecs[siJ * S_LEN]);
2185
2186 for (siK = 1; siK < S_LEN; siK++)
2187 {
2188 L_D = L_mac(L_D, pswWBasisVecs[siK + (siI * S_LEN)],
2189 pswWBasisVecs[siK + (siJ * S_LEN)]);
2190 }
2191 pppswDubD[siI][siJ][0] = extract_h(L_D);
2192 pppswDubD[siI][siJ][1] = extract_l(L_D);
2193 }
2194 }
2195
2196 /* compute the sum of the Djj's (to be used for scaling the Dmj's and */
2197 /* for computing G(0)); normalize it, get shift count for scaling Dmj's */
2198 /* -------------------------------------------------------------------- */
2199
2200 psw1 = pswWBasisVecs;
2201
2202 L_G0 = L_mult(psw1[0], psw1[0]);
2203
2204 for (siI = 1; siI < siNumBasis * S_LEN; siI++)
2205 {
2206 L_G0 = L_mac(L_G0, psw1[siI], psw1[siI]);
2207 }
2208
2209 siShiftCnt = add(-4, norm_l(L_G0));
2210
2211 L_G0 = L_shl(L_G0, siShiftCnt);
2212
2213 /* scale Dmj's and compute G(0) */
2214 /* ---------------------------- */
2215
2216 for (siI = 0; siI < siNumBasis - 1; siI++)
2217 {
2218
2219 for (siJ = siI + 1; siJ < siNumBasis; siJ++)
2220 {
2221
2222 L_D = L_deposit_h(pppswDubD[siI][siJ][0]);
2223 L_D = L_add(L_D, (LSP_MASK & L_deposit_l(pppswDubD[siI][siJ][1])));
2224
2225 L_D = L_shl(L_D, siShiftCnt);
2226
2227 L_D = L_shl(L_D, 1);
2228
2229 L_G0 = L_add(L_D, L_G0);
2230
2231 L_D = L_shl(L_D, 1);
2232
2233 ppswD[siI][siJ] = round(L_D);
2234 }
2235 }
2236
2237 swG0 = extract_h(L_G0);
2238
2239 /* build array of update values for codebook search */
2240 /* ------------------------------------------------ */
2241
2242 for (siI = 0; siI < siEBits; siI++)
2243 {
2244 pswCGUpdates[siI * (siEBits + 1)] = round(pL_R[siI]);
2245 }
2246 psw0 = &pswCGUpdates[siEBits];
2247 psw1 = &pswCGUpdates[1];
2248 psw2 = &pswCGUpdates[2 * siEBits];
2249
2250 for (siI = 0; siI < siEBits - 1; siI++)
2251 {
2252
2253 for (siJ = siI + 1; siJ < siEBits; siJ++)
2254 {
2255
2256 L_1 = L_deposit_h(ppswD[siI][siJ]);
2257 L_1 = L_shl(L_1, 1);
2258 psw1[siJ - 1 + (siI * siEBits)] = extract_h(L_1);
2259 psw2[siI + (siEBits * (siJ - 1))] = extract_h(L_1);
2260 }
2261 psw0[siI * (siEBits + 1)] = negate(ppswD[siI][siEBits]);
2262 }
2263
2264 psw0[siI * (siEBits + 1)] = negate(ppswD[siEBits - 1][siEBits]);
2265
2266 /* copy to negative side of array */
2267 /* ------------------------------ */
2268
2269 psw0 = &pswCGUpdates[(siEBits + 1) * siEBits];
2270
2271 for (siI = 0; siI < (siEBits + 1) * siEBits; siI++)
2272 {
2273 psw0[siI] = negate(pswCGUpdates[siI]);
2274 }
2275
2276 /* initialize array of bits (magnitude = 0.5) */
2277 /* ------------------------------------------ */
2278
2279 for (siI = 0; siI < siEBits; siI++)
2280 {
2281 pswBits[siI] = MINUS_HALF;
2282 }
2283
2284 /* initialize and do codebook search */
2285 /* --------------------------------- */
2286
2287 swGMax = swG0;
2288 swCCMax = mult_r(swC0, swC0);
2289 L_C = L_deposit_h(swC0);
2290 L_G = L_deposit_h(swG0);
2291 siBest = 0;
2292
2293 for (siI = 0; siI < (1 << siEBits) - 1; siI++)
2294 {
2295
2296 pswUpdatePtr = &pswCGUpdates[pswUIndex[siI]];
2297
2298 siBitIndex = pswBIndex[siI];
2299
2300 L_C = L_msu(L_C, pswUpdatePtr[0], 0x8000);
2301
2302 for (siJ = 0; siJ < siEBits - 1; siJ++)
2303 {
2304 L_G = L_mac(L_G, pswUpdatePtr[siJ + 1], pswBits[siBitIndex]);
2305 siBitIndex = pswModNextBit[siBitIndex];
2306 }
2307 L_G = L_msu(L_G, pswUpdatePtr[siJ + 1], 0x8000);
2308
2309 pswBits[siBitIndex] = negate(pswBits[siBitIndex]);
2310
2311 sw1 = extract_h(L_C);
2312 swCC = mult_r(sw1, sw1);
2313
2314 swG = extract_h(L_G);
2315 L_1 = L_mult(swG, swCCMax);
2316
2317 L_1 = L_msu(L_1, swGMax, swCC);
2318
2319 if (L_1 < 0)
2320 {
2321 swCCMax = swCC;
2322 swGMax = swG;
2323 siBest = add(siI, 1);
2324 }
2325 }
2326
2327 /* generate code for positive correlation; */
2328 /* compute correlation, if negative, invert code */
2329 /* --------------------------------------------- */
2330
2331 sw1 = siBest ^ (shr(siBest, 1));
2332
2333 siMask = 0x1;
2334 L_1 = 0L;
2335
2336 for (siI = 0; siI < siNumBasis; siI++)
2337 {
2338
2339 if ((sw1 & siMask) == 0)
2340 {
2341 L_1 = L_sub(L_1, pL_R[siI]);
2342 }
2343 else
2344 {
2345 L_1 = L_add(L_1, pL_R[siI]);
2346 }
2347
2348 siMask = shl(siMask, 1);
2349 }
2350
2351 if (L_1 < 0)
2352 {
2353 sw1 = sw1 ^ (sub(shl(1, siNumBasis), 1));
2354 }
2355
2356 /* return code */
2357 /* ----------- */
2358
2359 return (sw1);
2360 }