blob: 3ea53f7a01d9a70bc07d61e94492a95136d7095b [file] [log] [blame]
/*
** Copyright 2003-2010, VisualOn, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/***********************************************************************
* File: autocorr.c *
* *
* Description:Compute autocorrelations of signal with windowing *
* *
************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "acelp.h"
#include "ham_wind.tab"
#define UNUSED(x) (void)(x)
void Autocorr(
Word16 x[], /* (i) : Input signal */
Word16 m, /* (i) : LPC order */
Word16 r_h[], /* (o) Q15: Autocorrelations (msb) */
Word16 r_l[] /* (o) : Autocorrelations (lsb) */
)
{
Word32 i, norm, shift;
Word16 y[L_WINDOW];
Word32 L_sum, L_sum1, L_tmp, F_LEN;
Word16 *p1,*p2,*p3;
const Word16 *p4;
UNUSED(m);
/* Windowing of signal */
p1 = x;
p4 = vo_window;
p3 = y;
for (i = 0; i < L_WINDOW; i+=4)
{
*p3++ = vo_mult_r((*p1++), (*p4++));
*p3++ = vo_mult_r((*p1++), (*p4++));
*p3++ = vo_mult_r((*p1++), (*p4++));
*p3++ = vo_mult_r((*p1++), (*p4++));
}
/* calculate energy of signal */
L_sum = vo_L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */
for (i = 0; i < L_WINDOW; i++)
{
L_tmp = vo_L_mult(y[i], y[i]);
L_tmp = (L_tmp >> 8);
L_sum += L_tmp;
}
/* scale signal to avoid overflow in autocorrelation */
norm = norm_l(L_sum);
shift = 4 - (norm >> 1);
if(shift > 0)
{
p1 = y;
for (i = 0; i < L_WINDOW; i+=4)
{
*p1 = vo_shr_r(*p1, shift);
p1++;
*p1 = vo_shr_r(*p1, shift);
p1++;
*p1 = vo_shr_r(*p1, shift);
p1++;
*p1 = vo_shr_r(*p1, shift);
p1++;
}
}
/* Compute and normalize r[0] */
L_sum = 1;
for (i = 0; i < L_WINDOW; i+=4)
{
L_sum += vo_L_mult(y[i], y[i]);
L_sum += vo_L_mult(y[i+1], y[i+1]);
L_sum += vo_L_mult(y[i+2], y[i+2]);
L_sum += vo_L_mult(y[i+3], y[i+3]);
}
norm = norm_l(L_sum);
L_sum = (L_sum << norm);
r_h[0] = L_sum >> 16;
r_l[0] = (L_sum & 0xffff)>>1;
/* Compute r[1] to r[m] */
for (i = 1; i <= 8; i++)
{
L_sum1 = 0;
L_sum = 0;
F_LEN = (Word32)(L_WINDOW - 2*i);
p1 = y;
p2 = y + (2*i)-1;
do{
L_sum1 += *p1 * *p2++;
L_sum += *p1++ * *p2;
}while(--F_LEN!=0);
L_sum1 += *p1 * *p2++;
L_sum1 = L_sum1<<norm;
L_sum = L_sum<<norm;
r_h[(2*i)-1] = L_sum1 >> 15;
r_l[(2*i)-1] = L_sum1 & 0x00007fff;
r_h[(2*i)] = L_sum >> 15;
r_l[(2*i)] = L_sum & 0x00007fff;
}
return;
}