public MemoryStream SpeechSynthesis(string SpeekText) { MemoryStream mStream = new MemoryStream(1024 * 8); mStream.Write(new byte[44], 0, 44); Speek(SpeekText, ref mStream); //int ret = TTSDll.MSPLogout(); //if (ret != 0) throw new Exception("逆初始化TTS引擎错误,错误代码:" + ret); WAVE_Header header = getWave_Header((int)mStream.Length - 44); //创建wav文件头 byte[] headerByte = StructToBytes(header); //把文件头结构转化为字节数组 //写入文件头 mStream.Position = 0; //定位到文件头 mStream.Write(headerByte, 0, headerByte.Length); //写入文件头 return(mStream); }
/// <summary> /// 根据数据段的长度,生产文件头 /// </summary> /// <param name="data_len">音频数据长度</param> /// <returns>返回wav文件头结构体</returns> WAVE_Header getWave_Header(int data_len) { WAVE_Header wav_Header = new WAVE_Header(); wav_Header.RIFF_ID = 0x46464952; //字符RIFF wav_Header.File_Size = data_len + 36; wav_Header.RIFF_Type = 0x45564157; //字符WAVE wav_Header.FMT_ID = 0x20746D66; //字符fmt wav_Header.FMT_Size = 16; wav_Header.FMT_Tag = 0x0001; wav_Header.FMT_Channel = 1; //单声道 wav_Header.FMT_SamplesPerSec = 16000; //采样频率 wav_Header.AvgBytesPerSec = 32000; //每秒所需字节数 wav_Header.BlockAlign = 2; //每个采样1个字节 wav_Header.BitsPerSample = 16; //每个采样8bit wav_Header.DATA_ID = 0x61746164; //字符data wav_Header.DATA_Size = data_len; return(wav_Header); }
/// <summary> /// 根据数据段的长度,生产文件头 /// </summary> /// <param name="data_len">音频数据长度</param> /// <returns>返回wav文件头结构体</returns> WAVE_Header getWave_Header(int data_len) { WAVE_Header wav_Header = new WAVE_Header(); wav_Header.RIFF_ID = 0x46464952; //字符RIFF wav_Header.File_Size = data_len + 36; wav_Header.RIFF_Type = 0x45564157; //字符WAVE wav_Header.FMT_ID = 0x20746D66; //字符fmt wav_Header.FMT_Size = 16; wav_Header.FMT_Tag = 0x0001; wav_Header.FMT_Channel = 1; //单声道 wav_Header.FMT_SamplesPerSec = 16000; //采样频率 wav_Header.AvgBytesPerSec = 32000; //每秒所需字节数 wav_Header.BlockAlign = 2; //每个采样1个字节 wav_Header.BitsPerSample = 16; //每个采样8bit wav_Header.DATA_ID = 0x61746164; //字符data wav_Header.DATA_Size = data_len; return wav_Header; }
public void CreateWAV(string text) { try { if (string.IsNullOrEmpty(text)) { return; } string filename = "Call.wav"; //合成的语音文件 uint audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; string _params = ConfigurationManager.AppSettings["tts_putonghua"].ToString(); session_ID = MSCDLL.QTTSSessionBegin(_params, ref ret); //QTTSSessionBegin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } ret = MSCDLL.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 = MSCDLL.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 = MSCDLL.QTTSSessionEnd(Ptr2Str(session_ID), ""); } }
public byte[] Synthesis(string content, EAudioType eAudioType) { ValidateOption(); byte[] result; var ret = 0; var session_ID = new IntPtr(); var option = _optionsMonitor.CurrentValue; try { ///APPID请勿随意改动 string login_configs = $"appid ={option.AppId} ";//登录参数,自己注册后获取的appid if (string.IsNullOrEmpty(content)) { throw new ArgumentException("请输入合成语音的内容"); } uint audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; ret = XFTtsHelper.MSPLogin(string.Empty, string.Empty, login_configs); //第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn //MSPLogin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { throw new ArgumentException($"登录失败,失败error为{ret}"); } //string _params = "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"; session_ID = XFTtsHelper.QTTSSessionBegin(option.SessionBeginParams, ref ret); //session_ID = XFTtsHelper.QTTSSessionBegin(_params, ref ret); //QTTSSessionBegin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { throw new ArgumentException($"QTTSSessionBegin方法返回失败:{ret}"); } ret = XFTtsHelper.QTTSTextPut(Ptr2Str(session_ID), content, (uint)Encoding.Default.GetByteCount(content), string.Empty); //QTTSTextPut方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { throw new ArgumentException($"QTTSTextPut方法返回失败:{ret}"); } using (var memoryStream = new MemoryStream()) { memoryStream.Write(new byte[44], 0, 44); while (true) { IntPtr source = XFTtsHelper.QTTSAudioGet(Ptr2Str(session_ID), ref audio_len, ref synth_status, ref ret); if (ret != 0) { break; } byte[] array = new byte[(int)audio_len]; if (audio_len > 0 && source != default) { Marshal.Copy(source, array, 0, (int)audio_len); memoryStream.Write(array, 0, array.Length); } //Thread.Sleep(10);//官方文档是建议等待一段时间,但经测试,太长了。先去除 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; result = memoryStream.ToArray(); } if (eAudioType != EAudioType.WAV) { throw new Exception("未实现WAV转MP3"); } return(result); } finally { XFTtsHelper.QTTSSessionEnd(Ptr2Str(session_ID), ""); XFTtsHelper.MSPLogout();//退出登录 } }
/// <summary> ///音频合成 点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnTextToVoice_Click(object sender, EventArgs e) { try { //登录参数,自己注册后获取的appid string login_configs = "appid=5983daf6"; string text = txtInput.Text.Trim();//待合成的文本 uint audio_len = 0; if (string.IsNullOrEmpty(txtInput.Text.Trim())) { txtInput.Text = "请输入合成语音的内容"; return; } var speekerCode = IFYDll.GetSpeekerCode(cboSpeeker.SelectedIndex); LoadingHelper.ShowLoading("加载中", this, o => { SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; //第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn this.BeginInvoke(updateStatus, "登录接口"); ret = IFYDll.MSPLogin("*****@*****.**", "jkljlk123", login_configs); //MSPLogin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } string _params = $"ssm=1,ent=sms16k,vcn={speekerCode},spd=medium,aue=speex-wb;7,vol=x-loud,auf=audio/L16;rate=16000"; session_ID = IFYDll.QTTSSessionBegin(_params, ref ret); //QTTSSessionBegin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } //发送待合成音频文本 this.BeginInvoke(updateStatus, "发送文字"); ret = IFYDll.QTTSTextPut(Ptr2Str(session_ID), text, (uint)Encoding.Default.GetByteCount(text), string.Empty); //QTTSTextPut方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } //分块获取合成音频流 this.BeginInvoke(updateStatus, "获取合成语音"); MemoryStream memoryStream = new MemoryStream(); memoryStream.Write(new byte[44], 0, 44); while (true) { IntPtr source = IFYDll.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(); } }); this.BeginInvoke(updateStatus, "就绪"); } catch (Exception ex) { txtInput.Text = ex.Message; } finally { //主动结束本次音频合成 ret = IFYDll.QTTSSessionEnd(Ptr2Str(session_ID), ""); //退出登录 ret = IFYDll.MSPLogout(); } }
/// <summary> /// 把文字转化为声音,单路配置,一种语音 /// </summary> /// <param name="speekText">要转化成语音的文字</param> /// <param name="outWaveFlie">把声音转为文件,默认为不生产wave文件</param> private void speek(string speekText, string outWaveFlie = null) { if (speekText == "" || _speed == "" || _vol == "" || _speeker == "") { return; } string szParams = "ssm=1," + _speeker + ",spd=" + _speed + ",aue=speex-wb;7,vol=" + _vol + ",auf=audio/L16;rate=16000"; int ret = 0; try { sessionID = Ptr2Str(TTSDll.QTTSSessionBegin(szParams, ref ret)); if (ret != 0) { throw new Exception("初始化TTS引会话错误,错误代码:" + ret); } ret = TTSDll.QTTSTextPut(sessionID, speekText, (uint)Encoding.Default.GetByteCount(speekText), string.Empty); if (ret != 0) { throw new Exception("向服务器发送数据,错误代码:" + ret); } IntPtr audio_data; int audio_len = 0; SynthStatus synth_status = SynthStatus.TTS_FLAG_STILL_HAVE_DATA; MemoryStream fs = new MemoryStream(); fs.Write(new byte[44], 0, 44); //写44字节的空文件头 while (synth_status == SynthStatus.TTS_FLAG_STILL_HAVE_DATA) { audio_data = TTSDll.QTTSAudioGet(sessionID, ref audio_len, ref synth_status, ref ret); if (ret != 0) { break; } byte[] data = new byte[audio_len]; if (audio_len > 0) { Marshal.Copy(audio_data, data, 0, audio_len); } fs.Write(data, 0, data.Length); } WAVE_Header header = getWave_Header((int)fs.Length - 44); //创建wav文件头 byte[] headerByte = StructToBytes(header); //把文件头结构转化为字节数组 //写入文件头 fs.Position = 0; //定位到文件头 fs.Write(headerByte, 0, headerByte.Length); //写入文件头 fs.Position = 0; System.Media.SoundPlayer pl = new System.Media.SoundPlayer(fs); pl.Stop(); pl.Play(); if (outWaveFlie != null) { FileStream ofs = new FileStream(outWaveFlie, FileMode.Create); fs.WriteTo(ofs); fs.Close(); ofs.Close(); fs = null; ofs = null; } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } finally { ret = TTSDll.QTTSSessionEnd(sessionID, ""); if (ret != 0) { throw new Exception("结束TTS会话错误,错误代码:" + ret); } } }
private MemoryStream GetAudioData(string str) { int ret = 0; IntPtr session_ID; //APPID请勿随意改动 string login_configs = "appid = 5ac9f8d1"; //登录参数,自己注册后获取的appid string text = str; //text是待合成文本 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(null); } //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(null); } ret = TTSDll.QTTSTextPut(Ptr2Str(session_ID), text, (uint)Encoding.Default.GetByteCount(text), string.Empty); //QTTSTextPut方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return(null); } //内存流可直接在内存进行读写,不需要临时缓冲区或者临时文件 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; //将指针定位到开头 ret = TTSDll.QTTSSessionEnd(Ptr2Str(session_ID), ""); //结束会话 ret = TTSDll.MSPLogout(); //退出登录 return(memoryStream); }
/// <summary> /// 把文字转化为声音,单路配置,一种语音 /// </summary> /// <param name="speekText">要转化成语音的文字</param> /// <param name="outWaveFlie">把声音转为文件,默认为不生产wave文件</param> private void speek(string speekText, string outWaveFlie = null) { string szParams = "ssm=0,ent=intp65_en,vcn=" + _speaker + ",aue=speex-wb;7,auf=audio/L16;rate=16000"; int ret = 0; try { sessionID = Ptr2Str(TTS.QTTSSessionBegin(szParams, ref ret)); if (ret != 0) { throw new Exception("初始化TTS引会话错误,错误代码:" + ret); } ret = TTS.QTTSTextPut(sessionID, speekText, (uint)Encoding.Default.GetByteCount(speekText), string.Empty); if (ret != 0) { throw new Exception("向服务器发送数据,错误代码:" + ret); } IntPtr audio_data; int audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; MemoryStream ms = new MemoryStream(); ms.Write(new byte[44], 0, 44); //写44字节的空文件头 while (synth_status == SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA) { audio_data = TTS.QTTSAudioGet(sessionID, ref audio_len, ref synth_status, ref ret); //System.Diagnostics.Debug.WriteLine("audio_len:"+audio_len); if (audio_data != IntPtr.Zero) { //System.Diagnostics.Debug.WriteLine(">0"); byte[] data = new byte[audio_len]; Marshal.Copy(audio_data, data, 0, audio_len); //System.Diagnostics.Debug.WriteLine("data.length:"+data.Length); ms.Write(data, 0, data.Length); //System.Diagnostics.Debug.WriteLine("write end"); if (synth_status == SynthStatus.MSP_TTS_FLAG_DATA_END || ret != 0) { //System.Diagnostics.Debug.WriteLine("break"); break; } } } System.Diagnostics.Debug.WriteLine("wav header"); WAVE_Header header = getWave_Header((int)ms.Length - 44); //创建wav文件头 byte[] headerByte = StructToBytes(header); //把文件头结构转化为字节数组 //写入文件头 ms.Position = 0; //定位到文件头 ms.Write(headerByte, 0, headerByte.Length); //写入文件头 /* * System.Diagnostics.Debug.WriteLine("play"); * ms.Position = 0; * System.Media.SoundPlayer pl = new System.Media.SoundPlayer(ms); * pl.Stop(); * pl.Play(); */ if (outWaveFlie != null) { //System.Diagnostics.Debug.WriteLine("outWaveFile:"+outWaveFlie); FileStream fs = new FileStream(outWaveFlie, FileMode.Create); ms.WriteTo(fs); ms.Close(); fs.Close(); ms = null; fs = null; } } catch (Exception ex) { throw new Exception("Error:" + ex.Message); } finally { ret = TTS.QTTSSessionEnd(sessionID, ""); if (ret != 0) { throw new Exception("结束TTS会话错误,错误代码:" + ret); } } }
public static void NewMethod(string txt) { try { ///APPID请勿随意改动 string login_configs = "appid =5ce2167e "; //登录参数,自己注册后获取的appid string text = txt; //待合成的文本 string filename = "D:\\p.wav"; //合成的语音文件 uint audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; ret = SoundPlay.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 = SoundPlay.QTTSSessionBegin(_params, ref ret); //QTTSSessionBegin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } ret = SoundPlay.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 = SoundPlay.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); 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); memoryStream.WriteTo(fileStream); memoryStream.Close(); fileStream.Close(); } } catch (Exception ex) { } finally { ret = SoundPlay.QTTSSessionEnd(Ptr2Str(session_ID), ""); ret = SoundPlay.MSPLogout();//退出登录 } }
/// <summary> /// 把文字转化为声音,单路配置,一种语音 /// </summary> /// <param name="speekText">要转化成语音的文字</param> /// <param name="outWaveFlie">把声音转为文件,默认为不生产wave文件</param> public void Speak(string speekText, string szParams, string outWaveFlie) { byte[] bytes = null; int ret = 0; try { sessionID = Marshal.PtrToStringAuto(MSPAPI.QTTSSessionBegin(szParams, ref ret)); if (ret != 0) { if (ttsSpeakErrorEvent != null) { ttsSpeakErrorEvent.Invoke("初始化TTS引会话错误,错误代码:" + ret); } return; } ret = MSPAPI.QTTSTextPut(sessionID, speekText, (uint)Encoding.Unicode.GetByteCount(speekText), string.Empty); if (ret != 0) { if (ttsSpeakErrorEvent != null) { ttsSpeakErrorEvent.Invoke("向服务器发送数据,错误代码:" + ret); } return; } IntPtr audio_data; int audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; using (MemoryStream ms = new MemoryStream()) { ms.Write(new byte[44], 0, 44); //写44字节的空文件头 while (synth_status == SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA) { audio_data = MSPAPI.QTTSAudioGet(sessionID, ref audio_len, ref synth_status, ref ret); if (audio_data != IntPtr.Zero) { byte[] data = new byte[audio_len]; Marshal.Copy(audio_data, data, 0, audio_len); ms.Write(data, 0, data.Length); if (synth_status == SynthStatus.MSP_TTS_FLAG_DATA_END || ret != 0) { if (ret != 0) { if (ttsSpeakErrorEvent != null) { ttsSpeakErrorEvent.Invoke("下载TTS文件错误,错误代码:" + ret); } return; } break; } } Thread.Sleep(150); } System.Diagnostics.Debug.WriteLine("wav header"); WAVE_Header header = getWave_Header((int)ms.Length - 44); //创建wav文件头 byte[] headerByte = StructToBytes(header); //把文件头结构转化为字节数组 //写入文件头 ms.Position = 0; //定位到文件头 ms.Write(headerByte, 0, headerByte.Length); //写入文件头 bytes = ms.ToArray(); ms.Close(); } if (outWaveFlie != null) { if (File.Exists(outWaveFlie)) { File.Delete(outWaveFlie); } File.WriteAllBytes(outWaveFlie, bytes); } } catch (Exception ex) { if (ttsSpeakErrorEvent != null) { ttsSpeakErrorEvent.Invoke("Error:" + ex.Message); } return; } finally { ret = MSPAPI.QTTSSessionEnd(sessionID, ""); if (ret != 0) { if (ttsSpeakErrorEvent != null) { ttsSpeakErrorEvent.Invoke("结束TTS会话错误,错误代码:" + ret); } } else { if (tts_SpeakFinishedEvent != null) { tts_SpeakFinishedEvent.Invoke(speekText, bytes); } } } }
/// <summary> /// 语音识别 /// </summary> /// <param name="text"></param>文本内容 public void SpeechTest(String text, string ent, string vcn) { try { ///APPID请勿随意改动 string login_configs = "appid =59c4ae84 ";//登录参数,自己注册后获取的appid if (string.IsNullOrEmpty(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 _params = "ssm=1,ent=" + ent + ",vcn=" + vcn + ",spd=medium,aue=speex-wb;7,vol=x-loud,auf=audio/L16;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="text">要转换的文字</param> /// <param name="guisy">生成声音文件的标识</param> public string txt2ShengYin(string text, string guisy) { try { ///APPID请勿随意改动 string login_configs = ZmConfig.XunFeiAppId;//登录参数,自己注册后获取的appid if (string.IsNullOrEmpty(text)) { return("请输入合成语音的内容"); } string filename = guisy + ".wav"; //合成的语音文件 uint audio_len = 0; SynthStatus synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; //第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn // usr[in] 此参数保留,传入NULL即可。 //pwd[in] 此参数保留,传入NULL即可。 //params[in] 参见下表: //格式说明:每个参数和参数值通过key=value的形式组成参数对;如果有多个参数对,再用逗号进行拼接,如:key_1=value_1,key_2=value_2 //注意:每个参数(key)和参数值(value)均不得含有逗号(,)和等号(=),否则会被截断 //在线/离线业务 参数 名称 ret = TTSDll.MSPLogin(string.Empty, string.Empty, login_configs); //MSPLogin方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return("MSPLogin:"******"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("QTTSSessionBegin:" + ret.ToString()); } ret = TTSDll.QTTSTextPut(Ptr2Str(session_ID), text, (uint)Encoding.Default.GetByteCount(text), string.Empty); //QTTSTextPut方法返回失败 if (ret != (int)ErrorCode.MSP_SUCCESS) { return("QTTSTextPut:" + ret.ToString()); } 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; 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();//退出登录 } return("ok:" + guisy); }
/// <summary> /// 合成线程 /// </summary> private void ThreadStart() { try { ErrorCode errorCode; IntPtr ptr = Msc.QTTSSessionBegin(m_Params, out errorCode); if (errorCode != ErrorCode.MSP_SUCCESS) { Debug.Log("开始合成出错:(错误码)" + (int)errorCode); Account.Logout(); return; } ErrorCode errorCode1 = Msc.QTTSTextPut(ptr, m_Data, (uint)Encoding.Default.GetByteCount(m_Data), string.Empty); if (errorCode1 != ErrorCode.MSP_SUCCESS) { Debug.Log("文本写入出错:(错误码)" + (int)errorCode); Account.Logout(); return; } MemoryStream memoryStream = new MemoryStream(); SynthStatus synthStatus; ErrorCode errorCode2; uint length; while (true) { IntPtr data = Msc.QTTSAudioGet(ptr, out length, out synthStatus, out errorCode2); if (data != null) { if (length > 0) { byte[] vs = new byte[(int)length]; Marshal.Copy(data, vs, 0, (int)length); memoryStream.Write(vs, 0, vs.Length); Thread.Sleep(1000); } } if (errorCode2 != ErrorCode.MSP_SUCCESS) { Debug.Log("获取音频出错:(错误码)" + (int)errorCode2); Account.Logout(); return; } if (synthStatus == SynthStatus.MSP_TTS_FLAG_DATA_END) { break; } } ErrorCode errorCode3 = Msc.QTTSSessionEnd(ptr, "合成结束"); WAVE_Header wave_Header = getWave_Header((int)memoryStream.Length); byte[] head = StructToBytes(wave_Header); memoryStream.Position = 0L; memoryStream.Write(head, 0, head.Length); memoryStream.Position = 0L; if (errorCode3 != ErrorCode.MSP_SUCCESS) { Debug.Log("结束合成音频出错:(错误码)" + (int)errorCode2); Account.Logout(); return; } Account.Logout(); isDown = true; Data = memoryStream.GetBuffer(); Debug.Log("合成完成"); } catch (Exception e) { Debug.Log(e); Account.Logout(); } }