⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundstudiofrm.cs

📁 Programing SoundStudioCS
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Ernzo.WinForms.Controls;
using Ernzo.Windows.WaveAudio;
using Ernzo.Windows.DirectShowLib.MMStreaming;
using Ernzo.DSP;
using SoundStudioCS.Properties;
namespace SoundStudioCS
{

    public partial class SoundStudioFrm : Form, IWaveNotifyHandler
    {
        private const int WM_USER = 0x0400;
        private const int WM_AUDIO_DONE = WM_USER + 0x100;
        private const int WM_MIXM_CONTROL_CHANGE = MixerConstants.MM_MIXM_CONTROL_CHANGE;
        private const int MAX_BUFFERS = 4;
        //private const int MAX_BUFSIZE = 2048;
        private const double FFT_SPEED = 0.06;
        private const int NUM_FREQUENCY = 19;
        private int[] METER_FREQUENCY = new int[NUM_FREQUENCY] { 30, 60, 80, 90, 100, 150, 200, 330, 480, 660, 880, 1000, 1500, 2000, 3000, 5000, 8000, 12000, 16000 };
        private int[] _meterData = new int[NUM_FREQUENCY];
        private double[] RealIn;
        private double[] RealOut;
        private double[] ImagOut;
        private double[] AmplOut;
        private byte[] waveData;    // copy of wave data - unless 'unsafe' code is an option
        private WaveFormat _wfmt;
        private WaveBuffer[] _waveBuffer;
        private WaveOutDevice _waveOutput;
        private IntPtr _CopyWindowHandle;
        private MMAudioStream _AudioStream;
        private MultimediaStream _MediaStream;
        private uint _bufferSize;
        private uint _numSamples;
        private int _numOutBuffers;
        private WaveMixerDevice _mixerDevice;
        private IntPtr _mixerDataPtr;
        private int _MuteControlId;
        private int _VolumeControlId;

        public SoundStudioFrm()
        {
            InitializeComponent();
            _numSamples = 0;
            _numOutBuffers = 0;
        }

        private void Terminate()
        {
            ReleaseWaveOutput();
            ReleaseFFTData();
            _CopyWindowHandle = IntPtr.Zero;
            this.btnPlay.Enabled = true;
            this.btnStop.Enabled = false;
            this.btnMute.Enabled = false;
            this.ctlVolume.Enabled = false;
        }
        private void SoundStudioFrm_Load(object sender, EventArgs e)
        {
            this.peakMeterCtrl1.SetRange(40, 70, 100);
            this.peakMeterCtrl1.Start(33);
            this.btnPlay.Enabled = true;
            this.btnStop.Enabled = false;
            this.btnMute.Enabled = false;
            this.ctlVolume.Enabled = false;
        }

