public List<double[]> DetectBpm(double[] sig, ref DetectStatus ds, ref BeatStatus bs) { // 必要数の入力を複素数に変換 int n = (int)Math.Floor(Math.Log(sig.Length, 2)); int size = (int)Math.Pow(2, n > 14 ? 14 : n); // limit of AForge.NET Complex[] input = new Complex[size]; for (int i = 0; i < size; i++) { input[i] = new Complex(sig[i], 0); } // Bpm検出処理 List<Complex[]> filtered = filterBank(input); List<Complex[]> windowed = hwindow(filtered, 0.2); List<Complex[]> differentiated = diffrect(windowed); List<Complex[]> dft = timeCombPre(differentiated); double rBpm = timeCombRough(dft, ref ds); int maxBand = -1; double b2 = timeComb(dft, 0.1, rBpm - 1, rBpm + 1, ds.SamplePerSec, ref maxBand); bs.BpmRaw = b2; List<double[]> features = new List<double[]>(); for (int i = 0; i < _bandLimits.Length; i++) { double[] f = Array.ConvertAll<Complex, double>(differentiated[i], c => c.Re); features.Add(f); } //double[] features = Array.ConvertAll<Complex, double>(differentiated[maxBand], c => c.Re); return features; }
public void AdjustBeat(List<double[]> features, ref DetectStatus ds, ref BeatStatus bs) { int nstep = (int)Math.Floor(ds.SamplePerSec * (60 / bs.BpmDancer)); double maxe = 0; int maxs = -1; for (int s = 0; s < nstep; s += 2) { double e = 0; for (int i = 0; i < _bandLimits.Length; i++) { for (int j = 0; j < features[i].Length; j++) { double peakValue = 1 - (j % (s + nstep)) / (double)nstep; e += Math.Pow(features[i][j] * peakValue, 2) * _bandWeights[i]; } } if (maxe < e) { maxe = e; maxs = s; } } int beatStartSample = maxs; bs.BeatTickRaw = bs.SampleStartTick + beatStartSample * 1000 / ds.SamplePerSec; }