自造星球-创客空间  - 讨论区

标题:TTS(Text To Speech)技术实践

2015年07月14日 星期二 15:09

说到TTS语音合成技术,不得不提科大讯飞这家公司,在淘宝网上搜索“TTS语音合成”,结果中大部分都是科大讯飞的开发板。

这块开发板的集成度很高,自带功放,可以使用SPI、I2C、UART协议驱动,协议很简单,使用方便。

我是使用UART串口来做测试的,开发板默认的波特率是9600。

Arduino的程序文件的编码是UTF-8,但是TTS开发板只支持GBK、GB2312、BIG5、UNICODE四种编码,所以我们无法简单的在程序中嵌入中文字符串进行测试。

我采用的方法是加一个SD卡读卡器,将要合成语音的文本放到SD卡的文件中,Arduino读取文本文件后,发送到TTS开发板。

Arduino连接SD读卡器的接线请参考我之前的文章,Arduino连接TTS开发板使用的是软件模拟的串口,端口可以随意定义。

TTS开发板支持硬件方式检测工作状态,我将TTS的RDY引脚连接到了Arduino的3脚,这样就可以根据3脚的电平来判断TTS是否处于Busy的状态。

Arduino运行的代码比较长。我找了网易上的一篇新闻稿来测试,可以完整的阅读。

#include <SoftwareSerial.h>
SoftwareSerial xfs(6, 7); // RX, TX

#include <SPI.h>
#include <SD.h>
File myFile;
#define MAX_LEN 512
uint16_t n=MAX_LEN;
char buf[MAX_LEN];

bool xfs_is_idle(){
  if(digitalRead(3) == LOW) {
    return true;
  }else{
    return false;
  }
}

void setup()
{
  Serial.begin(9600);
  
  pinMode(3,INPUT);
  xfs.begin(9600);
  while(true ) {
    delay(1000);
    if(xfs_is_idle()) break;
  }
  check_xfs_return();
  
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  myFile = SD.open("xfs.txt");

}

uint16_t read_line(){
  uint16_t i=0;
  char c;
  memset(buf,0,sizeof(buf));
  while (myFile.available()) {
    if(i >= n-1){
      return i;
    }
    c=myFile.read();
    buf[i]=c;
    i++;
    Serial.print(c);
    if(c == '\n'){
      return i;
    }
  }
  return i;
}

int check_xfs_return(){
  if(xfs.available()) {
    uint8_t ret=xfs.read();
    if(ret == 0x4A){
      Serial.println("XFS init success.");
      return ret;
    }
    if(ret == 0x41) {
      Serial.println("Received valid commmand.");
      return ret;
    }
    if(ret == 0x45) {
      Serial.println("Received invalid commmand.");
      return ret;
    }
    if(ret == 0x4E) {
      Serial.println("XFS is busy.");
      return ret;
    }
    if(ret == 0x4F) {
      Serial.println("XFS is idle.");
      return ret;
    }
    Serial.println("I got an unknown return.");
    Serial.println(ret,HEX);
    return ret;
  } else {
    Serial.println("xfs is not available..");
    return 0;
  }
}

int send_string(){
    uint8_t c;
    c=0xFD;
    xfs.write(c);
    uint16_t len=strlen(buf)+2;
    c = len >> 8;
    xfs.write(c);
    c = (len << 8) >> 8;
    xfs.write(c);
    c=0x01;
    xfs.write(c);
    c=0x01;
    xfs.write(c);
    xfs.write(buf,strlen(buf));
    return 1;
}

void loop()
{
  uint16_t text_len=read_line();
  if(text_len == 0) {
    myFile.close();
    return;
  }
  if(text_len == 2) {
    return;
  }
  send_string();
  delay(1000);
  while(check_xfs_return() == 0) {
    delay(1000);
  }
  while(!xfs_is_idle()){
    delay(1000);
    Serial.println("xfs is busy.");
  }
   while(check_xfs_return() == 0) {
    delay(1000);
  }
}

 

我的主观感觉,TTS的合成效果还算不错,少数儿化音读不准。接下来,我准备配合ESP8266来做一个互联网新闻阅读器,以后不用听收音机了,呵呵。

更多资料:

《XFS5152CE语音合成芯片用户开发指南V1.2》

 

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号