中文TTS 的簡單實現(基於linux)之 實現語音合成

來源:互聯網
上載者:User

合成語音歸根到底是根據漢字在字元集的定位來取語音庫中的資料

定位方法:

根據救字的兩個位元組中的值.從高位元組算出漢字的位wm.從低位元組算出漢字的區qm,
(qm一176)*94+wm一160就是該況字在漢字集裡的位置position,
而該漢字所對應的語音資料的位移量就是(position一1) 3200+46。

根據定位方法取得漢字在語音庫中的發音資料後,根據WAV格式合成語音檔案。

定位和合成代碼如下:
#define MAXLEN  32000

/*
參數str:為純漢字的字串,且編碼格式為GBK
傳回值:
-1:表示語音庫檔案開啟錯誤
-2:表示合成語音檔案 開啟/建置錯誤
其它:函數執行成功
*/
int   wav(char *str) 
{
 FILE * fpf,*fpt;   //檔案指標
 int qm,wm;      //漢字區、位碼
 int re;               //函數傳回值
 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];           //發音資料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);      //取漢字的區碼
  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);     //取發音資料
  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;
}

 

其它:
由函數WAV可以看出,我們接收使用者的輸入字元的編碼必須為GBK編碼,
所以如果系統使用的不是 GBK編碼的話,我們還應當進行編碼轉換。
如果編碼正確的話,還得從把使用者的輸入中把中文字元給提取出來。
為此,我寫了小段代碼,用來過濾非中文字元的。
void trans(char *str)
{
 int i = 0, j = 0;
 while( str[i] != '/0' )
 {
  if ( str[i] < 0 )
      {
   str[j++] = str[i++];
   str[j++] = str[i++];
     }
  else
     i++;
 
 }   //end while
 str[j] = '/0'; 
}

 

 

文章導讀:
中文TTS 的簡單實現(基於linux)之 前言
http://blog.csdn.net/dedodong/archive/2006/07/15/923543.aspx

中文TTS 的簡單實現(基於linux)之 實現原理:
http://blog.csdn.net/dedodong/archive/2006/07/16/927041.aspx

中文TTS 的簡單實現(基於linux)之 語音庫的實現
http://blog.csdn.net/dedodong/archive/2006/08/22/1105742.aspx

中文TTS 的簡單實現(基於linux)之 後記
http://blog.csdn.net/dedodong/archive/2006/08/24/1109908.aspx

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.