私は現在、楽器を演奏しているソロ ミュージシャンの wav ファイルを分析し、その中の音符を検出するプログラムに取り組んでいます。これを行うために、FFT を実行し、生成されたデータを調べます。目標は、(ある時点で) midi ファイルを作成して楽譜を作成することです。
何が難しいのか、以前に試した人がいるかどうか、調査するのが良いことについて、いくつかの意見を聞きたかっただけです。現時点で私の最大の苦労は、すべての音符が純粋に 1 つの周波数であるとは限らず、和音をまだ検出できないことです。ただの単音。また、検出している音符の間に一時停止が必要なので、1 つが終了し、もう 1 つが開始したことを確認できます。これについてのコメントも大歓迎です!
これは、信号から新しいフレームが入ってくるときに使用するコードです。サンプルで最も支配的な周波数を探します。
//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];