Example #1
0
        // 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);
        }