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 Pathname: ./audio/gsm-amr/c/src/vad1.c
31 Functions:
32
33 ------------------------------------------------------------------------------
34 REVISION HISTORY
35
36 Description: Updated template used to PV coding template.
37 Changed to accept the pOverflow flag for EPOC compatibility.
38
39 Description: Made changes per review comments
40 (1) Removed include of "count.h"
41 (2) Replaced "basic_op.h" with individual include files
42 (3) Removed some unnecessary instances of sub().
43
44 Description: Replaced OSCL mem type functions and eliminated include
45 files that now are chosen by OSCL definitions
46
47 Description: Replaced "int" and/or "char" with OSCL defined types.
48
49 Description: Changed round function name to pv_round to avoid conflict with
50 round function in C standard library.
51
52 Who: Date:
53 Description:
54
55 ------------------------------------------------------------------------------
56 MODULE DESCRIPTION
57
58
59 ------------------------------------------------------------------------------
60 */
61
62 /*----------------------------------------------------------------------------
63 ; INCLUDES
64 ----------------------------------------------------------------------------*/
65
66 #include <stdlib.h>
67 #include <string.h>
68
69 #include "vad.h"
70 #include "typedef.h"
71 #include "shr.h"
72 #include "basic_op.h"
73 #include "cnst_vad.h"
74
75 /*----------------------------------------------------------------------------
76 ; MACROS
77 ; Define module specific macros here
78 ----------------------------------------------------------------------------*/
79
80 /*----------------------------------------------------------------------------
81 ; DEFINES
82 ; Include all pre-processor statements here. Include conditional
83 ; compile variables also.
84 ----------------------------------------------------------------------------*/
85
86 /*----------------------------------------------------------------------------
87 ; LOCAL FUNCTION DEFINITIONS
88 ; Function Prototype declaration
89 ----------------------------------------------------------------------------*/
90
91 /*----------------------------------------------------------------------------
92 ; LOCAL VARIABLE DEFINITIONS
93 ; Variable declaration - defined here and used outside this module
94 ----------------------------------------------------------------------------*/
95
96 /*
97 ------------------------------------------------------------------------------
98 FUNCTION NAME: first_filter_stage
99 ------------------------------------------------------------------------------
100 INPUT AND OUTPUT DEFINITIONS
101
102 Inputs:
103 data -- array of type Word16 -- filter memory
104 in -- array of type Word16 -- input signal
105
106 Outputs:
107 data -- array of type Word16 -- filter memory
108 out -- array of type Word16 -- output values, every other
109 output is low-pass part and
110 other is high-pass part every
111
112 pOverflow -- pointer to type Flag -- overflow indicator
113
114 Returns:
115 None
116
117 Global Variables Used:
118 None
119
120 Local Variables Needed:
121 None
122
123 ------------------------------------------------------------------------------
124 FUNCTION DESCRIPTION
125
126 Purpose : Scale input down by one bit. Calculate 5th order
127 half-band lowpass/highpass filter pair with
128 decimation.
129 ------------------------------------------------------------------------------
130 REQUIREMENTS
131
132 None
133
134 ------------------------------------------------------------------------------
135 REFERENCES
136
137 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
138
139 ------------------------------------------------------------------------------
140 PSEUDO-CODE
141
142
143 ------------------------------------------------------------------------------
144 RESOURCES USED [optional]
145
146 When the code is written for a specific target processor the
147 the resources used should be documented below.
148
149 HEAP MEMORY USED: x bytes
150
151 STACK MEMORY USED: x bytes
152
153 CLOCK CYCLES: (cycle count equation for this function) + (variable
154 used to represent cycle count for each subroutine
155 called)
156 where: (cycle count variable) = cycle count for [subroutine
157 name]
158
159 ------------------------------------------------------------------------------
160 CAUTION [optional]
161 [State any special notes, constraints or cautions for users of this function]
162
163 ------------------------------------------------------------------------------
164 */
165
first_filter_stage(Word16 in[],Word16 out[],Word16 data[],Flag * pOverflow)166 static void first_filter_stage(
167 Word16 in[], /* i : input signal */
168 Word16 out[], /* o : output values, every other */
169 /* output is low-pass part and */
170 /* other is high-pass part every */
171 Word16 data[], /* i/o : filter memory */
172 Flag *pOverflow /* o : Flag set when overflow occurs */
173 )
174 {
175 Word16 temp0;
176 Word16 temp1;
177 Word16 temp2;
178 Word16 temp3;
179 Word16 i;
180 Word16 data0;
181 Word16 data1;
182
183 data0 = data[0];
184 data1 = data[1];
185
186 for (i = 0; i < FRAME_LEN / 4; i++)
187 {
188 temp0 = mult(COEFF5_1, data0, pOverflow);
189 temp1 = shr(in[4*i+0], 2, pOverflow);
190 temp0 = sub(temp1, temp0, pOverflow);
191
192 temp1 = mult(COEFF5_1, temp0, pOverflow);
193 temp1 = add(data0, temp1, pOverflow);
194
195 temp3 = mult(COEFF5_2, data1, pOverflow);
196 temp2 = shr(in[4*i+1], 2, pOverflow);
197
198 temp3 = sub(temp2, temp3, pOverflow);
199
200 temp2 = mult(COEFF5_2, temp3, pOverflow);
201 temp2 = add(data1, temp2, pOverflow);
202
203 out[4*i+0] = add(temp1, temp2, pOverflow);
204 out[4*i+1] = sub(temp1, temp2, pOverflow);
205
206 temp1 = mult(COEFF5_1, temp0, pOverflow);
207 temp2 = shr(in[4*i+2], 2, pOverflow);
208 data0 = sub(temp2, temp1, pOverflow);
209
210 temp1 = mult(COEFF5_1, data0, pOverflow);
211 temp1 = add(temp0, temp1, pOverflow);
212
213 data1 = mult(COEFF5_2, temp3, pOverflow);
214 temp2 = shr(in[4*i+3], 2, pOverflow);
215 data1 = sub(temp2, data1, pOverflow);
216
217 temp2 = mult(COEFF5_2, data1, pOverflow);
218 temp2 = add(temp3, temp2, pOverflow);
219
220 out[4*i+2] = add(temp1, temp2, pOverflow);
221 out[4*i+3] = sub(temp1, temp2, pOverflow);
222 }
223
224 data[0] = data0;
225 data[1] = data1;
226 }
227
228
229 /*
230 ------------------------------------------------------------------------------
231 FUNCTION NAME: filter5
232 ------------------------------------------------------------------------------
233 INPUT AND OUTPUT DEFINITIONS
234
235 Inputs:
236 in0 -- array of type Word16 -- input values; output low-pass part
237 in1 -- array of type Word16 -- input values; output high-pass part
238 data -- array of type Word16 -- updated filter memory
239
240 Outputs:
241 in0 -- array of type Word16 -- input values; output low-pass part
242 in1 -- array of type Word16 -- input values; output high-pass part
243 data -- array of type Word16 -- updated filter memory
244 pOverflow -- pointer to type Flag -- overflow indicator
245
246 Returns:
247 None
248
249 Global Variables Used:
250 None
251
252 Local Variables Needed:
253 None
254
255 ------------------------------------------------------------------------------
256 FUNCTION DESCRIPTION
257
258 Purpose : Fifth-order half-band lowpass/highpass filter pair with
259 decimation.
260 ------------------------------------------------------------------------------
261 REQUIREMENTS
262
263 None
264
265 ------------------------------------------------------------------------------
266 REFERENCES
267
268 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
269
270 ------------------------------------------------------------------------------
271 PSEUDO-CODE
272
273
274 ------------------------------------------------------------------------------
275 RESOURCES USED [optional]
276
277 When the code is written for a specific target processor the
278 the resources used should be documented below.
279
280 HEAP MEMORY USED: x bytes
281
282 STACK MEMORY USED: x bytes
283
284 CLOCK CYCLES: (cycle count equation for this function) + (variable
285 used to represent cycle count for each subroutine
286 called)
287 where: (cycle count variable) = cycle count for [subroutine
288 name]
289
290 ------------------------------------------------------------------------------
291 CAUTION [optional]
292 [State any special notes, constraints or cautions for users of this function]
293
294 ------------------------------------------------------------------------------
295 */
296
filter5(Word16 * in0,Word16 * in1,Word16 data[],Flag * pOverflow)297 static void filter5(Word16 *in0, /* i/o : input values; output low-pass part */
298 Word16 *in1, /* i/o : input values; output high-pass part */
299 Word16 data[], /* i/o : updated filter memory */
300 Flag *pOverflow /* o : Flag set when overflow occurs */
301 )
302 {
303 Word16 temp0;
304 Word16 temp1;
305 Word16 temp2;
306
307 temp0 = mult(COEFF5_1, data[0], pOverflow);
308 temp0 = sub(*in0, temp0, pOverflow);
309
310 temp1 = mult(COEFF5_1, temp0, pOverflow);
311 temp1 = add(data[0], temp1, pOverflow);
312 data[0] = temp0;
313
314 temp0 = mult(COEFF5_2, data[1], pOverflow);
315 temp0 = sub(*in1, temp0, pOverflow);
316
317 temp2 = mult(COEFF5_2, temp0, pOverflow);
318 temp2 = add(data[1], temp2, pOverflow);
319
320 data[1] = temp0;
321
322 temp0 = add(temp1, temp2, pOverflow);
323 *in0 = shr(temp0, 1, pOverflow);
324
325 temp0 = sub(temp1, temp2, pOverflow);
326 *in1 = shr(temp0, 1, pOverflow);
327 }
328
329
330
331
332 /*
333 ------------------------------------------------------------------------------
334 FUNCTION NAME: filter3
335 ------------------------------------------------------------------------------
336 INPUT AND OUTPUT DEFINITIONS
337
338
339 Inputs:
340 in0 -- array of type Word16 -- input values; output low-pass part
341 in1 -- array of type Word16 -- input values; output high-pass part
342 data -- array of type Word16 -- updated filter memory
343
344 Outputs:
345 in0 -- array of type Word16 -- input values; output low-pass part
346 in1 -- array of type Word16 -- input values; output high-pass part
347 data -- array of type Word16 -- updated filter memory
348 pOverflow -- pointer to type Flag -- overflow indicator
349
350 Returns:
351 None
352
353 Global Variables Used:
354 None
355
356 Local Variables Needed:
357 None
358
359 ------------------------------------------------------------------------------
360 FUNCTION DESCRIPTION
361
362 Purpose : Third-order half-band lowpass/highpass filter pair with
363 decimation.
364 ------------------------------------------------------------------------------
365 REQUIREMENTS
366
367 None
368
369 ------------------------------------------------------------------------------
370 REFERENCES
371
372 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
373
374 ------------------------------------------------------------------------------
375 PSEUDO-CODE
376
377
378 ------------------------------------------------------------------------------
379 RESOURCES USED [optional]
380
381 When the code is written for a specific target processor the
382 the resources used should be documented below.
383
384 HEAP MEMORY USED: x bytes
385
386 STACK MEMORY USED: x bytes
387
388 CLOCK CYCLES: (cycle count equation for this function) + (variable
389 used to represent cycle count for each subroutine
390 called)
391 where: (cycle count variable) = cycle count for [subroutine
392 name]
393
394 ------------------------------------------------------------------------------
395 CAUTION [optional]
396 [State any special notes, constraints or cautions for users of this function]
397
398 ------------------------------------------------------------------------------
399 */
400
filter3(Word16 * in0,Word16 * in1,Word16 * data,Flag * pOverflow)401 static void filter3(
402 Word16 *in0, /* i/o : input values; output low-pass part */
403 Word16 *in1, /* i/o : input values; output high-pass part */
404 Word16 *data, /* i/o : updated filter memory */
405 Flag *pOverflow /* o : Flag set when overflow occurs */
406 )
407 {
408 Word16 temp1;
409 Word16 temp2;
410
411 temp1 = mult(COEFF3, *data, pOverflow);
412 temp1 = sub(*in1, temp1, pOverflow);
413
414 temp2 = mult(COEFF3, temp1, pOverflow);
415 temp2 = add(*data, temp2, pOverflow);
416
417 *data = temp1;
418
419 temp1 = sub(*in0, temp2, pOverflow);
420
421 *in1 = shr(temp1, 1, pOverflow);
422
423 temp1 = add(*in0, temp2, pOverflow);
424
425 *in0 = shr(temp1, 1, pOverflow);
426 }
427
428
429
430
431 /*
432 ------------------------------------------------------------------------------
433 FUNCTION NAME: level_calculation
434 ------------------------------------------------------------------------------
435 INPUT AND OUTPUT DEFINITIONS
436
437 Inputs:
438 data -- array of type Word16 -- signal buffer
439 sub_level -- pointer to type Word16 -- level calculated at the end of
440 the previous frame
441
442 count1 -- Word16 -- number of samples to be counted
443 count2 -- Word16 -- number of samples to be counted
444 ind_m -- Word16 -- step size for the index of the data buffer
445 ind_a -- Word16 -- starting index of the data buffer
446 scale -- Word16 -- scaling for the level calculation
447
448 Outputs:
449 sub_level -- pointer to tyep Word16 -- level of signal calculated from the
450 last (count2 - count1) samples.
451 pOverflow -- pointer to type Flag -- overflow indicator
452
453 Returns:
454 signal level
455
456 Global Variables Used:
457
458
459 Local Variables Needed:
460 None
461
462 ------------------------------------------------------------------------------
463 FUNCTION DESCRIPTION
464
465 Purpose : Calculate signal level in a sub-band. Level is calculated
466 by summing absolute values of the input data.
467
468 ------------------------------------------------------------------------------
469 REQUIREMENTS
470
471 None
472
473 ------------------------------------------------------------------------------
474 REFERENCES
475
476 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
477
478 ------------------------------------------------------------------------------
479 PSEUDO-CODE
480
481
482 ------------------------------------------------------------------------------
483 RESOURCES USED [optional]
484
485 When the code is written for a specific target processor the
486 the resources used should be documented below.
487
488 HEAP MEMORY USED: x bytes
489
490 STACK MEMORY USED: x bytes
491
492 CLOCK CYCLES: (cycle count equation for this function) + (variable
493 used to represent cycle count for each subroutine
494 called)
495 where: (cycle count variable) = cycle count for [subroutine
496 name]
497
498 ------------------------------------------------------------------------------
499 CAUTION [optional]
500 [State any special notes, constraints or cautions for users of this function]
501
502 ------------------------------------------------------------------------------
503 */
504
level_calculation(Word16 data[],Word16 * sub_level,Word16 count1,Word16 count2,Word16 ind_m,Word16 ind_a,Word16 scale,Flag * pOverflow)505 static Word16 level_calculation(
506 Word16 data[], /* i : signal buffer */
507 Word16 *sub_level, /* i : level calculate at the end of */
508 /* the previous frame */
509 /* o : level of signal calculated from the last */
510 /* (count2 - count1) samples */
511 Word16 count1, /* i : number of samples to be counted */
512 Word16 count2, /* i : number of samples to be counted */
513 Word16 ind_m, /* i : step size for the index of the data buffer */
514 Word16 ind_a, /* i : starting index of the data buffer */
515 Word16 scale, /* i : scaling for the level calculation */
516 Flag *pOverflow /* o : Flag set when overflow occurs */
517 )
518 {
519 Word32 l_temp1;
520 Word32 l_temp2;
521 Word16 level;
522 Word16 i;
523
524 l_temp1 = 0L;
525
526 for (i = count1; i < count2; i++)
527 {
528 l_temp1 = L_mac(l_temp1, 1, abs_s(data[ind_m*i+ind_a]), pOverflow);
529 }
530
531 l_temp2 = L_add(l_temp1, L_shl(*sub_level, sub(16, scale, pOverflow), pOverflow), pOverflow);
532 *sub_level = extract_h(L_shl(l_temp1, scale, pOverflow));
533
534 for (i = 0; i < count1; i++)
535 {
536 l_temp2 = L_mac(l_temp2, 1, abs_s(data[ind_m*i+ind_a]), pOverflow);
537 }
538 level = extract_h(L_shl(l_temp2, scale, pOverflow));
539
540 return level;
541 }
542
543
544
545
546 /*
547 ------------------------------------------------------------------------------
548 FUNCTION NAME: filter_bank
549 ------------------------------------------------------------------------------
550 INPUT AND OUTPUT DEFINITIONS
551
552 Inputs:
553 st -- pointer to type vadState1 -- State struct
554 in -- array of type Word16 -- input frame
555
556 Outputs:
557 level -- array of type Word16 -- signal levels at each band
558 st -- pointer to type vadState1 -- State struct
559 pOverflow -- pointer to type Flag -- overflow indicator
560
561 Returns:
562 None
563
564 Global Variables Used:
565 None
566
567 Local Variables Needed:
568 None
569
570 ------------------------------------------------------------------------------
571 FUNCTION DESCRIPTION
572
573 Purpose : Divides input signal into 9-bands and calculas level of
574 the signal in each band
575
576 ------------------------------------------------------------------------------
577 REQUIREMENTS
578
579 None
580
581 ------------------------------------------------------------------------------
582 REFERENCES
583
584 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
585
586 ------------------------------------------------------------------------------
587 PSEUDO-CODE
588
589
590 ------------------------------------------------------------------------------
591 RESOURCES USED [optional]
592
593 When the code is written for a specific target processor the
594 the resources used should be documented below.
595
596 HEAP MEMORY USED: x bytes
597
598 STACK MEMORY USED: x bytes
599
600 CLOCK CYCLES: (cycle count equation for this function) + (variable
601 used to represent cycle count for each subroutine
602 called)
603 where: (cycle count variable) = cycle count for [subroutine
604 name]
605
606 ------------------------------------------------------------------------------
607 CAUTION [optional]
608 [State any special notes, constraints or cautions for users of this function]
609
610 ------------------------------------------------------------------------------
611 */
612
filter_bank(vadState1 * st,Word16 in[],Word16 level[],Flag * pOverflow)613 static void filter_bank(
614 vadState1 *st, /* i/o : State struct */
615 Word16 in[], /* i : input frame */
616 Word16 level[], /* 0 : signal levels at each band */
617 Flag *pOverflow /* o : Flag set when overflow occurs */
618 )
619 {
620 Word16 i;
621 Word16 tmp_buf[FRAME_LEN];
622
623 /* calculate the filter bank */
624
625 first_filter_stage(in, tmp_buf, st->a_data5[0], pOverflow);
626
627 for (i = 0; i < FRAME_LEN / 4; i++)
628 {
629 filter5(&tmp_buf[4*i], &tmp_buf[4*i+2], st->a_data5[1], pOverflow);
630 filter5(&tmp_buf[4*i+1], &tmp_buf[4*i+3], st->a_data5[2], pOverflow);
631 }
632 for (i = 0; i < FRAME_LEN / 8; i++)
633 {
634 filter3(&tmp_buf[8*i+0], &tmp_buf[8*i+4], &st->a_data3[0], pOverflow);
635 filter3(&tmp_buf[8*i+2], &tmp_buf[8*i+6], &st->a_data3[1], pOverflow);
636 filter3(&tmp_buf[8*i+3], &tmp_buf[8*i+7], &st->a_data3[4], pOverflow);
637 }
638
639 for (i = 0; i < FRAME_LEN / 16; i++)
640 {
641 filter3(&tmp_buf[16*i+0], &tmp_buf[16*i+8], &st->a_data3[2], pOverflow);
642 filter3(&tmp_buf[16*i+4], &tmp_buf[16*i+12], &st->a_data3[3], pOverflow);
643 }
644
645 /* calculate levels in each frequency band */
646
647 /* 3000 - 4000 Hz*/
648 level[8] = level_calculation(tmp_buf, &st->sub_level[8], FRAME_LEN / 4 - 8,
649 FRAME_LEN / 4, 4, 1, 15, pOverflow);
650 /* 2500 - 3000 Hz*/
651 level[7] = level_calculation(tmp_buf, &st->sub_level[7], FRAME_LEN / 8 - 4,
652 FRAME_LEN / 8, 8, 7, 16, pOverflow);
653 /* 2000 - 2500 Hz*/
654 level[6] = level_calculation(tmp_buf, &st->sub_level[6], FRAME_LEN / 8 - 4,
655 FRAME_LEN / 8, 8, 3, 16, pOverflow);
656 /* 1500 - 2000 Hz*/
657 level[5] = level_calculation(tmp_buf, &st->sub_level[5], FRAME_LEN / 8 - 4,
658 FRAME_LEN / 8, 8, 2, 16, pOverflow);
659 /* 1000 - 1500 Hz*/
660 level[4] = level_calculation(tmp_buf, &st->sub_level[4], FRAME_LEN / 8 - 4,
661 FRAME_LEN / 8, 8, 6, 16, pOverflow);
662 /* 750 - 1000 Hz*/
663 level[3] = level_calculation(tmp_buf, &st->sub_level[3], FRAME_LEN / 16 - 2,
664 FRAME_LEN / 16, 16, 4, 16, pOverflow);
665 /* 500 - 750 Hz*/
666 level[2] = level_calculation(tmp_buf, &st->sub_level[2], FRAME_LEN / 16 - 2,
667 FRAME_LEN / 16, 16, 12, 16, pOverflow);
668 /* 250 - 500 Hz*/
669 level[1] = level_calculation(tmp_buf, &st->sub_level[1], FRAME_LEN / 16 - 2,
670 FRAME_LEN / 16, 16, 8, 16, pOverflow);
671 /* 0 - 250 Hz*/
672 level[0] = level_calculation(tmp_buf, &st->sub_level[0], FRAME_LEN / 16 - 2,
673 FRAME_LEN / 16, 16, 0, 16, pOverflow);
674 }
675
676
677
678 /*
679 ------------------------------------------------------------------------------
680 FUNCTION NAME: update_cntrl
681 ------------------------------------------------------------------------------
682 INPUT AND OUTPUT DEFINITIONS
683
684 Inputs:
685 st -- pointer to type vadState1 -- State struct
686 level -- array of type Word16 -- sub-band levels of the input frame
687
688 Outputs:
689 st -- pointer to type vadState1 -- State struct
690 pOverflow -- pointer to type Flag -- overflow indicator
691
692 Returns:
693 None
694
695 Global Variables Used:
696 None
697
698 Local Variables Needed:
699 None
700
701 ------------------------------------------------------------------------------
702 FUNCTION DESCRIPTION
703
704 Purpose : Control update of the background noise estimate.
705 Inputs : pitch: flags for pitch detection
706 stat_count: stationary counter
707 tone: flags indicating presence of a tone
708 complex: flags for complex detection
709 vadreg: intermediate VAD flags
710 Output : stat_count: stationary counter
711
712
713 ------------------------------------------------------------------------------
714 REQUIREMENTS
715
716 None
717
718 ------------------------------------------------------------------------------
719 REFERENCES
720
721 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
722
723 ------------------------------------------------------------------------------
724 PSEUDO-CODE
725
726
727 ------------------------------------------------------------------------------
728 RESOURCES USED [optional]
729
730 When the code is written for a specific target processor the
731 the resources used should be documented below.
732
733 HEAP MEMORY USED: x bytes
734
735 STACK MEMORY USED: x bytes
736
737 CLOCK CYCLES: (cycle count equation for this function) + (variable
738 used to represent cycle count for each subroutine
739 called)
740 where: (cycle count variable) = cycle count for [subroutine
741 name]
742
743 ------------------------------------------------------------------------------
744 CAUTION [optional]
745 [State any special notes, constraints or cautions for users of this function]
746
747 ------------------------------------------------------------------------------
748 */
749
update_cntrl(vadState1 * st,Word16 level[],Flag * pOverflow)750 static void update_cntrl(
751 vadState1 *st, /* i/o : State struct */
752 Word16 level[], /* i : sub-band levels of the input frame */
753 Flag *pOverflow /* o : Flag set when overflow occurs */
754 )
755 {
756 Word16 i;
757 Word16 temp;
758 Word16 stat_rat;
759 Word16 exp;
760 Word16 num;
761 Word16 denom;
762 Word16 alpha;
763
764 /* handle highband complex signal input separately */
765 /* if ther has been highband correlation for some time */
766 /* make sure that the VAD update speed is low for a while */
767 if (st->complex_warning != 0)
768 {
769 if (st->stat_count < CAD_MIN_STAT_COUNT)
770 {
771 st->stat_count = CAD_MIN_STAT_COUNT;
772 }
773 }
774 /* NB stat_count is allowed to be decreased by one below again */
775 /* deadlock in speech is not possible unless the signal is very */
776 /* complex and need a high rate */
777
778 /* if fullband pitch or tone have been detected for a while, initialize stat_count */
779 if (((Word16)(st->pitch & 0x6000) == 0x6000) ||
780 ((Word16)(st->tone & 0x7c00) == 0x7c00))
781 {
782 st->stat_count = STAT_COUNT;
783 }
784 else
785 {
786 /* if 8 last vad-decisions have been "0", reinitialize stat_count */
787 if ((st->vadreg & 0x7f80) == 0)
788 {
789 st->stat_count = STAT_COUNT;
790 }
791 else
792 {
793 stat_rat = 0;
794 for (i = 0; i < COMPLEN; i++)
795 {
796 if (level[i] > st->ave_level[i])
797 {
798 num = level[i];
799 denom = st->ave_level[i];
800 }
801 else
802 {
803 num = st->ave_level[i];
804 denom = level[i];
805 }
806 /* Limit nimimum value of num and denom to STAT_THR_LEVEL */
807 if (num < STAT_THR_LEVEL)
808 {
809 num = STAT_THR_LEVEL;
810 }
811 if (denom < STAT_THR_LEVEL)
812 {
813 denom = STAT_THR_LEVEL;
814 }
815
816 exp = norm_s(denom);
817
818 denom = shl(denom, exp, pOverflow);
819
820 /* stat_rat = num/denom * 64 */
821 temp = shr(num, 1, pOverflow);
822 temp = div_s(temp, denom);
823
824 stat_rat = add(stat_rat, shr(temp, sub(8, exp, pOverflow), pOverflow), pOverflow);
825 }
826
827 /* compare stat_rat with a threshold and update stat_count */
828 if (stat_rat > STAT_THR)
829 {
830 st->stat_count = STAT_COUNT;
831 }
832 else
833 {
834 if ((st->vadreg & 0x4000) != 0)
835 {
836 if (st->stat_count != 0)
837 {
838 st->stat_count = sub(st->stat_count, 1, pOverflow);
839 }
840 }
841 }
842 }
843 }
844
845 /* Update average amplitude estimate for stationarity estimation */
846 alpha = ALPHA4;
847 if (st->stat_count == STAT_COUNT)
848 {
849 alpha = 32767;
850 }
851 else if ((st->vadreg & 0x4000) == 0)
852 {
853 alpha = ALPHA5;
854 }
855
856 for (i = 0; i < COMPLEN; i++)
857 {
858 temp = sub(level[i], st->ave_level[i], pOverflow);
859 temp = mult_r(alpha, temp, pOverflow);
860
861 st->ave_level[i] =
862 add(
863 st->ave_level[i],
864 temp,
865 pOverflow);
866 }
867 }
868
869
870
871 /*
872 ------------------------------------------------------------------------------
873 FUNCTION NAME: hangover_addition
874 ------------------------------------------------------------------------------
875 INPUT AND OUTPUT DEFINITIONS
876
877 Inputs:
878 noise_level -- Word16 -- average level of the noise estimates
879 low_power -- Word16 -- flag power of the input frame
880
881 Outputs:
882 st -- pointer to type vadState1 -- State struct
883 pOverflow -- pointer to type Flag -- overflow indicato
884
885 Returns:
886 VAD_flag indicating final VAD decision (Word16)
887
888 Global Variables Used:
889 None
890
891 Local Variables Needed:
892 None
893
894 ------------------------------------------------------------------------------
895 FUNCTION DESCRIPTION
896
897 Function : hangover_addition
898 Purpose : Add hangover for complex signal or after speech bursts
899 Inputs : burst_count: counter for the length of speech bursts
900 hang_count: hangover counter
901 vadreg: intermediate VAD decision
902 Outputs : burst_count: counter for the length of speech bursts
903 hang_count: hangover counter
904 Return value : VAD_flag indicating final VAD decision
905
906
907 ------------------------------------------------------------------------------
908 REQUIREMENTS
909
910 None
911
912 ------------------------------------------------------------------------------
913 REFERENCES
914
915 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
916
917 ------------------------------------------------------------------------------
918 PSEUDO-CODE
919
920
921 ------------------------------------------------------------------------------
922 RESOURCES USED [optional]
923
924 When the code is written for a specific target processor the
925 the resources used should be documented below.
926
927 HEAP MEMORY USED: x bytes
928
929 STACK MEMORY USED: x bytes
930
931 CLOCK CYCLES: (cycle count equation for this function) + (variable
932 used to represent cycle count for each subroutine
933 called)
934 where: (cycle count variable) = cycle count for [subroutine
935 name]
936
937 ------------------------------------------------------------------------------
938 CAUTION [optional]
939 [State any special notes, constraints or cautions for users of this function]
940
941 ------------------------------------------------------------------------------
942 */
943
hangover_addition(vadState1 * st,Word16 noise_level,Word16 low_power,Flag * pOverflow)944 static Word16 hangover_addition(
945 vadState1 *st, /* i/o : State struct */
946 Word16 noise_level, /* i : average level of the noise */
947 /* estimates */
948 Word16 low_power, /* i : flag power of the input frame */
949 Flag *pOverflow /* o : Flag set when overflow occurs */
950 )
951 {
952 Word16 hang_len;
953 Word16 burst_len;
954
955 /*
956 Calculate burst_len and hang_len
957 burst_len: number of consecutive intermediate vad flags with "1"-decision
958 required for hangover addition
959 hang_len: length of the hangover
960 */
961
962 if (noise_level > HANG_NOISE_THR)
963 {
964 burst_len = BURST_LEN_HIGH_NOISE;
965 hang_len = HANG_LEN_HIGH_NOISE;
966 }
967 else
968 {
969 burst_len = BURST_LEN_LOW_NOISE;
970 hang_len = HANG_LEN_LOW_NOISE;
971 }
972
973 /* if the input power (pow_sum) is lower than a threshold, clear
974 counters and set VAD_flag to "0" "fast exit" */
975 if (low_power != 0)
976 {
977 st->burst_count = 0;
978 st->hang_count = 0;
979 st->complex_hang_count = 0;
980 st->complex_hang_timer = 0;
981 return 0;
982 }
983
984 if (st->complex_hang_timer > CVAD_HANG_LIMIT)
985 {
986 if (st->complex_hang_count < CVAD_HANG_LENGTH)
987 {
988 st->complex_hang_count = CVAD_HANG_LENGTH;
989 }
990 }
991
992 /* long time very complex signal override VAD output function */
993 if (st->complex_hang_count != 0)
994 {
995 st->burst_count = BURST_LEN_HIGH_NOISE;
996 st->complex_hang_count = sub(st->complex_hang_count, 1, pOverflow);
997 return 1;
998 }
999 else
1000 {
1001 /* let hp_corr work in from a noise_period indicated by the VAD */
1002 if (((st->vadreg & 0x3ff0) == 0) &&
1003 (st->corr_hp_fast > CVAD_THRESH_IN_NOISE))
1004 {
1005 return 1;
1006 }
1007 }
1008
1009 /* update the counters (hang_count, burst_count) */
1010 if ((st->vadreg & 0x4000) != 0)
1011 {
1012 st->burst_count = add(st->burst_count, 1, pOverflow);
1013
1014 if (st->burst_count >= burst_len)
1015 {
1016 st->hang_count = hang_len;
1017 }
1018 return 1;
1019 }
1020 else
1021 {
1022 st->burst_count = 0;
1023 if (st->hang_count > 0)
1024 {
1025 st->hang_count = sub(st->hang_count, 1, pOverflow);
1026 return 1;
1027 }
1028 }
1029 return 0;
1030 }
1031
1032
1033
1034 /*
1035 ------------------------------------------------------------------------------
1036 FUNCTION NAME: noise_estimate_update
1037 ------------------------------------------------------------------------------
1038 INPUT AND OUTPUT DEFINITIONS
1039
1040 Inputs:
1041 st -- pointer to type vadState1 -- State struct
1042 level -- array of type Word16 -- sub-band levels of the input frame
1043
1044 Outputs:
1045 st -- pointer to type vadState1 -- State struct
1046 pOverflow -- pointer to type Flag -- overflow indicator
1047
1048 Returns:
1049 None
1050
1051 Global Variables Used:
1052 None
1053
1054 Local Variables Needed:
1055 None
1056
1057 ------------------------------------------------------------------------------
1058 FUNCTION DESCRIPTION
1059
1060 Purpose : Update of background noise estimate
1061 Inputs : bckr_est: background noise estimate
1062 pitch: flags for pitch detection
1063 stat_count: stationary counter
1064 Outputs : bckr_est: background noise estimate
1065
1066 ------------------------------------------------------------------------------
1067 REQUIREMENTS
1068
1069 None
1070
1071 ------------------------------------------------------------------------------
1072 REFERENCES
1073
1074 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1075
1076 ------------------------------------------------------------------------------
1077 PSEUDO-CODE
1078
1079
1080 ------------------------------------------------------------------------------
1081 RESOURCES USED [optional]
1082
1083 When the code is written for a specific target processor the
1084 the resources used should be documented below.
1085
1086 HEAP MEMORY USED: x bytes
1087
1088 STACK MEMORY USED: x bytes
1089
1090 CLOCK CYCLES: (cycle count equation for this function) + (variable
1091 used to represent cycle count for each subroutine
1092 called)
1093 where: (cycle count variable) = cycle count for [subroutine
1094 name]
1095
1096 ------------------------------------------------------------------------------
1097 CAUTION [optional]
1098 [State any special notes, constraints or cautions for users of this function]
1099
1100 ------------------------------------------------------------------------------
1101 */
1102
noise_estimate_update(vadState1 * st,Word16 level[],Flag * pOverflow)1103 static void noise_estimate_update(
1104 vadState1 *st, /* i/o : State struct */
1105 Word16 level[], /* i : sub-band levels of the input frame */
1106 Flag *pOverflow /* o : Flag set when overflow occurs */
1107 )
1108 {
1109 Word16 i;
1110 Word16 alpha_up;
1111 Word16 alpha_down;
1112 Word16 bckr_add;
1113
1114 /* Control update of bckr_est[] */
1115 update_cntrl(st, level, pOverflow);
1116
1117 /* Choose update speed */
1118 bckr_add = 2;
1119
1120 if (((0x7800 & st->vadreg) == 0) &&
1121 ((st->pitch & 0x7800) == 0)
1122 && (st->complex_hang_count == 0))
1123 {
1124 alpha_up = ALPHA_UP1;
1125 alpha_down = ALPHA_DOWN1;
1126 }
1127 else
1128 {
1129 if ((st->stat_count == 0)
1130 && (st->complex_hang_count == 0))
1131 {
1132 alpha_up = ALPHA_UP2;
1133 alpha_down = ALPHA_DOWN2;
1134 }
1135 else
1136 {
1137 alpha_up = 0;
1138 alpha_down = ALPHA3;
1139 bckr_add = 0;
1140 }
1141 }
1142
1143 /* Update noise estimate (bckr_est) */
1144 for (i = 0; i < COMPLEN; i++)
1145 {
1146 Word16 temp;
1147
1148 temp = sub(st->old_level[i], st->bckr_est[i], pOverflow);
1149
1150 if (temp < 0)
1151 { /* update downwards*/
1152 temp = mult_r(alpha_down, temp, pOverflow);
1153 temp = add(st->bckr_est[i], temp, pOverflow);
1154
1155 st->bckr_est[i] = add(-2, temp, pOverflow);
1156
1157 /* limit minimum value of the noise estimate to NOISE_MIN */
1158 if (st->bckr_est[i] < NOISE_MIN)
1159 {
1160 st->bckr_est[i] = NOISE_MIN;
1161 }
1162 }
1163 else
1164 { /* update upwards */
1165 temp = mult_r(alpha_up, temp, pOverflow);
1166 temp = add(st->bckr_est[i], temp, pOverflow);
1167 st->bckr_est[i] = add(bckr_add, temp, pOverflow);
1168
1169 /* limit maximum value of the noise estimate to NOISE_MAX */
1170 if (st->bckr_est[i] > NOISE_MAX)
1171 {
1172 st->bckr_est[i] = NOISE_MAX;
1173 }
1174 }
1175 }
1176
1177 /* Update signal levels of the previous frame (old_level) */
1178 for (i = 0; i < COMPLEN; i++)
1179 {
1180 st->old_level[i] = level[i];
1181 }
1182 }
1183
1184
1185 /*
1186 ------------------------------------------------------------------------------
1187 FUNCTION NAME: complex_estimate_adapt
1188 ------------------------------------------------------------------------------
1189 INPUT AND OUTPUT DEFINITIONS
1190
1191 Inputs:
1192 st -- pointer to type vadState1 -- State struct
1193 low_power -- Word16 -- very low level flag of the input frame
1194
1195 Outputs:
1196 st -- pointer to type vadState1 -- State struct
1197 pOverflow -- pointer to type Flag -- overflow indicator
1198
1199 Returns:
1200 None
1201
1202 Global Variables Used:
1203 None
1204
1205 Local Variables Needed:
1206 None
1207
1208 ------------------------------------------------------------------------------
1209 FUNCTION DESCRIPTION
1210
1211 Function : complex_estimate_adapt
1212 Purpose : Update/adapt of complex signal estimate
1213 Inputs : low_power: low signal power flag
1214 Outputs : st->corr_hp_fast: long term complex signal estimate
1215
1216 ------------------------------------------------------------------------------
1217 REQUIREMENTS
1218
1219 None
1220
1221 ------------------------------------------------------------------------------
1222 REFERENCES
1223
1224 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1225
1226 ------------------------------------------------------------------------------
1227 PSEUDO-CODE
1228
1229
1230 ------------------------------------------------------------------------------
1231 RESOURCES USED [optional]
1232
1233 When the code is written for a specific target processor the
1234 the resources used should be documented below.
1235
1236 HEAP MEMORY USED: x bytes
1237
1238 STACK MEMORY USED: x bytes
1239
1240 CLOCK CYCLES: (cycle count equation for this function) + (variable
1241 used to represent cycle count for each subroutine
1242 called)
1243 where: (cycle count variable) = cycle count for [subroutine
1244 name]
1245
1246 ------------------------------------------------------------------------------
1247 CAUTION [optional]
1248 [State any special notes, constraints or cautions for users of this function]
1249
1250 ------------------------------------------------------------------------------
1251 */
1252
complex_estimate_adapt(vadState1 * st,Word16 low_power,Flag * pOverflow)1253 static void complex_estimate_adapt(
1254 vadState1 *st, /* i/o : VAD state struct */
1255 Word16 low_power, /* i : very low level flag of the input frame */
1256 Flag *pOverflow /* o : Flag set when overflow occurs */
1257 )
1258 {
1259 Word16 alpha; /* Q15 */
1260 Word32 L_tmp; /* Q31 */
1261
1262
1263 /* adapt speed on own state */
1264 if (st->best_corr_hp < st->corr_hp_fast) /* decrease */
1265 {
1266 if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH)
1267 { /* low state */
1268 alpha = CVAD_ADAPT_FAST;
1269 }
1270 else
1271 { /* high state */
1272 alpha = CVAD_ADAPT_REALLY_FAST;
1273 }
1274 }
1275 else /* increase */
1276 {
1277 if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH)
1278 {
1279 alpha = CVAD_ADAPT_FAST;
1280 }
1281 else
1282 {
1283 alpha = CVAD_ADAPT_SLOW;
1284 }
1285 }
1286
1287 L_tmp = L_deposit_h(st->corr_hp_fast);
1288 L_tmp = L_msu(L_tmp, alpha, st->corr_hp_fast, pOverflow);
1289 L_tmp = L_mac(L_tmp, alpha, st->best_corr_hp, pOverflow);
1290 st->corr_hp_fast = pv_round(L_tmp, pOverflow); /* Q15 */
1291
1292 if (st->corr_hp_fast < CVAD_MIN_CORR)
1293 {
1294 st->corr_hp_fast = CVAD_MIN_CORR;
1295 }
1296
1297 if (low_power != 0)
1298 {
1299 st->corr_hp_fast = CVAD_MIN_CORR;
1300 }
1301 }
1302
1303
1304 /*
1305 ------------------------------------------------------------------------------
1306 FUNCTION NAME: complex_vad
1307 ------------------------------------------------------------------------------
1308 INPUT AND OUTPUT DEFINITIONS
1309
1310 Inputs:
1311 st -- pointer to type vadState1 -- State struct
1312 low_power -- Word16 -- flag power of the input frame
1313
1314 Outputs:
1315 st -- pointer to type vadState1 -- State struct
1316 pOverflow -- pointer to type Flag -- overflow indicator
1317
1318
1319 Returns:
1320 the complex background decision
1321
1322 Global Variables Used:
1323 None
1324
1325 Local Variables Needed:
1326 None
1327
1328 ------------------------------------------------------------------------------
1329 FUNCTION DESCRIPTION
1330
1331 Purpose : complex background decision
1332 Return value : the complex background decision
1333
1334 ------------------------------------------------------------------------------
1335 REQUIREMENTS
1336
1337 None
1338
1339 ------------------------------------------------------------------------------
1340 REFERENCES
1341
1342 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1343
1344 ------------------------------------------------------------------------------
1345 PSEUDO-CODE
1346
1347
1348 ------------------------------------------------------------------------------
1349 RESOURCES USED [optional]
1350
1351 When the code is written for a specific target processor the
1352 the resources used should be documented below.
1353
1354 HEAP MEMORY USED: x bytes
1355
1356 STACK MEMORY USED: x bytes
1357
1358 CLOCK CYCLES: (cycle count equation for this function) + (variable
1359 used to represent cycle count for each subroutine
1360 called)
1361 where: (cycle count variable) = cycle count for [subroutine
1362 name]
1363
1364 ------------------------------------------------------------------------------
1365 CAUTION [optional]
1366 [State any special notes, constraints or cautions for users of this function]
1367
1368 ------------------------------------------------------------------------------
1369 */
1370
complex_vad(vadState1 * st,Word16 low_power,Flag * pOverflow)1371 static Word16 complex_vad(
1372 vadState1 *st, /* i/o : VAD state struct */
1373 Word16 low_power, /* i : flag power of the input frame */
1374 Flag *pOverflow /* o : Flag set when overflow occurs */
1375 )
1376 {
1377 st->complex_high = shr(st->complex_high, 1, pOverflow);
1378 st->complex_low = shr(st->complex_low, 1, pOverflow);
1379
1380 if (low_power == 0)
1381 {
1382 if (st->corr_hp_fast > CVAD_THRESH_ADAPT_HIGH)
1383 {
1384 st->complex_high |= 0x4000;
1385 }
1386
1387 if (st->corr_hp_fast > CVAD_THRESH_ADAPT_LOW)
1388 {
1389 st->complex_low |= 0x4000;
1390 }
1391 }
1392
1393 if (st->corr_hp_fast > CVAD_THRESH_HANG)
1394 {
1395 st->complex_hang_timer = add(st->complex_hang_timer, 1, pOverflow);
1396 }
1397 else
1398 {
1399 st->complex_hang_timer = 0;
1400 }
1401
1402 return ((Word16)(st->complex_high & 0x7f80) == 0x7f80 ||
1403 (Word16)(st->complex_low & 0x7fff) == 0x7fff);
1404 }
1405
1406
1407 /*
1408 ------------------------------------------------------------------------------
1409 FUNCTION NAME: vad_decision
1410 ------------------------------------------------------------------------------
1411 INPUT AND OUTPUT DEFINITIONS
1412
1413 Inputs:
1414 st -- pointer to type vadState1 -- State struct
1415 level -- array of type Word16 -- sub-band levels of the input frame
1416 pow_sum -- Word32 -- power of the input frame
1417
1418 Outputs:
1419 st -- pointer to type vadState1 -- State struct
1420 pOverflow -- pointer to type Flag -- overflow indicator
1421
1422 Returns:
1423 VAD_flag (Word16)
1424
1425 Global Variables Used:
1426 None
1427
1428 Local Variables Needed:
1429 None
1430
1431 ------------------------------------------------------------------------------
1432 FUNCTION DESCRIPTION
1433
1434 Purpose : Calculates VAD_flag
1435 Inputs : bckr_est: background noise estimate
1436 vadreg: intermediate VAD flags
1437 Outputs : noise_level: average level of the noise estimates
1438 vadreg: intermediate VAD flags
1439 Return value : VAD_flag
1440
1441 ------------------------------------------------------------------------------
1442 REQUIREMENTS
1443
1444 None
1445
1446 ------------------------------------------------------------------------------
1447 REFERENCES
1448
1449 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1450
1451 ------------------------------------------------------------------------------
1452 PSEUDO-CODE
1453
1454
1455 ------------------------------------------------------------------------------
1456 RESOURCES USED [optional]
1457
1458 When the code is written for a specific target processor the
1459 the resources used should be documented below.
1460
1461 HEAP MEMORY USED: x bytes
1462
1463 STACK MEMORY USED: x bytes
1464
1465 CLOCK CYCLES: (cycle count equation for this function) + (variable
1466 used to represent cycle count for each subroutine
1467 called)
1468 where: (cycle count variable) = cycle count for [subroutine
1469 name]
1470
1471 ------------------------------------------------------------------------------
1472 CAUTION [optional]
1473 [State any special notes, constraints or cautions for users of this function]
1474
1475 ------------------------------------------------------------------------------
1476 */
1477
vad_decision(vadState1 * st,Word16 level[COMPLEN],Word32 pow_sum,Flag * pOverflow)1478 static Word16 vad_decision(
1479 vadState1 *st, /* i/o : State struct */
1480 Word16 level[COMPLEN], /* i : sub-band levels of the input frame */
1481 Word32 pow_sum, /* i : power of the input frame */
1482 Flag *pOverflow /* o : Flag set when overflow occurs */
1483 )
1484 {
1485 Word16 i;
1486 Word16 snr_sum;
1487 Word32 L_temp;
1488 Word16 vad_thr;
1489 Word16 temp;
1490 Word16 noise_level;
1491 Word16 low_power_flag;
1492 Word16 temp1;
1493
1494 /*
1495 Calculate squared sum of the input levels (level)
1496 divided by the background noise components (bckr_est).
1497 */
1498 L_temp = 0;
1499
1500 for (i = 0; i < COMPLEN; i++)
1501 {
1502 Word16 exp;
1503
1504 exp = norm_s(st->bckr_est[i]);
1505 temp = shl(st->bckr_est[i], exp, pOverflow);
1506 temp = div_s(shr(level[i], 1, pOverflow), temp);
1507 temp = shl(temp, sub(exp, UNIRSHFT - 1, pOverflow), pOverflow);
1508 L_temp = L_mac(L_temp, temp, temp, pOverflow);
1509 }
1510
1511 snr_sum = extract_h(L_shl(L_temp, 6, pOverflow));
1512 snr_sum = mult(snr_sum, INV_COMPLEN, pOverflow);
1513
1514 /* Calculate average level of estimated background noise */
1515 L_temp = 0;
1516 for (i = 0; i < COMPLEN; i++)
1517 {
1518 L_temp = L_add(L_temp, st->bckr_est[i], pOverflow);
1519 }
1520
1521 noise_level = extract_h(L_shl(L_temp, 13, pOverflow));
1522
1523 /* Calculate VAD threshold */
1524 temp1 = sub(noise_level, VAD_P1, pOverflow);
1525 temp1 = mult(VAD_SLOPE, temp1, pOverflow);
1526 vad_thr = add(temp1, VAD_THR_HIGH, pOverflow);
1527
1528 if (vad_thr < VAD_THR_LOW)
1529 {
1530 vad_thr = VAD_THR_LOW;
1531 }
1532
1533 /* Shift VAD decision register */
1534 st->vadreg = shr(st->vadreg, 1, pOverflow);
1535
1536 /* Make intermediate VAD decision */
1537 if (snr_sum > vad_thr)
1538 {
1539 st->vadreg |= 0x4000;
1540 }
1541 /* primary vad decsion made */
1542
1543 /* check if the input power (pow_sum) is lower than a threshold" */
1544 if (L_sub(pow_sum, VAD_POW_LOW, pOverflow) < 0)
1545 {
1546 low_power_flag = 1;
1547 }
1548 else
1549 {
1550 low_power_flag = 0;
1551 }
1552
1553 /* update complex signal estimate st->corr_hp_fast and hangover reset timer using */
1554 /* low_power_flag and corr_hp_fast and various adaptation speeds */
1555 complex_estimate_adapt(st, low_power_flag, pOverflow);
1556
1557 /* check multiple thresholds of the st->corr_hp_fast value */
1558 st->complex_warning = complex_vad(st, low_power_flag, pOverflow);
1559
1560 /* Update speech subband vad background noise estimates */
1561 noise_estimate_update(st, level, pOverflow);
1562
1563 /* Add speech and complex hangover and return speech VAD_flag */
1564 /* long term complex hangover may be added */
1565 st->speech_vad_decision = hangover_addition(st, noise_level, low_power_flag, pOverflow);
1566
1567 return (st->speech_vad_decision);
1568 }
1569
1570
1571 /*
1572 ------------------------------------------------------------------------------
1573 FUNCTION NAME: vad1_init
1574 ------------------------------------------------------------------------------
1575 INPUT AND OUTPUT DEFINITIONS
1576
1577 Inputs:
1578 state -- double pointer to type vadState1 -- pointer to memory to
1579 be initialized.
1580
1581 Outputs:
1582 state -- points to initalized area in memory.
1583
1584 Returns:
1585 None
1586
1587 Global Variables Used:
1588 None
1589
1590 Local Variables Needed:
1591 None
1592
1593 ------------------------------------------------------------------------------
1594 FUNCTION DESCRIPTION
1595
1596 Allocates state memory and initializes state memory
1597
1598 ------------------------------------------------------------------------------
1599 REQUIREMENTS
1600
1601 None
1602
1603 ------------------------------------------------------------------------------
1604 REFERENCES
1605
1606 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1607
1608 ------------------------------------------------------------------------------
1609 PSEUDO-CODE
1610
1611
1612 ------------------------------------------------------------------------------
1613 RESOURCES USED [optional]
1614
1615 When the code is written for a specific target processor the
1616 the resources used should be documented below.
1617
1618 HEAP MEMORY USED: x bytes
1619
1620 STACK MEMORY USED: x bytes
1621
1622 CLOCK CYCLES: (cycle count equation for this function) + (variable
1623 used to represent cycle count for each subroutine
1624 called)
1625 where: (cycle count variable) = cycle count for [subroutine
1626 name]
1627
1628 ------------------------------------------------------------------------------
1629 CAUTION [optional]
1630 [State any special notes, constraints or cautions for users of this function]
1631
1632 ------------------------------------------------------------------------------
1633 */
1634
vad1_init(vadState1 ** state)1635 Word16 vad1_init(vadState1 **state)
1636 {
1637 vadState1* s;
1638
1639 if (state == (vadState1 **) NULL)
1640 {
1641 return -1;
1642 }
1643 *state = NULL;
1644
1645 /* allocate memory */
1646 if ((s = (vadState1 *) malloc(sizeof(vadState1))) == NULL)
1647 {
1648 return -1;
1649 }
1650
1651 vad1_reset(s);
1652
1653 *state = s;
1654
1655 return 0;
1656 }
1657
1658 /*
1659 ------------------------------------------------------------------------------
1660 FUNCTION NAME: vad1_reset
1661 ------------------------------------------------------------------------------
1662 INPUT AND OUTPUT DEFINITIONS
1663
1664 Inputs:
1665 state -- pointer to type vadState1 -- State struct
1666
1667 Outputs:
1668 state -- pointer to type vadState1 -- State struct
1669
1670 Returns:
1671 None
1672
1673 Global Variables Used:
1674 None
1675
1676 Local Variables Needed:
1677 None
1678
1679 ------------------------------------------------------------------------------
1680 FUNCTION DESCRIPTION
1681
1682 Purpose: Resets state memory to zero
1683
1684 ------------------------------------------------------------------------------
1685 REQUIREMENTS
1686
1687 None
1688
1689 ------------------------------------------------------------------------------
1690 REFERENCES
1691
1692 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1693
1694 ------------------------------------------------------------------------------
1695 PSEUDO-CODE
1696
1697
1698 ------------------------------------------------------------------------------
1699 RESOURCES USED [optional]
1700
1701 When the code is written for a specific target processor the
1702 the resources used should be documented below.
1703
1704 HEAP MEMORY USED: x bytes
1705
1706 STACK MEMORY USED: x bytes
1707
1708 CLOCK CYCLES: (cycle count equation for this function) + (variable
1709 used to represent cycle count for each subroutine
1710 called)
1711 where: (cycle count variable) = cycle count for [subroutine
1712 name]
1713
1714 ------------------------------------------------------------------------------
1715 CAUTION [optional]
1716 [State any special notes, constraints or cautions for users of this function]
1717
1718 ------------------------------------------------------------------------------
1719 */
1720
vad1_reset(vadState1 * state)1721 Word16 vad1_reset(vadState1 *state)
1722 {
1723 Word16 i;
1724 Word16 j;
1725
1726 if (state == (vadState1 *) NULL)
1727 {
1728 return -1;
1729 }
1730
1731 /* Initialize pitch detection variables */
1732 state->oldlag_count = 0;
1733 state->oldlag = 0;
1734 state->pitch = 0;
1735 state->tone = 0;
1736
1737 state->complex_high = 0;
1738 state->complex_low = 0;
1739 state->complex_hang_timer = 0;
1740
1741 state->vadreg = 0;
1742
1743 state->stat_count = 0;
1744 state->burst_count = 0;
1745 state->hang_count = 0;
1746 state->complex_hang_count = 0;
1747
1748 /* initialize memory used by the filter bank */
1749 for (i = 0; i < 3; i++)
1750 {
1751 for (j = 0; j < 2; j++)
1752 {
1753 state->a_data5[i][j] = 0;
1754 }
1755 }
1756
1757 for (i = 0; i < 5; i++)
1758 {
1759 state->a_data3[i] = 0;
1760 }
1761
1762 /* initialize the rest of the memory */
1763 for (i = 0; i < COMPLEN; i++)
1764 {
1765 state->bckr_est[i] = NOISE_INIT;
1766 state->old_level[i] = NOISE_INIT;
1767 state->ave_level[i] = NOISE_INIT;
1768 state->sub_level[i] = 0;
1769 }
1770
1771 state->best_corr_hp = CVAD_LOWPOW_RESET;
1772
1773 state->speech_vad_decision = 0;
1774 state->complex_warning = 0;
1775 state->sp_burst_count = 0;
1776
1777 state->corr_hp_fast = CVAD_LOWPOW_RESET;
1778
1779 return 0;
1780 }
1781
1782
1783 /*
1784 ------------------------------------------------------------------------------
1785 FUNCTION NAME: vad1_exit
1786 ------------------------------------------------------------------------------
1787 INPUT AND OUTPUT DEFINITIONS
1788
1789 Inputs:
1790 state -- pointer to type vadState1 -- State struct
1791
1792 Outputs:
1793 None
1794
1795 Returns:
1796 None
1797
1798 Global Variables Used:
1799 None
1800
1801 Local Variables Needed:
1802 None
1803
1804 ------------------------------------------------------------------------------
1805 FUNCTION DESCRIPTION
1806
1807 The memory used for state memory is freed
1808
1809 ------------------------------------------------------------------------------
1810 REQUIREMENTS
1811
1812 None
1813
1814 ------------------------------------------------------------------------------
1815 REFERENCES
1816
1817 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1818
1819 ------------------------------------------------------------------------------
1820 PSEUDO-CODE
1821
1822
1823 ------------------------------------------------------------------------------
1824 RESOURCES USED [optional]
1825
1826 When the code is written for a specific target processor the
1827 the resources used should be documented below.
1828
1829 HEAP MEMORY USED: x bytes
1830
1831 STACK MEMORY USED: x bytes
1832
1833 CLOCK CYCLES: (cycle count equation for this function) + (variable
1834 used to represent cycle count for each subroutine
1835 called)
1836 where: (cycle count variable) = cycle count for [subroutine
1837 name]
1838
1839 ------------------------------------------------------------------------------
1840 CAUTION [optional]
1841 [State any special notes, constraints or cautions for users of this function]
1842
1843 ------------------------------------------------------------------------------
1844 */
1845
vad1_exit(vadState1 ** state)1846 void vad1_exit(vadState1 **state)
1847 {
1848 if (state == NULL || *state == NULL)
1849 return;
1850
1851 /* deallocate memory */
1852 free(*state);
1853 *state = NULL;
1854
1855 return;
1856 }
1857
1858
1859 /*
1860 ------------------------------------------------------------------------------
1861 FUNCTION NAME: vad_complex_detection_update
1862 ------------------------------------------------------------------------------
1863 INPUT AND OUTPUT DEFINITIONS
1864
1865 Inputs:
1866 best_corr_hp -- Word16 -- best Corr
1867 state -- pointer to type vadState1 -- State struct
1868
1869 Outputs:
1870 state -- pointer to type vadState1 -- State struct
1871
1872 Returns:
1873 None
1874
1875 Global Variables Used:
1876 None
1877
1878 Local Variables Needed:
1879 None
1880
1881 ------------------------------------------------------------------------------
1882 FUNCTION DESCRIPTION
1883
1884 Purpose : update vad->bestCorr_hp complex signal feature state
1885 ------------------------------------------------------------------------------
1886 REQUIREMENTS
1887
1888 None
1889
1890 ------------------------------------------------------------------------------
1891 REFERENCES
1892
1893 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1894
1895 ------------------------------------------------------------------------------
1896 PSEUDO-CODE
1897
1898
1899 ------------------------------------------------------------------------------
1900 RESOURCES USED [optional]
1901
1902 When the code is written for a specific target processor the
1903 the resources used should be documented below.
1904
1905 HEAP MEMORY USED: x bytes
1906
1907 STACK MEMORY USED: x bytes
1908
1909 CLOCK CYCLES: (cycle count equation for this function) + (variable
1910 used to represent cycle count for each subroutine
1911 called)
1912 where: (cycle count variable) = cycle count for [subroutine
1913 name]
1914
1915 ------------------------------------------------------------------------------
1916 CAUTION [optional]
1917 [State any special notes, constraints or cautions for users of this function]
1918
1919 ------------------------------------------------------------------------------
1920 */
1921
vad_complex_detection_update(vadState1 * st,Word16 best_corr_hp)1922 void vad_complex_detection_update(
1923 vadState1 *st, /* i/o : State struct */
1924 Word16 best_corr_hp) /* i : best Corr */
1925 {
1926 st->best_corr_hp = best_corr_hp;
1927 }
1928
1929
1930
1931 /*
1932 ------------------------------------------------------------------------------
1933 FUNCTION NAME: vad_tone_detection
1934 ------------------------------------------------------------------------------
1935 INPUT AND OUTPUT DEFINITIONS
1936
1937 Inputs:
1938 st -- pointer to type vadState1 -- State struct
1939 t0 -- Word32 -- autocorrelation maxima
1940 t1 -- Word32 -- energy
1941
1942 Outputs:
1943 st -- pointer to type vadState1 -- State struct
1944 pOverflow -- pointer to type Flag -- overflow indicator
1945
1946 Returns:
1947 None
1948
1949 Global Variables Used:
1950 None
1951
1952 Local Variables Needed:
1953 None
1954
1955 ------------------------------------------------------------------------------
1956 FUNCTION DESCRIPTION
1957
1958 Purpose : Set tone flag if pitch gain is high. This is used to detect
1959 signaling tones and other signals with high pitch gain.
1960 Inputs : tone: flags indicating presence of a tone
1961 Outputs : tone: flags indicating presence of a tone
1962 ------------------------------------------------------------------------------
1963 REQUIREMENTS
1964
1965 None
1966
1967 ------------------------------------------------------------------------------
1968 REFERENCES
1969
1970 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1971
1972 ------------------------------------------------------------------------------
1973 PSEUDO-CODE
1974
1975
1976 ------------------------------------------------------------------------------
1977 RESOURCES USED [optional]
1978
1979 When the code is written for a specific target processor the
1980 the resources used should be documented below.
1981
1982 HEAP MEMORY USED: x bytes
1983
1984 STACK MEMORY USED: x bytes
1985
1986 CLOCK CYCLES: (cycle count equation for this function) + (variable
1987 used to represent cycle count for each subroutine
1988 called)
1989 where: (cycle count variable) = cycle count for [subroutine
1990 name]
1991
1992 ------------------------------------------------------------------------------
1993 CAUTION [optional]
1994 [State any special notes, constraints or cautions for users of this function]
1995
1996 ------------------------------------------------------------------------------
1997 */
1998
vad_tone_detection(vadState1 * st,Word32 t0,Word32 t1,Flag * pOverflow)1999 void vad_tone_detection(
2000 vadState1 *st, /* i/o : State struct */
2001 Word32 t0, /* i : autocorrelation maxima */
2002 Word32 t1, /* i : energy */
2003 Flag *pOverflow /* o : Flag set when overflow occurs */
2004 )
2005 {
2006 Word16 temp;
2007 /*
2008 if (t0 > TONE_THR * t1)
2009 set tone flag
2010 */
2011 temp = pv_round(t1, pOverflow);
2012
2013 if ((temp > 0) && (L_msu(t0, temp, TONE_THR, pOverflow) > 0))
2014 {
2015 st->tone |= 0x4000;
2016 }
2017 }
2018
2019
2020 /*
2021 ------------------------------------------------------------------------------
2022 FUNCTION NAME: vad_tone_detection_update
2023 ------------------------------------------------------------------------------
2024 INPUT AND OUTPUT DEFINITIONS
2025
2026 Inputs:
2027 one_lag_per_frame -- Word16 -- 1 if one open-loop lag is calculated per
2028 each frame, otherwise 0
2029 st -- pointer to type vadState1 -- State struct
2030
2031 Outputs:
2032 st -- pointer to type vadState1 -- State struct
2033 pOverflow -- pointer to type Flag -- overflow indicator
2034
2035 Returns:
2036 None
2037
2038 Global Variables Used:
2039 None
2040
2041 Local Variables Needed:
2042 None
2043
2044 ------------------------------------------------------------------------------
2045 FUNCTION DESCRIPTION
2046
2047 Purpose : Update the tone flag register. Tone flags are shifted right
2048 by one bit. This function should be called from the speech
2049 encoder before call to Vad_tone_detection() function.
2050
2051 ------------------------------------------------------------------------------
2052 REQUIREMENTS
2053
2054 None
2055
2056 ------------------------------------------------------------------------------
2057 REFERENCES
2058
2059 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
2060
2061 ------------------------------------------------------------------------------
2062 PSEUDO-CODE
2063
2064
2065 ------------------------------------------------------------------------------
2066 RESOURCES USED [optional]
2067
2068 When the code is written for a specific target processor the
2069 the resources used should be documented below.
2070
2071 HEAP MEMORY USED: x bytes
2072
2073 STACK MEMORY USED: x bytes
2074
2075 CLOCK CYCLES: (cycle count equation for this function) + (variable
2076 used to represent cycle count for each subroutine
2077 called)
2078 where: (cycle count variable) = cycle count for [subroutine
2079 name]
2080
2081 ------------------------------------------------------------------------------
2082 CAUTION [optional]
2083 [State any special notes, constraints or cautions for users of this function]
2084
2085 ------------------------------------------------------------------------------
2086 */
2087
vad_tone_detection_update(vadState1 * st,Word16 one_lag_per_frame,Flag * pOverflow)2088 void vad_tone_detection_update(
2089 vadState1 *st, /* i/o : State struct */
2090 Word16 one_lag_per_frame, /* i : 1 if one open-loop lag */
2091 /* is calculated per each */
2092 /* frame, otherwise 0 */
2093 Flag *pOverflow /* o : Flags overflow */
2094 )
2095 {
2096 /* Shift tone flags right by one bit */
2097 st->tone = shr(st->tone, 1, pOverflow);
2098
2099 /* If open-loop lag is calculated only once in each frame, do extra update
2100 and assume that the other tone flag of the frame is one. */
2101 if (one_lag_per_frame != 0)
2102 {
2103 st->tone = shr(st->tone, 1, pOverflow);
2104 st->tone |= 0x2000;
2105 }
2106 }
2107
2108
2109 /*
2110 ------------------------------------------------------------------------------
2111 FUNCTION NAME: vad_pitch_detection
2112 ------------------------------------------------------------------------------
2113 INPUT AND OUTPUT DEFINITIONS
2114
2115 Inputs:
2116 T_op -- array of type Word16 -- speech encoder open loop lags
2117 st -- pointer to type vadState1 -- State struct
2118
2119 Outputs:
2120 st -- pointer to type vadState1 -- State struct
2121 pOverflow -- pointer to type Flag -- overflow indicator
2122
2123 Returns:
2124 None
2125
2126 Global Variables Used:
2127 None
2128
2129 Local Variables Needed:
2130 None
2131
2132 ------------------------------------------------------------------------------
2133 FUNCTION DESCRIPTION
2134
2135 Purpose : Test whether signal contains pitch or other periodic
2136 component.
2137 Return value : Boolean voiced / unvoiced decision in state variable
2138
2139 ------------------------------------------------------------------------------
2140 REQUIREMENTS
2141
2142 None
2143
2144 ------------------------------------------------------------------------------
2145 REFERENCES
2146
2147 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
2148
2149 ------------------------------------------------------------------------------
2150 PSEUDO-CODE
2151
2152
2153 ------------------------------------------------------------------------------
2154 RESOURCES USED [optional]
2155
2156 When the code is written for a specific target processor the
2157 the resources used should be documented below.
2158
2159 HEAP MEMORY USED: x bytes
2160
2161 STACK MEMORY USED: x bytes
2162
2163 CLOCK CYCLES: (cycle count equation for this function) + (variable
2164 used to represent cycle count for each subroutine
2165 called)
2166 where: (cycle count variable) = cycle count for [subroutine
2167 name]
2168
2169 ------------------------------------------------------------------------------
2170 CAUTION [optional]
2171 [State any special notes, constraints or cautions for users of this function]
2172
2173 ------------------------------------------------------------------------------
2174 */
2175
vad_pitch_detection(vadState1 * st,Word16 T_op[],Flag * pOverflow)2176 void vad_pitch_detection(
2177 vadState1 *st, /* i/o : State struct */
2178 Word16 T_op[], /* i : speech encoder open loop lags */
2179 Flag *pOverflow /* o : Flag set when overflow occurs */
2180 )
2181 {
2182 Word16 lagcount;
2183 Word16 i;
2184 Word16 temp;
2185
2186 lagcount = 0;
2187
2188 for (i = 0; i < 2; i++)
2189 {
2190 temp = sub(st->oldlag, T_op[i], pOverflow);
2191 temp = abs_s(temp);
2192
2193 if (temp < LTHRESH)
2194 {
2195 lagcount = add(lagcount, 1, pOverflow);
2196 }
2197
2198 /* Save the current LTP lag */
2199 st->oldlag = T_op[i];
2200 }
2201
2202 /* Make pitch decision.
2203 Save flag of the pitch detection to the variable pitch.
2204 */
2205 st->pitch = shr(st->pitch, 1, pOverflow);
2206
2207 temp =
2208 add(
2209 st->oldlag_count,
2210 lagcount,
2211 pOverflow);
2212
2213 if (temp >= NTHRESH)
2214 {
2215 st->pitch |= 0x4000;
2216 }
2217
2218 /* Update oldlagcount */
2219 st->oldlag_count = lagcount;
2220 }
2221
2222 /*
2223 ------------------------------------------------------------------------------
2224 FUNCTION NAME: vad1
2225 ------------------------------------------------------------------------------
2226 INPUT AND OUTPUT DEFINITIONS
2227
2228 Inputs:
2229 st -- pointer to type vadState1 -- State struct
2230 in_buf -- array of type Word16 -- samples of the input frame
2231
2232 Outputs:
2233 st -- pointer to type vadState1 -- State struct
2234 pOverflow -- pointer to type Flag -- overflow indicator
2235
2236 Returns:
2237 VAD Decision, 1 = speech, 0 = noise
2238
2239 Global Variables Used:
2240 None
2241
2242 Local Variables Needed:
2243 None
2244
2245 ------------------------------------------------------------------------------
2246 FUNCTION DESCRIPTION
2247
2248 Purpose : Main program for Voice Activity Detection (VAD) for AMR
2249 Return value : VAD Decision, 1 = speech, 0 = noise
2250
2251 ------------------------------------------------------------------------------
2252 REQUIREMENTS
2253
2254 None
2255
2256 ------------------------------------------------------------------------------
2257 REFERENCES
2258
2259 vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
2260
2261 ------------------------------------------------------------------------------
2262 PSEUDO-CODE
2263
2264
2265 ------------------------------------------------------------------------------
2266 RESOURCES USED [optional]
2267
2268 When the code is written for a specific target processor the
2269 the resources used should be documented below.
2270
2271 HEAP MEMORY USED: x bytes
2272
2273 STACK MEMORY USED: x bytes
2274
2275 CLOCK CYCLES: (cycle count equation for this function) + (variable
2276 used to represent cycle count for each subroutine
2277 called)
2278 where: (cycle count variable) = cycle count for [subroutine
2279 name]
2280
2281 ------------------------------------------------------------------------------
2282 CAUTION [optional]
2283 [State any special notes, constraints or cautions for users of this function]
2284
2285 ------------------------------------------------------------------------------
2286 */
2287
vad1(vadState1 * st,Word16 in_buf[],Flag * pOverflow)2288 Word16 vad1(
2289 vadState1 *st, /* i/o : State struct */
2290 Word16 in_buf[], /* i : samples of the input frame */
2291 Flag *pOverflow /* o : Flag set when overflow occurs */
2292 )
2293 {
2294 Word16 level[COMPLEN];
2295 Word32 pow_sum;
2296 Word16 i;
2297
2298 /* Calculate power of the input frame. */
2299 pow_sum = 0L;
2300
2301 for (i = 0; i < FRAME_LEN; i++)
2302 {
2303 pow_sum = L_mac(pow_sum, in_buf[i-LOOKAHEAD], in_buf[i-LOOKAHEAD], pOverflow);
2304 }
2305
2306 /*
2307 If input power is very low, clear pitch flag of the current frame
2308 */
2309 if (L_sub(pow_sum, POW_PITCH_THR, pOverflow) < 0)
2310 {
2311 st->pitch = st->pitch & 0x3fff;
2312 }
2313
2314 /*
2315 If input power is very low, clear complex flag of the "current" frame
2316 */
2317 if (L_sub(pow_sum, POW_COMPLEX_THR, pOverflow) < 0)
2318 {
2319 st->complex_low = st->complex_low & 0x3fff;
2320 }
2321
2322 /*
2323 Run the filter bank which calculates signal levels at each band
2324 */
2325 filter_bank(st, in_buf, level, pOverflow);
2326
2327 return (vad_decision(st, level, pow_sum, pOverflow));
2328 }
2329
2330
2331