Estoy trabajando en un juego de plataformas que incluye música con detección de ritmo. Actualmente estoy detectando ritmos comprobando cuándo la amplitud actual excede una muestra histórica. Esto no funciona bien con géneros musicales, como el rock, que tienen una amplitud bastante estable.
Así que busqué más y encontré algoritmos que dividen el sonido en múltiples bandas usando FFT ... luego encontré el algoritmo Cooley-Tukey FFt
El único problema que tengo es que soy bastante nuevo en audio y no tengo idea de cómo usarlo para dividir la señal en varias señales.
Entonces mi pregunta es:
¿Cómo se usa una FFT para dividir una señal en múltiples bandas?
También para los chicos interesados, este es mi algoritmo en 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++;
}
}