📄 dhmm_model_mfc.cpp
字号:
// 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 + -