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/p_ol_wgh.c
35 Funtions: p_ol_wgh_init
36 p_ol_wgh_reset
37 p_ol_wgh_exit
38 Lag_max
39 Pitch_ol_wgh
40
41 Date: 02/05/2002
42 ------------------------------------------------------------------------------
43 REVISION HISTORY
44
45 Description: t0 was not being declared as Word32.
46
47 Description: Replaced OSCL mem type functions and eliminated include
48 files that now are chosen by OSCL definitions
49
50 Description: Replaced "int" and/or "char" with OSCL defined types.
51
52 Description: Changed round function name to pv_round to avoid conflict with
53 round function in C standard library.
54
55 Description:
56
57 ------------------------------------------------------------------------------
58 MODULE DESCRIPTION
59
60 The modules in this file compute the open loop pitch lag with weighting.
61 ------------------------------------------------------------------------------
62 */
63
64
65 /*----------------------------------------------------------------------------
66 ; INCLUDES
67 ----------------------------------------------------------------------------*/
68 #include <stdlib.h>
69
70 #include "p_ol_wgh.h"
71 #include "typedef.h"
72 #include "cnst.h"
73 #include "basic_op.h"
74 #include "gmed_n.h"
75 #include "inv_sqrt.h"
76 #include "vad1.h"
77 #include "calc_cor.h"
78 #include "hp_max.h"
79
80 /*----------------------------------------------------------------------------
81 ; MACROS
82 ; Define module specific macros here
83 ----------------------------------------------------------------------------*/
84
85
86 /*----------------------------------------------------------------------------
87 ; DEFINES
88 ; Include all pre-processor statements here. Include conditional
89 ; compile variables also.
90 ----------------------------------------------------------------------------*/
91
92 /*----------------------------------------------------------------------------
93 ; LOCAL FUNCTION DEFINITIONS
94 ; Function Prototype declaration
95 ----------------------------------------------------------------------------*/
96
97 /*----------------------------------------------------------------------------
98 ; LOCAL VARIABLE DEFINITIONS
99 ; Variable declaration - defined here and used outside this module
100 ----------------------------------------------------------------------------*/
101
102
103 /*
104 ------------------------------------------------------------------------------
105 FUNCTION NAME: p_ol_wgh_init
106 ------------------------------------------------------------------------------
107 INPUT AND OUTPUT DEFINITIONS
108
109 Inputs
110 state = pointer to a pointer of structure type pitchOLWghtState
111
112 Outputs:
113 None
114
115 Returns:
116 0 if the memory allocation is a success
117 -1 if the memory allocation fails
118
119 Global Variables Used:
120 None.
121
122 Local Variables Needed:
123 None.
124
125 ------------------------------------------------------------------------------
126 FUNCTION DESCRIPTION
127
128 This function allocates state memory and initializes state memory
129
130 ------------------------------------------------------------------------------
131 REQUIREMENTS
132
133 None.
134
135 ------------------------------------------------------------------------------
136 REFERENCES
137
138 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
139
140 ------------------------------------------------------------------------------
141 PSEUDO-CODE
142
143 int p_ol_wgh_init (pitchOLWghtState **state)
144 {
145 pitchOLWghtState* s;
146
147 if (state == (pitchOLWghtState **) NULL){
148 // fprintf(stderr, "p_ol_wgh_init: invalid parameter\n");
149 return -1;
150 }
151 *state = NULL;
152
153 // allocate memory
154 if ((s= (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL){
155 // fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n");
156 return -1;
157 }
158
159 p_ol_wgh_reset(s);
160
161 *state = s;
162
163 return 0;
164 }
165
166 ------------------------------------------------------------------------------
167 RESOURCES USED [optional]
168
169 When the code is written for a specific target processor the
170 the resources used should be documented below.
171
172 HEAP MEMORY USED: x bytes
173
174 STACK MEMORY USED: x bytes
175
176 CLOCK CYCLES: (cycle count equation for this function) + (variable
177 used to represent cycle count for each subroutine
178 called)
179 where: (cycle count variable) = cycle count for [subroutine
180 name]
181
182 ------------------------------------------------------------------------------
183 CAUTION [optional]
184 [State any special notes, constraints or cautions for users of this function]
185
186 ------------------------------------------------------------------------------
187 */
188
p_ol_wgh_init(pitchOLWghtState ** state)189 Word16 p_ol_wgh_init(pitchOLWghtState **state)
190 {
191 pitchOLWghtState* s;
192
193 if (state == (pitchOLWghtState **) NULL)
194 {
195 /* fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); */
196 return -1;
197 }
198 *state = NULL;
199
200 /* allocate memory */
201 if ((s = (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL)
202 {
203 /* fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); */
204 return -1;
205 }
206
207 p_ol_wgh_reset(s);
208
209 *state = s;
210
211 return 0;
212 }
213
214 /*----------------------------------------------------------------------------
215 ; End Function: p_ol_wgh_init
216 ----------------------------------------------------------------------------*/
217
218 /*
219 ------------------------------------------------------------------------------
220 FUNCTION NAME: p_ol_wgh_reset
221 ------------------------------------------------------------------------------
222 INPUT AND OUTPUT DEFINITIONS
223
224 Inputs
225 st = pointer to structure type pitchOLWghtState
226
227 Outputs:
228 None
229
230 Returns:
231 0 if the memory initialization is a success
232 -1 if the memory initialization fails
233
234 Global Variables Used:
235 None.
236
237 Local Variables Needed:
238 None.
239
240 ------------------------------------------------------------------------------
241 FUNCTION DESCRIPTION
242
243 This function initializes state memory to zero
244
245 ------------------------------------------------------------------------------
246 REQUIREMENTS
247
248 None.
249
250 ------------------------------------------------------------------------------
251 REFERENCES
252
253 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
254
255 ------------------------------------------------------------------------------
256 PSEUDO-CODE
257
258 int p_ol_wgh_reset (pitchOLWghtState *st)
259 {
260 if (st == (pitchOLWghtState *) NULL){
261 // fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n");
262 return -1;
263 }
264
265 // Reset pitch search states
266 st->old_T0_med = 40;
267 st->ada_w = 0;
268 st->wght_flg = 0;
269
270 return 0;
271 }
272
273 ------------------------------------------------------------------------------
274 RESOURCES USED [optional]
275
276 When the code is written for a specific target processor the
277 the resources used should be documented below.
278
279 HEAP MEMORY USED: x bytes
280
281 STACK MEMORY USED: x bytes
282
283 CLOCK CYCLES: (cycle count equation for this function) + (variable
284 used to represent cycle count for each subroutine
285 called)
286 where: (cycle count variable) = cycle count for [subroutine
287 name]
288
289 ------------------------------------------------------------------------------
290 CAUTION [optional]
291 [State any special notes, constraints or cautions for users of this function]
292
293 ------------------------------------------------------------------------------
294 */
295
p_ol_wgh_reset(pitchOLWghtState * st)296 Word16 p_ol_wgh_reset(pitchOLWghtState *st)
297 {
298 if (st == (pitchOLWghtState *) NULL)
299 {
300 /* fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); */
301 return -1;
302 }
303
304 /* Reset pitch search states */
305 st->old_T0_med = 40;
306 st->ada_w = 0;
307 st->wght_flg = 0;
308
309 return 0;
310 }
311
312 /*----------------------------------------------------------------------------
313 ; End Function: p_ol_wgh_reset
314 ----------------------------------------------------------------------------*/
315
316 /*
317 ------------------------------------------------------------------------------
318 FUNCTION NAME: p_ol_wgh_exit
319 ------------------------------------------------------------------------------
320 INPUT AND OUTPUT DEFINITIONS
321
322 Inputs
323 st = pointer to a pointer of structure type pitchOLWghtState
324
325 Outputs:
326 None
327
328 Returns:
329 0 if the memory initialization is a success
330 -1 if the memory initialization fails
331
332 Global Variables Used:
333 None.
334
335 Local Variables Needed:
336 None.
337
338 ------------------------------------------------------------------------------
339 FUNCTION DESCRIPTION
340
341 This function frees the memory used for state memory
342
343 ------------------------------------------------------------------------------
344 REQUIREMENTS
345
346 None.
347
348 ------------------------------------------------------------------------------
349 REFERENCES
350
351 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
352
353 ------------------------------------------------------------------------------
354 PSEUDO-CODE
355
356 void p_ol_wgh_exit (pitchOLWghtState **state)
357 {
358 if (state == NULL || *state == NULL)
359 return;
360
361 // deallocate memory
362 free(*state);
363 *state = NULL;
364
365 return;
366 }
367
368 ------------------------------------------------------------------------------
369 RESOURCES USED [optional]
370
371 When the code is written for a specific target processor the
372 the resources used should be documented below.
373
374 HEAP MEMORY USED: x bytes
375
376 STACK MEMORY USED: x bytes
377
378 CLOCK CYCLES: (cycle count equation for this function) + (variable
379 used to represent cycle count for each subroutine
380 called)
381 where: (cycle count variable) = cycle count for [subroutine
382 name]
383
384 ------------------------------------------------------------------------------
385 CAUTION [optional]
386 [State any special notes, constraints or cautions for users of this function]
387
388 ------------------------------------------------------------------------------
389 */
390
p_ol_wgh_exit(pitchOLWghtState ** state)391 void p_ol_wgh_exit(pitchOLWghtState **state)
392 {
393 if (state == NULL || *state == NULL)
394 return;
395
396 /* deallocate memory */
397 free(*state);
398 *state = NULL;
399
400 return;
401 }
402
403
404 /*----------------------------------------------------------------------------
405 ; End Function: p_ol_wgh_exit
406 ----------------------------------------------------------------------------*/
407 /*
408 ------------------------------------------------------------------------------
409 FUNCTION NAME: Lag_max
410 ------------------------------------------------------------------------------
411 INPUT AND OUTPUT DEFINITIONS
412
413 Inputs:
414 corr = pointer to buffer of correlation values (Word32)
415 scal_sig = pointer to buffer of scaled signal values (Word16)
416 scal_fac = scaled signal factor (Word16)
417 scal_flag = EFR compatible scaling flag (Word16)
418 L_frame = length of frame to compute pitch (Word16)
419 lag_max = maximum lag (Word16)
420 lag_min = minimum lag (Word16)
421 cor_max = pointer to the normalized correlation of selected lag (Word16)
422 rmax = pointer to max(<s[i]*s[j]>), (Word32)
423 r0 = pointer to the residual energy (Word32)
424 dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
425 pOverflow = Pointer to overflow (Flag)
426
427 Outputs:
428 cor_max contains the newly calculated normalized correlation of the
429 selected lag
430 rmax contains the newly calculated max(<s[i]*s[j]>)
431 r0 contains the newly calculated residual energy
432 pOverflow -> 1 if the math functions called by this routine saturate.
433
434 Returns:
435 p_max = lag of the max correlation found (Word16)
436
437 Global Variables Used:
438 None.
439
440 Local Variables Needed:
441 None.
442
443 ------------------------------------------------------------------------------
444 FUNCTION DESCRIPTION
445
446 This function finds the lag that has maximum correlation of scal_sig[] in a
447 given delay range.
448 The correlation is given by
449 cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max
450 The functions outputs the maximum correlation after normalization and the
451 corresponding lag.
452
453 ------------------------------------------------------------------------------
454 REQUIREMENTS
455
456 None.
457
458 ------------------------------------------------------------------------------
459 REFERENCES
460
461 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
462
463 ------------------------------------------------------------------------------
464 PSEUDO-CODE
465
466 static Word16 Lag_max ( // o : lag found
467 vadState *vadSt, // i/o : VAD state struct
468 Word32 corr[], // i : correlation vector.
469 Word16 scal_sig[], // i : scaled signal.
470 Word16 L_frame, // i : length of frame to compute pitch
471 Word16 lag_max, // i : maximum lag
472 Word16 lag_min, // i : minimum lag
473 Word16 old_lag, // i : old open-loop lag
474 Word16 *cor_max, // o : normalized correlation of selected lag
475 Word16 wght_flg, // i : is weighting function used
476 Word16 *gain_flg, // o : open-loop flag
477 Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0
478 )
479 {
480 Word16 i, j;
481 Word16 *p, *p1;
482 Word32 max, t0;
483 Word16 t0_h, t0_l;
484 Word16 p_max;
485 const Word16 *ww, *we;
486 Word32 t1;
487
488 ww = &corrweight[250];
489 we = &corrweight[123 + lag_max - old_lag];
490
491 max = MIN_32;
492 p_max = lag_max;
493
494 for (i = lag_max; i >= lag_min; i--)
495 {
496 t0 = corr[-i];
497
498 // Weighting of the correlation function.
499 L_Extract (corr[-i], &t0_h, &t0_l);
500 t0 = Mpy_32_16 (t0_h, t0_l, *ww);
501 ww--;
502 if (wght_flg > 0) {
503 // Weight the neighbourhood of the old lag
504 L_Extract (t0, &t0_h, &t0_l);
505 t0 = Mpy_32_16 (t0_h, t0_l, *we);
506 we--;
507 }
508
509 if (L_sub (t0, max) >= 0)
510 {
511 max = t0;
512 p_max = i;
513 }
514 }
515
516 p = &scal_sig[0];
517 p1 = &scal_sig[-p_max];
518 t0 = 0;
519 t1 = 0;
520
521 for (j = 0; j < L_frame; j++, p++, p1++)
522 {
523 t0 = L_mac (t0, *p, *p1);
524 t1 = L_mac (t1, *p1, *p1);
525 }
526
527 if (dtx)
528 { // no test() call since this if is only in simulation env
529 #ifdef VAD2
530 vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0); // Save max correlation
531 vadSt->L_R0 = L_add(vadSt->L_R0, t1); // Save max energy
532 #else
533 // update and detect tone
534 vad_tone_detection_update (vadSt, 0);
535 vad_tone_detection (vadSt, t0, t1);
536 #endif
537 }
538
539 // gain flag is set according to the open_loop gain
540 // is t2/t1 > 0.4 ?
541 *gain_flg = pv_round(L_msu(t0, pv_round(t1), 13107));
542
543 *cor_max = 0;
544
545 return (p_max);
546 }
547
548 ------------------------------------------------------------------------------
549 RESOURCES USED [optional]
550
551 When the code is written for a specific target processor the
552 the resources used should be documented below.
553
554 HEAP MEMORY USED: x bytes
555
556 STACK MEMORY USED: x bytes
557
558 CLOCK CYCLES: (cycle count equation for this function) + (variable
559 used to represent cycle count for each subroutine
560 called)
561 where: (cycle count variable) = cycle count for [subroutine
562 name]
563
564 ------------------------------------------------------------------------------
565 CAUTION [optional]
566 [State any special notes, constraints or cautions for users of this function]
567
568 ------------------------------------------------------------------------------
569 */
570
Lag_max(vadState * vadSt,Word32 corr[],Word16 scal_sig[],Word16 L_frame,Word16 lag_max,Word16 lag_min,Word16 old_lag,Word16 * cor_max,Word16 wght_flg,Word16 * gain_flg,Flag dtx,Flag * pOverflow)571 static Word16 Lag_max( /* o : lag found */
572 vadState *vadSt, /* i/o : VAD state struct */
573 Word32 corr[], /* i : correlation vector. */
574 Word16 scal_sig[], /* i : scaled signal. */
575 Word16 L_frame, /* i : length of frame to compute pitch */
576 Word16 lag_max, /* i : maximum lag */
577 Word16 lag_min, /* i : minimum lag */
578 Word16 old_lag, /* i : old open-loop lag */
579 Word16 *cor_max, /* o : normalized correlation of selected lag */
580 Word16 wght_flg, /* i : is weighting function used */
581 Word16 *gain_flg, /* o : open-loop flag */
582 Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */
583 Flag *pOverflow /* o : overflow flag */
584 )
585 {
586 Word16 i;
587 Word16 j;
588 Word16 *p;
589 Word16 *p1;
590 Word32 max;
591 Word32 t0;
592 Word16 t0_h;
593 Word16 t0_l;
594 Word16 p_max;
595 const Word16 *ww;
596 const Word16 *we;
597 Word32 t1;
598 Word16 temp;
599
600 ww = &corrweight[250];
601 we = &corrweight[123 + lag_max - old_lag];
602
603 max = MIN_32;
604 p_max = lag_max;
605
606 for (i = lag_max; i >= lag_min; i--)
607 {
608 t0 = corr[-i];
609
610 /* Weighting of the correlation function. */
611 L_Extract(corr[-i], &t0_h, &t0_l, pOverflow);
612 t0 = Mpy_32_16(t0_h, t0_l, *ww, pOverflow);
613 ww--;
614 if (wght_flg > 0)
615 {
616 /* Weight the neighbourhood of the old lag. */
617 L_Extract(t0, &t0_h, &t0_l, pOverflow);
618 t0 = Mpy_32_16(t0_h, t0_l, *we, pOverflow);
619 we--;
620 }
621
622 /* if (L_sub (t0, max) >= 0) */
623 if (t0 >= max)
624 {
625 max = t0;
626 p_max = i;
627 }
628 }
629 p = &scal_sig[0];
630 p1 = &scal_sig[-p_max];
631 t0 = 0;
632 t1 = 0;
633
634 for (j = 0; j < L_frame; j++, p++, p1++)
635 {
636 t0 = L_mac(t0, *p, *p1, pOverflow);
637 t1 = L_mac(t1, *p1, *p1, pOverflow);
638 }
639
640 if (dtx)
641 { /* no test() call since this if is only in simulation env */
642 #ifdef VAD2
643 /* Save max correlation */
644 vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0, pOverflow);
645 /* Save max energy */
646 vadSt->L_R0 = L_add(vadSt->L_R0, t1, pOverflow);
647 #else
648 /* update and detect tone */
649 vad_tone_detection_update(vadSt, 0, pOverflow);
650 vad_tone_detection(vadSt, t0, t1, pOverflow);
651 #endif
652 }
653
654 /* gain flag is set according to the open_loop gain */
655 /* is t2/t1 > 0.4 ? */
656 temp = pv_round(t1, pOverflow);
657 t1 = L_msu(t0, temp, 13107, pOverflow);
658 *gain_flg = pv_round(t1, pOverflow);
659
660 *cor_max = 0;
661
662 return (p_max);
663 }
664 /*----------------------------------------------------------------------------
665 ; End Function: Lag_max
666 ----------------------------------------------------------------------------*/
667
668 /*
669 ------------------------------------------------------------------------------
670 FUNCTION NAME: Pitch_ol_wgh
671 ------------------------------------------------------------------------------
672 INPUT AND OUTPUT DEFINITIONS
673
674 Inputs:
675 st = pointer to pitchOLWghtState structure
676 vadSt = pointer to a vadState structure
677 signal = pointer to buffer of signal used to compute the open loop
678 pitch where signal[-pit_max] to signal[-1] should be known
679 pit_min = 16 bit value specifies the minimum pitch lag
680 pit_max = 16 bit value specifies the maximum pitch lag
681 L_frame = 16 bit value specifies the length of frame to compute pitch
682 old_lags = pointer to history with old stored Cl lags (Word16)
683 ol_gain_flg = pointer to OL gain flag (Word16)
684 idx = 16 bit value specifies the frame index
685 dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0
686 pOverflow = pointer to Overflow indicator (Flag)
687 Outputs
688 st = The pitchOLWghtState may be modified
689 vadSt = The vadSt state structure may be modified.
690 pOverflow -> 1 if the math functions invoked by this routine saturate.
691
692 Returns:
693 p_max1 = 16 bit value representing the open loop pitch lag.
694
695 Global Variables Used:
696 None.
697
698 Local Variables Needed:
699 None.
700
701 ------------------------------------------------------------------------------
702 FUNCTION DESCRIPTION
703
704 This function performs an open-loop pitch search with weighting
705 ------------------------------------------------------------------------------
706 REQUIREMENTS
707
708 None.
709
710 ------------------------------------------------------------------------------
711 REFERENCES
712
713 pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
714
715 ------------------------------------------------------------------------------
716 PSEUDO-CODE
717
718 Word16 Pitch_ol_wgh ( // o : open loop pitch lag
719 pitchOLWghtState *st, // i/o : State struct
720 vadState *vadSt, // i/o : VAD state struct/
721 Word16 signal[], // i : signal used to compute the open loop pitch
722 // signal[-pit_max] to signal[-1] should be known
723 Word16 pit_min, // i : minimum pitch lag
724 Word16 pit_max, // i : maximum pitch lag
725 Word16 L_frame, // i : length of frame to compute pitch
726 Word16 old_lags[], // i : history with old stored Cl lags
727 Word16 ol_gain_flg[], // i : OL gain flag
728 Word16 idx, // i : index
729 Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0
730 )
731 {
732 Word16 i;
733 Word16 max1;
734 Word16 p_max1;
735 Word32 t0;
736 #ifndef VAD2
737 Word16 corr_hp_max;
738 #endif
739 Word32 corr[PIT_MAX+1], *corr_ptr;
740
741 // Scaled signal
742 Word16 scaled_signal[PIT_MAX + L_FRAME];
743 Word16 *scal_sig;
744
745 scal_sig = &scaled_signal[pit_max];
746
747 t0 = 0L;
748 for (i = -pit_max; i < L_frame; i++)
749 {
750 t0 = L_mac (t0, signal[i], signal[i]);
751 }
752 //
753 // Scaling of input signal
754 //
755 // if Overflow -> scal_sig[i] = signal[i]>>2
756 // else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2
757 // else -> scal_sig[i] = signal[i]
758
759 //
760 // Verification for risk of overflow.
761 //
762
763 // Test for overflow
764 if (L_sub (t0, MAX_32) == 0L)
765 {
766 for (i = -pit_max; i < L_frame; i++)
767 {
768 scal_sig[i] = shr (signal[i], 3);
769 }
770 }
771 else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
772 {
773 for (i = -pit_max; i < L_frame; i++)
774 {
775 scal_sig[i] = shl (signal[i], 3);
776 }
777 }
778 else
779 {
780 for (i = -pit_max; i < L_frame; i++)
781 {
782 scal_sig[i] = signal[i];
783 }
784 }
785
786 // calculate all coreelations of scal_sig, from pit_min to pit_max
787 corr_ptr = &corr[pit_max];
788 comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
789
790 p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
791 st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
792 dtx);
793
794 if (ol_gain_flg[idx] > 0)
795 {
796 // Calculate 5-point median of previous lag
797 for (i = 4; i > 0; i--) // Shift buffer
798 {
799 old_lags[i] = old_lags[i-1];
800 }
801 old_lags[0] = p_max1;
802 st->old_T0_med = gmed_n (old_lags, 5);
803 st->ada_w = 32767; // Q15 = 1.0
804 }
805 else
806 {
807 st->old_T0_med = p_max1;
808 st->ada_w = mult(st->ada_w, 29491); // = ada_w = ada_w * 0.9
809 }
810
811 if (sub(st->ada_w, 9830) < 0) // ada_w - 0.3
812 {
813 st->wght_flg = 0;
814 }
815 else
816 {
817 st->wght_flg = 1;
818 }
819
820 #ifndef VAD2
821 if (dtx)
822 { // no test() call since this if is only in simulation env
823 if (sub(idx, 1) == 0)
824 {
825 // calculate max high-passed filtered correlation of all lags
826 hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
827
828 // update complex background detector
829 vad_complex_detection_update(vadSt, corr_hp_max);
830 }
831 }
832 #endif
833
834 return (p_max1);
835 }
836
837 ------------------------------------------------------------------------------
838 RESOURCES USED [optional]
839
840 When the code is written for a specific target processor the
841 the resources used should be documented below.
842
843 HEAP MEMORY USED: x bytes
844
845 STACK MEMORY USED: x bytes
846
847 CLOCK CYCLES: (cycle count equation for this function) + (variable
848 used to represent cycle count for each subroutine
849 called)
850 where: (cycle count variable) = cycle count for [subroutine
851 name]
852
853 ------------------------------------------------------------------------------
854 CAUTION [optional]
855 [State any special notes, constraints or cautions for users of this function]
856
857 ------------------------------------------------------------------------------
858 */
859
Pitch_ol_wgh(pitchOLWghtState * st,vadState * vadSt,Word16 signal[],Word16 pit_min,Word16 pit_max,Word16 L_frame,Word16 old_lags[],Word16 ol_gain_flg[],Word16 idx,Flag dtx,Flag * pOverflow)860 Word16 Pitch_ol_wgh( /* o : open loop pitch lag */
861 pitchOLWghtState *st, /* i/o : State struct */
862 vadState *vadSt, /* i/o : VAD state struct */
863 Word16 signal[], /* i : signal used to compute the open loop pitch */
864 /* signal[-pit_max] to signal[-1] should be known */
865 Word16 pit_min, /* i : minimum pitch lag */
866 Word16 pit_max, /* i : maximum pitch lag */
867 Word16 L_frame, /* i : length of frame to compute pitch */
868 Word16 old_lags[], /* i : history with old stored Cl lags */
869 Word16 ol_gain_flg[], /* i : OL gain flag */
870 Word16 idx, /* i : index */
871 Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */
872 Flag *pOverflow /* o : overflow flag */
873 )
874 {
875 Word16 i;
876 Word16 max1;
877 Word16 p_max1;
878 Word32 t0;
879 #ifndef VAD2
880 Word16 corr_hp_max;
881 #endif
882 Word32 corr[PIT_MAX+1], *corr_ptr;
883
884 /* Scaled signal */
885 Word16 scaled_signal[PIT_MAX + L_FRAME];
886 Word16 *scal_sig;
887
888 scal_sig = &scaled_signal[pit_max];
889
890 t0 = 0L;
891 for (i = -pit_max; i < L_frame; i++)
892 {
893 t0 = L_mac(t0, signal[i], signal[i], pOverflow);
894 }
895 /*--------------------------------------------------------*
896 * Scaling of input signal. *
897 * *
898 * if Overflow -> scal_sig[i] = signal[i]>>2 *
899 * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 *
900 * else -> scal_sig[i] = signal[i] *
901 *--------------------------------------------------------*/
902
903 /*--------------------------------------------------------*
904 * Verification for risk of overflow. *
905 *--------------------------------------------------------*/
906
907 /* Test for overflow */
908 if (L_sub(t0, MAX_32, pOverflow) == 0L)
909 {
910 for (i = -pit_max; i < L_frame; i++)
911 {
912 scal_sig[i] = shr(signal[i], 3, pOverflow);
913 }
914 }
915 else if (L_sub(t0, (Word32) 1048576L, pOverflow) < (Word32) 0)
916 {
917 for (i = -pit_max; i < L_frame; i++)
918 {
919 scal_sig[i] = shl(signal[i], 3, pOverflow);
920 }
921 }
922 else
923 {
924 for (i = -pit_max; i < L_frame; i++)
925 {
926 scal_sig[i] = signal[i];
927 }
928 }
929
930 /* calculate all coreelations of scal_sig, from pit_min to pit_max */
931 corr_ptr = &corr[pit_max];
932 comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr);
933
934 p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
935 st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
936 dtx, pOverflow);
937
938 if (ol_gain_flg[idx] > 0)
939 {
940 /* Calculate 5-point median of previous lags */
941 for (i = 4; i > 0; i--) /* Shift buffer */
942 {
943 old_lags[i] = old_lags[i-1];
944 }
945 old_lags[0] = p_max1;
946 st->old_T0_med = gmed_n(old_lags, 5);
947 st->ada_w = 32767; /* Q15 = 1.0 */
948 }
949 else
950 {
951 st->old_T0_med = p_max1;
952 /* = ada_w = ada_w * 0.9 */
953 st->ada_w = mult(st->ada_w, 29491, pOverflow);
954 }
955
956 if (sub(st->ada_w, 9830, pOverflow) < 0) /* ada_w - 0.3 */
957 {
958 st->wght_flg = 0;
959 }
960 else
961 {
962 st->wght_flg = 1;
963 }
964
965 #ifndef VAD2
966 if (dtx)
967 { /* no test() call since this if is only in simulation env */
968 if (sub(idx, 1, pOverflow) == 0)
969 {
970 /* calculate max high-passed filtered correlation of all lags */
971 hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, pOverflow);
972
973 /* update complex background detector */
974 vad_complex_detection_update(vadSt, corr_hp_max);
975 }
976 }
977 #endif
978
979 return (p_max1);
980 }
981
982 /*----------------------------------------------------------------------------
983 ; End Function: Pitch_ol_wgh
984 ----------------------------------------------------------------------------*/
985
986
987
988
989
990