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.

335 lines
9.0 KiB

  1. /******************************************************************************
  2. * Duration.cpp *
  3. *--------------*
  4. *
  5. *------------------------------------------------------------------------------
  6. * Copyright (C) 1999 Microsoft Corporation Date: 04/28/99
  7. * All Rights Reserved
  8. *
  9. *********************************************************************** MC ****/
  10. //--- Additional includes
  11. #include "stdafx.h"
  12. #ifndef SPDebug_h
  13. #include <spdebug.h>
  14. #endif
  15. #ifndef Frontend_H
  16. #include "Frontend.h"
  17. #endif
  18. #ifndef AlloOps_H
  19. #include "AlloOps.h"
  20. #endif
  21. //-----------------------------
  22. // Data.cpp
  23. //-----------------------------
  24. extern const unsigned long g_AlloFlags[];
  25. extern const float g_BoundryDurTbl[];
  26. extern const float g_BoundryStretchTbl[];
  27. /*****************************************************************************
  28. * CDuration::Pause_Insertion *
  29. *----------------------------*
  30. * Description:
  31. * Duration Rule #1 - Pause Insertion
  32. *
  33. ********************************************************************** MC ***/
  34. void CDuration::Pause_Insertion( long userDuration, long silBreak )
  35. {
  36. SPDBG_FUNC( "CDuration::Pause_Insertion" );
  37. if( userDuration )
  38. {
  39. m_DurHold = ((float)userDuration / 1000);
  40. m_TotalDurScale = 1.0;
  41. }
  42. else if( silBreak )
  43. {
  44. m_DurHold = ((float)silBreak / 1000);
  45. }
  46. else
  47. {
  48. if( m_CurBoundary != NULL_BOUNDARY)
  49. {
  50. m_DurHold = g_BoundryDurTbl[(long)m_CurBoundary];
  51. //m_DurHold *= m_TotalDurScale;
  52. //----------------------------
  53. // Clip to limits
  54. //----------------------------
  55. if( m_DurHold > MAX_SIL_DUR )
  56. {
  57. m_DurHold = MAX_SIL_DUR;
  58. }
  59. /*else if( m_DurHold < MIN_ALLO_DUR )
  60. {
  61. m_DurHold = MIN_ALLO_DUR;
  62. }*/
  63. }
  64. }
  65. } /* CDuration::Pause_Insertion */
  66. /*****************************************************************************
  67. * CDuration::PhraseFinal_Lengthen *
  68. *---------------------------------*
  69. * Description:
  70. * Duration Rule #2 - Phrase-final Lengthening
  71. *
  72. ********************************************************************** MC ***/
  73. void CDuration::PhraseFinal_Lengthen( long /*cellCount*/ )
  74. {
  75. SPDBG_FUNC( "CDuration::PhraseFinal_Lengthen" );
  76. float stretchGain;
  77. if( m_cur_SyllableType & TERM_END_SYLL)
  78. {
  79. if( (m_cur_Stress) && (m_cur_VowelFlag) )
  80. {
  81. stretchGain = g_BoundryStretchTbl[(long)m_NextBoundary];
  82. m_DurHold *= stretchGain;
  83. //----------------------------
  84. // Clip to limits
  85. //----------------------------
  86. if( m_DurHold > MAX_ALLO_DUR )
  87. {
  88. m_DurHold = MAX_ALLO_DUR;
  89. }
  90. else if( m_DurHold < MIN_ALLO_DUR )
  91. {
  92. m_DurHold = MIN_ALLO_DUR;
  93. }
  94. }
  95. }
  96. } /* CDuration::PhraseFinal_Lengthen */
  97. #define EMPH_VOWEL_GAIN 1.0f
  98. #define EMPH_CONS_GAIN 1.25f
  99. #define EMPH_VOWEL_MIN 0.060f
  100. #define EMPH_CONS_MIN 0.020f
  101. #define EMPH_MIN_DUR 0.150f
  102. /*****************************************************************************
  103. * CDuration::Emphatic_Lenghen *
  104. *-----------------------------*
  105. * Description:
  106. * Duration Rule #8 - Lengthening for emphasis
  107. *
  108. ********************************************************************** MC ***/
  109. long CDuration::Emphatic_Lenghen( long lastStress )
  110. {
  111. SPDBG_FUNC( "CDuration::Emphatic_Lenghen" );
  112. long eFlag;
  113. bool isEmph;
  114. eFlag = lastStress;
  115. if( m_cur_Stress & EMPHATIC_STRESS )
  116. {
  117. isEmph = true;
  118. }
  119. else
  120. {
  121. isEmph = false;
  122. }
  123. if( (m_cur_PhonCtrl & WORD_INITIAL_CONSONANT) ||
  124. ( m_cur_VowelFlag && (!isEmph)) )
  125. {
  126. eFlag = false; // start of a new word OR non-emph vowel
  127. }
  128. if( isEmph )
  129. {
  130. eFlag = true; // continue lengthening until above condition is met
  131. }
  132. if( eFlag )
  133. {
  134. /*if( m_DurHold < EMPH_MIN_DUR )
  135. {
  136. m_durationPad += EMPH_MIN_DUR - m_DurHold;
  137. }*/
  138. float durDiff;
  139. if( m_cur_VowelFlag)
  140. {
  141. durDiff = (m_DurHold * EMPH_VOWEL_GAIN) - m_DurHold;
  142. if( durDiff < EMPH_VOWEL_MIN )
  143. {
  144. durDiff = EMPH_VOWEL_MIN;
  145. }
  146. }
  147. else
  148. {
  149. durDiff = (m_DurHold * EMPH_CONS_GAIN) - m_DurHold;
  150. if( durDiff < EMPH_CONS_MIN )
  151. {
  152. durDiff = EMPH_CONS_MIN;
  153. }
  154. }
  155. m_durationPad += durDiff; // lengthen phon for emph
  156. }
  157. return eFlag;
  158. } /* CDuration::Emphatic_Lenghen */
  159. /*****************************************************************************
  160. * CDuration::AlloDuration *
  161. *-------------------------*
  162. * Description:
  163. * Calculate durations
  164. *
  165. ********************************************************************** MC ***/
  166. void CDuration::AlloDuration( CAlloList *pAllos, float rateRatio )
  167. {
  168. SPDBG_FUNC( "CDuration::AlloDuration" );
  169. long eFlag;
  170. CAlloCell *pPrevCell, *pCurCell, *pNextCell, *pNext2Cell;
  171. long numOfCells;
  172. long userDuration, silBreak;
  173. numOfCells = pAllos->GetCount();
  174. if( numOfCells > 0 )
  175. {
  176. eFlag = false;
  177. //------------------------------
  178. // Fill the pipeline
  179. //------------------------------
  180. pPrevCell = pAllos->GetHeadCell();
  181. pCurCell = pAllos->GetNextCell();
  182. pNextCell = pAllos->GetNextCell();
  183. pNext2Cell = pAllos->GetNextCell();
  184. //------------------------------
  185. // 1st allo is always SIL
  186. //------------------------------
  187. pPrevCell->m_ftDuration = pPrevCell->m_UnitDur = PITCH_BUF_RES; // initial SIL
  188. while( pCurCell )
  189. {
  190. //------------------
  191. // Current
  192. //------------------
  193. m_cur_Phon = pCurCell->m_allo;
  194. m_cur_PhonCtrl = pCurCell->m_ctrlFlags;
  195. m_cur_SyllableType = m_cur_PhonCtrl & SYLLABLE_TYPE_FIELD;
  196. m_cur_Stress = m_cur_PhonCtrl & STRESS_FIELD;
  197. m_cur_PhonFlags = ::g_AlloFlags[m_cur_Phon];
  198. userDuration = pCurCell->m_user_Break;
  199. silBreak = pCurCell->m_Sil_Break;
  200. if( m_cur_PhonFlags & KVOWELF)
  201. {
  202. m_cur_VowelFlag = true;
  203. }
  204. else
  205. {
  206. m_cur_VowelFlag = false;
  207. }
  208. m_CurBoundary = pCurCell->m_TuneBoundaryType;
  209. m_NextBoundary = pCurCell->m_NextTuneBoundaryType;
  210. m_TotalDurScale = rateRatio * pCurCell->m_DurScale * pCurCell->m_ProsodyDurScale;
  211. m_DurHold = pCurCell->m_UnitDur;
  212. m_durationPad = 0;
  213. if( pCurCell->m_user_Emph > 0 )
  214. {
  215. m_cur_Stress |= EMPHATIC_STRESS;
  216. }
  217. //------------------
  218. // Prev
  219. //------------------
  220. m_prev_Phon = pPrevCell->m_allo;
  221. m_prev_PhonCtrl = pPrevCell->m_ctrlFlags;
  222. m_prev_PhonFlags = ::g_AlloFlags[m_prev_Phon];
  223. //------------------
  224. // Next
  225. //------------------
  226. if( pNextCell )
  227. {
  228. m_next_Phon = pNextCell->m_allo;
  229. m_next_PhonCtrl = pNextCell->m_ctrlFlags;
  230. }
  231. else
  232. {
  233. m_next_Phon = _SIL_;
  234. m_next_PhonCtrl = 0;
  235. }
  236. m_next_PhonFlags = ::g_AlloFlags[m_next_Phon];
  237. //------------------
  238. // 2 phons ahead
  239. //------------------
  240. if( pNext2Cell )
  241. {
  242. m_next2_Phon = pNext2Cell->m_allo;
  243. m_next2_PhonCtrl = pNext2Cell->m_ctrlFlags;
  244. }
  245. else
  246. {
  247. m_next2_Phon = _SIL_;
  248. m_next2_PhonCtrl = 0;
  249. }
  250. m_next2_PhonFlags = ::g_AlloFlags[m_next2_Phon];
  251. if( m_cur_Phon == _SIL_ )
  252. {
  253. //-------------------------------------------
  254. // #1 - Pause Insertion
  255. //-------------------------------------------
  256. Pause_Insertion( userDuration, silBreak );
  257. }
  258. else
  259. {
  260. //-------------------------------------------
  261. // #2 - Phrase-final Lengthening
  262. //-------------------------------------------
  263. PhraseFinal_Lengthen( numOfCells );
  264. //-------------------------------------------
  265. // #8 Lengthening for emphasis
  266. //-------------------------------------------
  267. eFlag = Emphatic_Lenghen( eFlag );
  268. }
  269. pCurCell->m_ftDuration = ((m_DurHold + m_durationPad) / m_TotalDurScale);
  270. //---------------------------------
  271. // Shift the pipeline once
  272. //---------------------------------
  273. pPrevCell = pCurCell;
  274. pCurCell = pNextCell;
  275. pNextCell = pNext2Cell;
  276. pNext2Cell = pAllos->GetNextCell();
  277. }
  278. }
  279. } /* CDuration::AlloDuration */