গানগুলিতে প্রহারগুলি সনাক্ত করতে আমি এই সাউন্ডএনলাইজার ক্লাসটি তৈরি করেছি:
class SoundAnalyzer
{
public SoundBuffer soundData;
public Sound sound;
public List<double> beatMarkers = new List<double>();
public SoundAnalyzer(string path)
{
soundData = new SoundBuffer(path);
sound = new Sound(soundData);
}
// C = threshold, N = size of history buffer / 1024 B = bands
public void PlaceBeatMarkers(float C, int N, int B)
{
List<double>[] instantEnergyList = new List<double>[B];
GetEnergyList(B, ref instantEnergyList);
for (int i = 0; i < B; i++)
{
PlaceMarkers(instantEnergyList[i], N, C);
}
beatMarkers.Sort();
}
private short[] getRange(int begin, int end, short[] array)
{
short[] result = new short[end - begin];
for (int i = 0; i < end - begin; i++)
{
result[i] = array[begin + i];
}
return result;
}
// get a array of with a list of energy for each band
private void GetEnergyList(int B, ref List<double>[] instantEnergyList)
{
for (int i = 0; i < B; i++)
{
instantEnergyList[i] = new List<double>();
}
short[] samples = soundData.Samples;
float timePerSample = 1 / (float)soundData.SampleRate;
int sampleIndex = 0;
int nextSamples = 1024;
int samplesPerBand = nextSamples / B;
// for the whole song
while (sampleIndex + nextSamples < samples.Length)
{
complex[] FFT = FastFourier.Calculate(getRange(sampleIndex, nextSamples + sampleIndex, samples));
// foreach band
for (int i = 0; i < B; i++)
{
double energy = 0;
for (int j = 0; j < samplesPerBand; j++)
energy += FFT[i * samplesPerBand + j].GetMagnitude();
energy /= samplesPerBand;
instantEnergyList[i].Add(energy);
}
if (sampleIndex + nextSamples >= samples.Length)
nextSamples = samples.Length - sampleIndex - 1;
sampleIndex += nextSamples;
samplesPerBand = nextSamples / B;
}
}
// place the actual markers
private void PlaceMarkers(List<double> instantEnergyList, int N, float C)
{
double timePerSample = 1 / (double)soundData.SampleRate;
int index = N;
int numInBuffer = index;
double 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++;
}
}
}
কোনও কারণে এটি কেবল 63৩7 সেকেন্ড থেকে প্রায় 1৪১ সেকেন্ড পর্যন্ত মারধর সনাক্ত করে এবং কেন তা আমার কোনও ধারণা নেই। আমি জানি যে আমি নকলগুলি খুঁজে পাচ্ছি বলে একাধিক ব্যান্ড থেকে বীটগুলি sertedোকানো হচ্ছে এবং মনে হচ্ছে এটি সেই মানগুলির মধ্যে প্রতিটি তাত্ক্ষণিক শক্তি মানকে একটি বিট বরাদ্দ করেছে।
এটি এর পরে মডেল করা হয়েছে: http://www.flipcode.com/misc/BeatDetectionAlgorithms.pdf
তাহলে মার কেন ঠিকমতো নিবন্ধন করবে না?