利用HTK工具包进行语音识别建模时,遇到任务语法中存在中文时候,无法生成对应的底层网络,这样就需要对HTK源码的部分内容进行修改,以下是我对HTK源码HParse及HVite部分内容改动记录,希望对有需要的人有帮助!自己也做个备份!
添加下面函数
static int IsSpace(char c)
{
if ((c == 0x09) ||( c == 0x0D) || (c == ' ' ))
return 1;
return 0;
}
修改下面的函数
修改HParse.C
static void PGetSym(void)
{
..../////////////
while ( IsSpace(ch)|| (ch=='/' && inlyne[curpos]=='*') ) //这里特别注意,网上有一个文章这里修改出错
{
if (!IsSpace(ch) || isspace((int) ch)) /* skip space */
PGetCh();
else { /* skip comment */
PGetCh(); PGetCh();
while (!(ch=='*' && inlyne[curpos]=='/')) PGetCh();
PGetCh(); PGetCh();
}
}
..../////////////以下部分代码为做修改
}
static void PGetIdent(void)
{
int i=0;
Ident id;
do {
if (ch==ESCAPE) PGetCh();
if (i<MAXIDENT) id[i++]=ch;
PGetCh();
} while(!IsSpace(ch)&& ch!='{' && ch!='}' && ch!='['&& ch!=']' &&//!isspace( (int)ch)
ch!='<' && ch!='>' && ch!='(' && ch!=')'&& ch!='=' &&
ch!=';' && ch!='|' && ch!='/' && ch!='%');
id[i]='\0';
ident = GetLabId(id,TRUE);
}
修改HNet.c
ReturnStatus WriteOneLattice(Lattice *lat,FILE *file,LatFormat format)
{
...///////////////////////////////
else if (ln->word!=NULL) {
fprintf(file,"W=%-19s ",ln->word->wordName->name);//
// ReWriteString(ln->word->wordName->name,注释掉
// NULL,ESCAPE_CHAR));
...////////////////////////////////
}
这样在生产的底层网络中就可以看到汉字,而不是汉字编码了。下面是我测试的一个简单例子:
这是taskgram中的内容
$somebody =我 | 小王 | 他们 | 他 | 你;
$place = 北京 | 图书馆 | 学校 | 家里;
$something = 出差 | 自习 | 上课 | 睡觉;
(SENT-START($somebody 在 $place $something) SENT-END)
没有修改HParse生产的网络
VERSION=1.0
N=11 L=22
I=0 W=END_SIL
I=1 W=sil
I=2 W=\344\275\240
I=3 W=!NULL
I=4 W=\345\260\274
I=5 W=\346\265\251
I=6 W=\345\245\275
I=7 W=sil
I=8 W=START_SIL
I=9 W=!NULL
I=10 W=!NULL
J=0 S=1 E=0
J=1 S=3 E=0
J=2 S=3 E=1
J=3 S=3 E=2
J=4 S=7 E=2
J=5 S=8 E=2
J=6 S=2 E=3
J=7 S=4 E=3
J=8 S=5 E=3
J=9 S=6 E=3
J=10 S=3 E=4
J=11 S=7 E=4
J=12 S=8 E=4
J=13 S=3 E=5
J=14 S=7 E=5
J=15 S=8 E=5
J=16 S=3 E=6
J=17 S=7 E=6
J=18 S=8 E=6
J=19 S=8 E=7
J=20 S=10 E=8
J=21 S=0 E=9
修改后的网络
VERSION=1.0
N=21 L=30
I=0 W=!NULL
I=1 W=!NULL
I=2 W=SENT-START
I=3 W=我
I=4 W=!NULL
I=5 W=小王
I=6 W=他们
I=7 W=他
I=8 W=你
I=9 W=在
I=10 W=北京
I=11 W=!NULL
I=12 W=图书馆
I=13 W=学校
I=14 W=家里
I=15 W=出差
I=16 W=!NULL
I=17 W=自习
I=18 W=上课
I=19 W=睡觉
I=20 W=SENT-END
J=0 S=20 E=1
J=1 S=0 E=2
J=2 S=2 E=3
J=3 S=3 E=4
J=4 S=5 E=4
J=5 S=6 E=4
J=6 S=7 E=4
J=7 S=8 E=4
J=8 S=2 E=5
J=9 S=2 E=6
J=10 S=2 E=7
J=11 S=2 E=8
J=12 S=4 E=9
J=13 S=9 E=10
J=14 S=10 E=11
J=15 S=12 E=11
J=16 S=13 E=11
J=17 S=14 E=11
J=18 S=9 E=12
J=19 S=9 E=13
J=20 S=9 E=14
J=21 S=11 E=15
J=22 S=15 E=16
J=23 S=17 E=16
J=24 S=18 E=16
J=25 S=19 E=16
J=26 S=11 E=17
J=27 S=11 E=18
J=28 S=11 E=19
J=29 S=16 E=20
至于HVite部分,我找了近一下午,总算找到改的地方了,修改HSheel.c 中WriteString函数
n=*p;
fputc(n,f);//添加的行
// fputc(ESCAPE_CHAR,f);
// fputc(((n/64)%8)+'0',f);fputc(((n/8)%8)+'0',f);fputc((n%8)+'0',f);
我将相应的位置给注释上了,并将字符之间输出到文件中,这样在结果文件中就可以看到中文了~~