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

发布时间:2015-11-04 15:39:08   来源:文档文库   
字号:

窗体顶端


窗体底端

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

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

SDK中目录如下:

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

 

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

 

步骤:

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

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

word/media/image2.gif

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

namespace TTS

{

publicenum 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枚举常量

///

/// vol参数的枚举常量

///

publicenum enuVol

{

x_soft,

soft,

medium,

loud,

x_loud

}

///

/// speed语速参数的枚举常量

///

publicenum enuSpeed

{

x_slow,

slow,

medium,

fast,

x_fast

}

///

/// speeker朗读者枚举常量

///

publicenum enuSpeeker

{

小燕_青年女声_中英文_普通话 = 0,

小宇_青年男声_中英文_普通话,

凯瑟琳_青年女声_英语,

亨利_青年男声_英语,

玛丽_青年女声_英语,

小研_青年女声_中英文_普通话,

小琪_青年女声_中英文_普通话,

小峰_青年男声_中英文_普通话,

小梅_青年女声_中英文_粤语,

小莉_青年女声_中英文_台普,

小蓉_青年女声_汉语_四川话,

小芸_青年女声_汉语_东北话,

小坤_青年男声_汉语_河南话,

小强_青年男声_汉语_湖南话,

小莹_青年女声_汉语_陕西话,

小新_童年男声_汉语_普通话,

楠楠_童年女声_汉语_普通话,

老孙_老年男声_汉语_普通话

}

publicenum SynthStatus

{

MSP_TTS_FLAG_STILL_HAVE_DATA = 1,

MSP_TTS_FLAG_DATA_END = 2,

MSP_TTS_FLAG_CMD_CANCELED = 0

}

#endregion

publicclass TTSDll

{

#region TTS dll import

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticexternint MSPLogin(string user, string password, string configs);

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticexternint MSPLogout();

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticextern IntPtr QTTSSessionBegin(string _params, refint errorCode);

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticexternint QTTSTextPut(string sessionID, string textString, uint textLen, string _params);

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticextern IntPtr QTTSAudioGet(string sessionID, refuint audioLen, ref SynthStatus synthStatus, refint errorCode);

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticextern IntPtr QTTSAudioInfo(string sessionID);

[DllImport("msc.dll", CallingConvention = CallingConvention.Winapi)]

publicstaticexternint QTTSSessionEnd(string sessionID, string hints);

#endregion

}

}

View Code

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

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

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

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

word/media/image2.gif

using System;

using System.Collections.Generic;

using System.ComponentModel;

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

{

publicpartialclass Form1 : Form

{

public Form1()

{

InitializeComponent();

}

int ret = 0;

IntPtr session_ID;

privatevoid button1_Click(object sender, EventArgs e)

{

try

{

///APPID请勿随意改动

string login_configs = "appid =***** ";//登录参数,自己注册后获取的appid

string 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);//第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn

//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(newbyte[44], 0, 44);

while (true)

{

IntPtr source = TTSDll.QTTSAudioGet(Ptr2Str(session_ID), ref audio_len, ref synth_status, ref ret);

byte[] array = newbyte[(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();//退出登录

}

}

///

/// 结构体转字符串

///

///

///

privatebyte[] StructToBytes(object structure)

{

int num = Marshal.SizeOf(structure);

IntPtr intPtr = Marshal.AllocHGlobal(num);

byte[] result;

try

{

Marshal.StructureToPtr(structure, intPtr, false);

byte[] array = newbyte[num];

Marshal.Copy(intPtr, array, 0, num);

result = array;

}

finally

{

Marshal.FreeHGlobal(intPtr);

}

return result;

}

///

/// 结构体初始化赋值

///

///

///

private WAVE_Header getWave_Header(int data_len)

{

returnnew 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

};

}

///

/// 语音音频头

///

privatestruct WAVE_Header

{

publicint RIFF_ID;

publicint File_Size;

publicint RIFF_Type;

publicint FMT_ID;

publicint FMT_Size;

publicshort FMT_Tag;

publicushort FMT_Channel;

publicint FMT_SamplesPerSec;

publicint AvgBytesPerSec;

publicushort BlockAlign;

publicushort BitsPerSample;

publicint DATA_ID;

publicint DATA_Size;

}

/// 指针转字符串

///

///指向非托管代码字符串的指针

///返回指针指向的字符串

publicstaticstring 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.To();

return Encoding.Default.GetString(lb.To());

}

}

}

View Code

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

 

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

http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=3771

http://bbs.xfyun.cn/forum.php?mo ... &highlight=c%23

posted @ 2015-05-15 11:52 feitiana03120 阅读(...) 评论(...) 编辑 收藏

刷新评论刷新页面返回顶部

博客园首页博问新闻闪存程序员招聘知识库

公告

Copyright ©2015 feitiana03120

本文来源:https://www.2haoxitong.net/k/doc/730d9953f90f76c660371a7d.html

《C#调用科大讯飞离线语音合成TTS.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式