确实,如您所料,信号处理是您不想自己实现的算法,因为它们非常复杂。
显然,对于 C#,您可以在那里找到一些库,但这里有一个执行 DFT/FFT 的优秀库,并且目前处于活动状态:DSPLib
DSPLib 有几个主要部分,但它的基本目标是允许一个真正的
对时间序列输入数组执行傅里叶变换,
产生可用的经典频谱输出,无需任何进一步
用户需要的调整。
如果我正确理解您想要什么,第二个示例就是您想要完成的任务(它缺少麦克风的录音)。
只是一条建议,注意窗口化,因为它会影响信号的频谱。
关于一个可能会让你感到困惑的概念的注释,零填充只是一个技巧,让样本数量等于 2 的幂,以便使用 FFT 算法。因此,生成的光谱以某种方式“人工”产生,分辨率更高。
void example2()
{
// Same Input Signal as Example 1 - Except a fractional cycle for frequency.
double amplitude = 1.0; double frequency = 20000.5;
UInt32 length = 1000; UInt32 zeroPadding = 9000; // NOTE: Zero Padding
double samplingRate = 100000;
double[] inputSignal = DSPLib.DSP.Generate.ToneSampling(amplitude, frequency, samplingRate, length);
// Apply window to the Input Data & calculate Scale Factor
double[] wCoefs = DSP.Window.Coefficients(DSP.Window.Type.Hamming, length);
double[] wInputData = DSP.Math.Multiply(inputSignal, wCoefs);
double wScaleFactor = DSP.Window.ScaleFactor.Signal(wCoefs);
// Instantiate & Initialize a new DFT
DSPLib.DFT dft = new DSPLib.DFT();
dft.Initialize(length, zeroPadding); // NOTE: Zero Padding
// Call the DFT and get the scaled spectrum back
Complex[] cSpectrum = dft.Execute(wInputData);
// Convert the complex spectrum to note: Magnitude Format
double[] lmSpectrum = DSPLib.DSP.ConvertComplex.ToMagnitude(cSpectrum);
// Properly scale the spectrum for the added window
lmSpectrum = DSP.Math.Multiply(lmSpectrum, wScaleFactor);
// For plotting on an XY Scatter plot generate the X Axis frequency Span
double[] freqSpan = dft.FrequencySpan(samplingRate);
// At this point a XY Scatter plot can be generated from,
// X axis => freqSpan
// Y axis => lmSpectrum
}
绘制后,结果如下:
放大光谱的峰值: