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.

806 lines
19 KiB

  1. /******************************************************************************
  2. * tips.cpp *
  3. *----------*
  4. *
  5. *------------------------------------------------------------------------------
  6. * Copyright (c) 1996-1997 Entropic Research Laboratory, Inc.
  7. * Copyright (C) 1998 Entropic, Inc
  8. * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00-12/4/00
  9. * All Rights Reserved
  10. *
  11. ********************************************************************* mplumpe was PACOG ***/
  12. #include "tips.h"
  13. #include "SynthUnit.h"
  14. #include "sigproc.h"
  15. #include <vapiIo.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>
  20. #include <limits.h>
  21. #include <assert.h>
  22. #include "ftol.h"
  23. const double CTips::m_iDefaultPeriod = .01; //10 msec.
  24. const double CTips::m_dMinF0 = 15.0; // Absolute minimum F0 alowed
  25. const int CTips::m_iHalfHanLen_c = 1024;
  26. /*****************************************************************************
  27. * CTips::CTips *
  28. *--------------*
  29. * Description:
  30. *
  31. ******************************************************************* PACOG ***/
  32. CTips::CTips (int iOptions)
  33. {
  34. m_fLptips = (bool) (iOptions & LpTips);
  35. m_fRtips = (iOptions & RTips) != 0;
  36. m_iSampFormat = 0;
  37. m_iSampFreq = 0;
  38. m_dGain = 1.0;
  39. m_pfF0 = 0;
  40. m_iNumF0 = 0;
  41. m_dRunTime = 0.0;
  42. m_dF0SampFreq = 0.0;
  43. m_dF0TimeNext = 0.0;
  44. m_dF0TimeStep = 0.0;
  45. m_dF0Value = 0.0;
  46. m_dAcumF0 = 0.0;
  47. m_iF0Idx = 0;
  48. m_dLastEpochTime = 0.0;
  49. m_dNewEpochTime = 0.0;
  50. m_aBuffer[0].m_pdSamples = 0;
  51. m_aBuffer[1].m_pdSamples = 0;
  52. m_iLpcOrder = 0;
  53. m_pdFiltMem = 0;
  54. m_pdInterpCoef = 0;
  55. m_pdLastCoef = 0;
  56. m_pUnit = 0;
  57. m_psSynthSamples = 0;
  58. m_iNumSynthSamples = 0;
  59. m_adHalfHanning = 0;
  60. }
  61. /*****************************************************************************
  62. * CTips::~CTips *
  63. *---------------*
  64. * Description:
  65. *
  66. ******************************************************************* mplumpe ***/
  67. CTips::~CTips ()
  68. {
  69. if (m_pdFiltMem)
  70. {
  71. delete[] m_pdFiltMem;
  72. }
  73. if (m_pdInterpCoef)
  74. {
  75. delete[] m_pdInterpCoef;
  76. }
  77. if (m_pdLastCoef)
  78. {
  79. delete[] m_pdLastCoef;
  80. }
  81. if (m_aBuffer[0].m_pdSamples)
  82. {
  83. delete[] m_aBuffer[0].m_pdSamples;
  84. }
  85. if (m_aBuffer[1].m_pdSamples)
  86. {
  87. delete[] m_aBuffer[1].m_pdSamples;
  88. }
  89. if (m_psSynthSamples)
  90. {
  91. delete[] m_psSynthSamples;
  92. }
  93. if (m_adHalfHanning)
  94. {
  95. delete [] m_adHalfHanning;
  96. }
  97. }
  98. /*****************************************************************************
  99. * CTips::Init *
  100. *-------------*
  101. * Description:
  102. *
  103. ******************************************************************* mplumpe ***/
  104. int CTips::Init (int iSampFormat, int iSampFreq)
  105. {
  106. int i;
  107. assert (iSampFreq>0);
  108. m_iSampFreq = iSampFreq;
  109. m_iSampFormat = iSampFormat;
  110. int iPeriodLen = (int) (iSampFreq * m_iDefaultPeriod);
  111. // Delete old buffers, if they exist
  112. if (m_aBuffer[0].m_pdSamples)
  113. {
  114. delete[] m_aBuffer[0].m_pdSamples;
  115. }
  116. if (m_aBuffer[1].m_pdSamples)
  117. {
  118. delete[] m_aBuffer[1].m_pdSamples;
  119. }
  120. // Allocate new ones, and initialize them to Zero.
  121. // NOTE: Only need to allocate buffer[1], really, since they'll be rotated before
  122. // synthesis.
  123. if ((m_aBuffer[0].m_pdSamples = new double[2 * iPeriodLen]) == 0 )
  124. {
  125. return 0;
  126. }
  127. //memset(m_aBuffer[0].m_pdSamples, 0, sizeof(double) * 2 * iPeriodLen);
  128. if ((m_aBuffer[1].m_pdSamples = new double [2 * iPeriodLen]) == 0)
  129. {
  130. return 0;
  131. }
  132. memset(m_aBuffer[1].m_pdSamples, 0, sizeof(double) * 2 * iPeriodLen);
  133. m_aBuffer[0].m_iNumSamples = 2 * iPeriodLen;
  134. m_aBuffer[0].m_iCenter = iPeriodLen;
  135. m_aBuffer[0].m_dDelay = 0.0;
  136. m_aBuffer[1].m_iNumSamples = 2 * iPeriodLen;
  137. m_aBuffer[1].m_iCenter = iPeriodLen;
  138. m_aBuffer[1].m_dDelay = 0.0;
  139. //
  140. // make Hanning buffer
  141. //
  142. if (m_adHalfHanning)
  143. {
  144. delete m_adHalfHanning;
  145. }
  146. if ((m_adHalfHanning = new double [m_iHalfHanLen_c]) == 0)
  147. {
  148. return 0;
  149. }
  150. for (i=0; i < m_iHalfHanLen_c; i++)
  151. {
  152. m_adHalfHanning[i] = 0.5-0.5*cos(M_PI*i/m_iHalfHanLen_c);
  153. }
  154. if (m_fLptips)
  155. {
  156. return LpcInit();
  157. }
  158. return 1;
  159. }
  160. /*****************************************************************************
  161. * CTips::SetGain *
  162. *----------------*
  163. * Description:
  164. *
  165. ******************************************************************* PACOG ***/
  166. void CTips::SetGain (double dGain)
  167. {
  168. assert (dGain>=0.0);
  169. m_dGain = dGain;
  170. }
  171. /*****************************************************************************
  172. * CTips::GetGain *
  173. *----------------*
  174. * Description:
  175. *
  176. ******************************************************************* PACOG ***/
  177. double CTips::GetGain ()
  178. {
  179. return m_dGain;
  180. }
  181. /*****************************************************************************
  182. * CTips::NewSentence *
  183. *--------------------*
  184. * Description:
  185. *
  186. ******************************************************************* PACOG ***/
  187. void CTips::NewSentence (float* pfF0, int iNumF0, int iF0SampFreq)
  188. {
  189. assert (pfF0);
  190. assert (iNumF0>0);
  191. assert (iF0SampFreq>0);
  192. m_pfF0 = pfF0;
  193. m_iNumF0 = iNumF0;
  194. m_dF0SampFreq = iF0SampFreq;
  195. m_dF0TimeStep = 1.0/iF0SampFreq;
  196. m_dRunTime = 0.0;
  197. m_dF0TimeNext = 0.0;
  198. m_dAcumF0 = 0.0;
  199. m_iF0Idx = 0;
  200. m_dLastEpochTime = 0.0;
  201. m_dNewEpochTime = 0.0;
  202. }
  203. /*****************************************************************************
  204. * CTips::NewUnit *
  205. *----------------*
  206. * Description:
  207. * Gets a new unit to synthesize, and does some analysis on it.
  208. ******************************************************************* PACOG ***/
  209. int CTips::NewUnit (CSynth* pUnit)
  210. {
  211. if (pUnit)
  212. {
  213. m_pUnit = pUnit;
  214. if (m_fLptips)
  215. {
  216. if (!m_pUnit->LpcAnalysis(m_iSampFreq, m_iLpcOrder))
  217. {
  218. return 0;
  219. }
  220. }
  221. if ( Prosody (pUnit) == -1)
  222. {
  223. return 0;
  224. }
  225. return 1;
  226. }
  227. return 0;
  228. }
  229. /*****************************************************************************
  230. * CTips::Prosody *
  231. *----------------*
  232. * Description:
  233. * We get synthesis epochs track for a segment. F0 curve integration is
  234. * therefore carried out here. The sampling frequency chosen is high enough
  235. * as to reduce jitter to an umperceivable level, but that depends on the
  236. * synthesis module being capable of synthesizing at that interval.
  237. *
  238. ******************************************************************* PACOG ***/
  239. int CTips::Prosody ( CSynth* pUnit )
  240. {
  241. double dF0IntegralTime = 0.0;
  242. assert (m_pfF0 && m_iNumF0>0);
  243. if (m_dNewEpochTime != m_dLastEpochTime)
  244. {
  245. if ((pUnit->m_pdSynEpochs = new double[2]) == 0)
  246. {
  247. return -1;
  248. }
  249. pUnit->m_pdSynEpochs[0] = m_dLastEpochTime;
  250. pUnit->m_pdSynEpochs[1] = m_dNewEpochTime;
  251. pUnit->m_iNumSynEpochs = 2;
  252. }
  253. else
  254. {
  255. if ((pUnit->m_pdSynEpochs = new double[1]) == 0)
  256. {
  257. return -1;
  258. }
  259. pUnit->m_pdSynEpochs[0] = m_dNewEpochTime;
  260. pUnit->m_iNumSynEpochs = 1;
  261. }
  262. while ( m_dRunTime < pUnit->m_dRunTimeLimit ||
  263. // Find an extra epoch, for the overlapping period
  264. // if the last epoch doesn't already cross the segment limit
  265. pUnit->m_pdSynEpochs[pUnit->m_iNumSynEpochs-1] < pUnit->m_dRunTimeLimit)
  266. {
  267. if (m_dRunTime >= m_dF0TimeNext)
  268. {
  269. m_dF0Value = m_pfF0[m_iF0Idx];
  270. if (m_iF0Idx < m_iNumF0-1)
  271. {
  272. m_iF0Idx++;
  273. }
  274. if (m_dF0Value<=0.0)
  275. {
  276. m_dF0Value = 100.0; // Best choice is f0=100Hz
  277. }
  278. else if (m_dF0Value <= m_dMinF0)
  279. {
  280. m_dF0Value = m_dMinF0;
  281. }
  282. m_dF0TimeNext += m_dF0TimeStep;
  283. }
  284. dF0IntegralTime = (1.0 - m_dAcumF0) / m_dF0Value;
  285. if (dF0IntegralTime >= m_dF0TimeStep)
  286. {
  287. m_dRunTime += m_dF0TimeStep;
  288. m_dAcumF0 += m_dF0Value * m_dF0TimeStep;
  289. }
  290. else
  291. {
  292. m_dRunTime += dF0IntegralTime;
  293. m_dAcumF0 = 0;
  294. //Got epoch
  295. m_dLastEpochTime = m_dNewEpochTime;
  296. m_dNewEpochTime = m_dRunTime;
  297. //Reallocate the synthesis epochs array
  298. double* pdSynEpochs = new double[pUnit->m_iNumSynEpochs + 1];
  299. if (!pdSynEpochs)
  300. {
  301. return -1;
  302. }
  303. memcpy(pdSynEpochs, pUnit->m_pdSynEpochs, pUnit->m_iNumSynEpochs * sizeof(double));
  304. delete[] pUnit->m_pdSynEpochs;
  305. pUnit->m_pdSynEpochs = pdSynEpochs;
  306. // And add a new epoch
  307. pUnit->m_pdSynEpochs[pUnit->m_iNumSynEpochs] = m_dNewEpochTime;
  308. pUnit->m_iNumSynEpochs++;
  309. }
  310. }
  311. if (pUnit->m_iNumSynEpochs <3)
  312. {
  313. delete[] pUnit->m_pdSynEpochs;
  314. pUnit->m_pdSynEpochs = 0;
  315. return 0;
  316. }
  317. // Synthesis epochs are in absolute synthesis time
  318. double epStartTime = ((long)(pUnit->m_pdSynEpochs[0] * m_iSampFreq)) / (double)m_iSampFreq;
  319. for (int i=0; i<pUnit->m_iNumSynEpochs; i++)
  320. {
  321. pUnit->m_pdSynEpochs[i] -= epStartTime;
  322. }
  323. return pUnit->FindPrecedent ();
  324. }
  325. /*****************************************************************************
  326. * CTips::Pending *
  327. *----------------*
  328. * Description:
  329. *
  330. ******************************************************************* PACOG ***/
  331. int CTips::Pending ()
  332. {
  333. return m_pUnit != 0;
  334. }
  335. /*****************************************************************************
  336. * CTips::NextPeriod *
  337. *-------------------*
  338. * Description:
  339. *
  340. ******************************************************************* PACOG ***/
  341. int CTips::NextPeriod (short** ppnSamples, int *piNumSamples)
  342. {
  343. int iPeriodLen;
  344. assert (ppnSamples && piNumSamples> 0);
  345. if (m_pUnit)
  346. {
  347. iPeriodLen = m_pUnit->NextBuffer (this);
  348. if ( iPeriodLen > 0 )
  349. {
  350. Synthesize (iPeriodLen);
  351. *ppnSamples = m_psSynthSamples;
  352. *piNumSamples = iPeriodLen;
  353. return 1;
  354. }
  355. else
  356. {
  357. delete m_pUnit;
  358. m_pUnit = 0;
  359. }
  360. }
  361. return 0;
  362. }
  363. /*****************************************************************************
  364. * CTips::FillBuffer *
  365. *-------------------*
  366. * Description:
  367. *
  368. ******************************************************************* PACOG ***/
  369. int CTips::SetBuffer ( double* pdSamples, int iNumSamples, int iCenter, double dDelay, double* pdLpcCoef)
  370. {
  371. // Advance buffers
  372. delete[] m_aBuffer[0].m_pdSamples;
  373. m_aBuffer[0] = m_aBuffer[1];
  374. m_aBuffer[1].m_pdSamples = pdSamples;
  375. m_aBuffer[1].m_iNumSamples = iNumSamples;
  376. m_aBuffer[1].m_iCenter = iCenter;
  377. m_aBuffer[1].m_dDelay = dDelay;
  378. m_pdNewCoef = pdLpcCoef;
  379. return 1;
  380. }
  381. /*****************************************************************************
  382. * CTips::Synthesize *
  383. *-------------------*
  384. * Description:
  385. *
  386. ******************************************************************* PACOG ***/
  387. int CTips::Synthesize (int iPeriodLen)
  388. {
  389. double* pdPeriodSamples = 0;
  390. double* windowedLeft = 0;
  391. int leftSize;
  392. double* windowedRight = 0;
  393. int rightSize;
  394. double *p1, *p2;
  395. int i;
  396. assert (iPeriodLen);
  397. if (m_fRtips)
  398. {
  399. NonIntegerDelay (m_aBuffer[1].m_pdSamples, m_aBuffer[1].m_iNumSamples, m_aBuffer[1].m_dDelay);
  400. }
  401. if (!GetWindowedSignal(0, iPeriodLen, &windowedLeft, &leftSize))
  402. {
  403. goto error;
  404. }
  405. if (!GetWindowedSignal(1, iPeriodLen, &windowedRight, &rightSize) )
  406. {
  407. goto error;
  408. }
  409. assert (windowedLeft && leftSize);
  410. assert (windowedRight && rightSize);
  411. if (!windowedLeft || !leftSize || !windowedRight || !rightSize )
  412. {
  413. goto error;
  414. }
  415. if ((pdPeriodSamples = new double[iPeriodLen]) == 0)
  416. {
  417. goto error;
  418. }
  419. p1=windowedLeft;
  420. p2=windowedRight;
  421. for (i=0; i<iPeriodLen - rightSize && i<leftSize; i++)
  422. {
  423. pdPeriodSamples[i] = *p1++;
  424. }
  425. // If windows overlap, they are added
  426. for ( ;i<leftSize; i++)
  427. {
  428. pdPeriodSamples[i] = *p1++ + *p2++;
  429. }
  430. // Else, we fill the space with zeros
  431. for (; i<iPeriodLen - rightSize; i++)
  432. {
  433. pdPeriodSamples[i] = 0.0;
  434. }
  435. for (;i<iPeriodLen;i++)
  436. {
  437. pdPeriodSamples[i] = *p2++;
  438. }
  439. delete[] windowedLeft;
  440. delete[] windowedRight;
  441. if (m_fLptips)
  442. {
  443. LpcSynth (pdPeriodSamples, iPeriodLen);
  444. }
  445. // reuse the same buffer if possible
  446. if ( m_iNumSynthSamples < iPeriodLen )
  447. {
  448. if (m_psSynthSamples)
  449. {
  450. delete[] m_psSynthSamples;
  451. }
  452. if ((m_psSynthSamples = new short[iPeriodLen]) == 0)
  453. {
  454. goto error;
  455. }
  456. m_iNumSynthSamples = iPeriodLen;
  457. }
  458. for (i=0; i<iPeriodLen; i++)
  459. {
  460. m_psSynthSamples[i] = ClipData(pdPeriodSamples[i]);
  461. }
  462. delete[] pdPeriodSamples;
  463. return 1;
  464. error:
  465. if (pdPeriodSamples)
  466. {
  467. delete[] pdPeriodSamples;
  468. }
  469. if (windowedLeft)
  470. {
  471. delete[] windowedLeft;
  472. }
  473. if (windowedRight)
  474. {
  475. delete[] windowedRight;
  476. }
  477. return 0;
  478. }
  479. /*****************************************************************************
  480. * CTips::GetWindowedSignal *
  481. *----------------------------*
  482. * Description:
  483. *
  484. ******************************************************************* PACOG ***/
  485. int CTips::GetWindowedSignal (int whichBuffer, int iPeriodLen,
  486. double** windowed, int* nWindowed)
  487. {
  488. double* sampPtr;
  489. int nSamples;
  490. int from;
  491. if (whichBuffer==0)
  492. {
  493. sampPtr = m_aBuffer[0].m_pdSamples + m_aBuffer[0].m_iCenter;
  494. nSamples = __min(iPeriodLen, (m_aBuffer[0].m_iNumSamples - m_aBuffer[0].m_iCenter));
  495. }
  496. else
  497. {
  498. from = __max(0, m_aBuffer[1].m_iCenter - iPeriodLen);
  499. sampPtr = m_aBuffer[1].m_pdSamples + from;
  500. nSamples = m_aBuffer[1].m_iCenter - from;
  501. }
  502. if (nSamples)
  503. {
  504. if ((*windowed = new double[nSamples]) == 0)
  505. {
  506. return 0;
  507. }
  508. *nWindowed = nSamples;
  509. memcpy (*windowed, sampPtr, nSamples * sizeof(**windowed));
  510. if (whichBuffer==0)
  511. {
  512. HalfHanning (*windowed, nSamples, 1.0, WindowSecondHalf);
  513. }
  514. else
  515. {
  516. HalfHanning (*windowed, nSamples, 1.0, WindowFirstHalf);
  517. }
  518. return 1;
  519. }
  520. else
  521. {
  522. fprintf (stderr, "NULL vector in GetWindowedSignal\n");
  523. }
  524. return 0;
  525. }
  526. /*****************************************************************************
  527. * CTips::HalfHanning *
  528. *--------------------*
  529. * Description:
  530. * 12/4/00 - Since ampl wasn't being used, I'm now asserting it equal
  531. * to 1 and ignoring it. Also, a large hanning window is
  532. * pre-computed and interpolated here, instead of being
  533. * calculated here.
  534. *
  535. ******************************************************************* mplumpe ***/
  536. void CTips::HalfHanning (double* x, int xLen, double ampl, int whichHalf)
  537. {
  538. double delta;
  539. double dk;
  540. int start;
  541. int sign;
  542. int i;
  543. assert (1 == ampl);
  544. if (x && xLen)
  545. {
  546. delta = m_iHalfHanLen_c / xLen;
  547. dk=0.; // FTOL function does rounding. If casting to int, need to start at 0.5 to get rounding
  548. /*
  549. * When multiplying by the second half, the window function is the same,
  550. * but we multiply from the last sample in the vector to the first
  551. * NOTE: The first sample is multiplyed by 0 in the case of the first
  552. * half, and by 1 (*ampl, of course) in the case of the second half.
  553. */
  554. switch (whichHalf)
  555. {
  556. case WindowSecondHalf:
  557. start=xLen;
  558. sign=-1;
  559. break;
  560. case WindowFirstHalf:
  561. x[0]=0.0;
  562. start=0;
  563. sign=1;
  564. break;
  565. default:
  566. fprintf(stderr, "Hanning, should especify a half window\n");
  567. return;
  568. }
  569. for (i=1; i<xLen; i++)
  570. {
  571. dk += delta;
  572. x[start+sign*i] *= m_adHalfHanning[FTOL(dk)];
  573. }
  574. }
  575. }
  576. /*****************************************************************************
  577. * CTips::ClipData *
  578. *-----------------*
  579. * Description:
  580. * 12/4/00 - now using the FTOL function, since the compiler doesn't do
  581. * the conversion efficiently.
  582. * 1/18/01 - The FTOL function rounds, whereas casting truncates. So,
  583. * we no longer need to ad .5 for pos numbers and subtract .5
  584. * for negative numbers.
  585. *
  586. ******************************************************************* mplumpe ***/
  587. short CTips::ClipData (double x)
  588. {
  589. if (x > SHRT_MAX )
  590. {
  591. return SHRT_MAX;
  592. }
  593. if (x < SHRT_MIN )
  594. {
  595. return SHRT_MIN;
  596. }
  597. return (short)FTOL(x);
  598. }
  599. /*****************************************************************************
  600. * CTips::LpcInit *
  601. *----------------*
  602. * Description:
  603. *
  604. ******************************************************************* PACOG ***/
  605. bool CTips::LpcInit ()
  606. {
  607. m_iLpcOrder = LpcOrder (m_iSampFreq);
  608. if ((m_pdFiltMem = new double [m_iLpcOrder]) == 0)
  609. {
  610. goto error;
  611. }
  612. memset( m_pdFiltMem, 0, m_iLpcOrder * sizeof (*m_pdFiltMem));
  613. if ((m_pdInterpCoef = new double [m_iLpcOrder]) == 0)
  614. {
  615. goto error;
  616. }
  617. memset( m_pdInterpCoef, 0, m_iLpcOrder * sizeof (*m_pdInterpCoef));
  618. if ((m_pdLastCoef = new double [m_iLpcOrder]) == 0)
  619. {
  620. goto error;
  621. }
  622. memset( m_pdLastCoef, 0, m_iLpcOrder * sizeof (*m_pdLastCoef));
  623. return true;
  624. error:
  625. LpcFreeAll();
  626. return false;
  627. }
  628. /*****************************************************************************
  629. * CTips::LpcSynth *
  630. *--------------------*
  631. * Description:
  632. *
  633. ******************************************************************* PACOG ***/
  634. void CTips::LpcSynth (double* pdPeriod, int iPeriodLen)
  635. {
  636. double alfa;
  637. int i;
  638. int j;
  639. for (i=0; i<iPeriodLen; i++)
  640. {
  641. alfa = i/(double)iPeriodLen;
  642. for (j=0; j<m_iLpcOrder ; j++) {
  643. m_pdInterpCoef[j] = (1.0 - alfa) * m_pdLastCoef[j] + alfa * m_pdNewCoef[j];
  644. }
  645. ParcorFilterSyn(pdPeriod+i, 1, m_pdInterpCoef, m_pdFiltMem, m_iLpcOrder );
  646. }
  647. memcpy( m_pdLastCoef, m_pdNewCoef, m_iLpcOrder * sizeof(*m_pdLastCoef));
  648. }
  649. /*****************************************************************************
  650. * CTips::LpcFreeAll *
  651. *----------------------*
  652. * Description:
  653. *
  654. ******************************************************************* PACOG ***/
  655. void CTips::LpcFreeAll()
  656. {
  657. if (m_pdFiltMem)
  658. {
  659. delete[] m_pdFiltMem;
  660. m_pdFiltMem = 0;
  661. }
  662. if (m_pdInterpCoef)
  663. {
  664. delete[] m_pdInterpCoef;
  665. m_pdInterpCoef = 0;
  666. }
  667. if (m_pdLastCoef)
  668. {
  669. delete[] m_pdLastCoef;
  670. m_pdInterpCoef = 0;
  671. }
  672. }