1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C#调用科大讯飞离线语音合成TTS

C#调用科大讯飞离线语音合成TTS

时间:2020-05-10 19:51:59

相关推荐

C#调用科大讯飞离线语音合成TTS

原作者勿怪,未经允许就转载了,感谢万分。

/xuguanghui/p/4505555.html

----------------------------------------------------

c#调用科大讯飞的离线语音合成,需要在科大讯飞开放平台: 注册、创建应用(获取APPID)、开通离线语音服务、下载SDK。

SDK中目录如下:

关于目录结构,讯飞平台的资料库中有介绍。

bin目录下有msc.dll动态库。c#调用科大讯飞的语音合成,需要引用该文件。该文件是C语言生成的dll,C#没办法直接引用。所有需要用C#重新封装一个TTS.dll,然后再在C#项目中引用封装的TTS.dll。

步骤:

1.在VS中新建一个类库项目(TTS),新建一个类文件(TTS.cs)

2.TTS.cs中的内容如下:

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,/* 0x27DB */ /* Accept socket */MSP_ERROR_NET_SENDSOCK = 10204,/* 0x27DC */ /* Send socket data */MSP_ERROR_NET_RECVSOCK = 10205,/* 0x27DD */ /* Recv socket data */MSP_ERROR_NET_INVALIDSOCK = 10206,/* 0x27DE */ /* Invalid socket handle */MSP_ERROR_NET_BADADDRESS = 10207,/* 0x27EF */ /* Bad network address */MSP_ERROR_NET_BINDSEQUENCE = 10208,/* 0x27E0 */ /* Bind after listen/connect */MSP_ERROR_NET_NOTOPENSOCK = 10209,/* 0x27E1 */ /* Socket is not opened */MSP_ERROR_NET_NOTBIND = 10210,/* 0x27E2 */ /* Socket is not bind to an address */MSP_ERROR_NET_NOTLISTEN = 10211,/* 0x27E3 */ /* Socket is not listenning */MSP_ERROR_NET_CONNECTCLOSE = 10212,/* 0x27E4 */ /* The other side of connection is closed */MSP_ERROR_NET_NOTDGRAMSOCK = 10213,/* 0x27E5 */ /* The socket is not datagram type *//* Error codes of mssp message 10300(0x283C) */MSP_ERROR_MSG_GENERAL = 10300,/* 0x283C */MSP_ERROR_MSG_PARSE_ERROR = 10301,/* 0x283D */MSP_ERROR_MSG_BUILD_ERROR = 10302,/* 0x283E */MSP_ERROR_MSG_PARAM_ERROR = 10303,/* 0x283F */MSP_ERROR_MSG_CONTENT_EMPTY = 10304,/* 0x2840 */MSP_ERROR_MSG_INVALID_CONTENT_TYPE = 10305,/* 0x2841 */MSP_ERROR_MSG_INVALID_CONTENT_LENGTH = 10306,/* 0x2842 */MSP_ERROR_MSG_INVALID_CONTENT_ENCODE = 10307,/* 0x2843 */MSP_ERROR_MSG_INVALID_KEY = 10308,/* 0x2844 */MSP_ERROR_MSG_KEY_EMPTY = 10309,/* 0x2845 */MSP_ERROR_MSG_SESSION_ID_EMPTY = 10310,/* 0x2846 */MSP_ERROR_MSG_LOGIN_ID_EMPTY = 10311,/* 0x2847 */MSP_ERROR_MSG_SYNC_ID_EMPTY = 10312,/* 0x2848 */MSP_ERROR_MSG_APP_ID_EMPTY = 10313,/* 0x2849 */MSP_ERROR_MSG_EXTERN_ID_EMPTY = 10314,/* 0x284A */MSP_ERROR_MSG_INVALID_CMD = 10315,/* 0x284B */MSP_ERROR_MSG_INVALID_SUBJECT = 10316,/* 0x284C */MSP_ERROR_MSG_INVALID_VERSION = 10317,/* 0x284D */MSP_ERROR_MSG_NO_CMD = 10318,/* 0x284E */MSP_ERROR_MSG_NO_SUBJECT = 10319,/* 0x284F */MSP_ERROR_MSG_NO_VERSION = 10320,/* 0x2850 */MSP_ERROR_MSG_MSSP_EMPTY = 10321,/* 0x2851 */MSP_ERROR_MSG_NEW_RESPONSE = 10322,/* 0x2852 */MSP_ERROR_MSG_NEW_CONTENT = 10323,/* 0x2853 */MSP_ERROR_MSG_INVALID_SESSION_ID = 10324,/* 0x2854 *//* Error codes of DataBase 10400(0x28A0)*/MSP_ERROR_DB_GENERAL = 10400,/* 0x28A0 */MSP_ERROR_DB_EXCEPTION = 10401,/* 0x28A1 */MSP_ERROR_DB_NO_RESULT = 10402,/* 0x28A2 */MSP_ERROR_DB_INVALID_USER = 10403,/* 0x28A3 */MSP_ERROR_DB_INVALID_PWD = 10404,/* 0x28A4 */MSP_ERROR_DB_CONNECT = 10405,/* 0x28A5 */MSP_ERROR_DB_INVALID_SQL = 10406,/* 0x28A6 */MSP_ERROR_DB_INVALID_APPID = 10407, /* 0x28A7 *//* Error codes of Resource 10500(0x2904)*/MSP_ERROR_RES_GENERAL = 10500,/* 0x2904 */MSP_ERROR_RES_LOAD = 10501,/* 0x2905 */ /* Load resource */MSP_ERROR_RES_FREE = 10502,/* 0x2906 */ /* Free resource */MSP_ERROR_RES_MISSING = 10503,/* 0x2907 */ /* Resource File Missing */MSP_ERROR_RES_INVALID_NAME = 10504,/* 0x2908 */ /* Invalid resource file name */MSP_ERROR_RES_INVALID_ID = 10505,/* 0x2909 */ /* Invalid resource ID */MSP_ERROR_RES_INVALID_IMG = 10506,/* 0x290A */ /* Invalid resource image pointer */MSP_ERROR_RES_WRITE = 10507,/* 0x290B */ /* Write read-only resource */MSP_ERROR_RES_LEAK = 10508,/* 0x290C */ /* Resource leak out */MSP_ERROR_RES_HEAD = 10509,/* 0x290D */ /* Resource head currupt */MSP_ERROR_RES_DATA = 10510,/* 0x290E */ /* Resource data currupt */MSP_ERROR_RES_SKIP = 10511,/* 0x290F */ /* Resource file skipped *//* Error codes of TTS 10600(0x2968)*/MSP_ERROR_TTS_GENERAL = 10600,/* 0x2968 */MSP_ERROR_TTS_TEXTEND = 10601,/* 0x2969 */ /* Meet text end */MSP_ERROR_TTS_TEXT_EMPTY = 10602,/* 0x296A */ /* no synth text *//* Error codes of Recognizer 10700(0x29CC) */MSP_ERROR_REC_GENERAL = 10700,/* 0x29CC */MSP_ERROR_REC_INACTIVE = 10701,/* 0x29CD */MSP_ERROR_REC_GRAMMAR_ERROR = 10702,/* 0x29CE */MSP_ERROR_REC_NO_ACTIVE_GRAMMARS = 10703,/* 0x29CF */MSP_ERROR_REC_DUPLICATE_GRAMMAR = 10704,/* 0x29D0 */MSP_ERROR_REC_INVALID_MEDIA_TYPE = 10705,/* 0x29D1 */MSP_ERROR_REC_INVALID_LANGUAGE = 10706,/* 0x29D2 */MSP_ERROR_REC_URI_NOT_FOUND = 10707,/* 0x29D3 */MSP_ERROR_REC_URI_TIMEOUT = 10708,/* 0x29D4 */MSP_ERROR_REC_URI_FETCH_ERROR = 10709,/* 0x29D5 *//* Error codes of Speech Detector 10800(0x2A30) */MSP_ERROR_EP_GENERAL = 10800,/* 0x2A30 */MSP_ERROR_EP_NO_SESSION_NAME = 10801,/* 0x2A31 */MSP_ERROR_EP_INACTIVE = 10802,/* 0x2A32 */MSP_ERROR_EP_INITIALIZED = 10803,/* 0x2A33 *//* Error codes of TUV */MSP_ERROR_TUV_GENERAL = 10900,/* 0x2A94 */MSP_ERROR_TUV_GETHIDPARAM = 10901,/* 0x2A95 */ /* Get Busin Param huanid*/MSP_ERROR_TUV_TOKEN = 10902,/* 0x2A96 */ /* Get Token */MSP_ERROR_TUV_CFGFILE = 10903,/* 0x2A97 */ /* Open cfg file */MSP_ERROR_TUV_RECV_CONTENT = 10904,/* 0x2A98 */ /* received content is error */MSP_ERROR_TUV_VERFAIL = 10905,/* 0x2A99 */ /* Verify failure *//* Error codes of IMTV */MSP_ERROR_IMTV_SUCCESS = 11000,/* 0x2AF8 */ /* 成功 */MSP_ERROR_IMTV_NO_LICENSE = 11001,/* 0x2AF9 */ /* 试用次数结束,用户需要付费 */MSP_ERROR_IMTV_SESSIONID_INVALID = 11002,/* 0x2AFA */ /* SessionId失效,需要重新登录通行证 */MSP_ERROR_IMTV_SESSIONID_ERROR = 11003,/* 0x2AFB */ /* SessionId为空,或者非法 */MSP_ERROR_IMTV_UNLOGIN = 11004,/* 0x2AFC */ /* 未登录通行证 */MSP_ERROR_IMTV_SYSTEM_ERROR = 11005,/* 0x2AFD */ /* 系统错误 *//* Error codes of HCR */MSP_ERROR_HCR_GENERAL = 11100,MSP_ERROR_HCR_RESOURCE_NOT_EXIST = 11101,/* Error codes of http 12000(0x2EE0) */MSP_ERROR_HTTP_BASE = 12000, /* 0x2EE0 *//*Error codes of ISV */MSP_ERROR_ISV_NO_USER = 13000, /* 32C8 */ /* the user doesn't exist */}#region TTS枚举常量/// <summary>/// vol参数的枚举常量/// </summary>public enum enuVol{x_soft,soft,medium,loud,x_loud}/// <summary>/// speed语速参数的枚举常量/// </summary>public enum enuSpeed{x_slow,slow,medium,fast,x_fast}/// <summary>/// speeker朗读者枚举常量/// </summary>public enum enuSpeeker{小燕_青年女声_中英文_普通话 = 0,小宇_青年男声_中英文_普通话,凯瑟琳_青年女声_英语,亨利_青年男声_英语,玛丽_青年女声_英语,小研_青年女声_中英文_普通话,小琪_青年女声_中英文_普通话,小峰_青年男声_中英文_普通话,小梅_青年女声_中英文_粤语,小莉_青年女声_中英文_台普,小蓉_青年女声_汉语_四川话,小芸_青年女声_汉语_东北话,小坤_青年男声_汉语_河南话,小强_青年男声_汉语_湖南话,小莹_青年女声_汉语_陕西话,小新_童年男声_汉语_普通话,楠楠_童年女声_汉语_普通话,老孙_老年男声_汉语_普通话}public enum SynthStatus{MSP_TTS_FLAG_STILL_HAVE_DATA = 1,MSP_TTS_FLAG_DATA_END = 2,MSP_TTS_FLAG_CMD_CANCELED = 0}#endregionpublic class TTSDll{#region TTS dll import[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern int MSPLogin(string user, string password, string configs);[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern int MSPLogout();[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern IntPtr QTTSSessionBegin(string _params, ref int errorCode);[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern int QTTSTextPut(string sessionID, string textString, uint textLen, string _params);[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern IntPtr QTTSAudioGet(string sessionID, ref uint audioLen, ref SynthStatus synthStatus, ref int errorCode);[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern IntPtr QTTSAudioInfo(string sessionID);[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]public static extern int QTTSSessionEnd(string sessionID, string hints);#endregion}}

