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