首頁 > 軟體

C#使用DirectX.DirectSound播放語音

2022-03-27 13:00:07

最近在做專案時,需要進行音訊檔的即時播放,並且要求同時播放多條語音,之前C#程式中語音播放一直使用System.Media類庫的SoundPlayer類進行播放,但是這個播放類有個弊端,就是在播放時不能搶佔式播放語音,經過查詢資料DirectX.DirectSound可同時播放多條語音。

DirectX.DirectSound的特點

1、可同時播放多條語音

2、可分左右聲道進行播放

3、可隨時釋放正在播放的語音

此元件處理流程:

1、建立播放執行緒

public void StartDirectXSoundThread(Control _con)
 {
    IsStart = true;
    if (control == null) control = _con;
    Task task = new Task(() =>
      {
         while (true)
            {
               try
              {
                if (!IsStart) break;
                if (!IsPlaying())
                  {
                     if (soundlist.Count > 0)
                      {
                        if (!IsPlayVoice)
                         {
                           IsPlayVoice = true;
                           control.Invoke((MethodInvoker)delegate
                               {
                                SoundPlay(soundlist[0]);
                                soundlist.RemoveAt(0);
                                });
                         }
                        }
                   }
          }
       catch (Exception ex)
         {
           LogHelper.Debug(ex);
         }
           finally
         {
          }
          Thread.Sleep(100);
         }
     });
 task.Start();
}

2、釋放播放執行緒

public void StopDirectXSoundThread()
{
  IsStart = false;
 }

3、判斷是否播放中,通過PlayPosition!=0和播放緩衝是否null的條件判斷是否播放

private bool IsPlaying()
  {
     bool Ret = false;
       try
         {
           if (IsCreate)
            {
                    if (secBuffer != null)
                    {
                        if (secBuffer.PlayPosition != 0)
                        {
                            Ret = true;
                        }
                    }
                }
            }
       catch (Exception ex)
       {
            LogHelper.Debug(ex);
        }
      return Ret;
}

4、播放音訊

public void SoundPlay(string _wavpath)
        {
            try
            {
                if (_wavpath.IndexOf("\") < 0)
                {
                    _wavpath = SoundPath + _wavpath;
                }
                if (_wavpath.IndexOf(".wav") < 0)
                {
                    _wavpath += ".wav";
                }
                if (!File.Exists(_wavpath))
                {
                    LogHelper.Info("無" + _wavpath + "檔案!");
                }
                else
                {
                    secDev.SetCooperativeLevel(control, CooperativeLevel.Normal);
                    BufferDescription buffdes = new BufferDescription()
                    {
                        GlobalFocus = true
                    };
                    secBuffer = new SecondaryBuffer(_wavpath, buffdes, secDev);
                    secBuffer.Play(0, BufferPlayFlags.Default);//設定緩衝區為預設播放 
                }
                IsCreate = true;
                IsPlayVoice = false;
            }
            catch (Exception ex)
            {
                LogHelper.Debug(ex);
     }
}

左右聲道通過secBuffer.Pan屬性進行控制,值含義見下圖:

a、Center中心通道,左右通道同時播放,預設值0

b、Right右通道,值10000

c、Right左通道,值-10000

5、清除播放中音訊 ,播放中的音訊可以通過Dispose()方法進行釋放

public void ClearPlay()
  {
  if (secBuffer != null)
   {
    soundlist.Clear();
    secBuffer.Dispose();
    IsCreate = false;
     }
}

6、定義

/// <summary>
/// 播放裝置
/// </summary>
private Device secDev = new Device();
 
/// <summary>
/// 播放緩衝區
/// </summary>
private SecondaryBuffer secBuffer = null;
 
/// <summary>
/// 視覺化元件
/// </summary>
private Control control;
 
/// <summary>
/// 是否被建立
/// </summary>
private bool IsCreate = false;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com