技术开发 频道

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

  跟直接朗读文本相似,我们仍旧使用SpVoice的Speak()函数朗读文本,只是我们通过指定SpVoice的AudioOutputStream属性,将语音输出到一个音频文件,这样就完成了文本文件到音频文件的转换。

  完成转换工作者线程的创建后,我们就可以利用它来完成具体的转换工作。在窗体的保存按钮的单击响应函数中,我们创建相应的工作者线程来进行文本的转换。

private void btnSavetoWAV_Click(object sender, EventArgs e)
        {
            
string strWAVFile = "";
            try
            {
                
// 使用保存文件对话框,选择保存的文件
                SaveFileDialog sfd
= new SaveFileDialog();
                sfd.Filter
= "All files (*.*)|*.*|wav files (*.wav)|*.wav";
                sfd.Title
= "Save to a wave file";
                sfd.FilterIndex
= 2;
                sfd.RestoreDirectory
= true;

                
if (sfd.ShowDialog() == DialogResult.OK)
                {
                    
// 获取用户输入的文件名
                    strWAVFile
= sfd.FileName;

                    
// 从Text Box控件获取要转换的文本
                    ArrayList arrText
= new ArrayList();
                    foreach (
String sLine in this.textPreview.Lines)
                        arrText.Add(sLine);

                    
// 显示进度条
                    progressForm
= new Form2();
                    progressForm.Show();

                    
// 创建工作者线程,并向工作者线程传递要转换的文本
                    WorkerThread myThreadFun
= new WorkerThread(
this.cmbVoices.SelectedIndex, arrText, strWAVFile);
                    
// 注册线程事件
                    myThreadFun.threadStartEvent
+= new EventHandler(method_threadStartEvent);
                    myThreadFun.threadEvent
+= new EventHandler(method_threadEvent);
                    myThreadFun.threadEndEvent
+= new EventHandler(method_threadEndEvent);
                    
// 创建线程,执行工作者线程
                    Thread thread
= new Thread(new ThreadStart(myThreadFun.runMethod));
                    
// 启动线程
                    thread.Start();
                }
            }
            catch
            {
            }
        }

  除了创建线程进行文本的转换之外,为了让我们的软件更加易用,更加人性化,我们还需要响应线程事件,移动进度条的位置以反映转换的进度,免得用户以为软件在比较长的转换过程中死掉了。

// 线程开始的时候调用的委托
        
private delegate void maxValueDelegate(int maxValue);
        
// 线程执行中调用的委托
        
private delegate void nowValueDelegate(int nowValue);
        
// 线程结束的时候调用的委托
        
private delegate void hideProgressDelegate(int n);
        
        
/// 线程完成事件,隐藏进度条窗口
      
/// 但是我们不能直接操作进度条,需要一个委托来替我们完成
        void method_threadEndEvent(
object sender, EventArgs e)
        {
            hideProgressDelegate hide
= new hideProgressDelegate(hideProgress);
            this.Invoke(hide,
0);
        }

        
/// 线程执行中的事件,设置进度条当前进度
        
/// 这里的sender,是WorkerThread 函数中传过来的当前值
        void method_threadEvent(
object sender, EventArgs e)
        {
            
int nowValue = Convert.ToInt32(sender);
            nowValueDelegate
now = new nowValueDelegate(setNow);
            this.Invoke(
now, nowValue);
        }
        
        
/// 线程开始事件,设置进度条最大值
        
/// 但是我不能直接操作进度条,需要一个委托来替我完成
        
///  这里的sender,是WorkerThread 函数中传过来的最大值
        void method_threadStartEvent(
object sender, EventArgs e)
        {
            
int maxValue = Convert.ToInt32(sender);
            maxValueDelegate max
= new maxValueDelegate(setMax);
            this.Invoke(max, maxValue);
        }

        
///  被委托调用的函数,专门操作进度条
        
private void setMax(int maxValue)
        {
            progressForm.progressBar1.Maximum
= maxValue;
        }
        
private void setNow(int nowValue)
        {
            progressForm.progressBar1.Value
= nowValue;
        }
        
private void hideProgress(int n)
        {
            progressForm.Hide();
        }
0
相关文章