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