DXSound.cs 8.61 KB
///--------------------------------------------------------------------------
/// Copyright (C) 2010 长沙中天电子设计开发有限公司版权所有。 
///
/// 文 件 名:DXSound.cs
/// 功能描述:音效模块
/// 
/// 使用方法:
/// 用LoadSound()方法加载音效文件
/// 播放时调用Play()方法
/// 停止调用Stop()或StopAll()方法
/// 
/// 注意:写new DXSound()代码时,取消代码调试信息:Ctrl+Alt+E,修改Managed Debuggin Assistants->LoaderLock 的选中状态去掉
/// 
/// 创建标识:杨斌 2010-08-05
/// 修改:杨斌 2012-06-18 加入mp3格式
/// 
///--------------------------------------------------------------------------
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.PowerPoint;
using System.Collections.Specialized;
using GeneralLib;


namespace GeneralLib
{
    public class DXSound
    {
        private Microsoft.DirectX.DirectSound.Device dev;
        private OrderedDictionary sndKeys;

        /// <summary>
        /// 是否初始化成功
        /// </summary>
        private bool initOK = false;

        public bool InitOK
        {
            get { return initOK; }
        }

        /// <summary>
        /// 说明:构造函数
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="owner">使用声音设备的程序的控件或窗体</param>
        public DXSound()
        {
            sndKeys = new OrderedDictionary();
        }

        /// <summary>
        /// 说明:初始化音效
        /// 创建:杨斌 2010-09-08
        /// </summary>
        /// <param name="owner">所有者控件</param>
        /// <returns></returns>
        public bool InitSound(Control owner)
        {
            initOK = false;

            try
            {
                dev = new Microsoft.DirectX.DirectSound.Device();
                dev.SetCooperativeLevel(owner.Handle, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal);
                //dev.SetCooperativeLevel((IntPtr)0, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal);
                initOK = true;
            }
            catch (Exception ex)
            {
                SystemLog.WriterLog(ex, false);
            }

            return initOK;
        }

        /// <summary>
        /// 说明:析构函数
        /// 创建:杨斌 2010-07-31
        /// </summary>
        ~DXSound()
        {
            //this.StopAll();
            if (dev != null) dev.Dispose();//必须手动释放
        }

        /// <summary>
        /// 获取播放文件格式
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns>小写,如wav、mp3</returns>
        private string GetSoundFormat(string filePath)
        {
            string res = "";

            try
            {
                int i = filePath.LastIndexOf(".");

                if (i >= 0)
                    res = filePath.Substring(i + 1);
            }
            catch (Exception ex)
            {
                SystemLog.WriterLog(ex);
            }

            return res;
        }

        /// <summary>
        /// 说明:加载声音文件
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        /// <param name="filePath">文件路径</param>
        /// <param name="mixCount">混音个数</param>
        /// <returns>是否成功</returns>
        public bool LoadSound(string key, string filePath, int mixCount)
        {
            bool loadOK = false;
            try
            {
                OrderedDictionary sndBufs = new OrderedDictionary();
                sndKeys.Add(key, sndBufs);
                sndBufs.Add("0", 0);//用来保存当前播放的缓冲索引
                if (dev != null)//若声卡初始化失败,dev==null,添加缓冲字典会报错,杨斌 2012-03-07
                {
                    for (int i = 1; i <= mixCount; i++)
                    {
                        Microsoft.DirectX.DirectSound.SecondaryBuffer sndBuf = new Microsoft.DirectX.DirectSound.SecondaryBuffer(filePath, dev);
                        sndBufs.Add(i.ToString(), sndBuf);
                    }
                }
                loadOK = true;
            }
            catch (Exception ex)
            {
                SystemLog.WriterLog(ex);
            }
            return loadOK;
        }

        /// <summary>
        /// 移除声音
        /// </summary>
        /// <param name="key">声音键值</param>
        public void RemoveSound(string key)
        {
            if (!sndKeys.Contains(key)) return;

            OrderedDictionary sndBufs = (OrderedDictionary)sndKeys[key];

            for (int i = 1; i < sndBufs.Count; i++)
            {
                Microsoft.DirectX.DirectSound.SecondaryBuffer sndBuf;
                try
                {
                    sndBuf = (Microsoft.DirectX.DirectSound.SecondaryBuffer)sndBufs[i];
                    sndBuf.Stop();
                    sndBuf.Dispose();
                }
                catch (Exception ex)
                {
                    SystemLog.WriterLog(ex);
                }
                finally
                {
                    sndBuf = null;
                }
            }

            sndKeys.Remove(key);

            sndBufs = null;
        }


        /// <summary>
        /// 说明:加载声音文件
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        /// <param name="filePath">文件路径</param>
        /// <returns>是否成功</returns>
        public bool LoadSound(string key, string filePath)
        {
            return LoadSound(key, filePath, 1);
        }

        /// <summary>
        /// 说明:播放声音
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        /// <param name="isLoop">是否循环播放</param>
        private void PlaySond(string key, bool isLoop)
        {
            if (!sndKeys.Contains(key)) return;

            OrderedDictionary sndBufs = (OrderedDictionary)sndKeys[key];

            if (sndBufs.Count < 2) return;

            int i = (int)sndBufs[0] + 1;//当前播放的缓冲索引+1
            if (i > sndBufs.Count - 1) i = sndBufs.Count - 1;

            try
            {
                Microsoft.DirectX.DirectSound.SecondaryBuffer sndBuf = (Microsoft.DirectX.DirectSound.SecondaryBuffer)sndBufs[i];
                sndBuf.Stop();
                sndBuf.SetCurrentPosition(0);
                sndBuf.Play(0, isLoop ? Microsoft.DirectX.DirectSound.BufferPlayFlags.Looping : Microsoft.DirectX.DirectSound.BufferPlayFlags.Default);
            }
            catch (Exception ex)
            {
                SystemLog.WriterLog(ex, false);
            }
            finally
            {
                sndBufs[0] = i;
            }
        }

        /// <summary>
        /// 说明:播放声音
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        public void Play(string key)
        {
            PlaySond(key, false);
        }

        /// <summary>
        /// 说明:循环播放声音
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        public void PlayLoop(string key)
        {
            PlaySond(key, true);
        }

        /// <summary>
        /// 说明:停止声音
        /// 创建:杨斌 2010-07-31
        /// </summary>
        /// <param name="key">声音键值</param>
        public void Stop(string key)
        {
            if (!sndKeys.Contains(key)) return;

            OrderedDictionary sndBufs = (OrderedDictionary)sndKeys[key];

            for (int i = 1; i < sndBufs.Count; i++)
            {
                try
                {
                    Microsoft.DirectX.DirectSound.SecondaryBuffer sndBuf = (Microsoft.DirectX.DirectSound.SecondaryBuffer)sndBufs[i];
                    sndBuf.Stop();
                    sndBuf.SetCurrentPosition(0);
                }
                catch (Exception ex)
                {
                    SystemLog.WriterLog(ex, false);
                }
                finally
                {
                    sndBufs[0] = 0;//当前播放的缓冲索引清零
                }
            }
        }

        /// <summary>
        /// 说明:停止所有声音
        /// 创建:杨斌 2010-07-31
        /// </summary>
        public void StopAll()
        {
            foreach (string key in sndKeys.Keys)
            {
                Stop(key);
            }
        }

    }
}