autocorr.c revision 956c553ab0ce72f8074ad0fda2ffd66a0305700c
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