Saya sedang mengerjakan game platformer yang mencakup musik dengan deteksi ketukan. Saat ini saya mendeteksi ketukan dengan memeriksa kapan amplitudo saat ini melebihi sampel historis. Ini tidak bekerja dengan baik dengan genre musik, seperti rock, yang memiliki amplitudo yang cukup mantap.
Jadi saya melihat lebih jauh dan menemukan algoritma yang membelah suara menjadi beberapa band menggunakan FFT ... kemudian saya menemukan algoritma Cooley-Tukey FFt
Satu-satunya masalah yang saya alami adalah bahwa saya cukup baru untuk audio dan saya tidak tahu bagaimana menggunakannya untuk membagi sinyal menjadi beberapa sinyal.
Jadi pertanyaan saya adalah:
Bagaimana Anda menggunakan FFT untuk membagi sinyal menjadi beberapa band?
Juga untuk orang-orang yang tertarik, ini adalah algoritma saya di 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++;
}
}