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