public WAVSound Modify(WAVSound sound, double relativeStartPitch, double relativeEndPitch, Boolean adjustDuration, double relativeDuration) { // First, find the speech type variation: // speechTypeEstimator = new SpeechTypeEstimator(); speechTypeEstimator.FindSpeechTypeVariation(sound); /* speechTypeEstimator.FindSpeechTypeVariation(sound, 0, frameDuration, frameShift, speechTypeLowPassCutoffFrequency, speechTypeLowPassRatioThreshold, * speechTypeEnergyThreshold, speechTypeSilenceThreshold); * speechTypeEstimator.Adjust(3); * speechTypeEstimator.Adjust(3); // repeat the adjustment to remove double errors. */ SpeechTypeSpecification speechTypeSpecification = speechTypeEstimator.SpeechTypeSpecification; // Next, find the pitch periods: PitchPeriodEstimator pitchPeriodEstimator = new PitchPeriodEstimator(); pitchPeriodEstimator.ComputePitchPeriods(sound, 0.0, sound.GetDuration()); //, minimumPitchPeriod, maximumPitchPeriod, frameShift); // 0.0120, 0.01, 0.03); pitchPeriodEstimator.AdjustAndInterpolate(speechTypeSpecification); //, pitchPeriodDeltaTime, setUnvoicedPitch); // 0.005, true); PitchPeriodSpecification pitchPeriodSpecification = pitchPeriodEstimator.PitchPeriodSpecification; // Then, find the pitch marks: pitchMarkEstimator = new PitchMarkEstimator(); pitchMarkEstimator.FindPitchMarks(sound, speechTypeSpecification, pitchPeriodSpecification); // , 0.0025, 0.0025, 0.45, 0.002); List <double> pitchMarkTimeList = pitchMarkEstimator.PitchMarkTimeList; // Then, change the pitch of the sound double originalDuration = sound.GetDuration(); double desiredDuration = originalDuration * relativeDuration; double actualRelativeDuration = relativeDuration; // Valid if the pitch is unchanged ... WAVSound pitchChangedSound; if ((Math.Abs(relativeStartPitch - 1) > double.Epsilon) || (Math.Abs(relativeEndPitch - 1) > double.Epsilon)) // To save some time, if only duration is to be changed.. { pitchChangedSound = ChangePitch(sound, pitchMarkTimeList, relativeStartPitch, relativeEndPitch); // The pitch change also changes the duration of the sound: double newDuration = pitchChangedSound.GetDuration(); actualRelativeDuration = desiredDuration / newDuration; // ...but if the pitch is changed, the duration changes too. } else { pitchChangedSound = sound; // No copying needed here, a reference is sufficient. modifiedPitchMarkTimeList = pitchMarkTimeList; // No pitch change => use original pitch marks. } // If the adjustDuration is true, change the duration, using the stored pitchmark time list (to avoid repeating the three steps above): if (adjustDuration) { WAVSound durationChangedSound = ChangeDuration(pitchChangedSound, modifiedPitchMarkTimeList, actualRelativeDuration); return(durationChangedSound); } else { return(pitchChangedSound); } }