        protected override void OnHandleDestroyed(EventArgs e)
        {
            Terminate();
            base.OnHandleDestroyed(e);
        }
        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                txtFilePath.Text = openDialog.FileName;
            }
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            if (_waveOutput == null)
            {
                CreateWaveOutput();
            }
            if (!_waveOutput.IsOpen())
            {
                _CopyWindowHandle = this.Handle;
                try
                {
                    // NOTE: Since our main thread belongs to a Single-thread apartment
                    // make sure this object is accessed from the same thread
                    // create multimedia stream object
                    IMediaStream pAudioStream = null;
                    _MediaStream = new MultimediaStream();
                    int mmr = _MediaStream.Initialize(STREAM_TYPE.STREAMTYPE_READ, (int)AMMSF_INIT.AMMSF_NOGRAPHTHREAD, null);
                    mmr = _MediaStream.AddMediaStream(null, MSPurposeId.PrimaryAudio, 0, out pAudioStream);
                    MSStatus.ThrowExceptionForHR(mmr);

                    // open media file
                    mmr = _MediaStream.OpenFile(this.txtFilePath.Text, (int)AMMSF_OPEN.AMMSF_RUN);
                    MSStatus.ThrowExceptionForHR(mmr);

                    _AudioStream = new MMAudioStream();
                    mmr = _AudioStream.SetMediaStream(pAudioStream);
                    MSStatus.ThrowExceptionForHR(mmr);

                    _wfmt = new WaveFormat(_AudioStream.Format);
                    mmr = _waveOutput.Open(WaveConstants.WAVE_MAPPER, _wfmt);
                    WaveOutStatus.ThrowExceptionForHR(mmr);

                    // calculate required buffer
                    _bufferSize = (uint)FFT.NextPowerOfTwo((uint)(_wfmt.BytesPerSecond * FFT_SPEED));
                    CreateBuffers();
                    AllocFFTData();
                    _numSamples = 0;
                    _numOutBuffers = 0;
                    for (int index = 0; index < MAX_BUFFERS; ++index)
                    {
                        WaveBuffer curBuffer = _waveBuffer[index];
                        int dwSize = curBuffer.BufferLength;
                        mmr = _AudioStream.GetSampleData(curBuffer.AudioData, ref dwSize, (int)COMPLETION_STATUS_FLAGS.COMPSTAT_WAIT, System.Threading.Timeout.Infinite);
                        MSStatus.ThrowExceptionForHR(mmr);
                        if (dwSize > 0)
                        {
                            mmr = _waveOutput.PrepareBuffer(curBuffer);
                            mmr = _waveOutput.AddBuffer(curBuffer);
                            WaveOutStatus.ThrowExceptionForHR(mmr);
                            Interlocked.Increment(ref _numOutBuffers);
                            if (index == 0)
                            {
                                mmr = _waveOutput.Start();
                                WaveOutStatus.ThrowExceptionForHR(mmr);
                            }
                        }
                    }
                    // setup mixer
                    CreateMixerDevice();
                    mmr = SetupMixer();
                    WaveOutStatus.ThrowExceptionForHR(mmr);
                    btnPlay.Enabled = false;
                    btnStop.Enabled = true;
                    btnMute.Enabled = true;
                    ctlVolume.Enabled = true;
                }
                catch (Exception ex) // typically: COMException, SystemException (waveout)
                {
                    DumpDebugMessage(ex.Message);
                    Terminate();
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            Terminate();
        }

        private void btnMute_CheckedChanged(object sender, EventArgs e)
        {
            if (_mixerDevice != null && _mixerDevice.IsOpen())
            {
                MixerControlDetails mxcd = new MixerControlDetails();
                tMIXERCONTROLDETAILS_BOOLEAN mxMute;

                mxMute.fValue = this.btnMute.Checked ? 1 : 0;
                Marshal.WriteInt32(_mixerDataPtr, mxMute.fValue);
                mxcd.ControlID = _MuteControlId;
                mxcd.NumChannels = 1;
                mxcd.MultipleItems = 0;
                mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_BOOLEAN));
                mxcd.DataArray = _mixerDataPtr;
                int hr = _mixerDevice.SetControlDetails(ref mxcd, MixerConstants.MIXER_SETCONTROLDETAILSF_VALUE);
            }
        }

        private void ctlVolume_ValueChanged(object sender, EventArgs e)
        {
            if (_mixerDevice != null && _mixerDevice.IsOpen())
            {
                MixerControlDetails mxcd = new MixerControlDetails();
                tMIXERCONTROLDETAILS_SIGNED mxVolume;

                mxVolume.lValue = this.ctlVolume.Value;
                Marshal.WriteInt32(_mixerDataPtr, mxVolume.lValue);
                mxcd.ControlID = _VolumeControlId;
                mxcd.NumChannels = 1;
                mxcd.MultipleItems = 0;
                mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_SIGNED));
                mxcd.DataArray = _mixerDataPtr;
                int hr = _mixerDevice.SetControlDetails(ref mxcd, MixerConstants.MIXER_SETCONTROLDETAILSF_VALUE);
            }
        }

        int SetupMixer()
        {
            int mmr = _mixerDevice.Open((int)_waveOutput.GetId(), WaveConstants.CALLBACK_WINDOW | MixerConstants.MIXER_OBJECTF_HWAVEOUT, this.Handle);
            if (mmr == WaveConstants.MMSYSERR_NOERROR)
            {
                MixerLineInfo mxli = new MixerLineInfo();
                MixerLineControls mxlcs = new MixerLineControls();
                MixerCaps mxcaps = new MixerCaps();
                MixerControlDetails mxcd = new MixerControlDetails();
                _mixerDataPtr = Marshal.AllocHGlobal(256);
                mmr = _mixerDevice.GetDeviceCaps(ref mxcaps);
                if (mmr == WaveConstants.MMSYSERR_NOERROR)
                {
                    DumpDebugMessage(string.Format("Mixer Caps: {0}, Ver:0x{1:x} (0x{2:x})", mxcaps.ProductName, mxcaps.Version, mxcaps.SupportFlag));
                }
                mxli.ComponentType = MixerConstants.MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
                mmr = _mixerDevice.GetLineInfo(ref mxli, MixerConstants.MIXER_GETLINEINFOF_COMPONENTTYPE);
                if (mmr == WaveConstants.MMSYSERR_NOERROR)
                {
                    tMIXERCONTROLW mxc;
                    Marshal.WriteInt32(_mixerDataPtr, (int)Marshal.OffsetOf(typeof(tMIXERCONTROLW), "cbStruct"), (int)Marshal.SizeOf(typeof(tMIXERCONTROLW)));
                    mxlcs.LineID = mxli.LineID;
                    mxlcs.NumControls = 1;
                    mxlcs.ControlType = MixerConstants.MIXERCONTROL_CONTROLTYPE_MUTE;
                    mxlcs.CbControl = (int)Marshal.SizeOf(typeof(tMIXERCONTROLW));
                    mxlcs.DataArray = _mixerDataPtr;
                    mmr = _mixerDevice.GetLineControls(ref mxlcs, MixerConstants.MIXER_GETLINECONTROLSF_ONEBYTYPE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -