最近在用SYN6288语音播报模块做项目,需要用C++做成这个语音播报模块。
但是遇到了一个问题,就是输入的中文字符编码在Ubuntu下面是hex-utf,而在Windows下是hex-gb2312,所以在Windows下测的好好的代码,放到Ubuntu下就乱报语音。
下面直接把我的研究成果发出来吧,直接封装好了的。
#include <stdio.h>
#include <iconv.h>
#include <string.h>
#include <string>
#include <iostream>
#include "uart.hpp"
using namespace std;
#define OUTLEN 255
#define debug
int code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen);
int utfTOgb2312(char *inbuf,int inlen,char *outbuf,int outlen);
void print(const std::string& content);
void speaker(const std::string& content)
{
#ifdef debug
print(content);
#endif
char *p = (char*)content.c_str();
#ifdef debug
printf("%s\n",p);
#endif
static unsigned char out[OUTLEN];
int rec = utfTOgb2312(p,strlen(p),(char*)out,OUTLEN);
int len = strlen((char*)out);
#ifdef debug
printf("rec=%d,strlen(out)=%d\n",rec,len);
for (int i=0;i<len;i++) printf("%x ",out[i]);
printf("\n");
#endif
unsigned char headOfFrame[5];
unsigned char length;
unsigned char ecc = 0;//定义校验字节
length=len;
/*senddata**/
headOfFrame[0] = 0xFD ;//构造帧头FD
headOfFrame[1] = 0x00 ;//构造数据区长度的高字节
headOfFrame[2] = length + 3;//构造数据区长度的低字节
headOfFrame[3] = 0x01 ;//构造命令字:合成播放命令
headOfFrame[4] = 0x00 ;//构造命令参数:编码格式为GB2312
for(char i=0; i<5; i++)//依次发送构造好的5个帧头字节
{
ecc=ecc^(headOfFrame[i]);//对发送的字节进行异或校验
}
for(char i=0; i<length; i++)//依次发送待合成的文本数据
{
ecc=ecc^(out[i]);//对发送的字节进行异或校验
}
#ifdef debug
printf("\nresualt:\n");
for (int i=0;i<5;i++) printf("%x ",headOfFrame[i]);
for (int i=0;i<length;i++) printf("%x ",out[i]);
printf("%x \n",ecc);
#endif
// 将字符数据通过串口发送到模块
speaker_sendString((char*)&headOfFrame[0], 5);
speaker_sendString((char*)&out[0], length);
speaker_sendString((char*)&ecc, 1);
}
int main()
{
std::string strspk = "这是用C++写的语音播报模块";
speaker(strspk);
return 0;
}
// ==================================================
// ==================================================
// 编码转换
int code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
// utf8码转为GB2312码
int utfTOgb2312(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
void print(const std::string& content)
{
std::cout<<content<<std::endl;
}
注:speaker_sendString(char*,int size)
这函数是笔者自己写的一个串口发送的函数,目前还在测试使用阶段,后续再写博客分享出来
附上程序测试结果:
完美解决问题nice。