/// <summary> /// 处理错误 /// </summary> /// <param name="errorMsg">错误的函数</param> /// <param name="ret">错误的返回值</param> /// <param name="sessionID">sessionID</param> /// <param name="writer">打开的文件</param> /// <param name="fs">打开的文件</param> private static void HandleErrorMsg(string errorMsg, int ret, string sessionID, BinaryWriter writer, FileStream fs) { Utils.CustomPrint(errorMsg + " err,errCode=" + ((ErrorCode)ret).ToString("G")); DllImports.QTTSSessionEnd(sessionID, errorMsg); if (writer != null) { writer.Close(); writer = null; } if (fs != null) { fs.Close(); fs = null; } }
/// <summary> /// 运行语音合成功能 /// </summary> /// <returns></returns> public IEnumerator RunTTS() { if (text == null) { yield break; } WaveFormat waveFormat = new WaveFormat(); int nLength = 0; int nFormatChunkLength = 0x10; // Format chunk length. short shPad = 1; // File padding int ret = 0; uint audioLen = 0; int sampleCount = 0; int synthStatus = (int)TTSStatus.MSP_TTS_FLAG_STILL_HAVE_DATA; IntPtr ptrSessionID = DllImports.QTTSSessionBegin(sessionTTSBeginParams, out ret); string sessionID = Marshal.PtrToStringAnsi(ptrSessionID); if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret) { Utils.CustomPrint("TTSSessionBegin failed, errCode=" + ((ErrorCode)ret).ToString("G")); yield break; } FileStream waveFile = new FileStream(textPath, FileMode.OpenOrCreate); BinaryWriter writer = new BinaryWriter(waveFile); char[] chunkRiff = { 'R', 'I', 'F', 'F' }; char[] chunkType = { 'W', 'A', 'V', 'E' }; char[] chunkFmt = { 'f', 'm', 't', ' ' }; char[] chunkData = { 'd', 'a', 't', 'a' }; //RIFF块 writer.Write(chunkRiff); writer.Write(nLength); writer.Write(chunkType); //WAVE块 writer.Write(chunkFmt); writer.Write(nFormatChunkLength); writer.Write(shPad); writer.Write(waveFormat.mChannels); writer.Write(waveFormat.mSamplesPerSecond); writer.Write(waveFormat.mAverageBytesPerSecond); writer.Write(waveFormat.mBlockAlign); writer.Write(waveFormat.mBitsPerSample); //数据块 writer.Write(chunkData); writer.Write((int)0); // The sample length will be written in later. ret = DllImports.QTTSTextPut(sessionID, text, (uint)text.Length, null); if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret) { HandleErrorMsg("QTTSTextPut", ret, sessionID, writer, waveFile); yield break; } Utils.CustomPrint("正在合成 ...\n"); while (true) { ///获取合成音频 IntPtr data = DllImports.QTTSAudioGet(sessionID, ref audioLen, ref synthStatus, out ret); if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret) { break; } if (IntPtr.Zero != data) { byte[] buff = new byte[audioLen]; Marshal.Copy(data, buff, 0, buff.Length); writer.Write(buff, 0, buff.Length); sampleCount += (int)audioLen;///计算data_size大小 buff = null; } if (TTSStatus.MSP_TTS_FLAG_DATA_END == (TTSStatus)synthStatus) { break; } Utils.CustomPrint(">"); yield return(new WaitForSeconds(0.2f)); } if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret) { Utils.CustomPrint("QTTSAudioGet failed, errCode=" + ((ErrorCode)ret).ToString("G")); DllImports.QTTSSessionEnd(sessionID, "AudioGetError"); writer.Close(); waveFile.Close(); yield break; } //写WAV文件尾 writer.Seek(4, SeekOrigin.Begin); writer.Write((int)(sampleCount + 36)); writer.Seek(40, SeekOrigin.Begin); writer.Write(sampleCount); writer.Close(); waveFile.Close(); writer = null; waveFile = null; ///合成完毕 ret = DllImports.QTTSSessionEnd(sessionID, "Normal"); if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret) { Utils.CustomPrint("QTTSSessionEnd failed, errCode=" + ((ErrorCode)ret).ToString("G")); } ptrSessionID = IntPtr.Zero; Utils.CustomPrint("合成完毕"); yield break; }