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

DSP编程

开发平台:

Visual C++

  1. // DHMM_VQ_MFC.cpp:
  2. // Implementation of the DHMM_VQ_MFC Module.
  3. // That is to Train VQ Code_Book.
  4. //
  5. // Created 2001/08, By DongMing, MDSR.
  6. //
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "DHMM_VQ_MFC.h"
  10. #include "kwspot.h"
  11. #include "DAT_File_Access.h"
  12. #include "DHMM_GL.h"
  13. #include "DHMM_LHS.h"
  14. #include "DHMM_HQ.h"
  15. #include "DHMM_WP.h"
  16. //////////////////////////////////////////////////////////////////////
  17. // Private functions
  18. // 函数功能:将一个词的一帧特征进行VQ编码
  19. int DHMM_VQ_Encode_A_Code_Word(DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim,
  20.    double * pd_Code_Word);
  21. // 函数功能:将一个词的一帧特征进行VQ编码,定点程序
  22. int DHMM_VQ_Encode_A_Code_Word_FIX(DYNA_2DIM_INT_ARRAY d2dna_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim,
  23.    int * pn_Code_Word);
  24. extern PRO_CONFIG u_Pro_Config;
  25. //////////////////////////////////////////////////////////////////////
  26. // API functions
  27. //////////////////////////////////////////////////////////////////////
  28. // 函数名称:DHMM_VQ
  29. // 函数功能:DHMM程序进行码书训练模块的入口
  30. // 函数性质:API
  31. // 输入参数:
  32. // 无
  33. // 输出参数:
  34. // 无
  35. // 返回值:
  36. // 0 表示成功
  37. // 备注:本模块完成DHMM的码书训练,模块的应用接口实际上是基于文件的,
  38. // 训练的码书存放在u_Pro_Config.sz_Tmp_Code_Book_File_Name
  39. int DHMM_VQ(void)
  40. {
  41. int nRetCode;
  42. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
  43. DYNA_2DIM_DOUBLE_ARRAY d2dda_Total_Feature;
  44. long n_Total_Feature_Num;
  45. d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  46. ASSERT(d2dda_Code_Book != NULL);
  47. // Load_Only Code_Book
  48. if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_GENERATE_CODE_BOOK_MASK) == VQ_CONFIG_LOAD_ONLY_CODE_BOOK)
  49. {
  50. nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  51. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  52. ASSERT(nRetCode == 0);
  53. }
  54. // Train_Only Code_Book
  55. else if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_GENERATE_CODE_BOOK_MASK) == VQ_CONFIG_TRAIN_ONLY_CODE_BOOK)
  56. {
  57. nRetCode = DHMM_VQ_Load_All_Feature(&d2dda_Total_Feature, &n_Total_Feature_Num);
  58. ASSERT(nRetCode == 0);
  59. nRetCode = DHMM_VQ_Train_Code_Book(d2dda_Total_Feature, n_Total_Feature_Num, u_Pro_Config.n_Feature_Dim,
  60. NULL, d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size);
  61. ASSERT(nRetCode == 0);
  62. nRetCode = DHMM_VQ_Save_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  63. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  64. ASSERT(nRetCode == 0);
  65. DHMM_VQ_To_519_CodeBook();
  66. d2dda_Free(d2dda_Total_Feature, n_Total_Feature_Num, u_Pro_Config.n_Feature_Dim);
  67. }
  68. nRetCode = DHMM_VQ_Save_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  69. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  70. ASSERT(nRetCode == 0);
  71. d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  72. return 0;
  73. }
  74. //////////////////////////////////////////////////////////////////////
  75. // 函数名称:DHMM_VQ_Train_Code_Book
  76. // 函数功能:训练码书
  77. // 函数性质:API
  78. // 输入参数:
  79. // d2dda_Total_Feature,存放所有的特征
  80. // n_Total_Feature_Num,总的特征数
  81. // n_Code_Word_Dim,特征维数
  82. // d2dda_Initial_Code_Book,存放初始码书,允许为NULL,表示程序自动初始化
  83. // n_Code_Book_Size,码书大小
  84. // 输出参数:
  85. // d2dda_Code_Book,存放训好的码书
  86. // 返回值:
  87. // 0 表示成功
  88. // 备注:
  89. // 该函数是一个分发函数,按照u_Pro_Config.l_VQ_Config配置的信息
  90. // 将具体调用不同的函数体
  91. int DHMM_VQ_Train_Code_Book(DYNA_2DIM_DOUBLE_ARRAY d2dda_Total_Feature, int n_Total_Feature_Num, int n_Code_Word_Dim,
  92. DYNA_2DIM_DOUBLE_ARRAY d2dda_Initial_Code_Book, DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size)
  93. {
  94. switch (u_Pro_Config.l_VQ_Config & VQ_CONFIG_TRAIN_PROCEDURE_MASK)
  95. {
  96. case VQ_CONFIG_TRAIN_PROCEDURE_STD:
  97. ASSERT(0);
  98. break;
  99. case VQ_CONFIG_TRAIN_PROCEDURE_GL:
  100. return DHMM_VQ_Train_Code_Book_GL(d2dda_Total_Feature, n_Total_Feature_Num, n_Code_Word_Dim,
  101. d2dda_Initial_Code_Book, d2dda_Code_Book, n_Code_Book_Size);
  102. break;
  103. case VQ_CONFIG_TRAIN_PROCEDURE_LHS:
  104. ASSERT(0); //LHS的训练过程,与GL的完全相同,故略去
  105. break;
  106. case VQ_CONFIG_TRAIN_PROCEDURE_HQ:
  107. return DHMM_VQ_Train_Code_Book_HQ(d2dda_Total_Feature, n_Total_Feature_Num, n_Code_Word_Dim,
  108. d2dda_Initial_Code_Book, d2dda_Code_Book, n_Code_Book_Size);
  109. break;
  110. case VQ_CONFIG_TRAIN_PROCEDURE_WP:
  111. return DHMM_VQ_Train_Code_Book_WP(d2dda_Total_Feature, n_Total_Feature_Num, n_Code_Word_Dim,
  112. d2dda_Initial_Code_Book, d2dda_Code_Book, n_Code_Book_Size);
  113. break;
  114. default:
  115. ASSERT(0);
  116. break;
  117. }
  118. return 0;
  119. }
  120. //////////////////////////////////////////////////////////////////////
  121. // 函数名称:DHMM_VQ_Save_Code_Book_File
  122. // 函数功能:向.DAT格式的码书文件中存储码书
  123. // 函数性质:API
  124. // 输入参数:
  125. // sz_Tosave_Code_Book_File_Name,存放码书的文件名
  126. // n_Code_Book_Size,码书的大小(VQ的结果数)
  127. // n_Code_Word_Dim,每个码字的维数
  128. // 输出参数:
  129. // d2dda_Code_Book,存放待写入的码书
  130. // 返回值:
  131. // 0 表示成功
  132. // 备注:
  133. // 码书存储使用.DAT格式中的码书存储格式,可参见DAT_File_Access模块
  134. int DHMM_VQ_Save_Code_Book_File(char * sz_Tosave_Code_Book_File_Name,
  135. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim)
  136. {
  137. FILE * fp_Code_Book_File;
  138. CODE_BOOK_FILE_HEAD u_Code_Book_File_Head;
  139. long l_Word_Sample_Offset;
  140. int n_Code_Word_Index;
  141. long lTmp;
  142. fp_Code_Book_File = fopen(sz_Tosave_Code_Book_File_Name, "wb");
  143. ASSERT(fp_Code_Book_File != NULL);
  144. memset(&u_Code_Book_File_Head, 0, sizeof(u_Code_Book_File_Head));
  145. u_Code_Book_File_Head.lVersion = DAT_FILE_VERSION;
  146. strcpy(u_Code_Book_File_Head.szName, "CodeBook");
  147. u_Code_Book_File_Head.sCodeBookNum = u_Code_Book_File_Head.sCodeBookNum2 = 1;
  148. strcpy(u_Code_Book_File_Head.szParameterType, "CodeBook");
  149. u_Code_Book_File_Head.sSampleType = SAMPLE_DATA_TYPE_DOUBLE;
  150. u_Code_Book_File_Head.sFeatureOrder = n_Code_Word_Dim;
  151. u_Code_Book_File_Head.sCodeBookSize = n_Code_Book_Size;
  152. ASSERT(sizeof(u_Code_Book_File_Head) == 200);
  153. fwrite(&u_Code_Book_File_Head, sizeof(u_Code_Book_File_Head), 1, fp_Code_Book_File);
  154. lTmp = 0;
  155. fwrite(&lTmp, sizeof(long), 1, fp_Code_Book_File);
  156. fwrite(&lTmp, sizeof(long), 1, fp_Code_Book_File);
  157. fseek(fp_Code_Book_File, 0, SEEK_END);
  158. l_Word_Sample_Offset = ftell(fp_Code_Book_File);
  159. fseek(fp_Code_Book_File, 200 + 4 * 2 * (0), SEEK_SET);
  160. fwrite(&l_Word_Sample_Offset, sizeof(long), 1, fp_Code_Book_File);
  161. fwrite(&n_Code_Book_Size, sizeof(long), 1, fp_Code_Book_File);
  162. fseek(fp_Code_Book_File, l_Word_Sample_Offset, SEEK_SET);
  163. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  164. {
  165. fwrite(d2dda_Code_Book[n_Code_Word_Index], sizeof(double), n_Code_Word_Dim, fp_Code_Book_File);
  166. }
  167. fclose(fp_Code_Book_File);
  168. return 0;
  169. }
  170. //////////////////////////////////////////////////////////////////////
  171. // 函数名称:DHMM_VQ_Load_Code_Book_File
  172. // 函数功能:从.DAT格式的码书文件中读取码书
  173. // 函数性质:API
  174. // 输入参数:
  175. // sz_Toload_Code_Book_File_Name,存放码书的文件名
  176. // n_Code_Book_Size,码书的大小(VQ的结果数)
  177. // n_Code_Word_Dim,每个码字的维数
  178. // 输出参数:
  179. // d2dda_Code_Book,存放读出的码书
  180. // 返回值:
  181. // 0 表示成功
  182. // 备注:
  183. // 码书存储使用.DAT格式中的码书存储格式,可参见DAT_File_Access模块
  184. int DHMM_VQ_Load_Code_Book_File(char * sz_Toload_Code_Book_File_Name,
  185. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim)
  186. {
  187. FILE * fp_Code_Book_File;
  188. CODE_BOOK_FILE_HEAD u_Code_Book_File_Head;
  189. long l_Word_Sample_Offset;
  190. int n_Code_Word_Index;
  191. fp_Code_Book_File = fopen(sz_Toload_Code_Book_File_Name, "rb");
  192. ASSERT(fp_Code_Book_File != NULL);
  193. fread(&u_Code_Book_File_Head, sizeof(u_Code_Book_File_Head), 1, fp_Code_Book_File);
  194. ASSERT(u_Code_Book_File_Head.lVersion >= DAT_FILE_VERSION);
  195. ASSERT(u_Code_Book_File_Head.sCodeBookSize == n_Code_Book_Size);
  196. ASSERT(u_Code_Book_File_Head.sFeatureOrder == n_Code_Word_Dim);
  197. fread(&l_Word_Sample_Offset, sizeof(long), 1, fp_Code_Book_File);
  198. fseek(fp_Code_Book_File, l_Word_Sample_Offset, SEEK_SET);
  199. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  200. {
  201. fread(d2dda_Code_Book[n_Code_Word_Index], sizeof(double), n_Code_Word_Dim, fp_Code_Book_File);
  202. }
  203. fclose(fp_Code_Book_File);
  204. return 0;
  205. }
  206. //////////////////////////////////////////////////////////////////////
  207. // 函数名称:DHMM_VQ_Encode_A_Word_Sample
  208. // 函数功能:将一个词的所有帧特征进行VQ编码
  209. // 函数性质:API
  210. // 输入参数:
  211. // d2dda_Code_Book,存放码书
  212. // n_Code_Book_Size,码书大小
  213. // n_Code_Word_Dim,特征维数
  214. // pu_Word_Sample->d2dda_Feature_Sequence,待VQ的词每帧特征
  215. // 输出参数:
  216. // pu_Word_Sample->pn_VQed_Feature_Sequence,VQ后的词每帧特征
  217. // 返回值:
  218. // 0 表示成功
  219. // 备注:
  220. int DHMM_VQ_Encode_A_Word_Sample(DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim,
  221.  WORD_SAMPLE * pu_Word_Sample)
  222. {
  223. int n_Word_Sample_Frame_Index;
  224. ASSERT(n_Code_Word_Dim == pu_Word_Sample->n_Feature_Dim);
  225. for (n_Word_Sample_Frame_Index = 0; n_Word_Sample_Frame_Index < pu_Word_Sample->n_Feature_Sequence_Len; n_Word_Sample_Frame_Index++)
  226. {
  227. pu_Word_Sample->pn_VQed_Feature_Sequence[n_Word_Sample_Frame_Index] = 
  228. DHMM_VQ_Encode_A_Code_Word(d2dda_Code_Book, n_Code_Book_Size, n_Code_Word_Dim,
  229. pu_Word_Sample->d2dda_Feature_Sequence[n_Word_Sample_Frame_Index]);
  230. }
  231. return 0;
  232. }
  233. //////////////////////////////////////////////////////////////////////
  234. // 函数名称:DHMM_VQ_Encode_A_Code_Word
  235. // 函数功能:将一个词的一帧特征进行VQ编码
  236. // 函数性质:Private
  237. // 输入参数:
  238. // d2dda_Code_Book,存放码书
  239. // n_Code_Book_Size,码书大小
  240. // n_Code_Word_Dim,特征维数
  241. // pd_Code_Word,待VQ的一帧特征
  242. // 输出参数:
  243. // 无
  244. // 返回值:
  245. // VQ后的一帧特征
  246. // 备注:
  247. static int DHMM_VQ_Encode_A_Code_Word(DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book, int n_Code_Book_Size, int n_Code_Word_Dim,
  248.    double * pd_Code_Word)
  249. {
  250. int n_VQ_Result;
  251. double d_VQ_Result_Distance;
  252. int n_Code_Book_Word_Index, n_Code_Word_Dim_Index;
  253. double dTmp;
  254. double dSqr;
  255. n_VQ_Result = -1;
  256. d_VQ_Result_Distance = MAX_DOUBLE_VALUE;
  257. for (n_Code_Book_Word_Index = 0; n_Code_Book_Word_Index < n_Code_Book_Size; n_Code_Book_Word_Index++)
  258. {
  259. dTmp = 0.0F;
  260. for (n_Code_Word_Dim_Index = 0; n_Code_Word_Dim_Index < n_Code_Word_Dim; n_Code_Word_Dim_Index++)
  261. {
  262. dSqr = (pd_Code_Word[n_Code_Word_Dim_Index] - d2dda_Code_Book[n_Code_Book_Word_Index][n_Code_Word_Dim_Index])*32768/4;
  263. dTmp += dSqr * dSqr / 2;
  264. }
  265. if (dTmp < d_VQ_Result_Distance)
  266. {
  267. n_VQ_Result = n_Code_Book_Word_Index;
  268. d_VQ_Result_Distance = dTmp;
  269. }
  270. }
  271. return(n_VQ_Result);
  272. }
  273. int DHMM_VQ_To_519_CodeBook(void)
  274. {
  275. int nRetCode;
  276. DYNA_2DIM_DOUBLE_ARRAY d2dda_Code_Book;
  277. int n_Code_Word_Index;
  278. int n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
  279. int n_Code_Word_Dim = u_Pro_Config.n_Feature_Dim;
  280. d2dda_Code_Book = d2dda_New(u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  281. ASSERT(d2dda_Code_Book != NULL);
  282. nRetCode = DHMM_VQ_Load_Code_Book_File(u_Pro_Config.sz_Toload_Code_Book_File_Name,
  283. d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  284. ASSERT(nRetCode == 0);
  285. CString Code_Book_txt = u_Pro_Config.sz_Toload_Code_Book_File_Name;
  286. Code_Book_txt.Replace(".DAT","519.dat");
  287. FILE *fp_Code_Book_File = fopen(Code_Book_txt,"wb");
  288. // added by wangxia
  289. FILE *fp_Code_Book_TXT_File = fopen("..//..//data//codeTXT.dat","wb+");
  290. FILE *fp_Code_Book_BIN_File = fopen("..//..//data//codeBIN.dat","wb+");
  291. ASSERT(fp_Code_Book_File != NULL);
  292. short data;
  293. float f_data;
  294. for (n_Code_Word_Index = 0; n_Code_Word_Index < n_Code_Book_Size; n_Code_Word_Index++)
  295. {
  296. for(int dim = 0 ; dim < n_Code_Word_Dim; dim++)
  297. {
  298. f_data = ((d2dda_Code_Book[n_Code_Word_Index][dim]) * 32768L/4/* + 0.5F*/);
  299. ASSERT((f_data >= short(MIN_SHORT_VALUE)) && (f_data <= MAX_SHORT_VALUE));
  300. data = (short)f_data;
  301.             fwrite(&data, sizeof(short), 1, fp_Code_Book_File);
  302. fprintf(fp_Code_Book_TXT_File, "%d,",data);
  303. fwrite(&data, sizeof(short), 1, fp_Code_Book_BIN_File);
  304. }
  305. }
  306. d2dda_Free(d2dda_Code_Book, u_Pro_Config.n_VQ_Code_Book_Size, u_Pro_Config.n_Feature_Dim);
  307. fclose(fp_Code_Book_File);
  308. fclose(fp_Code_Book_TXT_File);
  309. fclose(fp_Code_Book_BIN_File);
  310. return 0;
  311. }
  312. //////////////////////////////////////////////////////////////////////
  313. // 函数名称:DHMM_VQ_Load_All_Feature
  314. // 函数功能:从语料库中读取全部的特征
  315. // 函数性质:API
  316. // 输入参数:
  317. // 无
  318. // 输出参数:
  319. // pd2dda_Total_Feature,存放读出的特征
  320. // pn_Total_Feature_Num,存放读出的总的特征数
  321. // 返回值:
  322. // 0 表示成功
  323. // 备注:
  324. // !!!!!该函数的内存分配策略特别,
  325. // 返回的存储全部码字的数组,由callee分配内存,因此,caller必须负责释放!!!!!
  326. // 特征文件的文件名格式在u_Pro_Config.sz_Feature_Origin_File_Name_Format指出,
  327. // 语料库人数在u_Pro_Config.n_Feature_Person_Num指出
  328. int DHMM_VQ_Load_All_Feature(DYNA_2DIM_DOUBLE_ARRAY * pd2dda_Total_Feature, long * pn_Total_Feature_Num)
  329. {
  330. int nRetCode;
  331. char sz_Feature_File_Name[256];
  332. char sz_Silence_File_Name[256];
  333. FEATURE_FILE_HEAD u_Feature_File_Head;
  334. long n_Total_Frame_Num;
  335. DYNA_2DIM_DOUBLE_ARRAY d2dda_All_Feature;
  336. int n_Person_Index, n_Sentence_Index, n_Total_Frame_Index;
  337. // 统计所有语料库的总特征数目
  338. n_Total_Frame_Num = 0;
  339. for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
  340. {
  341. // 如果只用训练集的特征训练VQ码本,则跳过统计测试集特征
  342. if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_LOAD_ALL_FEATURE_METHOD_MASK) == VQ_CONFIG_LOAD_TRAIN_SET_ONLY)
  343. {
  344. if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
  345. {
  346. 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;
  347. }
  348. else
  349. {
  350. 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;
  351. }
  352. }
  353. else if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_LOAD_ALL_FEATURE_METHOD_MASK) == VQ_CONFIG_LOAD_ALL_FEATURE)
  354. {}
  355. sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
  356. nRetCode = dfa_Feature_Get_File_Info(sz_Feature_File_Name, &u_Feature_File_Head);
  357. ASSERT(nRetCode == 0);
  358. //ASSERT((u_Feature_File_Head.sSentenceNum == u_Feature_File_Head.sSentenceNum2) && (u_Feature_File_Head.sSentenceNum == u_Pro_Config.n_Feature_Sentence_Num)); ASSERT(u_Feature_File_Head.sFeatureOrder == u_Pro_Config.n_Feature_Dim);
  359. n_Total_Frame_Num += dfa_Feature_Get_File_Total_Frame_Num(sz_Feature_File_Name, u_Pro_Config.n_Feature_Sentence_Num, u_Pro_Config.n_Sentence_Start_Index);
  360. if (u_Pro_Config.USE_SILENCE_FEA == 1)
  361. {
  362. strcpy(sz_Silence_File_Name, sz_Feature_File_Name);
  363. int j = strlen(sz_Silence_File_Name) - 4;
  364. sz_Silence_File_Name[j] = '';
  365. strcat(sz_Silence_File_Name,"_sl.dat");
  366. nRetCode = dfa_Feature_Get_File_Info(sz_Silence_File_Name, &u_Feature_File_Head);
  367. ASSERT(nRetCode == 0);
  368. ASSERT(u_Feature_File_Head.sFeatureOrder == u_Pro_Config.n_Feature_Dim);
  369. n_Total_Frame_Num += dfa_Feature_Get_Silence_Total_Frame_Num(sz_Silence_File_Name, u_Pro_Config.n_Feature_Sentence_Num, u_Pro_Config.n_Sentence_Start_Index);
  370. }
  371. }
  372. // 为存放所有特征分配内存
  373. d2dda_All_Feature = d2dda_New(n_Total_Frame_Num, u_Pro_Config.n_Feature_Dim);
  374. // 读入所有特征
  375. n_Total_Frame_Index = 0;
  376. for (n_Person_Index = 0; n_Person_Index < u_Pro_Config.n_Feature_Person_Num; n_Person_Index++)
  377. {
  378. // 如果只用训练集的特征训练VQ码本,则跳过读取测试集特征
  379. if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_LOAD_ALL_FEATURE_METHOD_MASK) == VQ_CONFIG_LOAD_TRAIN_SET_ONLY)
  380. {
  381. if (u_Pro_Config.n_DHMM_Model_Person_Start_Index <= u_Pro_Config.n_DHMM_Model_Person_End_Index)
  382. {
  383. 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;
  384. }
  385. else
  386. {
  387. 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;
  388. }
  389. }
  390. else if ((u_Pro_Config.l_VQ_Config & VQ_CONFIG_LOAD_ALL_FEATURE_METHOD_MASK) == VQ_CONFIG_LOAD_ALL_FEATURE)
  391. {}
  392. sprintf(sz_Feature_File_Name, u_Pro_Config.sz_Feature_Origin_File_Name_Format, n_Person_Index);
  393. for(n_Sentence_Index = 0; n_Sentence_Index < u_Pro_Config.n_Feature_Sentence_Num; n_Sentence_Index++)
  394. {
  395. int Sen_Index = n_Sentence_Index + u_Pro_Config.n_Sentence_Start_Index;
  396. int framenum = dfa_Feature_Read_A_Sentence(sz_Feature_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim, &d2dda_All_Feature[n_Total_Frame_Index]);
  397. ASSERT(framenum >= 0);
  398. n_Total_Frame_Index += framenum;
  399. if (u_Pro_Config.USE_SILENCE_FEA == 1)
  400. {
  401. strcpy(sz_Silence_File_Name, sz_Feature_File_Name);
  402. int j = strlen(sz_Silence_File_Name) - 4;
  403. sz_Silence_File_Name[j] = '';
  404. strcat(sz_Silence_File_Name,"_sl.dat");
  405. framenum = dfa_Feature_Read_A_Silence(sz_Silence_File_Name, Sen_Index, u_Pro_Config.n_Feature_Dim, &d2dda_All_Feature[n_Total_Frame_Index]);
  406. ASSERT(framenum >= 0);
  407. n_Total_Frame_Index += framenum;
  408. }
  409. }
  410. }
  411. ASSERT(n_Total_Frame_Index == n_Total_Frame_Num);
  412. *pd2dda_Total_Feature = d2dda_All_Feature;
  413. *pn_Total_Feature_Num = n_Total_Frame_Num;
  414. return 0;
  415. }