Example #1
0
        /// <summary>
        /// Pitch estimation by autocorrelation method
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="samplingRate"></param>
        /// <param name="startPos"></param>
        /// <param name="endPos"></param>
        /// <param name="low"></param>
        /// <param name="high"></param>
        /// <returns></returns>
        public static float FromAutoCorrelation(float[] signal,
                                                int samplingRate,
                                                int startPos = 0,
                                                int endPos   = -1,
                                                float low    = 80,
                                                float high   = 400)
        {
            if (endPos == -1)
            {
                endPos = signal.Length;
            }

            var pitch1 = (int)(1.0 * samplingRate / high);    // 2,5 ms = 400Hz
            var pitch2 = (int)(1.0 * samplingRate / low);     // 12,5 ms = 80Hz

            var block = new DiscreteSignal(samplingRate, signal)[startPos, endPos].Samples;

            var fftSize = MathUtils.NextPowerOfTwo(2 * block.Length - 1);

            var cc = new float[fftSize];

            new Convolver(fftSize).CrossCorrelate(block, block.FastCopy(), cc);

            var start = pitch1 + block.Length - 1;
            var end   = Math.Min(start + pitch2, cc.Length);

            var max = start < cc.Length ? cc[start] : 0;

            var peakIndex = start;

            for (var k = start; k < end; k++)
            {
                if (cc[k] > max)
                {
                    max       = cc[k];
                    peakIndex = k - block.Length + 1;
                }
            }

            return(max > 1.0f ? (float)samplingRate / peakIndex : 0);
        }