Tôi đang làm việc trên một trò chơi platformer bao gồm âm nhạc với tính năng phát hiện nhịp. Tôi hiện đang phát hiện nhịp đập bằng cách kiểm tra khi biên độ hiện tại vượt quá mẫu lịch sử. Điều này không hoạt động tốt với các thể loại âm nhạc, như rock, có biên độ khá ổn định.
Vì vậy, tôi đã nhìn xa hơn và thấy các thuật toán chia âm thanh thành nhiều dải bằng FFT ... sau đó tôi tìm thấy thuật toán Cooley-Tukey FFt
Vấn đề duy nhất tôi gặp phải là tôi khá mới với âm thanh và tôi không biết làm thế nào để sử dụng điều đó để phân chia tín hiệu thành nhiều tín hiệu.
Vì vậy, câu hỏi của tôi là:
Làm thế nào để bạn sử dụng FFT để chia tín hiệu thành nhiều băng tần?
Ngoài ra, đối với những người quan tâm, đây là thuật toán của tôi trong 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++;
}
}