FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/ec_gains.c @ 362:9cbd1b5d061f
libtwamr: integrate ec_gains.c
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Mon, 06 May 2024 02:08:43 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 361:9aa554f8cf39 | 362:9cbd1b5d061f |
|---|---|
| 1 /* | |
| 2 ******************************************************************************** | |
| 3 * | |
| 4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 | |
| 5 * R99 Version 3.3.0 | |
| 6 * REL-4 Version 4.1.0 | |
| 7 * | |
| 8 ******************************************************************************** | |
| 9 * | |
| 10 * File : ec_gains.c | |
| 11 * Purpose: : Error concealment for pitch and codebook gains | |
| 12 * | |
| 13 ******************************************************************************** | |
| 14 */ | |
| 15 | |
| 16 /* | |
| 17 ******************************************************************************** | |
| 18 * MODULE INCLUDE FILE AND VERSION ID | |
| 19 ******************************************************************************** | |
| 20 */ | |
| 21 #include "namespace.h" | |
| 22 #include "ec_gains.h" | |
| 23 | |
| 24 /* | |
| 25 ******************************************************************************** | |
| 26 * INCLUDE FILES | |
| 27 ******************************************************************************** | |
| 28 */ | |
| 29 #include "typedef.h" | |
| 30 #include "basic_op.h" | |
| 31 #include "oper_32b.h" | |
| 32 #include "no_count.h" | |
| 33 #include "cnst.h" | |
| 34 #include "gmed_n.h" | |
| 35 #include "gc_pred.h" | |
| 36 #include "gains_tab.h" | |
| 37 | |
| 38 /* | |
| 39 ******************************************************************************** | |
| 40 * PUBLIC PROGRAM CODE | |
| 41 ******************************************************************************** | |
| 42 */ | |
| 43 | |
| 44 /* | |
| 45 ************************************************************************** | |
| 46 * | |
| 47 * Function : ec_gain_code_reset | |
| 48 * Purpose : Resets state memory | |
| 49 * | |
| 50 ************************************************************************** | |
| 51 */ | |
| 52 void ec_gain_code_reset (ec_gain_codeState *state) | |
| 53 { | |
| 54 Word16 i; | |
| 55 | |
| 56 for ( i = 0; i < 5; i++) | |
| 57 state->gbuf[i] = 1; | |
| 58 state->past_gain_code = 0; | |
| 59 state->prev_gc = 1; | |
| 60 } | |
| 61 | |
| 62 /* | |
| 63 ************************************************************************** | |
| 64 * | |
| 65 * Function : ec_gain_code | |
| 66 * Purpose : conceal the codebook gain | |
| 67 * Call this function only in BFI (instead of normal gain | |
| 68 * decoding function) | |
| 69 * | |
| 70 ************************************************************************** | |
| 71 */ | |
| 72 void ec_gain_code ( | |
| 73 ec_gain_codeState *st, /* i/o : State struct */ | |
| 74 gc_predState *pred_state, /* i/o : MA predictor state */ | |
| 75 Word16 state, /* i : state of the state machine */ | |
| 76 Word16 *gain_code /* o : decoded innovation gain */ | |
| 77 ) | |
| 78 { | |
| 79 static const Word16 cdown[7] = | |
| 80 { | |
| 81 32767, 32112, 32112, 32112, | |
| 82 32112, 32112, 22937 | |
| 83 }; | |
| 84 | |
| 85 Word16 tmp; | |
| 86 Word16 qua_ener_MR122; | |
| 87 Word16 qua_ener; | |
| 88 | |
| 89 /* calculate median of last five gain values */ | |
| 90 tmp = gmed_n (st->gbuf,5); move16 (); | |
| 91 | |
| 92 /* new gain = minimum(median, past_gain) * cdown[state] */ | |
| 93 test (); | |
| 94 if (sub (tmp, st->past_gain_code) > 0) | |
| 95 { | |
| 96 tmp = st->past_gain_code; move16 (); | |
| 97 } | |
| 98 tmp = mult (tmp, cdown[state]); | |
| 99 *gain_code = tmp; move16 (); | |
| 100 | |
| 101 /* update table of past quantized energies with average of | |
| 102 * current values | |
| 103 */ | |
| 104 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener); | |
| 105 gc_pred_update(pred_state, qua_ener_MR122, qua_ener); | |
| 106 } | |
| 107 | |
| 108 /* | |
| 109 ************************************************************************** | |
| 110 * | |
| 111 * Function : ec_gain_code_update | |
| 112 * Purpose : update the codebook gain concealment state; | |
| 113 * limit gain_code if the previous frame was bad | |
| 114 * Call this function always after decoding (or concealing) | |
| 115 * the gain | |
| 116 * | |
| 117 ************************************************************************** | |
| 118 */ | |
| 119 void ec_gain_code_update ( | |
| 120 ec_gain_codeState *st, /* i/o : State struct */ | |
| 121 Word16 bfi, /* i : flag: frame is bad */ | |
| 122 Word16 prev_bf, /* i : flag: previous frame was bad */ | |
| 123 Word16 *gain_code /* i/o : decoded innovation gain */ | |
| 124 ) | |
| 125 { | |
| 126 Word16 i; | |
| 127 | |
| 128 /* limit gain_code by previous good gain if previous frame was bad */ | |
| 129 test (); | |
| 130 if (bfi == 0) | |
| 131 { | |
| 132 test (); | |
| 133 if (prev_bf != 0) | |
| 134 { | |
| 135 test (); | |
| 136 if (sub (*gain_code, st->prev_gc) > 0) | |
| 137 { | |
| 138 *gain_code = st->prev_gc; move16 (); | |
| 139 } | |
| 140 } | |
| 141 st->prev_gc = *gain_code; move16 (); | |
| 142 } | |
| 143 | |
| 144 /* update EC states: previous gain, gain buffer */ | |
| 145 st->past_gain_code = *gain_code; move16 (); | |
| 146 | |
| 147 for (i = 1; i < 5; i++) | |
| 148 { | |
| 149 st->gbuf[i - 1] = st->gbuf[i]; move16 (); | |
| 150 } | |
| 151 st->gbuf[4] = *gain_code; move16 (); | |
| 152 | |
| 153 return; | |
| 154 } | |
| 155 | |
| 156 /* | |
| 157 ************************************************************************** | |
| 158 * | |
| 159 * Function: ec_gain_pitch_reset | |
| 160 * Purpose: Resets state memory | |
| 161 * | |
| 162 ************************************************************************** | |
| 163 */ | |
| 164 void ec_gain_pitch_reset (ec_gain_pitchState *state) | |
| 165 { | |
| 166 Word16 i; | |
| 167 | |
| 168 for(i = 0; i < 5; i++) | |
| 169 state->pbuf[i] = 1640; | |
| 170 state->past_gain_pit = 0; | |
| 171 state->prev_gp = 16384; | |
| 172 } | |
| 173 | |
| 174 /* | |
| 175 ************************************************************************** | |
| 176 * | |
| 177 * Function : ec_gain_pitch | |
| 178 * Purpose : conceal the pitch gain | |
| 179 * Call this function only in BFI (instead of normal gain | |
| 180 * decoding function) | |
| 181 * | |
| 182 ************************************************************************** | |
| 183 */ | |
| 184 void ec_gain_pitch ( | |
| 185 ec_gain_pitchState *st, /* i/o : state variables */ | |
| 186 Word16 state, /* i : state of the state machine */ | |
| 187 Word16 *gain_pitch /* o : pitch gain (Q14) */ | |
| 188 ) | |
| 189 { | |
| 190 static const Word16 pdown[7] = | |
| 191 { | |
| 192 32767, 32112, 32112, 26214, | |
| 193 9830, 6553, 6553 | |
| 194 }; | |
| 195 | |
| 196 Word16 tmp; | |
| 197 | |
| 198 /* calculate median of last five gains */ | |
| 199 tmp = gmed_n (st->pbuf, 5); move16 (); | |
| 200 | |
| 201 /* new gain = minimum(median, past_gain) * pdown[state] */ | |
| 202 test (); | |
| 203 if (sub (tmp, st->past_gain_pit) > 0) | |
| 204 { | |
| 205 tmp = st->past_gain_pit; move16 (); | |
| 206 } | |
| 207 *gain_pitch = mult (tmp, pdown[state]); | |
| 208 } | |
| 209 | |
| 210 /* | |
| 211 ************************************************************************** | |
| 212 * | |
| 213 * Function : ec_gain_pitch_update | |
| 214 * Purpose : update the pitch gain concealment state; | |
| 215 * limit gain_pitch if the previous frame was bad | |
| 216 * Call this function always after decoding (or concealing) | |
| 217 * the gain | |
| 218 * | |
| 219 ************************************************************************** | |
| 220 */ | |
| 221 void ec_gain_pitch_update ( | |
| 222 ec_gain_pitchState *st, /* i/o : state variables */ | |
| 223 Word16 bfi, /* i : flag: frame is bad */ | |
| 224 Word16 prev_bf, /* i : flag: previous frame was bad */ | |
| 225 Word16 *gain_pitch /* i/o : pitch gain */ | |
| 226 ) | |
| 227 { | |
| 228 Word16 i; | |
| 229 | |
| 230 test (); | |
| 231 if (bfi == 0) | |
| 232 { | |
| 233 test (); | |
| 234 if (prev_bf != 0) | |
| 235 { | |
| 236 test (); | |
| 237 if (sub (*gain_pitch, st->prev_gp) > 0) | |
| 238 { | |
| 239 *gain_pitch = st->prev_gp; | |
| 240 } | |
| 241 } | |
| 242 st->prev_gp = *gain_pitch; move16 (); | |
| 243 } | |
| 244 | |
| 245 st->past_gain_pit = *gain_pitch; move16 (); | |
| 246 | |
| 247 test (); | |
| 248 if (sub (st->past_gain_pit, 16384) > 0) /* if (st->past_gain_pit > 1.0) */ | |
| 249 { | |
| 250 st->past_gain_pit = 16384; move16 (); | |
| 251 } | |
| 252 for (i = 1; i < 5; i++) | |
| 253 { | |
| 254 st->pbuf[i - 1] = st->pbuf[i]; move16 (); | |
| 255 } | |
| 256 st->pbuf[4] = st->past_gain_pit; move16 (); | |
| 257 } |
