c# - C# 中 FFT 的音高检测
问题描述
我正在制作一个程序来调整铜管乐队。我开始用麦克风录音。
public void StartMicListening()
{
int audioDevNumber = 0;
WaveInEvent wIN = new WaveInEvent();
wIN.DeviceNumber = audioDevNumber;
wIN.WaveFormat = new NAudio.Wave.WaveFormat(RATE, 1);
wIN.BufferMilliseconds = (int)((double)BUFFERSIZE / (double)RATE * 1000.0);
wIN.DataAvailable += new EventHandler<WaveInEventArgs>(AudioDataAvailable);
bwp = new BufferedWaveProvider(wIN.WaveFormat);
bwp.BufferLength = BUFFERSIZE * 2;
bwp.DiscardOnBufferOverflow = true;
try
{
wIN.StartRecording();
}
catch
{
Console.WriteLine("Can't see device");
}
//Console.WriteLine("Recording");
}
接下来我要计算 FFT
public void calculateFFT()
{
var audioBytes = new byte[BUFFERSIZE];
bwp.Read(audioBytes, 0, BUFFERSIZE);
int pointCount = audioBytes.Length / 2;
double[] pcm = new double[pointCount];
double[] fft = new double[pointCount];
double[] fftReal = new double[pointCount/2];
for (int i = 0; i < pointCount; i++)
{
// read the int16 from the two bytes
Int16 val = BitConverter.ToInt16(audioBytes, i * 2);
// store the value in Ys as a percent (+/- 100% = 200%)
pcm[i] = (double)(val) / Math.Pow(2, 18) * 200.0;
}
fft = FFT(pcm);
Array.Copy(fft, fftReal, fftReal.Length);
}
当我使用 440 Hz 音调的音调发生器 ( https://www.szynalski.com/tone-generator/ ) 测试此代码时,我从 fftReal 获得最大值,它运行良好。但是当我将它与萨克斯管的声音一起使用时,我从 fftReal 中获得最大值,我检测到有时是 440Hz,有时是 880Hz,有时是 1320Hz。880 Hz 和 1320 Hz 是 A 音调(440 Hz)的等分,但我只需要检测频谱的第一个音高(440 Hz)。有什么解决办法吗?Mayba 你们中的一些人已经用 C# 完成了它,可以分享给我。
解决方案
推荐阅读
- xcode - 如何在不使用 Xcode 的情况下导出 Apple Developer Id 证书
- java - Java cucumber IllegalArgumentException 路径不一致
- php - 表查询,从table1中选择数据,但前提是table2中的用户设置设置为特定值
- javascript - 从胡须模板 Moodle 3.7 中获取数据
- internationalization - 全球分数的 PageSpeed Insights
- python - NameError:未定义名称“board1”
- vba - 为整个word文档应用pagesetup
- r - 用于拆分括号内容的正则表达式:例如“Emulsifiers (322, 476)”为“Emulsifier 322”和“Emulsifier 476”?
- ruby-on-rails - 使用 Shrine 和 image_processing gem 模糊图像
- python - Numpy np.array() 构造函数行为“不一致”