Je travaille sur un jeu de plateforme qui comprend de la musique avec détection de battements. Je détecte actuellement des battements en vérifiant quand l'amplitude actuelle dépasse un échantillon historique. Cela ne fonctionne pas bien avec les genres de musique, comme le rock, qui ont une amplitude assez stable.
J'ai donc regardé plus loin et trouvé des algorithmes divisant le son en plusieurs bandes en utilisant la FFT ... puis j'ai trouvé l' algorithme Cooley-Tukey FFt
Le seul problème que j'ai est que je suis assez nouveau dans l'audio et je n'ai aucune idée de comment l'utiliser pour diviser le signal en plusieurs signaux.
Ma question est donc:
Comment utilisez-vous une FFT pour diviser un signal en plusieurs bandes?
Aussi pour les gars intéressés, voici mon algorithme 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++;
}
}