在讯飞开放平台下载离线语音合成SDK
解压SDK压缩包
使用msc.dll
在VS中创建项目,项目结构如图:
TTSDLL代码:
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 } #endregion public 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 }
PLay.cs 类,代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public static class Play 2 { 3 private static int ret = 0; 4 private static IntPtr session_ID; 5 public static void NewMethod(string txt) 6 { 7 try 8 { 9 ///APPID请勿随意改动 10 string login_configs = "appid =5ce2167e ";//登录参数,自己注册后获取的appid 11 string text = txt;//待合成的文本 12 if (string.IsNullOrEmpty(txt)) 13 { 14 text = "请输入合成语音的内容"; 15 } 16 17 string filename = "d:\\p.wav"; //合成的语音文件 18 uint audio_len = 0; 19 20 SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; 21 ret = TTSDLL.MSPLogin(string.Empty, string.Empty, login_configs);//第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn 22 //MSPLogin方法返回失败 23 if (ret != (int)ErrorCode.MSP_SUCCESS) 24 { 25 return; 26 } 27 //string parameter = "engine_type = local, voice_name=xiaoyan, tts_res_path =fo|res\\tts\\xiaoyan.jet;fo|res\\tts\\common.jet, sample_rate = 16000"; 28 string _params = "ssm=1,ent=sms16k,vcn=xiaoyan,spd=medium,aue=speex-wb;7,vol=x-loud,auf=audio/L16;rate=16000"; 29 //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"; 30 session_ID = TTSDLL.QTTSSessionBegin(_params, ref ret); 31 //QTTSSessionBegin方法返回失败 32 if (ret != (int)ErrorCode.MSP_SUCCESS) 33 { 34 return; 35 } 36 ret = TTSDLL.QTTSTextPut(Ptr2Str(session_ID), text, (uint)Encoding.Default.GetByteCount(text), string.Empty); 37 //QTTSTextPut方法返回失败 38 if (ret != (int)ErrorCode.MSP_SUCCESS) 39 { 40 return; 41 } 42 43 MemoryStream memoryStream = new MemoryStream(); 44 memoryStream.Write(new byte[44], 0, 44); 45 while (true) 46 { 47 IntPtr source = TTSDLL.QTTSAudioGet(Ptr2Str(session_ID), ref audio_len, ref synth_status, ref ret); 48 byte[] array = new byte[(int)audio_len]; 49 if (audio_len > 0) 50 { 51 Marshal.Copy(source, array, 0, (int)audio_len); 52 } 53 memoryStream.Write(array, 0, array.Length); 54 Thread.Sleep(150); 55 if (synth_status == SynthStatus.MSP_TTS_FLAG_DATA_END || ret != 0) 56 break; 57 } 58 WAVE_Header wave_Header = getWave_Header((int)memoryStream.Length - 44); 59 byte[] array2 = StructToBytes(wave_Header); 60 memoryStream.Position = 0L; 61 memoryStream.Write(array2, 0, array2.Length); 62 memoryStream.Position = 0L; 63 SoundPlayer soundPlayer = new SoundPlayer(memoryStream); 64 soundPlayer.Stop(); 65 soundPlayer.Play(); 66 if (filename != null) 67 { 68 FileStream fileStream = new FileStream(filename, FileMode.Create); 69 memoryStream.WriteTo(fileStream); 70 memoryStream.Close(); 71 fileStream.Close(); 72 } 73 74 } 75 catch (Exception ex) 76 { 77 } 78 finally 79 { 80 ret = TTSDLL.QTTSSessionEnd(Ptr2Str(session_ID), ""); 81 ret = TTSDLL.MSPLogout();//退出登录 82 } 83 } 84 85 /// <summary> 86 /// 结构体转字符串 87 /// </summary> 88 /// <param name="structure"></param> 89 /// <returns></returns> 90 private static byte[] StructToBytes(object structure) 91 { 92 int num = Marshal.SizeOf(structure); 93 IntPtr intPtr = Marshal.AllocHGlobal(num); 94 byte[] result; 95 try 96 { 97 Marshal.StructureToPtr(structure, intPtr, false); 98 byte[] array = new byte[num]; 99 Marshal.Copy(intPtr, array, 0, num); 100 result = array; 101 } 102 finally 103 { 104 Marshal.FreeHGlobal(intPtr); 105 } 106 return result; 107 } 108 109 /// <summary> 110 /// 结构体初始化赋值 111 /// </summary> 112 /// <param name="data_len"></param> 113 /// <returns></returns> 114 private static WAVE_Header getWave_Header(int data_len) 115 { 116 return new WAVE_Header 117 { 118 RIFF_ID = 1179011410, 119 File_Size = data_len + 36, 120 RIFF_Type = 1163280727, 121 FMT_ID = 544501094, 122 FMT_Size = 16, 123 FMT_Tag = 1, 124 FMT_Channel = 1, 125 FMT_SamplesPerSec = 16000, 126 AvgBytesPerSec = 32000, 127 BlockAlign = 2, 128 BitsPerSample = 16, 129 DATA_ID = 1635017060, 130 DATA_Size = data_len 131 }; 132 } 133 /// <summary> 134 /// 语音音频头 135 /// </summary> 136 private struct WAVE_Header 137 { 138 public int RIFF_ID; 139 public int File_Size; 140 public int RIFF_Type; 141 public int FMT_ID; 142 public int FMT_Size; 143 public short FMT_Tag; 144 public ushort FMT_Channel; 145 public int FMT_SamplesPerSec; 146 public int AvgBytesPerSec; 147 public ushort BlockAlign; 148 public ushort BitsPerSample; 149 public int DATA_ID; 150 public int DATA_Size; 151 } 152 /// 指针转字符串 153 /// </summary> 154 /// <param name="p">指向非托管代码字符串的指针</param> 155 /// <returns>返回指针指向的字符串</returns> 156 public static string Ptr2Str(IntPtr p) 157 { 158 List<byte> lb = new List<byte>(); 159 while (Marshal.ReadByte(p) != 0) 160 { 161 lb.Add(Marshal.ReadByte(p)); 162 p = p + 1; 163 } 164 byte[] bs = lb.ToArray(); 165 return Encoding.Default.GetString(lb.ToArray()); 166 } 167 }
在Form1中调用
-----------------------------------------------
感谢CSDN上各位大神提供源码
-----------------------------------------------