在嵌入式设备中常常会用到tts(Text To Speech)播报,在使用tts语音库时需要注意一下几点:
1、生成tts语音的频率。通常情况下 tts语音频率为8k。
2、设备声卡支持的频率。这个跟硬件有关系。有8k、16、32等。
如果生成的语音频率与硬件不匹配,那么我们怎么处理呢?
我们可以把tts语音频率转换为硬件支持的频率。
通常 SOUND_PCM_WRITE_BITS 为16位
如把 8k 转 16k
就是每个16位复制一次。(相同16位出现 2次)
如果是8k转32k
就是每个16位复制3次。(相同16位出现 4次)
下面是8k转16k
int i = 0;
int j = 0;
for(i = 0 ; i < len; i += 2)//每两个字节即使16位
{
for(j = 0; j < 2 ;j++)//2次相同 16k = 8k*2
{
status = write(fd_dev_w,ttsbuf+i,2);//每次写16位
if(status <= 0)
{
perror("Cannot write soundcard");
close(fd_dev_w);
return 1;
}
}
}
下面附上tts播放代码
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <xxx_tts.h>
#define SIZE 16
#define CHANNELS 1
//播放tts语音 buf
int play_pcm(char *ttsbuf,int len)
{
int fd_dev_w;
int arg;
int status;
fd_dev_w = open("/dev/dsp", O_WRONLY,0777);
if (fd_dev_w < 0)
{
perror("Cannot open /dev/dsp device");
return 1;
}
arg = SIZE;//16位
status = ioctl(fd_dev_w, SOUND_PCM_WRITE_BITS, &arg);//set SOUND_PCM_WRITE_BITS if (status == -1)
{
perror("Cannot set SOUND_PCM_WRITE_BITS ");
close(fd_dev_w);
return 1;
}
arg = CHANNELS;
status = ioctl(fd_dev_w, SOUND_PCM_WRITE_CHANNELS, &arg);//set SOUND_PCM_WRITE_CHANNELS
if (status == -1)
{
perror("Cannot set SOUND_PCM_WRITE_CHANNELS");
close(fd_dev_w);
return 1;
}
arg = 32000;
status = ioctl(fd_dev_w, SOUND_PCM_WRITE_RATE, &arg);//set SOUND_PCM_WRITE_RATE
if (status == -1)
{
perror("Cannot set SOUND_PCM_WRITE_RATE");
close(fd_dev_w);
return 1;
}
int i = 0;
int j = 0;
for(i = 0 ; i < len; i += 2)
{
for(j = 0; j < 2 ;j++)
{
status = write(fd_dev_w,ttsbuf+i,2);
if(status <= 0)
{
perror("Cannot write soundcard");
close(fd_dev_w);
return 1;
}
}
}
close(fd_dev_w);
return 0;
}
int main(int argc, char * argv[])
{
char * ptest = "hello jerry";
if(argc >1)
ptest = argv[1];
char ttsbuf[64*1024]= {0};
int nret=xxx_tts_set_speech_text(ptest,ttsbuf,sizeof(ttsbuf));
printf("len = %d\n ",nret);
if(nret > 0)
{
play_pcm(ttsbuf,nret);
}
return 0;
}