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

📄 soundstudiofrm.cs

📁 Programing SoundStudioCS
💻 CS
📖 第 1 页 / 共 3 页
字号:
                    if (mmr == WaveConstants.MMSYSERR_NOERROR)
                    {
                        tMIXERCONTROLDETAILS_BOOLEAN mxMute;
                        mxc = (tMIXERCONTROLW)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLW));
                        _MuteControlId = mxc.dwControlID;
                        DumpDebugMessage(string.Format("Mute control: {0}", mxc.dwControlID));

                        mxcd.ControlID = _MuteControlId;
                        mxcd.NumChannels = 1;
                        mxcd.MultipleItems = 0;
                        mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_BOOLEAN));
                        mxcd.DataArray = _mixerDataPtr;
                        mmr = _mixerDevice.GetControlDetails(ref mxcd, MixerConstants.MIXER_GETCONTROLDETAILSF_VALUE);
                        if (mmr == WaveConstants.MMSYSERR_NOERROR)
                        {
                            mxMute = (tMIXERCONTROLDETAILS_BOOLEAN)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLDETAILS_BOOLEAN));
                            this.btnMute.Checked = (mxMute.fValue != 0);
                        }
                    }

                    mxlcs.LineID = mxli.LineID;
                    mxlcs.NumControls = 1;
                    mxlcs.ControlType = MixerConstants.MIXERCONTROL_CONTROLTYPE_VOLUME;
                    mxlcs.CbControl = (int)Marshal.SizeOf(typeof(tMIXERCONTROLW));
                    mxlcs.DataArray = _mixerDataPtr;
                    Marshal.WriteInt32(_mixerDataPtr, (int)Marshal.OffsetOf(typeof(tMIXERCONTROLW), "cbStruct"), (int)Marshal.SizeOf(typeof(tMIXERCONTROLW)));
                    mmr = _mixerDevice.GetLineControls(ref mxlcs, MixerConstants.MIXER_GETLINECONTROLSF_ONEBYTYPE);
                    if (mmr == WaveConstants.MMSYSERR_NOERROR)
                    {
                        tMIXERCONTROLDETAILS_SIGNED mxVolume;
                        mxc = (tMIXERCONTROLW)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLW));
                        _VolumeControlId = mxc.dwControlID;
                        DumpDebugMessage(string.Format("Volume control: {0}", mxc.dwControlID));

                        mxcd.ControlID = _VolumeControlId;
                        mxcd.NumChannels = 1;
                        mxcd.MultipleItems = 0;
                        mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_SIGNED));
                        mxcd.DataArray = _mixerDataPtr;
                        mmr = _mixerDevice.GetControlDetails(ref mxcd, MixerConstants.MIXER_GETCONTROLDETAILSF_VALUE);
                        if (mmr == WaveConstants.MMSYSERR_NOERROR)
                        {
                            mxVolume = (tMIXERCONTROLDETAILS_SIGNED)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLDETAILS_SIGNED));
                            this.ctlVolume.SetRange(mxc.Bounds.Signed.lMinimum, mxc.Bounds.Signed.lMaximum);
                            this.ctlVolume.TickFrequency = ((mxc.Bounds.Signed.lMaximum-mxc.Bounds.Signed.lMinimum) / 10);
                            this.ctlVolume.Value = (int)((ushort)mxVolume.lValue);
                        }
                    }
                }
            }
            return mmr;
        }

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        protected override void WndProc(ref Message m)
        {
            // Listen for operating system messages.
            switch (m.Msg)
            {
                // Process audio done message
                case WM_AUDIO_DONE:
                {
                    GCHandle gch = (GCHandle)(m.LParam);
                    WaveBuffer wbuf = gch.Target as WaveBuffer;
                    if (wbuf != null && _waveOutput != null)
                    {
                        try
                        {
                            int mmr = _waveOutput.UnprepareBuffer(wbuf);
                            WaveOutStatus.ThrowExceptionForHR(mmr);
                            Interlocked.Decrement(ref _numOutBuffers);

                            WaveStatus status = _waveOutput.GetDeviceStatus();
                            if (status == WaveStatus.waveStarted)
                            {
                                ProcessAudioData(wbuf);
                            }
                        }
                        catch (Exception ex) // typically: COMException, SystemException (waveout)
                        {
                            DumpDebugMessage(ex.Message);
                        }
                    }
                    else
                    {
                        DumpDebugMessage("WM_AUDIO_DONE - AUDIO STOPPED");
                    }
                    if (gch.IsAllocated)
                    {
                        gch.Free();
                    }
                    return;
                }
                case WM_MIXM_CONTROL_CHANGE: // MixerConstants.MM_MIXM_CONTROL_CHANGE
                {
                    if (_mixerDevice != null && _mixerDevice.IsOpen())
                    {
                        MixerControlDetails mxcd = new MixerControlDetails();
                        mxcd.ControlID = (int)(m.LParam);
                        mxcd.NumChannels = 1;
                        int hr = MSStatus.MS_S_FALSE;
                        if (mxcd.ControlID == _MuteControlId)
                        {
                            mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_BOOLEAN));
                            mxcd.DataArray = _mixerDataPtr;
                            hr = MSStatus.MS_S_OK;
                        }
                        else if (mxcd.ControlID == _VolumeControlId)
                        {
                            mxcd.CbDetails = (int)Marshal.SizeOf(typeof(tMIXERCONTROLDETAILS_SIGNED));
                            mxcd.DataArray = _mixerDataPtr;
                            hr = MSStatus.MS_S_OK;
                        }
                        if (hr == MSStatus.MS_S_OK)
                        {
                            hr = _mixerDevice.GetControlDetails(ref mxcd, MixerConstants.MIXER_GETCONTROLDETAILSF_VALUE);
                            if (mxcd.ControlID == _MuteControlId)
                            {
                                tMIXERCONTROLDETAILS_BOOLEAN mxMute;
                                mxMute = (tMIXERCONTROLDETAILS_BOOLEAN)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLDETAILS_BOOLEAN));
                                this.btnMute.Checked = (mxMute.fValue != 0);
                                if (this.btnMute.Checked)
                                {
                                    this.btnMute.Image = Resources.sound_mute;
                                }
                                else
                                {
                                    this.btnMute.Image = Resources.sound;
                                }
                            }
                            else if (mxcd.ControlID == _VolumeControlId)
                            {
                                tMIXERCONTROLDETAILS_SIGNED mxVolume;
                                mxVolume = (tMIXERCONTROLDETAILS_SIGNED)Marshal.PtrToStructure(_mixerDataPtr, typeof(tMIXERCONTROLDETAILS_SIGNED));
                                this.ctlVolume.Value = mxVolume.lValue;
                            }
                        }
                    }
                    return;
                }
            }
            base.WndProc(ref m);
        }

        private delegate void WndProcCallback(ref Message m);
        public void ProcessEvent(IWaveDevice waveDevice, int uMsg, WaveBuffer wbuf)
        {
            if (waveDevice == _waveOutput)
            {
                switch (uMsg)
                {
                    case WaveConstants.MM_WOM_OPEN:
                        DumpDebugMessage("Wave Opened");
                        break;
                    case WaveConstants.MM_WOM_DONE:
                        {
                            GCHandle gch = GCHandle.Alloc(wbuf);
                            // Create message
                            if (this.IsHandleCreated)
                            {
                                Message m = Message.Create(_CopyWindowHandle, WM_AUDIO_DONE, IntPtr.Zero, (IntPtr)gch);
                                WndProcCallback wndCallback = new WndProcCallback(WndProc);
                                // Ensure all calls will be thread-safe
                                this.BeginInvoke(wndCallback, m);
                            }
                        }
                        break;
                    case WaveConstants.MM_WOM_CLOSE:
                        DumpDebugMessage("Wave Closed");
                        break;
                }
            }
        }

        private void ProcessAudioData(WaveBuffer wbuf)
        {
            try
            {
                if (_waveOutput.GetDeviceStatus() == WaveStatus.waveStarted)
                {
                    ComputeFFT(wbuf);
                }

                int chunkSize = wbuf.BufferLength;
                int mmr = _AudioStream.GetSampleData(wbuf.AudioData, ref chunkSize, (int)COMPLETION_STATUS_FLAGS.COMPSTAT_WAIT, System.Threading.Timeout.Infinite);
                MSStatus.ThrowExceptionForHR(mmr);
                if (mmr == MSStatus.MS_S_OK)
                {
                    // Append silence if necessary
                    PutAudioData(wbuf.AudioData, wbuf.BufferLength, chunkSize, _wfmt);
                    mmr = _waveOutput.PrepareBuffer(wbuf);
                    WaveOutStatus.ThrowExceptionForHR(mmr);

                    mmr = _waveOutput.AddBuffer(wbuf);
                    WaveOutStatus.ThrowExceptionForHR(mmr);
                    Interlocked.Increment(ref _numOutBuffers);
                }
                else if (_numOutBuffers == 0) // all buffers done
                {
                    // stop
                    Terminate();
                }
            }
            catch (Exception ex) // typically: COMException, SystemException (waveout)
            {
                DumpDebugMessage(ex.Message);
            }
        }

        void ComputeFFT(WaveBuffer wbuf)
        {
            if (GetAudioData(wbuf.AudioData, wbuf.BufferLength, _wfmt))
            {
                // adjust FFT Sample to next power 2 but fill data with silence
                uint pow2Samples = FFT.NextPowerOfTwo(_numSamples);
                if (pow2Samples != _numSamples)
                {
                    double dsilence = 0.0;
                    if (_wfmt.BitsPerSample == 8)
                    {
                        dsilence = 128.0;
                    }
                    for (uint ii = _numSamples; ii < pow2Samples; ii++)
                    {
                        RealIn[ii] = dsilence;
                    }
                    _numSamples = pow2Samples;
                }

                // You may want to add 'USE_FFTLIB' under the project settings (Build->General tab)
                // to get better performance
#if USE_FFTLIB
                // Do the FFT
                FFTLib.ComputeD(_numSamples, RealIn, null, RealOut, ImagOut, false);
                // We can skip N/2 to N samples (mirror frequencies) - Digital samples are real integer
                FFTLib.NormD(_numSamples / 2, RealOut, ImagOut, AmplOut);

⌨️ 快捷键说明

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