⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhmm_model_mfc.cpp

📁 语音识别配套的VQ及DHMM模型训练程序(C语言)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	DHMM_MODEL_MFC.cpp:
//		Implementation of the DHMM_MODEL_MFC Module.
//		That is to train DHMM_Model.
//
//	Created 2001/08, By DongMing, MDSR.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DHMM_Model_MFC.h"
#include "kwspot.h"
#include "DAT_File_Access.h"
#include "DHMM_VQ_MFC.h"

#include "DHMM_GL.h"
#include "DHMM_LHS.h"
#include "DHMM_HQ.h"

extern PRO_CONFIG u_Pro_Config;

//////////////////////////////////////////////////////////////////////
//	API functions

//////////////////////////////////////////////////////////////////////
//	函数名称:DHMM_Model
//	函数功能:DHMM程序进行模型训练模块的入口
//	函数性质:API
//	输入参数:
//		无
//	输出参数:
//		无
//	返回值:
//		0 表示成功
//	备注:本模块完成DHMM模型训练,模块的应用接口实际上是基于文件的,
//		训练的结果将保存在u_Pro_Config.sz_Toload_DHMM_Model_File_Name中
int DHMM_Model(void)
{
	int nRetCode;
	DHMM_MODEL * pu_DHMM_Model;
	int n_Model_Index;
	DHMM_MODEL Silence_Model;
	int Total_Model_Num;

	if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
	{
		//  为静音模型多准备两个状态
		u_Pro_Config.n_DHMM_Model_State_Num += 2;
	}
	Total_Model_Num =u_Pro_Config.n_DHMM_Model_Num;

	//	为DHMM模型准备内存
	pu_DHMM_Model = new DHMM_MODEL[Total_Model_Num];
	ASSERT(pu_DHMM_Model);
	for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
	{
		pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
		pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
		pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
		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);
		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);
		ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
			&& (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
			&& (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
	}

	Silence_Model.n_State_Num = 1;
	Silence_Model.n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
	Silence_Model.pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
	Silence_Model.d2dda_A = d2dda_New(Silence_Model.n_State_Num, Silence_Model.n_State_Num);
	Silence_Model.d2dda_B = d2dda_New(Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
	ASSERT((Silence_Model.pdPi != NULL)
		&& (Silence_Model.d2dda_A != NULL)
		&& (Silence_Model.d2dda_B != NULL));

	//	Load_Only With Silence DHMM_Model
	if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
	{
		nRetCode = DHMM_Model_Load_DHMM_Model_File_With_Silence(u_Pro_Config.sz_Toload_DHMM_Model_File_Name, pu_DHMM_Model, Total_Model_Num);
		ASSERT(nRetCode == 0);
	}
	//	Train_Only With Silence DHMM_Model
	else if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL)
	{
		nRetCode = DHMM_Model_Train_Silence_DHMM_Model(&Silence_Model);
		nRetCode = DHMM_Model_Train_All_DHMM_Model(pu_DHMM_Model, u_Pro_Config.n_DHMM_Model_Num);
		ASSERT(nRetCode == 0);
		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);
		ASSERT(nRetCode == 0);
	}

	//	释放模型占用内存
	for (n_Model_Index = 0; n_Model_Index < Total_Model_Num; n_Model_Index++)
	{
		delete[] pu_DHMM_Model[n_Model_Index].pdPi;
		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);
		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);
	}
	delete[] pu_DHMM_Model;
	if ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)
	{
		//  为静音模型多准备两个状态
		u_Pro_Config.n_DHMM_Model_State_Num -= 2;
	}

	delete [] Silence_Model.pdPi;
	d2dda_Free(Silence_Model.d2dda_A, Silence_Model.n_State_Num, Silence_Model.n_State_Num);
	d2dda_Free(Silence_Model.d2dda_B, Silence_Model.n_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);

	return 0;
}

