技术开发 频道

微软SAPI:让你的软件能说会道

  因为 将一段比较长的文本转换成声音文件,通常是一个比较长的过程,所以在这里我们创建一个专门的工作者线程来负责文本的转换,而界面线程则负责显示转换的进度。

// 工作者线程类
    
public class WorkerThread
    {
        
// 用户选择的语音
        
private int nVoiceIndex;
        
// 保存的文件名
        
private string strFileName;
        
// 需要转换的文本
        
private ArrayList arrText;
        
        
// 构造函数,利用构造函数向线程传递参数
        
public WorkerThread(int nIndex, ArrayList aText, string sFileName )
        {
            nVoiceIndex
= nIndex;
            arrText
= aText;
            strFileName
= sFileName;
        }

        
// 线程开始事件
        
public event EventHandler threadStartEvent;
        
// 线程执行时的事件
        
public event EventHandler threadEvent;
        
// 线程结束事件
        
public event EventHandler threadEndEvent;

        
// 线程函数
        
public void runMethod()
        {
            
// 创建SpVoice对象,并选择用户选中的语音
            SpVoice voice
= new SpVoice();
            voice.Voice
= voice.GetVoices(string.Empty, string.Empty).Item(nVoiceIndex);
            try
            {
                
// 创建流媒体文件
                SpeechStreamFileMode SpFileMode
=
                       SpeechStreamFileMode.SSFMCreateForWrite;
                SpFileStream SpFileStream
= new SpFileStream();
                
// 这里我们设置输出的频率,这样可以决定输出文件的大小
                SpFileStream.Format.Type
= SpeechAudioFormatType.SAFTCCITT_ALaw_8kHzMono;
                
// 还可以选择更高品质的格式,不过产生的文件体积更大
            
// SpFileStream.Format.Type = SpeechAudioFormatType.SAFT11kHz16BitMono;

                
// 创建文件,并将SpVoice的输出流指定为当前文件
                SpFileStream.Open(strFileName, SpFileMode,
false);
                voice.AudioOutputStream
= SpFileStream;

                
// 发送线程开始事件,通知主界面,设定进度条的最大值为Count
                threadStartEvent.Invoke(arrText.Count,
new EventArgs());  
              
// 开始将文本输出到音频文件
                
int nCount = 0;
                foreach (
string sOutput in arrText)
                {
                    voice.Speak(sOutput, SpeechVoiceSpeakFlags.SVSFlagsAsync);
                    
// 发送线程运行时事件,移动进度条的位置
                    threadEvent.Invoke(nCount,
new EventArgs());
                    voice.WaitUntilDone(
-1);
                    
++nCount;
                }
                
                
// 关闭音频文件
                SpFileStream.Close();
            }
            catch
            {
            }
            
// 发送线程结束事件,通知主界面关闭进度条
            threadEndEvent.Invoke(
new object(), new EventArgs());
        }
    }
0
相关文章