비트 감지 기능이있는 음악이 포함 된 플랫 포머 게임을 만들고 있습니다. 현재 진폭이 과거 샘플을 초과하는 시점을 확인하여 비트를 감지하고 있습니다. 이것은 꽤 일정한 진폭을 갖는 록과 같은 음악 장르에서는 잘 작동하지 않습니다.
FFT를 사용하여 사운드를 여러 대역으로 나누는 알고리즘을 찾았습니다. 그런 다음 Cooley-Tukey FFt 알고리즘을 찾았습니다.
내가 가지고있는 유일한 문제는 오디오를 처음 접했고 신호를 여러 신호로 나누는 데 어떻게 사용할지 모른다는 것입니다.
그래서 내 질문은 :
FFT를 사용하여 신호를 여러 대역으로 분할하는 방법은 무엇입니까?
또한 관심있는 사람들을 위해, 이것은 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++;
}
}