1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.073
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/dtx_enc.c
35 Funtions: dtx_enc_init
36 dtx_enc_reset
37 dtx_enc_exit
38 dtx_enc
39 dtx_buffer
40 tx_dtx_handler
41
42 Date: 06/08/2000
43
44 ------------------------------------------------------------------------------
45 REVISION HISTORY
46
47 Description: Updated template used to PV coding template. First attempt at
48 optimizing C code.
49
50 Description: Updated file per comments gathered from Phase 2/3 review.
51 Synched up with new template (Inputs/Outputs section). Deleted
52 lines leftover from original code prior to the code section of
53 dtx_enc_exit function. Deleted confusing comment in the log_en
54 calculation in dtx_enc function. Restructured IF statement in
55 the calculation of the sum of squares of speech signals in
56 dtx_buffer.
57
58 Description: Added setting of Overflow flag in inlined code.
59
60 Description: Synchronized file with UTMS version 3.2.0. Updated coding
61 template. Removed unnecessary include files.
62
63 Description: Made the following changes per comments from Phase 2/3 review:
64 1. Modified FOR loops to count down.
65 2. Fixed typecasting issue with TI C compiler.
66 3. Fixed comment in dtx_enc pseudo-code.
67 4. Added dtx_enc code comment pertaining to possible assembly
68 implementation.
69
70 Description: Added calls to add() in tx_dtx_handler. Updated copyright year.
71
72 Description: Pass in pointer to overflow flag to all functions requiring this
73 flag. This is to make the library EPOC compatible.
74
75 Description: For dtx_enc_reset() only
76 1. Replaced copy() with memcpy.
77 2. Eliminated include file copy.h
78 3. Eliminated printf statement
79 For dtx_buffer()
80 1. Replaced copy() with memcpy.
81 2. Eliminated math operations that unnecessary checked for
82 saturation, in some cases this by shifting before adding and
83 in other cases by evaluating the operands
84 3. Unrolled loop to speed up execution
85
86 Description: For dtx_buffer()
87 1. Modified scaling and added check for saturation. Previous
88 scaling was correct but altered precision, this cause bit
89 exactness test failure.
90
91 Description: For dtx_buffer()
92 1. Modified scaling and saturation checks. Previous
93 scaling was correct but altered precision, this cause bit
94 exactness test failure for dtx vad2.
95
96 Description: Replaced OSCL mem type functions and eliminated include
97 files that now are chosen by OSCL definitions
98
99 Description: Replaced "int" and/or "char" with OSCL defined types.
100
101 Description:
102
103 ------------------------------------------------------------------------------
104 MODULE DESCRIPTION
105
106 This file contains the various functions that perform the computation of the
107 Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX)
108 mode.
109
110 ------------------------------------------------------------------------------
111 */
112
113
114 /*----------------------------------------------------------------------------
115 ; INCLUDES
116 ----------------------------------------------------------------------------*/
117 #include <stdlib.h>
118 #include <string.h>
119
120 #include "dtx_enc.h"
121 #include "q_plsf.h"
122 #include "typedef.h"
123 #include "mode.h"
124 #include "basic_op.h"
125 #include "log2.h"
126 #include "lsp_lsf.h"
127 #include "reorder.h"
128
129 /*----------------------------------------------------------------------------
130 ; MACROS
131 ; Define module specific macros here
132 ----------------------------------------------------------------------------*/
133 extern Word32 L_add(Word32 L_var1, Word32 L_var2, Flag *pOverflow);
134
135 /*----------------------------------------------------------------------------
136 ; DEFINES
137 ; Include all pre-processor statements here. Include conditional
138 ; compile variables also.
139 ----------------------------------------------------------------------------*/
140
141 /*----------------------------------------------------------------------------
142 ; LOCAL FUNCTION DEFINITIONS
143 ; Function Prototype declaration
144 ----------------------------------------------------------------------------*/
145
146 /*----------------------------------------------------------------------------
147 ; LOCAL VARIABLE DEFINITIONS
148 ; Variable declaration - defined here and used outside this module
149 ----------------------------------------------------------------------------*/
150
151
152 /*
153 ------------------------------------------------------------------------------
154 FUNCTION NAME: dtx_enc_init
155 ------------------------------------------------------------------------------
156 INPUT AND OUTPUT DEFINITIONS
157
158 Inputs:
159 st = pointer to an array of pointers to structures of type
160 dtx_encState
161
162 Outputs:
163 pointer pointed to by st is set to the address of the allocated
164 memory
165
166 Returns:
167 return_value = 0, if initialization was successful; -1, otherwise (int)
168
169 Global Variables Used:
170 None
171
172 Local Variables Needed:
173 None
174
175 ------------------------------------------------------------------------------
176 FUNCTION DESCRIPTION
177
178 This function allocates the state memory used by the dtx_enc function.
179
180 ------------------------------------------------------------------------------
181 REQUIREMENTS
182
183 None
184
185 ------------------------------------------------------------------------------
186 REFERENCES
187
188 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
189
190 ------------------------------------------------------------------------------
191 PSEUDO-CODE
192
193 int dtx_enc_init (dtx_encState **st)
194 {
195 dtx_encState* s;
196
197 if (st == (dtx_encState **) NULL){
198 fprintf(stderr, "dtx_enc_init: invalid parameter\n");
199 return -1;
200 }
201
202 *st = NULL;
203
204 // allocate memory
205 if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){
206 fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
207 return -1;
208 }
209
210 dtx_enc_reset(s);
211 *st = s;
212
213 return 0;
214 }
215
216 ------------------------------------------------------------------------------
217 RESOURCES USED [optional]
218
219 When the code is written for a specific target processor the
220 the resources used should be documented below.
221
222 HEAP MEMORY USED: x bytes
223
224 STACK MEMORY USED: x bytes
225
226 CLOCK CYCLES: (cycle count equation for this function) + (variable
227 used to represent cycle count for each subroutine
228 called)
229 where: (cycle count variable) = cycle count for [subroutine
230 name]
231
232 ------------------------------------------------------------------------------
233 CAUTION [optional]
234 [State any special notes, constraints or cautions for users of this function]
235
236 ------------------------------------------------------------------------------
237 */
238
dtx_enc_init(dtx_encState ** st)239 Word16 dtx_enc_init(dtx_encState **st)
240 {
241 dtx_encState* s;
242
243 if (st == (dtx_encState **) NULL)
244 {
245 return(-1);
246 }
247
248 *st = NULL;
249
250 /* allocate memory */
251 if ((s = (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL)
252 {
253 return(-1);
254 }
255
256 dtx_enc_reset(s);
257 *st = s;
258
259 return(0);
260 }
261
262 /****************************************************************************/
263
264 /*
265 ------------------------------------------------------------------------------
266 FUNCTION NAME: dtx_enc_reset
267 ------------------------------------------------------------------------------
268 INPUT AND OUTPUT DEFINITIONS
269
270 Inputs:
271 st = pointer to structures of type dtx_encState
272
273 Outputs:
274 structure pointed to by st is initialized to its reset value
275
276 Returns:
277 return_value = 1, if reset was successful; -1, otherwise (int)
278
279 Global Variables Used:
280 None
281
282 Local Variables Needed:
283 lsp_init_data = table containing LSP initialization values;
284 table elements are constants of type Word16;
285 table length is M
286
287 ------------------------------------------------------------------------------
288 FUNCTION DESCRIPTION
289
290 This function initializes the fields of the state memory used by dtx_enc
291 to their reset values.
292
293 ------------------------------------------------------------------------------
294 REQUIREMENTS
295
296 None
297
298 ------------------------------------------------------------------------------
299 REFERENCES
300
301 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
302
303 ------------------------------------------------------------------------------
304 PSEUDO-CODE
305
306 int dtx_enc_reset (dtx_encState *st)
307 {
308 Word16 i;
309
310 if (st == (dtx_encState *) NULL){
311 fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
312 return -1;
313 }
314
315 st->hist_ptr = 0;
316 st->log_en_index = 0;
317 st->init_lsf_vq_index = 0;
318 st->lsp_index[0] = 0;
319 st->lsp_index[1] = 0;
320 st->lsp_index[2] = 0;
321
322 // Init lsp_hist[]
323 for(i = 0; i < DTX_HIST_SIZE; i++)
324 {
325 Copy(lsp_init_data, &st->lsp_hist[i * M], M);
326 }
327
328 // Reset energy history
329 Set_zero(st->log_en_hist, M);
330
331 st->dtxHangoverCount = DTX_HANG_CONST;
332 st->decAnaElapsedCount = 32767;
333
334 return 1;
335 }
336
337 ------------------------------------------------------------------------------
338 RESOURCES USED [optional]
339
340 When the code is written for a specific target processor the
341 the resources used should be documented below.
342
343 HEAP MEMORY USED: x bytes
344
345 STACK MEMORY USED: x bytes
346
347 CLOCK CYCLES: (cycle count equation for this function) + (variable
348 used to represent cycle count for each subroutine
349 called)
350 where: (cycle count variable) = cycle count for [subroutine
351 name]
352
353 ------------------------------------------------------------------------------
354 CAUTION [optional]
355 [State any special notes, constraints or cautions for users of this function]
356
357 ------------------------------------------------------------------------------
358 */
359
dtx_enc_reset(dtx_encState * st)360 Word16 dtx_enc_reset(dtx_encState *st)
361 {
362 Word16 i;
363
364 if (st == (dtx_encState *) NULL)
365 {
366 return(-1);
367 }
368
369 st->hist_ptr = 0;
370 st->log_en_index = 0;
371 st->init_lsf_vq_index = 0;
372 st->lsp_index[0] = 0;
373 st->lsp_index[1] = 0;
374 st->lsp_index[2] = 0;
375
376 /* Init lsp_hist[] */
377 for (i = 0; i < DTX_HIST_SIZE; i++)
378 {
379 memcpy(&st->lsp_hist[i * M], lsp_init_data, M*sizeof(Word16));
380 }
381
382 /* Reset energy history */
383 memset(st->log_en_hist, 0, sizeof(Word16)*M);
384 st->dtxHangoverCount = DTX_HANG_CONST;
385 st->decAnaElapsedCount = 32767;
386
387 return(1);
388 }
389
390 /****************************************************************************/
391
392 /*
393 ------------------------------------------------------------------------------
394 FUNCTION NAME: dtx_enc_exit
395 ------------------------------------------------------------------------------
396 INPUT AND OUTPUT DEFINITIONS
397
398 Inputs:
399 st = pointer to an array of pointers to structures of type
400 dtx_encState
401
402 Outputs:
403 st points to the NULL address
404
405 Returns:
406 None
407
408 Global Variables Used:
409 None
410
411 Local Variables Needed:
412 None
413
414 ------------------------------------------------------------------------------
415 FUNCTION DESCRIPTION
416
417 This function deallocates the state memory used by dtx_enc function.
418
419 ------------------------------------------------------------------------------
420 REQUIREMENTS
421
422 None
423
424 ------------------------------------------------------------------------------
425 REFERENCES
426
427 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
428
429 ------------------------------------------------------------------------------
430 PSEUDO-CODE
431
432 void dtx_enc_exit (dtx_encState **st)
433 {
434 if (st == NULL || *st == NULL)
435 return;
436
437 // deallocate memory
438 free(*st);
439 *st = NULL;
440
441 return;
442 }
443
444 ------------------------------------------------------------------------------
445 RESOURCES USED [optional]
446
447 When the code is written for a specific target processor the
448 the resources used should be documented below.
449
450 HEAP MEMORY USED: x bytes
451
452 STACK MEMORY USED: x bytes
453
454 CLOCK CYCLES: (cycle count equation for this function) + (variable
455 used to represent cycle count for each subroutine
456 called)
457 where: (cycle count variable) = cycle count for [subroutine
458 name]
459
460 ------------------------------------------------------------------------------
461 CAUTION [optional]
462 [State any special notes, constraints or cautions for users of this function]
463
464 ------------------------------------------------------------------------------
465 */
466
dtx_enc_exit(dtx_encState ** st)467 void dtx_enc_exit(dtx_encState **st)
468 {
469 if (st == NULL || *st == NULL)
470 {
471 return;
472 }
473
474 /* deallocate memory */
475 free(*st);
476 *st = NULL;
477
478 return;
479 }
480
481 /****************************************************************************/
482
483 /*
484 ------------------------------------------------------------------------------
485 FUNCTION NAME: dtx_enc
486 ------------------------------------------------------------------------------
487 INPUT AND OUTPUT DEFINITIONS
488
489 Inputs:
490 st = pointer to structures of type dtx_encState
491 computeSidFlag = compute SID flag of type Word16
492 qSt = pointer to structures of type Q_plsfState
493 predState = pointer to structures of type gc_predState
494 anap = pointer to an array of pointers to analysis parameters of
495 type Word16
496
497 Outputs:
498 structure pointed to by st contains the newly calculated SID
499 parameters
500 structure pointed to by predState contains the new logarithmic frame
501 energy
502 pointer pointed to by anap points to the location of the new
503 logarithmic frame energy and new LSPs
504
505 Returns:
506 return_value = 0 (int)
507
508 Global Variables Used:
509 None
510
511 Local Variables Needed:
512 None
513
514 ------------------------------------------------------------------------------
515 FUNCTION DESCRIPTION
516
517 This function calculates the SID parameters when in the DTX mode.
518
519 ------------------------------------------------------------------------------
520 REQUIREMENTS
521
522 None
523
524 ------------------------------------------------------------------------------
525 REFERENCES
526
527 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
528
529 ------------------------------------------------------------------------------
530 PSEUDO-CODE
531
532 int dtx_enc(dtx_encState *st, // i/o : State struct
533 Word16 computeSidFlag, // i : compute SID
534 Q_plsfState *qSt, // i/o : Qunatizer state struct
535 gc_predState* predState, // i/o : State struct
536 Word16 **anap // o : analysis parameters
537 )
538 {
539 Word16 i,j;
540 Word16 log_en;
541 Word16 lsf[M];
542 Word16 lsp[M];
543 Word16 lsp_q[M];
544 Word32 L_lsp[M];
545
546 // VOX mode computation of SID parameters
547 if ((computeSidFlag != 0) ||
548 (st->log_en_index == 0))
549 {
550 // compute new SID frame if safe i.e don't
551 // compute immediately after a talk spurt
552 log_en = 0;
553 for (i = 0; i < M; i++)
554 {
555 L_lsp[i] = 0;
556 }
557
558 // average energy and lsp
559 for (i = 0; i < DTX_HIST_SIZE; i++)
560 {
561 log_en = add(log_en,
562 shr(st->log_en_hist[i],2));
563
564 for (j = 0; j < M; j++)
565 {
566 L_lsp[j] = L_add(L_lsp[j],
567 L_deposit_l(st->lsp_hist[i * M + j]));
568 }
569 }
570
571 log_en = shr(log_en, 1);
572 for (j = 0; j < M; j++)
573 {
574 lsp[j] = extract_l(L_shr(L_lsp[j], 3)); // divide by 8
575 }
576
577 // quantize logarithmic energy to 6 bits
578 st->log_en_index = add(log_en, 2560); // +2.5 in Q10
579 st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10
580 st->log_en_index = shr(st->log_en_index, 8);
581
582 if (sub(st->log_en_index, 63) > 0)
583 {
584 st->log_en_index = 63;
585 }
586 if (st->log_en_index < 0)
587 {
588 st->log_en_index = 0;
589 }
590
591 // update gain predictor memory
592 log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4
593 log_en = sub(log_en, 2560); // add 2.5 in Q11
594
595 log_en = sub(log_en, 9000);
596 if (log_en > 0)
597 {
598 log_en = 0;
599 }
600 if (sub(log_en, -14436) < 0)
601 {
602 log_en = -14436;
603 }
604
605 // past_qua_en for other modes than MR122
606 predState->past_qua_en[0] = log_en;
607 predState->past_qua_en[1] = log_en;
608 predState->past_qua_en[2] = log_en;
609 predState->past_qua_en[3] = log_en;
610
611 // scale down by factor 20*log10(2) in Q15
612 log_en = mult(5443, log_en);
613
614 // past_qua_en for mode MR122
615 predState->past_qua_en_MR122[0] = log_en;
616 predState->past_qua_en_MR122[1] = log_en;
617 predState->past_qua_en_MR122[2] = log_en;
618 predState->past_qua_en_MR122[3] = log_en;
619
620 // make sure that LSP's are ordered
621 Lsp_lsf(lsp, lsf, M);
622 Reorder_lsf(lsf, LSF_GAP, M);
623 Lsf_lsp(lsf, lsp, M);
624
625 // Quantize lsp and put on parameter list
626 Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
627 &st->init_lsf_vq_index);
628 }
629
630 *(*anap)++ = st->init_lsf_vq_index; // 3 bits
631
632 *(*anap)++ = st->lsp_index[0]; // 8 bits
633 *(*anap)++ = st->lsp_index[1]; // 9 bits
634 *(*anap)++ = st->lsp_index[2]; // 9 bits
635
636
637 *(*anap)++ = st->log_en_index; // 6 bits
638 // = 35 bits
639
640 return 0;
641 }
642
643 ------------------------------------------------------------------------------
644 RESOURCES USED [optional]
645
646 When the code is written for a specific target processor the
647 the resources used should be documented below.
648
649 HEAP MEMORY USED: x bytes
650
651 STACK MEMORY USED: x bytes
652
653 CLOCK CYCLES: (cycle count equation for this function) + (variable
654 used to represent cycle count for each subroutine
655 called)
656 where: (cycle count variable) = cycle count for [subroutine
657 name]
658
659 ------------------------------------------------------------------------------
660 CAUTION [optional]
661 [State any special notes, constraints or cautions for users of this function]
662
663 ------------------------------------------------------------------------------
664 */
665
dtx_enc(dtx_encState * st,Word16 computeSidFlag,Q_plsfState * qSt,gc_predState * predState,Word16 ** anap,Flag * pOverflow)666 void dtx_enc(dtx_encState *st, /* i/o : State struct */
667 Word16 computeSidFlag, /* i : compute SID */
668 Q_plsfState *qSt, /* i/o : Qunatizer state struct */
669 gc_predState* predState, /* i/o : State struct */
670 Word16 **anap, /* o : analysis parameters */
671 Flag *pOverflow /* i/o : overflow indicator */
672 )
673 {
674 Word16 i, j;
675 Word16 temp;
676 Word16 log_en;
677 Word16 lsf[M];
678 Word16 lsp[M];
679 Word16 lsp_q[M];
680 Word32 L_lsp[M];
681
682 /* VOX mode computation of SID parameters */
683
684 if ((computeSidFlag != 0) ||
685 (st->log_en_index == 0))
686 {
687 /* compute new SID frame if safe i.e don't
688 * compute immediately after a talk spurt */
689 log_en = 0;
690 for (i = M - 1; i >= 0; i--)
691 {
692 L_lsp[i] = 0;
693 }
694
695 /* average energy and lsp */
696 for (i = DTX_HIST_SIZE - 1; i >= 0; i--)
697 {
698 if (st->log_en_hist[i] < 0)
699 {
700 temp = ~((~(st->log_en_hist[i])) >> 2);
701 }
702 else
703 {
704 temp = st->log_en_hist[i] >> 2;
705 }
706 log_en = add(log_en, temp, pOverflow);
707
708 for (j = M - 1; j >= 0; j--)
709 {
710 L_lsp[j] = L_add(L_lsp[j],
711 (Word32)(st->lsp_hist[i * M + j]),
712 pOverflow);
713 }
714 }
715
716 if (log_en < 0)
717 {
718 log_en = ~((~log_en) >> 1);
719 }
720 else
721 {
722 log_en = log_en >> 1;
723 }
724
725 for (j = M - 1; j >= 0; j--)
726 {
727 /* divide by 8 */
728 if (L_lsp[j] < 0)
729 {
730 lsp[j] = (Word16)(~((~L_lsp[j]) >> 3));
731 }
732 else
733 {
734 lsp[j] = (Word16)(L_lsp[j] >> 3);
735 }
736 }
737
738 /* quantize logarithmic energy to 6 bits */
739 /* +2.5 in Q10 */
740 st->log_en_index = add(log_en, 2560, pOverflow);
741 /* add 0.5/4 in Q10 */
742 st->log_en_index = add(st->log_en_index, 128, pOverflow);
743 if (st->log_en_index < 0)
744 {
745 st->log_en_index = ~((~st->log_en_index) >> 8);
746 }
747 else
748 {
749 st->log_en_index = st->log_en_index >> 8;
750 }
751
752 /*---------------------------------------------*/
753 /* Limit to max and min allowable 6-bit values */
754 /* Note: For assembly implementation, use the */
755 /* following: */
756 /* if(st->long_en_index >> 6 != 0) */
757 /* { */
758 /* if(st->long_en_index < 0) */
759 /* { */
760 /* st->long_en_index = 0 */
761 /* } */
762 /* else */
763 /* { */
764 /* st->long_en_index = 63 */
765 /* } */
766 /* } */
767 /*---------------------------------------------*/
768 if (st->log_en_index > 63)
769 {
770 st->log_en_index = 63;
771 }
772 else if (st->log_en_index < 0)
773 {
774 st->log_en_index = 0;
775 }
776
777 /* update gain predictor memory */
778 /* Q11 and divide by 4 */
779 log_en = (Word16)(((Word32) st->log_en_index) << (-2 + 10));
780
781 log_en = sub(log_en, 11560, pOverflow);
782
783 if (log_en > 0)
784 {
785 log_en = 0;
786 }
787 else if (log_en < -14436)
788 {
789 log_en = -14436;
790 }
791
792 /* past_qua_en for other modes than MR122 */
793 predState->past_qua_en[0] = log_en;
794 predState->past_qua_en[1] = log_en;
795 predState->past_qua_en[2] = log_en;
796 predState->past_qua_en[3] = log_en;
797
798 /* scale down by factor 20*log10(2) in Q15 */
799 log_en = (Word16)(((Word32)(5443 * log_en)) >> 15);
800
801 /* past_qua_en for mode MR122 */
802 predState->past_qua_en_MR122[0] = log_en;
803 predState->past_qua_en_MR122[1] = log_en;
804 predState->past_qua_en_MR122[2] = log_en;
805 predState->past_qua_en_MR122[3] = log_en;
806
807 /* make sure that LSP's are ordered */
808 Lsp_lsf(lsp, lsf, M, pOverflow);
809 Reorder_lsf(lsf, LSF_GAP, M, pOverflow);
810 Lsf_lsp(lsf, lsp, M, pOverflow);
811
812 /* Quantize lsp and put on parameter list */
813 Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
814 &st->init_lsf_vq_index, pOverflow);
815 }
816
817 *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */
818 *(*anap)++ = st->lsp_index[0]; /* 8 bits */
819 *(*anap)++ = st->lsp_index[1]; /* 9 bits */
820 *(*anap)++ = st->lsp_index[2]; /* 9 bits */
821 *(*anap)++ = st->log_en_index; /* 6 bits */
822 /* = 35 bits */
823
824 }
825
826 /****************************************************************************/
827
828
829 /*
830 ------------------------------------------------------------------------------
831 FUNCTION NAME: dtx_buffer
832 ------------------------------------------------------------------------------
833 INPUT AND OUTPUT DEFINITIONS
834
835 Inputs:
836 st = pointer to structures of type dtx_encState
837 lsp_new = LSP vector whose elements are of type Word16; vector
838 length is M
839 speech = vector of speech samples of type Word16; vector length is
840 BFR_SIZE_GSM
841
842 Outputs:
843 structure pointed to by st contains the new LSPs and logarithmic
844 frame energy
845
846 Returns:
847 return_value = 0 (int)
848
849 Global Variables Used:
850 None
851
852 Local Variables Needed:
853 None
854
855 ------------------------------------------------------------------------------
856 FUNCTION DESCRIPTION
857
858 This function handles the DTX buffer.
859
860 ------------------------------------------------------------------------------
861 REQUIREMENTS
862
863 None
864
865 ------------------------------------------------------------------------------
866 REFERENCES
867
868 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
869
870 ------------------------------------------------------------------------------
871 PSEUDO-CODE
872
873 int dtx_buffer(dtx_encState *st, // i/o : State struct
874 Word16 lsp_new[], // i : LSP vector
875 Word16 speech[] // i : speech samples
876 )
877 {
878 Word16 i;
879 Word32 L_frame_en;
880 Word16 log_en_e;
881 Word16 log_en_m;
882 Word16 log_en;
883
884 // update pointer to circular buffer
885 st->hist_ptr = add(st->hist_ptr, 1);
886 if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
887 {
888 st->hist_ptr = 0;
889 }
890
891 // copy lsp vector into buffer
892 Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
893
894 // compute log energy based on frame energy
895 L_frame_en = 0; // Q0
896 for (i=0; i < L_FRAME; i++)
897 {
898 L_frame_en = L_mac(L_frame_en, speech[i], speech[i]);
899 }
900 Log2(L_frame_en, &log_en_e, &log_en_m);
901
902 // convert exponent and mantissa to Word16 Q10
903 log_en = shl(log_en_e, 10); // Q10
904 log_en = add(log_en, shr(log_en_m, 15-10));
905
906 // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193
907 log_en = sub(log_en, 8521);
908
909 // insert into log energy buffer with division by 2
910 log_en = shr(log_en, 1);
911 st->log_en_hist[st->hist_ptr] = log_en; // Q10
912
913 return 0;
914 }
915
916 ------------------------------------------------------------------------------
917 RESOURCES USED [optional]
918
919 When the code is written for a specific target processor the
920 the resources used should be documented below.
921
922 HEAP MEMORY USED: x bytes
923
924 STACK MEMORY USED: x bytes
925
926 CLOCK CYCLES: (cycle count equation for this function) + (variable
927 used to represent cycle count for each subroutine
928 called)
929 where: (cycle count variable) = cycle count for [subroutine
930 name]
931
932 ------------------------------------------------------------------------------
933 CAUTION [optional]
934 [State any special notes, constraints or cautions for users of this function]
935
936 ------------------------------------------------------------------------------
937 */
938
dtx_buffer(dtx_encState * st,Word16 lsp_new[],Word16 speech[],Flag * pOverflow)939 void dtx_buffer(dtx_encState *st, /* i/o : State struct */
940 Word16 lsp_new[], /* i : LSP vector */
941 Word16 speech[], /* i : speech samples */
942 Flag *pOverflow /* i/o : overflow indicator */
943 )
944 {
945
946 Word16 i;
947 Word32 L_frame_en;
948 Word32 L_temp;
949 Word16 log_en_e;
950 Word16 log_en_m;
951 Word16 log_en;
952 Word16 *p_speech = &speech[0];
953
954 /* update pointer to circular buffer */
955 st->hist_ptr += 1;
956
957 if (st->hist_ptr == DTX_HIST_SIZE)
958 {
959 st->hist_ptr = 0;
960 }
961
962 /* copy lsp vector into buffer */
963 memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16));
964
965 /* compute log energy based on frame energy */
966 L_frame_en = 0; /* Q0 */
967
968 for (i = L_FRAME; i != 0; i--)
969 {
970 L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1;
971 p_speech++;
972 if (L_frame_en < 0)
973 {
974 L_frame_en = MAX_32;
975 break;
976 }
977 }
978
979 Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow);
980
981 /* convert exponent and mantissa to Word16 Q10 */
982 /* Q10 */
983 L_temp = ((Word32) log_en_e) << 10;
984 if (L_temp != (Word32)((Word16) L_temp))
985 {
986 *pOverflow = 1;
987 log_en = (log_en_e > 0) ? MAX_16 : MIN_16;
988 }
989 else
990 {
991 log_en = (Word16) L_temp;
992 }
993
994 log_en += log_en_m >> (15 - 10);
995
996 /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
997 log_en -= 8521;
998
999 /* insert into log energy buffer with division by 2 */
1000
1001 st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */
1002
1003 }
1004
1005 /****************************************************************************/
1006
1007 /*
1008 ------------------------------------------------------------------------------
1009 FUNCTION NAME: tx_dtx_handler
1010 ------------------------------------------------------------------------------
1011 INPUT AND OUTPUT DEFINITIONS
1012
1013 Inputs:
1014 st = pointer to structures of type dtx_encState
1015 vad_flag = VAD decision flag of type Word16
1016 usedMode = pointer to the currently used mode of type enum Mode
1017
1018 Outputs:
1019 structure pointed to by st contains the newly calculated speech
1020 hangover
1021
1022 Returns:
1023 compute_new_sid_possible = flag to indicate a change in the
1024 used mode; store type is Word16
1025
1026 Global Variables Used:
1027 None
1028
1029 Local Variables Needed:
1030 None
1031
1032 ------------------------------------------------------------------------------
1033 FUNCTION DESCRIPTION
1034
1035 This function adds extra speech hangover to analyze speech on the decoding
1036 side.
1037
1038 ------------------------------------------------------------------------------
1039 REQUIREMENTS
1040
1041 None
1042
1043 ------------------------------------------------------------------------------
1044 REFERENCES
1045
1046 dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1047
1048 ------------------------------------------------------------------------------
1049 PSEUDO-CODE
1050
1051 Word16 tx_dtx_handler(dtx_encState *st, // i/o : State struct
1052 Word16 vad_flag, // i : vad decision
1053 enum Mode *usedMode // i/o : mode changed or not
1054 )
1055 {
1056 Word16 compute_new_sid_possible;
1057
1058 // this state machine is in synch with the GSMEFR txDtx machine
1059 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
1060
1061 compute_new_sid_possible = 0;
1062
1063 if (vad_flag != 0)
1064 {
1065 st->dtxHangoverCount = DTX_HANG_CONST;
1066 }
1067 else
1068 { // non-speech
1069 if (st->dtxHangoverCount == 0)
1070 { // out of decoder analysis hangover
1071 st->decAnaElapsedCount = 0;
1072 *usedMode = MRDTX;
1073 compute_new_sid_possible = 1;
1074 }
1075 else
1076 { // in possible analysis hangover
1077 st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
1078
1079 // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH
1080 if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
1081 DTX_ELAPSED_FRAMES_THRESH) < 0)
1082 {
1083 *usedMode = MRDTX;
1084 // if short time since decoder update, do not add extra HO
1085 }
1086 // else
1087 // override VAD and stay in
1088 // speech mode *usedMode
1089 // and add extra hangover
1090 }
1091 }
1092
1093 return compute_new_sid_possible;
1094 }
1095
1096 ------------------------------------------------------------------------------
1097 RESOURCES USED [optional]
1098
1099 When the code is written for a specific target processor the
1100 the resources used should be documented below.
1101
1102 HEAP MEMORY USED: x bytes
1103
1104 STACK MEMORY USED: x bytes
1105
1106 CLOCK CYCLES: (cycle count equation for this function) + (variable
1107 used to represent cycle count for each subroutine
1108 called)
1109 where: (cycle count variable) = cycle count for [subroutine
1110 name]
1111
1112 ------------------------------------------------------------------------------
1113 CAUTION [optional]
1114 [State any special notes, constraints or cautions for users of this function]
1115
1116 ------------------------------------------------------------------------------
1117 */
1118
tx_dtx_handler(dtx_encState * st,Word16 vad_flag,enum Mode * usedMode,Flag * pOverflow)1119 Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */
1120 Word16 vad_flag, /* i : vad decision */
1121 enum Mode *usedMode, /* i/o : mode changed or not */
1122 Flag *pOverflow /* i/o : overflow indicator */
1123 )
1124 {
1125 Word16 compute_new_sid_possible;
1126 Word16 count;
1127
1128 /* this state machine is in synch with the GSMEFR txDtx machine */
1129 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow);
1130
1131 compute_new_sid_possible = 0;
1132
1133 if (vad_flag != 0)
1134 {
1135 st->dtxHangoverCount = DTX_HANG_CONST;
1136 }
1137 else
1138 { /* non-speech */
1139 if (st->dtxHangoverCount == 0)
1140 { /* out of decoder analysis hangover */
1141 st->decAnaElapsedCount = 0;
1142 *usedMode = MRDTX;
1143 compute_new_sid_possible = 1;
1144 }
1145 else
1146 { /* in possible analysis hangover */
1147 st->dtxHangoverCount -= 1;
1148
1149 /* decAnaElapsedCount + dtxHangoverCount < */
1150 /* DTX_ELAPSED_FRAMES_THRESH */
1151 count = add(st->decAnaElapsedCount, st->dtxHangoverCount,
1152 pOverflow);
1153 if (count < DTX_ELAPSED_FRAMES_THRESH)
1154 {
1155 *usedMode = MRDTX;
1156 /* if short time since decoder update, */
1157 /* do not add extra HO */
1158 }
1159 }
1160 }
1161
1162 return(compute_new_sid_possible);
1163 }
1164