1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 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 express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 18 /*********************************************************************** 19 * File: autocorr.c * 20 * * 21 * Description:Compute autocorrelations of signal with windowing * 22 * * 23 ************************************************************************/ 24 25 #include "typedef.h" 26 #include "basic_op.h" 27 #include "oper_32b.h" 28 #include "acelp.h" 29 #include "ham_wind.tab" 30 31 #define UNUSED(x) (void)(x) 32 33 void Autocorr( 34 Word16 x[], /* (i) : Input signal */ 35 Word16 m, /* (i) : LPC order */ 36 Word16 r_h[], /* (o) Q15: Autocorrelations (msb) */ 37 Word16 r_l[] /* (o) : Autocorrelations (lsb) */ 38 ) 39 { 40 Word32 i, norm, shift; 41 Word16 y[L_WINDOW]; 42 Word32 L_sum, L_sum1, L_tmp, F_LEN; 43 Word16 *p1,*p2,*p3; 44 const Word16 *p4; 45 UNUSED(m); 46 47 /* Windowing of signal */ 48 p1 = x; 49 p4 = vo_window; 50 p3 = y; 51 52 for (i = 0; i < L_WINDOW; i+=4) 53 { 54 *p3++ = vo_mult_r((*p1++), (*p4++)); 55 *p3++ = vo_mult_r((*p1++), (*p4++)); 56 *p3++ = vo_mult_r((*p1++), (*p4++)); 57 *p3++ = vo_mult_r((*p1++), (*p4++)); 58 } 59 60 /* calculate energy of signal */ 61 L_sum = vo_L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */ 62 for (i = 0; i < L_WINDOW; i++) 63 { 64 L_tmp = vo_L_mult(y[i], y[i]); 65 L_tmp = (L_tmp >> 8); 66 L_sum += L_tmp; 67 } 68 69 /* scale signal to avoid overflow in autocorrelation */ 70 norm = norm_l(L_sum); 71 shift = 4 - (norm >> 1); 72 if(shift > 0) 73 { 74 p1 = y; 75 for (i = 0; i < L_WINDOW; i+=4) 76 { 77 *p1 = vo_shr_r(*p1, shift); 78 p1++; 79 *p1 = vo_shr_r(*p1, shift); 80 p1++; 81 *p1 = vo_shr_r(*p1, shift); 82 p1++; 83 *p1 = vo_shr_r(*p1, shift); 84 p1++; 85 } 86 } 87 88 /* Compute and normalize r[0] */ 89 L_sum = 1; 90 for (i = 0; i < L_WINDOW; i+=4) 91 { 92 L_sum += vo_L_mult(y[i], y[i]); 93 L_sum += vo_L_mult(y[i+1], y[i+1]); 94 L_sum += vo_L_mult(y[i+2], y[i+2]); 95 L_sum += vo_L_mult(y[i+3], y[i+3]); 96 } 97 98 norm = norm_l(L_sum); 99 L_sum = (L_sum << norm); 100 101 r_h[0] = L_sum >> 16; 102 r_l[0] = (L_sum & 0xffff)>>1; 103 104 /* Compute r[1] to r[m] */ 105 for (i = 1; i <= 8; i++) 106 { 107 L_sum1 = 0; 108 L_sum = 0; 109 F_LEN = (Word32)(L_WINDOW - 2*i); 110 p1 = y; 111 p2 = y + (2*i)-1; 112 do{ 113 L_sum1 += *p1 * *p2++; 114 L_sum += *p1++ * *p2; 115 }while(--F_LEN!=0); 116 117 L_sum1 += *p1 * *p2++; 118 119 L_sum1 = L_sum1<<norm; 120 L_sum = L_sum<<norm; 121 122 r_h[(2*i)-1] = L_sum1 >> 15; 123 r_l[(2*i)-1] = L_sum1 & 0x00007fff; 124 r_h[(2*i)] = L_sum >> 15; 125 r_l[(2*i)] = L_sum & 0x00007fff; 126 } 127 return; 128 } 129 130 131 132