В настоящее время я работаю над программой, которая анализирует wav-файл соло-музыканта, играющего на инструменте, и обнаруживает в нем ноты.Для этого он выполняет БПФ, а затем просматривает полученные данные.Цель состоит в том, чтобы (в какой-то момент) создать ноты, написав миди-файл.
Я просто хотел получить несколько мнений о том, что может быть трудным в этом вопросе, пробовали ли кто-нибудь это раньше, может быть, нескольковещи, которые было бы хорошо исследовать.На данный момент моя самая большая борьба состоит в том, что не все ноты являются чисто одной частотой, и я пока не могу обнаружить аккорды;только отдельные заметки.Также должна быть пауза между заметками, которые я обнаруживаю, чтобы я точно знал, что одна из них закончилась, а другая началась.Любые комментарии по этому поводу также будут очень кстати!
Это код, который я использую, когда из сигнала приходит новый кадр.он ищет частоту, которая является наиболее доминирующей в выборке:
//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];