FreeCalypso > hg > efr-experiments
comparison src/g_pitch.c @ 0:56410792419a
src: original EFR source from ETSI
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Wed, 03 Apr 2024 05:31:37 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:56410792419a |
|---|---|
| 1 /************************************************************************* | |
| 2 * | |
| 3 * FUNCTION: G_pitch | |
| 4 * | |
| 5 * PURPOSE: Compute the pitch (adaptive codebook) gain. Result in Q12 | |
| 6 * | |
| 7 * DESCRIPTION: | |
| 8 * The adaptive codebook gain is given by | |
| 9 * | |
| 10 * g = <x[], y[]> / <y[], y[]> | |
| 11 * | |
| 12 * where x[] is the target vector, y[] is the filtered adaptive | |
| 13 * codevector, and <> denotes dot product. | |
| 14 * The gain is limited to the range [0,1.2] | |
| 15 * | |
| 16 *************************************************************************/ | |
| 17 | |
| 18 #include "typedef.h" | |
| 19 #include "basic_op.h" | |
| 20 #include "oper_32b.h" | |
| 21 #include "count.h" | |
| 22 #include "sig_proc.h" | |
| 23 | |
| 24 Word16 G_pitch ( /* (o) : Gain of pitch lag saturated to 1.2 */ | |
| 25 Word16 xn[], /* (i) : Pitch target. */ | |
| 26 Word16 y1[], /* (i) : Filtered adaptive codebook. */ | |
| 27 Word16 L_subfr /* : Length of subframe. */ | |
| 28 ) | |
| 29 { | |
| 30 Word16 i; | |
| 31 Word16 xy, yy, exp_xy, exp_yy, gain; | |
| 32 Word32 s; | |
| 33 | |
| 34 Word16 scaled_y1[80]; /* Usually dynamic allocation of (L_subfr) */ | |
| 35 | |
| 36 /* divide by 2 "y1[]" to avoid overflow */ | |
| 37 | |
| 38 for (i = 0; i < L_subfr; i++) | |
| 39 { | |
| 40 scaled_y1[i] = shr (y1[i], 2); move16 (); | |
| 41 } | |
| 42 | |
| 43 /* Compute scalar product <y1[],y1[]> */ | |
| 44 | |
| 45 s = 0L; move32 (); /* Avoid case of all zeros */ | |
| 46 for (i = 0; i < L_subfr; i++) | |
| 47 { | |
| 48 s = L_mac (s, y1[i], y1[i]); | |
| 49 } | |
| 50 test (); | |
| 51 if (L_sub (s, MAX_32) != 0L) /* Test for overflow */ | |
| 52 { | |
| 53 s = L_add (s, 1L); /* Avoid case of all zeros */ | |
| 54 exp_yy = norm_l (s); | |
| 55 yy = round (L_shl (s, exp_yy)); | |
| 56 } | |
| 57 else | |
| 58 { | |
| 59 s = 1L; move32 (); /* Avoid case of all zeros */ | |
| 60 for (i = 0; i < L_subfr; i++) | |
| 61 { | |
| 62 s = L_mac (s, scaled_y1[i], scaled_y1[i]); | |
| 63 } | |
| 64 exp_yy = norm_l (s); | |
| 65 yy = round (L_shl (s, exp_yy)); | |
| 66 exp_yy = sub (exp_yy, 4); | |
| 67 } | |
| 68 | |
| 69 /* Compute scalar product <xn[],y1[]> */ | |
| 70 | |
| 71 Overflow = 0; move16 (); | |
| 72 s = 1L; move32 (); /* Avoid case of all zeros */ | |
| 73 for (i = 0; i < L_subfr; i++) | |
| 74 { | |
| 75 Carry = 0; move16 (); | |
| 76 s = L_macNs (s, xn[i], y1[i]); | |
| 77 | |
| 78 test (); | |
| 79 if (Overflow != 0) | |
| 80 { | |
| 81 break; | |
| 82 } | |
| 83 } | |
| 84 test (); | |
| 85 if (Overflow == 0) | |
| 86 { | |
| 87 exp_xy = norm_l (s); | |
| 88 xy = round (L_shl (s, exp_xy)); | |
| 89 } | |
| 90 else | |
| 91 { | |
| 92 s = 1L; move32 (); /* Avoid case of all zeros */ | |
| 93 for (i = 0; i < L_subfr; i++) | |
| 94 { | |
| 95 s = L_mac (s, xn[i], scaled_y1[i]); | |
| 96 } | |
| 97 exp_xy = norm_l (s); | |
| 98 xy = round (L_shl (s, exp_xy)); | |
| 99 exp_xy = sub (exp_xy, 2); | |
| 100 } | |
| 101 | |
| 102 /* If (xy < 4) gain = 0 */ | |
| 103 | |
| 104 i = sub (xy, 4); | |
| 105 | |
| 106 test (); | |
| 107 if (i < 0) | |
| 108 return ((Word16) 0); | |
| 109 | |
| 110 /* compute gain = xy/yy */ | |
| 111 | |
| 112 xy = shr (xy, 1); /* Be sure xy < yy */ | |
| 113 gain = div_s (xy, yy); | |
| 114 | |
| 115 i = add (exp_xy, 3 - 1); /* Denormalization of division */ | |
| 116 i = sub (i, exp_yy); | |
| 117 | |
| 118 gain = shr (gain, i); | |
| 119 | |
| 120 /* if(gain >1.2) gain = 1.2 */ | |
| 121 | |
| 122 test (); | |
| 123 if (sub (gain, 4915) > 0) | |
| 124 { | |
| 125 gain = 4915; move16 (); | |
| 126 } | |
| 127 return (gain); | |
| 128 } |
