DHMM_MODEL_MFC.cpp
上传用户:avbj512
上传日期:2013-09-18
资源大小:6239k
文件大小:28k
源码类别:

DSP编程

开发平台:

Visual C++

  1. // DHMM_MODEL_MFC.cpp:
  2. // Implementation of the DHMM_MODEL_MFC Module.
  3. // That is to train DHMM_Model.
  4. //
  5. // Created 2001/08, By DongMing, MDSR.
  6. //
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "DHMM_Model_MFC.h"
  10. #include "kwspot.h"
  11. #include "DAT_File_Access.h"
  12. #include "DHMM_VQ_MFC.h"
  13. #include "DHMM_GL.h"
  14. #include "DHMM_LHS.h"
  15. #include "DHMM_HQ.h"
  16. extern PRO_CONFIG u_Pro_Config;
  17. //////////////////////////////////////////////////////////////////////
  18. // API functions
  19. //////////////////////////////////////////////////////////////////////
  20. // 函数名称:DHMM_Model
  21. // 函数功能:DHMM程序进行模型训练模块的入口
  22. // 函数性质:API
  23. // 输入参数:
  24. // 无
  25. // 输出参数:
  26. // 无
  27. // 返回值:
  28. // 0 表示成功
  29. // 备注:本模块完成DHMM模型训练,模块的应用接口实际上是基于文件的,
  30. // 训练的结果将保存在u_Pro_Config.sz_Toload_DHMM_Model_File_Name中
  31. int DHMM_Model(void)
  32. {
  33. int nRetCode;
  34. DHMM_MODEL * pu_DHMM_Model;
  35. int n_Model_Index;
  36. DHMM_MODEL Silence_Model;
  37. int Total_Model_Num;
  38. if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
  39. {
  40. //  为静音模型多准备两个状态
  41. u_Pro_Config.n_DHMM_Model_State_Num += 2;
  42. }
  43. Total_Model_Num =u_Pro_Config.n_DHMM_Model_Num;
  44. // 为DHMM模型准备内存
  45. pu_DHMM_Model = new DHMM_MODEL[Total_Model_Num];
  46. ASSERT(pu_DHMM_Model);
  47. for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
  48. {
  49. pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
  50. pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
  51. pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
  52. pu_DHMM_Model[n_Model_Index].d2dda_A = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
  53. pu_DHMM_Model[n_Model_Index].d2dda_B = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  54. ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
  55. && (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
  56. && (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
  57. }
  58. Silence_Model.n_State_Num = 1;
  59. Silence_Model.n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
  60. Silence_Model.pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
  61. Silence_Model.d2dda_A = d2dda_New(Silence_Model.n_State_Num, Silence_Model.n_State_Num);
  62. Silence_Model.d2dda_B = d2dda_New(Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  63. ASSERT((Silence_Model.pdPi != NULL)
  64. && (Silence_Model.d2dda_A != NULL)
  65. && (Silence_Model.d2dda_B != NULL));
  66. // Load_Only With Silence DHMM_Model
  67. if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
  68. {
  69. nRetCode = DHMM_Model_Load_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, Total_Model_Num);
  70. ASSERT(nRetCode == 0);
  71. }
  72. // Train_Only With Silence DHMM_Model
  73. else if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL)
  74. {
  75. nRetCode = DHMM_Model_Train_Silence_DHMM_Model(&Silence_Model);
  76. nRetCode = DHMM_Model_Train_All_DHMM_Model(pu_DHMM_Model, u_Pro_Config.n_DHMM_Model_Num);
  77. ASSERT(nRetCode == 0);
  78. nRetCode = DHMM_Model_Save_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, &Silence_Model,Total_Model_Num);
  79. ASSERT(nRetCode == 0);
  80. }
  81. // 释放模型占用内存
  82. for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
  83. {
  84. delete[] pu_DHMM_Model[n_Model_Index].pdPi;
  85. d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_A, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
  86. d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_B, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  87. }
  88. delete[] pu_DHMM_Model;
  89. if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
  90. {
  91. //  为静音模型多准备两个状态
  92. u_Pro_Config.n_DHMM_Model_State_Num -= 2;
  93. }
  94. delete [] Silence_Model.pdPi;
  95. d2dda_Free(Silence_Model.d2dda_A, Silence_Model.n_State_Num, Silence_Model.n_State_Num);
  96. d2dda_Free(Silence_Model.d2dda_B, Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  97. return 0;
  98. }
  99. //////////////////////////////////////////////////////////////////////
  100. // 函数名称:DHMM_Model_Save_DHMM_Model_File_With_Silence
  101. // 函数功能:向文件写入DHMM模型
  102. // 函数性质:API
  103. // 输入参数:
  104. // sz_Tosave_DHMM_Model_File_Name,存储模型的文件名
  105. // n_DHMM_Model_Num,要存储的模型个数
  106. // 输出参数:
  107. // pu_DHMM_Model,存放待写入的DHMM模型
  108. // 返回值:
  109. // 0 表示成功
  110. // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
  111. // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
  112. int DHMM_Model_Save_DHMM_Model_File_With_Silence(char * sz_Tosave_DHMM_Model_File_Name,
  113. DHMM_MODEL * pu_DHMM_Model, DHMM_MODEL * pu_Silence_Model, int n_DHMM_Model_Num)
  114. {
  115. FILE * fp_DHMM_Model_File;
  116. DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
  117. long l_Word_Sample_Offset;
  118. int n_Model_Index, n_State_Index;
  119. long lTmp;
  120. CString Silence_File(sz_Tosave_DHMM_Model_File_Name);
  121. Silence_File.Replace(".DAT", "WS.DAT");
  122. fp_DHMM_Model_File = fopen(Silence_File, "wb");
  123. ASSERT(fp_DHMM_Model_File != NULL);
  124. // 填写模型文件头
  125. memset(&u_DHMM_Model_File_Head, 0, sizeof(u_DHMM_Model_File_Head));
  126. u_DHMM_Model_File_Head.lVersion = DAT_FILE_VERSION;
  127. strcpy(u_DHMM_Model_File_Head.szName, "DHMM_Model");
  128. u_DHMM_Model_File_Head.sDHMM_Model_Num = u_DHMM_Model_File_Head.sDHMM_Model_Num2 = n_DHMM_Model_Num;
  129. strcpy(u_DHMM_Model_File_Head.szParameterType, "DHMMModel");
  130. u_DHMM_Model_File_Head.sSampleType = SAMPLE_DATA_TYPE_DOUBLE;
  131. u_DHMM_Model_File_Head.sModelStateNum = pu_DHMM_Model[0].n_State_Num + 2;
  132. u_DHMM_Model_File_Head.sCodeBookSize = pu_DHMM_Model[0].n_Code_Book_Size;
  133. ASSERT(sizeof(u_DHMM_Model_File_Head) == 200);
  134. fwrite(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);
  135. // 用空索引表占据空间
  136. lTmp = 0;
  137. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  138. {
  139. fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
  140. fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
  141. }
  142. // 依次写入每个模型
  143. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  144. {
  145. // 得到模型的文件偏移值,写入索引表
  146. fseek(fp_DHMM_Model_File, 0, SEEK_END);
  147. l_Word_Sample_Offset = ftell(fp_DHMM_Model_File);
  148. fseek(fp_DHMM_Model_File, 200 + 4 * 2 * (n_Model_Index), SEEK_SET);
  149. fwrite(&l_Word_Sample_Offset, sizeof(long), 1, fp_DHMM_Model_File);
  150. fseek(fp_DHMM_Model_File, l_Word_Sample_Offset, SEEK_SET);
  151. // Pi
  152. fwrite(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
  153. // A
  154. for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
  155. {
  156. fwrite(pu_DHMM_Model[n_Model_Index].d2dda_A[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
  157. }
  158. // B
  159. fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
  160. for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
  161. {
  162. fwrite(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
  163. }
  164. fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
  165. }
  166. fclose(fp_DHMM_Model_File);
  167. return 0;
  168. }
  169. //////////////////////////////////////////////////////////////////////
  170. // 函数名称:DHMM_Model_Load_DHMM_Model_File_With_Silence
  171. // 函数功能:从文件读入带静音的DHMM模型
  172. // 函数性质:API
  173. // 输入参数:
  174. // sz_Toload_DHMM_Model_File_Name,存储模型的文件名
  175. // n_DHMM_Model_Num,要读取的模型个数
  176. // 输出参数:
  177. // pu_DHMM_Model,存放读出的DHMM模型
  178. // 返回值:
  179. // 0 表示成功
  180. // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
  181. // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
  182. int DHMM_Model_Load_DHMM_Model_File_With_Silence(char * sz_Toload_DHMM_Model_File_Name,
  183. DHMM_MODEL * pu_DHMM_Model, int n_DHMM_Model_Num)
  184. {
  185. FILE * fp_DHMM_Model_File;
  186. DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
  187. int * pn_DHMM_Model_Offset;
  188. int n_Model_Index, n_State_Index;
  189. long lTmp;
  190. CString Silence_File(sz_Toload_DHMM_Model_File_Name);
  191. Silence_File.Replace(".DAT", "WS.DAT");
  192. fp_DHMM_Model_File = fopen(Silence_File, "rb");
  193. ASSERT(fp_DHMM_Model_File != NULL);
  194. fread(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);
  195. ASSERT(u_DHMM_Model_File_Head.lVersion >= DAT_FILE_VERSION);
  196. // ASSERT(u_DHMM_Model_File_Head.sDHMM_Model_Num == u_Pro_Config.n_DHMM_Model_Num);
  197. // ASSERT(u_DHMM_Model_File_Head.sModelStateNum == pu_DHMM_Model->n_State_Num);
  198. pn_DHMM_Model_Offset = new int[n_DHMM_Model_Num];
  199. ASSERT(pn_DHMM_Model_Offset != NULL);
  200. // 读入每个模型的文件偏移
  201. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  202. {
  203. fread(&pn_DHMM_Model_Offset[n_Model_Index], sizeof(long), 1, fp_DHMM_Model_File);
  204. fread(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
  205. }
  206. // 依次读入每个模型数据
  207. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  208. {
  209. pu_DHMM_Model[n_Model_Index].n_State_Num = u_DHMM_Model_File_Head.sModelStateNum;
  210. pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_DHMM_Model_File_Head.sCodeBookSize;
  211. fseek(fp_DHMM_Model_File, pn_DHMM_Model_Offset[n_Model_Index], SEEK_SET);
  212. // Pi
  213. fread(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
  214. // A
  215. for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
  216. {
  217. fread(pu_DHMM_Model[n_Model_Index].d2dda_A[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
  218. }
  219. // B
  220. for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum; n_State_Index++)
  221. {
  222. fread(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
  223. }
  224. }
  225. delete[] pn_DHMM_Model_Offset;
  226. fclose(fp_DHMM_Model_File);
  227. return 0;
  228. }
  229. //////////////////////////////////////////////////////////////////////
  230. // 函数名称:DHMM_Model_To_519_Model
  231. // 函数功能:向文件写入可以用于519系统的定点,对数化,DHMM模型。
  232. // 函数性质:API
  233. // 备注:关于DHMM_MODEL的定义,参见公共的.H文件
  234. // 模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
  235. int DHMM_Model_To_519_Model(void)
  236. {
  237. DHMM_MODEL * pu_DHMM_Model;
  238. int n_Model_Index;
  239. int n_DHMM_Model_Num;
  240. int nRetCode;
  241. char ModelFile[256];
  242. strcpy(ModelFile, u_Pro_Config.sz_Toload_DHMM_Model_File_Name);
  243. n_DHMM_Model_Num = u_Pro_Config.n_DHMM_Model_Num;
  244. if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
  245. | ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
  246. {
  247. u_Pro_Config.n_DHMM_Model_State_Num += 2;
  248. }
  249. // 为DHMM模型准备内存
  250. pu_DHMM_Model = new DHMM_MODEL[n_DHMM_Model_Num];
  251. ASSERT(pu_DHMM_Model);
  252. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  253. {
  254. pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
  255. pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
  256. pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
  257. pu_DHMM_Model[n_Model_Index].d2dda_A = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
  258. pu_DHMM_Model[n_Model_Index].d2dda_B = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  259. ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
  260. && (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
  261. && (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
  262. }
  263. double** d2dda_B;
  264. double** d2dda_LogB = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  265. ASSERT((d2dda_LogB != NULL));
  266. if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
  267. | ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
  268. {
  269. nRetCode = DHMM_Model_Load_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, n_DHMM_Model_Num);
  270. }
  271. ASSERT(nRetCode == 0);
  272. CString model_519file = u_Pro_Config.sz_Toload_DHMM_Model_File_Name;
  273. model_519file.Replace(".DAT", "519.dat");
  274. FILE *fp_DHMM_Model_File, *fp_DHMM_Model_TXT_File, *fp_DHMM_Model_BIN_File;
  275. fp_DHMM_Model_File = fopen(model_519file, "wb");
  276. fp_DHMM_Model_TXT_File = fopen("..//..//data//modelTXT.dat","wb+");
  277. fp_DHMM_Model_BIN_File = fopen("..//..//data//modelBIN.dat","wb+");
  278. ASSERT(fp_DHMM_Model_File != NULL);
  279. short data;
  280. // 依次写入每个模型
  281. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  282. {
  283. d2dda_B = pu_DHMM_Model[n_Model_Index].d2dda_B;
  284. // B
  285. for (int n_State_Index = 0; n_State_Index < u_Pro_Config.n_DHMM_Model_State_Num; n_State_Index++)
  286. {
  287. for(int n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
  288. {
  289. if (d2dda_B[n_State_Index][n_Code_Word_Index] < EPSILON_DOUBLE_VALUE)
  290. d2dda_B[n_State_Index][n_Code_Word_Index] = EPSILON_DOUBLE_VALUE;
  291. d2dda_LogB[n_State_Index][n_Code_Word_Index]
  292. = (int)(log10(d2dda_B[n_State_Index][n_Code_Word_Index]) * (65536L / LOG_SCALE) + 32768L/* + 0.5F*/);
  293. ASSERT((d2dda_LogB[n_State_Index][n_Code_Word_Index] >= short(MIN_SHORT_VALUE)) && (d2dda_LogB[n_State_Index][n_Code_Word_Index] <= MAX_SHORT_VALUE));
  294. data = (short)d2dda_LogB[n_State_Index][n_Code_Word_Index];
  295. fwrite(&data,sizeof(short),1,fp_DHMM_Model_File);
  296. // if ((n_Model_Index < 15) || (n_Model_Index > 15 && n_Model_Index < 20)
  297. // || (n_Model_Index > 25 && n_Model_Index < 34))
  298. {
  299. fwrite(&data,sizeof(short),1,fp_DHMM_Model_BIN_File);
  300. fprintf(fp_DHMM_Model_TXT_File,"%d,",data);
  301. }
  302. }
  303. }
  304. fprintf(fp_DHMM_Model_TXT_File,"n");
  305. }
  306. fclose(fp_DHMM_Model_File);
  307. fclose(fp_DHMM_Model_TXT_File);
  308. fclose(fp_DHMM_Model_BIN_File);
  309. d2dda_Free(d2dda_LogB, pu_DHMM_Model->n_State_Num, pu_DHMM_Model->n_Code_Book_Size);
  310. // 释放模型占用内存
  311. for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
  312. {
  313. delete[] pu_DHMM_Model[n_Model_Index].pdPi;
  314. d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_A, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_DHMM_Model_State_Num);
  315. d2dda_Free(pu_DHMM_Model[n_Model_Index].d2dda_B, u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
  316. }
  317. delete[] pu_DHMM_Model;
  318. if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
  319. u_Pro_Config.n_DHMM_Model_State_Num -= 2;
  320. else if((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) ==  MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
  321. u_Pro_Config.n_DHMM_Model_State_Num -= 2;
  322. return 0;
  323. }
  324. //////////////////////////////////////////////////////////////////////
  325. // 函数名称:DHMM_Model_Train_All_DHMM_Model
  326. // 函数功能:训练所有词的DHMM模型
  327. // 函数性质:API
  328. // 输入参数:
  329. // n_DHMM_Model_Num,要训练的模型个数
  330. // 输出参数:
  331. // pu_DHMM_Model,存放训好的DHMM模型
  332. // 返回值:
  333. // 0 表示成功
  334. // 备注:关于训练的细节参数,均在u_Pro_Config中指定,
  335. // n_Feature_Person_Num,总的语料库人数
  336. // n_DHMM_Model_Train_Set_Person_Num,训练集的人数
  337. // n_DHMM_Model_Person_Start_Index,训练集起始人的标号,
  338. // 训练集将从此人顺序持续指定人数,标号越界自动折返到0
  339. int DHMM_Model_Train_All_DHMM_Model(DHMM_MODEL * pu_DHMM_Model, int n_DHMM_Model_Num)
  340. {
  341. int nRetCode;
  342. char sz_Feature_File_Name[256];
  343. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
  344. WORD_SAMPLE * pu_Word_Sample;
  345. int n_Word_Sample_Index, n_Person_Index, n_Train_Set_Person_Index;
  346. // 读入码书
  347. d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  348. ASSERT(d2dda_Code_Book != NULL);
  349. nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  350. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  351. ASSERT(nRetCode == 0);
  352. ASSERT((0 <= u_Pro_Config.n_DHMM_Model_Person_Start_Index) && (u_Pro_Config.n_DHMM_Model_Person_Start_Index < u_Pro_Config.n_Feature_Person_Num)
  353. && (0 <= u_Pro_Config.n_DHMM_Model_Person_End_Index) && (u_Pro_Config.n_DHMM_Model_Person_End_Index < u_Pro_Config.n_Feature_Person_Num));
  354. // 为训练集的词条准备内存
  355. pu_Word_Sample = new WORD_SAMPLE[u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num];
  356. ASSERT(pu_Word_Sample != NULL);
  357. // 该重循环,训练每一个词条的模型
  358. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < u_Pro_Config.n_DHMM_Model_Num; n_Word_Sample_Index++)
  359. {
  360. int Sen_Index = n_Word_Sample_Index + u_Pro_Config.n_Sentence_Start_Index;
  361. // 该重循环,对一个词条,用所有训练集进行训练的数据准备
  362. n_Train_Set_Person_Index = 0;
  363. for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
  364. {
  365. // 跳过测试集的人
  366. if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
  367. {
  368. if ((n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index) || (n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index)) continue;
  369. }
  370. else
  371. {
  372. if ((n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index) && (n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index)) continue;
  373. }
  374. // 准备该词条的内存空间
  375. sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
  376. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = dfa_Feature_Get_Sentence_Frame_Num(sz_Feature_File_Name, Sen_Index);
  377. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim = u_Pro_Config.n_Feature_Dim;
  378. pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence =
  379. d2dda_New(pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
  380. pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence = 
  381. new int[pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len];
  382. ASSERT((pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence  != NULL)
  383. && (pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence != NULL));
  384. // 读入特征参数
  385. nRetCode = dfa_Feature_Read_A_Sentence(sz_Feature_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim,
  386. pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence);
  387. ASSERT(nRetCode == pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len);
  388. // VQ特征
  389. DHMM_VQ_Encode_A_Word_Sample(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim,
  390. &pu_Word_Sample[n_Train_Set_Person_Index]);
  391. // 释放原始的特征参数占用空间
  392. d2dda_Free(pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence,
  393. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
  394. n_Train_Set_Person_Index++;
  395. }
  396. ASSERT(n_Train_Set_Person_Index == u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num);
  397. PRO_LOG("Model:tTraining Model %4d of %4d.n", n_Word_Sample_Index, u_Pro_Config.n_DHMM_Model_Num);
  398. // 训练一个词条的模型
  399. DHMM_Model_Train_DHMM_Model(pu_Word_Sample, u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num, &pu_DHMM_Model[n_Word_Sample_Index]);
  400. // 释放VQ后的特征占用的内存
  401. for (n_Train_Set_Person_Index = 0; n_Train_Set_Person_Index < u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num; n_Train_Set_Person_Index++)
  402. {
  403. delete[] pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence;
  404. }
  405. }
  406. // 释放所有训练集的词条所占内存,释放码书内存
  407. delete[] pu_Word_Sample;
  408. d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  409. return 0;
  410. }
  411. //////////////////////////////////////////////////////////////////////
  412. // 函数名称:DHMM_Model_Train_Silence_DHMM_Model
  413. // 函数功能:训练静音的单状态DHMM模型
  414. // 函数性质:API
  415. // 输入参数:
  416. // n_DHMM_Model_Num,要训练的模型个数
  417. // 输出参数:
  418. // pu_DHMM_Model,存放训好的DHMM模型
  419. // 返回值:
  420. // 0 表示成功
  421. // 备注:关于训练的细节参数,均在u_Pro_Config中指定,
  422. // n_Feature_Person_Num,总的语料库人数
  423. // n_DHMM_Model_Train_Set_Person_Num,训练集的人数
  424. // n_DHMM_Model_Person_Start_Index,训练集起始人的标号,
  425. // 训练集将从此人顺序持续指定人数,标号越界自动折返到0
  426. int DHMM_Model_Train_Silence_DHMM_Model(DHMM_MODEL * pu_DHMM_Model)
  427. {
  428. int nRetCode;
  429. char sz_Feature_File_Name[256];
  430. char sz_Silence_File_Name[256];
  431. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
  432. WORD_SAMPLE * pu_Word_Sample;
  433. int n_Word_Sample_Index, n_Person_Index, n_Train_Set_Person_Index;
  434. int n_DHMM_Model_Train_Set_Person_Num; 
  435. int     i, j/*, k,  n,  m*/;
  436. int  Status_num = 1;
  437. int     Output_num = u_Pro_Config.n_VQ_Code_Book_Size; // VQ码本大小(码字个数)
  438. double  *Pi; // 初始概率
  439. double  **A; // A矩阵:Status_num*Status_num
  440. double  **B; // B矩阵:Status_num*Output_num
  441. double  w;
  442. // Generate (A, B, Pi)
  443. Pi = pu_DHMM_Model->pdPi; // The above block transform to this line. #DongMing#
  444. // allocate memory for A matrix
  445. A = pu_DHMM_Model->d2dda_A; // The above block transform to this line. #DongMing#
  446. // allocate memory for B matrix
  447. B = pu_DHMM_Model->d2dda_B; // The above block transform to this line. #DongMing#
  448. // 初始化初始概率Pi:状态0概率为1,其余状态概率为0
  449. Pi[0] = 1;
  450. for(i=1; i<Status_num; i++) Pi[i] = 0;
  451. for(i=0; i<Status_num; i++)
  452. {
  453. // 初始化A矩阵
  454. for(j=0; j<Status_num; j++) A[i][j] = 0;
  455. if(i < Status_num-1)
  456. {
  457. A[i][i]   = 0.5;
  458. A[i][i+1] = 0.5;
  459. }
  460. else
  461. {
  462. A[i][i]   = 1.0;
  463. }
  464. // 归一化A矩阵
  465. w = 0;
  466. for(j=0; j<Status_num; j++) w = w + A[i][j];
  467. for(j=0; j<Status_num; j++) A[i][j] = A[i][j] / w;
  468. w = 0;
  469. // 初始化B矩阵
  470. for(j=0; j<Output_num; j++)
  471. {
  472. B[i][j] = 1.0 / Output_num * (0.9 + ((rand()%1000) / 5000.0));
  473. w = w + B[i][j];
  474. }
  475. // 归一化B矩阵
  476. for(j=0; j<Output_num; j++) B[i][j] = 0; //B[i][j] / w;
  477. }
  478. // 读入码书
  479. d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  480. ASSERT(d2dda_Code_Book != NULL);
  481. nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  482. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  483. ASSERT(nRetCode == 0);
  484. ASSERT((0 <= u_Pro_Config.n_DHMM_Model_Person_Start_Index) && (u_Pro_Config.n_DHMM_Model_Person_Start_Index < u_Pro_Config.n_Feature_Person_Num)
  485. && (0 <= u_Pro_Config.n_DHMM_Model_Person_End_Index) && (u_Pro_Config.n_DHMM_Model_Person_End_Index < u_Pro_Config.n_Feature_Person_Num));
  486. // 为训练集的词条准备内存
  487. pu_Word_Sample = new WORD_SAMPLE[u_Pro_Config.n_DHMM_Model_Train_Set_Person_Num * u_Pro_Config.n_DHMM_Model_Num];
  488. ASSERT(pu_Word_Sample != NULL);
  489. n_Train_Set_Person_Index = 0;
  490. // 该重循环,加载每一个词条的静音数据
  491. for (n_Word_Sample_Index = 0; n_Word_Sample_Index < u_Pro_Config.n_DHMM_Model_Num; n_Word_Sample_Index++)
  492. {
  493. int Sen_Index = n_Word_Sample_Index + u_Pro_Config.n_Sentence_Start_Index;
  494. // 该重循环,对一个词条,用所有训练集进行训练的数据准备
  495. for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
  496. {
  497. // 跳过测试集的人
  498. if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
  499. {
  500. if ((n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index) || (n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index)) continue;
  501. }
  502. else
  503. {
  504. if ((n_Person_Index > u_Pro_Config.n_DHMM_Model_Person_End_Index) && (n_Person_Index < u_Pro_Config.n_DHMM_Model_Person_Start_Index)) continue;
  505. }
  506. // 修改文件名
  507. sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
  508. strcpy(sz_Silence_File_Name, sz_Feature_File_Name);
  509. int j = strlen(sz_Silence_File_Name) - 4;
  510. sz_Silence_File_Name[j] = '';
  511. strcat(sz_Silence_File_Name,"_sl.dat");
  512. // 准备该词条的内存空间
  513. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = dfa_Feature_Get_Silence_Frame_Num(sz_Silence_File_Name, Sen_Index);
  514. //pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len = 2 * RELAX_FRAME;
  515. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim = u_Pro_Config.n_Feature_Dim;
  516. pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence =
  517. d2dda_New(pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
  518. pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence = 
  519. new int[pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len];
  520. ASSERT((pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence  != NULL)
  521. && (pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence != NULL));
  522. // 读入特征参数
  523. nRetCode = dfa_Feature_Read_A_Silence(sz_Silence_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim,
  524. pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence);
  525. ASSERT(nRetCode == pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len);
  526. // VQ特征
  527. DHMM_VQ_Encode_A_Word_Sample(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim,
  528. &pu_Word_Sample[n_Train_Set_Person_Index]);
  529. // 释放原始的特征参数占用空间
  530. d2dda_Free(pu_Word_Sample[n_Train_Set_Person_Index].d2dda_Feature_Sequence,
  531. pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Sequence_Len, pu_Word_Sample[n_Train_Set_Person_Index].n_Feature_Dim);
  532. n_Train_Set_Person_Index++;
  533. }
  534. }
  535. PRO_LOG("Model:tTraining Silence Model...n");
  536.     n_DHMM_Model_Train_Set_Person_Num = n_Train_Set_Person_Index;
  537. int fr_num;
  538. for(i = 0; i < n_DHMM_Model_Train_Set_Person_Num; i++)
  539. {
  540. fr_num = pu_Word_Sample[i].n_Feature_Sequence_Len;
  541. for(j = 0; j < fr_num; j++)
  542. B[0][pu_Word_Sample[i].pn_VQed_Feature_Sequence[j]]++;
  543. }
  544. // 释放VQ后的特征占用的内存
  545. for (n_Train_Set_Person_Index = 0; n_Train_Set_Person_Index < n_DHMM_Model_Train_Set_Person_Num; n_Train_Set_Person_Index++)
  546. {
  547. delete[] pu_Word_Sample[n_Train_Set_Person_Index].pn_VQed_Feature_Sequence;
  548. }
  549. for(i = 0; i < Output_num; i++)
  550. {
  551. B[0][i] /= (fr_num * n_DHMM_Model_Train_Set_Person_Num);
  552. if (B[0][i] < Epsilon_B)
  553. B[0][i] = Epsilon_B;
  554. }
  555. for(j=0; j<Output_num; j++)
  556. w = w + B[0][j];
  557. // 归一化B矩阵
  558. for(j=0; j<Output_num; j++) B[0][j] = B[0][j] / w;
  559. // 释放所有训练集的词条所占内存,释放码书内存
  560. delete[] pu_Word_Sample;
  561. d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  562. return 0;
  563. }
  564. //////////////////////////////////////////////////////////////////////
  565. // 函数名称:DHMM_Model_Train_DHMM_Model
  566. // 函数功能:训练一个词的DHMM模型
  567. // 函数性质:API
  568. // 输入参数:
  569. // pu_Word_Sample,存放该词训练集的数据
  570. // n_Word_Sample_Num,训练集的词数
  571. // 输出参数:
  572. // pu_DHMM_Model,存放训好的DHMM模型
  573. // 返回值:
  574. // 0 表示成功
  575. // 备注:WORD_SAMPLE的定义,参见公共的.H文件
  576. // 该函数是一个分发函数,按照u_Pro_Config.l_DHMM_Model_Config配置的信息
  577. // 将具体调用不同的函数体
  578. int DHMM_Model_Train_DHMM_Model(WORD_SAMPLE * pu_Word_Sample, int n_Word_Sample_Num,
  579. DHMM_MODEL * pu_DHMM_Model)
  580. {
  581. switch (u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_TRAIN_PROCEDURE_MASK)
  582. {
  583. case MODEL_CONFIG_TRAIN_PROCEDURE_STD:
  584. ASSERT(0);
  585. break;
  586. case MODEL_CONFIG_TRAIN_PROCEDURE_GL:
  587. return DHMM_Model_Train_DHMM_Model_GL(pu_Word_Sample, n_Word_Sample_Num, pu_DHMM_Model);
  588. break;
  589. case MODEL_CONFIG_TRAIN_PROCEDURE_LHS:
  590. ASSERT(0); //LHS的训练过程,与GL的完全相同,故略去
  591. break;
  592. case MODEL_CONFIG_TRAIN_PROCEDURE_HQ:
  593. return DHMM_Model_Train_DHMM_Model_HQ(pu_Word_Sample, n_Word_Sample_Num, pu_DHMM_Model);
  594. break;
  595. case MODEL_CONFIG_TRAIN_PROCEDURE_WP:
  596. ASSERT(0);
  597. break;
  598. default:
  599. ASSERT(0);
  600. break;
  601. }
  602. return 0;
  603. }