FreeCalypso > hg > gsm-codec-lib
comparison libgsmefr/q_gains.c @ 53:49dd1ac8e75b
libgsmefr: import most *.c files from ETSI source
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 25 Nov 2022 16:18:21 +0000 |
| parents | |
| children | 03599300d2db |
comparison
equal
deleted
inserted
replaced
| 52:988fd7ff514f | 53:49dd1ac8e75b |
|---|---|
| 1 /*--------------------------------------------------------------------------* | |
| 2 * Function q_gain_pitch(), q_gain_code() * | |
| 3 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
| 4 * Scalar quantization of the pitch gain and the innovative codebook gain. * | |
| 5 * * | |
| 6 * MA prediction is performed on the innovation energy * | |
| 7 * (in dB/(20*log10(2))) with mean removed. * | |
| 8 *-------------------------------------------------------------------------*/ | |
| 9 | |
| 10 #include "typedef.h" | |
| 11 #include "basic_op.h" | |
| 12 #include "oper_32b.h" | |
| 13 #include "count.h" | |
| 14 #include "sig_proc.h" | |
| 15 | |
| 16 #include "gains_tb.h" | |
| 17 | |
| 18 #include "cnst.h" | |
| 19 #include "dtx.h" | |
| 20 | |
| 21 /* past quantized energies. */ | |
| 22 /* initialized to -14.0/constant, constant = 20*Log10(2) */ | |
| 23 Word16 past_qua_en[4]; | |
| 24 | |
| 25 /* MA prediction coeff */ | |
| 26 Word16 pred[4]; | |
| 27 | |
| 28 extern Word16 CN_excitation_gain, gain_code_old_tx[4 * DTX_HANGOVER]; | |
| 29 | |
| 30 Word16 q_gain_pitch ( /* Return index of quantization */ | |
| 31 Word16 *gain /* (i) : Pitch gain to quantize */ | |
| 32 ) | |
| 33 { | |
| 34 Word16 i, index, gain_q14, err, err_min; | |
| 35 | |
| 36 gain_q14 = shl (*gain, 2); | |
| 37 | |
| 38 err_min = abs_s (sub (gain_q14, qua_gain_pitch[0])); | |
| 39 index = 0; move16 (); | |
| 40 | |
| 41 for (i = 1; i < NB_QUA_PITCH; i++) | |
| 42 { | |
| 43 err = abs_s (sub (gain_q14, qua_gain_pitch[i])); | |
| 44 | |
| 45 test (); | |
| 46 if (sub (err, err_min) < 0) | |
| 47 { | |
| 48 err_min = err; move16 (); | |
| 49 index = i; move16 (); | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 *gain = shr (qua_gain_pitch[index], 2); move16 (); | |
| 54 | |
| 55 return index; | |
| 56 } | |
| 57 | |
| 58 /* average innovation energy. */ | |
| 59 /* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */ | |
| 60 | |
| 61 #define MEAN_ENER 783741L /* 36/(20*log10(2)) */ | |
| 62 | |
| 63 Word16 q_gain_code ( /* Return quantization index */ | |
| 64 Word16 code[], /* (i) : fixed codebook excitation */ | |
| 65 Word16 lcode, /* (i) : codevector size */ | |
| 66 Word16 *gain, /* (i/o) : quantized fixed codebook gain */ | |
| 67 Word16 txdtx_ctrl, | |
| 68 Word16 i_subfr | |
| 69 ) | |
| 70 { | |
| 71 Word16 i, index; | |
| 72 Word16 gcode0, err, err_min, exp, frac; | |
| 73 Word32 ener, ener_code; | |
| 74 Word16 aver_gain; | |
| 75 static Word16 gcode0_CN; | |
| 76 | |
| 77 logic16 (); test (); | |
| 78 if ((txdtx_ctrl & TX_SP_FLAG) != 0) | |
| 79 { | |
| 80 | |
| 81 /*-------------------------------------------------------------------* | |
| 82 * energy of code: * | |
| 83 * ~~~~~~~~~~~~~~~ * | |
| 84 * ener_code(Q17) = 10 * Log10(energy/lcode) / constant * | |
| 85 * = 1/2 * Log2(energy/lcode) * | |
| 86 * constant = 20*Log10(2) * | |
| 87 *-------------------------------------------------------------------*/ | |
| 88 | |
| 89 /* ener_code = log10(ener_code/lcode) / (20*log10(2)) */ | |
| 90 ener_code = 0; move32 (); | |
| 91 for (i = 0; i < lcode; i++) | |
| 92 { | |
| 93 ener_code = L_mac (ener_code, code[i], code[i]); | |
| 94 } | |
| 95 /* ener_code = ener_code / lcode */ | |
| 96 ener_code = L_mult (round (ener_code), 26214); | |
| 97 | |
| 98 /* ener_code = 1/2 * Log2(ener_code) */ | |
| 99 Log2 (ener_code, &exp, &frac); | |
| 100 ener_code = L_Comp (sub (exp, 30), frac); | |
| 101 | |
| 102 /* predicted energy */ | |
| 103 | |
| 104 ener = MEAN_ENER; move32 (); | |
| 105 for (i = 0; i < 4; i++) | |
| 106 { | |
| 107 ener = L_mac (ener, past_qua_en[i], pred[i]); | |
| 108 } | |
| 109 | |
| 110 /*-------------------------------------------------------------------* | |
| 111 * predicted codebook gain * | |
| 112 * ~~~~~~~~~~~~~~~~~~~~~~~ * | |
| 113 * gcode0(Qx) = Pow10( (ener*constant - ener_code*constant) / 20 ) * | |
| 114 * = Pow2(ener-ener_code) * | |
| 115 * constant = 20*Log10(2) * | |
| 116 *-------------------------------------------------------------------*/ | |
| 117 | |
| 118 ener = L_shr (L_sub (ener, ener_code), 1); | |
| 119 L_Extract (ener, &exp, &frac); | |
| 120 | |
| 121 gcode0 = extract_l (Pow2 (exp, frac)); /* predicted gain */ | |
| 122 | |
| 123 gcode0 = shl (gcode0, 4); | |
| 124 | |
| 125 /*-------------------------------------------------------------------* | |
| 126 * Search for best quantizer * | |
| 127 *-------------------------------------------------------------------*/ | |
| 128 | |
| 129 err_min = abs_s (sub (*gain, mult (gcode0, qua_gain_code[0]))); | |
| 130 index = 0; move16 (); | |
| 131 | |
| 132 for (i = 1; i < NB_QUA_CODE; i++) | |
| 133 { | |
| 134 err = abs_s (sub (*gain, mult (gcode0, qua_gain_code[i]))); | |
| 135 | |
| 136 test (); | |
| 137 if (sub (err, err_min) < 0) | |
| 138 { | |
| 139 err_min = err; move16 (); | |
| 140 index = i; move16 (); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 *gain = mult (gcode0, qua_gain_code[index]); | |
| 145 move16 (); | |
| 146 | |
| 147 /*------------------------------------------------------------------* | |
| 148 * update table of past quantized energies * | |
| 149 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
| 150 * past_qua_en(Q12) = 20 * Log10(qua_gain_code) / constant * | |
| 151 * = Log2(qua_gain_code) * | |
| 152 * constant = 20*Log10(2) * | |
| 153 *------------------------------------------------------------------*/ | |
| 154 | |
| 155 for (i = 3; i > 0; i--) | |
| 156 { | |
| 157 past_qua_en[i] = past_qua_en[i - 1];move16 (); | |
| 158 } | |
| 159 Log2 (L_deposit_l (qua_gain_code[index]), &exp, &frac); | |
| 160 | |
| 161 past_qua_en[0] = shr (frac, 5); move16 (); | |
| 162 past_qua_en[0] = add (past_qua_en[0], shl (sub (exp, 11), 10)); | |
| 163 move16 (); | |
| 164 | |
| 165 update_gain_code_history_tx (*gain, gain_code_old_tx); | |
| 166 } | |
| 167 else | |
| 168 { | |
| 169 logic16 (); test (); test (); | |
| 170 if ((txdtx_ctrl & TX_PREV_HANGOVER_ACTIVE) != 0 && (i_subfr == 0)) | |
| 171 { | |
| 172 gcode0_CN = update_gcode0_CN (gain_code_old_tx); | |
| 173 gcode0_CN = shl (gcode0_CN, 4); | |
| 174 } | |
| 175 *gain = CN_excitation_gain; move16 (); | |
| 176 | |
| 177 logic16 (); test (); test (); | |
| 178 if ((txdtx_ctrl & TX_SID_UPDATE) != 0) | |
| 179 { | |
| 180 aver_gain = aver_gain_code_history (CN_excitation_gain, | |
| 181 gain_code_old_tx); | |
| 182 | |
| 183 /*---------------------------------------------------------------* | |
| 184 * Search for best quantizer * | |
| 185 *---------------------------------------------------------------*/ | |
| 186 | |
| 187 err_min = abs_s (sub (aver_gain, | |
| 188 mult (gcode0_CN, qua_gain_code[0]))); | |
| 189 index = 0; move16 (); | |
| 190 | |
| 191 for (i = 1; i < NB_QUA_CODE; i++) | |
| 192 { | |
| 193 err = abs_s (sub (aver_gain, | |
| 194 mult (gcode0_CN, qua_gain_code[i]))); | |
| 195 | |
| 196 test (); | |
| 197 if (sub (err, err_min) < 0) | |
| 198 { | |
| 199 err_min = err; move16 (); | |
| 200 index = i; move16 (); | |
| 201 } | |
| 202 } | |
| 203 } | |
| 204 update_gain_code_history_tx (*gain, gain_code_old_tx); | |
| 205 | |
| 206 /*-------------------------------------------------------------------* | |
| 207 * reset table of past quantized energies * | |
| 208 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
| 209 *-------------------------------------------------------------------*/ | |
| 210 | |
| 211 for (i = 0; i < 4; i++) | |
| 212 { | |
| 213 past_qua_en[i] = -2381; move16 (); | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 return index; | |
| 218 } |
