1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: p_ol_wgh.cpp
35 Functions: p_ol_wgh_init
41 ------------------------------------------------------------------------------
44 The modules in this file compute the open loop pitch lag with weighting.
45 ------------------------------------------------------------------------------
49 /*----------------------------------------------------------------------------
51 ----------------------------------------------------------------------------*/
63 /*----------------------------------------------------------------------------
65 ; Define module specific macros here
66 ----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------
71 ; Include all pre-processor statements here. Include conditional
72 ; compile variables also.
73 ----------------------------------------------------------------------------*/
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; Function Prototype declaration
78 ----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; Variable declaration - defined here and used outside this module
83 ----------------------------------------------------------------------------*/
87 ------------------------------------------------------------------------------
88 FUNCTION NAME: p_ol_wgh_init
89 ------------------------------------------------------------------------------
90 INPUT AND OUTPUT DEFINITIONS
93 state = pointer to a pointer of structure type pitchOLWghtState
99 0 if the memory allocation is a success
100 -1 if the memory allocation fails
102 Global Variables Used:
105 Local Variables Needed:
108 ------------------------------------------------------------------------------
111 This function allocates state memory and initializes state memory
113 ------------------------------------------------------------------------------
118 ------------------------------------------------------------------------------
121 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
123 ------------------------------------------------------------------------------
126 int p_ol_wgh_init (pitchOLWghtState **state)
130 if (state == (pitchOLWghtState **) NULL){
131 // fprintf(stderr, "p_ol_wgh_init: invalid parameter\n");
137 if ((s= (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL){
138 // fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n");
149 ------------------------------------------------------------------------------
151 [State any special notes, constraints or cautions for users of this function]
153 ------------------------------------------------------------------------------
156 Word16 p_ol_wgh_init(pitchOLWghtState **state)
160 if (state == (pitchOLWghtState **) NULL)
162 /* fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); */
167 /* allocate memory */
168 if ((s = (pitchOLWghtState *) oscl_malloc(sizeof(pitchOLWghtState))) == NULL)
170 /* fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); */
181 /*----------------------------------------------------------------------------
182 ; End Function: p_ol_wgh_init
183 ----------------------------------------------------------------------------*/
186 ------------------------------------------------------------------------------
187 FUNCTION NAME: p_ol_wgh_reset
188 ------------------------------------------------------------------------------
189 INPUT AND OUTPUT DEFINITIONS
192 st = pointer to structure type pitchOLWghtState
198 0 if the memory initialization is a success
199 -1 if the memory initialization fails
201 Global Variables Used:
204 Local Variables Needed:
207 ------------------------------------------------------------------------------
210 This function initializes state memory to zero
212 ------------------------------------------------------------------------------
217 ------------------------------------------------------------------------------
220 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
222 ------------------------------------------------------------------------------
225 int p_ol_wgh_reset (pitchOLWghtState *st)
227 if (st == (pitchOLWghtState *) NULL){
228 // fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n");
232 // Reset pitch search states
240 ------------------------------------------------------------------------------
242 [State any special notes, constraints or cautions for users of this function]
244 ------------------------------------------------------------------------------
247 Word16 p_ol_wgh_reset(pitchOLWghtState *st)
249 if (st == (pitchOLWghtState *) NULL)
251 /* fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); */
255 /* Reset pitch search states */
263 /*----------------------------------------------------------------------------
264 ; End Function: p_ol_wgh_reset
265 ----------------------------------------------------------------------------*/
268 ------------------------------------------------------------------------------
269 FUNCTION NAME: p_ol_wgh_exit
270 ------------------------------------------------------------------------------
271 INPUT AND OUTPUT DEFINITIONS
274 st = pointer to a pointer of structure type pitchOLWghtState
280 0 if the memory initialization is a success
281 -1 if the memory initialization fails
283 Global Variables Used:
286 Local Variables Needed:
289 ------------------------------------------------------------------------------
292 This function frees the memory used for state memory
294 ------------------------------------------------------------------------------
299 ------------------------------------------------------------------------------
302 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
304 ------------------------------------------------------------------------------
307 void p_ol_wgh_exit (pitchOLWghtState **state)
309 if (state == NULL || *state == NULL)
319 ------------------------------------------------------------------------------
321 [State any special notes, constraints or cautions for users of this function]
323 ------------------------------------------------------------------------------
326 void p_ol_wgh_exit(pitchOLWghtState **state)
328 if (state == NULL || *state == NULL)
331 /* deallocate memory */
339 /*----------------------------------------------------------------------------
340 ; End Function: p_ol_wgh_exit
341 ----------------------------------------------------------------------------*/
343 ------------------------------------------------------------------------------
344 FUNCTION NAME: Lag_max
345 ------------------------------------------------------------------------------
346 INPUT AND OUTPUT DEFINITIONS
349 corr = pointer to buffer of correlation values (Word32)
350 scal_sig = pointer to buffer of scaled signal values (Word16)
351 scal_fac = scaled signal factor (Word16)
352 scal_flag = EFR compatible scaling flag (Word16)
353 L_frame = length of frame to compute pitch (Word16)
354 lag_max = maximum lag (Word16)
355 lag_min = minimum lag (Word16)
356 cor_max = pointer to the normalized correlation of selected lag (Word16)
357 rmax = pointer to max(<s[i]*s[j]>), (Word32)
358 r0 = pointer to the residual energy (Word32)
359 dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
360 pOverflow = Pointer to overflow (Flag)
363 cor_max contains the newly calculated normalized correlation of the
365 rmax contains the newly calculated max(<s[i]*s[j]>)
366 r0 contains the newly calculated residual energy
367 pOverflow -> 1 if the math functions called by this routine saturate.
370 p_max = lag of the max correlation found (Word16)
372 Global Variables Used:
375 Local Variables Needed:
378 ------------------------------------------------------------------------------
381 This function finds the lag that has maximum correlation of scal_sig[] in a
383 The correlation is given by
384 cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max
385 The functions outputs the maximum correlation after normalization and the
388 ------------------------------------------------------------------------------
393 ------------------------------------------------------------------------------
396 p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
398 ------------------------------------------------------------------------------
401 static Word16 Lag_max ( // o : lag found
402 vadState *vadSt, // i/o : VAD state struct
403 Word32 corr[], // i : correlation vector.
404 Word16 scal_sig[], // i : scaled signal.
405 Word16 L_frame, // i : length of frame to compute pitch
406 Word16 lag_max, // i : maximum lag
407 Word16 lag_min, // i : minimum lag
408 Word16 old_lag, // i : old open-loop lag
409 Word16 *cor_max, // o : normalized correlation of selected lag
410 Word16 wght_flg, // i : is weighting function used
411 Word16 *gain_flg, // o : open-loop flag
412 Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0
420 const Word16 *ww, *we;
423 ww = &corrweight[250];
424 we = &corrweight[123 + lag_max - old_lag];
429 for (i = lag_max; i >= lag_min; i--)
433 // Weighting of the correlation function.
434 L_Extract (corr[-i], &t0_h, &t0_l);
435 t0 = Mpy_32_16 (t0_h, t0_l, *ww);
438 // Weight the neighbourhood of the old lag
439 L_Extract (t0, &t0_h, &t0_l);
440 t0 = Mpy_32_16 (t0_h, t0_l, *we);
444 if (L_sub (t0, max) >= 0)
452 p1 = &scal_sig[-p_max];
456 for (j = 0; j < L_frame; j++, p++, p1++)
458 t0 = L_mac (t0, *p, *p1);
459 t1 = L_mac (t1, *p1, *p1);
463 { // no test() call since this if is only in simulation env
465 vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0); // Save max correlation
466 vadSt->L_R0 = L_add(vadSt->L_R0, t1); // Save max energy
468 // update and detect tone
469 vad_tone_detection_update (vadSt, 0);
470 vad_tone_detection (vadSt, t0, t1);
474 // gain flag is set according to the open_loop gain
476 *gain_flg = pv_round(L_msu(t0, pv_round(t1), 13107));
483 ------------------------------------------------------------------------------
485 [State any special notes, constraints or cautions for users of this function]
487 ------------------------------------------------------------------------------
490 static Word16 Lag_max( /* o : lag found */
491 vadState *vadSt, /* i/o : VAD state struct */
492 Word32 corr[], /* i : correlation vector. */
493 Word16 scal_sig[], /* i : scaled signal. */
494 Word16 L_frame, /* i : length of frame to compute pitch */
495 Word16 lag_max, /* i : maximum lag */
496 Word16 lag_min, /* i : minimum lag */
497 Word16 old_lag, /* i : old open-loop lag */
498 Word16 *cor_max, /* o : normalized correlation of selected lag */
499 Word16 wght_flg, /* i : is weighting function used */
500 Word16 *gain_flg, /* o : open-loop flag */
501 Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */
502 Flag *pOverflow /* o : overflow flag */
519 ww = &corrweight[250];
520 we = &corrweight[123 + lag_max - old_lag];
525 for (i = lag_max; i >= lag_min; i--)
529 /* Weighting of the correlation function. */
530 L_Extract(corr[-i], &t0_h, &t0_l, pOverflow);
531 t0 = Mpy_32_16(t0_h, t0_l, *ww, pOverflow);
535 /* Weight the neighbourhood of the old lag. */
536 L_Extract(t0, &t0_h, &t0_l, pOverflow);
537 t0 = Mpy_32_16(t0_h, t0_l, *we, pOverflow);
541 /* if (L_sub (t0, max) >= 0) */
549 p1 = &scal_sig[-p_max];
553 for (j = 0; j < L_frame; j++, p++, p1++)
555 t0 = L_mac(t0, *p, *p1, pOverflow);
556 t1 = L_mac(t1, *p1, *p1, pOverflow);
560 { /* no test() call since this if is only in simulation env */
562 /* Save max correlation */
563 vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0, pOverflow);
564 /* Save max energy */
565 vadSt->L_R0 = L_add(vadSt->L_R0, t1, pOverflow);
567 /* update and detect tone */
568 vad_tone_detection_update(vadSt, 0, pOverflow);
569 vad_tone_detection(vadSt, t0, t1, pOverflow);
573 /* gain flag is set according to the open_loop gain */
574 /* is t2/t1 > 0.4 ? */
575 temp = pv_round(t1, pOverflow);
576 t1 = L_msu(t0, temp, 13107, pOverflow);
577 *gain_flg = pv_round(t1, pOverflow);
583 /*----------------------------------------------------------------------------
584 ; End Function: Lag_max
585 ----------------------------------------------------------------------------*/
588 ------------------------------------------------------------------------------
589 FUNCTION NAME: Pitch_ol_wgh
590 ------------------------------------------------------------------------------
591 INPUT AND OUTPUT DEFINITIONS
594 st = pointer to pitchOLWghtState structure
595 vadSt = pointer to a vadState structure
596 signal = pointer to buffer of signal used to compute the open loop
597 pitch where signal[-pit_max] to signal[-1] should be known
598 pit_min = 16 bit value specifies the minimum pitch lag
599 pit_max = 16 bit value specifies the maximum pitch lag
600 L_frame = 16 bit value specifies the length of frame to compute pitch
601 old_lags = pointer to history with old stored Cl lags (Word16)
602 ol_gain_flg = pointer to OL gain flag (Word16)
603 idx = 16 bit value specifies the frame index
604 dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0
605 pOverflow = pointer to Overflow indicator (Flag)
607 st = The pitchOLWghtState may be modified
608 vadSt = The vadSt state structure may be modified.
609 pOverflow -> 1 if the math functions invoked by this routine saturate.
612 p_max1 = 16 bit value representing the open loop pitch lag.
614 Global Variables Used:
617 Local Variables Needed:
620 ------------------------------------------------------------------------------
623 This function performs an open-loop pitch search with weighting
624 ------------------------------------------------------------------------------
629 ------------------------------------------------------------------------------
632 pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
634 ------------------------------------------------------------------------------
637 Word16 Pitch_ol_wgh ( // o : open loop pitch lag
638 pitchOLWghtState *st, // i/o : State struct
639 vadState *vadSt, // i/o : VAD state struct/
640 Word16 signal[], // i : signal used to compute the open loop pitch
641 // signal[-pit_max] to signal[-1] should be known
642 Word16 pit_min, // i : minimum pitch lag
643 Word16 pit_max, // i : maximum pitch lag
644 Word16 L_frame, // i : length of frame to compute pitch
645 Word16 old_lags[], // i : history with old stored Cl lags
646 Word16 ol_gain_flg[], // i : OL gain flag
647 Word16 idx, // i : index
648 Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0
658 Word32 corr[PIT_MAX+1], *corr_ptr;
661 Word16 scaled_signal[PIT_MAX + L_FRAME];
664 scal_sig = &scaled_signal[pit_max];
667 for (i = -pit_max; i < L_frame; i++)
669 t0 = L_mac (t0, signal[i], signal[i]);
672 // Scaling of input signal
674 // if Overflow -> scal_sig[i] = signal[i]>>2
675 // else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2
676 // else -> scal_sig[i] = signal[i]
679 // Verification for risk of overflow.
683 if (L_sub (t0, MAX_32) == 0L)
685 for (i = -pit_max; i < L_frame; i++)
687 scal_sig[i] = shr (signal[i], 3);
690 else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
692 for (i = -pit_max; i < L_frame; i++)
694 scal_sig[i] = shl (signal[i], 3);
699 for (i = -pit_max; i < L_frame; i++)
701 scal_sig[i] = signal[i];
705 // calculate all coreelations of scal_sig, from pit_min to pit_max
706 corr_ptr = &corr[pit_max];
707 comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
709 p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
710 st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
713 if (ol_gain_flg[idx] > 0)
715 // Calculate 5-point median of previous lag
716 for (i = 4; i > 0; i--) // Shift buffer
718 old_lags[i] = old_lags[i-1];
720 old_lags[0] = p_max1;
721 st->old_T0_med = gmed_n (old_lags, 5);
722 st->ada_w = 32767; // Q15 = 1.0
726 st->old_T0_med = p_max1;
727 st->ada_w = mult(st->ada_w, 29491); // = ada_w = ada_w * 0.9
730 if (sub(st->ada_w, 9830) < 0) // ada_w - 0.3
741 { // no test() call since this if is only in simulation env
742 if (sub(idx, 1) == 0)
744 // calculate max high-passed filtered correlation of all lags
745 hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
747 // update complex background detector
748 vad_complex_detection_update(vadSt, corr_hp_max);
756 ------------------------------------------------------------------------------
758 [State any special notes, constraints or cautions for users of this function]
760 ------------------------------------------------------------------------------
763 Word16 Pitch_ol_wgh( /* o : open loop pitch lag */
764 pitchOLWghtState *st, /* i/o : State struct */
765 vadState *vadSt, /* i/o : VAD state struct */
766 Word16 signal[], /* i : signal used to compute the open loop pitch */
767 /* signal[-pit_max] to signal[-1] should be known */
768 Word16 pit_min, /* i : minimum pitch lag */
769 Word16 pit_max, /* i : maximum pitch lag */
770 Word16 L_frame, /* i : length of frame to compute pitch */
771 Word16 old_lags[], /* i : history with old stored Cl lags */
772 Word16 ol_gain_flg[], /* i : OL gain flag */
773 Word16 idx, /* i : index */
774 Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */
775 Flag *pOverflow /* o : overflow flag */
785 Word32 corr[PIT_MAX+1], *corr_ptr;
788 Word16 scaled_signal[PIT_MAX + L_FRAME];
791 scal_sig = &scaled_signal[pit_max];
794 for (i = -pit_max; i < L_frame; i++)
796 t0 = L_mac(t0, signal[i], signal[i], pOverflow);
798 /*--------------------------------------------------------*
799 * Scaling of input signal. *
801 * if Overflow -> scal_sig[i] = signal[i]>>2 *
802 * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 *
803 * else -> scal_sig[i] = signal[i] *
804 *--------------------------------------------------------*/
806 /*--------------------------------------------------------*
807 * Verification for risk of overflow. *
808 *--------------------------------------------------------*/
810 /* Test for overflow */
811 if (L_sub(t0, MAX_32, pOverflow) == 0L)
813 for (i = -pit_max; i < L_frame; i++)
815 scal_sig[i] = shr(signal[i], 3, pOverflow);
818 else if (L_sub(t0, (Word32) 1048576L, pOverflow) < (Word32) 0)
820 for (i = -pit_max; i < L_frame; i++)
822 scal_sig[i] = shl(signal[i], 3, pOverflow);
827 for (i = -pit_max; i < L_frame; i++)
829 scal_sig[i] = signal[i];
833 /* calculate all coreelations of scal_sig, from pit_min to pit_max */
834 corr_ptr = &corr[pit_max];
835 comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr);
837 p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
838 st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
841 if (ol_gain_flg[idx] > 0)
843 /* Calculate 5-point median of previous lags */
844 for (i = 4; i > 0; i--) /* Shift buffer */
846 old_lags[i] = old_lags[i-1];
848 old_lags[0] = p_max1;
849 st->old_T0_med = gmed_n(old_lags, 5);
850 st->ada_w = 32767; /* Q15 = 1.0 */
854 st->old_T0_med = p_max1;
855 /* = ada_w = ada_w * 0.9 */
856 st->ada_w = (Word16)((Word32)(st->ada_w * 29491) >> 15);
859 if (sub(st->ada_w, 9830, pOverflow) < 0) /* ada_w - 0.3 */
870 { /* no test() call since this if is only in simulation env */
871 if (sub(idx, 1, pOverflow) == 0)
873 /* calculate max high-passed filtered correlation of all lags */
874 hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, pOverflow);
876 /* update complex background detector */
877 vad_complex_detection_update(vadSt, corr_hp_max);
885 /*----------------------------------------------------------------------------
886 ; End Function: Pitch_ol_wgh
887 ----------------------------------------------------------------------------*/