📄 __waveinput_soundstudiofrm.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using Ernzo.WinForms.Controls;
using Ernzo.Windows.WaveAudio;
using Ernzo.DSP;
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 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 WaveBuffer[] _waveBuffer;
private WaveInDevice _waveInput;
private IntPtr _CopyWindowHandle;
private WaveFormat _wfmt;
private uint _bufferSize;
private uint _numSamples;
private int _numOutBuffers;
public SoundStudioFrm()
{
InitializeComponent();
_wfmt = new WaveFormat();
_wfmt.SetPCMFormat(11025, 1, 16);
_bufferSize = FFT.NextPowerOfTwo((UInt32)(_wfmt.BytesPerSecond * FFT_SPEED));
_numSamples = 0;
_numOutBuffers = 0;
}
private void Terminate()
{
ReleaseWaveInput();
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;
this.btnBrowse.Enabled = false; // not used
}
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 (_waveInput == null)
{
CreateWaveInput();
}
if (!_waveInput.IsOpen())
{
_CopyWindowHandle = this.Handle;
try
{
int mmr = _waveInput.Open(WaveConstants.WAVE_MAPPER, _wfmt);
WaveInStatus.ThrowExceptionForHR(mmr);
CreateBuffers();
AllocFFTData();
_numSamples = 0;
_numOutBuffers = 0;
for (int index = 0; index < MAX_BUFFERS; ++index)
{
WaveBuffer curBuffer = _waveBuffer[index];
mmr = _waveInput.PrepareBuffer(curBuffer);
mmr = _waveInput.AddBuffer(curBuffer);
WaveInStatus.ThrowExceptionForHR(mmr);
Interlocked.Increment(ref _numOutBuffers);
}
mmr = _waveInput.Start();
WaveInStatus.ThrowExceptionForHR(mmr);
btnPlay.Enabled = false;
btnStop.Enabled = true;
btnMute.Enabled = false; // not used!!
ctlVolume.Enabled = true;
}
catch (Exception ex) // Typically: COMException, SystemException
{
DumpDebugMessage(ex.Message);
MessageBox.Show(ex.Message);
}
}
}
private void btnStop_Click(object sender, EventArgs e)
{
Terminate();
}
private void btnMute_CheckedChanged(object sender, EventArgs e)
{
}
private void ctlVolume_ValueChanged(object sender, EventArgs e)
{
}
[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 && _waveInput != null)
{
try
{
int mmr = _waveInput.UnprepareBuffer(wbuf);
WaveInStatus.ThrowExceptionForHR(mmr);
Interlocked.Decrement(ref _numOutBuffers);
WaveStatus status = _waveInput.GetDeviceStatus();
if (status == WaveStatus.waveStarted)
{
ProcessAudioData(wbuf);
}
}
catch (Exception ex) // Typically: COMException, SystemException
{
DumpDebugMessage(ex.Message);
}
}
else
{
DumpDebugMessage("WM_AUDIO_DONE - AUDIO STOPPED");
}
if (gch.IsAllocated)
{
gch.Free();
}
return;
}
default:
break;
}
base.WndProc(ref m);
}
private delegate void WndProcCallback(ref Message m);
public void ProcessEvent(IWaveDevice waveDevice, int uMsg, WaveBuffer wbuf)
{
if (waveDevice == _waveInput)
{
switch (uMsg)
{
case WaveConstants.MM_WIM_OPEN:
DumpDebugMessage("Wave Opened");
break;
case WaveConstants.MM_WIM_DATA:
{
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_WIM_CLOSE:
DumpDebugMessage("Wave Closed");
break;
}
}
}
private void ProcessAudioData(WaveBuffer wbuf)
{
try
{
if (_waveInput.GetDeviceStatus() == WaveStatus.waveStarted)
{
ComputeFFT(wbuf);
int mmr = _waveInput.PrepareBuffer(wbuf);
WaveInStatus.ThrowExceptionForHR(mmr);
mmr = _waveInput.AddBuffer(wbuf);
WaveInStatus.ThrowExceptionForHR(mmr);
Interlocked.Increment(ref _numOutBuffers);
}
}
catch (Exception ex) // COMException, SystemException (waveinput)
{
DumpDebugMessage(ex.Message);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -