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
33void 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