Я працюю над ігровою платформою, яка включає музику з виявленням ритму. На даний момент я виявляю удари, перевіряючи, коли поточна амплітуда перевищує історичну вибірку. Це не дуже добре працює з такими жанрами музики, як рок, які мають досить стійку амплітуду.
Тому я подивився далі і знайшов алгоритми, що розбивають звук на кілька діапазонів за допомогою FFT ... тоді я знайшов алгоритм Cooley-Tukey FFt
Єдина проблема, яка у мене виникає, полягає в тому, що я абсолютно новачок у аудіо, і я не маю уявлення, як це використовувати для розділення сигналу на кілька сигналів.
Отже, моє питання:
Як ви використовуєте FFT, щоб розділити сигнал на кілька діапазонів?
Також для хлопців, які цікавляться, це мій алгоритм на c #:
// C = threshold, N = size of history buffer / 1024
public void PlaceBeatMarkers(float C, int N)
{
List<float> instantEnergyList = new List<float>();
short[] samples = soundData.Samples;
float timePerSample = 1 / (float)soundData.SampleRate;
int sampleIndex = 0;
int nextSamples = 1024;
// Calculate instant energy for every 1024 samples.
while (sampleIndex + nextSamples < samples.Length)
{
float instantEnergy = 0;
for (int i = 0; i < nextSamples; i++)
{
instantEnergy += Math.Abs((float)samples[sampleIndex + i]);
}
instantEnergy /= nextSamples;
instantEnergyList.Add(instantEnergy);
if(sampleIndex + nextSamples >= samples.Length)
nextSamples = samples.Length - sampleIndex - 1;
sampleIndex += nextSamples;
}
int index = N;
int numInBuffer = index;
float historyBuffer = 0;
//Fill the history buffer with n * instant energy
for (int i = 0; i < index; i++)
{
historyBuffer += instantEnergyList[i];
}
// If instantEnergy / samples in buffer < instantEnergy for the next sample then add beatmarker.
while (index + 1 < instantEnergyList.Count)
{
if(instantEnergyList[index + 1] > (historyBuffer / numInBuffer) * C)
beatMarkers.Add((index + 1) * 1024 * timePerSample);
historyBuffer -= instantEnergyList[index - numInBuffer];
historyBuffer += instantEnergyList[index + 1];
index++;
}
}