C#調用科大訊飛在線語音合成(Windows)

1、下載在線語音合成SDK,SDK中如下圖是官方提供的在線語音合成C語言的例子

(在開始用C#做時,可以先研究下他們的例子)

這是整個工程的流程:

2、創建自己的C#工程,將SDK中msc.dll文件複製到C#工程中的debug文件下

(msc和appid是相互對應的,要是自己SDK中的)

3、下面便是代碼部分了

首先要封裝自己的dll:

因爲msc.dll是C語言寫的,所以自己要封yibu裝一個C#的dll,就是把工程裏需要的函數和結構體封裝到自己的dll中,因爲代碼太長,我就粘了主要的一部分

 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
    }

接着便是主要合成語音了(主代碼如下):

private static void button1_Click(string str)
		{
			int ret = 0;
		    IntPtr session_ID;
			//APPID請勿隨意改動
			string login_configs = "appid = 5ac9f8d1";//登錄參數,自己註冊後獲取的appid
			string text=str;//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(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(150);//防止CPU頻繁佔用
				if (synth_status == SynthStatus.MSP_TTS_FLAG_DATA_END || ret != 0)
					break;
			}
			WAVE_Header wave_Header = getWave_Header((int)memoryStream.Length - 44);
			byte[] array2 = 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);//將內存流中的數據寫入到文件流,文件流寫入到音頻文件中I
				memoryStream.Close();//關閉流
				fileStream.Close();
			}
			ret = TTSDll.QTTSSessionEnd(Ptr2Str(session_ID), "");//結束會話
			ret = TTSDll.MSPLogout();//退出登錄
		}

運行結果如下(輸入想轉換的文字內容,支持中英文,打回車就會播放轉換的語音,同時在工程的debug目錄下生成音頻文件):

文章參考:https://blog.csdn.net/wyq1153/article/details/72178422/

文章對應demo:https://download.csdn.net/download/hyy_sui_yuan/10634487

如有問題歡迎提問,看到一定及時解答

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章