PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/jni/bx16_fixedp/bv16/coarptch.c

https://github.com/sortir/sipdroid
C | 604 lines | 439 code | 106 blank | 59 comment | 96 complexity | 6ba558f74f689273c239a02eec63e823 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
  1. /*****************************************************************************/
  2. /* BroadVoice(R)16 (BV16) Fixed-Point ANSI-C Source Code */
  3. /* Revision Date: November 13, 2009 */
  4. /* Version 1.1 */
  5. /*****************************************************************************/
  6. /*****************************************************************************/
  7. /* Copyright 2000-2009 Broadcom Corporation */
  8. /* */
  9. /* This software is provided under the GNU Lesser General Public License, */
  10. /* version 2.1, as published by the Free Software Foundation ("LGPL"). */
  11. /* This program is distributed in the hope that it will be useful, but */
  12. /* WITHOUT ANY SUPPORT OR WARRANTY; without even the implied warranty of */
  13. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LGPL for */
  14. /* more details. A copy of the LGPL is available at */
  15. /* http://www.broadcom.com/licenses/LGPLv2.1.php, */
  16. /* or by writing to the Free Software Foundation, Inc., */
  17. /* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  18. /*****************************************************************************/
  19. /*****************************************************************************
  20. coarptch.c: Coarse pitch search
  21. $Log$
  22. ******************************************************************************/
  23. #include "typedef.h"
  24. #include "bvcommon.h"
  25. #include "bv16cnst.h"
  26. #include "bv16strct.h"
  27. #include "bv16externs.h"
  28. #include "basop32.h"
  29. Word16 coarsepitch(
  30. Word16 *xw, /* (i) (normalized) weighted signal */
  31. struct BV16_Encoder_State *cstate) /* (i/o) Coder State */
  32. {
  33. Word16 s; /* Q2 */
  34. Word16 a, b;
  35. Word16 im;
  36. Word16 maxdev, flag, mpflag;
  37. Word32 eni, deltae;
  38. Word32 cc;
  39. Word16 ah,al, bh, bl;
  40. Word32 a0, a1, a2, a3;
  41. Word32 *lp0;
  42. Word16 exp, new_exp;
  43. Word16 *fp0, *fp1, *fp2, *fp3, *sp;
  44. Word16 *fp1_h, *fp1_l, *fp2_h, *fp2_l;
  45. Word16 cor2max, cor2max_exp;
  46. Word16 cor2m, cor2m_exp;
  47. Word16 s0, t0, t1, exp0, exp1, e2, e3;
  48. Word16 threshold;
  49. Word16 mplth; /* Q2 */
  50. Word16 i, j, k, n, npeaks, imax, idx[MAXPPD-MINPPD+1];
  51. Word16 cpp;
  52. Word16 plag[HMAXPPD], cor2[MAXPPD1], cor2_exp[MAXPPD1];
  53. Word16 cor2i[HMAXPPD], cor2i_exp[HMAXPPD], xwd[LXD];
  54. Word16 tmp_h[DFO+FRSZ], tmp_l[DFO+FRSZ]; /* DPF Q7 */
  55. Word32 cor[MAXPPD1], energy[MAXPPD1], lxwd[FRSZD];
  56. Word16 energy_man[MAXPPD1], energy_exp[MAXPPD1];
  57. Word16 energyi_man[HMAXPPD], energyi_exp[HMAXPPD];
  58. Word16 energym_man, energym_exp;
  59. Word16 energymax_man, energymax_exp;
  60. /* Lowpass filter xw() to 800 hz; shift & output into xwd() */
  61. /* AP and AZ filtering and decimation */
  62. fp1_h = tmp_h + DFO;
  63. fp1_l = tmp_l + DFO;
  64. sp = xw;
  65. a1 = 1;
  66. for (i=0;i<DFO;i++) tmp_h[i] = cstate->dfm_h[2*i+1];
  67. for (i=0;i<DFO;i++) tmp_l[i] = cstate->dfm_h[2*i];
  68. lp0 = lxwd;
  69. for (i=0;i<FRSZD;i++) {
  70. for (k=0;k<DECF;k++) {
  71. a0 = L_shr(L_deposit_h(*sp++),10);
  72. fp2_h = fp1_h-1;
  73. fp2_l = fp1_l-1;
  74. for (j=0;j<DFO;j++)
  75. a0=L_sub(a0,Mpy_32(*fp2_h--,*fp2_l--,adf_h[j+1],adf_l[j+1]));
  76. a0 = L_shl(a0, 2); /* adf Q13 */
  77. L_Extract(a0, fp1_h++, fp1_l++);
  78. }
  79. fp2_h = fp1_h-1;
  80. fp2_l = fp1_l-1;
  81. a0 = Mpy_32_16(*fp2_h--, *fp2_l--, bdf[0]);
  82. for (j=0;j<DFO;j++)
  83. a0=L_add(a0,Mpy_32_16(*fp2_h--,*fp2_l--,bdf[j+1]));
  84. *lp0++ = a0;
  85. a0 = L_abs(a0);
  86. if (a1 < a0)
  87. a1 = a0;
  88. }
  89. /* copy temp buffer to memory */
  90. fp1_h -= DFO;
  91. fp1_l -= DFO;
  92. for (i=0;i<DFO;i++) {
  93. cstate->dfm_h[2*i+1] = fp1_h[i];
  94. cstate->dfm_h[2*i] = fp1_l[i];
  95. }
  96. lp0 = lxwd;
  97. new_exp = sub(norm_l(a1), 3); /* headroom to avoid overflow */
  98. exp = sub(cstate->xwd_exp,new_exp); /* increase in bit-resolution */
  99. if (exp < 0) { /* Descending signal level */
  100. new_exp = cstate->xwd_exp;
  101. exp = 0;
  102. }
  103. for (i=0;i<XDOFF;i++)
  104. xwd[i] = shr(cstate->xwd[i], exp);
  105. /* fill-in new exponent */
  106. fp0 = xwd + XDOFF;
  107. for (i=0;i<FRSZD;i++)
  108. fp0[i] = intround(L_shl(lp0[i],new_exp));
  109. /* update signal memory for next frame */
  110. exp0 = 1;
  111. for (i=0;i<XDOFF;i++) {
  112. exp1 = abs_s(xwd[FRSZD+i]);
  113. if (exp1 > exp0)
  114. exp0 = exp1;
  115. }
  116. exp0 = sub(norm_s(exp0),3); /* extra exponent for next frame */
  117. exp = sub(exp0, exp);
  118. if (exp >=0)
  119. {
  120. for (i=0;i<XDOFF-FRSZD;i++)
  121. cstate->xwd[i] = shl(cstate->xwd[i+FRSZD], exp);
  122. }
  123. else
  124. {
  125. exp = -exp;
  126. if (exp >=15)
  127. exp = 15;
  128. for (i=0;i<XDOFF-FRSZD;i++)
  129. cstate->xwd[i] = shr(cstate->xwd[i+FRSZD], exp);
  130. }
  131. for (;i<XDOFF;i++)
  132. cstate->xwd[i] = shl(xwd[FRSZD+i],exp0);
  133. cstate->xwd_exp = add(new_exp, exp0);
  134. /* Compute correlation & energy of prediction basis vector */
  135. /* reset local buffers */
  136. for (i=0;i<MAXPPD1;i++)
  137. cor[i] = energy[i] = 0;
  138. fp0 = xwd+MAXPPD1;
  139. fp1 = xwd+MAXPPD1-M1;
  140. a0 = a1 = 0;
  141. for (i=0;i<(LXD-MAXPPD1);i++) {
  142. a0 = L_mac0(a0, *fp1, *fp1);
  143. a1 = L_mac0(a1, *fp0++, *fp1++);
  144. }
  145. cor[M1-1] = a1;
  146. energy[M1-1] = a0;
  147. energy_exp[M1-1] = norm_l(energy[M1-1]);
  148. energy_man[M1-1] = extract_h(L_shl(energy[M1-1], energy_exp[M1-1]));
  149. s0 = cor2_exp[M1-1] = norm_l(a1);
  150. t0 = extract_h(L_shl(a1, s0));
  151. cor2[M1-1] = extract_h(L_mult(t0, t0));
  152. if (a1 < 0)
  153. cor2[M1-1] = negate(cor2[M1-1]);
  154. fp2 = xwd+LXD-M1-1;
  155. fp3 = xwd+MAXPPD1-M1-1;
  156. for (i=M1;i<M2;i++) {
  157. fp0 = xwd+MAXPPD1;
  158. fp1 = xwd+MAXPPD1-i-1;
  159. a1 = 0;
  160. for (j=0;j<(LXD-MAXPPD1);j++)
  161. a1 = L_mac0(a1,*fp0++,*fp1++);
  162. cor[i] = a1;
  163. a0 = L_msu0(a0, *fp2, *fp2);
  164. a0 = L_mac0(a0, *fp3, *fp3);
  165. fp2--; fp3--;
  166. energy[i] = a0;
  167. energy_exp[i] = norm_l(energy[i]);
  168. energy_man[i] = extract_h(L_shl(energy[i], energy_exp[i]));
  169. s0 = cor2_exp[i] = norm_l(a1);
  170. t0 = extract_h(L_shl(a1, s0));
  171. cor2[i] = extract_h(L_mult(t0, t0));
  172. if (a1 < 0)
  173. cor2[i] = negate(cor2[i]);
  174. }
  175. /* Find positive correlation peaks */
  176. /* Find maximum of cor*cor/energy among positive correlation peaks */
  177. npeaks = 0;
  178. n = MINPPD-1;
  179. while ((npeaks < MAX_NPEAKS) && (n<MAXPPD)) {
  180. if (cor[n]>0) {
  181. a0 = L_mult(energy_man[n-1],cor2[n]);
  182. a1 = L_mult(energy_man[n], cor2[n-1]);
  183. exp0 = shl(sub(cor2_exp[n], cor2_exp[n-1]),1);
  184. exp0 = add(exp0, energy_exp[n-1]);
  185. exp0 = sub(exp0, energy_exp[n]);
  186. if (exp0>=0)
  187. a0 = L_shr(a0, exp0);
  188. else
  189. a1 = L_shl(a1, exp0);
  190. if (a0 > a1) {
  191. a0 = L_mult(energy_man[n+1],cor2[n]);
  192. a1 = L_mult(energy_man[n], cor2[n+1]);
  193. exp0 = shl(sub(cor2_exp[n], cor2_exp[n+1]),1);
  194. exp0 = add(exp0, energy_exp[n+1]);
  195. exp0 = sub(exp0, energy_exp[n]);
  196. if (exp0>=0)
  197. a0 = L_shr(a0, exp0);
  198. else
  199. a1 = L_shl(a1, exp0);
  200. if (a0 > a1) {
  201. idx[npeaks] = n;
  202. npeaks++;
  203. }
  204. }
  205. }
  206. n++;
  207. }
  208. /* Return early if there is no peak or only one peak */
  209. if (npeaks == 0){ /* if there are no positive peak, */
  210. return MINPPD*DECF; /* return minimum pitch period in decimated domain */
  211. }
  212. if (npeaks == 1){ /* if there is exactly one peak, */
  213. return (idx[0]+1)*DECF; /* return the time lag for this single peak */
  214. }
  215. /* If program proceeds to here, there are 2 or more peaks */
  216. cor2max=(Word16) 0x8000;
  217. cor2max_exp= (Word16) 0;
  218. energymax_man=1;
  219. energymax_exp=0;
  220. imax=0;
  221. for (i=0; i < npeaks; i++) {
  222. /* Use quadratic interpolation to find the interpolated cor[] and
  223. energy[] corresponding to interpolated peak of cor2[]/energy[] */
  224. /* first calculate coefficients of y(x)=ax^2+bx+c; */
  225. n=idx[i];
  226. a0=L_sub(L_shr(L_add(cor[n+1],cor[n-1]),1),cor[n]);
  227. L_Extract(a0, &ah, &al);
  228. a0=L_shr(L_sub(cor[n+1],cor[n-1]),1);
  229. L_Extract(a0, &bh, &bl);
  230. cc=cor[n];
  231. /* Initialize variables before searching for interpolated peak */
  232. im=0;
  233. cor2m_exp = cor2_exp[n];
  234. cor2m = cor2[n];
  235. energym_exp = energy_exp[n];
  236. energym_man = energy_man[n];
  237. eni=energy[n];
  238. /* Determine which side the interpolated peak falls in, then
  239. do the search in the appropriate range */
  240. a0 = L_mult(energy_man[n-1],cor2[n+1]);
  241. a1 = L_mult(energy_man[n+1], cor2[n-1]);
  242. exp0 = shl(sub(cor2_exp[n+1], cor2_exp[n-1]),1);
  243. exp0 = add(exp0, energy_exp[n-1]);
  244. exp0 = sub(exp0, energy_exp[n+1]);
  245. if (exp0>=0)
  246. a0 = L_shr(a0, exp0);
  247. else
  248. a1 = L_shl(a1, exp0);
  249. if (a0 > a1) { /* if right side */
  250. deltae = L_shr(L_sub(energy[n+1], eni), 2);
  251. for (k = 0; k < HDECF; k++) {
  252. a0=L_add(L_add(Mpy_32_16(ah,al,x2[k]),Mpy_32_16(bh,bl,x[k])),cc);
  253. eni = L_add(eni, deltae);
  254. a1 = eni;
  255. exp0 = norm_l(a0);
  256. s0 = extract_h(L_shl(a0, exp0));
  257. s0 = extract_h(L_mult(s0, s0));
  258. e2 = energym_exp;
  259. t0 = energym_man;
  260. a2 = L_mult(t0, s0);
  261. e3 = norm_l(a1);
  262. t1 = extract_h(L_shl(a1, e3));
  263. a3 = L_mult(t1, cor2m);
  264. exp1 = shl(sub(exp0, cor2m_exp),1);
  265. exp1 = add(exp1, e2);
  266. exp1 = sub(exp1, e3);
  267. if (exp1>=0)
  268. a2 = L_shr(a2, exp1);
  269. else
  270. a3 = L_shl(a3, exp1);
  271. if (a2 > a3) {
  272. im = k+1;
  273. cor2m = s0;
  274. cor2m_exp = exp0;
  275. energym_exp = e3;
  276. energym_man = t1;
  277. }
  278. }
  279. } else { /* if interpolated peak is on the left side */
  280. deltae = L_shr(L_sub(energy[n-1], eni), 2);
  281. for (k = 0; k < HDECF; k++) {
  282. a0=L_add(L_sub(Mpy_32_16(ah,al,x2[k]),Mpy_32_16(bh,bl,x[k])),cc);
  283. eni = L_add(eni, deltae);
  284. a1=eni;
  285. exp0 = norm_l(a0);
  286. s0 = extract_h(L_shl(a0, exp0));
  287. s0 = extract_h(L_mult(s0, s0));
  288. e2 = energym_exp;
  289. t0 = energym_man;
  290. a2 = L_mult(t0, s0);
  291. e3 = norm_l(a1);
  292. t1 = extract_h(L_shl(a1, e3));
  293. a3 = L_mult(t1, cor2m);
  294. exp1 = shl(sub(exp0, cor2m_exp),1);
  295. exp1 = add(exp1, e2);
  296. exp1 = sub(exp1, e3);
  297. if (exp1>=0)
  298. a2 = L_shr(a2, exp1);
  299. else
  300. a3 = L_shl(a3, exp1);
  301. if (a2 > a3) {
  302. im = -k-1;
  303. cor2m = s0;
  304. cor2m_exp = exp0;
  305. energym_exp = e3;
  306. energym_man = t1;
  307. }
  308. }
  309. }
  310. /* Search done; assign cor2[] and energy[] corresponding to
  311. interpolated peak */
  312. plag[i]=add(shl(add(idx[i],1),2),im); /* lag of interp. peak */
  313. cor2i[i]=cor2m;
  314. cor2i_exp[i]=cor2m_exp;
  315. /* interpolated energy[] of i-th interpolated peak */
  316. energyi_exp[i] = energym_exp;
  317. energyi_man[i] = energym_man;
  318. /* Search for global maximum of interpolated cor2[]/energy[] peak */
  319. a0 = L_mult(cor2m,energymax_man);
  320. a1 = L_mult(cor2max, energyi_man[i]);
  321. exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
  322. exp0 = add(exp0, energymax_exp);
  323. exp0 = sub(exp0, energyi_exp[i]);
  324. if (exp0 >=0)
  325. a0 = L_shr(a0, exp0);
  326. else
  327. a1 = L_shl(a1, exp0);
  328. if (a0 > a1) {
  329. imax=i;
  330. cor2max=cor2m;
  331. cor2max_exp=cor2m_exp;
  332. energymax_exp = energyi_exp[i];
  333. energymax_man = energyi_man[i];
  334. }
  335. }
  336. cpp=plag[imax]; /* first candidate for coarse pitch period */
  337. mplth=plag[npeaks-1]; /* set mplth to the lag of last peak */
  338. /* Find the largest peak (if there is any) around the last pitch */
  339. maxdev= shr(cstate->cpplast,2); /* maximum deviation from last pitch */
  340. im = -1;
  341. cor2m=(Word16) 0x8000;
  342. cor2m_exp= (Word16) 0;
  343. energym_man = 1;
  344. energym_exp = 0;
  345. for (i=0;i<npeaks;i++) { /* loop thru the peaks before the largest peak */
  346. if (abs_s(sub(plag[i],cstate->cpplast)) <= maxdev) {
  347. a0 = L_mult(cor2i[i],energym_man);
  348. a1 = L_mult(cor2m, energyi_man[i]);
  349. exp0 = shl(sub(cor2i_exp[i], cor2m_exp),1);
  350. exp0 = add(exp0, energym_exp);
  351. exp0 = sub(exp0, energyi_exp[i]);
  352. if (exp0 >=0)
  353. a0 = L_shr(a0, exp0);
  354. else
  355. a1 = L_shl(a1, exp0);
  356. if (a0 > a1) {
  357. im=i;
  358. cor2m=cor2i[i];
  359. cor2m_exp=cor2i_exp[i];
  360. energym_man = energyi_man[i];
  361. energym_exp = energyi_exp[i];
  362. }
  363. }
  364. } /* if there is no peaks around last pitch, then im is still -1 */
  365. /* Now see if we should pick any alternatice peak */
  366. /* first, search first half of pitch range, see if any qualified peak
  367. has large enough peaks at every multiple of its lag */
  368. i=0;
  369. while (2*plag[i] < mplth) {
  370. /* Determine the appropriate threshold for this peak */
  371. if (i != im) { /* if not around last pitch, */
  372. threshold = TH1; /* use a higher threshold */
  373. } else { /* if around last pitch */
  374. threshold = TH2; /* use a lower threshold */
  375. }
  376. /* If threshold exceeded, test peaks at multiples of this lag */
  377. a0 = L_mult(cor2i[i],energymax_man);
  378. t1 = extract_h(L_mult(energyi_man[i], threshold));
  379. a1 = L_mult(cor2max, t1);
  380. exp0 = shl(sub(cor2i_exp[i], cor2max_exp),1);
  381. exp0 = add(exp0, energymax_exp);
  382. exp0 = sub(exp0, energyi_exp[i]);
  383. if (exp0 >=0)
  384. a0 = L_shr(a0, exp0);
  385. else
  386. a1 = L_shl(a1, exp0);
  387. if (a0 > a1) {
  388. flag=1;
  389. j=i+1;
  390. k=0;
  391. s=shl(plag[i],1); /* initialize t to twice the current lag */
  392. while (s<=mplth) { /* loop thru all multiple lag <= mplth */
  393. mpflag=0; /* initialize multiple pitch flag to 0 */
  394. t0 = mult_r(s,MPDTH);
  395. a=sub(s, t0); /* multiple pitch range lower bound */
  396. b=add(s, t0); /* multiple pitch range upper bound */
  397. while (j < npeaks) { /* loop thru peaks with larger lags */
  398. if (plag[j] > b) { /* if range exceeded, */
  399. break; /* break the innermost while loop */
  400. } /* if didn't break, then plag[j] <= b */
  401. if (plag[j] > a) { /* if current peak lag within range, */
  402. /* then check if peak value large enough */
  403. a0 = L_mult(cor2i[j],energymax_man);
  404. if (k<4)
  405. t1 = MPTH[k];
  406. else
  407. t1 = MPTH4;
  408. t1 = extract_h(L_mult(t1, energyi_man[j]));
  409. a1 = L_mult(cor2max, t1);
  410. exp0 = shl(sub(cor2i_exp[j], cor2max_exp),1);
  411. exp0 = add(exp0, energymax_exp);
  412. exp0 = sub(exp0, energyi_exp[j]);
  413. if (exp0 >=0)
  414. a0 = L_shr(a0, exp0);
  415. else
  416. a1 = L_shl(a1, exp0);
  417. if (a0 > a1) {
  418. mpflag=1; /* if peak large enough, set mpflag, */
  419. break; /* and break the innermost while loop */
  420. }
  421. }
  422. j++;
  423. }
  424. /* if no qualified peak found at this multiple lag */
  425. if (mpflag == 0) {
  426. flag=0; /* disqualify the lag plag[i] */
  427. break; /* and break the while (s<=mplth) loop */
  428. }
  429. k++;
  430. s = add(s, plag[i]); /* update s to the next multiple pitch lag */
  431. }
  432. /* if there is a qualified peak at every multiple of plag[i], */
  433. if (flag == 1) {
  434. cpp = plag[i]; /* then accept this as final pitch */
  435. return cpp; /* and return to calling function */
  436. }
  437. }
  438. i++;
  439. if (i == npeaks)
  440. break; /* to avoid out of array bound error */
  441. }
  442. /* If program proceeds to here, none of the peaks with lags < 0.5*mplth
  443. qualifies as the final pitch. in this case, check if
  444. there is any peak large enough around last pitch. if so, use its
  445. lag as the final pitch. */
  446. if (im != -1) { /* if there is at least one peak around last pitch */
  447. if (im == imax) { /* if this peak is also the global maximum, */
  448. return cpp; /* return first pitch candidate at global max */
  449. }
  450. if (im < imax) { /* if lag of this peak < lag of global max, */
  451. a0 = L_mult(cor2m,energymax_man);
  452. t1 = extract_h(L_mult(energym_man, LPTH2));
  453. a1 = L_mult(cor2max, t1);
  454. exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
  455. exp0 = add(exp0, energymax_exp);
  456. exp0 = sub(exp0, energym_exp);
  457. if (exp0 >=0)
  458. a0 = L_shr(a0, exp0);
  459. else
  460. a1 = L_shl(a1, exp0);
  461. if (a0 > a1) {
  462. if (plag[im] > HMAXPPD*DECF) {
  463. cpp=plag[im];
  464. return cpp;
  465. }
  466. for (k=2; k<=5;k++) { /* check if current candidate pitch */
  467. s=mult(plag[imax],invk[k-2]); /* is a sub-multiple of */
  468. t0 = mult_r(s,SMDTH);
  469. a=sub(s, t0); /* the time lag of */
  470. b=add(s, t0); /* the global maximum peak */
  471. if (plag[im]>a && plag[im]<b) { /* if so, */
  472. cpp=plag[im]; /* accept this peak, */
  473. return cpp; /* and return as pitch */
  474. }
  475. }
  476. }
  477. } else { /* if lag of this peak > lag of global max, */
  478. a0 = L_mult(cor2m,energymax_man);
  479. t1 = extract_h(L_mult(energym_man, LPTH1));
  480. a1 = L_mult(cor2max, t1);
  481. exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
  482. exp0 = add(exp0, energymax_exp);
  483. exp0 = sub(exp0, energym_exp);
  484. if (exp0 >=0)
  485. a0 = L_shr(a0, exp0);
  486. else
  487. a1 = L_shl(a1, exp0);
  488. if (a0 > a1) {
  489. cpp = plag[im]; /* if this peak is large enough, */
  490. return cpp; /* accept its lag */
  491. }
  492. }
  493. }
  494. /* If program proceeds to here, we have no choice but to accept the
  495. lag of the global maximum */
  496. return cpp;
  497. }