Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        /// <summary>各BPM候補でエネルギーを算出</summary>
        private double timeCombRough(List<Complex[]> dft, ref DetectStatus ds)
        {
            int n = dft[0].Length;
            int nbands = _bandLimits.Length;

            double maxe = 0; double bpmResult = 0;
            int ei = 0;
            for (double bpm = ds.MinBpm; bpm <= ds.MaxBpm; bpm += ds.BpmAcc)
            {
                /// Initialize energy and filter to zero(s)
                double e = 0;
                Complex[] fil = new Complex[n];
                for (int i = 0; i < fil.Length; i++) fil[i] = new Complex(0, 0);

                /// Calculate the difference between peaks in the filter for a certain tempo
                int nstep = (int)Math.Floor(ds.SamplePerSec * 60 / bpm);

                /// Set every nstep samples of the filter to one
                for (int i = 0; i < _npulses && i * nstep < fil.Length; i++)
                {
                    fil[i * nstep] = new Complex(1, 0);
                }

                /// Get the filter in the frequency domain
                FourierTransform.FFT(fil, FourierTransform.Direction.Forward);

                /// Calculate the energy after convolution
                for (int i = 0; i < nbands; i++)
                {
                    double sum = 0;
                    for (int j = 0; j < fil.Length; j++)
                    {
                        Complex c = fil[j] * dft[i][j];
                        sum += Math.Pow(c.Re, 2) + Math.Pow(c.Im, 2);
                    }
                    e += sum * _bandWeights[i];
                }

                /// Set the energy to DetectStatus
                lock (ds.BpmEnergies)
                {
                    ds.BpmEnergies[ei] = (1 - _energyDecay) * ds.BpmEnergies[ei] + _energyDecay * e;
                }
                if (maxe < ds.BpmEnergies[ei])
                {
                    maxe = ds.BpmEnergies[ei];
                    bpmResult = bpm;
                }
                ei++;
            }
            return bpmResult;
        }