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.

551 lines
12 KiB

  1. /******************************************************************************
  2. * SynthUnit.cpp *
  3. *---------------*
  4. *
  5. *------------------------------------------------------------------------------
  6. * Copyright (C) 1996 Entropic, Inc
  7. * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00
  8. * All Rights Reserved
  9. *
  10. ********************************************************************* PACOG ***/
  11. #include "SynthUnit.h"
  12. #include "tips.h"
  13. #include <sigproc.h>
  14. #include <assert.h>
  15. #include <string.h>
  16. #include <vapiIo.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <float.h>
  21. #include <limits.h>
  22. #include <assert.h>
  23. #include "ftol.h"
  24. /*
  25. * This is the internal frequency at which the prosody module works.
  26. * This value of samp freq. is arbitary. We chose 44100 for high resolution
  27. */
  28. #define TIME_STEP (1.0/44100.0)
  29. struct NewF0Struct
  30. {
  31. double f0;
  32. double time;
  33. };
  34. /*****************************************************************************
  35. * CSynth::CSynth *
  36. *----------------*
  37. * Description:
  38. *
  39. ******************************************************************* PACOG ***/
  40. CSynth::CSynth(int iSampFreq)
  41. {
  42. m_iSampFreq = iSampFreq;
  43. m_pdSamples = 0;
  44. m_pEpochs = 0;
  45. m_pdSynEpochs = 0;
  46. m_piMapping = 0;
  47. m_iNumSynEpochs = 0;
  48. m_ppdLpcCoef = 0;
  49. m_iCurrentPeriod = 0;
  50. m_iRepetitions = 0;
  51. m_iInvert = 0;
  52. m_iLpcOrder = 0;
  53. }
  54. /*****************************************************************************
  55. * CSynth::~CSynth *
  56. *-----------------*
  57. * Description:
  58. *
  59. ******************************************************************* PACOG ***/
  60. CSynth::~CSynth()
  61. {
  62. if ( m_pdSamples )
  63. {
  64. delete[] m_pdSamples;
  65. }
  66. if ( m_pEpochs )
  67. {
  68. delete[] m_pEpochs;
  69. }
  70. if ( m_pdSynEpochs )
  71. {
  72. delete[] m_pdSynEpochs;
  73. }
  74. if ( m_piMapping )
  75. {
  76. delete[] m_piMapping;
  77. }
  78. if (m_ppdLpcCoef)
  79. {
  80. FreeLpcCoef();
  81. }
  82. }
  83. /*****************************************************************************
  84. * CSynth:: GetNewF0 *
  85. *-------------------*
  86. * Description:
  87. *
  88. *********************************************************************** WD ***/
  89. void CSynth::GetNewF0 (std::vector<NewF0Struct>* pvNewF0, double* pdTime, double* pdRunTime )
  90. {
  91. NewF0Struct newF0;
  92. for ( int i = 1; i < m_iNumEpochs; i++ )
  93. {
  94. newF0.f0 = (int) ( 1.0 / ( m_pEpochs[ i ].time - m_pEpochs[ i - 1 ].time ) );
  95. newF0.f0 *= m_dF0Ratio;
  96. newF0.time = *pdTime + m_pEpochs[ i ].time;
  97. pvNewF0->push_back ( newF0 );
  98. }
  99. *pdTime += m_pEpochs[ m_iNumEpochs - 1 ].time;
  100. if ( pdRunTime )
  101. {
  102. *pdRunTime = m_dRunTimeLimit;
  103. }
  104. }
  105. /*****************************************************************************
  106. * CTips::ClipData *
  107. *-----------------*
  108. * Description:
  109. * 12/4/00 - now using the FTOL function, since the compiler doesn't do
  110. * the conversion efficiently.
  111. *
  112. ******************************************************************* mplumpe ***/
  113. short CSynth::ClipData (double x)
  114. {
  115. if (x>=0)
  116. {
  117. if (x > SHRT_MAX )
  118. {
  119. return SHRT_MAX;
  120. }
  121. x+= 0.5;
  122. }
  123. else
  124. {
  125. if (x < SHRT_MIN )
  126. {
  127. return SHRT_MIN;
  128. }
  129. x-= 0.5;
  130. }
  131. return (short)FTOL(x);
  132. }
  133. /*****************************************************************************
  134. * CSynth::LpcAnalysis *
  135. *---------------------*
  136. * Description:
  137. *
  138. ******************************************************************* PACOG ***/
  139. int CSynth::LpcAnalysis (int iSampFreq, int iOrder)
  140. {
  141. double* pdFiltMem = 0;
  142. double* pdInterpCoef = 0;
  143. double alfa;
  144. int frameLen;
  145. int frameIdx;
  146. int start;
  147. int end;
  148. int i;
  149. int j;
  150. if (m_iNumEpochs)
  151. {
  152. m_iLpcOrder = iOrder;
  153. if ((m_ppdLpcCoef = new double*[m_iNumEpochs] ) == 0)
  154. {
  155. goto error;
  156. }
  157. memset( m_ppdLpcCoef, 0, m_iNumEpochs * sizeof (*m_ppdLpcCoef));
  158. if ((pdFiltMem = new double[m_iLpcOrder]) == 0)
  159. {
  160. goto error;
  161. }
  162. memset (pdFiltMem, 0, m_iLpcOrder * sizeof(*pdFiltMem));
  163. if ((pdInterpCoef = new double[m_iLpcOrder]) == 0)
  164. {
  165. goto error;
  166. }
  167. memset (pdInterpCoef, 0, m_iLpcOrder * sizeof(*pdInterpCoef));
  168. for (frameIdx=0; frameIdx<m_iNumEpochs; frameIdx ++)
  169. {
  170. if (frameIdx==0)
  171. {
  172. start =0;
  173. }
  174. else
  175. {
  176. start = (int) (m_pEpochs[frameIdx-1].time * iSampFreq);
  177. }
  178. if (frameIdx==m_iNumEpochs-1)
  179. {
  180. end = m_iNumSamples-1;
  181. }
  182. else
  183. {
  184. end = (int)(m_pEpochs[frameIdx+1].time * iSampFreq);
  185. }
  186. frameLen = end-start;
  187. m_ppdLpcCoef[frameIdx] = GetDurbinCoef(m_pdSamples + start, frameLen);
  188. }
  189. for (frameIdx=0; frameIdx<m_iNumEpochs-1; frameIdx ++)
  190. {
  191. if (frameIdx==0)
  192. {
  193. start = 0;
  194. }
  195. else
  196. {
  197. start = (int)(m_pEpochs[frameIdx].time * iSampFreq);
  198. }
  199. if (frameIdx==m_iNumEpochs-2)
  200. {
  201. end = m_iNumSamples-1;
  202. }
  203. else
  204. {
  205. end = (int)(m_pEpochs[frameIdx+1].time * iSampFreq);
  206. }
  207. for (i=start; i<end; i++)
  208. {
  209. alfa = (double)(i-start)/(double)(end-start);
  210. for (j=0; j<m_iLpcOrder ; j++)
  211. {
  212. pdInterpCoef[j] = (1.0 - alfa) * m_ppdLpcCoef[frameIdx][j] +
  213. alfa * m_ppdLpcCoef[frameIdx+1][j];
  214. }
  215. ParcorFilterAn (m_pdSamples + i, 1, pdInterpCoef, pdFiltMem, m_iLpcOrder);
  216. }
  217. }
  218. }
  219. delete[] pdFiltMem;
  220. delete[] pdInterpCoef;
  221. return 1;
  222. error:
  223. if (pdFiltMem)
  224. {
  225. delete[] pdFiltMem;
  226. }
  227. if (pdInterpCoef)
  228. {
  229. delete[] pdInterpCoef;
  230. }
  231. return 0;
  232. }
  233. /*****************************************************************************
  234. * CSynth::FindPrecedent *
  235. *-----------------------*
  236. * Description:
  237. *
  238. ******************************************************************* PACOG ***/
  239. int CSynth::FindPrecedent ()
  240. {
  241. double* warp;
  242. double durFactor;
  243. double distAnt;
  244. double distPost;
  245. int sIndex;
  246. int aIndex;
  247. int i;
  248. durFactor = m_pdSynEpochs[m_iNumSynEpochs-1]/m_pEpochs[m_iNumEpochs-1].time;
  249. warp = new double[m_iNumEpochs];
  250. if (!warp)
  251. {
  252. return -1;
  253. }
  254. for (i=0; i<m_iNumEpochs; i++)
  255. {
  256. warp[i]= m_pEpochs[i].time * durFactor;
  257. }
  258. if ((m_piMapping= new int[m_iNumSynEpochs]) == 0)
  259. {
  260. return -1;
  261. }
  262. m_piMapping[0]=0;
  263. m_piMapping[m_iNumSynEpochs-1] = m_iNumEpochs-1;
  264. aIndex=1;
  265. for ( sIndex=1; sIndex<(m_iNumSynEpochs-1); sIndex++ )
  266. {
  267. while (warp[aIndex] < m_pdSynEpochs[sIndex])
  268. {
  269. aIndex++;
  270. }
  271. distAnt = fabs ( m_pdSynEpochs[sIndex] - warp[aIndex-1] );
  272. distPost = fabs ( m_pdSynEpochs[sIndex] - warp[aIndex] );
  273. if (distAnt<distPost)
  274. {
  275. if (aIndex<2)
  276. {
  277. m_piMapping[sIndex] = aIndex;
  278. }
  279. else
  280. {
  281. m_piMapping[sIndex] = aIndex-1;
  282. }
  283. }
  284. else
  285. {
  286. if (aIndex>m_iNumEpochs-2)
  287. {
  288. m_piMapping[sIndex] = m_iNumEpochs-2;
  289. }
  290. else
  291. {
  292. m_piMapping[sIndex] = aIndex;
  293. }
  294. }
  295. }
  296. delete[] warp;
  297. //DEBUG
  298. /*
  299. fprintf (stderr, "+++++++++++++++++++++++++++\n");
  300. for (i=0; i<m_iNumEpochs; i++) {
  301. fprintf (stderr, "m_pEpochs[%d]=%f\n", i, m_pEpochs[i].time);
  302. }
  303. for (i=0; i<m_iNumSynEpochs; i++) {
  304. fprintf (stderr, "Syn[%d]=%f ->m_pEpochs[%d]\n", i, m_pdSynEpochs[i], (*m_piMapping)[i]);
  305. }
  306. */
  307. return 1;
  308. }
  309. /*****************************************************************************
  310. * CSynth::NextBuffer *
  311. *--------------------*
  312. * Description:
  313. *
  314. ******************************************************************* PACOG ***/
  315. int CSynth::NextBuffer (CTips* pTips)
  316. {
  317. double* pdSamples;
  318. int iNumSamples;
  319. int iCenter;
  320. double dDelay;
  321. double* pdLpcCoef;
  322. double gainVal;
  323. int centerIdx;
  324. int from;
  325. int to;
  326. int center;
  327. double origDelay;
  328. double synthDelay;
  329. int reverse=0;
  330. int voiced;
  331. int iPeriodLen;
  332. int i;
  333. assert (pTips);
  334. if (m_iCurrentPeriod >= m_iNumSynEpochs-2 )
  335. {
  336. return 0; //We are done with this unit
  337. }
  338. // The first short-term signal is centered in 1, not 0
  339. m_iCurrentPeriod++;
  340. centerIdx = (int)m_piMapping[m_iCurrentPeriod];
  341. voiced = m_pEpochs[centerIdx].voiced;
  342. //Round to internal sampling freq
  343. synthDelay = (m_pdSynEpochs[m_iCurrentPeriod] * m_iSampFreq) -
  344. (int)(m_pdSynEpochs[m_iCurrentPeriod] * m_iSampFreq + TIME_STEP/2.0);
  345. if ( !voiced && (centerIdx==m_piMapping[m_iCurrentPeriod-1]) )
  346. {
  347. m_iRepetitions++;
  348. m_iRepetitions%=4;
  349. m_iInvert = !m_iInvert;
  350. if (m_iRepetitions==1 || m_iRepetitions==2)
  351. {
  352. reverse=1;
  353. }
  354. }
  355. else
  356. {
  357. m_iRepetitions=0;
  358. m_iInvert=0;
  359. }
  360. from = (int)( m_pEpochs[centerIdx-1].time * m_iSampFreq );
  361. to = (int)( m_pEpochs[centerIdx+1].time * m_iSampFreq );
  362. center = (int)( m_pEpochs[centerIdx].time * m_iSampFreq );
  363. origDelay = (m_pEpochs[centerIdx].time * m_iSampFreq) - center + TIME_STEP/2.0;
  364. iNumSamples = to-from;
  365. iCenter = center - from;
  366. dDelay = origDelay - synthDelay;
  367. if ((pdSamples = new double[iNumSamples]) == 0)
  368. {
  369. return 0;
  370. }
  371. if ( !reverse )
  372. {
  373. memcpy (pdSamples, m_pdSamples + from, (iNumSamples)*sizeof(double));
  374. }
  375. else
  376. {
  377. for (i = 0; i<iNumSamples ; i++ )
  378. {
  379. pdSamples[i] = m_pdSamples[from + iNumSamples - i -1];
  380. }
  381. iCenter = iNumSamples - iCenter;
  382. dDelay = -dDelay;
  383. }
  384. gainVal = m_dGain * pTips->GetGain();
  385. if (m_iInvert)
  386. {
  387. gainVal *= -1;
  388. }
  389. for (i=0; i<iNumSamples; i++)
  390. {
  391. pdSamples[i] *= gainVal;
  392. }
  393. if (m_ppdLpcCoef)
  394. {
  395. pdLpcCoef = m_ppdLpcCoef[centerIdx];
  396. }
  397. else
  398. {
  399. pdLpcCoef = 0;
  400. }
  401. pTips->SetBuffer (pdSamples, iNumSamples, iCenter, dDelay, pdLpcCoef);
  402. //NOTE: Do not delete pdSamples, it will be deleted in CTips::Synthesize
  403. iPeriodLen = (int)(m_pdSynEpochs[m_iCurrentPeriod+1] * m_iSampFreq) -
  404. (int)(m_pdSynEpochs[m_iCurrentPeriod] * m_iSampFreq);
  405. return iPeriodLen;
  406. }
  407. /*****************************************************************************
  408. * CSynth::LpcGetDurbinCoef *
  409. *--------------------------*
  410. * Description:
  411. *
  412. ******************************************************************* PACOG ***/
  413. double* CSynth::GetDurbinCoef(double* data, int nData)
  414. {
  415. double* win;
  416. double* coef;
  417. int i;
  418. assert(data);
  419. win = ComputeWindow (WINDOW_HAMM, nData, 0);
  420. for (i=0; i<nData; i++)
  421. {
  422. win[i] *= data[i];
  423. }
  424. coef = ::GetDurbinCoef (win, nData, m_iLpcOrder, LPC_PARCOR, 0);
  425. delete[] win;
  426. return coef;
  427. }
  428. /*****************************************************************************
  429. * CSynth::FreeLpcCoef *
  430. *---------------------*
  431. * Description:
  432. *
  433. ******************************************************************* PACOG ***/
  434. void CSynth::FreeLpcCoef()
  435. {
  436. for (int i=0; i< m_iNumEpochs; i++)
  437. {
  438. if (m_ppdLpcCoef[i])
  439. {
  440. delete[] m_ppdLpcCoef[i];
  441. }
  442. }
  443. delete[] m_ppdLpcCoef;
  444. m_ppdLpcCoef = 0;
  445. }
  446. /*****************************************************************************
  447. * *
  448. *----------------------*
  449. * Description:
  450. *
  451. ******************************************************************* PACOG ***/
  452. /*
  453. int CSynth::FindPrecedentCopy ( )
  454. {
  455. int i;
  456. m_iNumSynEpochs = m_iNumEpochs;
  457. m_pdSynEpochs = new double[m_iNumEpochs];
  458. m_piMapping = new int[m_iNumEpochs];
  459. for (i=0; i<m_iNumEpochs; i++)
  460. {
  461. m_pdSynEpochs[i]= m_pEpochs[i].time;
  462. }
  463. for (i=0; i<m_iNumEpochs; i++)
  464. {
  465. m_piMapping[i] = i;
  466. }
  467. return 1;
  468. }
  469. */