1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*       File: cor_h_x.c                                                *
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*      Description:Compute correlation between target "x[]" and "h[]"  *
215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*                  Designed for codebook search (24 pulses, 4 tracks,  *
225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*                  4 pulses per track, 16 positions in each track) to  *
235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen*                  avoid saturation.                                   *
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define L_SUBFR   64
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NB_TRACK  4
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define STEP      4
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_x(
365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 h[],                           /* (i) Q12 : impulse response of weighted synthesis filter */
375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 x[],                           /* (i) Q0  : target vector                                 */
385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        Word16 dn[]                           /* (o) <12bit : correlation between target and h[]         */
395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        )
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 i, j;
425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 L_tmp, y32[L_SUBFR], L_tot;
435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word16 *p1, *p2;
445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 *p3;
455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    Word32 L_max, L_max1, L_max2, L_max3;
465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* first keep the result on 32 bits and find absolute maximum */
475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tot  = 1;
485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_max  = 0;
495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_max1 = 0;
505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_max2 = 0;
515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_max3 = 0;
525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR; i += STEP)
535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 1;                                    /* 1 -> to avoid null dn[] */
555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p1 = &x[i];
565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p2 = &h[0];
575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (j = i; j < L_SUBFR; j++)
58a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        y32[i] = L_tmp;
61a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(L_tmp > L_max)
635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_max = L_tmp;
655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 1L;
685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p1 = &x[i+1];
695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p2 = &h[0];
705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (j = i+1; j < L_SUBFR; j++)
71a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        y32[i+1] = L_tmp;
74a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(L_tmp > L_max1)
765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_max1 = L_tmp;
785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 1;
815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p1 = &x[i+2];
825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p2 = &h[0];
835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (j = i+2; j < L_SUBFR; j++)
84a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        y32[i+2] = L_tmp;
87a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(L_tmp > L_max2)
895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_max2 = L_tmp;
915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        L_tmp = 1;
945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p1 = &x[i+3];
955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        p2 = &h[0];
965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        for (j = i+3; j < L_SUBFR; j++)
97a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        y32[i+3] = L_tmp;
100a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
1015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        if(L_tmp > L_max3)
1025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        {
1035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen            L_max3 = L_tmp;
1045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        }
1055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
1065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* tot += 3*max / 8 */
107a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen    if (L_max > INT_MAX - L_max1 ||
108a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_max + L_max1 > INT_MAX - L_max2 ||
109a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen            L_max + L_max1 + L_max2 > INT_MAX - L_max3) {
110a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_max = INT_MAX >> 2;
111a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen    } else {
112a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen        L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);
113a87228e3e3f42d3676ced0d38ad9913d7bef9de6Marco Nelissen    }
1145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tot = vo_L_add(L_tot, L_max);       /* +max/4 */
1155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    L_tot = vo_L_add(L_tot, (L_max >> 1));  /* +max/8 */
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* Find the number of right shifts to do on y32[] so that    */
1185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    /* 6.0 x sumation of max of dn[] in each track not saturate. */
1195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    j = norm_l(L_tot) - 4;             /* 4 -> 16 x tot */
1205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p1 = dn;
1215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    p3 = y32;
1225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    for (i = 0; i < L_SUBFR; i+=4)
1235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    {
1245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *p1++ = vo_round(L_shl(*p3++, j));
1255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *p1++ = vo_round(L_shl(*p3++, j));
1265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *p1++ = vo_round(L_shl(*p3++, j));
1275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen        *p1++ = vo_round(L_shl(*p3++, j));
1285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    }
1295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen    return;
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
134