C++实现自己的文本转语音程序(简单版)
目录
Text to Audio
1. Preface
早在很久之前就应该完成这个任务了,但是在此之前都没找到很好的思路,而且每天还有其他任务要去完成,兜兜转转才拖到了今天。这个想法来自《软件开发技术与应用》的一次课后作业,当时我正在看《C++ Primer 5》这本书,但是总是感觉看语法书好枯燥,当时脑子不停地在想C++到定能干嘛,就当我学不下去的时候,我想起了这次的课后作业,我可以用C++写一个简单的文本转语音的程序!虽然用其他语言可能更容易实现,而且网上的参考资料也会更多些,可能是一直有一种盲目的执着吧!于是疯狂地找有关C++写文本转语音的资料,可是很大部分都是TTS和微软语音开发包,都已经封装好了,虽说都开源,但是写的代码都很难看懂,有些底层的代码根本就没有。我最后甚至都想去看TTS之类的源码,然后模仿写一个,但是在短时间内根本就不太可能,更何况我还没有那么多时间,后来终于天道酬勤吧,得到了大神的相助,我一下茅塞顿开,原来我的想法其实是有点偏了,其实还是挺简单的!
于是写了这篇文章来纪念一下此次开发历程以及留到以后当作回忆吧!也可以供以后慢慢完善,也希望大家不吝赐教!
2. Requirement
- 实现一个简单的“文本转化为语音”程序,不能直接调用TTS等“文本转语音”开发包
- 音频资料需要自己录音
- 程序可以接受用户输入的一段文本,然后将其转化为自己的录音播放出来
3. Analysis and Implement
本程序实现的一个文本转语音程序的简单版本,即目前只实现了将一串数字转化为语音播出来。以下是本程序实现的主要步骤(希望能对大家有点启发):
1. 首先将每个数字的发音录成单个MP3文件保存下来
2. 程序先对输入的文本进行预处理,比如不允许文本中出现除数字以外的其他字符,另外,考虑到可读的整数有限,于是 规定长度大于10的当作一串单纯的数字逐个读出即可,具体实现 部分 代码如下:
std::vector<std::string> StringHandler::prase()
{
switch (flag) {
case 1: // 将字符串转化为一个长整数
{
long num = std::stol(sourceString);
if (num == 0) {
targetVector.push_back(posTable[0]);
}
else {
int pos = 0;
while (num != 0) {
targetVector.push_back(std::to_string(num % 10));
if (num / 10 != 0)
targetVector.push_back(posTable[++pos]);
num /= 10;
}
/*for (auto it = targetVector.rbegin(); it != targetVector.rend(); ++it)
std::cout << *it << " ";
std::cout << std::endl;*/
}
break;
}
case 2: //将每个字符转化为数字
{
for (int i = sourceString.size() - 1; i >= 0; --i)
targetVector.push_back(sourceString.substr(i, 1));
break;
}
case 0:
std::cout << "The length of source string is zero!" << std::endl;
break;
default:
std::cerr << "X error!" << std::endl;
}
return targetVector;
}
3. 将转化后的字符串存入vector容器中,并做好vector中的元素到音频文件的映射
std::string posTable[10] = { "0","10","100","1000","10000","100000","1000000","10000000","100000000","1000000000" };
4. 最后将转换好的多个音频文件依次用mciSendString函数打开(播放)
void TextPlayer::play(std::vector<std::string> &vec)
{
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::string comm = "play msc/" + *it + ".mp3 wait";
mciSendString(comm.c_str(), 0, 0, 0);
}
}
4. Sumary and Expectation
本程序还是过于简单,思路也比较简单,但是还是尽可能的在编程技巧上作了优化,比如将预处理和语音播放操作都封装成类;另外也算是对自己前段时间看书的效果的一次检测吧!
接下来的工作是希望能进一步实现文字的转语音的操作,也很乐意大家留下宝贵的意见!个人水平有限,本来不想公开分享的,但是本着共享无罪的原则,希望跟大家一起进步(请各位大佬抬手~v~)!
5. Appreciation
这里要特别感谢上文提到的大神---my teacher,真是一语惊醒梦中人呀(虽然一直在做梦 2333),希望这份答案还能入你的法眼。
References
1. 在线音乐剪辑网站
2. 源码(欢迎留言)