引言
最近接到个项目,需要多声卡播放文字语音,涉及到指定声卡和语音合成的问题,于是各种查各种copy,中间走了一段弯路,写这篇文章帮助有需要的人。本人菜鸡,第一次写博客,不足之处请多多指教。
科大讯飞离线合成参考了这篇文章https://blog.csdn.net/wyq1153/article/details/72178422
首先感谢作者,其次发现其中有些错误,导致我的离线合成速度慢而且有时不成功,后来发现是参数有误,原文实际是使用在线合成,而且需要拷贝的文件也没有交代清楚,本文尽量详细的列出每一个步骤。
Microsoft Speech离线合成
我的项目使用的是Version 11,语言包选择的Hui Hui,中英文效果感觉不错,当然,英文也可以使用原生的英文语音包。5.X版本,系统自带的Lili效果一般,过于生硬。
环境安装
https://www.microsoft.com/en-us/download/details.aspx?id=27226 下载开发环境
https://www.microsoft.com/en-us/download/details.aspx?id=27224 下载离线语音包
https://www.microsoft.com/en-us/download/details.aspx?id=27225 下载运行环境
根据自己的系统选择SDK,根据需要下载TTS语音包,Runtime是给最后产品终端装的,开发不需要安装。
安装步骤先安装SDK,这里要记住路径,项目引用dll需要。再依次安装自己需要的语音包(中文推荐HuiHui,英文的话HuiHui和Helen都不错)。
项目引用
引用Microsoft.Speech.dll,文件位置根据安装SDK的路径寻找,我系统64位,默认路径为C:\Program Files\Microsoft SDKs\Speech\v11.0\Assembly下。
代码using Microsoft.Speech.Synthesis;
关键代码如下
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer();
List<InstalledVoice> voices = speechSynthesizer.GetInstalledVoices().ToList();
//声源名称集合,如Microsoft Server Speech Text to Speech Voice (zh-CN, HuiHui)
List<string> sources = new List<string>();
foreach (InstalledVoice voice in voices)
{
sources.Add(voice.VoiceInfo.Name);
}
string fileName = AppDomain.CurrentDomain.BaseDirectory + "Call.wav";
//根据上面的集合可以自己用combobox实现指定声源
speechSynthesizer.SelectVoice(sources[0]);
speechSynthesizer.SetOutputToWaveFile(fileName);
speechSynthesizer.Speak("需要合成为语音的文本内容");
speechSynthesizer.SetOutputToNull();
MessageBox.Show("合成完毕");
科大讯飞离线合成
重头戏来了,微软的语音合成开发其实很简单,但是科大讯飞没有针对C#的开发,对我这种一门开发语言都还掌握不好的小白来说,真的很痛苦。闲话少说,开始正文。
环境安装
https://www.xfyun.cn/services/offline_tts 注册并下载试用版离线SDK,下载好的压缩包解压如下图
网上搜的几篇离线教程,都是说只要一个dll文件就可以了,被这一步骤坑的人应该不少,语音资源文件不拷贝,怎么可能离线合成语音…
代码的编写可以参考引言中的链接,有几个地方要注意修改,为了方便我还是全贴出来吧
首先新建一个类库项目,名称就叫TTS吧,然后新建TTS类,代码如下。根据系统32位或者64位选择导入msc.dll或者msc_x64.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace TTS
{
public enum ErrorCode
{
MSP_SUCCESS = 0,
MSP_ERROR_FAIL = -1,
MSP_ERROR_EXCEPTION = -2,
/* General errors 10100(0x2774) */
MSP_ERROR_GENERAL = 10100, /* 0x2774 */
MSP_ERROR_OUT_OF_MEMORY = 10101, /* 0x2775 */
MSP_ERROR_FILE_NOT_FOUND = 10102, /* 0x2776 */
MSP_ERROR_NOT_SUPPORT = 10103, /* 0x2777 */
MSP_ERROR_NOT_IMPLEMENT = 10104, /* 0x2778 */
MSP_ERROR_ACCESS = 10105, /* 0x2779 */
MSP_ERROR_INVALID_PARA = 10106, /* 0x277A */
MSP_ERROR_INVALID_PARA_VALUE = 10107, /* 0x277B */
MSP_ERROR_INVALID_HANDLE = 10108, /* 0x277C */
MSP_ERROR_INVALID_DATA = 10109, /* 0x277D */
MSP_ERROR_NO_LICENSE = 10110, /* 0x277E */
MSP_ERROR_NOT_INIT = 10111, /* 0x277F */
MSP_ERROR_NULL_HANDLE = 10112, /* 0x2780 */
MSP_ERROR_OVERFLOW = 10113, /* 0x2781 */
MSP_ERROR_TIME_OUT = 10114, /* 0x2782 */
MSP_ERROR_OPEN_FILE = 10115, /* 0x2783 */
MSP_ERROR_NOT_FOUND = 10116, /* 0x2784 */
MSP_ERROR_NO_ENOUGH_BUFFER = 10117, /* 0x2785 */
MSP_ERROR_NO_DATA = 10118, /* 0x2786 */
MSP_ERROR_NO_MORE_DATA = 10119, /* 0x2787 */
MSP_ERROR_SKIPPED = 10120, /* 0x2788 */
MSP_ERROR_ALREADY_EXIST = 10121, /* 0x2789 */
MSP_ERROR_LOAD_MODULE = 10122, /* 0x278A */
MSP_ERROR_BUSY = 10123, /* 0x278B */
MSP_ERROR_INVALID_CONFIG = 10124, /* 0x278C */
MSP_ERROR_VERSION_CHECK = 10125, /* 0x278D */
MSP_ERROR_CANCELED = 10126, /* 0x278E */
MSP_ERROR_INVALID_MEDIA_TYPE = 10127, /* 0x278F */
MSP_ERROR_CONFIG_INITIALIZE = 10128, /* 0x2790 */
MSP_ERROR_CREATE_HANDLE = 10129, /* 0x2791 */
MSP_ERROR_CODING_LIB_NOT_LOAD = 10130, /* 0x2792 */
/* Error codes of network 10200(0x27D8)*/
MSP_ERROR_NET_GENERAL = 10200, /* 0x27D8 */
MSP_ERROR_NET_OPENSOCK = 10201, /* 0x27D9 */ /* Open socket */
MSP_ERROR_NET_CONNECTSOCK = 10202, /* 0x27DA */ /* Connect socket */
MSP_ERROR_NET_ACCEPTSOCK = 10203