| /* |
| ** 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; |
| } |
| |
| |
| |