java 调用linux的tts_中文TTS 的简单实现(基于linux)之 实现语音合成
合成語音歸根到底是根據(jù)漢字在字符集的定位來取語音庫中的數(shù)據(jù)
定位方法:
根據(jù)救字的兩個字節(jié)中的值.從高字節(jié)算出漢字的位wm.從低字節(jié)算出漢字的區(qū)qm,
(qm一176)*94+wm一160就是該況字在漢字集里的位置position,
而該漢字所對應的語音數(shù)據(jù)的偏移量就是(position一1) 3200+46。
根據(jù)定位方法取得漢字在語音庫中的發(fā)音數(shù)據(jù)后,根據(jù)WAV格式合成語音文件。
定位和合成代碼如下:
#define MAXLEN? 32000
/*
參數(shù)str:為純漢字的字符串,且編碼格式為GBK
返回值:
-1:表示語音庫文件打開錯誤
-2:表示合成語音文件 打開/生成錯誤
其它:函數(shù)執(zhí)行成功
*/
int?? wav(char *str)
{
FILE * fpf,*fpt;?? //文件指針
int qm,wm;???? ?//漢字區(qū)、位碼
int re;?????????????? //函數(shù)返回值
long fileleng=0;?? //文件長度 后面修改WAV格式時有用
if((fpf=fopen("ddd.wav","rb+"))==NULL)??? //打開語音庫文件
return -1;
if((fpt=fopen("china.wav","wb+"))==NULL)? //打開或生成合成后的語音文件,用來播放的
return -2;
char head[46];??????????????????? ?? //WAV 文件頭
char buffer[MAXLEN];?????????? //發(fā)音數(shù)據(jù)BUFF
memset(buffer,0,MAXLEN);? //置0
fread(head,sizeof(head),1,fpf);???? //讀語音庫文件頭
fwrite(head,sizeof(head),1,fpt);??? //寫入合成語音文件
int l=strlen(str);
char *s=str;
for(int i=0;i<=l;i=i+2)
{
qm=(unsigned char)*(s+i);????? //取漢字的區(qū)碼
wm=(unsigned char)*(s+1+i);????? //取漢字的位碼
if (qm<176||qm>215)?? //判斷是否在漢字字符集中
continue;
if (wm<161||wm>254)? //判斷是否在漢字字符集中
continue;
int position =(qm-176)*94+wm-160;
int offset=(position-1)*MAXLEN+46;???? //定位
fseek(fpf,offset,0);
fread(buffer,sizeof(buffer),1,fpf);???? //取發(fā)音數(shù)據(jù)
fwrite(buffer,sizeof(buffer),1,fpt);?? ? //寫入合成文件
fileleng++;????????????????????????????????????????? //合成文件長度增加
}?? //end for
re =fileleng;
fileleng=fileleng*MAXLEN;
fseek(fpt,42,SEEK_SET);
fwrite(&fileleng,sizeof(long),1,fpt);??? //修改合成文件的WAV格式,主要是修改文件大小,具體請看WAV格式表
fileleng+=44;
fseek(fpt,4,SEEK_SET);
fwrite(&fileleng,sizeof(long),1,fpt);? //修改合成文件的WAV格式,主要是修改文件大小,具體請看WAV格式表
fclose(fpf);???? //關閉文件
fclose(fpt);
return re;
}
其它:
由函數(shù)WAV可以看出,我們接收用戶的輸入字符的編碼必須為GBK編碼,
所以如果系統(tǒng)使用的不是 GBK編碼的話,我們還應當進行編碼轉(zhuǎn)換。
如果編碼正確的話,還得從把用戶的輸入中把中文字符給提取出來。
為此,我寫了小段代碼,用來過濾非中文字符的。
void trans(char *str)
{
int i = 0, j = 0;
while( str[i] != '' )
{
if ( str[i] < 0 )
{
str[j++] = str[i++];
str[j++] = str[i++];
}
else
i++;
}?? //end while
str[j] = '';
}
總結
以上是生活随笔為你收集整理的java 调用linux的tts_中文TTS 的简单实现(基于linux)之 实现语音合成的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学公式教程latex版
- 下一篇: html语言教案模版,大班语言教案模板