3.把该类库生成一个TTS.dll

4.在C#项目中引用该类库TTS.dll

5.另外需要把下载的SDK中的msc.dll放到语音合成项目中的Debug目录下面(可以百度一下C#调用C/C++的DLL)

6.语音合成项目的代码如下:

using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using TTS;using System.Runtime.InteropServices;using System.IO;using System.Media;using System.Threading;namespace OfflineSpeech{public partial class Form1 : Form{public Form1(){InitializeComponent();}int ret = 0;IntPtr session_ID;private void button1_Click(object sender, EventArgs e){try{///APPID请勿随意改动string login_configs = "appid =***** ";//登录参数,自己注册后获取的appidstring text = richTextBox1.Text.Trim();//待合成的文本if (string.IsNullOrEmpty(richTextBox1.Text.Trim())){text = "请输入合成语音的内容";}string filename = "Call.wav"; //合成的语音文件uint audio_len = 0;SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA;ret = TTSDll.MSPLogin(string.Empty, string.Empty, login_configs);//第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在//MSPLogin方法返回失败if (ret !=(int) ErrorCode.MSP_SUCCESS){return;}//string parameter = "engine_type = local, voice_name=xiaoyan, tts_res_path =fo|res\\tts\\xiaoyan.jet;fo|res\\tts\\common.jet, sample_rate = 16000";string _params = "ssm=1,ent=sms16k,vcn=xiaoyan,spd=medium,aue=speex-wb;7,vol=x-loud,auf=audio/L16;rate=16000";//string @params = "engine_type = local,voice_name=xiaoyan,speed=50,volume=50,pitch=50,rcn=1, text_encoding = UTF8, background_sound=1,sample_rate = 16000";session_ID = TTSDll.QTTSSessionBegin(_params, ref ret);//QTTSSessionBegin方法返回失败if (ret != (int)ErrorCode.MSP_SUCCESS){return;}ret = TTSDll.QTTSTextPut(Ptr2Str(session_ID), text, (uint)Encoding.Default.GetByteCount(text), string.Empty);//QTTSTextPut方法返回失败if (ret != (int)ErrorCode.MSP_SUCCESS){return;}MemoryStream memoryStream = new MemoryStream();memoryStream.Write(new byte[44], 0, 44);while (true){IntPtr source = TTSDll.QTTSAudioGet(Ptr2Str(session_ID), ref audio_len, ref synth_status, ref ret);byte[] array = new byte[(int)audio_len];if (audio_len > 0){Marshal.Copy(source, array, 0, (int)audio_len);}memoryStream.Write(array, 0, array.Length);Thread.Sleep(1000);if (synth_status == SynthStatus.MSP_TTS_FLAG_DATA_END || ret != 0)break;}WAVE_Header wave_Header = getWave_Header((int)memoryStream.Length - 44);byte[] array2 = this.StructToBytes(wave_Header);memoryStream.Position = 0L;memoryStream.Write(array2, 0, array2.Length);memoryStream.Position = 0L;SoundPlayer soundPlayer = new SoundPlayer(memoryStream);soundPlayer.Stop();soundPlayer.Play();if (filename != null){FileStream fileStream = new FileStream(filename, FileMode.Create,FileAccess.Write);memoryStream.WriteTo(fileStream);memoryStream.Close();fileStream.Close();}}catch (Exception){}finally{ret = TTSDll.QTTSSessionEnd(Ptr2Str(session_ID), "");ret = TTSDll.MSPLogout();//退出登录}}/// <summary>/// 结构体转字符串/// </summary>/// <param name="structure"></param>/// <returns></returns>private byte[] StructToBytes(object structure){int num = Marshal.SizeOf(structure);IntPtr intPtr = Marshal.AllocHGlobal(num);byte[] result;try{Marshal.StructureToPtr(structure, intPtr, false);byte[] array = new byte[num];Marshal.Copy(intPtr, array, 0, num);result = array;}finally{Marshal.FreeHGlobal(intPtr);}return result;}/// <summary>/// 结构体初始化赋值/// </summary>/// <param name="data_len"></param>/// <returns></returns>private WAVE_Header getWave_Header(int data_len){return new WAVE_Header{RIFF_ID = 1179011410,File_Size = data_len + 36,RIFF_Type = 1163280727,FMT_ID = 544501094,FMT_Size = 16,FMT_Tag = 1,FMT_Channel = 1,FMT_SamplesPerSec = 16000,AvgBytesPerSec = 32000,BlockAlign = 2,BitsPerSample = 16,DATA_ID = 1635017060,DATA_Size = data_len};}/// <summary>/// 语音音频头/// </summary>private struct WAVE_Header{public int RIFF_ID;public int File_Size;public int RIFF_Type;public int FMT_ID;public int FMT_Size;public short FMT_Tag;public ushort FMT_Channel;public int FMT_SamplesPerSec;public int AvgBytesPerSec;public ushort BlockAlign;public ushort BitsPerSample;public int DATA_ID;public int DATA_Size;}/// 指针转字符串/// </summary>/// <param name="p">指向非托管代码字符串的指针</param>/// <returns>返回指针指向的字符串</returns>public static string Ptr2Str(IntPtr p){List<byte> lb = new List<byte>();while (Marshal.ReadByte(p) != 0){lb.Add(Marshal.ReadByte(p));p = p + 1;}byte[] bs = lb.ToArray();return Encoding.Default.GetString(lb.ToArray());}}}

7.语音合成项目界面如下:

推荐科大讯飞平台论坛帖子:

/forum.php?mod=viewthread&tid=3771

/forum.php?mo ... &highlight=c%23

源码:

WindowsFormsApplication1.zip

appid :要使用自己在科大讯飞官网创建应用后的appid

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。