diff options
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src/p_med_ol.c')
-rw-r--r-- | media/libstagefright/codecs/amrwbenc/src/p_med_ol.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c new file mode 100644 index 0000000..b8174b9 --- /dev/null +++ b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c @@ -0,0 +1,256 @@ +/* + ** 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: p_med_ol.c * +* * +* Description: Compute the open loop pitch lag * +* output: open loop pitch lag * +************************************************************************/ + +#include "typedef.h" +#include "basic_op.h" +#include "acelp.h" +#include "oper_32b.h" +#include "math_op.h" +#include "p_med_ol.tab" + +Word16 Pitch_med_ol( + Word16 wsp[], /* i: signal used to compute the open loop pitch*/ + /* wsp[-pit_max] to wsp[-1] should be known */ + Coder_State *st, /* i/o: codec global structure */ + Word16 L_frame /* i: length of frame to compute pitch */ + ) +{ + Word16 Tm; + Word16 hi, lo; + Word16 *ww, *we, *hp_wsp; + Word16 exp_R0, exp_R1, exp_R2; + Word32 i, j, max, R0, R1, R2; + Word16 *p1, *p2; + Word16 L_min = 17; /* minimum pitch lag: PIT_MIN / OPL_DECIM */ + Word16 L_max = 115; /* maximum pitch lag: PIT_MAX / OPL_DECIM */ + Word16 L_0 = st->old_T0_med; /* old open-loop pitch */ + Word16 *gain = &(st->ol_gain); /* normalize correlation of hp_wsp for the lag */ + Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/ + Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */ + Word16 wght_flg = st->ol_wght_flg; /* is weighting function used */ + + ww = &corrweight[198]; + we = &corrweight[98 + L_max - L_0]; + + max = MIN_32; + Tm = 0; + for (i = L_max; i > L_min; i--) + { + /* Compute the correlation */ + R0 = 0; + p1 = wsp; + p2 = &wsp[-i]; + for (j = 0; j < L_frame; j+=4) + { + R0 += vo_L_mult((*p1++), (*p2++)); + R0 += vo_L_mult((*p1++), (*p2++)); + R0 += vo_L_mult((*p1++), (*p2++)); + R0 += vo_L_mult((*p1++), (*p2++)); + } + /* Weighting of the correlation function. */ + hi = R0>>16; + lo = (R0 & 0xffff)>>1; + + R0 = Mpy_32_16(hi, lo, *ww); + ww--; + + if ((L_0 > 0) && (wght_flg > 0)) + { + /* Weight the neighbourhood of the old lag. */ + hi = R0>>16; + lo = (R0 & 0xffff)>>1; + R0 = Mpy_32_16(hi, lo, *we); + we--; + } + if(R0 >= max) + { + max = R0; + Tm = i; + } + } + + /* Hypass the wsp[] vector */ + hp_wsp = old_hp_wsp + L_max; + Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem); + + /* Compute normalize correlation at delay Tm */ + R0 = 0; + R1 = 0; + R2 = 0; + p1 = hp_wsp; + p2 = hp_wsp - Tm; + for (j = 0; j < L_frame; j+=4) + { + R2 += vo_mult32(*p1, *p1); + R1 += vo_mult32(*p2, *p2); + R0 += vo_mult32(*p1++, *p2++); + R2 += vo_mult32(*p1, *p1); + R1 += vo_mult32(*p2, *p2); + R0 += vo_mult32(*p1++, *p2++); + R2 += vo_mult32(*p1, *p1); + R1 += vo_mult32(*p2, *p2); + R0 += vo_mult32(*p1++, *p2++); + R2 += vo_mult32(*p1, *p1); + R1 += vo_mult32(*p2, *p2); + R0 += vo_mult32(*p1++, *p2++); + } + R0 = R0 <<1; + R1 = (R1 <<1) + 1L; + R2 = (R2 <<1) + 1L; + /* gain = R0/ sqrt(R1*R2) */ + + exp_R0 = norm_l(R0); + R0 = (R0 << exp_R0); + + exp_R1 = norm_l(R1); + R1 = (R1 << exp_R1); + + exp_R2 = norm_l(R2); + R2 = (R2 << exp_R2); + + + R1 = vo_L_mult(vo_round(R1), vo_round(R2)); + + i = norm_l(R1); + R1 = (R1 << i); + + exp_R1 += exp_R2; + exp_R1 += i; + exp_R1 = 62 - exp_R1; + + Isqrt_n(&R1, &exp_R1); + + R0 = vo_L_mult(voround(R0), voround(R1)); + exp_R0 = 31 - exp_R0; + exp_R0 += exp_R1; + + *gain = vo_round(L_shl(R0, exp_R0)); + + /* Shitf hp_wsp[] for next frame */ + + for (i = 0; i < L_max; i++) + { + old_hp_wsp[i] = old_hp_wsp[i + L_frame]; + } + + return (Tm); +} + +/************************************************************************ +* Function: median5 * +* * +* Returns the median of the set {X[-2], X[-1],..., X[2]}, * +* whose elements are 16-bit integers. * +* * +* Input: * +* X[-2:2] 16-bit integers. * +* * +* Return: * +* The median of {X[-2], X[-1],..., X[2]}. * +************************************************************************/ + +Word16 median5(Word16 x[]) +{ + Word16 x1, x2, x3, x4, x5; + Word16 tmp; + + x1 = x[-2]; + x2 = x[-1]; + x3 = x[0]; + x4 = x[1]; + x5 = x[2]; + + if (x2 < x1) + { + tmp = x1; + x1 = x2; + x2 = tmp; + } + if (x3 < x1) + { + tmp = x1; + x1 = x3; + x3 = tmp; + } + if (x4 < x1) + { + tmp = x1; + x1 = x4; + x4 = tmp; + } + if (x5 < x1) + { + x5 = x1; + } + if (x3 < x2) + { + tmp = x2; + x2 = x3; + x3 = tmp; + } + if (x4 < x2) + { + tmp = x2; + x2 = x4; + x4 = tmp; + } + if (x5 < x2) + { + x5 = x2; + } + if (x4 < x3) + { + x3 = x4; + } + if (x5 < x3) + { + x3 = x5; + } + return (x3); +} + + +Word16 Med_olag( /* output : median of 5 previous open-loop lags */ + Word16 prev_ol_lag, /* input : previous open-loop lag */ + Word16 old_ol_lag[5] + ) +{ + Word32 i; + + /* Use median of 5 previous open-loop lags as old lag */ + + for (i = 4; i > 0; i--) + { + old_ol_lag[i] = old_ol_lag[i - 1]; + } + + old_ol_lag[0] = prev_ol_lag; + + i = median5(&old_ol_lag[2]); + + return i; + +} + + + |