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.

604 lines
14 KiB

  1. //==========================================================================
  2. //
  3. // tsm.cpp --
  4. //
  5. // Copyright (c) 2000 Microsoft Corp.
  6. // Copyright (c) 1998 Entropic, Inc.
  7. // Copyright (c) 1993 Entropic Research Laboratory, Inc.
  8. // Copyright (c) 1991-1992 Massachusetts Institute of Technology
  9. //
  10. // WARNING: THE TECHNIQUE USED IN THIS CODE HAS A UNITED STATES PATENT
  11. // PENDING.
  12. //
  13. //==========================================================================
  14. #include "tsm.h"
  15. #include "vapiio.h"
  16. #include <stdlib.h>
  17. #include <assert.h>
  18. static const char *mitcy = "@(#)Copyright (c) 1991-1992, "
  19. "Massachusetts Institute of Technology\n@(#)All rights reserved";
  20. //--------------------------------------------------------------------------
  21. //
  22. //
  23. //
  24. //--------------------------------------------------------------------------
  25. CTsm::CTsm (double timeScale, int iSampFreq, int* piFrameLen, int* piFrameShift)
  26. {
  27. double sampFreqFactor;
  28. assert (iSampFreq>0);
  29. assert (timeScale>0.0);
  30. m_dScale = timeScale;
  31. m_iWinLen = 120;
  32. m_iShiftAna = 80;
  33. m_iShiftSyn = 80;
  34. m_iShiftMax = 100;
  35. sampFreqFactor = iSampFreq/8000.0;
  36. m_iWinLen = (int) (m_iWinLen * sampFreqFactor);
  37. m_iShiftAna = (int) (m_iShiftAna * sampFreqFactor);
  38. m_iShiftSyn = (int) (m_iShiftSyn * sampFreqFactor);
  39. m_iShiftMax = (int) (m_iShiftMax * sampFreqFactor);
  40. m_iFrameLen = m_iWinLen + m_iShiftMax;
  41. m_iFrameShift = (int) (m_iShiftAna * timeScale);
  42. m_iNumPts = m_iWinLen - m_iShiftSyn;
  43. m_pfOldTail = new double[m_iFrameLen];
  44. if ( piFrameLen && piFrameShift )
  45. {
  46. if ( m_pfOldTail==NULL)
  47. {
  48. *piFrameLen = 0;
  49. *piFrameShift = 0;
  50. }
  51. else
  52. {
  53. *piFrameLen = m_iFrameLen;
  54. *piFrameShift = m_iFrameShift;
  55. }
  56. }
  57. }
  58. //--------------------------------------------------------------------------
  59. //
  60. //
  61. //
  62. //--------------------------------------------------------------------------
  63. CTsm::~CTsm ()
  64. {
  65. assert (m_pfOldTail);
  66. if (m_pfOldTail)
  67. {
  68. delete[] m_pfOldTail;
  69. }
  70. }
  71. //--------------------------------------------------------------------------
  72. //
  73. //
  74. //
  75. //--------------------------------------------------------------------------
  76. int CTsm::SetScaleFactor (double timeScale)
  77. {
  78. assert (timeScale>0.0);
  79. m_dScale = timeScale;
  80. if (timeScale > 0.0)
  81. {
  82. m_iFrameShift = (int) (m_iShiftAna * timeScale);
  83. }
  84. return m_iFrameShift;
  85. }
  86. //--------------------------------------------------------------------------
  87. //
  88. // Returns iSampFreq if successful
  89. //
  90. //--------------------------------------------------------------------------
  91. int CTsm::SetSamplingFrequency (int iSampFreq)
  92. {
  93. double sampFreqFactor;
  94. assert (iSampFreq>0.0);
  95. m_iWinLen = 120;
  96. m_iShiftAna = 80;
  97. m_iShiftSyn = 80;
  98. m_iShiftMax = 100;
  99. sampFreqFactor = iSampFreq/8000.0;
  100. m_iWinLen = (int) (m_iWinLen * sampFreqFactor);
  101. m_iShiftAna = (int) (m_iShiftAna * sampFreqFactor);
  102. m_iShiftSyn = (int) (m_iShiftSyn * sampFreqFactor);
  103. m_iShiftMax = (int) (m_iShiftMax * sampFreqFactor);
  104. m_iFrameLen = m_iWinLen + m_iShiftMax;
  105. m_iFrameShift = (int) (m_iShiftAna * m_dScale);
  106. m_iNumPts = m_iWinLen - m_iShiftSyn;
  107. if ( m_pfOldTail )
  108. {
  109. delete [] m_pfOldTail;
  110. m_pfOldTail = NULL;
  111. }
  112. m_pfOldTail = new double[m_iFrameLen];
  113. if ( m_pfOldTail )
  114. {
  115. return iSampFreq;
  116. }
  117. else
  118. {
  119. return 0;
  120. }
  121. }
  122. //--------------------------------------------------------------------------
  123. //
  124. //
  125. //
  126. //--------------------------------------------------------------------------
  127. int CTsm::FirstFrame (double* buffer)
  128. {
  129. int i;
  130. assert (buffer);
  131. for (i = 0; i < m_iNumPts; i++)
  132. {
  133. m_pfOldTail[i] = buffer[m_iShiftSyn+i];
  134. }
  135. m_iLag = 0;
  136. return m_iShiftSyn;
  137. }
  138. //--------------------------------------------------------------------------
  139. //
  140. //
  141. //
  142. //--------------------------------------------------------------------------
  143. int CTsm::AddFrame (double* buffer, int* lag, int* nSamp)
  144. {
  145. int i;
  146. int prevLag;
  147. assert (buffer);
  148. prevLag = m_iLag + m_iShiftSyn - m_iFrameShift;
  149. if ( (0 <= prevLag) && (prevLag <= m_iShiftMax))
  150. {
  151. m_iLag = prevLag;
  152. }
  153. else
  154. {
  155. m_iLag = Crosscor(m_pfOldTail, buffer, m_iShiftMax, m_iNumPts);
  156. }
  157. // This loop is the overlap-add step
  158. for (i=0; i<m_iNumPts; i++)
  159. {
  160. buffer[m_iLag+i] = ((m_pfOldTail[i] * (m_iNumPts - i)) + (buffer[m_iLag+i] * i)) / m_iNumPts;
  161. }
  162. *lag = m_iLag;
  163. *nSamp = m_iShiftSyn;
  164. for (i=0; i<m_iNumPts; i++)
  165. {
  166. m_pfOldTail[i] = buffer[m_iLag + m_iShiftSyn + i];
  167. }
  168. return (m_iLag + m_iShiftSyn);
  169. }
  170. //--------------------------------------------------------------------------
  171. //
  172. //
  173. //
  174. //--------------------------------------------------------------------------
  175. int CTsm::LastFrame (double* buffer, int buffLen, int* lag, int *nSamp)
  176. {
  177. int i;
  178. assert (buffer);
  179. assert (buffLen>0);
  180. assert (lag);
  181. assert (nSamp);
  182. for (i=0; i<m_iNumPts && i < buffLen; i++)
  183. {
  184. buffer[i] = ((m_pfOldTail[i] * (m_iNumPts - i)) + (buffer[i] * i)) / m_iNumPts;
  185. }
  186. *lag = 0;
  187. *nSamp = buffLen;
  188. return buffLen;
  189. }
  190. //--------------------------------------------------------------------------
  191. //
  192. //
  193. //
  194. //--------------------------------------------------------------------------
  195. int CTsm::Crosscor(double* oldwin, double* newwin, int kmax, int numPts)
  196. {
  197. double xcor;
  198. double xcormax;
  199. double numer;
  200. double denom;
  201. double *rgdenom=NULL;
  202. int bestk;
  203. int k;
  204. int i;
  205. bestk = 0;
  206. xcormax = 0.0;
  207. denom = 0.0;
  208. if (NULL == (rgdenom = new double[kmax+numPts+1]))
  209. return 0;
  210. // Precalculate the denominator values. The denominator is the sum of the square of a set of
  211. // newwin samples, so square all of them, and sum the appropriate set. We're calculating one
  212. // extra because the update goes one beyond the last window.
  213. for (k=0; k <numPts+kmax+1; k++)
  214. {
  215. rgdenom[k] = newwin[k] * newwin[k];
  216. }
  217. for (k=0; k < numPts; k++)
  218. {
  219. denom += rgdenom[k];
  220. }
  221. for (k=0; k <= kmax; k++)
  222. {
  223. numer = 0.0;
  224. for (i = 0; i < numPts; i++)
  225. {
  226. numer += oldwin[i] * newwin[k+i];
  227. }
  228. // A shift can only be the best if the correlation is positive.
  229. if (numer > 0)
  230. {
  231. xcor = (numer * numer)/denom;
  232. if (xcor > xcormax)
  233. {
  234. xcormax = xcor;
  235. bestk = k;
  236. }
  237. }
  238. // Shift the denomination window one sample
  239. denom = denom - rgdenom[k] + rgdenom[k + numPts];
  240. }
  241. delete rgdenom;
  242. return bestk;
  243. }
  244. //--------------------------------------------------------------------------
  245. //
  246. // Adjusts time scale putting resulting samples in ppvOutSamples.
  247. // Converts format if necessary.
  248. //
  249. //---------------------------------------------------------- JOEM 01/2001 --
  250. int CTsm::AdjustTimeScale(const void* pvInSamples, const int iNumInSamples,
  251. void** ppvOutSamples, int* piNumOutSamples, WAVEFORMATEX* pFormat )
  252. {
  253. char* pcSamples = NULL;
  254. short* pnSamples = NULL;
  255. short* pnOutSamples = NULL;
  256. double* pdBuffer = NULL;
  257. int iFrameLen = 0;
  258. int iFrameShift = 0;
  259. int firstSample = 0;
  260. int lag = 0;
  261. int lastSamp = 0;
  262. bool fSamplesEnd = false;
  263. int i = 0;
  264. if ( iNumInSamples <= m_iFrameLen )
  265. {
  266. goto error;
  267. }
  268. int iInFormatType = VapiIO::TypeOf (pFormat);
  269. if ( iInFormatType == VAPI_ALAW || iInFormatType == VAPI_ULAW )
  270. {
  271. //--- Convert samples to VAPI_PCM16
  272. pnSamples = new short [iNumInSamples];
  273. if ( !pnSamples )
  274. {
  275. goto error;
  276. }
  277. if ( 0 == VapiIO::DataFormatConversion ((char *)pvInSamples, iInFormatType, (char*)pnSamples, VAPI_PCM16, iNumInSamples) )
  278. {
  279. goto error;
  280. }
  281. }
  282. else if ( iInFormatType == VAPI_PCM8 )
  283. {
  284. // cast to char
  285. pcSamples = (char*) pvInSamples;
  286. }
  287. else if ( iInFormatType == VAPI_PCM16 )
  288. {
  289. // cast to short
  290. pnSamples = (short*) pvInSamples;
  291. }
  292. else
  293. {
  294. goto error;
  295. }
  296. iFrameLen = m_iFrameLen;
  297. iFrameShift = m_iFrameShift;
  298. // pdBuffer big enough for one frame
  299. pdBuffer = new double[iFrameLen];
  300. if ( !pdBuffer )
  301. {
  302. goto error;
  303. }
  304. // new data buffer overestimates the size that might be needed.
  305. // Actual sample count is accumulated below.
  306. // make SURE to overestimate the number of samples needed, so arbitrarily
  307. // add 1 to the rate before multiplying the sample count.
  308. double dRate = 1.0/m_dScale + 1;
  309. *piNumOutSamples = (int) ( dRate * iNumInSamples );
  310. pnOutSamples = new short[*piNumOutSamples];
  311. if ( !pnOutSamples )
  312. {
  313. goto error;
  314. }
  315. int iSamp = 0;
  316. // First frame to process
  317. if ( pcSamples )
  318. {
  319. for ( i=0; i<iFrameLen; i++ )
  320. {
  321. pdBuffer[i] = (double) pcSamples[i];
  322. }
  323. }
  324. else if ( pnSamples )
  325. {
  326. for ( i=0; i<iFrameLen; i++ )
  327. {
  328. pdBuffer[i] = (double) pnSamples[i];
  329. }
  330. }
  331. else
  332. {
  333. goto error;
  334. }
  335. lastSamp = FirstFrame(pdBuffer);
  336. if ( pcSamples )
  337. {
  338. for ( i=0; i<lastSamp; i++ )
  339. {
  340. pnOutSamples[i] = (short) pcSamples[i];
  341. }
  342. }
  343. else if ( pnSamples )
  344. {
  345. for ( i=0; i<lastSamp; i++ )
  346. {
  347. pnOutSamples[i] = pnSamples[i];
  348. }
  349. }
  350. else
  351. {
  352. goto error;
  353. }
  354. *piNumOutSamples = lastSamp;
  355. // LOOP OVER FRAMES
  356. while ( !fSamplesEnd )
  357. {
  358. if ( pcSamples )
  359. {
  360. for ( i=0; i<iFrameLen; i++ )
  361. {
  362. if ( firstSample + i < iNumInSamples )
  363. {
  364. pdBuffer[i] = (double) pcSamples[firstSample + i];
  365. }
  366. else
  367. {
  368. iFrameLen = i;
  369. fSamplesEnd = true;
  370. break;
  371. }
  372. }
  373. }
  374. else if ( pnSamples )
  375. {
  376. for ( i=0; i<iFrameLen; i++ )
  377. {
  378. if ( firstSample + i < iNumInSamples )
  379. {
  380. pdBuffer[i] = (double) pnSamples[firstSample + i];
  381. }
  382. else
  383. {
  384. iFrameLen = i;
  385. fSamplesEnd = true;
  386. break;
  387. }
  388. }
  389. }
  390. else
  391. {
  392. goto error;
  393. }
  394. if ( fSamplesEnd )
  395. {
  396. if ( iFrameLen > 0 )
  397. {
  398. lastSamp = LastFrame (pdBuffer, iFrameLen, &lag, &iSamp);
  399. }
  400. else
  401. {
  402. iSamp = 0; lag = 0;
  403. }
  404. }
  405. else
  406. {
  407. lastSamp = AddFrame (pdBuffer, &lag, &iSamp);
  408. }
  409. for ( i=0; i<iSamp; i++ )
  410. {
  411. pnOutSamples[i+*piNumOutSamples] = (short)(pdBuffer[i+lag]);
  412. }
  413. *piNumOutSamples += iSamp;
  414. firstSample += iFrameShift;
  415. }
  416. // Flush the remaining samples
  417. if ( iFrameLen > lastSamp )
  418. {
  419. for ( i=0; i < iFrameLen - lastSamp; i++ )
  420. {
  421. pnOutSamples[i+*piNumOutSamples] = (short)pdBuffer[i+lastSamp];
  422. }
  423. *piNumOutSamples += ( iFrameLen - lastSamp );
  424. }
  425. if ( pdBuffer )
  426. {
  427. delete [] pdBuffer;
  428. pdBuffer = NULL;
  429. }
  430. if ( pnSamples && pnSamples != pvInSamples ) // might have allocated, or might have just cast.
  431. {
  432. delete [] pnSamples;
  433. pnSamples = NULL;
  434. }
  435. // DO WE NEED TO CONVERT BACK?
  436. if ( iInFormatType == VAPI_ALAW )
  437. {
  438. //--- Convert samples back
  439. *ppvOutSamples = new char [*piNumOutSamples];
  440. if ( !*ppvOutSamples )
  441. {
  442. goto error;
  443. }
  444. if ( 0 == VapiIO::DataFormatConversion ((char*)pnOutSamples, VAPI_PCM16, (char*)*ppvOutSamples, iInFormatType, *piNumOutSamples) )
  445. {
  446. goto error;
  447. }
  448. delete [] pnOutSamples;
  449. pnOutSamples = NULL;
  450. }
  451. if ( iInFormatType == VAPI_ULAW )
  452. {
  453. //--- Convert samples back
  454. *ppvOutSamples = new char [*piNumOutSamples];
  455. if ( !*ppvOutSamples )
  456. {
  457. goto error;
  458. }
  459. if ( 0 == VapiIO::DataFormatConversion ((char*)pnOutSamples, VAPI_PCM16, (char*)*ppvOutSamples, iInFormatType, *piNumOutSamples) )
  460. {
  461. goto error;
  462. }
  463. delete [] pnOutSamples;
  464. pnOutSamples = NULL;
  465. }
  466. if ( iInFormatType == VAPI_PCM8 )
  467. {
  468. //--- Convert samples back
  469. *ppvOutSamples = new char [*piNumOutSamples];
  470. if ( !*ppvOutSamples )
  471. {
  472. goto error;
  473. }
  474. if ( 0 == VapiIO::DataFormatConversion ((char*)pnOutSamples, VAPI_PCM16, (char*)*ppvOutSamples, iInFormatType, *piNumOutSamples) )
  475. {
  476. goto error;
  477. }
  478. delete [] pnOutSamples;
  479. pnOutSamples = NULL;
  480. }
  481. else if ( iInFormatType == VAPI_PCM16 )
  482. {
  483. *ppvOutSamples = pnOutSamples; // blocksize is already short
  484. }
  485. else
  486. {
  487. return 0;
  488. }
  489. return 1;
  490. error:
  491. if ( pnSamples && pnSamples != pvInSamples ) // might have allocated, or might have just cast.
  492. {
  493. delete [] pnSamples;
  494. }
  495. if ( pnOutSamples )
  496. {
  497. delete [] pnOutSamples;
  498. }
  499. if ( pdBuffer )
  500. {
  501. delete [] pdBuffer;
  502. }
  503. if ( *ppvOutSamples )
  504. {
  505. delete [] (*ppvOutSamples);
  506. *ppvOutSamples = NULL;
  507. }
  508. return 0;
  509. }