1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11/****************************************************************** 12 13 iLBC Speech Coder ANSI-C Source Code 14 15 WebRtcIlbcfix_XcorrCoef.c 16 17******************************************************************/ 18 19#include "defines.h" 20 21/*----------------------------------------------------------------* 22 * cross correlation which finds the optimal lag for the 23 * crossCorr*crossCorr/(energy) criteria 24 *---------------------------------------------------------------*/ 25 26int WebRtcIlbcfix_XcorrCoef( 27 int16_t *target, /* (i) first array */ 28 int16_t *regressor, /* (i) second array */ 29 int16_t subl, /* (i) dimension arrays */ 30 int16_t searchLen, /* (i) the search lenght */ 31 int16_t offset, /* (i) samples offset between arrays */ 32 int16_t step /* (i) +1 or -1 */ 33 ){ 34 int k; 35 int16_t maxlag; 36 int16_t pos; 37 int16_t max; 38 int16_t crossCorrScale, Energyscale; 39 int16_t crossCorrSqMod, crossCorrSqMod_Max; 40 int32_t crossCorr, Energy; 41 int16_t crossCorrmod, EnergyMod, EnergyMod_Max; 42 int16_t *tp, *rp; 43 int16_t *rp_beg, *rp_end; 44 int16_t totscale, totscale_max; 45 int16_t scalediff; 46 int32_t newCrit, maxCrit; 47 int shifts; 48 49 /* Initializations, to make sure that the first one is selected */ 50 crossCorrSqMod_Max=0; 51 EnergyMod_Max=WEBRTC_SPL_WORD16_MAX; 52 totscale_max=-500; 53 maxlag=0; 54 pos=0; 55 56 /* Find scale value and start position */ 57 if (step==1) { 58 max=WebRtcSpl_MaxAbsValueW16(regressor, (int16_t)(subl+searchLen-1)); 59 rp_beg = regressor; 60 rp_end = ®ressor[subl]; 61 } else { /* step==-1 */ 62 max=WebRtcSpl_MaxAbsValueW16(®ressor[-searchLen], (int16_t)(subl+searchLen-1)); 63 rp_beg = ®ressor[-1]; 64 rp_end = ®ressor[subl-1]; 65 } 66 67 /* Introduce a scale factor on the Energy in int32_t in 68 order to make sure that the calculation does not 69 overflow */ 70 71 if (max>5000) { 72 shifts=2; 73 } else { 74 shifts=0; 75 } 76 77 /* Calculate the first energy, then do a +/- to get the other energies */ 78 Energy=WebRtcSpl_DotProductWithScale(regressor, regressor, subl, shifts); 79 80 for (k=0;k<searchLen;k++) { 81 tp = target; 82 rp = ®ressor[pos]; 83 84 crossCorr=WebRtcSpl_DotProductWithScale(tp, rp, subl, shifts); 85 86 if ((Energy>0)&&(crossCorr>0)) { 87 88 /* Put cross correlation and energy on 16 bit word */ 89 crossCorrScale=(int16_t)WebRtcSpl_NormW32(crossCorr)-16; 90 crossCorrmod=(int16_t)WEBRTC_SPL_SHIFT_W32(crossCorr, crossCorrScale); 91 Energyscale=(int16_t)WebRtcSpl_NormW32(Energy)-16; 92 EnergyMod=(int16_t)WEBRTC_SPL_SHIFT_W32(Energy, Energyscale); 93 94 /* Square cross correlation and store upper int16_t */ 95 crossCorrSqMod=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(crossCorrmod, crossCorrmod, 16); 96 97 /* Calculate the total number of (dynamic) right shifts that have 98 been performed on (crossCorr*crossCorr)/energy 99 */ 100 totscale=Energyscale-(crossCorrScale<<1); 101 102 /* Calculate the shift difference in order to be able to compare the two 103 (crossCorr*crossCorr)/energy in the same domain 104 */ 105 scalediff=totscale-totscale_max; 106 scalediff=WEBRTC_SPL_MIN(scalediff,31); 107 scalediff=WEBRTC_SPL_MAX(scalediff,-31); 108 109 /* Compute the cross multiplication between the old best criteria 110 and the new one to be able to compare them without using a 111 division */ 112 113 if (scalediff<0) { 114 newCrit = ((int32_t)crossCorrSqMod*EnergyMod_Max)>>(-scalediff); 115 maxCrit = ((int32_t)crossCorrSqMod_Max*EnergyMod); 116 } else { 117 newCrit = ((int32_t)crossCorrSqMod*EnergyMod_Max); 118 maxCrit = ((int32_t)crossCorrSqMod_Max*EnergyMod)>>scalediff; 119 } 120 121 /* Store the new lag value if the new criteria is larger 122 than previous largest criteria */ 123 124 if (newCrit > maxCrit) { 125 crossCorrSqMod_Max = crossCorrSqMod; 126 EnergyMod_Max = EnergyMod; 127 totscale_max = totscale; 128 maxlag = k; 129 } 130 } 131 pos+=step; 132 133 /* Do a +/- to get the next energy */ 134 Energy += step*(WEBRTC_SPL_RSHIFT_W32( 135 ((int32_t)(*rp_end)*(*rp_end)) - ((int32_t)(*rp_beg)*(*rp_beg)), 136 shifts)); 137 rp_beg+=step; 138 rp_end+=step; 139 } 140 141 return(maxlag+offset); 142} 143