FreeCalypso > hg > gsm-codec-lib
comparison libgsmefr/dtx.c @ 67:58b64224d4ac
libgsmefr: dtx.c compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 26 Nov 2022 05:09:07 +0000 |
parents | 824ff833bda9 |
children |
comparison
equal
deleted
inserted
replaced
66:824ff833bda9 | 67:58b64224d4ac |
---|---|
52 * interpolate_CN_lsf() | 52 * interpolate_CN_lsf() |
53 * interpolate_CN_param() | 53 * interpolate_CN_param() |
54 * | 54 * |
55 **************************************************************************/ | 55 **************************************************************************/ |
56 | 56 |
57 #include "gsm_efr.h" | |
57 #include "typedef.h" | 58 #include "typedef.h" |
59 #include "namespace.h" | |
58 #include "basic_op.h" | 60 #include "basic_op.h" |
59 #include "cnst.h" | 61 #include "cnst.h" |
60 #include "sig_proc.h" | 62 #include "sig_proc.h" |
61 #include "count.h" | 63 #include "memops.h" |
64 #include "no_count.h" | |
62 #include "dtx.h" | 65 #include "dtx.h" |
66 #include "enc_state.h" | |
67 #include "dec_state.h" | |
63 | 68 |
64 /* Inverse values of DTX hangover period and DTX hangover period + 1 */ | 69 /* Inverse values of DTX hangover period and DTX hangover period + 1 */ |
65 | 70 |
66 #define INV_DTX_HANGOVER (0x7fff / DTX_HANGOVER) | 71 #define INV_DTX_HANGOVER (0x7fff / DTX_HANGOVER) |
67 #define INV_DTX_HANGOVER_P1 (0x7fff / (DTX_HANGOVER+1)) | 72 #define INV_DTX_HANGOVER_P1 (0x7fff / (DTX_HANGOVER+1)) |
68 | 73 |
69 #define NB_PULSE 10 /* Number of pulses in fixed codebook excitation */ | 74 #define NB_PULSE 10 /* Number of pulses in fixed codebook excitation */ |
70 | |
71 /* SID frame classification thresholds */ | |
72 | |
73 #define VALID_SID_THRESH 2 | |
74 #define INVALID_SID_THRESH 16 | |
75 | 75 |
76 /* Constant DTX_ELAPSED_THRESHOLD is used as threshold for allowing | 76 /* Constant DTX_ELAPSED_THRESHOLD is used as threshold for allowing |
77 SID frame updating without hangover period in case when elapsed | 77 SID frame updating without hangover period in case when elapsed |
78 time measured from previous SID update is below 24 */ | 78 time measured from previous SID update is below 24 */ |
79 | 79 |
80 #define DTX_ELAPSED_THRESHOLD (24 + DTX_HANGOVER - 1) | 80 #define DTX_ELAPSED_THRESHOLD (24 + DTX_HANGOVER - 1) |
81 | 81 |
82 /* Index map for encoding and detecting SID codeword */ | |
83 | |
84 static const Word16 SID_codeword_bit_idx[95] = | |
85 { | |
86 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, | |
87 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, | |
88 66, 67, 68, 94, 95, 96, 98, 99, 100, 101, | |
89 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, | |
90 112, 113, 114, 115, 116, 117, 118, 148, 149, 150, | |
91 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, | |
92 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, | |
93 171, 196, 197, 198, 199, 200, 201, 202, 203, 204, | |
94 205, 206, 207, 208, 209, 212, 213, 214, 215, 216, | |
95 217, 218, 219, 220, 221 | |
96 }; | |
97 | |
98 Word16 txdtx_ctrl; /* Encoder DTX control word */ | |
99 Word16 rxdtx_ctrl; /* Decoder DTX control word */ | |
100 Word16 CN_excitation_gain; /* Unquantized fixed codebook gain */ | |
101 Word32 L_pn_seed_tx; /* PN generator seed (encoder) */ | |
102 Word32 L_pn_seed_rx; /* PN generator seed (decoder) */ | |
103 Word16 rx_dtx_state; /* State of comfort noise insertion period */ | |
104 | |
105 static Word16 txdtx_hangover; /* Length of hangover period (VAD=0, SP=1) */ | |
106 static Word16 rxdtx_aver_period;/* Length of hangover period (VAD=0, SP=1) */ | |
107 static Word16 txdtx_N_elapsed; /* Measured time from previous SID frame */ | |
108 static Word16 rxdtx_N_elapsed; /* Measured time from previous SID frame */ | |
109 static Word16 old_CN_mem_tx[6]; /* The most recent CN parameters are stored*/ | |
110 static Word16 prev_SID_frames_lost; /* Counter for lost SID frames */ | |
111 static Word16 buf_p_tx; /* Circular buffer pointer for gain code | |
112 history update in tx */ | |
113 static Word16 buf_p_rx; /* Circular buffer pointer for gain code | |
114 history update in rx */ | |
115 | |
116 Word16 lsf_old_tx[DTX_HANGOVER][M]; /* Comfort noise LSF averaging buffer */ | |
117 Word16 lsf_old_rx[DTX_HANGOVER][M]; /* Comfort noise LSF averaging buffer */ | |
118 | |
119 Word16 gain_code_old_tx[4 * DTX_HANGOVER]; /* Comfort noise gain averaging | |
120 buffer */ | |
121 Word16 gain_code_old_rx[4 * DTX_HANGOVER]; /* Comfort noise gain averaging | |
122 buffer */ | |
123 | |
124 /************************************************************************* | 82 /************************************************************************* |
125 * | 83 * |
126 * FUNCTION NAME: reset_tx_dtx | 84 * FUNCTION NAME: reset_tx_dtx |
127 * | 85 * |
128 * PURPOSE: Resets the static variables of the TX DTX handler to their | 86 * PURPOSE: Resets the static variables of the TX DTX handler to their |
129 * initial values | 87 * initial values |
130 * | 88 * |
131 *************************************************************************/ | 89 *************************************************************************/ |
132 | 90 |
133 void reset_tx_dtx () | 91 void reset_tx_dtx (struct EFR_encoder_state *st) |
134 { | 92 { |
135 Word16 i; | 93 Word16 i; |
136 | 94 |
137 /* suppose infinitely long speech period before start */ | 95 /* suppose infinitely long speech period before start */ |
138 | 96 |
139 txdtx_hangover = DTX_HANGOVER; | 97 st->txdtx_hangover = DTX_HANGOVER; |
140 txdtx_N_elapsed = 0x7fff; | 98 st->txdtx_N_elapsed = 0x7fff; |
141 txdtx_ctrl = TX_SP_FLAG | TX_VAD_FLAG; | 99 st->txdtx_ctrl = TX_SP_FLAG | TX_VAD_FLAG; |
142 | 100 |
143 for (i = 0; i < 6; i++) | 101 for (i = 0; i < 6; i++) |
144 { | 102 { |
145 old_CN_mem_tx[i] = 0; | 103 st->old_CN_mem_tx[i] = 0; |
146 } | 104 } |
147 | 105 |
148 for (i = 0; i < DTX_HANGOVER; i++) | 106 for (i = 0; i < DTX_HANGOVER; i++) |
149 { | 107 { |
150 lsf_old_tx[i][0] = 1384; | 108 st->lsf_old_tx[i][0] = 1384; |
151 lsf_old_tx[i][1] = 2077; | 109 st->lsf_old_tx[i][1] = 2077; |
152 lsf_old_tx[i][2] = 3420; | 110 st->lsf_old_tx[i][2] = 3420; |
153 lsf_old_tx[i][3] = 5108; | 111 st->lsf_old_tx[i][3] = 5108; |
154 lsf_old_tx[i][4] = 6742; | 112 st->lsf_old_tx[i][4] = 6742; |
155 lsf_old_tx[i][5] = 8122; | 113 st->lsf_old_tx[i][5] = 8122; |
156 lsf_old_tx[i][6] = 9863; | 114 st->lsf_old_tx[i][6] = 9863; |
157 lsf_old_tx[i][7] = 11092; | 115 st->lsf_old_tx[i][7] = 11092; |
158 lsf_old_tx[i][8] = 12714; | 116 st->lsf_old_tx[i][8] = 12714; |
159 lsf_old_tx[i][9] = 13701; | 117 st->lsf_old_tx[i][9] = 13701; |
160 } | 118 } |
161 | 119 |
162 for (i = 0; i < 4 * DTX_HANGOVER; i++) | 120 for (i = 0; i < 4 * DTX_HANGOVER; i++) |
163 { | 121 { |
164 gain_code_old_tx[i] = 0; | 122 st->gain_code_old_tx[i] = 0; |
165 } | 123 } |
166 | 124 |
167 L_pn_seed_tx = PN_INITIAL_SEED; | 125 st->L_pn_seed_tx = PN_INITIAL_SEED; |
168 | 126 |
169 buf_p_tx = 0; | 127 st->buf_p_tx = 0; |
170 return; | 128 return; |
171 } | 129 } |
172 | 130 |
173 /************************************************************************* | 131 /************************************************************************* |
174 * | 132 * |
177 * PURPOSE: Resets the static variables of the RX DTX handler to their | 135 * PURPOSE: Resets the static variables of the RX DTX handler to their |
178 * initial values | 136 * initial values |
179 * | 137 * |
180 *************************************************************************/ | 138 *************************************************************************/ |
181 | 139 |
182 void reset_rx_dtx () | 140 void reset_rx_dtx (struct EFR_decoder_state *st) |
183 { | 141 { |
184 Word16 i; | 142 Word16 i; |
185 | 143 |
186 /* suppose infinitely long speech period before start */ | 144 /* suppose infinitely long speech period before start */ |
187 | 145 |
188 rxdtx_aver_period = DTX_HANGOVER; | 146 st->rxdtx_aver_period = DTX_HANGOVER; |
189 rxdtx_N_elapsed = 0x7fff; | 147 st->rxdtx_N_elapsed = 0x7fff; |
190 rxdtx_ctrl = RX_SP_FLAG; | 148 st->rxdtx_ctrl = RX_SP_FLAG; |
191 | 149 |
192 for (i = 0; i < DTX_HANGOVER; i++) | 150 for (i = 0; i < DTX_HANGOVER; i++) |
193 { | 151 { |
194 lsf_old_rx[i][0] = 1384; | 152 st->lsf_old_rx[i][0] = 1384; |
195 lsf_old_rx[i][1] = 2077; | 153 st->lsf_old_rx[i][1] = 2077; |
196 lsf_old_rx[i][2] = 3420; | 154 st->lsf_old_rx[i][2] = 3420; |
197 lsf_old_rx[i][3] = 5108; | 155 st->lsf_old_rx[i][3] = 5108; |
198 lsf_old_rx[i][4] = 6742; | 156 st->lsf_old_rx[i][4] = 6742; |
199 lsf_old_rx[i][5] = 8122; | 157 st->lsf_old_rx[i][5] = 8122; |
200 lsf_old_rx[i][6] = 9863; | 158 st->lsf_old_rx[i][6] = 9863; |
201 lsf_old_rx[i][7] = 11092; | 159 st->lsf_old_rx[i][7] = 11092; |
202 lsf_old_rx[i][8] = 12714; | 160 st->lsf_old_rx[i][8] = 12714; |
203 lsf_old_rx[i][9] = 13701; | 161 st->lsf_old_rx[i][9] = 13701; |
204 } | 162 } |
205 | 163 |
206 for (i = 0; i < 4 * DTX_HANGOVER; i++) | 164 for (i = 0; i < 4 * DTX_HANGOVER; i++) |
207 { | 165 { |
208 gain_code_old_rx[i] = 0; | 166 st->gain_code_old_rx[i] = 0; |
209 } | 167 } |
210 | 168 |
211 L_pn_seed_rx = PN_INITIAL_SEED; | 169 st->L_pn_seed_rx = PN_INITIAL_SEED; |
212 rx_dtx_state = CN_INT_PERIOD - 1; | 170 st->rx_dtx_state = CN_INT_PERIOD - 1; |
213 | 171 |
214 prev_SID_frames_lost = 0; | 172 st->prev_SID_frames_lost = 0; |
215 buf_p_rx = 0; | 173 st->buf_p_rx = 0; |
216 | 174 |
217 return; | 175 return; |
218 } | 176 } |
219 | 177 |
220 /************************************************************************* | 178 /************************************************************************* |
240 * RETURN VALUE: none | 198 * RETURN VALUE: none |
241 * | 199 * |
242 *************************************************************************/ | 200 *************************************************************************/ |
243 | 201 |
244 void tx_dtx ( | 202 void tx_dtx ( |
245 Word16 VAD_flag, | 203 struct EFR_encoder_state *st, |
246 Word16 *txdtx_ctrl | 204 Word16 VAD_flag |
247 ) | 205 ) |
248 { | 206 { |
249 | |
250 /* N_elapsed (frames since last SID update) is incremented. If SID | 207 /* N_elapsed (frames since last SID update) is incremented. If SID |
251 is updated N_elapsed is cleared later in this function */ | 208 is updated N_elapsed is cleared later in this function */ |
252 | 209 |
253 txdtx_N_elapsed = add (txdtx_N_elapsed, 1); | 210 st->txdtx_N_elapsed = add (st->txdtx_N_elapsed, 1); |
254 | 211 |
255 /* If voice activity was detected, reset hangover counter */ | 212 /* If voice activity was detected, reset hangover counter */ |
256 | 213 |
257 test (); | |
258 if (sub (VAD_flag, 1) == 0) | 214 if (sub (VAD_flag, 1) == 0) |
259 { | 215 { |
260 txdtx_hangover = DTX_HANGOVER; move16 (); | 216 st->txdtx_hangover = DTX_HANGOVER; |
261 *txdtx_ctrl = TX_SP_FLAG | TX_VAD_FLAG; move16 (); logic16 (); | 217 st->txdtx_ctrl = TX_SP_FLAG | TX_VAD_FLAG; |
262 } | 218 } |
263 else | 219 else |
264 { | 220 { |
265 test (); | 221 if (st->txdtx_hangover == 0) |
266 if (txdtx_hangover == 0) | |
267 { | 222 { |
268 /* Hangover period is over, SID should be updated */ | 223 /* Hangover period is over, SID should be updated */ |
269 | 224 |
270 txdtx_N_elapsed = 0; move16 (); | 225 st->txdtx_N_elapsed = 0; |
271 | 226 |
272 /* Check if this is the first frame after hangover period */ | 227 /* Check if this is the first frame after hangover period */ |
273 test (); logic16 (); | 228 if ((st->txdtx_ctrl & TX_HANGOVER_ACTIVE) != 0) |
274 if ((*txdtx_ctrl & TX_HANGOVER_ACTIVE) != 0) | |
275 { | 229 { |
276 *txdtx_ctrl = TX_PREV_HANGOVER_ACTIVE | 230 st->txdtx_ctrl = TX_PREV_HANGOVER_ACTIVE |
277 | TX_SID_UPDATE; move16 (); logic16 (); | 231 | TX_SID_UPDATE; |
278 L_pn_seed_tx = PN_INITIAL_SEED; move32 (); | 232 st->L_pn_seed_tx = PN_INITIAL_SEED; |
279 } | 233 } |
280 else | 234 else |
281 { | 235 { |
282 *txdtx_ctrl = TX_SID_UPDATE; move16 (); | 236 st->txdtx_ctrl = TX_SID_UPDATE; |
283 } | 237 } |
284 } | 238 } |
285 else | 239 else |
286 { | 240 { |
287 /* Hangover period is not over, update hangover counter */ | 241 /* Hangover period is not over, update hangover counter */ |
288 txdtx_hangover = sub (txdtx_hangover, 1); | 242 st->txdtx_hangover = sub (st->txdtx_hangover, 1); |
289 | 243 |
290 /* Check if elapsed time from last SID update is greater than | 244 /* Check if elapsed time from last SID update is greater than |
291 threshold. If not, set SP=0 (although hangover period is not | 245 threshold. If not, set SP=0 (although hangover period is not |
292 over) and use old SID parameters for new SID frame. | 246 over) and use old SID parameters for new SID frame. |
293 N_elapsed counter must be summed with hangover counter in order | 247 N_elapsed counter must be summed with hangover counter in order |
294 to avoid erroneus SP=1 decision in case when N_elapsed is grown | 248 to avoid erroneus SP=1 decision in case when N_elapsed is grown |
295 bigger than threshold and hangover period is still active */ | 249 bigger than threshold and hangover period is still active */ |
296 | 250 |
297 test (); | 251 if (sub (add (st->txdtx_N_elapsed, st->txdtx_hangover), |
298 if (sub (add (txdtx_N_elapsed, txdtx_hangover), | |
299 DTX_ELAPSED_THRESHOLD) < 0) | 252 DTX_ELAPSED_THRESHOLD) < 0) |
300 { | 253 { |
301 /* old SID frame should be used */ | 254 /* old SID frame should be used */ |
302 *txdtx_ctrl = TX_USE_OLD_SID; move16 (); | 255 st->txdtx_ctrl = TX_USE_OLD_SID; |
303 } | 256 } |
304 else | 257 else |
305 { | 258 { |
306 test (); logic16 (); | 259 if ((st->txdtx_ctrl & TX_HANGOVER_ACTIVE) != 0) |
307 if ((*txdtx_ctrl & TX_HANGOVER_ACTIVE) != 0) | |
308 { | 260 { |
309 *txdtx_ctrl = TX_PREV_HANGOVER_ACTIVE | 261 st->txdtx_ctrl = TX_PREV_HANGOVER_ACTIVE |
310 | TX_HANGOVER_ACTIVE | 262 | TX_HANGOVER_ACTIVE |
311 | TX_SP_FLAG; move16 (); logic16 (); logic16 (); | 263 | TX_SP_FLAG; |
312 } | 264 } |
313 else | 265 else |
314 { | 266 { |
315 *txdtx_ctrl = TX_HANGOVER_ACTIVE | 267 st->txdtx_ctrl = TX_HANGOVER_ACTIVE |
316 | TX_SP_FLAG; move16 (); logic16 (); | 268 | TX_SP_FLAG; |
317 } | 269 } |
318 } | 270 } |
319 } | 271 } |
320 } | 272 } |
321 | 273 |
355 * RETURN VALUE: none | 307 * RETURN VALUE: none |
356 * | 308 * |
357 *************************************************************************/ | 309 *************************************************************************/ |
358 | 310 |
359 void rx_dtx ( | 311 void rx_dtx ( |
360 Word16 *rxdtx_ctrl, | 312 struct EFR_decoder_state *st, |
361 Word16 TAF, | 313 Word16 TAF, |
362 Word16 bfi, | 314 Word16 bfi, |
363 Word16 SID_flag | 315 Word16 SID_flag |
364 ) | 316 ) |
365 { | 317 { |
368 /* Frame classification according to bfi-flag and ternary-valued | 320 /* Frame classification according to bfi-flag and ternary-valued |
369 SID flag. The frames between SID updates (not actually trans- | 321 SID flag. The frames between SID updates (not actually trans- |
370 mitted) are also classified here; they will be discarded later | 322 mitted) are also classified here; they will be discarded later |
371 and provided with "NO TRANSMISSION"-flag */ | 323 and provided with "NO TRANSMISSION"-flag */ |
372 | 324 |
373 test (); test (); | |
374 test (); test (); | |
375 test (); test (); | |
376 if ((sub (SID_flag, 2) == 0) && (bfi == 0)) | 325 if ((sub (SID_flag, 2) == 0) && (bfi == 0)) |
377 { | 326 { |
378 frame_type = VALID_SID_FRAME; move16 (); | 327 frame_type = VALID_SID_FRAME; move16 (); |
379 } | 328 } |
380 else if ((SID_flag == 0) && (bfi == 0)) | 329 else if ((SID_flag == 0) && (bfi == 0)) |
390 frame_type = INVALID_SID_FRAME; move16 (); | 339 frame_type = INVALID_SID_FRAME; move16 (); |
391 } | 340 } |
392 | 341 |
393 /* Update of decoder state */ | 342 /* Update of decoder state */ |
394 /* Previous frame was classified as a speech frame */ | 343 /* Previous frame was classified as a speech frame */ |
395 test (); logic16 (); | 344 if ((st->rxdtx_ctrl & RX_SP_FLAG) != 0) |
396 if ((*rxdtx_ctrl & RX_SP_FLAG) != 0) | 345 { |
397 { | |
398 test (); test (); test (); test (); | |
399 if (sub (frame_type, VALID_SID_FRAME) == 0) | 346 if (sub (frame_type, VALID_SID_FRAME) == 0) |
400 { | 347 { |
401 *rxdtx_ctrl = RX_FIRST_SID_UPDATE; move16 (); | 348 st->rxdtx_ctrl = RX_FIRST_SID_UPDATE; |
402 } | 349 } |
403 else if (sub (frame_type, INVALID_SID_FRAME) == 0) | 350 else if (sub (frame_type, INVALID_SID_FRAME) == 0) |
404 { | 351 { |
405 *rxdtx_ctrl = RX_FIRST_SID_UPDATE | 352 st->rxdtx_ctrl = RX_FIRST_SID_UPDATE |
406 | RX_INVALID_SID_FRAME; move16 (); logic16(); | 353 | RX_INVALID_SID_FRAME; |
407 } | 354 } |
408 else if (sub (frame_type, UNUSABLE_FRAME) == 0) | 355 else if (sub (frame_type, UNUSABLE_FRAME) == 0) |
409 { | 356 { |
410 *rxdtx_ctrl = RX_SP_FLAG; move16 (); | 357 st->rxdtx_ctrl = RX_SP_FLAG; |
411 } | 358 } |
412 else if (sub (frame_type, GOOD_SPEECH_FRAME) == 0) | 359 else if (sub (frame_type, GOOD_SPEECH_FRAME) == 0) |
413 { | 360 { |
414 *rxdtx_ctrl = RX_SP_FLAG; move16 (); | 361 st->rxdtx_ctrl = RX_SP_FLAG; |
415 } | 362 } |
416 } | 363 } |
417 else | 364 else |
418 { | 365 { |
419 test (); test (); test (); test (); | |
420 if (sub (frame_type, VALID_SID_FRAME) == 0) | 366 if (sub (frame_type, VALID_SID_FRAME) == 0) |
421 { | 367 { |
422 *rxdtx_ctrl = RX_CONT_SID_UPDATE; move16 (); | 368 st->rxdtx_ctrl = RX_CONT_SID_UPDATE; |
423 } | 369 } |
424 else if (sub (frame_type, INVALID_SID_FRAME) == 0) | 370 else if (sub (frame_type, INVALID_SID_FRAME) == 0) |
425 { | 371 { |
426 *rxdtx_ctrl = RX_CONT_SID_UPDATE | 372 st->rxdtx_ctrl = RX_CONT_SID_UPDATE |
427 | RX_INVALID_SID_FRAME; move16 (); logic16 (); | 373 | RX_INVALID_SID_FRAME; |
428 } | 374 } |
429 else if (sub (frame_type, UNUSABLE_FRAME) == 0) | 375 else if (sub (frame_type, UNUSABLE_FRAME) == 0) |
430 { | 376 { |
431 *rxdtx_ctrl = RX_CNI_BFI; move16 (); | 377 st->rxdtx_ctrl = RX_CNI_BFI; |
432 } | 378 } |
433 else if (sub (frame_type, GOOD_SPEECH_FRAME) == 0) | 379 else if (sub (frame_type, GOOD_SPEECH_FRAME) == 0) |
434 { | 380 { |
435 /* If the previous frame (during CNI period) was muted, | 381 /* If the previous frame (during CNI period) was muted, |
436 raise the RX_PREV_DTX_MUTING flag */ | 382 raise the RX_PREV_DTX_MUTING flag */ |
437 test (); logic16 (); | 383 if ((st->rxdtx_ctrl & RX_DTX_MUTING) != 0) |
438 if ((*rxdtx_ctrl & RX_DTX_MUTING) != 0) | |
439 { | 384 { |
440 *rxdtx_ctrl = RX_SP_FLAG | RX_FIRST_SP_FLAG | 385 st->rxdtx_ctrl = RX_SP_FLAG | RX_FIRST_SP_FLAG |
441 | RX_PREV_DTX_MUTING; move16 (); logic16 (); | 386 | RX_PREV_DTX_MUTING; |
442 logic16 (); | |
443 } | 387 } |
444 else | 388 else |
445 { | 389 { |
446 *rxdtx_ctrl = RX_SP_FLAG | RX_FIRST_SP_FLAG; move16 (); | 390 st->rxdtx_ctrl = RX_SP_FLAG | RX_FIRST_SP_FLAG; |
447 logic16 (); | |
448 } | 391 } |
449 } | 392 } |
450 } | 393 } |
451 | 394 |
452 | 395 if ((st->rxdtx_ctrl & RX_SP_FLAG) != 0) |
453 test (); logic16 (); | 396 { |
454 if ((*rxdtx_ctrl & RX_SP_FLAG) != 0) | 397 st->prev_SID_frames_lost = 0; |
455 { | 398 st->rx_dtx_state = CN_INT_PERIOD - 1; |
456 prev_SID_frames_lost = 0; move16 (); | |
457 rx_dtx_state = CN_INT_PERIOD - 1; move16 (); | |
458 } | 399 } |
459 else | 400 else |
460 { | 401 { |
461 /* First SID frame */ | 402 /* First SID frame */ |
462 test (); logic16 (); | 403 if ((st->rxdtx_ctrl & RX_FIRST_SID_UPDATE) != 0) |
463 if ((*rxdtx_ctrl & RX_FIRST_SID_UPDATE) != 0) | 404 { |
464 { | 405 st->prev_SID_frames_lost = 0; |
465 prev_SID_frames_lost = 0; move16 (); | 406 st->rx_dtx_state = CN_INT_PERIOD - 1; |
466 rx_dtx_state = CN_INT_PERIOD - 1; move16 (); | |
467 } | 407 } |
468 | 408 |
469 /* SID frame detected, but not the first SID */ | 409 /* SID frame detected, but not the first SID */ |
470 test (); logic16 (); | 410 if ((st->rxdtx_ctrl & RX_CONT_SID_UPDATE) != 0) |
471 if ((*rxdtx_ctrl & RX_CONT_SID_UPDATE) != 0) | 411 { |
472 { | 412 st->prev_SID_frames_lost = 0; |
473 prev_SID_frames_lost = 0; move16 (); | 413 |
474 | |
475 test (); test (); | |
476 if (sub (frame_type, VALID_SID_FRAME) == 0) | 414 if (sub (frame_type, VALID_SID_FRAME) == 0) |
477 { | 415 { |
478 rx_dtx_state = 0; move16 (); | 416 st->rx_dtx_state = 0; |
479 } | 417 } |
480 else if (sub (frame_type, INVALID_SID_FRAME) == 0) | 418 else if (sub (frame_type, INVALID_SID_FRAME) == 0) |
481 { | 419 { |
482 test (); | 420 if (sub(st->rx_dtx_state, (CN_INT_PERIOD - 1)) < 0) |
483 if (sub(rx_dtx_state, (CN_INT_PERIOD - 1)) < 0) | |
484 { | 421 { |
485 rx_dtx_state = add(rx_dtx_state, 1); move16 (); | 422 st->rx_dtx_state = add(st->rx_dtx_state, 1); |
486 } | 423 } |
487 } | 424 } |
488 } | 425 } |
489 | 426 |
490 /* Bad frame received in CNI mode */ | 427 /* Bad frame received in CNI mode */ |
491 test (); logic16 (); | 428 if ((st->rxdtx_ctrl & RX_CNI_BFI) != 0) |
492 if ((*rxdtx_ctrl & RX_CNI_BFI) != 0) | 429 { |
493 { | 430 if (sub (st->rx_dtx_state, (CN_INT_PERIOD - 1)) < 0) |
494 test (); | |
495 if (sub (rx_dtx_state, (CN_INT_PERIOD - 1)) < 0) | |
496 { | 431 { |
497 rx_dtx_state = add (rx_dtx_state, 1); move16 (); | 432 st->rx_dtx_state = add (st->rx_dtx_state, 1); |
498 } | 433 } |
499 | 434 |
500 /* If an unusable frame is received during CNI period | 435 /* If an unusable frame is received during CNI period |
501 when TAF == 1, the frame is classified as a lost | 436 when TAF == 1, the frame is classified as a lost |
502 SID frame */ | 437 SID frame */ |
503 test (); | |
504 if (sub (TAF, 1) == 0) | 438 if (sub (TAF, 1) == 0) |
505 { | 439 { |
506 *rxdtx_ctrl = *rxdtx_ctrl | RX_LOST_SID_FRAME; | 440 st->rxdtx_ctrl = st->rxdtx_ctrl | RX_LOST_SID_FRAME; |
507 move16 (); logic16 (); | 441 st->prev_SID_frames_lost = add (st->prev_SID_frames_lost, 1); |
508 prev_SID_frames_lost = add (prev_SID_frames_lost, 1); | |
509 } | 442 } |
510 else /* No transmission occurred */ | 443 else /* No transmission occurred */ |
511 { | 444 { |
512 *rxdtx_ctrl = *rxdtx_ctrl | RX_NO_TRANSMISSION; | 445 st->rxdtx_ctrl = st->rxdtx_ctrl | RX_NO_TRANSMISSION; |
513 move16 (); logic16 (); | |
514 } | 446 } |
515 | 447 |
516 test (); | 448 if (sub (st->prev_SID_frames_lost, 1) > 0) |
517 if (sub (prev_SID_frames_lost, 1) > 0) | |
518 { | 449 { |
519 *rxdtx_ctrl = *rxdtx_ctrl | RX_DTX_MUTING; | 450 st->rxdtx_ctrl = st->rxdtx_ctrl | RX_DTX_MUTING; |
520 move16 (); logic16 (); | |
521 } | 451 } |
522 } | 452 } |
523 } | 453 } |
524 | 454 |
525 /* N_elapsed (frames since last SID update) is incremented. If SID | 455 /* N_elapsed (frames since last SID update) is incremented. If SID |
526 is updated N_elapsed is cleared later in this function */ | 456 is updated N_elapsed is cleared later in this function */ |
527 | 457 |
528 rxdtx_N_elapsed = add (rxdtx_N_elapsed, 1); | 458 st->rxdtx_N_elapsed = add (st->rxdtx_N_elapsed, 1); |
529 | 459 |
530 test (); logic16 (); | 460 if ((st->rxdtx_ctrl & RX_SP_FLAG) != 0) |
531 if ((*rxdtx_ctrl & RX_SP_FLAG) != 0) | 461 { |
532 { | 462 st->rxdtx_aver_period = DTX_HANGOVER; |
533 rxdtx_aver_period = DTX_HANGOVER; move16 (); | |
534 } | 463 } |
535 else | 464 else |
536 { | 465 { |
537 test (); test (); | 466 if (sub (st->rxdtx_N_elapsed, DTX_ELAPSED_THRESHOLD) > 0) |
538 if (sub (rxdtx_N_elapsed, DTX_ELAPSED_THRESHOLD) > 0) | 467 { |
539 { | 468 st->rxdtx_ctrl |= RX_UPD_SID_QUANT_MEM; |
540 *rxdtx_ctrl |= RX_UPD_SID_QUANT_MEM; move16 (); logic16 (); | 469 st->rxdtx_N_elapsed = 0; |
541 rxdtx_N_elapsed = 0; move16 (); | 470 st->rxdtx_aver_period = 0; |
542 rxdtx_aver_period = 0; move16 (); | 471 st->L_pn_seed_rx = PN_INITIAL_SEED; |
543 L_pn_seed_rx = PN_INITIAL_SEED; move32 (); | 472 } |
544 } | 473 else if (st->rxdtx_aver_period == 0) |
545 else if (rxdtx_aver_period == 0) | 474 { |
546 { | 475 st->rxdtx_N_elapsed = 0; |
547 rxdtx_N_elapsed = 0; move16 (); | |
548 } | 476 } |
549 else | 477 else |
550 { | 478 { |
551 rxdtx_aver_period = sub (rxdtx_aver_period, 1); | 479 st->rxdtx_aver_period = sub (st->rxdtx_aver_period, 1); |
552 } | 480 } |
553 } | 481 } |
554 | 482 |
555 return; | 483 return; |
556 } | 484 } |
572 * RETURN VALUE: none | 500 * RETURN VALUE: none |
573 * | 501 * |
574 *************************************************************************/ | 502 *************************************************************************/ |
575 | 503 |
576 void CN_encoding ( | 504 void CN_encoding ( |
505 struct EFR_encoder_state *st, | |
577 Word16 params[], | 506 Word16 params[], |
578 Word16 txdtx_ctrl | 507 Word16 txdtx_ctrl |
579 ) | 508 ) |
580 { | 509 { |
581 Word16 i; | 510 Word16 i; |
582 | 511 |
583 test (); logic16 (); | |
584 if ((txdtx_ctrl & TX_SID_UPDATE) != 0) | 512 if ((txdtx_ctrl & TX_SID_UPDATE) != 0) |
585 { | 513 { |
586 /* Store new CN parameters in memory to be used later as old | 514 /* Store new CN parameters in memory to be used later as old |
587 CN parameters */ | 515 CN parameters */ |
588 | 516 |
589 /* LPC parameter indices */ | 517 /* LPC parameter indices */ |
590 for (i = 0; i < 5; i++) | 518 for (i = 0; i < 5; i++) |
591 { | 519 { |
592 old_CN_mem_tx[i] = params[i]; move16 (); | 520 st->old_CN_mem_tx[i] = params[i]; |
593 } | 521 } |
594 /* Codebook index computed in last subframe */ | 522 /* Codebook index computed in last subframe */ |
595 old_CN_mem_tx[5] = params[56]; move16 (); | 523 st->old_CN_mem_tx[5] = params[56]; |
596 } | 524 } |
597 test (); logic16 (); | |
598 if ((txdtx_ctrl & TX_USE_OLD_SID) != 0) | 525 if ((txdtx_ctrl & TX_USE_OLD_SID) != 0) |
599 { | 526 { |
600 /* Use old CN parameters previously stored in memory */ | 527 /* Use old CN parameters previously stored in memory */ |
601 for (i = 0; i < 5; i++) | 528 for (i = 0; i < 5; i++) |
602 { | 529 { |
603 params[i] = old_CN_mem_tx[i]; move16 (); | 530 params[i] = st->old_CN_mem_tx[i]; |
604 } | 531 } |
605 params[17] = old_CN_mem_tx[5]; move16 (); | 532 params[17] = st->old_CN_mem_tx[5]; |
606 params[30] = old_CN_mem_tx[5]; move16 (); | 533 params[30] = st->old_CN_mem_tx[5]; |
607 params[43] = old_CN_mem_tx[5]; move16 (); | 534 params[43] = st->old_CN_mem_tx[5]; |
608 params[56] = old_CN_mem_tx[5]; move16 (); | 535 params[56] = st->old_CN_mem_tx[5]; |
609 } | 536 } |
610 /* Set all the rest of the parameters to zero (SID codeword will | 537 /* Set all the rest of the parameters to zero (SID codeword will |
611 be written later) */ | 538 be written later) */ |
612 for (i = 0; i < 12; i++) | 539 for (i = 0; i < 12; i++) |
613 { | 540 { |
614 params[i + 5] = 0; move16 (); | 541 params[i + 5] = 0; |
615 params[i + 18] = 0; move16 (); | 542 params[i + 18] = 0; |
616 params[i + 31] = 0; move16 (); | 543 params[i + 31] = 0; |
617 params[i + 44] = 0; move16 (); | 544 params[i + 44] = 0; |
618 } | 545 } |
619 | 546 |
620 return; | 547 return; |
621 } | |
622 | |
623 /************************************************************************* | |
624 * | |
625 * FUNCTION NAME: sid_codeword_encoding | |
626 * | |
627 * PURPOSE: Encoding of the SID codeword into the SID frame. The SID | |
628 * codeword consists of 95 bits, all set to '1'. | |
629 * | |
630 * INPUTS: ser2[0..243] Serial-mode speech parameter frame before | |
631 * writing SID codeword into it | |
632 * | |
633 * OUTPUTS: ser2[0..243] Serial-mode speech parameter frame with | |
634 * SID codeword written into it | |
635 * | |
636 * RETURN VALUE: none | |
637 * | |
638 *************************************************************************/ | |
639 | |
640 void sid_codeword_encoding ( | |
641 Word16 ser2[] | |
642 ) | |
643 { | |
644 Word16 i; | |
645 | |
646 for (i = 0; i < 95; i++) | |
647 { | |
648 ser2[SID_codeword_bit_idx[i]] = 1; move16 (); | |
649 } | |
650 | |
651 return; | |
652 } | |
653 | |
654 /************************************************************************* | |
655 * | |
656 * FUNCTION NAME: sid_frame_detection | |
657 * | |
658 * PURPOSE: Detecting of SID codeword from a received frame. The frames | |
659 * are classified into three categories based on how many bit | |
660 * errors occur in the SID codeword: | |
661 * - VALID SID FRAME | |
662 * - INVALID SID FRAME | |
663 * - SPEECH FRAME | |
664 * | |
665 * INPUTS: ser2[0..243] Received serial-mode speech parameter frame | |
666 * | |
667 * OUTPUTS: none | |
668 * | |
669 * RETURN VALUE: Ternary-valued SID classification flag | |
670 * | |
671 *************************************************************************/ | |
672 | |
673 Word16 sid_frame_detection ( | |
674 Word16 ser2[] | |
675 ) | |
676 { | |
677 Word16 i, nbr_errors, sid; | |
678 | |
679 /* Search for bit errors in SID codeword */ | |
680 nbr_errors = 0; move16 (); | |
681 for (i = 0; i < 95; i++) | |
682 { | |
683 test (); | |
684 if (ser2[SID_codeword_bit_idx[i]] == 0) | |
685 { | |
686 nbr_errors = add (nbr_errors, 1); | |
687 } | |
688 } | |
689 | |
690 /* Frame classification */ | |
691 test (); test (); | |
692 if (sub (nbr_errors, VALID_SID_THRESH) < 0) | |
693 { /* Valid SID frame */ | |
694 sid = 2; move16 (); | |
695 } | |
696 else if (sub (nbr_errors, INVALID_SID_THRESH) < 0) | |
697 { /* Invalid SID frame */ | |
698 sid = 1; move16 (); | |
699 } | |
700 else | |
701 { /* Speech frame */ | |
702 sid = 0; move16 (); | |
703 } | |
704 | |
705 return sid; | |
706 } | 548 } |
707 | 549 |
708 /************************************************************************* | 550 /************************************************************************* |
709 * | 551 * |
710 * FUNCTION NAME: update_lsf_history | 552 * FUNCTION NAME: update_lsf_history |
861 * RETURN VALUE: none | 703 * RETURN VALUE: none |
862 * | 704 * |
863 *************************************************************************/ | 705 *************************************************************************/ |
864 | 706 |
865 void update_gain_code_history_tx ( | 707 void update_gain_code_history_tx ( |
866 Word16 new_gain_code, | 708 struct EFR_encoder_state *st, |
867 Word16 gain_code_old_tx[4 * DTX_HANGOVER] | 709 Word16 new_gain_code |
868 ) | 710 ) |
869 { | 711 { |
870 | |
871 /* Circular buffer */ | 712 /* Circular buffer */ |
872 gain_code_old_tx[buf_p_tx] = new_gain_code; move16 (); | 713 st->gain_code_old_tx[st->buf_p_tx] = new_gain_code; |
873 | 714 |
874 test (); | 715 if (sub (st->buf_p_tx, (4 * DTX_HANGOVER - 1)) == 0) |
875 if (sub (buf_p_tx, (4 * DTX_HANGOVER - 1)) == 0) | 716 { |
876 { | 717 st->buf_p_tx = 0; |
877 buf_p_tx = 0; move16 (); | |
878 } | 718 } |
879 else | 719 else |
880 { | 720 { |
881 buf_p_tx = add (buf_p_tx, 1); | 721 st->buf_p_tx = add (st->buf_p_tx, 1); |
882 } | 722 } |
883 | 723 |
884 return; | 724 return; |
885 } | 725 } |
886 | 726 |
904 * RETURN VALUE: none | 744 * RETURN VALUE: none |
905 * | 745 * |
906 *************************************************************************/ | 746 *************************************************************************/ |
907 | 747 |
908 void update_gain_code_history_rx ( | 748 void update_gain_code_history_rx ( |
909 Word16 new_gain_code, | 749 struct EFR_decoder_state *st, |
910 Word16 gain_code_old_rx[4 * DTX_HANGOVER] | 750 Word16 new_gain_code |
911 ) | 751 ) |
912 { | 752 { |
913 | |
914 /* Circular buffer */ | 753 /* Circular buffer */ |
915 gain_code_old_rx[buf_p_rx] = new_gain_code; move16 (); | 754 st->gain_code_old_rx[st->buf_p_rx] = new_gain_code; |
916 | 755 |
917 test (); | 756 if (sub (st->buf_p_rx, (4 * DTX_HANGOVER - 1)) == 0) |
918 if (sub (buf_p_rx, (4 * DTX_HANGOVER - 1)) == 0) | 757 { |
919 { | 758 st->buf_p_rx = 0; |
920 buf_p_rx = 0; move16 (); | |
921 } | 759 } |
922 else | 760 else |
923 { | 761 { |
924 buf_p_rx = add (buf_p_rx, 1); | 762 st->buf_p_rx = add (st->buf_p_rx, 1); |
925 } | 763 } |
926 | 764 |
927 return; | 765 return; |
928 } | 766 } |
929 | 767 |