📄 __waveinput_soundstudiofrm.cs
字号:
}
void ComputeFFT(WaveBuffer wbuf)
{
if (GetAudioData(wbuf.AudioData, wbuf.BytesRecorded, _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);
#else
FFT.Compute(_numSamples, RealIn, null, RealOut, ImagOut, false);
FFT.Norm(_numSamples / 2, RealOut, ImagOut, AmplOut);
#endif
double maxAmpl = (_wfmt.BitsPerSample == 8) ? (127.0 * 127.0) : (32767.0 * 32767.0);
// update meter
int centerFreq = (int)(_wfmt.SamplesPerSecond / 2);
for (int i = 0; i < NUM_FREQUENCY; ++i)
{
if (METER_FREQUENCY[i] > centerFreq)
_meterData[i] = 0;
else
{
int indice = (int)(METER_FREQUENCY[i] * _numSamples / _wfmt.SamplesPerSecond);
int metervalue = (int)(100+ 20.0 * Math.Log10(AmplOut[indice] / maxAmpl));
_meterData[i] = metervalue;
}
}
peakMeterCtrl1.SetData(_meterData, 0, NUM_FREQUENCY);
_numSamples = 0; // ready to do it again
}
else
{
DumpDebugMessage("GET Audio data failed.");
}
}
bool GetAudioData(IntPtr ptr, int cbSize, WaveFormat wfmt)
{
bool samplesReady = false;
if (cbSize == 0)
return false; // no data
switch (wfmt.BitsPerSample)
{
case 8:
{
// NOTE: waveData member is necessary to prevent using 'unsafe' code block
Marshal.Copy(ptr, waveData, 0, (int)cbSize);
if (wfmt.Channels == 1) // mono
{
for (uint i = 0; i < cbSize; ++i)
{
RealIn[i] = (double)((waveData[i] - 128) << 6);// Out = (In-128)*64
}
_numSamples = (uint)cbSize;
}
else if (wfmt.Channels == 2) // stereo
{
// Stereo has Right+Left channels
int Samples = cbSize >> 1;
for (uint i = 0, j = 0; i < Samples; ++i, j += 2)
{
RealIn[i] = (double)((waveData[j] - 128) << 6); // Out = (In-128)*64
// LeftIn[i] = (double)((waveData[j+1]-128)<<6); // Out = (In-128)*64
}
_numSamples = (uint)Samples;
}
samplesReady = (_numSamples != 0);
}
break;
case 16:
{
// NOTE: waveData member is necessary to prevent using 'unsafe' code block
Marshal.Copy(ptr, waveData, 0, (int)cbSize);
if (wfmt.Channels == 1) // mono
{
int Samples = cbSize >> 1;
for (uint i = 0, j = 0; i < Samples; ++i, j += 2)
{
short val = (short)unchecked(((waveData[j + 1] << 8) + waveData[j]));
RealIn[i] = (double)val;
}
_numSamples = (uint)Samples;
}
else if (wfmt.Channels == 2) // stereo
{
// Stereo has Right+Left channels
int Samples = cbSize >> 2;
for (uint i = 0, j = 0; i < Samples; ++i, j += 4)
{
short val = unchecked((short)((waveData[j + 1] << 8) + waveData[j])); // right
RealIn[i] = (double)val;
// val = unchecked((short)((waveData[j+3] << 8) + waveData[j+2])); // left
}
_numSamples = (uint)Samples;
}
samplesReady = (_numSamples != 0);
}
break;
default:
System.Diagnostics.Debug.Assert(false, "Format not supported"); // not supported
break;
}
return samplesReady;
}
bool PutAudioData(IntPtr pbData, int cbSize, int recvBytes, WaveFormat wfmt)
{
bool samplesReady = true;
switch (wfmt.BitsPerSample)
{
case 8:
{
// fill with silence - no smoothing
if (cbSize > recvBytes)
{
MemorySet(pbData, 0x80, (cbSize - recvBytes));
}
}
break;
case 16:
default:
{
// fill with silence - no smoothing
if (cbSize > recvBytes)
{
MemorySet(pbData, 0x00, (cbSize - recvBytes));
}
}
break;
}
return samplesReady;
}
void MemorySet(IntPtr ptrData, byte val, int cb)
{
byte[] silence = { val };
for (int i = 0; i < cb; ++i)
{
IntPtr ptrDest = (IntPtr)((int)ptrData + i);
Marshal.Copy(silence, 0, ptrDest, 1);
}
}
void CreateWaveInput()
{
if (_waveInput == null)
{
_waveInput = new WaveInDevice();
_waveInput.SetNotifyHandler(this);
}
}
void ReleaseWaveInput()
{
if (_waveInput != null)
{
_waveInput.Close();
ReleaseBuffers();
_waveInput.SetNotifyHandler(null);
_waveInput = null;
}
}
void CreateBuffers()
{
if (_waveBuffer == null)
{
_waveBuffer = new WaveBuffer[MAX_BUFFERS];
for (int ii = 0; ii < MAX_BUFFERS; ++ii)
{
_waveBuffer[ii] = new WaveBuffer();
_waveBuffer[ii].Allocate((int)_bufferSize);
}
}
}
void ReleaseBuffers()
{
if (_waveBuffer != null)
{
for (int ii = 0; ii < MAX_BUFFERS; ++ii)
{
_waveBuffer[ii].Dispose();
}
_waveBuffer = null;
}
}
void AllocFFTData()
{
int numSamples = (int)_bufferSize / _wfmt.BlockAlign;
RealIn = new double[numSamples];
RealOut = new double[numSamples];
ImagOut = new double[numSamples];
AmplOut = new double[numSamples];
waveData = new byte[_bufferSize];
}
void ReleaseFFTData()
{
RealIn = null;
RealOut = null;
ImagOut = null;
AmplOut = null;
waveData = null;
}
[ConditionalAttribute("DEBUG")]
void DumpWaveErrorMessage(string message, int error)
{
StringBuilder sError = new StringBuilder(256);
WaveInput.waveInGetErrorTextW(error, sError, 256);
Trace.WriteLine(string.Format("{0} {1}", message, sError.ToString()));
}
[ConditionalAttribute("DEBUG")]
void DumpDebugMessage(string message)
{
Trace.WriteLine(message);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -