Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
8.2 KiB

  1. /******************************************************************************
  2. * lpc.cpp *
  3. *---------*
  4. * I/O library functions for extended speech files (vapi format)
  5. *------------------------------------------------------------------------------
  6. * Copyright (C) 1999 Entropic, Inc
  7. * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00
  8. * All Rights Reserved
  9. *
  10. ********************************************************************* PACOG ***/
  11. #include "sigprocInt.h"
  12. /*****************************************************************************
  13. * ParcorFilterSyn *
  14. *-----------------*
  15. * Description:
  16. * Synthesis lattice filter.
  17. ******************************************************************* PACOG ***/
  18. void ParcorFilterSyn (double* pdData, int iNumData, double* pdParcor, double* pdMemory, int iOrder)
  19. {
  20. double dAlfa;
  21. int j;
  22. assert (pdData);
  23. assert (pdParcor);
  24. assert (pdMemory);
  25. for (int i=0; i<iNumData; i++)
  26. {
  27. dAlfa = pdData[i];
  28. for (j=iOrder-1; j>=0; j--)
  29. {
  30. dAlfa += pdMemory[j] * pdParcor[j];
  31. if (j<iOrder-1)
  32. {
  33. pdMemory[j+1] = pdMemory[j] - dAlfa * pdParcor[j];
  34. }
  35. }
  36. pdMemory[0] = dAlfa;
  37. pdData[i] = dAlfa;
  38. }
  39. }
  40. /*****************************************************************************
  41. * ParcorFilterAn *
  42. *----------------*
  43. * Description:
  44. * Inverse filter, lattice form.
  45. ******************************************************************* PACOG ***/
  46. void ParcorFilterAn (double* pdData, int iNumData, double* pdParcor, double* pdMemory, int iOrder)
  47. {
  48. double dAlfa;
  49. double dBeta;
  50. double dDelay;
  51. int j;
  52. assert (pdData);
  53. assert (pdParcor);
  54. assert (pdMemory);
  55. for (int i=0; i<iNumData; i++)
  56. {
  57. dAlfa = pdData[i];
  58. dDelay = pdData[i];
  59. for (j=0; j<iOrder; j++)
  60. {
  61. dBeta = pdMemory[j] - dAlfa * pdParcor[j];
  62. dAlfa -= pdMemory[j] * pdParcor[j];
  63. pdMemory[j] = dDelay;
  64. dDelay = dBeta;
  65. }
  66. pdData[i] = dAlfa;
  67. }
  68. }
  69. /*****************************************************************************
  70. * Cepstrum *
  71. *----------*
  72. * Description:
  73. * Computes order +1 autocorrelation coefficients of a data segment.
  74. ******************************************************************* PACOG ***/
  75. double* Autocor(double* x, int xLen, int iOrder)
  76. {
  77. double* aut;
  78. int i;
  79. int n;
  80. assert (x);
  81. assert (xLen>0);
  82. assert (iOrder>0);
  83. if ((aut = new double[iOrder+1]) != 0)
  84. {
  85. memset (aut, 0, sizeof(*aut) * (iOrder+1));
  86. for (i=0; i<=iOrder; i++)
  87. {
  88. for (n=0; n<xLen- i; n++)
  89. {
  90. aut[i] += x[n] * x[i+n];
  91. }
  92. aut[i] /= xLen;
  93. }
  94. }
  95. return aut;
  96. }
  97. /*****************************************************************************
  98. * NormAutocor *
  99. *-------------*
  100. * Description:
  101. * Computes autocorrelation coefficients of a data segment, normalized
  102. * by the value of the energy in that segment (r[0]). The energy value
  103. * is returned in r[0].
  104. ******************************************************************* PACOG ***/
  105. double* NormAutocor(double* x, int xLen, int iOrder)
  106. {
  107. double* aut;
  108. int i;
  109. int n;
  110. assert (x);
  111. assert (xLen>0);
  112. assert (iOrder>0);
  113. if ((aut = new double[iOrder+1]) != NULL)
  114. {
  115. memset (aut, 0, sizeof(*aut) * (iOrder+1));
  116. for (i=0; i<=iOrder; i++)
  117. {
  118. for (n=0; n<xLen - i; n++)
  119. {
  120. aut[i] += x[n] * x[i+n];
  121. }
  122. }
  123. for (i=iOrder; i>=0; i-- )
  124. {
  125. aut[i] /= aut[0];
  126. }
  127. }
  128. return aut;
  129. }
  130. /*****************************************************************************
  131. * DurbinRecursion *
  132. *-----------------*
  133. * Description:
  134. *
  135. ******************************************************************* PACOG ***/
  136. double* DurbinRecursion (double* pdAutoc, int iOrder, int iCoefType, double *pdError)
  137. {
  138. double* pdCoef = 0;
  139. double* pdAlfa1 = 0;
  140. double* pdAlfa2 = 0;
  141. double* pdParcor = 0;
  142. double dW;
  143. double dU;
  144. int m;
  145. int i;
  146. assert (pdAutoc);
  147. assert (iOrder>0);
  148. if ((pdAlfa1 = new double[iOrder+1]) == 0)
  149. {
  150. goto error;
  151. }
  152. memset (pdAlfa1, 0, sizeof(*pdAlfa1)* (iOrder+1));
  153. if ((pdAlfa2 = new double[iOrder+1]) == 0)
  154. {
  155. goto error;
  156. }
  157. memset (pdAlfa2, 0, sizeof(*pdAlfa2)* (iOrder+1));
  158. pdAlfa1[0] = pdAlfa2[0] = 1.0;
  159. if ((pdParcor = new double[iOrder+1]) == 0)
  160. {
  161. goto error;
  162. }
  163. memset (pdParcor, 0, sizeof(*pdParcor)* (iOrder+1));
  164. dW = pdAutoc[1];
  165. dU = pdAutoc[0];
  166. for (m=1; m<=iOrder; m++)
  167. {
  168. if (dU == 0.0)
  169. {
  170. pdParcor[m] = 0.0;
  171. }
  172. else
  173. {
  174. pdParcor[m]= dW/dU;
  175. }
  176. dU *= (1.0 - pdParcor[m]*pdParcor[m]);
  177. for (i=1; i<=m; i++)
  178. {
  179. pdAlfa1[i] = pdAlfa2[i] - pdParcor[m]*pdAlfa2[m-i];
  180. }
  181. if (m<iOrder)
  182. {
  183. dW = 0.0;
  184. for (i=0; i<=m; i++ )
  185. {
  186. dW += pdAlfa1[i]*pdAutoc[m+1-i];
  187. }
  188. memcpy (pdAlfa2, pdAlfa1, (iOrder+1)*sizeof(*pdAlfa1));
  189. }
  190. }
  191. if (pdError)
  192. {
  193. *pdError = sqrt(dU);
  194. /*
  195. double acum=0.0;
  196. for (i=0;i<=iOrder;i++)
  197. {
  198. acum+=pdAlfa1[i]+pdAutoc[i];
  199. }
  200. *pdError=sqrt(acum);
  201. */
  202. }
  203. if ((pdCoef = new double[iOrder]) == 0)
  204. {
  205. goto error;
  206. }
  207. if (iCoefType == LPC_ALFA)
  208. {
  209. for (i=0 ; i<iOrder; i++)
  210. {
  211. pdCoef[i] = pdAlfa1[i+1];
  212. }
  213. }
  214. else
  215. {
  216. for (i=0 ; i<iOrder; i++)
  217. {
  218. pdCoef[i] = pdParcor[i+1];
  219. }
  220. }
  221. delete[] pdAlfa1;
  222. delete[] pdAlfa2;
  223. delete[] pdParcor;
  224. return pdCoef;
  225. error:
  226. if (pdAlfa1)
  227. {
  228. delete[] pdAlfa1;
  229. }
  230. if (pdAlfa2)
  231. {
  232. delete[] pdAlfa2;
  233. }
  234. if (pdParcor)
  235. {
  236. delete[] pdParcor;
  237. }
  238. return 0;
  239. }
  240. /*****************************************************************************
  241. * GetDurbinCoef *
  242. *---------------*
  243. * Description:
  244. *
  245. ******************************************************************* PACOG ***/
  246. double* GetDurbinCoef(double* pdData, int iNumData, int iOrder, int iCoefType, double *pdError)
  247. {
  248. double* pdAutoc;
  249. double* coef;
  250. assert(pdData);
  251. assert(pdData>0);
  252. assert(iOrder>0);
  253. if ((pdAutoc = Autocor (pdData, iNumData, iOrder)) == 0)
  254. {
  255. return 0;
  256. }
  257. coef = DurbinRecursion ( pdAutoc, iOrder, iCoefType, pdError);
  258. delete[] pdAutoc;
  259. return coef;
  260. }
  261. /*****************************************************************************
  262. * ParcorToAlfa *
  263. *--------------*
  264. * Description:
  265. * Converts reflexion coefficient into Prediction coefs.
  266. ******************************************************************* PACOG ***/
  267. bool ParcorToAlfa (double* pdParcor, double* pdAlfa, int iOrder)
  268. {
  269. double *a1 = 0;
  270. double *a2 = 0;
  271. double *k1 = 0;
  272. int m;
  273. int i;
  274. bool fRetVal = false;
  275. assert (pdParcor);
  276. assert (pdAlfa);
  277. assert (iOrder>0);
  278. if ((a1 = new double[iOrder]) == 0)
  279. {
  280. goto exit;
  281. }
  282. memset (a1, 0, iOrder * sizeof(*a1));
  283. if ((a2 = new double[iOrder]) == 0)
  284. {
  285. goto exit;
  286. }
  287. memset (a2, 0, iOrder * sizeof(*a2));
  288. if ((k1 = new double[iOrder]) == 0)
  289. {
  290. goto exit;
  291. }
  292. a1[0] = a2[0] = 1.0;
  293. for (i=0; i<iOrder; i++)
  294. {
  295. k1[i+1] = pdParcor[i];
  296. }
  297. for (m=1; m<=iOrder; m++)
  298. {
  299. for (i=1;i<=m;i++)
  300. {
  301. a1[i] = a2[i] - k1[m]*a2[m-i];
  302. }
  303. if (m<iOrder)
  304. {
  305. memcpy(a2, a1, iOrder * sizeof(*a1));
  306. }
  307. }
  308. for (i=0; i<iOrder; i++)
  309. {
  310. pdAlfa[i] = a1[i+1];
  311. }
  312. fRetVal = true;
  313. exit:
  314. if (a1)
  315. {
  316. delete[] a1;
  317. }
  318. if (a2)
  319. {
  320. delete[] a2;
  321. }
  322. if (k1)
  323. {
  324. delete[] k1;
  325. }
  326. return fRetVal;
  327. }