我目前正在开发一个程序,该程序分析独奏音乐家演奏乐器的 wav 文件并检测其中的音符。为此,它执行 FFT,然后查看生成的数据。目标是(在某个时候)通过编写一个 MIDI 文件来制作乐谱。
我只是想就它可能有什么困难得到一些意见,是否有人以前尝试过,也许有一些东西可以研究一下。目前,我最大的困难是并非所有音符都纯粹是一个频率,而且我还无法检测和弦;只是一个音符。我检测到的音符之间也必须有一个停顿,所以我确定一个已经结束,另一个开始了。对此的任何评论也将非常受欢迎!
这是我在从信号中进入新帧时使用的代码。它寻找样本中最主要的频率:
//Get frequency vector for power match
double[] frequencyVectorDoubleArray = Accord.Audio.Tools.GetFrequencyVector(waveSignal.Length, waveSignal.SampleRate);
powerSpectrumDoubleArray[0] = 0; // zero DC
double[,] frequencyPowerDoubleArray = new double[powerSpectrumDoubleArray.Length, 2];
for (int i = 0; i < powerSpectrumDoubleArray.Length; i++)
{
if (frequencyVectorDoubleArray[i] > 15.00)
{
frequencyPowerDoubleArray[i, 0] = frequencyVectorDoubleArray[i];
frequencyPowerDoubleArray[i, 1] = powerSpectrumDoubleArray[i];
}
}
//Method for finding the highest frequency in a sample of frequency domain data
//But I want to filter out stuff
pulsePowerDouble = lowestPowerAcceptedDouble;//0;//lowestPowerAccepted;
int frequencyIndexAtPulseInt = 0;
int oldFrequencyIndexAtPulse = 0;
for (int j = 0; j < frequencyPowerDoubleArray.Length / 2; j++)
{
if (frequencyPowerDoubleArray[j, 1] > pulsePowerDouble)
{
oldPulsePowerDouble = pulsePowerDouble;
pulsePowerDouble = frequencyPowerDoubleArray[j, 1];
oldFrequencyIndexAtPulse = frequencyIndexAtPulseInt;
frequencyIndexAtPulseInt = j;
}
}
foundFreq = frequencyPowerDoubleArray[frequencyIndexAtPulseInt, 0];