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_Refiner.c 16 17 ******************************************************************/ 18 19 #include "defines.h" 20 #include "constants.h" 21 #include "enh_upsample.h" 22 #include "my_corr.h" 23 24 /*----------------------------------------------------------------* 25 * find segment starting near idata+estSegPos that has highest 26 * correlation with idata+centerStartPos through 27 * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a 28 * resolution of ENH_UPSO times the original of the original 29 * sampling rate 30 *---------------------------------------------------------------*/ 31 32 void WebRtcIlbcfix_Refiner( 33 int16_t *updStartPos, /* (o) updated start point (Q-2) */ 34 int16_t *idata, /* (i) original data buffer */ 35 int16_t idatal, /* (i) dimension of idata */ 36 int16_t centerStartPos, /* (i) beginning center segment */ 37 int16_t estSegPos, /* (i) estimated beginning other segment (Q-2) */ 38 int16_t *surround, /* (i/o) The contribution from this sequence 39 summed with earlier contributions */ 40 int16_t gain /* (i) Gain to use for this sequence */ 41 ){ 42 int16_t estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim; 43 int16_t tloc,tloc2,i,st,en,fraction; 44 45 int32_t maxtemp, scalefact; 46 int16_t *filtStatePtr, *polyPtr; 47 /* Stack based */ 48 int16_t filt[7]; 49 int32_t corrVecUps[ENH_CORRDIM*ENH_UPS0]; 50 int32_t corrVecTemp[ENH_CORRDIM]; 51 int16_t vect[ENH_VECTL]; 52 int16_t corrVec[ENH_CORRDIM]; 53 54 /* defining array bounds */ 55 56 estSegPosRounded=WEBRTC_SPL_RSHIFT_W16((estSegPos - 2),2); 57 58 searchSegStartPos=estSegPosRounded-ENH_SLOP; 59 60 if (searchSegStartPos<0) { 61 searchSegStartPos=0; 62 } 63 searchSegEndPos=estSegPosRounded+ENH_SLOP; 64 65 if(searchSegEndPos+ENH_BLOCKL >= idatal) { 66 searchSegEndPos=idatal-ENH_BLOCKL-1; 67 } 68 corrdim=searchSegEndPos-searchSegStartPos+1; 69 70 /* compute upsampled correlation and find 71 location of max */ 72 73 WebRtcIlbcfix_MyCorr(corrVecTemp,idata+searchSegStartPos, 74 (int16_t)(corrdim+ENH_BLOCKL-1),idata+centerStartPos,ENH_BLOCKL); 75 76 /* Calculate the rescaling factor for the correlation in order to 77 put the correlation in a int16_t vector instead */ 78 maxtemp=WebRtcSpl_MaxAbsValueW32(corrVecTemp, (int16_t)corrdim); 79 80 scalefact=WebRtcSpl_GetSizeInBits(maxtemp)-15; 81 82 if (scalefact>0) { 83 for (i=0;i<corrdim;i++) { 84 corrVec[i]=(int16_t)WEBRTC_SPL_RSHIFT_W32(corrVecTemp[i], scalefact); 85 } 86 } else { 87 for (i=0;i<corrdim;i++) { 88 corrVec[i]=(int16_t)corrVecTemp[i]; 89 } 90 } 91 /* In order to guarantee that all values are initialized */ 92 for (i=corrdim;i<ENH_CORRDIM;i++) { 93 corrVec[i]=0; 94 } 95 96 /* Upsample the correlation */ 97 WebRtcIlbcfix_EnhUpsample(corrVecUps,corrVec); 98 99 /* Find maximum */ 100 tloc=WebRtcSpl_MaxIndexW32(corrVecUps, (int16_t) (ENH_UPS0*corrdim)); 101 102 /* make vector can be upsampled without ever running outside 103 bounds */ 104 *updStartPos = (int16_t)WEBRTC_SPL_MUL_16_16(searchSegStartPos,4) + tloc + 4; 105 106 tloc2 = WEBRTC_SPL_RSHIFT_W16((tloc+3), 2); 107 108 st=searchSegStartPos+tloc2-ENH_FL0; 109 110 /* initialize the vector to be filtered, stuff with zeros 111 when data is outside idata buffer */ 112 if(st<0){ 113 WebRtcSpl_MemSetW16(vect, 0, (int16_t)(-st)); 114 WEBRTC_SPL_MEMCPY_W16(&vect[-st], idata, (ENH_VECTL+st)); 115 } 116 else{ 117 en=st+ENH_VECTL; 118 119 if(en>idatal){ 120 WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], 121 (ENH_VECTL-(en-idatal))); 122 WebRtcSpl_MemSetW16(&vect[ENH_VECTL-(en-idatal)], 0, 123 (int16_t)(en-idatal)); 124 } 125 else { 126 WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], ENH_VECTL); 127 } 128 } 129 /* Calculate which of the 4 fractions to use */ 130 fraction=(int16_t)WEBRTC_SPL_MUL_16_16(tloc2,ENH_UPS0)-tloc; 131 132 /* compute the segment (this is actually a convolution) */ 133 134 filtStatePtr = filt + 6; 135 polyPtr = (int16_t*)WebRtcIlbcfix_kEnhPolyPhaser[fraction]; 136 for (i=0;i<7;i++) { 137 *filtStatePtr-- = *polyPtr++; 138 } 139 140 WebRtcSpl_FilterMAFastQ12( 141 &vect[6], vect, filt, 142 ENH_FLO_MULT2_PLUS1, ENH_BLOCKL); 143 144 /* Add the contribution from this vector (scaled with gain) to the total surround vector */ 145 WebRtcSpl_AddAffineVectorToVector( 146 surround, vect, gain, 147 (int32_t)32768, 16, ENH_BLOCKL); 148 149 return; 150 } 151