// 20170803 #region Comments // This method uses Steps 2-4 of the YIN method (Cheveigne and Kawahara, 2002). // (Step 1 is only used (in the paper) for comparison, and Steps 5-6 only provide // minor absolute improvements. #endregion /* public double GetPitchPeriod(WAVSound sound, double time, double maximumPitchPeriod, double threshold) * { * int sampleIndex = sound.GetSampleIndexAtTime(time); * int maximumIndexDuration = (int)Math.Round(maximumPitchPeriod * sound.SampleRate); * double minimum = double.MaxValue; * double pitchPeriod = 0; * List<double> periodList = new List<double>(); * List<double> shiftedSquareDifferenceList = new List<double>(); * List<double> normalizedShiftedSquaredDifferenceList = new List<double>(); * periodList.Add(0); * shiftedSquareDifferenceList.Add(0); * normalizedShiftedSquaredDifferenceList.Add(1); * * for (int ii = 1; ii <= maximumIndexDuration; ii++) * { * int indexDuration = ii; * double shiftedSquareDifference = sound.GetShiftedSquareDifference(sampleIndex, ii, maximumIndexDuration); * shiftedSquareDifferenceList.Add(shiftedSquareDifference); * double period = indexDuration / (double)sound.SampleRate; * periodList.Add(period); * double average = shiftedSquareDifferenceList.Average(); * double normalizedShiftedSquareDifference = shiftedSquareDifference / average; * if (normalizedShiftedSquareDifference < minimum) * { * minimum = normalizedShiftedSquareDifference; * pitchPeriod = period; * } * normalizedShiftedSquaredDifferenceList.Add(normalizedShiftedSquareDifference); * } * int minimumIndex = FindFirstMinimum(normalizedShiftedSquaredDifferenceList, threshold); * if (minimumIndex > 0) // Otherwise use the global minimum, computed above. * { * pitchPeriod = minimumIndex / (double)sound.SampleRate; * } * return pitchPeriod; * } */ public double ComputeFramePitchPeriod(WAVSound sound, double time) // , double minimumPitchPeriod, double maximumPitchPeriod) { int sampleIndex = sound.GetSampleIndexAtTime(time); int minimumIndexDuration = (int)Math.Round(minimumPitchPeriod * sound.SampleRate); int maximumIndexDuration = (int)Math.Round(maximumPitchPeriod * sound.SampleRate); double minimumAverageMagnitudeDifference = double.MaxValue; int indexDurationAtMinimum = 0; for (int ii = minimumIndexDuration; ii <= maximumIndexDuration; ii++) { double averageMagnitudeDifference = sound.GetAbsoluteMagnitudeDifference(sampleIndex, ii, maximumIndexDuration); if (averageMagnitudeDifference < minimumAverageMagnitudeDifference) { minimumAverageMagnitudeDifference = averageMagnitudeDifference; indexDurationAtMinimum = ii; } } double pitchPeriod = indexDurationAtMinimum / (double)sound.SampleRate; return(pitchPeriod); }