C#使用DirectX.DirectSound播放语音

作者:程序猿evint 时间:2022-08-28 01:22:33 

最近在做项目时,需要进行音频文件的即时播放,并且要求同时播放多条语音,之前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

C#使用DirectX.DirectSound播放语音

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;

来源:https://blog.csdn.net/evint888/article/details/122387024

标签:C#,DirectX.DirectSound,播放语音
0
投稿

猜你喜欢

  • Android Camera2采集摄像头原始数据

    2021-06-23 22:55:53
  • C#实现简单屏幕监控的方法

    2023-07-31 10:29:25
  • OpenCV和C++实现图像的翻转(镜像)、平移、旋转、仿射与透视变换

    2023-07-14 23:47:22
  • 你是不是这样写异常处理代码的呢?

    2022-08-08 02:10:10
  • Java实现数组转字符串及字符串转数组的方法分析

    2022-04-14 10:53:44
  • C#利用性能计数器监控网络状态

    2022-01-05 00:13:53
  • Java设计模式中组合模式应用详解

    2022-08-01 01:51:53
  • Android布局之绝对布局AbsoluteLayout详解

    2023-07-26 07:44:27
  • SpringMVC上传图片与访问

    2023-12-06 17:54:31
  • 深入Unix时间戳与C# DateTime时间类型互换的详解

    2023-06-04 21:48:11
  • golang实现java uuid的序列化方法

    2022-12-30 11:30:57
  • Java构建JDBC应用程序的实例操作

    2023-08-07 12:09:13
  • Android批量插入数据到SQLite数据库的方法

    2022-09-28 06:18:06
  • Taro打包Android apk过程详解

    2022-01-31 02:55:27
  • Android HandlerThread案例详解

    2022-04-20 09:46:25
  • Java中的zookeeper常用命令详解

    2022-12-07 05:46:35
  • java设计模式(实战)-责任链模式

    2022-12-24 23:07:53
  • Android开发之使用ExifInterface获取拍照后的图片属性

    2021-05-29 23:36:36
  • Spring boot配置 swagger的示例代码

    2023-03-07 13:10:44
  • Android Fragment动态创建详解及示例代码

    2023-04-26 00:25:33
  • asp之家 软件编程 m.aspxhome.com