Home | History | Annotate | Download | only in src
      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