autocorr.c revision b676a05348e4c516fa8b57e33b10548e6142c3f8
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 31void Autocorr( 32 Word16 x[], /* (i) : Input signal */ 33 Word16 m, /* (i) : LPC order */ 34 Word16 r_h[], /* (o) Q15: Autocorrelations (msb) */ 35 Word16 r_l[] /* (o) : Autocorrelations (lsb) */ 36 ) 37{ 38 Word32 i, norm, shift; 39 Word16 y[L_WINDOW]; 40 Word32 L_sum, L_sum1, L_tmp, F_LEN; 41 Word16 *p1,*p2,*p3; 42 const Word16 *p4; 43 /* Windowing of signal */ 44 p1 = x; 45 p4 = vo_window; 46 p3 = y; 47 48 for (i = 0; i < L_WINDOW; i+=4) 49 { 50 *p3++ = vo_mult_r((*p1++), (*p4++)); 51 *p3++ = vo_mult_r((*p1++), (*p4++)); 52 *p3++ = vo_mult_r((*p1++), (*p4++)); 53 *p3++ = vo_mult_r((*p1++), (*p4++)); 54 } 55 56 /* calculate energy of signal */ 57 L_sum = vo_L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */ 58 for (i = 0; i < L_WINDOW; i++) 59 { 60 L_tmp = vo_L_mult(y[i], y[i]); 61 L_tmp = (L_tmp >> 8); 62 L_sum += L_tmp; 63 } 64 65 /* scale signal to avoid overflow in autocorrelation */ 66 norm = norm_l(L_sum); 67 shift = 4 - (norm >> 1); 68 if(shift > 0) 69 { 70 p1 = y; 71 for (i = 0; i < L_WINDOW; i+=4) 72 { 73 *p1 = vo_shr_r(*p1, shift); 74 p1++; 75 *p1 = vo_shr_r(*p1, shift); 76 p1++; 77 *p1 = vo_shr_r(*p1, shift); 78 p1++; 79 *p1 = vo_shr_r(*p1, shift); 80 p1++; 81 } 82 } 83 84 /* Compute and normalize r[0] */ 85 L_sum = 1; 86 for (i = 0; i < L_WINDOW; i+=4) 87 { 88 L_sum += vo_L_mult(y[i], y[i]); 89 L_sum += vo_L_mult(y[i+1], y[i+1]); 90 L_sum += vo_L_mult(y[i+2], y[i+2]); 91 L_sum += vo_L_mult(y[i+3], y[i+3]); 92 } 93 94 norm = norm_l(L_sum); 95 L_sum = (L_sum << norm); 96 97 r_h[0] = L_sum >> 16; 98 r_l[0] = (L_sum & 0xffff)>>1; 99 100 /* Compute r[1] to r[m] */ 101 for (i = 1; i <= 8; i++) 102 { 103 L_sum1 = 0; 104 L_sum = 0; 105 F_LEN = (Word32)(L_WINDOW - 2*i); 106 p1 = y; 107 p2 = y + (2*i)-1; 108 do{ 109 L_sum1 += *p1 * *p2++; 110 L_sum += *p1++ * *p2; 111 }while(--F_LEN!=0); 112 113 L_sum1 += *p1 * *p2++; 114 115 L_sum1 = L_sum1<<norm; 116 L_sum = L_sum<<norm; 117 118 r_h[(2*i)-1] = L_sum1 >> 15; 119 r_l[(2*i)-1] = L_sum1 & 0x00007fff; 120 r_h[(2*i)] = L_sum >> 15; 121 r_l[(2*i)] = L_sum & 0x00007fff; 122 } 123 return; 124} 125 126 127 128