闪亮星空

仰望的孩子

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WaveLib
{
    /// 
    /// 音量控制
    /// 
    public class AudioMixerHelper : object
    {
        #region API及常量声明
        [DllImport("winmm.dll")]
        private static extern uint sndPlaySound(string lpszSoundName, Int64 uSndMode);

        private const long SND_SYNC = 0;
        private const long SND_ASYNC = 1;
        private const long SND_LOOP = 8;
        private const long SND_STOP = 4;

        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern uint mixerGetNumDevs();


        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerGetDevCaps(uint uMxId, ref MIXERCAPS pmxcaps, uint cbmxcaps);

        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerOpen(ref uint phmx, uint uMxId, uint dwCallback, uint dwInstance, ObjectFlag fdwOpen);
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerClose(uint hmx);

        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerGetLineInfo(uint hmxobj, ref MIXERLINE pmxl, GetLineInfoFlag fdwInfo);

        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerGetLineControls(uint hmxobj, ref MIXERLINECONTROLS pmxlc, GetLineControlsFlag fdwControls);

        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerGetControlDetails(uint hmxobj, ref MIXERCONTROLDETAILS pmxcd, GetControlDetailsFlag fdwDetails);
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
        private static extern MMSYSERR mixerSetControlDetails(uint hmxobj, ref MIXERCONTROLDETAILS pmxcd, SetControlDetailsFlag fdwDetails);

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(ref byte Struct, uint ptr, uint cb);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(ref MIXERCONTROL Struct, uint ptr, uint cb);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(ref MIXERCONTROLDETAILS_LISTTEXT Struct, uint ptr, uint cb);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(ref MIXERCONTROLDETAILS_UNSIGNED Struct, uint ptr, uint cb);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(uint ptr, ref MIXERCONTROLDETAILS_LISTTEXT Struct, uint cb);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern void RtlMoveMemory(uint ptr, ref MIXERCONTROLDETAILS_UNSIGNED Struct, uint cb);

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern uint GlobalAlloc(uint wFlags, uint dwBytes);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern uint GlobalLock(uint hmem);
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        private static extern uint GlobalFree(uint hmem);


        private const int MAXPNAMELEN = 32;
        private const int MIXER_LONG_NAME_CHARS = 64;
        private const int MIXER_SHORT_NAME_CHARS = 16;
        private enum MMSYSERR : uint
        {
            NOERROR = 0x0,
            ERROR = (NOERROR + 1),
            BADDEVICEID = (NOERROR + 2),
            NOTENABLED = (NOERROR + 3),
            ALLOCATED = (NOERROR + 4),
            INVALHANDLE = (NOERROR + 5),
            NODRIVER = (NOERROR + 6),
            NOMEM = (NOERROR + 7),
            NOTSUPPORTED = (NOERROR + 8),
            BADERRNUM = (NOERROR + 9),
            INVALFLAG = (NOERROR + 10),
            INVALPARAM = (NOERROR + 11),
            HANDLEBUSY = (NOERROR + 12),
            INVALIDALIAS = (NOERROR + 13),
            BADDB = (NOERROR + 14),
            KEYNOTFOUND = (NOERROR + 15),
            READERROR = (NOERROR + 16),
            WRITEERROR = (NOERROR + 17),
            DELETEERROR = (NOERROR + 18),
            VALNOTFOUND = (NOERROR + 19),
            NODRIVERCB = (NOERROR + 20)

        };
        public enum Mid : short
        {
            MM_MICROSOFT = 1,
            MM_CREATIVE = 2,
            MM_MEDIAVISION = 3,
            MM_FUJITSU = 4,
            MM_ARTISOFT = 20,
            MM_TURTLE_BEACH = 21,
            MM_IBM = 22,
            MM_VOCALTEC = 23,
            MM_ROLAND = 24,
            MM_DSP_SOLUTIONS = 25,
            MM_NEC = 26,
            MM_ATI = 27,
            MM_WANGLABS = 28,
            MM_TANDY = 29,
            MM_VOYETRA = 30,
            MM_ANTEX = 31,
            MM_ICL_PS = 32,
            MM_INTEL = 33,
            MM_GRAVIS = 34,
            MM_VAL = 35,
            MM_INTERACTIVE = 36,
            MM_YAMAHA = 37,
            MM_EVEREX = 38,
            MM_ECHO = 39,
            MM_SIERRA = 40,
            MM_CAT = 41,
            MM_APPS = 42,
            MM_DSP_GROUP = 43,
            MM_MELABS = 44,
            MM_COMPUTER_FRIENDS = 45,
            MM_ESS = 46,
            MM_AUDIOFILE = 47,
            MM_MOTOROLA = 48,
            MM_CANOPUS = 49,
            MM_EPSON = 50,
            MM_TRUEVISION = 51,
            MM_AZTECH = 52,
            MM_VIDEOLOGIC = 53,
            MM_SCALACS = 54,
            MM_KORG = 55,
            MM_APT = 56,
            MM_ICS = 57,
            MM_ITERATEDSYS = 58,
            MM_METHEUS = 59,
            MM_LOGITECH = 60,
            MM_WINNOV = 61,
            MM_NCR = 62,
            MM_EXAN = 63,
            MM_AST = 64,
            MM_WILLOWPOND = 65,
            MM_SONICFOUNDRY = 66,
            MM_VITEC = 67,
            MM_MOSCOM = 68,
            MM_SILICONSOFT = 69,
            MM_SUPERMAC = 73,
            MM_AUDIOPT = 74,
            MM_SPEECHCOMP = 76,
            MM_DOLBY = 78,
            MM_OKI = 79,
            MM_AURAVISION = 80,
            MM_OLIVETTI = 81,
            MM_IOMAGIC = 82,
            MM_MATSUSHITA = 83,
            MM_CONTROLRES = 84,
            MM_XEBEC = 85,
            MM_NEWMEDIA = 86,
            MM_NMS = 87,
            MM_LYRRUS = 88,
            MM_COMPUSIC = 89,
            MM_OPTI = 90,
            MM_DIALOGIC = 93
        }
        public enum GetLineInfoFlag : uint
        {
            DESTINATION = 0x0,
            SOURCE = 0x1,
            LINEID = 0x2,
            COMPONENTTYPE = 0x3,
            TARGETTYPE = 0x4,
            QUERYMASK = 0xF,
        }
        public enum ObjectFlag : uint
        {
            MIXER = 0x00000000,
            WAVEOUT = 0x10000000,
            WAVEIN = 0x20000000,
            MIDIOUT = 0x30000000,
            MIDIIN = 0x40000000,
            AUX = 0x50000000,
            HANDLE = 0x80000000,
            HMIDIIN = (HANDLE | MIDIIN),
            HMIDIOUT = (HANDLE | MIDIOUT),
            HMIXER = (HANDLE | MIXER),
            HWAVEIN = (HANDLE | WAVEIN),
            HWAVEOUT = (HANDLE | WAVEOUT)
        }
        public enum LineFlag : uint
        {
            ACTIVE = 0x00000001,
            DISCONNECTED = 0x00008000,
            SOURCE = 0x80000000,
        }
        public enum ComponentType : uint
        {
            DST_UNDEFINED = 0x0000,
            DST_DIGITAL = (DST_UNDEFINED + 1),
            DST_LINE = (DST_UNDEFINED + 2),
            DST_MONITOR = (DST_UNDEFINED + 3),
            DST_SPEAKERS = (DST_UNDEFINED + 4),
            DST_HEADPHONES = (DST_UNDEFINED + 5),
            DST_TELEPHONE = (DST_UNDEFINED + 6),
            DST_WAVEIN = (DST_UNDEFINED + 7),
            DST_VOICEIN = (DST_UNDEFINED + 8),

            SRC_UNDEFINED = 0x1000,
            SRC_DIGITAL = (SRC_UNDEFINED + 1),
            SRC_LINE = (SRC_UNDEFINED + 2),
            SRC_MICROPHONE = (SRC_UNDEFINED + 3),
            SRC_SYNTHESIZER = (SRC_UNDEFINED + 4),
            SRC_COMPACTDISC = (SRC_UNDEFINED + 5),
            SRC_TELEPHONE = (SRC_UNDEFINED + 6),
            SRC_PCSPEAKER = (SRC_UNDEFINED + 7),
            SRC_WAVEOUT = (SRC_UNDEFINED + 8),
            SRC_AUXILIARY = (SRC_UNDEFINED + 9),
            SRC_ANALOG = (SRC_UNDEFINED + 10),

        }
        public enum TargetType : uint
        {
            UNDEFINED = 0x0,
            WAVEOUT = 0x1,
            WAVEIN = 0x2,
            MIDIOUT = 0x3,
            MIDIIN = 0x4,
            AUX = 0x5,
        }
        public enum ControlType_Units : uint
        {
            CUSTOM = 0x000000,
            BOOLEAN = 0x010000,
            SIGNED = 0x020000,
            UNSIGNED = 0x030000,
            DECIBELS = 0x040000,
            PERCENT = 0x050000,
            MASK = 0xFF0000,
        }
        public enum ControlType_SubClass : uint
        {
            LIST_SINGLE = 0x0000000,
            METER_POLLED = 0x0000000,
            SWITCH_BOOLEAN = 0x0000000,
            TIME_MICROSECS = 0x0000000,
            LIST_MULTIPLE = 0x1000000,
            SWITCH_BUTTON = 0x1000000,
            TIME_MILLISECS = 0x1000000,
            MASK = 0xF000000,
        }
        public enum ControlType_Class : uint
        {
            CUSTOM = 0x00000000,
            METER = 0x10000000,
            SWITCH = 0x20000000,
            NUMBER = 0x30000000,
            SLIDER = 0x40000000,
            FADER = 0x50000000,
            TIME = 0x60000000,
            LIST = 0x70000000,
            MASK = 0xF0000000,
        }
        public enum ControlType : uint
        {
            CUSTOM = (ControlType_Class.CUSTOM | ControlType_Units.CUSTOM),
            BOOLEANMETER = (ControlType_Class.METER | ControlType_SubClass.METER_POLLED | ControlType_Units.BOOLEAN),
            SIGNEDMETER = (ControlType_Class.METER | ControlType_SubClass.METER_POLLED | ControlType_Units.SIGNED),
            PEAKMETER = (SIGNEDMETER + 1),
            UNSIGNEDMETER = (ControlType_Class.METER | ControlType_SubClass.METER_POLLED | ControlType_Units.UNSIGNED),
            BUTTON = (ControlType_Class.SWITCH | ControlType_SubClass.SWITCH_BUTTON | ControlType_Units.BOOLEAN),
            BOOLEAN = (ControlType_Class.SWITCH | ControlType_SubClass.SWITCH_BOOLEAN | ControlType_Units.BOOLEAN),
            ONOFF = (BOOLEAN + 1),
            MUTE = (BOOLEAN + 2),
            MONO = (BOOLEAN + 3),
            LOUDNESS = (BOOLEAN + 4),
            STEREOENH = (BOOLEAN + 5),
            PERCENT = (ControlType_Class.NUMBER | ControlType_Units.PERCENT),
            SIGNED = (ControlType_Class.NUMBER | ControlType_Units.SIGNED),
            UNSIGNED = (ControlType_Class.NUMBER | ControlType_Units.UNSIGNED),
            DECIBELS = (ControlType_Class.NUMBER | ControlType_Units.DECIBELS),
            SLIDER = (ControlType_Class.SLIDER | ControlType_Units.SIGNED),
            PAN = (SLIDER + 1),
            QSOUNDPAN = (SLIDER + 2),
            FADER = (ControlType_Class.FADER | ControlType_Units.UNSIGNED),
            VOLUME = (FADER + 1),
            BASS = (FADER + 2),
            TREBLE = (FADER + 3),
            EQUALIZER = (FADER + 4),
            MICROTIME = (ControlType_Class.TIME | ControlType_SubClass.TIME_MICROSECS | ControlType_Units.UNSIGNED),
            MILLITIME = (ControlType_Class.TIME | ControlType_SubClass.TIME_MILLISECS | ControlType_Units.UNSIGNED),
            SINGLESELECT = (ControlType_Class.LIST | ControlType_SubClass.LIST_SINGLE | ControlType_Units.BOOLEAN),
            MUX = (SINGLESELECT + 1),
            MULTIPLESELECT = (ControlType_Class.LIST | ControlType_SubClass.LIST_MULTIPLE | ControlType_Units.BOOLEAN),
            MIXER = (MULTIPLESELECT + 1),

        }
        public enum GetLineControlsFlag : uint
        {
            ALL = 0x0,
            ONEBYID = 0x1,
            ONEBYTYPE = 0x2,
            QUERYMASK = 0xF,
        }
        public enum GetControlDetailsFlag : uint
        {
            VALUE = 0x0,
            LISTTEXT = 0x1,
            QUERYMASK = 0xF,
        }
        public enum SetControlDetailsFlag : uint
        {
            VALUE = 0x0,
            CUSTOM = 0x1,
            QUERYMASK = 0xF,

        }


        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERCAPS
        {
            public Mid wMid;
            public short wPid;
            public int vDriverVersion;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
            public string szPname;
            public uint fdwSupport;
            public uint cDestinations;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERLINE
        {
            public uint cbStruct;
            public uint dwDestination;
            public uint dwSource;
            public uint dwLineID;
            public uint fdwLine;
            public uint dwUser;
            public ComponentType dwComponentType;
            public uint cChannels;
            public uint cConnections;
            public uint cControls;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)]
            public string szShortName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)]
            public string szName;
            public TargetType dwType;
            public uint dwDeviceID;
            public Mid wMid;
            public short wPid;
            public uint vDriverVersion;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
            public string szPname;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERLINECONTROLS
        {
            public uint cbStruct;
            public uint dwLineID;

            public uint dwControl;
            public uint cControls;
            public uint cbmxctrl;
            public uint pamxctrl;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERCONTROL
        {
            public uint cbStruct;
            public uint dwControlID;
            public ControlType dwControlType;
            public uint fdwControl;
            public uint cMultipleItems;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)]
            public string szShortName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)]
            public string szName;
            public uint dwMinimum;
            public uint dwMaximum;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public uint[] dwReserved;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERCONTROLDETAILS
        {
            public uint cbStruct;
            public uint dwControlID;
            public uint cChannels;
            public uint item;
            public uint cbDetails;
            public uint paDetails;
        }


        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERCONTROLDETAILS_LISTTEXT
        {
            public uint dwParam1;
            public uint dwParam2;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)]
            public string szName;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MIXERCONTROLDETAILS_UNSIGNED
        {
            public uint dwValue;
        }


        private uint StructLen(object Structure)
        {
            return Convert.ToUInt32(Marshal.SizeOf(Structure));
        }


        private string MMSYSERR_ToString(MMSYSERR ERR)
        {
            switch (ERR)
            {
                case MMSYSERR.NOERROR:
                    return "No error.";
                case MMSYSERR.BADDEVICEID:
                    return "Invalid device identifier.";
                case MMSYSERR.NOTENABLED:
                    return "The driver is not enabled.";
                case MMSYSERR.ALLOCATED:
                    return "Device is opened by the maximum number of clients.";
                case MMSYSERR.INVALHANDLE:
                    return "Invalid handle.";
                case MMSYSERR.NODRIVER:
                    return "No mixer device is available.";
                case MMSYSERR.NOMEM:
                    return "The system is unable to allocate resources.";
                case MMSYSERR.NOTSUPPORTED:
                    return "The ACM driver did not process the message..";
                case MMSYSERR.BADERRNUM:
                    return "The specified error number is out of range.";
                case MMSYSERR.INVALFLAG:
                    return "One or more flags are invalid.";
                case MMSYSERR.INVALPARAM:
                    return "One or more parameters are invalid.";
                case MMSYSERR.HANDLEBUSY:
                    return "Handle busy.";
                case MMSYSERR.INVALIDALIAS:
                    return "Invalid Alias.";
                case MMSYSERR.READERROR:
                    return "Read error.";
                case MMSYSERR.WRITEERROR:
                    return "Write error.";
                case MMSYSERR.DELETEERROR:
                    return "Delete error.";
                default:
                    return "Undifined error code.";
            }
        }


        public string Mid_ToString(Mid wMid)
        {
            switch (wMid)
            {
                case Mid.MM_MICROSOFT:
                    return "Microsoft Corporation";
                case Mid.MM_CREATIVE:
                    return "Creative Labs, Inc.";
                case Mid.MM_MEDIAVISION:
                    return "Media Vision, Inc.";
                case Mid.MM_FUJITSU:
                    return "Fujitsu, Ltd.";
                case Mid.MM_ARTISOFT:
                    return "Artisoft, Inc.";
                case Mid.MM_TURTLE_BEACH:
                    return "Turtle Beach Systems";
                case Mid.MM_IBM:
                    return "International Business Machines";
                case Mid.MM_VOCALTEC:
                    return "VocalTec, Inc.";
                case Mid.MM_ROLAND:
                    return "Roland Corporation";
                case Mid.MM_DSP_SOLUTIONS:
                    return "DSP Solutions, Inc.";
                case Mid.MM_NEC:
                    return "NEC Corporation";
                case Mid.MM_ATI:
                    return "ATI Technologies, Inc.";
                case Mid.MM_WANGLABS:
                    return "Wang Laboratories";
                case Mid.MM_TANDY:
                    return "Tandy Corporation";
                case Mid.MM_VOYETRA:
                    return "Voyetra Technologies";
                case Mid.MM_ANTEX:
                    return "Antex Electronics Corporation";
                case Mid.MM_ICL_PS:
                    return "ICL Personal Systems";
                case Mid.MM_INTEL:
                    return "Intel Corporation";
                case Mid.MM_GRAVIS:
                    return "Advanced Gravis Computer Technology, Ltd.";
                case Mid.MM_VAL:
                    return "Video Associates Labs, Inc.";
                case Mid.MM_INTERACTIVE:
                    return "InterActive, Inc.";
                case Mid.MM_YAMAHA:
                    return "Yamaha Corporation of America";
                case Mid.MM_EVEREX:
                    return "Everex Systems, Inc.";
                case Mid.MM_ECHO:
                    return "Echo Speech Corporation";
                case Mid.MM_SIERRA:
                    return "Sierra Semiconductor Corporation";
                case Mid.MM_CAT:
                    return "Computer Aided Technology, Inc.";
                case Mid.MM_APPS:
                    return "APPS Software";
                case Mid.MM_DSP_GROUP:
                    return "DSP Group, Inc.";
                case Mid.MM_MELABS:
                    return "microEngineering Labs";
                case Mid.MM_COMPUTER_FRIENDS:
                    return "Computer Friends, Inc.";
                case Mid.MM_ESS:
                    return "ESS Technology, Inc.";
                case Mid.MM_AUDIOFILE:
                    return "Audio, Inc.";
                case Mid.MM_MOTOROLA:
                    return "Motorola, Inc.";
                case Mid.MM_CANOPUS:
                    return "Canopus, Co., Ltd.";
                case Mid.MM_EPSON:
                    return "Seiko Epson Corporation, Inc.";
                case Mid.MM_TRUEVISION:
                    return "Truevision, Inc.";
                case Mid.MM_AZTECH:
                    return "Aztech Labs, Inc.";
                case Mid.MM_VIDEOLOGIC:
                    return "VideoLogic, Inc.";
                case Mid.MM_SCALACS:
                    return "SCALACS";
                case Mid.MM_KORG:
                    return "Toshihiko Okuhura, Korg, Inc.";
                case Mid.MM_APT:
                    return "Audio Processing Technology";
                case Mid.MM_ICS:
                    return "Integrated Circuit Systems, Inc.";
                case Mid.MM_ITERATEDSYS:
                    return "Iterated Systems, Inc.";
                case Mid.MM_METHEUS:
                    return "Metheus Corporation";
                case Mid.MM_LOGITECH:
                    return "Logitech, Inc.";
                case Mid.MM_WINNOV:
                    return "Winnov, LP";
                case Mid.MM_NCR:
                    return "NCR Corporation";
                case Mid.MM_EXAN:
                    return "EXAN, Ltd.";
                case Mid.MM_AST:
                    return "AST Research, Inc.";
                case Mid.MM_WILLOWPOND:
                    return "Willow Pond Corporation";
                case Mid.MM_SONICFOUNDRY:
                    return "Sonic Foundry";
                case Mid.MM_VITEC:
                    return "Visual Information Technologies, Inc.";
                case Mid.MM_MOSCOM:
                    return "MOSCOM Corporation";
                case Mid.MM_SILICONSOFT:
                    return "Silicon Software, Inc.";
                case Mid.MM_SUPERMAC:
                    return "Supermac Technology, Inc.";
                case Mid.MM_AUDIOPT:
                    return "Audio Processing Technology";
                case Mid.MM_SPEECHCOMP:
                    return "Speech Compression";
                case Mid.MM_DOLBY:
                    return "Dolby Laboratories, Inc.";
                case Mid.MM_OKI:
                    return "OKI";
                case Mid.MM_AURAVISION:
                    return "Auravision Corporation";
                case Mid.MM_OLIVETTI:
                    return "Ing. C. Olivetti & C., S.p.A.";
                case Mid.MM_IOMAGIC:
                    return "I/O Magic Corporation";
                case Mid.MM_MATSUSHITA:
                    return "Matsushita Electric Corporation of America";
                case Mid.MM_CONTROLRES:
                    return "Control Resources Corporation";
                case Mid.MM_XEBEC:
                    return "Xebec Multimedia Solutions Limited";
                case Mid.MM_NEWMEDIA:
                    return "New Media Corporation";
                case Mid.MM_NMS:
                    return "Natural MicroSystems Corporation";
                case Mid.MM_LYRRUS:
                    return "Lyrrus, Inc.";
                case Mid.MM_COMPUSIC:
                    return "Compusic";
                case Mid.MM_OPTI:
                    return "OPTi, Inc.";
                case Mid.MM_DIALOGIC:
                    return "Dialogic Corporation";
                default:
                    return "Unknow";
            }
        }

        #endregion

        private byte Prev_Speaker_Vol = 0;
        private bool Prev_Speaker_Mute = false;
        private byte Prev_WaveOut_Vol = 0;
        private bool Prev_WaveOut_Mute = false;

        public void Play(string FileName, byte Vol)
        {
            try
            {
                GetVolume(ComponentType.DST_SPEAKERS, ref Prev_Speaker_Vol, ref Prev_Speaker_Mute);
                GetVolume(ComponentType.SRC_WAVEOUT, ref Prev_WaveOut_Vol, ref Prev_WaveOut_Mute);
                SetVolume(ComponentType.DST_SPEAKERS, Vol, false);
                SetVolume(ComponentType.SRC_WAVEOUT, Vol, false);

                long Result = sndPlaySound(FileName, SND_ASYNC);
            }
            catch (Exception exp)
            {

            }
        }

        /// 
        /// 设置静音
        /// 
        /// 
        public void SetMute(bool bMute)
        {
            byte vol = 0;
            bool bPrev = false;
            try
            {
                GetVolume(ComponentType.SRC_MICROPHONE, ref vol, ref bPrev);

                SetVolume(ComponentType.SRC_MICROPHONE, vol, bMute);
            }
            catch (Exception exp)
            {

            }

        }
        /// 
        /// 判断是否静音
        /// 
        /// 
        public bool GetMute()
        {
            byte vol = 0;
            bool bPrev = false;
            try
            {
                GetVolume(ComponentType.DST_SPEAKERS, ref vol, ref bPrev);
            }
            catch (Exception exp)
            {

            }
            if (bPrev)
                return true;
            else
                return false;
        }
        /// 
        /// 提取当前音量
        /// 
        /// 
        public int GetSound()
        {
            byte vol = 0;
            bool bPrev = false;
            try
            {
                GetVolume(ComponentType.DST_SPEAKERS, ref vol, ref bPrev);
            }
            catch (Exception exp)
            {

            }
            return vol;
        }
        /// 
        /// 设置音量
        /// 
        /// 
        public void SetSound(int volume)
        {
            try
            {
                byte vol = 0;
                bool bPrev = false;
                GetVolume(ComponentType.DST_SPEAKERS, ref vol, ref bPrev);
                SetVolume(ComponentType.DST_SPEAKERS, (byte)(vol + volume), bPrev);
            }
            catch (Exception exp)
            {

            }
        }

        public void PlayLoop(string FileName, byte Vol)
        {

            GetVolume(ComponentType.DST_SPEAKERS, ref Prev_Speaker_Vol, ref Prev_Speaker_Mute);
            GetVolume(ComponentType.SRC_WAVEOUT, ref Prev_WaveOut_Vol, ref Prev_WaveOut_Mute);
            SetVolume(ComponentType.DST_SPEAKERS, Vol, false);
            SetVolume(ComponentType.SRC_WAVEOUT, Vol, false);

            long Result = sndPlaySound(FileName, SND_ASYNC | SND_LOOP);
        }

        public void StopPlay()
        {
            long Result = sndPlaySound("", SND_STOP);
            SetVolume(ComponentType.DST_SPEAKERS, Prev_Speaker_Vol, Prev_Speaker_Mute);
            SetVolume(ComponentType.SRC_WAVEOUT, Prev_WaveOut_Vol, Prev_WaveOut_Mute);
        }

        private bool GetVolume(ComponentType Source, ref byte Volume, ref bool Mute)
        {
            uint hmixer = 0;

            bool bGetVolume = false;
            MMSYSERR Rc;

            if (mixerGetNumDevs() < 1)
            {
                MessageBox.Show("No Sound card!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                bGetVolume = false;
            }
            else
            {
                Rc = mixerOpen(ref hmixer, 0, 0, 0, 0);
                if (MMSYSERR.NOERROR != Rc)
                {
                    MessageBox.Show("MixerOpen Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                    bGetVolume = false;
                }
                else
                {
                    bGetVolume = true;
                    long Value;

                    Value = GetControlDetails(hmixer, Source, ControlType.VOLUME);
                    if (Value > -1)
                        Volume = Convert.ToByte(Value);
                    else
                        bGetVolume = false;

                    Value = GetControlDetails(hmixer, Source, ControlType.MUTE);
                    if (Value > -1)
                        Mute = Value != 0;
                    else
                        bGetVolume = false;

                }
                Rc = mixerClose(hmixer);
            }
            return bGetVolume;

        }

        private long GetControlDetails(uint hmixer, ComponentType componentType, ControlType ctrlType)
        {
            uint hmem;
            MMSYSERR Rc;
            MIXERCONTROL mxc = new MIXERCONTROL();
            MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS();
            MIXERLINE mxl = new MIXERLINE();
            MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
            MIXERCONTROLDETAILS_UNSIGNED mxcdu = new MIXERCONTROLDETAILS_UNSIGNED();

            mxl.cbStruct = StructLen(mxl);
            mxl.dwComponentType = componentType;

            Rc = mixerGetLineInfo(hmixer, ref mxl, GetLineInfoFlag.COMPONENTTYPE);
            if (MMSYSERR.NOERROR == Rc)
            {
                mxlc.cbStruct = StructLen(mxlc);
                mxlc.dwLineID = mxl.dwLineID;
                mxlc.dwControl = Convert.ToUInt32(ctrlType);
                mxlc.cControls = mxl.cControls;
                mxlc.cbmxctrl = StructLen(mxc);

                hmem = GlobalAlloc(64, StructLen(mxc));
                mxlc.pamxctrl = GlobalLock(hmem);
                mxc.cbStruct = StructLen(mxc);

                Rc = mixerGetLineControls(hmixer, ref mxlc, GetLineControlsFlag.ONEBYTYPE);
                if (MMSYSERR.NOERROR == Rc)
                {
                    RtlMoveMemory(ref mxc, mxlc.pamxctrl, StructLen(mxc));
                    GlobalFree(hmem);

                    mxcd.item = 0;
                    mxcd.dwControlID = mxc.dwControlID;
                    mxcd.cbStruct = StructLen(mxcd);
                    mxcd.cChannels = 1;

                    hmem = GlobalAlloc(64, StructLen(mxcdu));
                    mxcd.cbDetails = StructLen(mxcdu);
                    mxcd.paDetails = GlobalLock(hmem);
                    Rc = mixerGetControlDetails(hmixer, ref mxcd, GetControlDetailsFlag.VALUE);
                    if (Rc == MMSYSERR.NOERROR)
                    {
                        RtlMoveMemory(ref mxcdu, mxcd.paDetails, StructLen(mxcdu));
                        GlobalFree(hmem);
                        return 100 * (mxcdu.dwValue - mxc.dwMinimum) / (mxc.dwMaximum - mxc.dwMinimum);
                    }
                    else
                    {
                        GlobalFree(hmem);
                        MessageBox.Show("mixerGetControlDetails Failed!!", "Error!!!", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                        return -1;
                    }
                }
                else
                {
                    MessageBox.Show("mixerGetLineControls Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                    GlobalFree(hmem);
                    return -1;
                }
            }
            else
            {
                MessageBox.Show("mixerGetLineInfo Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                return -1;
            }
        }

        private bool SetVolume(ComponentType Source, byte Volume, bool Mute)
        {
            uint hmixer = 0;

            bool bSetVolume = false;
            MIXERCONTROL mxc = new MIXERCONTROL();
            MMSYSERR Rc;

            if (mixerGetNumDevs() < 1)
            {
                MessageBox.Show("No Sound card!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                bSetVolume = false;
            }
            else
            {
                Rc = mixerOpen(ref hmixer, 0, 0, 0, 0);
                if (MMSYSERR.NOERROR != Rc)
                {
                    MessageBox.Show("MixerOpen Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                    bSetVolume = false;
                }
                else
                {
                    bSetVolume = true;
                    bSetVolume = bSetVolume | SetControlDetails(hmixer, Source, ControlType.VOLUME, Volume);

                    if (Mute == true)
                        bSetVolume = bSetVolume | SetControlDetails(hmixer, Source, ControlType.MUTE, 100);
                    else
                        bSetVolume = bSetVolume | SetControlDetails(hmixer, Source, ControlType.MUTE, 0);

                }
                Rc = mixerClose(hmixer);
            }
            return bSetVolume;

        }


        private bool SetControlDetails(uint hmixer, ComponentType componentType, ControlType ctrlType, byte Value)
        {
            uint hmem;
            MMSYSERR Rc;
            MIXERCONTROL mxc = new MIXERCONTROL();
            MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS();
            MIXERLINE mxl = new MIXERLINE();
            MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
            MIXERCONTROLDETAILS_UNSIGNED mxcdu = new MIXERCONTROLDETAILS_UNSIGNED();

            mxl.cbStruct = StructLen(mxl);
            mxl.dwComponentType = componentType;

            Rc = mixerGetLineInfo(hmixer, ref mxl, GetLineInfoFlag.COMPONENTTYPE);
            if (MMSYSERR.NOERROR == Rc)
            {
                mxlc.cbStruct = StructLen(mxlc);
                mxlc.dwLineID = mxl.dwLineID;
                mxlc.dwControl = Convert.ToUInt32(ctrlType);
                mxlc.cControls = mxl.cControls;
                mxlc.cbmxctrl = StructLen(mxc);

                hmem = GlobalAlloc(64, StructLen(mxc));
                mxlc.pamxctrl = GlobalLock(hmem);
                mxc.cbStruct = StructLen(mxc);

                Rc = mixerGetLineControls(hmixer, ref mxlc, GetLineControlsFlag.ONEBYTYPE);
                if (MMSYSERR.NOERROR == Rc)
                {
                    RtlMoveMemory(ref mxc, mxlc.pamxctrl, StructLen(mxc));
                    GlobalFree(hmem);

                    mxcd.item = 0;
                    mxcd.dwControlID = mxc.dwControlID;
                    mxcd.cbStruct = StructLen(mxcd);
                    mxcd.cbDetails = StructLen(mxcdu);

                    hmem = GlobalAlloc(64, StructLen(mxcdu));
                    mxcd.paDetails = GlobalLock(hmem);
                    mxcd.cChannels = 1;
                    mxcdu.dwValue = mxc.dwMinimum + Convert.ToUInt32(Value * (mxc.dwMaximum - mxc.dwMinimum) / 100);

                    RtlMoveMemory(mxcd.paDetails, ref mxcdu, StructLen(mxcdu));

                    Rc = mixerSetControlDetails(hmixer, ref mxcd, SetControlDetailsFlag.VALUE);
                    GlobalFree(hmem);
                    if (MMSYSERR.NOERROR == Rc)
                        return true;
                    else
                    {
                        MessageBox.Show("mixerSetControlDetails Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                        return false;
                    }
                }
                else
                {
                    MessageBox.Show("mixerGetLineControls Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                    return false;
                }
            }
            else
            {
                MessageBox.Show("mixerGetLineInfo Failed!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                return false;
            }
        }
    }

}

posted on 2009-07-10 15:20  超边缘  阅读(899)  评论(0编辑  收藏  举报