//////////////////////////////////////////////////////////////////////
//	函数名称:DHMM_Model_Save_DHMM_Model_File_With_Silence
//	函数功能:向文件写入DHMM模型
//	函数性质:API
//	输入参数:
//		sz_Tosave_DHMM_Model_File_Name,存储模型的文件名
//		n_DHMM_Model_Num,要存储的模型个数
//	输出参数:
//		pu_DHMM_Model,存放待写入的DHMM模型
//	返回值:
//		0 表示成功
//	备注:关于DHMM_MODEL的定义,参见公共的.H文件
//		模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
int DHMM_Model_Save_DHMM_Model_File_With_Silence(char * sz_Tosave_DHMM_Model_File_Name,
									DHMM_MODEL * pu_DHMM_Model, DHMM_MODEL * pu_Silence_Model, int n_DHMM_Model_Num)
{
	FILE * fp_DHMM_Model_File;
	DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
	long l_Word_Sample_Offset;
	int n_Model_Index, n_State_Index;
	long lTmp;

	CString Silence_File(sz_Tosave_DHMM_Model_File_Name);
	Silence_File.Replace(".DAT", "WS.DAT");
	fp_DHMM_Model_File = fopen(Silence_File, "wb");
	ASSERT(fp_DHMM_Model_File != NULL);

	//	填写模型文件头
	memset(&u_DHMM_Model_File_Head, 0, sizeof(u_DHMM_Model_File_Head));
	u_DHMM_Model_File_Head.lVersion = DAT_FILE_VERSION;
	strcpy(u_DHMM_Model_File_Head.szName, "DHMM_Model");
	u_DHMM_Model_File_Head.sDHMM_Model_Num = u_DHMM_Model_File_Head.sDHMM_Model_Num2 = n_DHMM_Model_Num;
	strcpy(u_DHMM_Model_File_Head.szParameterType, "DHMMModel");
	u_DHMM_Model_File_Head.sSampleType = SAMPLE_DATA_TYPE_DOUBLE;
	u_DHMM_Model_File_Head.sModelStateNum = pu_DHMM_Model[0].n_State_Num + 2;
	u_DHMM_Model_File_Head.sCodeBookSize = pu_DHMM_Model[0].n_Code_Book_Size;

	ASSERT(sizeof(u_DHMM_Model_File_Head) == 200);
	fwrite(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);

	//	用空索引表占据空间
	lTmp = 0;
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
		fwrite(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
	}

	//	依次写入每个模型
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		//	得到模型的文件偏移值,写入索引表
		fseek(fp_DHMM_Model_File, 0, SEEK_END);
		l_Word_Sample_Offset = ftell(fp_DHMM_Model_File);
		fseek(fp_DHMM_Model_File, 200 + 4 * 2 * (n_Model_Index), SEEK_SET);
		fwrite(&l_Word_Sample_Offset, sizeof(long), 1, fp_DHMM_Model_File);

		fseek(fp_DHMM_Model_File, l_Word_Sample_Offset, SEEK_SET);
		//	Pi
		fwrite(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
		//	A
		for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
		{
			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);
		}
		//	B
		fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
		for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
		{
			fwrite(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
		}
		fwrite(pu_Silence_Model[0].d2dda_B[0], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);

	}

	fclose(fp_DHMM_Model_File);

	return 0;
}

//////////////////////////////////////////////////////////////////////
//	函数名称:DHMM_Model_Load_DHMM_Model_File_With_Silence
//	函数功能:从文件读入带静音的DHMM模型
//	函数性质:API
//	输入参数:
//		sz_Toload_DHMM_Model_File_Name,存储模型的文件名
//		n_DHMM_Model_Num,要读取的模型个数
//	输出参数:
//		pu_DHMM_Model,存放读出的DHMM模型
//	返回值:
//		0 表示成功
//	备注:关于DHMM_MODEL的定义,参见公共的.H文件
//		模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
int DHMM_Model_Load_DHMM_Model_File_With_Silence(char * sz_Toload_DHMM_Model_File_Name,
									DHMM_MODEL * pu_DHMM_Model, int n_DHMM_Model_Num)
{
	FILE * fp_DHMM_Model_File;
	DHMM_MODEL_FILE_HEAD u_DHMM_Model_File_Head;
	int * pn_DHMM_Model_Offset;
	int n_Model_Index, n_State_Index;
	long lTmp;

	CString Silence_File(sz_Toload_DHMM_Model_File_Name);
	Silence_File.Replace(".DAT", "WS.DAT");
	fp_DHMM_Model_File = fopen(Silence_File, "rb");
	ASSERT(fp_DHMM_Model_File != NULL);

	fread(&u_DHMM_Model_File_Head, sizeof(u_DHMM_Model_File_Head), 1, fp_DHMM_Model_File);
	ASSERT(u_DHMM_Model_File_Head.lVersion >= DAT_FILE_VERSION);
//	ASSERT(u_DHMM_Model_File_Head.sDHMM_Model_Num == u_Pro_Config.n_DHMM_Model_Num);

//	ASSERT(u_DHMM_Model_File_Head.sModelStateNum == pu_DHMM_Model->n_State_Num);

	pn_DHMM_Model_Offset = new int[n_DHMM_Model_Num];
	ASSERT(pn_DHMM_Model_Offset != NULL);

	//	读入每个模型的文件偏移
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		fread(&pn_DHMM_Model_Offset[n_Model_Index], sizeof(long), 1, fp_DHMM_Model_File);
		fread(&lTmp, sizeof(long), 1, fp_DHMM_Model_File);
	}

	//	依次读入每个模型数据
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		pu_DHMM_Model[n_Model_Index].n_State_Num = u_DHMM_Model_File_Head.sModelStateNum;
		pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_DHMM_Model_File_Head.sCodeBookSize;

		fseek(fp_DHMM_Model_File, pn_DHMM_Model_Offset[n_Model_Index], SEEK_SET);

		//	Pi
		fread(pu_DHMM_Model[n_Model_Index].pdPi, sizeof(double), u_DHMM_Model_File_Head.sModelStateNum - 2, fp_DHMM_Model_File);
		//	A
		for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum - 2; n_State_Index++)
		{
			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);
		}
		//	B
		for (n_State_Index = 0; n_State_Index < u_DHMM_Model_File_Head.sModelStateNum; n_State_Index++)
		{
			fread(pu_DHMM_Model[n_Model_Index].d2dda_B[n_State_Index], sizeof(double), u_DHMM_Model_File_Head.sCodeBookSize, fp_DHMM_Model_File);
		}
	}

	delete[] pn_DHMM_Model_Offset;
	fclose(fp_DHMM_Model_File);

	return 0;
}

