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