Leaked source code of windows server 2003
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.

694 lines
26 KiB

  1. //
  2. // ITU-T G.723 Floating Point Speech Coder ANSI C Source Code. Version 1.00
  3. // copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  4. // Universite de Sherbrooke, Intel Corporation. All rights reserved.
  5. //
  6. #include "timer.h"
  7. #include "ctiming.h"
  8. #include "opt.h"
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "typedef.h"
  12. #include "cst_lbc.h"
  13. #include "tab_lbc.h"
  14. #include "coder.h"
  15. #include "lpc.h"
  16. #include "lsp.h"
  17. #include "exc_lbc.h"
  18. #include "util_lbc.h"
  19. #include "memory.h"
  20. #include "mmxutil.h"
  21. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  22. #pragma message ("Current log encode timing computations handle 2057 frames max")
  23. void OutputEncodeTimingStatistics(char * szFileName, ENC_TIMING_INFO * pEncTimingInfo, unsigned long dwFrameCount);
  24. void OutputEncTimingDetail(FILE * pFile, ENC_TIMING_INFO * pEncTimingInfo);
  25. #endif // } LOG_ENCODE_TIMINGS_ON
  26. //
  27. // This file includes the coder main functions
  28. //
  29. //--------------------------------------------------
  30. void Init_Coder(CODDEF *CodStat)
  31. {
  32. int i;
  33. // Init prev Lsp to Dc
  34. for (i=0; i < LpcOrder; i++)
  35. CodStat->PrevLsp[i] = LspDcTable[i];
  36. CodStat->p = 9;
  37. CodStat->q = 9;
  38. CodStat->VadAct = 1;
  39. /* Initialize the taming procedure */
  40. for(i=0; i<SizErr; i++) CodStat->Err[i] = Err0;
  41. }
  42. //---------------------------------------------------
  43. Flag Coder(float *DataBuff, Word32 *Vout, CODDEF *CodStat,
  44. int quality, int UseCpuId, int UseMMX)
  45. {
  46. int i,j,flags ;
  47. static int qual2flags[16] =
  48. {SC_DEF,SC_DEF,SC_DEF,SC_DEF,SC_DEF,SC_DEF,SC_DEF,SC_DEF,
  49. SC_DEF,SC_DEF,SC_DEF,SC_DEF,
  50. SC_LAG1 | SC_GAIN | SC_FINDB,
  51. SC_GAIN | SC_FINDB,
  52. SC_FINDB,
  53. 0};
  54. // Local variables
  55. float UnqLpc[SubFrames*LpcOrder];
  56. float QntLpc[SubFrames*LpcOrder];
  57. float PerLpc[2*SubFrames*LpcOrder];
  58. float LspVect[LpcOrder];
  59. LINEDEF Line;
  60. PWDEF Pw[SubFrames];
  61. float ImpResp[SubFrLen];
  62. float Dpnt[PitchMax+Frame];
  63. float *dptr;
  64. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  65. unsigned long dwStartLow;
  66. unsigned long dwStartHigh;
  67. unsigned long dwElapsed;
  68. unsigned long dwBefore;
  69. unsigned long dwEncode = 0;
  70. int bTimingThisFrame = 0;
  71. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  72. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  73. unsigned long dwRem_Dc = 0;
  74. unsigned long dwComp_Lpc = 0;
  75. unsigned long dwAtoLsp = 0;
  76. unsigned long dwLsp_Qnt = 0;
  77. unsigned long dwLsp_Inq = 0;
  78. unsigned long dwLsp_Int = 0;
  79. unsigned long dwMem_Shift = 0;
  80. unsigned long dwWght_Lpc = 0;
  81. unsigned long dwError_Wght = 0;
  82. unsigned long dwFew_Lps_In_Coder = 0;
  83. unsigned long dwFilt_Pw = 0;
  84. unsigned long dwComp_Ir = 0;
  85. unsigned long dwSub_Ring = 0;
  86. unsigned long dwFind_Acbk = 0;
  87. unsigned long dwFind_Fcbk = 0;
  88. unsigned long dwDecode_Acbk = 0;
  89. unsigned long dwReconstr_Excit = 0;
  90. unsigned long dwUpd_Ring = 0;
  91. unsigned long dwLine_Pack = 0;
  92. unsigned long dwComp_IrTemp = 0;
  93. unsigned long dwSub_RingTemp = 0;
  94. unsigned long dwFind_AcbkTemp = 0;
  95. unsigned long dwFind_FcbkTemp = 0;
  96. unsigned long dwDecode_AcbkTemp = 0;
  97. unsigned long dwReconstr_ExcitTemp = 0;
  98. unsigned long dwUpd_RingTemp = 0;
  99. #endif // } DETAILED_ENCODE_TIMINGS_ON
  100. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  101. ENC_TIMING_INFO * pEncTimingInfo = NULL;
  102. #endif // } LOG_ENCODE_TIMINGS_ON
  103. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  104. TIMER_START(bTimingThisFrame,dwStartLow,dwStartHigh);
  105. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  106. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  107. if (CodStat->dwStatFrameCount < ENC_TIMING_INFO_FRAME_COUNT)
  108. {
  109. CodStat->dwStartLow = dwStartLow;
  110. CodStat->dwStartHigh = dwStartHigh;
  111. }
  112. CodStat->bTimingThisFrame = bTimingThisFrame;
  113. #endif // } LOG_ENCODE_TIMINGS_ON
  114. if (quality < 0 || quality > 15) quality = 0;
  115. flags = qual2flags[quality];
  116. // If UseCpuId is set, determine whether to use MMX based on the
  117. // actual hardware CPUID. Otherwise, just use the passed-in parameter.
  118. #if COMPILE_MMX
  119. if (UseCpuId)
  120. UseMMX = IsMMX();
  121. #else
  122. UseMMX = UseCpuId = FALSE;
  123. #endif //COMPILE_MMX
  124. //Coder Start
  125. Line.Crc = 0;
  126. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  127. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  128. #endif // } DETAILED_ENCODE_TIMINGS_ON
  129. Rem_Dc(DataBuff, CodStat);
  130. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  131. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwRem_Dc);
  132. #endif // } DETAILED_ENCODE_TIMINGS_ON
  133. // Compute the Unquantized Lpc set for whole frame
  134. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  135. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  136. #endif // } DETAILED_ENCODE_TIMINGS_ON
  137. #if COMPILE_MMX
  138. if (UseMMX)
  139. Comp_LpcInt(UnqLpc, CodStat->PrevDat, DataBuff, CodStat);
  140. else
  141. #endif
  142. Comp_Lpc(UnqLpc, CodStat->PrevDat, DataBuff, CodStat);
  143. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  144. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwComp_Lpc);
  145. #endif // } DETAILED_ENCODE_TIMINGS_ON
  146. // Convert to Lsp
  147. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  148. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  149. #endif // } DETAILED_ENCODE_TIMINGS_ON
  150. AtoLsp(LspVect, &UnqLpc[LpcOrder*(SubFrames-1)], CodStat->PrevLsp);
  151. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  152. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwAtoLsp);
  153. #endif // } DETAILED_ENCODE_TIMINGS_ON
  154. // VQ Lsp vector
  155. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  156. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  157. #endif // } DETAILED_ENCODE_TIMINGS_ON
  158. Line.LspId = Lsp_Qnt(LspVect, CodStat->PrevLsp, UseMMX);
  159. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  160. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwLsp_Qnt);
  161. #endif // } DETAILED_ENCODE_TIMINGS_ON
  162. // Inverse quantization of the LSP
  163. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  164. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  165. #endif // } DETAILED_ENCODE_TIMINGS_ON
  166. Lsp_Inq(LspVect, CodStat->PrevLsp, Line.LspId, Line.Crc);
  167. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  168. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwLsp_Inq);
  169. #endif // } DETAILED_ENCODE_TIMINGS_ON
  170. // Interpolate the Lsp vectors
  171. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  172. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  173. #endif // } DETAILED_ENCODE_TIMINGS_ON
  174. Lsp_Int(QntLpc, LspVect, CodStat->PrevLsp);
  175. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  176. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwLsp_Int);
  177. #endif // } DETAILED_ENCODE_TIMINGS_ON
  178. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  179. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  180. #endif // } DETAILED_ENCODE_TIMINGS_ON
  181. Mem_Shift(CodStat->PrevDat, DataBuff);
  182. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  183. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwMem_Shift);
  184. #endif // } DETAILED_ENCODE_TIMINGS_ON
  185. // Compute Percetual filter Lpc coefficeints
  186. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  187. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  188. #endif // } DETAILED_ENCODE_TIMINGS_ON
  189. Wght_Lpc(PerLpc, UnqLpc);
  190. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  191. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwWght_Lpc);
  192. #endif // } DETAILED_ENCODE_TIMINGS_ON
  193. // Apply the perceptual weighting filter
  194. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  195. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  196. #endif // } DETAILED_ENCODE_TIMINGS_ON
  197. Error_Wght(DataBuff, PerLpc,CodStat);
  198. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  199. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwError_Wght);
  200. #endif // } DETAILED_ENCODE_TIMINGS_ON
  201. // Compute Open loop pitch estimates
  202. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  203. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  204. #endif // } DETAILED_ENCODE_TIMINGS_ON
  205. // Construct the buffer
  206. memcpy(Dpnt,CodStat->PrevWgt,4*PitchMax);
  207. memcpy(&Dpnt[PitchMax],DataBuff,4*Frame);
  208. /*
  209. for (i=0; i < PitchMax;i++)
  210. Dpnt[i] = CodStat->PrevWgt[i];
  211. for (i=0;i < Frame;i++)
  212. Dpnt[PitchMax+i] = DataBuff[i];
  213. */
  214. j = PitchMax;
  215. for (i=0; i < SubFrames/2; i++)
  216. {
  217. #if COMPILE_MMX
  218. if (UseMMX)
  219. Line.Olp[i] = Estim_Int(Dpnt, j);
  220. else
  221. #endif
  222. Line.Olp[i] = Estim_Pitch(Dpnt, j);
  223. j += 2*SubFrLen;
  224. }
  225. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  226. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwFew_Lps_In_Coder);
  227. #endif // } DETAILED_ENCODE_TIMINGS_ON
  228. // Compute the Hmw
  229. j = PitchMax;
  230. for (i=0; i < SubFrames; i++)
  231. {
  232. Pw[i] = Comp_Pw(Dpnt, j, Line.Olp[i>>1]);
  233. j += SubFrLen;
  234. }
  235. // Reload the buffer
  236. for (i=0; i < PitchMax; i++)
  237. Dpnt[i] = CodStat->PrevWgt[i];
  238. for (i=0; i < Frame; i++)
  239. Dpnt[PitchMax+i] = DataBuff[i];
  240. // Save PrevWgt
  241. for (i=0; i < PitchMax; i++)
  242. CodStat->PrevWgt[i] = Dpnt[Frame+i];
  243. // Apply the Harmonic filter
  244. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  245. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  246. #endif // } DETAILED_ENCODE_TIMINGS_ON
  247. j = 0;
  248. for (i=0; i < SubFrames; i++)
  249. {
  250. Filt_Pw(DataBuff, Dpnt, j , Pw[i]);
  251. j += SubFrLen;
  252. }
  253. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  254. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwFilt_Pw);
  255. #endif // } DETAILED_ENCODE_TIMINGS_ON
  256. // Start the sub frame processing loop
  257. dptr = DataBuff;
  258. for (i=0; i < SubFrames; i++)
  259. {
  260. // Compute full impulse responce
  261. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  262. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  263. #endif // } DETAILED_ENCODE_TIMINGS_ON
  264. Comp_Ir(ImpResp, &QntLpc[i*LpcOrder], &PerLpc[i*2*LpcOrder], Pw[i]);
  265. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  266. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwComp_IrTemp);
  267. #endif // } DETAILED_ENCODE_TIMINGS_ON
  268. // Subtruct the ringing of previos sub-frame
  269. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  270. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  271. #endif // } DETAILED_ENCODE_TIMINGS_ON
  272. Sub_Ring(dptr, &QntLpc[i*LpcOrder], &PerLpc[i*2*LpcOrder],
  273. CodStat->PrevErr, Pw[i], CodStat);
  274. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  275. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwSub_RingTemp);
  276. #endif // } DETAILED_ENCODE_TIMINGS_ON
  277. // Compute adaptive code book contribution
  278. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  279. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  280. #endif // } DETAILED_ENCODE_TIMINGS_ON
  281. #if COMPILE_MMX
  282. if(UseMMX)
  283. Find_AcbkInt(dptr, ImpResp, CodStat->PrevExc, &Line,i, CodStat->WrkRate, flags, CodStat);
  284. else
  285. #endif
  286. Find_Acbk(dptr, ImpResp, CodStat->PrevExc, &Line,i, CodStat->WrkRate, flags, CodStat);
  287. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  288. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwFind_AcbkTemp);
  289. #endif // } DETAILED_ENCODE_TIMINGS_ON
  290. // Compute fixed code book contribution
  291. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  292. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  293. #endif // } DETAILED_ENCODE_TIMINGS_ON
  294. Find_Fcbk(dptr, ImpResp, &Line, i, CodStat->WrkRate, flags, UseMMX);
  295. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  296. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwFind_FcbkTemp);
  297. #endif // } DETAILED_ENCODE_TIMINGS_ON
  298. // Reconstruct the excitation
  299. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  300. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  301. #endif // } DETAILED_ENCODE_TIMINGS_ON
  302. Decod_Acbk(ImpResp, CodStat->PrevExc, Line.Olp[i>>1],
  303. Line.Sfs[i].AcLg, Line.Sfs[i].AcGn, CodStat->WrkRate);
  304. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  305. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwDecode_AcbkTemp);
  306. #endif // } DETAILED_ENCODE_TIMINGS_ON
  307. for (j=SubFrLen; j < PitchMax; j++)
  308. CodStat->PrevExc[j-SubFrLen] = CodStat->PrevExc[j];
  309. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  310. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  311. #endif // } DETAILED_ENCODE_TIMINGS_ON
  312. for (j=0; j < SubFrLen; j++)
  313. {
  314. dptr[j] = dptr[j]*2.0f+ImpResp[j];
  315. CodStat->PrevExc[PitchMax-SubFrLen+j] = dptr[j];
  316. /* Clip the new samples */
  317. #if 1 //do clipping
  318. //clip to +/- 32767.0 doing abs & compare with integer unit
  319. //if clipping is needed shift sign bit to use as lookup table index
  320. #define FLTCLIP(x) \
  321. {\
  322. const float T[2] = {32767.0f, -32767.0f};\
  323. if ((asint(x) & 0x7fffffff) > asint(T[0]))\
  324. x = T[((unsigned)asint(x)) >> 31];\
  325. }
  326. FLTCLIP(CodStat->PrevExc[PitchMax-SubFrLen+j]);
  327. #endif //optclip
  328. }
  329. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  330. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwReconstr_ExcitTemp);
  331. #endif // } DETAILED_ENCODE_TIMINGS_ON
  332. /* Update exc_err */
  333. Update_Err(Line.Olp[i>>1], Line.Sfs[i].AcLg, Line.Sfs[i].AcGn, CodStat);
  334. // Update the ringing delays
  335. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  336. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  337. #endif // } DETAILED_ENCODE_TIMINGS_ON
  338. Upd_Ring(dptr, &QntLpc[i*LpcOrder], &PerLpc[i*2*LpcOrder],
  339. CodStat->PrevErr, CodStat);
  340. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  341. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwUpd_RingTemp);
  342. #endif // } DETAILED_ENCODE_TIMINGS_ON
  343. dptr += SubFrLen;
  344. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  345. // Sum stats
  346. dwComp_Ir += dwComp_IrTemp; dwComp_IrTemp = 0;
  347. dwSub_Ring += dwSub_RingTemp; dwSub_RingTemp = 0;
  348. dwFind_Acbk += dwFind_AcbkTemp; dwFind_AcbkTemp = 0;
  349. dwFind_Fcbk += dwFind_FcbkTemp; dwFind_FcbkTemp = 0;
  350. dwDecode_Acbk += dwDecode_AcbkTemp; dwDecode_AcbkTemp = 0;
  351. dwReconstr_Excit += dwReconstr_ExcitTemp; dwReconstr_ExcitTemp = 0;
  352. dwUpd_Ring += dwUpd_RingTemp; dwUpd_RingTemp = 0;
  353. #endif // } DETAILED_ENCODE_TIMINGS_ON
  354. }
  355. // Pack the Line structure
  356. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  357. TIMER_BEFORE(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore);
  358. #endif // } DETAILED_ENCODE_TIMINGS_ON
  359. Line_Pack(&Line, Vout,&(CodStat->VadAct),CodStat->WrkRate);
  360. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  361. TIMER_AFTER_P5(bTimingThisFrame,dwStartLow,dwStartHigh,dwBefore,dwElapsed,dwLine_Pack);
  362. #endif // } DETAILED_ENCODE_TIMINGS_ON
  363. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  364. TIMER_STOP(bTimingThisFrame,dwStartLow,dwStartHigh,dwEncode);
  365. #endif // } ENCODE_TIMINGS_ON
  366. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  367. if (bTimingThisFrame && (CodStat->dwStatFrameCount < ENC_TIMING_INFO_FRAME_COUNT))
  368. {
  369. pEncTimingInfo = &CodStat->EncTimingInfo[CodStat->dwStatFrameCount];
  370. pEncTimingInfo->dwEncode = dwEncode;
  371. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  372. pEncTimingInfo->dwRem_Dc = dwRem_Dc;
  373. pEncTimingInfo->dwComp_Lpc = dwComp_Lpc;
  374. pEncTimingInfo->dwAtoLsp = dwAtoLsp;
  375. pEncTimingInfo->dwLsp_Qnt = dwLsp_Qnt;
  376. pEncTimingInfo->dwLsp_Inq = dwLsp_Inq;
  377. pEncTimingInfo->dwLsp_Int = dwLsp_Int;
  378. pEncTimingInfo->dwMem_Shift = dwMem_Shift;
  379. pEncTimingInfo->dwWght_Lpc = dwWght_Lpc;
  380. pEncTimingInfo->dwError_Wght = dwError_Wght;
  381. pEncTimingInfo->dwFew_Lps_In_Coder = dwFew_Lps_In_Coder;
  382. pEncTimingInfo->dwFilt_Pw = dwFilt_Pw;
  383. pEncTimingInfo->dwComp_Ir = dwComp_Ir;
  384. pEncTimingInfo->dwSub_Ring = dwSub_Ring;
  385. pEncTimingInfo->dwFind_Acbk = dwFind_Acbk;
  386. pEncTimingInfo->dwFind_Fcbk = dwFind_Fcbk;
  387. pEncTimingInfo->dwDecode_Acbk = dwDecode_Acbk;
  388. pEncTimingInfo->dwReconstr_Excit = dwReconstr_Excit;
  389. pEncTimingInfo->dwUpd_Ring = dwUpd_Ring;
  390. pEncTimingInfo->dwLine_Pack = dwLine_Pack;
  391. #endif // } DETAILED_ENCODE_TIMINGS_ON
  392. CodStat->dwStatFrameCount++;
  393. }
  394. else
  395. {
  396. _asm int 3;
  397. }
  398. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  399. return (Flag) True;
  400. }
  401. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  402. void OutputEncodeTimingStatistics(char * szFileName, ENC_TIMING_INFO * pEncTimingInfo, unsigned long dwFrameCount)
  403. {
  404. FILE * pFile;
  405. ENC_TIMING_INFO * pTempEncTimingInfo;
  406. ENC_TIMING_INFO etiTemp;
  407. int i;
  408. int iCount;
  409. pFile = fopen(szFileName, "a");
  410. if (pFile == NULL)
  411. goto done;
  412. #if 0
  413. // Too verbose !!!
  414. /* Output the detail information
  415. */
  416. fprintf(pFile,"\nDetail Timing Information\n");
  417. for ( i = 0, pTempEncTimingInfo = pEncTimingInfo ; i < dwFrameCount ; i++, pTempEncTimingInfo++ )
  418. {
  419. fprintf(pFile, "Frame %d Detail Timing Information\n", i);
  420. OutputEncTimingDetail(pFile, pTempEncTimingInfo);
  421. }
  422. #endif
  423. /* Compute the total information
  424. */
  425. memset(&etiTemp, 0, sizeof(ENC_TIMING_INFO));
  426. iCount = 0;
  427. for ( i = 0, pTempEncTimingInfo = pEncTimingInfo ; i < dwFrameCount ; i++, pTempEncTimingInfo++ )
  428. {
  429. iCount++;
  430. etiTemp.dwEncode += pTempEncTimingInfo->dwEncode;
  431. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  432. etiTemp.dwRem_Dc += pTempEncTimingInfo->dwRem_Dc;
  433. etiTemp.dwComp_Lpc += pTempEncTimingInfo->dwComp_Lpc;
  434. etiTemp.dwAtoLsp += pTempEncTimingInfo->dwAtoLsp;
  435. etiTemp.dwLsp_Qnt += pTempEncTimingInfo->dwLsp_Qnt;
  436. etiTemp.dwLsp_Inq += pTempEncTimingInfo->dwLsp_Inq;
  437. etiTemp.dwLsp_Int += pTempEncTimingInfo->dwLsp_Int;
  438. etiTemp.dwMem_Shift += pTempEncTimingInfo->dwMem_Shift;
  439. etiTemp.dwWght_Lpc += pTempEncTimingInfo->dwWght_Lpc;
  440. etiTemp.dwError_Wght += pTempEncTimingInfo->dwError_Wght;
  441. etiTemp.dwFew_Lps_In_Coder += pTempEncTimingInfo->dwFew_Lps_In_Coder;
  442. etiTemp.dwFilt_Pw += pTempEncTimingInfo->dwFilt_Pw;
  443. etiTemp.dwComp_Ir += pTempEncTimingInfo->dwComp_Ir;
  444. etiTemp.dwSub_Ring += pTempEncTimingInfo->dwSub_Ring;
  445. etiTemp.dwFind_Acbk += pTempEncTimingInfo->dwFind_Acbk;
  446. etiTemp.dwFind_Fcbk += pTempEncTimingInfo->dwFind_Fcbk;
  447. etiTemp.dwDecode_Acbk += pTempEncTimingInfo->dwDecode_Acbk;
  448. etiTemp.dwReconstr_Excit += pTempEncTimingInfo->dwReconstr_Excit;
  449. etiTemp.dwUpd_Ring += pTempEncTimingInfo->dwUpd_Ring;
  450. etiTemp.dwLine_Pack += pTempEncTimingInfo->dwLine_Pack;
  451. #endif // } DETAILED_ENCODE_TIMINGS_ON
  452. }
  453. if (iCount > 0)
  454. {
  455. /* Output the total information
  456. */
  457. fprintf(pFile,"Total for %d frames\n", iCount);
  458. OutputEncTimingDetail(pFile, &etiTemp);
  459. /* Compute the average
  460. */
  461. etiTemp.dwEncode = (etiTemp.dwEncode + (iCount / 2)) / iCount;
  462. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  463. etiTemp.dwRem_Dc = (etiTemp.dwRem_Dc + (iCount / 2)) / iCount;
  464. etiTemp.dwComp_Lpc = (etiTemp.dwComp_Lpc + (iCount / 2)) / iCount;
  465. etiTemp.dwAtoLsp = (etiTemp.dwAtoLsp + (iCount / 2)) / iCount;
  466. etiTemp.dwLsp_Qnt = (etiTemp.dwLsp_Qnt + (iCount / 2)) / iCount;
  467. etiTemp.dwLsp_Inq = (etiTemp.dwLsp_Inq + (iCount / 2)) / iCount;
  468. etiTemp.dwLsp_Int = (etiTemp.dwLsp_Int + (iCount / 2)) / iCount;
  469. etiTemp.dwMem_Shift = (etiTemp.dwMem_Shift + (iCount / 2)) / iCount;
  470. etiTemp.dwWght_Lpc = (etiTemp.dwWght_Lpc + (iCount / 2)) / iCount;
  471. etiTemp.dwError_Wght = (etiTemp.dwError_Wght + (iCount / 2)) / iCount;
  472. etiTemp.dwFew_Lps_In_Coder = (etiTemp.dwFew_Lps_In_Coder + (iCount / 2)) / iCount;
  473. etiTemp.dwFilt_Pw = (etiTemp.dwFilt_Pw + (iCount / 2)) / iCount;
  474. etiTemp.dwComp_Ir = (etiTemp.dwComp_Ir + (iCount / 2)) / iCount;
  475. etiTemp.dwSub_Ring = (etiTemp.dwSub_Ring + (iCount / 2)) / iCount;
  476. etiTemp.dwFind_Acbk = (etiTemp.dwFind_Acbk + (iCount / 2)) / iCount;
  477. etiTemp.dwFind_Fcbk = (etiTemp.dwFind_Fcbk + (iCount / 2)) / iCount;
  478. etiTemp.dwDecode_Acbk = (etiTemp.dwDecode_Acbk + (iCount / 2)) / iCount;
  479. etiTemp.dwReconstr_Excit = (etiTemp.dwReconstr_Excit + (iCount / 2)) / iCount;
  480. etiTemp.dwUpd_Ring = (etiTemp.dwUpd_Ring + (iCount / 2)) / iCount;
  481. etiTemp.dwLine_Pack = (etiTemp.dwLine_Pack + (iCount / 2)) / iCount;
  482. #endif // } DETAILED_ENCODE_TIMINGS_ON
  483. /* Output the average information
  484. */
  485. fprintf(pFile,"Average over %d frames\n", iCount);
  486. OutputEncTimingDetail(pFile, &etiTemp);
  487. }
  488. fclose(pFile);
  489. done:
  490. return;
  491. }
  492. void OutputEncTimingDetail(FILE * pFile, ENC_TIMING_INFO * pEncTimingInfo)
  493. {
  494. unsigned long dwOther;
  495. unsigned long dwRoundUp;
  496. unsigned long dwDivisor;
  497. fprintf(pFile, "\tEncode = %10u (%d milliseconds at 166Mhz)\n", pEncTimingInfo->dwEncode,
  498. (pEncTimingInfo->dwEncode + 83000) / 166000);
  499. dwOther = pEncTimingInfo->dwEncode;
  500. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  501. /* This is needed because of the integer truncation.
  502. */
  503. dwDivisor = pEncTimingInfo->dwEncode / 100; // to yield a percent
  504. dwRoundUp = dwDivisor / 2;
  505. if (dwDivisor)
  506. {
  507. fprintf(pFile, "\tRem_Dc = %10u (%2d%%)\n", pEncTimingInfo->dwRem_Dc,
  508. (pEncTimingInfo->dwRem_Dc + dwRoundUp) / dwDivisor);
  509. dwOther -= pEncTimingInfo->dwRem_Dc;
  510. fprintf(pFile, "\tComp_Lpc = %10u (%2d%%)\n", pEncTimingInfo->dwComp_Lpc,
  511. (pEncTimingInfo->dwComp_Lpc + dwRoundUp) / dwDivisor);
  512. dwOther -= pEncTimingInfo->dwComp_Lpc;
  513. fprintf(pFile, "\tAtoLsp = %10u (%2d%%)\n", pEncTimingInfo->dwAtoLsp,
  514. (pEncTimingInfo->dwAtoLsp + dwRoundUp) / dwDivisor);
  515. dwOther -= pEncTimingInfo->dwAtoLsp;
  516. fprintf(pFile, "\tLsp_Qnt = %10u (%2d%%)\n", pEncTimingInfo->dwLsp_Qnt,
  517. (pEncTimingInfo->dwLsp_Qnt + dwRoundUp) / dwDivisor);
  518. dwOther -= pEncTimingInfo->dwLsp_Qnt;
  519. fprintf(pFile, "\tLsp_Inq = %10u (%2d%%)\n", pEncTimingInfo->dwLsp_Inq,
  520. (pEncTimingInfo->dwLsp_Inq + dwRoundUp) / dwDivisor);
  521. dwOther -= pEncTimingInfo->dwLsp_Inq;
  522. fprintf(pFile, "\tLsp_Int = %10u (%2d%%)\n", pEncTimingInfo->dwLsp_Int,
  523. (pEncTimingInfo->dwLsp_Int + dwRoundUp) / dwDivisor);
  524. dwOther -= pEncTimingInfo->dwLsp_Int;
  525. fprintf(pFile, "\tMem_Shift = %10u (%2d%%)\n", pEncTimingInfo->dwMem_Shift,
  526. (pEncTimingInfo->dwMem_Shift + dwRoundUp) / dwDivisor);
  527. dwOther -= pEncTimingInfo->dwMem_Shift;
  528. fprintf(pFile, "\tWght_Lpc = %10u (%2d%%)\n", pEncTimingInfo->dwWght_Lpc,
  529. (pEncTimingInfo->dwWght_Lpc + dwRoundUp) / dwDivisor);
  530. dwOther -= pEncTimingInfo->dwWght_Lpc;
  531. fprintf(pFile, "\tError_Wght = %10u (%2d%%)\n", pEncTimingInfo->dwError_Wght,
  532. (pEncTimingInfo->dwError_Wght + dwRoundUp) / dwDivisor);
  533. dwOther -= pEncTimingInfo->dwError_Wght;
  534. fprintf(pFile, "\tFew_Lps_In_Coder = %10u (%2d%%)\n", pEncTimingInfo->dwFew_Lps_In_Coder,
  535. (pEncTimingInfo->dwFew_Lps_In_Coder + dwRoundUp) / dwDivisor);
  536. dwOther -= pEncTimingInfo->dwFew_Lps_In_Coder;
  537. fprintf(pFile, "\tFilt_Pw = %10u (%2d%%)\n", pEncTimingInfo->dwFilt_Pw,
  538. (pEncTimingInfo->dwFilt_Pw + dwRoundUp) / dwDivisor);
  539. dwOther -= pEncTimingInfo->dwFilt_Pw;
  540. fprintf(pFile, "\tComp_Ir = %10u (%2d%%)\n", pEncTimingInfo->dwComp_Ir,
  541. (pEncTimingInfo->dwComp_Ir + dwRoundUp) / dwDivisor);
  542. dwOther -= pEncTimingInfo->dwComp_Ir;
  543. fprintf(pFile, "\tSub_Ring = %10u (%2d%%)\n", pEncTimingInfo->dwSub_Ring,
  544. (pEncTimingInfo->dwSub_Ring + dwRoundUp) / dwDivisor);
  545. dwOther -= pEncTimingInfo->dwSub_Ring;
  546. fprintf(pFile, "\tFind_Acbk = %10u (%2d%%)\n", pEncTimingInfo->dwFind_Acbk,
  547. (pEncTimingInfo->dwFind_Acbk + dwRoundUp) / dwDivisor);
  548. dwOther -= pEncTimingInfo->dwFind_Acbk;
  549. fprintf(pFile, "\tFind_Fcbk = %10u (%2d%%)\n", pEncTimingInfo->dwFind_Fcbk,
  550. (pEncTimingInfo->dwFind_Fcbk + dwRoundUp) / dwDivisor);
  551. dwOther -= pEncTimingInfo->dwFind_Fcbk;
  552. fprintf(pFile, "\tDecode_Acbk = %10u (%2d%%)\n", pEncTimingInfo->dwDecode_Acbk,
  553. (pEncTimingInfo->dwDecode_Acbk + dwRoundUp) / dwDivisor);
  554. dwOther -= pEncTimingInfo->dwDecode_Acbk;
  555. fprintf(pFile, "\tReconstr_Excit = %10u (%2d%%)\n", pEncTimingInfo->dwReconstr_Excit,
  556. (pEncTimingInfo->dwReconstr_Excit + dwRoundUp) / dwDivisor);
  557. dwOther -= pEncTimingInfo->dwReconstr_Excit;
  558. fprintf(pFile, "\tUpd_Ring = %10u (%2d%%)\n", pEncTimingInfo->dwUpd_Ring,
  559. (pEncTimingInfo->dwUpd_Ring + dwRoundUp) / dwDivisor);
  560. dwOther -= pEncTimingInfo->dwUpd_Ring;
  561. fprintf(pFile, "\tLine_Pack = %10u (%2d%%)\n", pEncTimingInfo->dwLine_Pack,
  562. (pEncTimingInfo->dwLine_Pack + dwRoundUp) / dwDivisor);
  563. dwOther -= pEncTimingInfo->dwLine_Pack;
  564. fprintf(pFile, "\tOther = %10u (%2d%%)\n", dwOther,
  565. (dwOther + dwRoundUp) / dwDivisor);
  566. }
  567. #endif // } DETAILED_ENCODE_TIMINGS_ON
  568. }
  569. #endif // { LOG_ENCODE_TIMINGS_ON