//////////////////////////////////////////////////////////////////////
//	函数名称:DHMM_Model_To_519_Model
//	函数功能:向文件写入可以用于519系统的定点,对数化,DHMM模型。
//	函数性质:API
//	备注:关于DHMM_MODEL的定义,参见公共的.H文件
//		模型存储使用.DAT格式中的模型存储格式,可参见DAT_File_Access模块
int DHMM_Model_To_519_Model(void)
{
	DHMM_MODEL * pu_DHMM_Model;
	int n_Model_Index;
	int n_DHMM_Model_Num;
	int nRetCode;

	char ModelFile[256];
	strcpy(ModelFile, u_Pro_Config.sz_Toload_DHMM_Model_File_Name);

	n_DHMM_Model_Num = u_Pro_Config.n_DHMM_Model_Num;
	if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
		| ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
	{
		u_Pro_Config.n_DHMM_Model_State_Num += 2;
	}


	//	为DHMM模型准备内存
	pu_DHMM_Model = new DHMM_MODEL[n_DHMM_Model_Num];
	ASSERT(pu_DHMM_Model);
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		pu_DHMM_Model[n_Model_Index].n_State_Num = u_Pro_Config.n_DHMM_Model_State_Num;
		pu_DHMM_Model[n_Model_Index].n_Code_Book_Size = u_Pro_Config.n_VQ_Code_Book_Size;
		pu_DHMM_Model[n_Model_Index].pdPi = new double[u_Pro_Config.n_DHMM_Model_State_Num];
		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);
		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);
		ASSERT((pu_DHMM_Model[n_Model_Index].pdPi != NULL)
			&& (pu_DHMM_Model[n_Model_Index].d2dda_A != NULL)
			&& (pu_DHMM_Model[n_Model_Index].d2dda_B != NULL));
	}

	double** d2dda_B;
	double** d2dda_LogB = d2dda_New(u_Pro_Config.n_DHMM_Model_State_Num, u_Pro_Config.n_VQ_Code_Book_Size);
	ASSERT((d2dda_LogB != NULL));

	if (((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == (MODEL_CONFIG_TRAIN_WITH_SILENCE_MODEL))
		| ((u_Pro_Config.l_DHMM_Model_Config & MODEL_CONFIG_GENERATE_DHMM_MODEL_MASK) == ( MODEL_CONFIG_LOAD_WITH_SILENCE_MODEL)))
	{
		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);
	}
	ASSERT(nRetCode == 0);

	CString model_519file = u_Pro_Config.sz_Toload_DHMM_Model_File_Name;
	model_519file.Replace(".DAT", "519.dat");

	FILE *fp_DHMM_Model_File, *fp_DHMM_Model_TXT_File, *fp_DHMM_Model_BIN_File;
	fp_DHMM_Model_File = fopen(model_519file, "wb");
	fp_DHMM_Model_TXT_File = fopen("..//..//data//modelTXT.dat","wb+");
	fp_DHMM_Model_BIN_File = fopen("..//..//data//modelBIN.dat","wb+");
	ASSERT(fp_DHMM_Model_File != NULL);

	short data;

	//	依次写入每个模型
	for (n_Model_Index = 0; n_Model_Index < n_DHMM_Model_Num; n_Model_Index++)
	{
		d2dda_B = pu_DHMM_Model[n_Model_Index].d2dda_B;
		//	B
		for (int n_State_Index = 0; n_State_Index < u_Pro_Config.n_DHMM_Model_State_Num; n_State_Index++)
		{
			for(int n_Code_Word_Index = 0; n_Code_Word_Index < pu_DHMM_Model->n_Code_Book_Size; n_Code_Word_Index++)
			{
				if (d2dda_B[n_State_Index][n_Code_Word_Index] < EPSILON_DOUBLE_VALUE)
					d2dda_B[n_State_Index][n_Code_Word_Index] = EPSILON_DOUBLE_VALUE;
				d2dda_LogB[n_State_Index][n_Code_Word_Index]
					= (int)(log10(d2dda_B[n_State_Index][n_Code_Word_Index]) * (65536L / LOG_SCALE) + 32768L/* + 0.5F*/);
				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));
				data = (short)d2dda_LogB[n_State_Index][n_Code_Word_Index];
				fwrite(&data,sizeof(short),1,fp_DHMM_Model_File);
//				if ((n_Model_Index < 15) || (n_Model_Index > 15 && n_Model_Index < 20)
//					|| (n_Model_Index > 25 && n_Model_Index < 34))
				{	
					fwrite(&data,sizeof(short),1,fp_DHMM_Model_BIN_File);
					fprintf(fp_DHMM_Model_TXT_File,"%d,",data);
				}
					
			}
			
		}
		fprintf(fp_DHMM_Model_TXT_File,"\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -