Ich arbeite an einem Platformer-Spiel, das Musik mit Beat-Erkennung enthält. Momentan erkenne ich Beats, indem ich überprüfe, ob die aktuelle Amplitude eine historische Stichprobe überschreitet. Dies funktioniert nicht gut mit Musikgenres wie Rock, die eine ziemlich konstante Amplitude haben.
Also habe ich weiter gesucht und Algorithmen gefunden, die den Sound mit FFT in mehrere Bänder aufteilen ... dann habe ich die gefunden aufteilen. Cooley-Tukey FFt-Algorithmus gefunden
Das einzige Problem, das ich habe, ist, dass ich für Audio ziemlich neu bin und keine Ahnung habe, wie ich das verwenden soll, um das Signal in mehrere Signale aufzuteilen.
Meine Frage lautet also:
Wie verwendet man eine FFT, um ein Signal in mehrere Bänder aufzuteilen?
Auch für die Interessierten ist dies mein Algorithmus in 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++;
}
}